2017-06-13 67 views
2

在Objective-C(或C一般),如果我打算有兩個文件,如斯威夫特功能前瞻性聲明或原型

的main.m:

void foo(); 

int main (int argc, const char * argv[]) 
{ 
    foo(); 
    return 0; 
} 

FOO .M:

void foo() { 
    // do something 
} 

我可以編譯的main.m到main.o,甚至無需foo.m,然後編譯foo.m,然後鏈接main.o:

$ clang -c main.m 

# later 
$ clang main.o foo.m -o FooExecutable 

我的理解是,main.m第一行的前向聲明或原型是使這項工作的原因。

有沒有辦法在Swift中創建相同類型的設置?我還沒有找到一種方法來做出相應的main.swift編譯。

main.swift:

// How do I tell the compiler to trust me that foo() will be implemented? 

foo() 

foo.swift:

func foo() { 
    // do something 
} 

然後:

# This works: 
$ swiftc main.swift foo.swift -o FooExecutable 

# This doesn't: 
$ swiftc -emit-object main.swift 

main.swift:3:1: error: use of unresolved identifier 'foo' 
foo() 
^~~ 

回答

2

你不能沒有定義它在聲明斯威夫特功能,編譯器 需要「foo.swift」才能編譯「main.swift」。

這裏是一個如何可以單獨編譯斯威夫特文件,然後鏈接目標文件的例子:

 
swift -frontend -c -module-name myprog -primary-file main.swift foo.swift 
swift -frontend -c -module-name myprog -primary-file foo.swift main.swift 

swiftc -o myprog main.o foo.o 

這是一個非常簡單的例子,真正的應用程序,你可能需要導入 額外的框架,並設置多選項。在編譯項目時Xcode可以檢查 ,在報告導航器中可以找到完整的編譯器和鏈接器輸出 。

另請參閱SWIFT MAKEFILES – TAKE 2 對於基於GNU Make的解決方案。

另一種選擇是針對 。swift模塊和共享庫進行編譯, How do I import a swift function declared in a compiled .swiftmodule into another swift file?。 然後func foo必須被標記爲public

foo.swift:

public func foo() { 
    print("foo") 
} 
 
swiftc -emit-module -emit-library -module-name Foo -module-link-name Foo foo.swift 

創建Foo.swiftmodule和libfoo.dylib的(這也可以在 獨立的步驟進行)。現在main.swift可以導入Foo模塊

main。SWIFT:

import Foo 
foo() 
 
swiftc -emit-object -I . main.swift 

和目標文件可以對共享庫鏈接:

 
swiftc -o myprog -L . main.o 
+0

從鏈接答案,聽起來就像.swiftmodule文件描述了接口,但沒有按」 t包含實現,所以我可以像'swooper -emit-module foo.swift -module-name FooModule -module-link-name FooModule'那樣執行'foo()'和'swiftc -emit-object -一世 。 main.swift'將main.swift編譯成main.o;然後,一旦foo.swift被實現,'swiftc -emit-library foo.swift -module-name FooModule -module-link-name FooModule'來構建庫和'swiftc main.o -L .'來構建/鏈接最終執行我認爲這實際上也在起作用...... – Isaac

+0

@Isaac:是的,這就是我所說的「另一種選擇」。編譯只需要.swiftmodule,但鏈接需要.dylib。 - 然後你有一個主要的可執行文件「main」,它依賴於共享庫「libFooModule.dylib」,而在另一個解決方案中(和你的C例子),你只有一個主要的可執行文件。 –

+0

啊,我忽略了圖書館是動態的。我認爲這仍然適用於我的目的。如果我將過程的細節編輯到答案中,請介意嗎? (我寧願在答案中提供這些細節,並接受這些細節,而不是在單獨的答案中添加這些細節。) – Isaac