Essayez de mélanger le langage C et Swift dans un seul projet (OS X, Linux)

Aperçu

emballer

  1. Créez un fichier objet à partir d'une source de langage C avec clang
  2. Compilez la source Swift avec le fichier objet avec swiftc
  3. Voilà (vous n'avez pas besoin de lire cet article si vous comprenez cela)

environnement

OS X


$ clang --version
Apple LLVM version 7.3.0 (clang-703.0.29)
Target: x86_64-apple-darwin15.5.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

$ swift --version
Apple Swift version 2.2 (swiftlang-703.0.18.1 clang-703.0.29)
Target: x86_64-apple-macosx10.9

Linux


$ clang --version
clang version 3.8.0 (tags/RELEASE_380/final)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/local/bin

$ swift --version
Swift version 2.2.1 (swift-2.2.1-RELEASE)
Target: x86_64-unknown-linux-gnu

fichier source

Par souci de simplicité, je n'ai préparé que trois fichiers cette fois.

$ ls
c.c  c.h  swift.swift

c.h


#include <stdio.h>
void c_function(const char * string);

c.c


#include "c.h"
void c_function(const char * string) {
  (void)printf("%s", string);
}

swift.swift


c_function("Hello, I'm Swift.\n")

Procédure de compilation

Créer un fichier objet à partir d'une source de langage C

OS&#x0020;X,&#x0020;Commun à Linux


$ clang -c c.c -oc.o
$ ls
c.c  c.h  c.o  swift.swift

l'a fait. Vous pouvez utiliser gcc au lieu de clang.

Compilez la source Swift avec le fichier objet

OS&#x0020;X


$ xcrun --sdk macosx swiftc swift.swift c.o -import-objc-header c.h
ld: warning: object file (c.o) was built for newer OSX version (10.11) than being linked (10.9)
$ ls
c.c		c.h		c.o		main		swift.swift
$ ./main
Hello, I'm Swift.

Linux


$ swiftc swift.swift c.o -import-objc-header c.h
$ ls
c.c  c.h  c.o  main  swift.swift
$ ./main
Hello, I'm Swift.

l'a fait. C'est la fin. C’est facile, non? [^ 1]

[^ 1]: Il y a un avertissement sur OS X, mais il est pratiquement inoffensif. En regardant la cible de Swift 2.2 d'OS X, c'est x86_64-apple-macosx10.9, donc il peut être préférable de compiler c.o en utilisant le SDK de 10.9 ... mais ignorez-le ici.

Collection NG

-import-objc-header?

Qu'est-ce que c'est délicieux?

Pour une raison quelconque, je ne vois pas cette option même avec swiftc --help [^ 2].

[^ 2]: J'apprécie "[Swift sans Xcode (de REPL à la génération de bibliothèque) # Objective-Bridge C et C](http://qiita.com/demmy/items/c4a6a430787d3097a6df#objective-c et J'ai découvert dans "Bridge c)".

Sans -import-objc-header?

$ swiftc swift.swift c.o
swift.swift:1:1: error: use of unresolved identifier 'c_function'
c_function("Hello, I'm Swift.\n")
^~~~~~~~~~

... n'est-ce pas?

Pas -import-c-header.

Comme il s'agit d'un en-tête de langage C, je veux utiliser -import-c-header ...

$ swiftc swift.swift c.o -import-c-header c.h
<unknown>:0: error: unknown argument: '-import-c-header'

… J'ai été grondé. Objective-C inclut complètement le langage C en termes de spécifications de langage, il semble donc théoriquement qu'il n'y ait aucun problème à lire l'en-tête C avec -import-objc-header, mais ... cela semble désagréable.

Dois-je utiliser xcrun sur OS X?

OS&#x0020;X


$ swiftc swift.swift c.o -import-objc-header c.h
(Abréviation)./c.h:1:10: error: 'stdio.h' file not found
#include <stdio.h>
         ^
<unknown>:0: error: failed to import bridging header 'c.h'

Je ne trouve pas l'en-tête de la bibliothèque de langage C standard. Il n'y a aucun problème avec Linux.

Un peu plus de façon détournée

Après avoir créé le fichier objet à partir de la source du langage C, créez le fichier objet dans Swift, puis essayez de le rassembler. En d'autres termes ...

OS&#x0020;X,&#x0020;Commun à Linux


$ clang -c c.c -oc.o
$ ls
c.c  c.h  c.o  swift.swift

C'est pareil. Ensuite, créez également un fichier objet dans Swift:

OS&#x0020;X


$ xcrun --sdk macosx swiftc -c swift.swift -oswift.o -import-objc-header c.h
$ ls
c.c		c.h		c.o		swift.o		swift.swift

Linux


$ swiftc -c swift.swift -oswift.o -import-objc-header c.h
$ ls
c.c  c.h  c.o  swift.o  swift.swift

Résumez les c.o et swift.o créés de cette manière:

OS&#x0020;X,&#x0020;Commun à Linux


$ swiftc swift.o c.o 2> /dev/null
$ ls
c.c  c.h  c.o  main  swift.o  swift.swift
$ ./main
Hello, I'm Swift.

l'a fait. Au fait, si vous faites clang swift.o c.o -omain, on vous dira où se trouve libswiftCore. {Dylib, so} (j'ai un message d'erreur très déroutant sous Linux). Donc, pour OS X, compilez (lien) avec clang swift.o co -omain -L / Applications / Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx -lswiftCore Je peux, mais quand j'essaye de le faire

OS&#x0020;X


$ ./main
dyld: Library not loaded: @rpath/libswiftCore.dylib
  Referenced from: (Abréviation)./main
  Reason: image not found
Trace/BPT trap: 5

Est dit. … Utilisez vite et docilement.

Recommended Posts

Essayez de mélanger le langage C et Swift dans un seul projet (OS X, Linux)
Essayez de mélanger plus de langage C et Swift dans un seul projet (OS X, Linux)
Organiser les builds dans des combinaisons C ++ / Java et Win / Linux
Essayez gRPC dans le projet Spring Boot et Spring Cloud (Mac OS)
Essayez d'exécuter ruby-net-nntp et tmail en 2020
CGI en C et Dart: Introduction (1)
Manipulez bien le caractère C ** avec Swift