Linking Boost - неопределенная ссылка на `boost :: serialization :: singleton_module :: get_lock () ' - PullRequest
0 голосов
/ 06 сентября 2018

У меня есть собственная библиотека mylib, которая использует библиотеку Boost для сериализации и динамически связывает ее. Теперь я хочу связать свою библиотеку с другим кодом - команда выглядит так:

/usr/bin/g++-8   -Wall -g  -rdynamic CMakeFiles/net_test_ode_1.dir/net_test_ode_1.cpp.o  -o ../bin/examples/net_test_ode_1 -Wl,-rpath,/home/martin/MyLib/build/lib:/home/martin/MyLib/external_dependencies/boost/stage/lib ../lib/libmylib.so ../../external_dependencies/boost/stage/lib/libboost_system.so ../../external_dependencies/boost/stage/lib/libboost_serialization.so ../../external_dependencies/boost/stage/lib/libboost_random.so 
../lib/libmylib.so: undefined reference to `boost::serialization::singleton_module::get_lock()'
collect2: error: ld returned 1 exit status

Как видите, я связываю не только libmylib.so, но и libboost_serialization.so, поэтому не должно быть никаких отсутствующих зависимостей.

Тем не менее, я получаю эту неопределенную ошибку ссылки. Это еще более запутанно, потому что я уже связал это со своей библиотекой, поэтому здесь это не нужно, если я правильно понимаю.

Знаете, что я делаю не так?


CMakeLists.txt - моя библиотека

if ("${BUILD_LIB}" STREQUAL "yes")
    add_library(mylib SHARED
        source codes...       
    )

    set_target_properties(
        mylib

        PROPERTIES
            INCLUDE_DIRECTORIES "${ROOT_DIR}/include;${SRC_DIR};${Boost_INCLUDE_DIRS}"
            LINK_LIBRARIES "${BOOST_LIBRARIES}"
            ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib"
            LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib"
            RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin"
    )

CMakeLists.txt - мой исполняемый файл

add_executable(net_test_1 net_test_1.cpp)

set_target_properties(
    net_test_1

    PROPERTIES
        INCLUDE_DIRECTORIES "${ROOT_DIR}/include"
        LINK_LIBRARIES "mylib;${BOOST_LIBRARIES}"
        ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib/"
        LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib"
        RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/examples"
)

EDIT:

Согласно комментарию компора, я добавил

target_link_libraries(mylib PUBLIC ${BOOST_LIBRARIES})

в CMakeLists с моей библиотекой и

target_link_libraries(net_test_1 PUBLIC mylib)

в CMakeLists с моим исполняемым файлом.

Я также удалил строку с LINK_LIBRARIES из set_target_properties(), но, к сожалению, это ничего не меняет, и проблема все еще сохраняется.


РЕДАКТИРОВАТЬ 2:

Я пытался использовать -rpath-link согласно комментарию ChrisD, но результат все тот же

/usr/bin/g++   -Wall -g  -rdynamic CMakeFiles/net_test_ode_1.dir/net_test_ode_1.cpp.o  -o ../bin/examples/net_test_ode_1 -Wl,-rpath-link=/home/martin/MyLibRepo/external_dependencies/boost/stage/lib ../lib/libmylib.so ../../external_dependencies/boost/stage/lib/libboost_system.so ../../external_dependencies/boost/stage/lib/libboost_serialization.so ../../external_dependencies/boost/stage/lib/libboost_random.so
../lib/libmylib.so: undefined reference to `boost::serialization::singleton_module::get_lock()'

Я обнаружил, что когда я добавляю -lboost_serialization к команде компиляции, она работает без ошибок. Как это возможно? Я думал, что добавления ../../external_dependencies/boost/stage/lib/libboost_serialization.so к команде достаточно, поскольку это указывает на правильную библиотеку.

1 Ответ

0 голосов
/ 07 сентября 2018

Итак, я создал минимальный проект Boost, в котором используется библиотека сериализации.

Структура проекта:

.
├── app
│   ├── app.cpp
│   └── CMakeLists.txt
├── CMakeLists.txt
└── mylib
    ├── CMakeLists.txt
    ├── mylib.cpp
    └── mylib.hpp

Приложение / CMakeLists.txt:

add_executable(app app.cpp)
target_include_directories(app PUBLIC mylib)
target_link_libraries(app PUBLIC mylib)

MyLib / CMakeLists.txt:

add_library(mylib mylib.cpp)

target_include_directories(mylib PUBLIC 
  ${CMAKE_CURRENT_SOURCE_DIR}
  ${Boost_INCLUDE_DIRS})

target_link_libraries(mylib PUBLIC ${Boost_LIBRARIES})

main CMakeLists.txt:

cmake_minimum_required(VERSION 3.11)

project(ser CXX)

find_package(Boost COMPONENTS serialization REQUIRED)

add_subdirectory(app)
add_subdirectory(mylib)

Я считаю, что вам нужно использовать переменные, установленные find_package, так как они приобретаются способом, который соответствует установке вашей системы. Вы всегда можете пройти через doc и повлиять на любой аспект, который вам требуется.

...