簡體   English   中英

強制target_link_libraries使用c ++鏈接器

[英]force target_link_libraries to use c++ linker

TL; DR

有沒有辦法強制cmake在將靜態c ++庫鏈接到ac可執行文件時使用c ++鏈接器?


我有一個靜態庫,包含2個對象,一個C ++文件和該文件中函數的C包裝器(構造函數,析構函數和打印函數),類似於這個 SO答案。 最后一段說明:

現在,有趣的部分是確保您正確地將所有必需的C ++庫鏈接到更大的庫中。 對於gcc(或clang),這意味着只使用g ++進行最后的鏈接階段。

我可以用我的MCVE驗證這一點。 g++替換gcc可以解決問題並且一切正常

$ gcc -static main.c -L. -lCPPclass -o main
./libCPPclass.a(CInt.o): In function `newCINT':
CInt.cpp:(.text+0xd): undefined reference to `operator new(unsigned long)'
CInt.cpp:(.text+0x28): undefined reference to `operator delete(void*)'
./libCPPclass.a(CInt.o): In function `delCINT':
CInt.cpp:(.text+0x5e): undefined reference to `operator delete(void*)'
./libCPPclass.a(CInt.o):(.eh_frame+0x13): undefined reference to `__gxx_personality_v0'
./libCPPclass.a(CPPclass.o): In function `CPPclass::print_success()':
CPPclass.cpp:(.text+0x26): undefined reference to `std::cout'
CPPclass.cpp:(.text+0x2b): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)'
./libCPPclass.a(CPPclass.o): In function `__static_initialization_and_destruction_0(int, int)':
CPPclass.cpp:(.text+0x54): undefined reference to `std::ios_base::Init::Init()'
CPPclass.cpp:(.text+0x63): undefined reference to `std::ios_base::Init::~Init()'
collect2: error: ld returned 1 exit status
$
$#REPLACE gcc with g++
$
$ g++ -static main.c -L. -lCPPclass -o main
$ ./main
Success!

然而,我的真實代碼是使用CMake構建的,所以我試圖用CMake構建這個MCVE,這讓我回到原來的問題。 我的CMakeLists.txt文件如下:

cmake_minimum_required(VERSION 2.8)
project(Cmain C CXX)

add_library(CPPclass STATIC IMPORTED)
set_property(TARGET CPPclass PROPERTY IMPORTED_LOCATION ./libCPPclass.a)
add_executable(main main.c)
target_link_libraries(main CPPclass)

但是,當我運行cmake . 然后make我得到與上面相同的錯誤

$ cmake .
-- Configuring done
-- Generating done
-- Build files have been written to: /home/me/temp
$ make
Linking C executable main
./libCPPclass.a(CInt.o): In function `newCINT':
CInt.cpp:(.text+0xd): undefined reference to `operator new(unsigned long)'
CInt.cpp:(.text+0x28): undefined reference to `operator delete(void*)'

當然,如果我將main.c重命名為main.cpp ,CMake將使用g ++編譯可執行文件,target_link_libraries將無錯誤地執行,但它有點挫敗了c包裝器的用途,並且在我的實際用例中不起作用。

在目標上將鏈接器語言設置為CXX

set_target_properties(my_target PROPERTIES LINKER_LANGUAGE CXX)

我認為這比stdc++答案更好,因為它是通用的(我目前正在處理clang的libc ++)。 它可能不會比IMPORTED_LINK_INTERFACE_LANGUAGES答案更好,但它肯定更直接。

做這個:

set_target_properties(CPPclass PROPERTIES
  IMPORTED_LOCATION ./libCPPclass.a
  IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
)

正如@BillyONeal在上面的評論中提到的,我不需要一個不同的鏈接器來獲得所需的額外庫,我只需要將libstdc ++添加到要鏈接的庫列表中。

cmake_minimum_required(VERSION 2.8)
project(Cmain C CXX)

add_library(CPPclass STATIC IMPORTED)
set_property(TARGET CPPclass PROPERTY IMPORTED_LOCATION ./libCPPclass.a)
add_executable(main main.c)
target_link_libraries(main CPPclass stdc++)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM