**编辑:发现我的问题。正如以下答案所解释的,在制作静态库时,我实际上并没有进行任何链接。相反,我创建了一个共享库并静态链接 libstdc++。
我正在尝试创建一种在运行内核(2.6.37)的古老 arm 平台上使用 c++11 的方法。不幸的是,我们 BSP 包含的最新交叉编译是 GCC 4.5.3,它不支持我们需要的所有 c++11 实用程序。
最初我尝试使用旧版本的 crosstool-ng 来构建交叉编译器,但旧版本太坏了。较新的版本不支持 2.6.37 内核。我能够完成一个构建,但是没有构建 g++ 二进制文件,这使得整个努力毫无用处(我确实检查了 menuconfig 中是否启用了 c++)。
因此,我的最后一个选择是在 4.9.4 版本本地构建 gcc 并创建一个静态链接库,让我的 gcc 4.5.3 交叉编译器链接。这似乎在大多数情况下都有效。我使用以下内容在目标上创建我的库:
g++ -std=c++11 --static -c main2.cpp
ar -cvq libmain2.a main2.o
然后我复制这些文件并尝试使用 gcc 4.5.3 在主机上构建并获得以下信息:
arm-angstrom-linux-gnueabi-g++ simple.cpp -lmain2 -L.
(我清理了一些输出)
未定义对 `std::_Hash_bytes(void const*, unsigned int, unsigned int)' 的 引用 未定义对 std::__throw_regex_error(std::regex_constants::error_type)' 的引用
但是,当我使用 nm 时,我得到以下信息:
$ arm-angstrom-linux-gnueabi-nm libmain2.a | grep Hash_bytes
U _ZSt11_Hash_bytesPKvjj
U _ZSt11_Hash_bytesPKvjj
$ arm-angstrom-linux-gnueabi-nm libmain2.a | grep throw_regex
U _ZSt19__throw_regex_errorNSt15regex_constants10error_typeE
U _ZSt19__throw_regex_errorNSt15regex_constants10error_typeE
有谁知道到底发生了什么?不幸的是,我们需要能够在主机系统上使用我们的交叉编译器来完成大多数工作,但我们还需要集成这个使用 c++11 的特定库。
另请注意,如果我从我的代码中取出正则表达式和哈希功能,但保留其他 c++11 概念,如 nullptr、类型推断、委托等,则代码编译并在目标上运行良好。
编辑:好的,所以经过更多调查,看起来函数 _Hash_bytes 和 __throw_regex_error 没有被静态链接到静态库中。我想我需要知道为什么会这样才能解决这个问题。