Linux上的Swift – 导入第三方模块

我在Linux上写了一些入门级的swift代码作为学习练习。

作为一个普通的任务,我希望在自己的代码中使用第三方的Swift模块。 我们称这个模块为“Foo”。 Foo模块有一个Package.swift文件,在该目录下运行swift build之后,它创build了.build/debug/libFoo.so

现在我想用这个做两件事情:

  1. 能够在REPL中import Foo
  2. 能够在我自己的swift程序中导入Foo,也许通过链接这个共享对象。

我有一种感觉,两个任务是相关的,所以现在他们是在同一个问题。

对于1.,我不明白包是如何被REPL“find”的。 我试过swift -F .build/debug -framework Foo但是我得到了“没有这样的模块”的错误。 我也试过swift -I .build/debug结果相同。

对于2.,我检查了swiftc --help并且有-L-l选项,但是我无法find正确的方法来使用这些:

 $ swiftc main.swift -L ../foo.git/.build/debug -llibFoo.so main.swift:1:8: error: no such module 'Foo' import Foo ^ 

我使用的是Swift 2.2或者3.0(用于游戏,而不是用于2.2的swift build ,因为没有swift build – 但是它产生相同的输出)。

请注意,我明白swift build可以自动下载并build立第三方模块,但我想知道如何将磁盘模块,因为他们可能是我自己的工作进行中的模块。


编辑:我尝试了基于一个发现,你可以使用本地path作为包的dependencies:列表中的url:参数的swift3的一个小实验,至less为本地开发。

我创build了一个BarBar/Package.swift目录:

 import PackageDescription let package = Package(name: "Bar") 

我还创build了Bar/Sources/bar.swift其中包含:

 public func bar(arg: Int) -> Int { return arg * 2 } 

其意图是模块Bar提供了称为bar(arg:)的函数。

我做了一个git initgit add .git commit -m "Initial commit." 然后git tag 1.0.0为这个模块创build一个标记的本地 git仓库。

然后回到顶层,我创build了目录FooFoo/Package.swift

 import PackageDescription let package = Package( name: "Foo", dependencies: [ .Package(url: "../Bar", majorVersion: 1) ] ) 

请注意../Bar的相对path。

我也创build了Foo/Sources/main.swift

 import Bar print(bar(arg: 11)) 

现在当我在Fooswift build时,它会克隆Bar并build立它。 但是,然后我得到以下错误; 没有这样的模块

 $ swift build Compile Swift Module 'Bar' (1 sources) Compile Swift Module 'Foo' (1 sources) .../Foo/Sources/main.swift:1:8: error: no such module 'Bar' import Bar ^ <unknown>:0: error: build had 1 command failures error: exit(1): .../swift-3.0-PREVIEW-4-ubuntu14.04/usr/bin/swift-build-tool -f .../Foo/.build/debug.yaml 

奇怪的是,如果我再次执行完全相同的构build命令,我会得到一个不同的错误:

 $ swift build Compile Swift Module 'Foo' (1 sources) Linking .build/debug/Bar .../Foo/Sources/main.swift:3:7: error: use of unresolved identifier 'bar' print(bar(arg: 11)) ^~~ <unknown>:0: error: build had 1 command failures error: exit(1): .../swift-3.0-PREVIEW-4-ubuntu14.04/usr/bin/swift-build-tool -f .../Foo/.build/debug.yaml 

我曾希望这可能工作。

正如文档中所述,Linux上的Swift及其软件包管理器正在进行中,所以难怪有缺陷和缺乏信息。 不过,这是我通过实验和阅读帮助找到的。

如果模块Foo/LibLocationFoo.swiftmodule中有一个库/moduleeLocation ,那么可以在Swift程序中导入和使用Foo ,调用它的main.swift ,然后通过执行

 swiftc -I /moduleeLocation -L /LibLocation -lFoo main.swift 

你也可以在REPL中通过启动它

 swift -I /moduleeLocation -L /LibLocation -lFoo 

即基本上给它与swiftc相同的论点。 顺便说一句,如果模块是使用swift buildmoduleeLocation可能与LibLocation相同。

正如我在前面的评论中提到的,你用FooBar创建的例子,都是用swift build ,对我来说工作得很好,所以我不能重现这个问题。

顺便说一句,除了阅读swift.org文档和命令行帮助外,还可以通过使用-v标志运行swift build和其他命令来搜集大量有趣且潜在有用的信息。 要了解一些隐藏的选项可用与swiftc

 swiftc -help-hidden