问题
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:
- I downloaded boost_1_72_0.tar.gz and
tar xzvf boost_1_72_0.tar.gz
inside third_party directory. cd
inside boost_1_72_0.DST_DIR=/my local path/
where I want to install../bootstrap.sh --prefix=${DST_DIR} --includedir=${DST_DIR} --libdir={DST_DIR} --with-libraries=filesystem,system
../b2 link=static --prefix=${DST_DIR} install --
which creates include and lib directories insideDST_DIR
- Inside my build directory I am doing CMake where my CMakeLists.txt is present.
- The CMake command works fine.
- 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