Повышение 1.57 файловой системы / ошибка компоновщика системы с gcc 4.9.2

Я строю библиотеку API и использую ее как общую для проекта unittest. API делает некоторые звонки следующим образом

#include <boost/filesystem.hpp>

void LoadResources(const std::string& dataPath)
{
    boost::filesystem::path path(dataPath);
    boost::filesystem::path file("test.txt");
    boost::filesystem::path canonical = boost::filesystem::canonical(dataPath / file);

    if (boost::filesystem::exists(canonical)) {
         ...
    }
}

Тогда модульный тест просто вызывает эту функцию, но я не могу построить ее из-за ошибки компоновщика

/home/ubuntu/tonkatsu/lib/libdominion.so: undefined reference to `boost::filesystem::detail::canonical(boost::filesystem::path const&, boost::filesystem::path const&, boost::system::error_code*)'
/home/ubuntu/tonkatsu/lib/libdominion.so: undefined reference to `boost::filesystem::detail::current_path(boost::system::error_code*)'
/home/ubuntu/tonkatsu/lib/libdominion.so: undefined reference to `boost::system::system_category()'
/home/ubuntu/tonkatsu/lib/libdominion.so: undefined reference to `boost::filesystem::detail::status(boost::filesystem::path const&, boost::system::error_code*)'
/home/ubuntu/tonkatsu/lib/libdominion.so: undefined reference to `boost::system::generic_category()'
/home/ubuntu/tonkatsu/lib/libdominion.so: undefined reference to `boost::filesystem::path::operator/=(boost::filesystem::path const&)'
collect2: error: ld returned 1 exit status

Но мой CMakeList.txt правильно настроен с

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++14")
find_package(Boost COMPONENTS system filesystem log thread unit_test_framework REQUIRED)
...
target_link_libraries(unittest ${Boost_LIBRARIES} dominion)

И сделать VERBOSE=1 тоже правильно

/usr/bin/c++    -Wall -std=c++14    CMakeFiles/unittest.dir/home/ubuntu/tonkatsu/src/unittest/main.cpp.o CMakeFiles/unittest.dir/home/ubuntu/tonkatsu/src/unittest/dominion/api.cpp.o CMakeFiles/unittest.dir/home/ubuntu/tonkatsu/src/unittest/dominion/attributes.cpp.o CMakeFiles/unittest.dir/home/ubuntu/tonkatsu/src/unittest/dominion/dice.cpp.o CMakeFiles/unittest.dir/home/ubuntu/tonkatsu/src/unittest/lib/minicsv.cpp.o  -o /home/ubuntu/tonkatsu/bin/unittest -rdynamic /usr/local/lib/libboost_system.so /usr/local/lib/libboost_filesystem.so /usr/local/lib/libboost_log.so /usr/local/lib/libboost_thread.so /usr/local/lib/libboost_unit_test_framework.so -lpthread /home/ubuntu/tonkatsu/lib/libdominion.so -Wl,-rpath,/usr/local/lib:/home/ubuntu/tonkatsu/lib

У меня не было никаких проблем, прежде чем я начал использовать boost::filesystem. Это хорошо работает с VS2013, но на Linux с использованием GCC 4.9.2 я не могу понять, почему. Сначала я подумал, что, может быть, версия Boost была неправильной (Ubuntu предоставляет только 1,55, а я использовал 1,57 на Windows), поэтому я тоже построил 1,57 на Linux, но ошибка все еще была. Существует также ошибка повышения, связанная с C++11, но она была исправлена ​​с 1,57

Я посмотрел похожие вопросы по этому вопросу, но люди в большинстве случаев забывали ссылаться на boost_system, а я нет.

1 ответ

Решение

Ubuntu неявно проходит --as-needed компоновщику. Это приводит к тому, что порядок библиотек имеет значение даже для разделяемых библиотек: если библиотека не используется каким-либо объектом, перечисленным перед ней в командной строке, она отбрасывается. список dominion до повышения в target_link_libraries скорее всего поможет.

Другие вопросы по тегам