gpt4 book ai didi

linux - Swift on Linux - 导入第三方模块

转载 作者:IT王子 更新时间:2023-10-29 00:54:34 24 4
gpt4 key购买 nike

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

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

现在我想用它做两件事:

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

我觉得这两个任务是相关的,所以现在它们在同一个问题中。

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

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

$ 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(使用 swim 而不是 swift build 用于 2.2,因为没有 swift build - 但我相信它会产生相同的输出)。

请注意,我了解 swift build 可以自动下载和构建第三方模块,但是我想知道如何合并磁盘上的模块,因为它们可能是我自己的工作-进度模块。


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

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

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

我还创建了 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 为这个模块创建一个标记的 local git repo。

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

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

注意 ../Bar 的相对路径。

我还创建了 Foo/Sources/main.swift:

import Bar
print(bar(arg: 11))

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

$ 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

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

$ 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

我曾希望这会奏效。

最佳答案

Be able to import Foo in my own swift program, perhaps by linking with this shared object.

使用您在“编辑”之后在问题中发布的示例,如果您使用 swift build,这似乎可以正常工作。 Swift Package Manager将为您处理所有依赖项,即使它们在磁盘上(这适用于 Swift 3 和 4):

$ cd Foo

$ swift build
Cloning /path/to/Bar
HEAD is now at 0c3fd6e Initial commit.
Resolved version: 1.0.0
Compile Swift Module 'Bar' (1 sources)
Compile Swift Module 'Foo' (1 sources)
Linking ./.build/debug/Foo

$ .build/debug/Foo
22

请注意 Foo/.build/debug 不包含任何 .so 文件:

$ ls Foo/.build/debug
Bar.build Bar.swiftdoc Bar.swiftmodule Foo Foo.build Foo.swiftdoc Foo.swiftmodule ModuleCache

我相信应该使用 .swiftdoc 和 .swiftmodule 文件。

Be able to import Foo in the REPL.

这部分有点乱,但我找到了解决方案 here .要将其应用于您的示例,您有两种选择:

  • Use swift build with extra flags (这适用于 Swift 3 和 4):

    $ cd Bar

    $ swift build -Xswiftc -emit-library
    Compile Swift Module 'Bar' (1 sources)

    $ swift -I .build/debug -L . -lBar
    1> import Bar
    2> bar(arg: 11)
    $R0: Int = 22
    3>

    这会在当前目录中创建 libBar.so:

    $ ls
    libBar.so Package.swift Sources


  • Update your Package.manifest (这是 Swift 4 特有的):

    1. 更新后的 Package.manifest 看起来像这样:

      // swift-tools-version:4.0
      import PackageDescription

      let package = Package(
      name: "Bar",
      products: [
      .library(
      name: "Bar",
      type: .dynamic,
      targets: ["Bar"]),
      ],
      targets: [
      .target(
      name: "Bar",
      dependencies: [],
      path: "Sources"),
      ]
      )
    2. 这就是构建和调用 REPL 的方式:

      $ cd Bar

      $ swift build
      Compile Swift Module 'Bar' (1 sources)
      Linking ./.build/x86_64-unknown-linux/debug/libBar.so

      $ swift -I .build/debug -L .build/debug -lBar
      1> import Bar
      2> bar(arg: 11)
      $R0: Int = 22
      3>

    这会在 .build/debug 目录中创建 libBar.so:

    $ ls .build/debug
    Bar.build Bar.swiftdoc Bar.swiftmodule libBar.so ModuleCache

如果您无法重现这些结果,我建议清除所有 .build 目录和 .so 文件,并安装一个干净的 Swift 版本(为此我推荐 swiftenv)。

关于linux - Swift on Linux - 导入第三方模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39071564/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com