如何将一个 CMake 目标库中的函数定义传播到指向它的目标链接以解决未定义符号错误

问题描述 投票:0回答:1

我的项目结构是

project/
  lib/
      CMakeLists.txt
      lib.cpp
      lib.h
      sublib/
          CMakeLists.txt
          sublib.h
          sublib.cpp
  test/
      CMakeLists.txt
      test.cpp # this must link to lib only, not lib and sublib

项目/CMakeLists.txt

add_subdirectory(lib) 
add_subdirectory(test)

项目/测试/CMakeLists.txt

add_executable(test test.cpp)
add_test(test test)
target_link_libraries(
  test
  lib)

项目/lib/CMakeLists.txt

add_subdirectory(sublib)

add_library(lib lib.cpp)
target_link_libraries(
  lib
  sublib)

项目/lib/sublib/CMakeLists.txt

add_library(sublib sublib.cpp)
target_link_libraries(
  sublib
  some other libs like thrift)

在lib.cpp中

Lib::process() {
    Sublib::process();
}

在 sublib.cpp 中

void Sublib::process() {
...
}

我遇到了类似的错误

架构 x86_64 的未定义符号: “Sublib::process()”,参考自: lib.cpp.o 中的 Sublib::process() ld:未找到架构 x86_64

的符号

我的问题是,如何使

Sublib::process()
对目标测试可见,而不必像这样将其链接到子库?还有许多其他测试目标已经依赖于 lib 但不依赖于 sublib。

add_executable(test test.cpp)
add_test(test test)
target_link_libraries(
  test
  lib
  sublib)
c++ cmake build libraries
1个回答
0
投票

我认为发生

undefined symbol
错误是因为
test
目标无法直接查看
sublib
中定义的函数,即使
lib
链接到
sublib

您需要将
sublib
的链接接口传播到
lib
的链接接口,以便
test
可以通过
sublib
看到
lib
的符号。

target_link_libraries()

PUBLIC 中使用
INTERFACE
lib
CMakeLists.txt
关键字来指定
sublib
lib
公共接口的一部分。

# project/lib/CMakeLists.txt
add_subdirectory(sublib)

add_library(lib lib.cpp)
target_link_libraries(
  lib
  PUBLIC          # That is the key change
  sublib)

通过将

sublib
设置为
PUBLIC
lib
依赖项,您可以确保链接到
lib
的任何目标也将链接到
sublib
,这应该可以解决未定义符号错误。

© www.soinside.com 2019 - 2024. All rights reserved.