未定义符号'<Symbol>'的引用...添加符号时出错:命令行缺少DSO(使用CMake)

3

问题简述:

我正在编写一个项目,并且已经成功编译了我写的代码(到目前为止),所以我想,我应该开始编写一个示例可执行文件,以确保一切都按照我的意愿工作。我是C++的新手,CMake更是一个蒟蒻(所以如果代码看起来不好,请原谅)。在创建可执行文件的基础之后,我决定运行make,但结果出现了错误:

/usr/bin/ld: CMakeFiles/oneLinkAdaptive.dir/oneLinkAdaptiveExample.cpp.o: undefined reference to symbol '_ZN5robot12configurator16initializeParamsEPKc'
/usr/bin/ld: //home/pi/Desktop/cfucr/build/src/configurator/libconfigurator-libs.so: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
make[2]: *** [src/examples/CMakeFiles/oneLinkAdaptive.dir/build.make:86: src/examples/oneLinkAdaptive] Error 1
make[1]: *** [CMakeFiles/Makefile2:46987: src/examples/CMakeFiles/oneLinkAdaptive.dir/all] Error 2
make: *** [Makefile:130: all] Error 2

据我了解,这实际上是一个CMake错误,我可能未能添加库或者我的C++代码中未能找到某个函数。

namespace robot
{
namespace configurator
{

std::tuple<ParamsR, ParamsF, ParamsC> initializeParams(const char* configFile);
...

我不太倾向于相信C++代码有问题,但说实话,我现在一点也不清楚。我在网上翻了一些帖子并尝试了一些方法,例如移动库以确保在将可执行文件添加到CMake之前创建libsconfigurator-libs库,在确保我实际包含libsconfigurator-libs库时进行检查,将东西从PRIVATE更改为PUBLIC等。

主要的src CMake文件编写如下:

# Add controller main files #
add_library(cfucr-libs
  controller.cpp
  controller.hpp
)

# Add the `src` directory to be included #
set(CFUCR_BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR})

include_directories(
  ${CFUCR_BASE_DIR}
)

# Add a list of subdirectories #
add_subdirectory(configurator)
add_subdirectory(control)
add_subdirectory(filter)
add_subdirectory(mathUtilities)
add_subdirectory(thirdParty)
add_subdirectory(types)

target_link_libraries(cfucr-libs PRIVATE
  configurator-libs
  control-libs
  filter-libs
  math-utilities-libs
  type-libs
  tinyxml2
  eigen
)

add_subdirectory(examples)

可执行文件位于 examples 子目录下,所以我将 add_subdirectory 移到文件底部。这样,我就可以确保将我创建的所有其他库添加到主要的 cfucr 库中。 examples CMake 文件的编写如下:
# Add controller example main files #
add_library(examples-libs
  oneLinkAdaptiveExample.cpp
)

# Make executable files for controller examples #
add_executable(oneLinkAdaptive
  oneLinkAdaptiveExample.cpp
)

target_link_libraries(oneLinkAdaptive PRIVATE
  cfucr-libs
  examples-libs
)

基本上,只需创建可执行文件并将主要库添加到其中即可。 配置器库非常简单,并提供如下:

# Add configurator files #
add_library(configurator-libs
  configurator.cpp
  configurator.hpp
)

我已经尝试修复了一段时间,但似乎没有任何作用。我不完全理解所有这些是如何运作的,因此无法自己解决问题。如果有人对我可能做错的事情有任何想法,我很愿意听取意见。此外,如果我需要发布其他内容(任何更多的CMake文件或源文件)以帮助澄清问题,请告诉我,我会发布它们!
谢谢!
1个回答

3
你应该尝试将此调用改为target_link_libraries
target_link_libraries(cfucr-libs PRIVATE
  configurator-libs
  control-libs
  filter-libs
  math-utilities-libs
  type-libs
  tinyxml2
  eigen
)

使用PUBLIC代替:

target_link_libraries(cfucr-libs PUBLIC
  configurator-libs
  control-libs
  filter-libs
  math-utilities-libs
  type-libs
  tinyxml2
  eigen
)

使用PRIVATE关键字,列出的库(例如configurator-libs)不会成为链接接口的一部分。因此,消费CMake目标(例如您的可执行文件)将无法看到这些库及其定义。使用PUBLIC关键字,列出的库将被添加到链接接口中,因此当您将cfucr-libs链接到可执行文件oneLinkAdaptive时,它也将使用这些库。
我鼓励您仔细阅读target_link_libraries文档,特别是描述作用域关键字(即PUBLICPRIVATE等)差异的链接部分。

更新后,库内部有了PUBLIC!我之前尝试过这样做,但是当我这样做时,出现了许多未定义的引用,所以我认为我正在使情况变得更糟。感谢您的明确解释!我将尝试看看是否可以修复这些未定义的引用! - michaelR

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接