在嵌入式平台中,业务使用C语言开发,在交叉编译过程中会链接一个第三方的c++静态库,该第三放库使用了std,需要链接libstdc++的库,由于所在的嵌入式平台中没有libstdc++.so库,如果将libstdc++.so拷贝板子上,需要占用5MB空间,很浪费空间,准备使用libstdc++的静态库,在链接过程中出现如下问题;
整个业务的编译使用cmake构建,使用如下方式进行链接;
add_executable(${target} ${src_sample})
target_link_libraries(${target} -static-libgcc;-static-libstdc++)
但是在最终的链接过程中出现如下错误;
undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>,
这个错误的原因是不能识别std
,即没有链接'libstdc++'的库,在cmake中有链接-static-libstdc++
,而且交叉工具链中是有libstdc++.a库,当我们将cmake改为:
add_executable(${target} ${src_sample})
target_link_libraries(${target} -lstdc++)
可以编译成功,但此时链接的是stdc++动态库,与预期相违背;
经过漫长的资料查阅终于找到原因:
gcc的链接说明:
https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html#Link-Options
-static-libstdc++
When the g++ program is used to link a C++ program, it normally automatically links against libstdc++. If libstdc++ is available as a shared library, and the -static option is not used, then this links against the shared version of libstdc++. That is normally fine. However, it is sometimes useful to freeze the version of libstdc++ used by the program without going all the way to a fully static link. The -static-libstdc++ option directs the g++ driver to link libstdc++ statically, without necessarily linking other libraries statically.
'lstdc++'是gcc和g++都能识别,但是'-static-libstdc++'只有g++可以识别,而我的业务代码都是使用C语言编写的,在链接时cmake默认使用的是gcc,但是gcc不能识别'-static-libstdc++',最终不会链接到实际的libstdc++.a,所以在链接时出现不能识别std
的问题;
知道原因了,就很好解决了,在链接阶段将cmake的链接选项改为g++即可,添加如下一行就可以正常链接成功;
set_target_properties(${target} PROPERTIES LINKER_LANGUAGE CXX)