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 的條件判斷,但大多數嵌入式項目這樣寫最穩妥。