Неопределенная ссылка на символ » … Ошибка добавления символов: DSO отсутствует в командной строке (с CMake)

#c #linux #cmake

#c #linux #cmake

Вопрос:

Краткий обзор проблемы:

Я пишу проект и смог получить написанный мной код (на данный момент) для компиляции, поэтому я подумал, что мне следует начать писать пример исполняемого файла, чтобы убедиться, что все работает так, как я задумал. Я новичок в 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 , но, честно говоря, на данный момент я понятия не имею.) Я немного покопался в Интернете и попробовал кое-что из других сообщений, т. Е. переместил библиотеку, чтобы убедиться, что libsconfigurator-libs библиотека создавалась перед добавлением исполняемого файла в CMake, проверил, действительно ли я включал 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:

Вам следует попробовать изменить этот вызов на 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 ) не являются частью интерфейса link. Таким образом, целевые объекты CMake (например, ваш исполняемый файл) не будут иметь видимости этих библиотек и их определений. С помощью PUBLIC перечисленные библиотеки добавляются в интерфейс link, поэтому ваш исполняемый файл oneLinkAdaptive использует их также, когда вы ссылаетесь cfucr-libs на него.

Я рекомендую вам ознакомиться с target_link_libraries документацией, особенно с разделом, описывающим различия между ключевыми словами области видимости (т.Е. PUBLIC , PRIVATE и т.д.).

Комментарии:

1. Обновлено, чтобы сделать это PUBLIC внутри библиотеки! Я пробовал это раньше, но когда я это сделал, я получил кучу неопределенных ссылок, поэтому я подумал, что делаю все хуже. Спасибо за ясность! Я попытаюсь посмотреть, смогу ли я исправить эти неопределенные ссылки!