通过命令行编译和链接 Swift/Objective-C++ 应用程序
Compiling & linking a Swift/Objective-C++ app via the command line
将 C++ 组件添加到正在编译的 Swift 应用程序并通过命令行 运行 后,我现在需要编译 C++ 和 Objective-C++ (* .mm) 文件和 link 它们与 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++ 库。我尝试将这些 lib 标志添加到以下命令,但无济于事:
cpp.o: FooRenderer/FooRenderer/FooLibrary.cpp
clang++ -c --std=c++14 -lstdc++ -lc++ -stdlib=libstdc++ -o $@ $^
我错过了什么?
一个问题是最后一个命令行中缺少 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
目标的命令是不必要的,因为这些是链接器标志,此时您只是在编译。
此外,您可能不需要 objc.o
目标的 cpp.o
依赖项,因为您仍在编译并且编译不依赖于其他目标文件。如果没有 -framework Foundation
,你可能会做得很好,但它不会伤害任何东西。
虽然我对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 $@ $^
并且在编译时添加链接器flags/libraries没有任何意义。
将 C++ 组件添加到正在编译的 Swift 应用程序并通过命令行 运行 后,我现在需要编译 C++ 和 Objective-C++ (* .mm) 文件和 link 它们与 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++ 库。我尝试将这些 lib 标志添加到以下命令,但无济于事:
cpp.o: FooRenderer/FooRenderer/FooLibrary.cpp
clang++ -c --std=c++14 -lstdc++ -lc++ -stdlib=libstdc++ -o $@ $^
我错过了什么?
一个问题是最后一个命令行中缺少 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
目标的命令是不必要的,因为这些是链接器标志,此时您只是在编译。
此外,您可能不需要 objc.o
目标的 cpp.o
依赖项,因为您仍在编译并且编译不依赖于其他目标文件。如果没有 -framework Foundation
,你可能会做得很好,但它不会伤害任何东西。
虽然我对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 $@ $^
并且在编译时添加链接器flags/libraries没有任何意义。