Static linking with Boost Filesystem not working

寵の児 提交于 2021-02-10 18:34:48

问题


I am trying to build boost from source and I need static linking as I am thinking to move this statically linked boost project to AWS lambda servers.

I have done the following steps:

  1. I downloaded boost_1_72_0.tar.gz and tar xzvf boost_1_72_0.tar.gz inside third_party directory.
  2. cd inside boost_1_72_0.
  3. DST_DIR=/my local path/ where I want to install.
  4. ./bootstrap.sh --prefix=${DST_DIR} --includedir=${DST_DIR} --libdir={DST_DIR} --with-libraries=filesystem,system.
  5. ./b2 link=static --prefix=${DST_DIR} install --which creates include and lib directories inside DST_DIR
  6. Inside my build directory I am doing CMake where my CMakeLists.txt is present.
  7. The CMake command works fine.
  8. But the make command gives an error.

Here is my CMakeLists.txt

cmake_minimum_required(VERSION 3.5)

set(CMAKE_CXX_STANDARD 11)
project(executable LANGUAGES CXX)

set(TARGET "/path to boost directory/boost_1_72_0")

set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)

SET(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
SET(BUILD_SHARED_LIBS OFF)
SET(CMAKE_EXE_LINKER_FLAGS "-static")

set(Boost_NO_SYSTEM_PATHS True)

message(STATUS "${Boost_NO_SYSTEM_PATHS}")
if (Boost_NO_SYSTEM_PATHS)
  set(BOOST_ROOT "${TARGET}")
  message(STATUS "${Boost_ROOT}")
  set(BOOST_INCLUDE_DIRS "${TARGET}/include/")
  set(BOOST_LIBRARY_DIRS "${TARGET}/lib/")
endif (Boost_NO_SYSTEM_PATHS)

message(STATUS "${BOOST_INCLUDE_DIRS}")
message(STATUS "boost library dirs")
message(STATUS "${BOOST_LIBRARY_DIRS}")
find_package(Boost REQUIRED filesystem system)
if(Boost_FOUND)      
    include_directories(${BOOST_INCLUDE_DIRS})
    add_executable(${PROJECT_NAME} "execute_code.cpp") 
    message(STATUS "boost libraries" "${BOOST_LIBRARIES}")
    target_link_libraries(executable ${BOOST_LIBRARIES})
endif()

execute_code.cpp

#include <boost/filesystem.hpp>
#include<iostream>

bool path_exists(string file_path)
{
    boost::filesystem::path p{file_path};
    return boost::filesystem::exists(p);
}

int main(int argc, char** argv) {
 string source_file = argv[1];
 if (!path_exists(source)) {
    cout << "source file doesn't exist";
    return 0;
 }
 return 0;
}

Error I am getting is:

CMakeFiles/executable.dir/execute_code.cpp.o: In function `boost::filesystem::exists(boost::filesystem::path const&)':
execute_code.cpp:(.text._ZN5boost10filesystem6existsERKNS0_4pathE[_ZN5boost10filesystem6existsERKNS0_4pathE]+0x2f): undefined reference to `boost::filesystem::detail::status(boost::filesystem::path const&, boost::system::error_code*)'
collect2: error: ld returned 1 exit status
CMakeFiles/executable.dir/build.make:113: recipe for target 'executable' failed
make[2]: *** [executable] Error 1
CMakeFiles/Makefile2:75: recipe for target 'CMakeFiles/executable.dir/all' failed
make[1]: *** [CMakeFiles/executable.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2

I am new to C++ and CMake. Is there anything silly, which I am missing here?

I went through How can I get CMake to find my alternative Boost installation? and other answers but doesn't seem to work in my case.


回答1:


You seem to be using the old CMake variables for Boost. As of Boost 1.70, Boost now provides CMake support to make it easier for CMake to find and use Boost for your project (see documentation on this page).

When you build Boost, you will see CMake package configuration files for each Boost library (typically placed along with the built libraries in a cmake folder). You can use find_package() in CONFIG mode to find these package configuration files. These provide imported targets such as Boost::filesystem that you can link to directly. This way, if the filesystem library is missing, you don't have to sift through the list of libraries in the BOOST_LIBRARIES variable when compilation/linking fails. Instead, CMake will tell you the library is missing at the CMake configure-time.

Also, the Boost library dependencies should now be resolved automatically. So, if you're using filesystem, you should no longer have to explicitly call out the system library also. Boost should resolve this dependency for you. With these changes, your find_package() command usage could look like this:

find_package(Boost CONFIG REQUIRED filesystem)
if(Boost_FOUND)
    add_executable(${PROJECT_NAME} "execute_code.cpp") 
    target_link_libraries(executable PRIVATE Boost::filesystem)
endif()

For what it's worth, you can run make VERBOSE=1 to see the verbose output at the link stage to verify that all the correct libraries are being linked. You should be able to see that Boost's filesystem and system libraries are linked, and you can verify they are the desired static (.a) libraries.



来源:https://stackoverflow.com/questions/60395828/static-linking-with-boost-filesystem-not-working

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!