我在Linux上写了一些入门级的swift代码作为学习练习。
作为一个普通的任务,我希望在自己的代码中使用第三方的Swift模块。 我们称这个模块为“Foo”。 Foo模块有一个Package.swift文件,在该目录下运行swift build
之后,它创build了.build/debug/libFoo.so
。
现在我想用这个做两件事情:
import 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了一个Bar
和Bar/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 init
, git add .
, git commit -m "Initial commit."
然后git tag 1.0.0
为这个模块创build一个标记的本地 git仓库。
然后回到顶层,我创build了目录Foo
和Foo/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))
现在当我在Foo
里swift 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
在/LibLocation
和Foo.swiftmodule
中有一个库/moduleeLocation
,那么可以在Swift程序中导入和使用Foo
,调用它的main.swift
,然后通过执行
swiftc -I /moduleeLocation -L /LibLocation -lFoo main.swift
你也可以在REPL中通过启动它
swift -I /moduleeLocation -L /LibLocation -lFoo
即基本上给它与swiftc
相同的论点。 顺便说一句,如果模块是使用swift build
, moduleeLocation
可能与LibLocation
相同。
正如我在前面的评论中提到的,你用Foo
和Bar
创建的例子,都是用swift build
,对我来说工作得很好,所以我不能重现这个问题。
顺便说一句,除了阅读swift.org文档和命令行帮助外,还可以通过使用-v
标志运行swift build
和其他命令来搜集大量有趣且潜在有用的信息。 要了解一些隐藏的选项可用与swiftc
做
swiftc -help-hidden