[英]Error to use C++ on Swift project on Xcode: Undefined symbols for architecture x86_64
There are a lot of questions about this on the web but I couldn't solve my problem.网上有很多关于这个的问题,但我无法解决我的问题。 I've been studying this for a few days.
我已经研究了几天了。
I want run a simple C++ class on Swift project, to this I followed this tutorial: http://www.swiftprogrammer.info/swift_call_cpp.html .我想在 Swift 项目上运行一个简单的 C++ 类,对此我遵循了本教程: http ://www.swiftprogrammer.info/swift_call_cpp.html。 Basically I've followed the steps:
基本上我遵循了以下步骤:
junk.cpp
and junk.h
filesjunk.cpp
和junk.h
文件g++ or/and clang++
g++ or/and clang++
$ ar r libjunkcpp.a junk.o
$ ar r libjunkcpp.a junk.o
ranlib libjunkcpp.a
Build Phases -> Link Binary With Libraries -> Add
Build Phases -> Link Binary With Libraries -> Add
When I compiles, the follow errors occurs:当我编译时,出现以下错误:
Undefined symbols for architecture x86_64:
"A::getInt()", referenced from:
_getIntFromCPP in wrapper.o
"A::A(int)", referenced from:
_getIntFromCPP in wrapper.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
junk.h
垃圾.h
class A {
public:
A(int);
int getInt();
private:
int m_Int;
};
junk.cpp
垃圾.cpp
#include "junk.h"
A::A(int _i) : m_Int(_i) {}
int A::getInt() {
return m_Int
}
wrapper.cpp
包装器.cpp
#include "junk.h"
extern "C" int getIntFromCPP() {
// Create an instance of A, defined in
// the library, and call getInt() on it:
return A(1234).getInt();
}
bridge.h
桥.h
int getIntFromCPP();
This is an issue that sometimes occurs when using C or C++ libraries that get bridged through Objective-C into Swift.当使用通过 Objective-C 桥接到 Swift 的 C 或 C++ 库时,有时会出现这个问题。 The issue isn't with how the Archive (static library) is built -- rather, it's a problem with an overly-aggressive linker creating the application.
问题不在于 Archive(静态库)的构建方式——而是创建应用程序的过于激进的链接器的问题。
The problem is that the linker sees the binding symbols and the C++ symbols, but never sees it being called from anywhere because it is actually invoked from a different language (Swift).问题是链接器看到了绑定符号和 C++ 符号,但从未看到它从任何地方被调用,因为它实际上是从不同的语言 (Swift) 调用的。 This ultimately results in the linker aggressively stripping all symbols that it doesn't believe are being used in an effort to save space, which effectively removes all of the C++ code.
这最终会导致链接器主动剥离所有它不认为正在使用的符号以节省空间,从而有效地删除所有 C++ 代码。
When this happens, nm
will report the correct symbols as existing in the archive, but the actual application will fail to execute due to the symbols not being found.发生这种情况时,
nm
将报告存档中存在正确的符号,但实际应用程序将由于未找到符号而无法执行。
As for solutions, there are actually several questions/answers already on Stack Overflow that address this issue in varying degrees:至于解决方案,实际上 Stack Overflow 上已经有几个问题/答案在不同程度上解决了这个问题:
How to disable C++ dead code stripping in xcode , where the solution is to use the linker flag -force_load
to force that the static symbols are actually loaded.如何在 xcode 中禁用 C++ 死代码剥离,解决方案是使用链接器标志
-force_load
强制实际加载静态符号。
Keeping Xcode from stripping out unused symbols from a static library which suggests using __attribute__((constructor))
to trick the linker into thinking the symbols are needed on construction, thus keeping them in.防止 Xcode 从静态库中剥离未使用的符号,这建议使用
__attribute__((constructor))
来欺骗链接器认为构建时需要符号,从而将它们保留在其中。
Xcode Archive debug strip errors , which more broadly suggests toggling some Xcode configurations that may result in the symbols not being stripped. Xcode Archive debug strip errors ,这更广泛地建议切换一些可能导致符号不被剥离的 Xcode 配置。 The suggestions in the answers here may conflict with the above two links, however.
但是,此处答案中的建议可能与上述两个链接冲突。
It is difficult to provide a definitive and clear answer without more information on the existing setup, such as where wrapper.cpp
is built, and how the bindings get used from within the Swift project.如果没有有关现有设置的更多信息(例如构建
wrapper.cpp
的位置以及如何在 Swift 项目中使用绑定),则很难提供明确明确的答案。 Given that this question is from 2018, I don't suspect there will be much more information on what this setup was at the time.鉴于这个问题是从 2018 年开始的,我不怀疑会有更多关于当时的设置的信息。
From the described symptoms, this sounds exactly like the issue my colleagues faced when doing C++/Swift bindings -- and the solution was ultimately to use -force_load
which ensures that the archive is preserved in totality into the final application.从所描述的症状来看,这听起来就像我的同事在进行 C++/Swift 绑定时遇到的问题——解决方案最终是使用
-force_load
以确保将存档完整保留到最终应用程序中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.