Boost 1.57 filesystem/system linker error with gcc 4.9.2

1.2k views Asked by At

I am building an api library and use it as shared for the unittest project. The api is doing some calls the following way

#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)) {
         ...
    }
}

Then the unit test is just calling that function but I cannot build it because of a linker error

/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

But my CMakeList.txt is properly setup with

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)

And make VERBOSE=1 is correct too

/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

I didn't have any problems before I started using boost::filesystem. This is working just fine with VS2013 but on linux using GCC 4.9.2 i can't seems to figure out why. I thought at first maybe the boost version was wrong (ubuntu only provides 1.55 and I was using 1.57 on windows) so I built 1.57 on linux too but the error was still there. There is also that boost bug related to c++11 but it was fixed with 1.57

I have looked the similar questions on the subject but people were mostly forgetting to link to boost_system and I don't.

1

There are 1 answers

0
Marc Glisse On BEST ANSWER

Ubuntu implicitly passes --as-needed to the linker. This has the effect that the order of libraries matters, even for shared libraries: if a library is not used by any object listed before it on the command line, it is discarded. Listing dominion before boost in target_link_libraries is likely to help.