[ad_1]
From Swift 4 there may be native assist for wrapping C libraries in Swift system module packages. This implies that you may simply ship your individual system modules, you simply need to be taught the right way to use the Swift Package deal Supervisor.😅
Bridging header inside Xcode
Let’s hearth up Xcode and begin a model new single view app iOS mission. Fill out the required fields, and naturally select the Swift language. Subsequent, add a brand new file and select the C file template.
After you enter the title and verify the additionally create header file field, Xcode will ask you concerning the Goal-C bridging header file. Simply create it. The title of this file is difficult, as a result of it additionally helps different C household languages, like pure C or C++, Goal-C and plus-plus. 😉
Let’s create a public header for the C code (factorial.h
):
#ifndef factorial_h
#outline factorial_h
#embrace <stdio.h>
lengthy factorial(int n);
#endif /* factorial_h */
That is gona be the implementation of the tactic (factorial.c
):
#embrace "factorial.h"
lengthy factorial(int n) n == 1) return 1;
return n * factorial(n-1);
Contained in the bridging header, merely import the C header file:
#embrace "factorial.h"
Someplace inside a Swift file you need to use the factorial technique:
print("Whats up (factorial(5))!")
// it really prints out "Whats up 120!" ;)
Compile and run. 🔨 It simply works. 🌟 Magic! 🌟
You are able to do the very same factor to make use of Goal-C lessons inside your Swift initiatives. Apple has nice docs about this system, it is best to learn that if you wish to know extra about combine and match.
Delivery C code with SPM
The true enjoyable begins if you begin utilizing the Swift Package deal Supervisor to construct C household primarily based sources. From Swift 3.0 you’ll be able to construct C language targets with SPM. If you do not know the right way to use the SPM instrument, it is best to learn my complete tutorial concerning the Swift Package deal Supervisor first.
The one factor that you will have to do it is a correct listing construction (plus you may want the package deal description file), and the package deal supervisor will take care all the remainder. Right here is every thing what you have to construct the factorial instance with SPM.
import PackageDescription
let package deal = Package deal(
title: "cfactorial",
merchandise: [
.library(name: "cfactorial", targets: ["cfactorial"]),
],
targets: [
.target(
name: "cfactorial",
path: "./Sources/factorial"
),
]
)
The listing construction ought to be one thing like this.
Sources
factorial
embrace
factorial.h
factorial.c
You also needs to change the #embrace "factorial.h"
line contained in the factorial.c
file to #embrace "embrace/factorial.h"
as a result of we made a brand new embrace listing. That is NOT obligatory, however should you do not put your umbrella header into the embrace listing, you may want to supply a modulemap
file, and supply the proper location of your header. For those who use the embrace construction SPM will generate every thing for you.
With this system you’ll be able to import your cfactorial
module from every other Swift package deal and name the factorial technique, like we did by Xcode. You simply have so as to add this module as a dependency, oh by the way in which you’ll be able to even name this module from one other C mission made with SPM! 💥
.package deal(url: "https://gitlab.com/theswiftdev/cfactorial", .department("grasp")),
Congratulations, you simply shipped your first C code with Swift Package deal Supervisor. This setup additionally works with C, C++, Goal-C, Goal-C++ code.
Wrapping C [system] modules with SPM
If you wish to wrap a C [system] library and name it immediately from Swift you’ll be able to crete a model new wrapper package deal with the assistance of the Swift Package deal Supervisor. To begin you need to use the swift package deal init --type system-module
command, it will create a generic template mission.
These are particular packages in response to Apple, you simply need to ship your individual modulemap
and a header file to show the wanted APIs, however first – clearly – you may want the same old package deal definition file:
import PackageDescription
let package deal = Package deal(
title: "ccurl",
suppliers: [
.brew(["curl"]),
.apt(["libcurl4-openssl-dev"])
]
)
Contained in the Package deal.swift file you’ll be able to set the suppliers for the library (like brew on macOS or aptitude for Ubuntu / Debian and the others). Right here is an effective recommendation for you: sudo apt-get set up pkg-config
underneath Linux to make issues work, as a result of the system will seek for package deal header recordsdata with the assistance of the pkgConfig property. For instance if you wish to use libxml2
and pkg-config
just isn’t put in, you will not have the ability to compile / use your system module.
Subsequent you may want a module.modulemap
file, which is fairly simple.
module ccurl [system] {
header "shim.h"
hyperlink "curl"
export *
}
Concerning the hyperlink property see the Xcode launch notes seek for “auto-linking”
Lastly add an additional shim.h header file to import all of the required APIs. Normally I do not prefer to import immediately the required header recordsdata from the modulemap
file that is why I’m utilizing this shim.h
– title it such as you need – you may see in a second why am I preferring this technique, however here’s a fundamental one.
#ifndef CLIB_SWIFT_CURL
#outline CLIB_SWIFT_CURL
#import <curl/curl.h>;
#endif
Let’s speak about why I like importing the shim file. You probably have platform variations you need to use a neat trick with the assistance of utilizing macros, for instance you’ll be able to import header recordsdata from completely different places should you verify for the __APPLE__
platform macro.
#ifndef CLIB_SWIFT_EXAMPLE
#outline CLIB_SWIFT_EXAMPLE
#ifdef __APPLE__
#embrace "/usr/native/embrace/instance.h"
#else
#embrace "/usr/embrace/instance.h"
#endif
#endif
Cool, huh? 🍎 + 🔨 = ❤️
[ad_2]