Versuchen Sie, C-Sprache und Swift in einem Projekt (OS X, Linux) zu mischen.

Überblick

einpacken

  1. Erstellen Sie mit clang eine Objektdatei aus einer C-Sprachquelle
  2. Kompilieren Sie die Swift-Quelle mit der Objektdatei mit swiftc
  3. Das war's (Sie müssen diesen Artikel nicht lesen, wenn Sie das verstehen)

Umgebung

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

Quelldatei

Der Einfachheit halber habe ich diesmal nur drei Dateien vorbereitet.

$ 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")

Kompilierungsverfahren

Erstellen Sie eine Objektdatei aus einer C-Sprachquelle

OS&#x0020;X,&#x0020;Gemeinsam für Linux


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

erledigt. Sie können gcc anstelle von clang verwenden.

Kompilieren Sie die Swift-Quelle mit der Objektdatei

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.

erledigt. Das ist das Ende. Es ist einfach, oder? [^ 1]

[^ 1]: Unter OS X gibt es eine Warnung, die jedoch praktisch harmlos ist. Wenn man sich das Ziel von Swift 2.2 von OS X ansieht, ist es "x86_64-apple-macosx10.9", daher ist es möglicherweise besser, c.o mit dem SDK von 10.9 zu kompilieren ... aber ignorieren Sie es hier.

NG Sammlung

-import-objc-header?

Was ist es lecker?

Aus irgendeinem Grund sehe ich diese Option selbst bei swiftc --help [^ 2] nicht.

[^ 2]: Ich möchte "[ohne Xcode Swift (von REPL bis zur Bibliotheksgenerierung) # Objective-Bridge C und C](http://qiita.com/demmy/items/c4a6a430787d3097a6df#objective-c und (Brücke c) ".

Ohne -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")
^~~~~~~~~~

... nicht wahr?

Nicht -import-c-Header.

Da es sich um einen C-Sprach-Header handelt, möchte ich -import-c-header verwenden ...

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

… Ich wurde gescholten. Objective-C enthält die C-Sprache in Bezug auf die Sprachspezifikationen vollständig, so dass es theoretisch kein Problem gibt, den C-Header mit -import-objc-header zu lesen, aber ... es scheint unangenehm.

Soll ich xcrun unter OS X verwenden?

OS&#x0020;X


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

Ich kann den Header der Standard-C-Sprachbibliothek nicht finden. Es gibt kein Problem mit Linux.

Ein bisschen mehr Kreisverkehr

Nachdem Sie die Objektdatei aus der C-Sprachquelle erstellt haben, erstellen Sie die Objektdatei in Swift und versuchen Sie dann, sie zusammenzusetzen. Mit anderen Worten ...

OS&#x0020;X,&#x0020;Gemeinsam für Linux


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

Das ist das gleiche. Erstellen Sie als Nächstes auch in Swift eine Objektdatei:

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

Fassen Sie die auf diese Weise erstellten c.o und swift.o zusammen:

OS&#x0020;X,&#x0020;Gemeinsam für 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.

erledigt. Übrigens, wenn Sie "swang swift.o c.o -omain" machen, wird Ihnen gesagt, wo libswiftCore. {Dylib, so} ist (ich habe eine sehr verwirrende Fehlermeldung unter Linux). Kompilieren (verknüpfen) Sie für OS X mit clang swift.o co -omain -L / Applications / Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx -lswiftCore Ich kann, aber wenn ich es versuche

OS&#x0020;X


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

Ich sagte. … Verwenden Sie Swiftc gehorsam.

Recommended Posts

Versuchen Sie, C-Sprache und Swift in einem Projekt (OS X, Linux) zu mischen.
Versuchen Sie, mehr C-Sprache und Swift in einem Projekt (OS X, Linux) zu mischen.
Organisieren Sie Builds in C ++ / Java- und Win / Linux-Kombinationen
Probieren Sie gRPC im Spring Boot & Spring Cloud-Projekt (Mac OS) aus.
Versuchen Sie, ruby-net-nntp und tmail im Jahr 2020 auszuführen
CGI in C und Dart: Einführung (1)
Behandle C char ** gut mit Swift