【问题标题】:Static linking with Boost Filesystem not working与 Boost 文件系统的静态链接不起作用
【发布时间】:2020-02-25 13:31:39
【问题描述】:

我正在尝试从源代码构建 boost,我需要静态链接,因为我正在考虑将这个静态链接的 boost 项目移动到 AWS lambda 服务器。

我做了以下步骤:

  1. 我在第三方目录中下载了 boost_1_72_0.tar.gz 和 tar xzvf boost_1_72_0.tar.gz
  2. cd 在 boost_1_72_0 内。
  3. DST_DIR=/my local path/ 我想安装的地方。
  4. ./bootstrap.sh --prefix=${DST_DIR} --includedir=${DST_DIR} --libdir={DST_DIR} --with-libraries=filesystem,system
  5. ./b2 link=static --prefix=${DST_DIR} install --DST_DIR 中创建包含和库目录
  6. 在我的构建目录中,我在 CMakeLists.txt 所在的位置进行 CMake。
  7. CMake 命令运行良好。
  8. 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? 和其他答案,但似乎不适用于我的情况。

【问题讨论】:

  • 你使用的是什么版本的 CMake?
  • cmake 版本 3.16.3

标签: c++ boost cmake linker-errors


【解决方案1】:

您似乎在为 Boost 使用旧的 CMake 变量。从 Boost 1.70 开始,Boost 现在提供 CMake 支持,以便 CMake 更轻松地为您的项目查找和使用 Boost(请参阅this 页面上的文档)。

当您构建 Boost 时,您将看到每个 Boost 库的 CMake 包配置文件(通常与构建的库一起放置在 cmake 文件夹中)。您可以在CONFIG 模式下使用find_package() 找到这些包配置文件。这些提供了导入的 目标,例如您可以直接链接到的Boost::filesystem。这样,如果缺少filesystem 库,您不必在编译/链接失败时筛选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 以查看链接阶段的详细输出,以验证所有正确的库都被链接。您应该能够看到 Boost 的 filesystemsystem 库已链接,并且您可以验证它们是所需的静态 (.a) 库。

【讨论】:

  • 但我已经在使用 cmake 的最新版本和 Boost 1.72。此外,当我打印 Boost 库变量时,会打印出:third_party/boost_1_72_0/lib/libboost_filesystem.a;third_party/boost_1_72_0/lib/libboost_system.a,我认为这是正确的。问题似乎出在使用 make 编译时。
  • target_link_libraries(executable PRIVATE Boost::filesystem) 而不是 target_link_libraries(executable ${BOOST_LIBRARIES}) 成功了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多