【问题标题】:Compiling & linking a Swift/Objective-C++ app via the command line通过命令行编译和链接 Swift/Objective-C++ 应用程序
【发布时间】:2016-12-06 02:31:11
【问题描述】:

将 C++ 组件添加到通过命令行编译和运行的 Swift 应用程序后,我现在需要编译 C++ 和 Objective-C++ (*.mm) 文件并将它们与 Swift 应用程序链接。

生成文件:

all: foo-renderer

clean:
  rm -f foo-renderer cpp.o objc.o

cpp.o: FooRenderer/FooRenderer/FooLibrary.cpp
  clang++ -c -o $@ $^

objc.o: cpp.o FooRenderer/FooRenderer/FooLibraryWrapper.mm
  clang++ -c -framework Foundation -o $@ $^

foo-renderer: objc.o FooRenderer/FooRenderer/*.swift
  xcrun -sdk macosx swiftc -import-objc-header FooRenderer/FooRenderer/FooRenderer-Bridging-Header.h -o $@ $^

编译器因以下错误而失败:

ld: warning: object file (objc.o) was built for newer OSX version (10.12) than being linked (10.9)
Undefined symbols for architecture x86_64:
  "__ZN11FooLibrary23printifyERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE", referenced from:
      -[FooLibraryWrapper printify:] in objc.o
  "__ZN11FooLibrary8optimizeERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE", referenced from:
      -[FooLibraryWrapper optimize:] in objc.o
  "__ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE6__initEPKcm", referenced from:
      -[FooLibraryWrapper printify:] in objc.o
      -[FooLibraryWrapper optimize:] in objc.o
  "__ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev", referenced from:
      -[FooLibraryWrapper printify:] in objc.o
      -[FooLibraryWrapper optimize:] in objc.o
  "__ZSt9terminatev", referenced from:
      ___clang_call_terminate in objc.o
  "___cxa_begin_catch", referenced from:
      ___clang_call_terminate in objc.o
  "___gxx_personality_v0", referenced from:
      -[FooLibraryWrapper printify:] in objc.o
      -[FooLibraryWrapper optimize:] in objc.o
      Dwarf Exception Unwind Info (__eh_frame) in objc.o
ld: symbol(s) not found for architecture x86_64

我的第一直觉是标准 C++ 库没有被包括在内。我尝试将这些库标志添加到以下命令中,但无济于事:

cpp.o: FooRenderer/FooRenderer/FooLibrary.cpp
  clang++ -c --std=c++14 -lstdc++ -lc++ -stdlib=libstdc++ -o $@ $^

我错过了什么?

【问题讨论】:

  • 您是否尝试过明确指定要使用的 SDK,以及最低和最高操作系统版本? Xcode 做这些。您可能想使用 Xcode 进行构建,并通过展开报告导航器中的条目来查看它传递的内容(每行右侧都有一个不可见的图标显示)。
  • (我的意思是链接器警告)

标签: c++ objective-c swift clang objective-c++


【解决方案1】:

一个问题是最后一个命令行中缺少cpp.o。将它添加到依赖列表应该可以解决问题:

foo-renderer: objc.o FooRenderer/FooRenderer/*.swift cpp.o
      xcrun -sdk macosx swiftc -import-objc-header FooRenderer/FooRenderer/FooRenderer-Bridging-Header.h -o $@ $^

这是因为链接器需要 C++ 代码中的符号定义。

-l... 标志添加到cpp.o 目标的命令是不必要的,因为这些是链接器标志,此时您只是在编译。

此外,您可能不需要 cpp.o 目标的 cpp.o 依赖项,因为您仍在编译并且编译不依赖于其他目标文件。如果没有-framework Foundation,你可能会做得很好,但这不会造成任何伤害。

【讨论】:

  • 非常感谢@OmniProg!很好的答案,这真的很有帮助。
【解决方案2】:

虽然我对 objc/clang/swift 不是很熟悉,但我有一些关于如何进行的指导,

> "__ZN11FooLibrary23printifyERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE",
> referenced from:
>       -[FooLibraryWrapper printify:] in objc.o

上面说在函数 printify 的 objc 目标文件中,你有一个未定义的符号,可能是 FooLibrary::printify::basic_string::char_traits,所以很可能你缺少一个 c++ 库,尝试添加 libc++ 库你的链接命令。

cpp.o: FooRenderer/FooRenderer/FooLibrary.cpp
  clang++ -c --std=c++14 -lstdc++ -lc++ -stdlib=libstdc++ -o $@ $^

在编译期间添加链接器标志/库没有任何意义。

【讨论】:

    猜你喜欢
    • 2014-07-30
    • 2011-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-24
    • 1970-01-01
    相关资源
    最近更新 更多