CMakeLists.txt 里写了:
target_link_libraries(${PROJECT_NAME} PRIVATEgccstdc++
)
target_link_options(${PROJECT_NAME} PRIVATE -static-libstdc++)
看起来像是“链接了两次 C++ 标准库”,其实它们的作用完全不同:
1. target_link_libraries(... stdc++)
- 作用:显式把
libstdc++.a
或libstdc++.so
链接进目标文件。 - 这会让链接器去找
-lstdc++
,即 C++ 标准库。 - 如果用 C++ 源码,通常编译器会自动加上,但有些交叉编译/特殊场景需要你手动加。
2. target_link_options(... -static-libstdc++)
- 作用:告诉编译器/链接器“用静态方式链接 C++ 标准库”,即强制用
libstdc++.a
而不是libstdc++.so
。 - 这是 GCC 的一个特殊选项,等价于命令行
-static-libstdc++
。 - 它不是链接库,而是改变链接方式。
为什么要两个都写?
- 只写
stdc++
:链接器会找 C++ 标准库,但可能用动态库(.so)也可能用静态库(.a),取决于默认设置。 - 只写
-static-libstdc++
:如果你的工程里没有任何 C++ 源文件,链接器可能不会自动加 C++ 标准库,导致链接失败。 - 都写:最保险,既确保链接 C++ 标准库,又确保用静态方式。
总结
target_link_libraries(... stdc++)
:确保链接 C++ 标准库target_link_options(... -static-libstdc++)
:确保用静态方式链接 C++ 标准库
这两句不是重复,而是配合使用,保证你的嵌入式/交叉编译工程在所有场景下都能正确、静态地链接 C++ 标准库。
如需进一步精简或自动判断是否需要 stdc++
,可以用 CMake 的条件判断,但大多数嵌入式项目这样写最稳妥。