与 Boost 文件系统的静态链接不起作用
Static linking with Boost Filesystem not working
我正在尝试从源构建 boost,我需要静态链接,因为我正在考虑将这个静态链接的 boost 项目移动到 AWS lambda 服务器。
我已经完成了以下步骤:
- 我在 third_party 目录中下载了 boost_1_72_0.tar.gz 和
tar xzvf boost_1_72_0.tar.gz
。
cd
里面 boost_1_72_0。
DST_DIR=/my local path/
我要安装的地方。
./bootstrap.sh --prefix=${DST_DIR} --includedir=${DST_DIR} --libdir={DST_DIR} --with-libraries=filesystem,system
.
./b2 link=static --prefix=${DST_DIR} install --
在 DST_DIR
中创建 include 和 lib 目录
- 在我的构建目录中,我正在执行我的 CMakeLists.txt 所在的 CMake。
- CMake 命令工作正常。
- 但是
make
命令报错
这是我的 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;
}
我得到的错误是:
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
我是 C++ 和 CMake 的新手。有什么愚蠢的,我在这里想念的吗?
我查看了 How can I get CMake to find my alternative Boost installation? 和其他答案,但似乎对我的情况不起作用。
您似乎在为 Boost 使用旧的 CMake 变量。从 Boost 1.70 开始,Boost 现在提供 CMake 支持,使 CMake 更容易为您的项目找到和使用 Boost(请参阅 this 页面上的文档)。
构建 Boost 时,您会看到每个 Boost 库的 CMake 包配置文件(通常与构建的库一起放在 cmake
文件夹中)。您可以使用 find_package()
in CONFIG
模式来查找这些软件包配置文件。这些提供 导入的 目标,例如 Boost::filesystem
,您可以 link 直接访问它们。这样,如果缺少 filesystem
库,当 compilation/linking 失败时,您不必筛选 BOOST_LIBRARIES
变量中的库列表。相反,CMake 会在 CMake 配置时告诉您库丢失。
此外,Boost 库依赖项现在应该会自动解析。因此,如果您正在使用 filesystem
,您应该不再需要显式调用 system
库。 Boost 应该为您解决这种依赖性。通过这些更改,您的 find_package()
命令用法可能如下所示:
find_package(Boost CONFIG REQUIRED filesystem)
if(Boost_FOUND)
add_executable(${PROJECT_NAME} "execute_code.cpp")
target_link_libraries(executable PRIVATE Boost::filesystem)
endif()
对于它的价值,您可以 运行 make VERBOSE=1
查看 link 阶段的详细输出,以 验证 所有link 编辑了正确的库。您应该能够看到 Boost 的 filesystem
和 system
库是 linked,并且您可以验证它们是所需的静态 (.a
) 库。
我正在尝试从源构建 boost,我需要静态链接,因为我正在考虑将这个静态链接的 boost 项目移动到 AWS lambda 服务器。
我已经完成了以下步骤:
- 我在 third_party 目录中下载了 boost_1_72_0.tar.gz 和
tar xzvf boost_1_72_0.tar.gz
。 cd
里面 boost_1_72_0。DST_DIR=/my local path/
我要安装的地方。./bootstrap.sh --prefix=${DST_DIR} --includedir=${DST_DIR} --libdir={DST_DIR} --with-libraries=filesystem,system
../b2 link=static --prefix=${DST_DIR} install --
在DST_DIR
中创建 include 和 lib 目录
- 在我的构建目录中,我正在执行我的 CMakeLists.txt 所在的 CMake。
- CMake 命令工作正常。
- 但是
make
命令报错
这是我的 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;
}
我得到的错误是:
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
我是 C++ 和 CMake 的新手。有什么愚蠢的,我在这里想念的吗?
我查看了 How can I get CMake to find my alternative Boost installation? 和其他答案,但似乎对我的情况不起作用。
您似乎在为 Boost 使用旧的 CMake 变量。从 Boost 1.70 开始,Boost 现在提供 CMake 支持,使 CMake 更容易为您的项目找到和使用 Boost(请参阅 this 页面上的文档)。
构建 Boost 时,您会看到每个 Boost 库的 CMake 包配置文件(通常与构建的库一起放在 cmake
文件夹中)。您可以使用 find_package()
in CONFIG
模式来查找这些软件包配置文件。这些提供 导入的 目标,例如 Boost::filesystem
,您可以 link 直接访问它们。这样,如果缺少 filesystem
库,当 compilation/linking 失败时,您不必筛选 BOOST_LIBRARIES
变量中的库列表。相反,CMake 会在 CMake 配置时告诉您库丢失。
此外,Boost 库依赖项现在应该会自动解析。因此,如果您正在使用 filesystem
,您应该不再需要显式调用 system
库。 Boost 应该为您解决这种依赖性。通过这些更改,您的 find_package()
命令用法可能如下所示:
find_package(Boost CONFIG REQUIRED filesystem)
if(Boost_FOUND)
add_executable(${PROJECT_NAME} "execute_code.cpp")
target_link_libraries(executable PRIVATE Boost::filesystem)
endif()
对于它的价值,您可以 运行 make VERBOSE=1
查看 link 阶段的详细输出,以 验证 所有link 编辑了正确的库。您应该能够看到 Boost 的 filesystem
和 system
库是 linked,并且您可以验证它们是所需的静态 (.a
) 库。