Компиляция и связывание кода Swift + Objective C из командной строки OS X

Компиляция Swift из командной строки OS X:

swift -sdk $(xcrun --show-sdk-path --sdk macosx) test.swift

Компиляция объекта C из командной строки:

clang -lobjc -framework Foundation -c testObject.m

Я могу добавить параметр -c в любой компилятор для создания файлов .o.

Как связать эти два исходных файла в одном приложении?

Или больше нужно строить?

Ответ 1

TL; DR. Предпочтительно использовать инструментарий Xcode, так как там много чего происходит. Но можно использовать инструменты командной строки.

Я предупреждаю вас, что это быстрый и грязный пример того, как компилировать и запускать файлы .m и .swift, связанные с Cocoa и средой Swift. Я даже не пытаюсь следовать лучшим практикам с обеих сторон.

Предположим, что у вас есть класс Objective-C:

$ cat C.h
#import <Cocoa/Cocoa.h>
@interface C : NSObject
@property (retain) NSString *c;
@end

$ cat C.m
#import "C.h"

@implementation C

- (id)init {
  self = [super init];
  self.c = @"Hello world!";
  return self;
}

@end

И у вас есть файл Swift, который использует этот класс:

$ cat S.swift
let c = C()

println(c.c)

Вам просто нужно скомпилировать файлы Objective-C и Swift в файлы .o, отдельно:

xcrun clang C.m -o C.o -c
# Be sure to import the bridge header (our only header in this example)
xcrun swiftc -c S.swift -import-objc-header C.h -F /System/Library/Frameworks -I/usr/include

Как вы можете видеть, нам пришлось вручную включать пути структуры и заголовка, чтобы компилятор Swift обнаружил нужные файлы (лучше всего было бы искать их в SDK, а не в установленных файлах, btw (с xcrun --show-sdk-path)).

Затем нам просто нужно связать их, потянув все Swift и Objective-C исполняемые файлы. Поскольку swift по умолчанию тянет библиотеки Objective-C, нам даже не нужно указывать многое:

xcrun swiftc -o app C.o S.o

Вот, наш исполняемый файл связан, и мы можем его запустить!

$ ./app
Hello world!

Это очень интересно, но я бы посоветовал не использовать эти инструменты напрямую, если вы на самом деле не создаете систему сборки для своего проекта, которая их нацеливает, и есть веская причина не использовать Xcode/ xcodebuild.