【问题标题】:Swift shared libraries getting statically linked for command-line apps?Swift 共享库为命令行应用程序静态链接?
【发布时间】:2015-05-16 14:58:49
【问题描述】:

我正在尝试在我的 Mac OS X Swift 应用程序中使用外部框架。外部框架也使用 Swift,因此依赖于 Swift 共享库(例如,libswiftCore.dylib)。这是通过命令验证的

$ otool -L PromiseKit.framework/PromiseKit
PromiseKit.framework/PromiseKit:
    ...
    @rpath/libswiftCore.dylib (compatibility version 0.0.0, current version 0.0.0)

抬头@rpath我明白了

$ otool -l PromiseKit.framework/PromiseKit
      ...
      cmd LC_RPATH
  cmdsize 40
     path @executable_path/Frameworks (offset 12)

所以在运行时我希望 @rpath 解析为 @executable_path/Frameworks

问题

我得到一个运行时错误

dyld: Library not loaded: @rpath/libswiftCore.dylib
  Referenced from: .../PromiseKit.framework/Versions/A/PromiseKit
  Reason: image not found

查看包含我构建的可执行文件的文件夹,我没有看到 Frameworks 文件夹。

尝试修复失败

我尝试为我的应用将EMBEDDED_CONTENT_CONTAINS_SWIFT 设置为YES,但这仍然不会创建Frameworks 文件夹。

我尝试手动创建 Frameworks 文件夹并在 Swift 共享库中复制(来自 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx。这修复了原始错误,但是现在我看到了像这样的重复符号变暖:

objc[64445]: Class _TtC10Foundation15NSSimpleCString is implemented in both
   .../Frameworks/libswiftFoundation.dylib and
   .../myApp.
   One of the two will be used. Which one is undefined.

问题

Swift 库是否有可能被静态链接到我的应用程序中?如果是这样,我该如何关闭它并让 XCode 创建 Frameworks 文件夹版本?

我认为重要的一点是它是一个命令行应用程序。我尝试创建一个常规应用程序并添加框架,我在 .app 包中获得了预期的 Frameworks 文件夹,它包含 Swift 共享库

【问题讨论】:

标签: xcode swift static-linking dynamic-linking mac-frameworks


【解决方案1】:

我可以在有或没有外部框架的情况下获得一个快速的命令行工具,只要:

  1. 框架将 swift 库复制到其 Frameworks 目录中(可选)
  2. 命令行工具在尝试复制 swift 库时不会生成构建失败
  3. 工具运行路径配置了包含 swift 库的路径

要让框架复制 swift 库,请设置:

"Embedded Content Contains Swift Code" = Yes

为避免在工具尝试将 swift 库复制到其不存在的 Bundle Frameworks 目录时构建失败,请设置:

"Embedded Content Contains Swift Code" = Yes

要配置工具的运行路径,请将以下内容之一添加到 LD_RUNPATH_SEARCH_PATHS:

A.外部框架中的 swift 库:

@executable_path/PromiseKit.framework/Versions/A/Frameworks

请注意,Xcode 默认情况下不会将版本/A/框架符号链接到框架,就像它对资源、标头和模块所做的那样。

B. Xcode 应用中的 swift 库:

$(DEVELOPER_DIR)/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx

这仅适用于安装在可执行文件需要运行的每台机器上的足够相似的 Xcode。但它不需要外部框架来使该工具工作。

C. swift 库重新分布在与可执行文件相同的目录中:

@executable_path

或者,如果可执行文件位于 bin/ 目录中并且库位于 lib/ 目录中:

@executable_path/../lib

这可以重新分发,并且不需要外部框架来使工具工作。但它需要在 Xcode 中手动复制文件阶段才能以这种方式设置目录结构。


请注意,如果工具配置有:

"Embedded Content Contains Swift Code" = Yes

Xcode 抛出以下构建错误:

2015-06-04 00:56:28.816 swift-stdlib-tool[5208:2453424] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSFileManager copyItemAtPath:toPath:error:]: destination path is nil'
*** First throw call stack:
(
    0   CoreFoundation                      0x00007fff8ee4503c __exceptionPreprocess + 172
    1   libobjc.A.dylib                     0x00007fff89f1c76e objc_exception_throw + 43
    2   CoreFoundation                      0x00007fff8ee44eed +[NSException raise:format:] + 205
    3   Foundation                          0x00007fff926569b7 -[NSFileManager copyItemAtPath:toPath:error:] + 185
    4   swift-stdlib-tool                   0x000000010526b485 _Z13copyLibrariesP8NSStringS0_P19NSMutableDictionary + 853
    5   swift-stdlib-tool                   0x000000010526c60b main + 3915
    6   libdyld.dylib                       0x00007fff97d785c9 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
Copying libswiftCore.dylib from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx to (null)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多