强制 target_link_libraries 使用 C++ 链接器

2024-04-12

TL;DR

将静态 c++ 库链接到 c 可执行文件时,有没有办法强制 cmake 使用 c++ 链接器?


我有一个静态库,由 2 个对象组成,一个 C++ 文件和一个该文件中函数的 C 包装器(构造函数、析构函数和打印函数),类似于this https://stackoverflow.com/a/2045860/3288829所以回答。最后一段指出:

现在有趣的部分是确保您将所有必需的 C++ 库正确链接到更大的库中。对于 gcc(或 clang),这意味着仅使用 g++ 执行最后的链接阶段。

我可以用我的 MCVE 验证这一点。更换gcc with g++解决问题,一切正常

$ 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 to main.cpp,CMake 将使用 g++ 编译可执行文件,并且 target_link_libraries 将执行而不会出现错误,但它有点违背了 c 包装器的目的,并且在我的实际用例中不起作用。


Do this:

set_target_properties(CPPclass PROPERTIES
  IMPORTED_LOCATION ./libCPPclass.a
  IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

强制 target_link_libraries 使用 C++ 链接器 的相关文章

随机推荐