2017-06-13 30 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