【问题标题】:Can't link program using Boost.Filesystem无法使用 Boost.Filesystem 链接程序
【发布时间】:2013-03-16 01:46:29
【问题描述】:

我正在尝试运行程序,在 Ubuntu 12.10 上使用 boost::filesystem 的示例代码,但它不想构建。

#include <iostream>
#include <boost/filesystem.hpp>
using namespace boost::filesystem;
using namespace std;

void fun(const string& dirPath);
int main()
{
    fun("/home");
    return 0;
}

void fun(const string& dirPath)
{
    path p (dirPath); 

    if (exists(p))  
    {
        if (is_regular_file(p))   
            cout << p << " size is " << file_size(p) << '\n';

        else if (is_directory(p))    
            cout << p << "is a directory\n";

        else
            cout << p << "exists, but is neither a regular file nor a directory\n";
    }
    else
        cout << p << "does not exist\n";
}

以及 CMake 代码:

project(tttest)
cmake_minimum_required(VERSION 2.8)
aux_source_directory(. SRC_LIST)
add_executable(${PROJECT_NAME} ${SRC_LIST})
FIND_PACKAGE(Boost 1.53 COMPONENTS filesystem system REQUIRED)
include_directories(${Boost_INCLUDE_DIR})
link_directories(${Boost_LIBRARY_DIR})
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${Boost_LIBRARIES})

不幸的是它会产生错误

CMakeFiles/tttest.dir/main.cpp.o: In function `boost::filesystem::exists(boost::filesystem::path const&)':
main.cpp:(.text._ZN5boost10filesystem6existsERKNS0_4pathE[_ZN5boost10filesystem6existsERKNS0_4pathE]+0x19): undefined reference to `boost::filesystem::detail::status(boost::filesystem::path const&, boost::system::error_code*)'
CMakeFiles/tttest.dir/main.cpp.o: In function `boost::filesystem::is_directory(boost::filesystem::path const&)':
main.cpp:(.text._ZN5boost10filesystem12is_directoryERKNS0_4pathE[_ZN5boost10filesystem12is_directoryERKNS0_4pathE]+0x19): undefined reference to `boost::filesystem::detail::status(boost::filesystem::path const&, boost::system::error_code*)'
CMakeFiles/tttest.dir/main.cpp.o: In function `boost::filesystem::is_regular_file(boost::filesystem::path const&)':
main.cpp:(.text._ZN5boost10filesystem15is_regular_fileERKNS0_4pathE[_ZN5boost10filesystem15is_regular_fileERKNS0_4pathE]+0x19): undefined reference to `boost::filesystem::detail::status(boost::filesystem::path const&, boost::system::error_code*)'
CMakeFiles/tttest.dir/main.cpp.o: In function `boost::filesystem::file_size(boost::filesystem::path const&)':
main.cpp:(.text._ZN5boost10filesystem9file_sizeERKNS0_4pathE[_ZN5boost10filesystem9file_sizeERKNS0_4pathE]+0x19): undefined reference to `boost::filesystem::detail::file_size(boost::filesystem::path const&, boost::system::error_code*)'
collect2: error: ld returned 1 exit status

这个问题的原因是什么,如何解决?

【问题讨论】:

  • 尝试使用自动检测到的 boost 版本进行构建:FIND_PACKAGE(Boost COMPONENTS filesystem system REQUIRED)
  • 我将 cmake 添加到标签中。这个问题似乎与 cmake 相关。
  • 你的 CMake 版本能识别 boost 1.53 吗?您可能希望打印出 CMakeLists.txt 中包含的 ${Boost_LIBRARIES} 内容,以更好地了解正在发生的事情。 MESSAGE(status ${Boost_LIBRARIES}) 应该这样做。
  • 你能设置选择的答案吗?

标签: c++ boost cmake


【解决方案1】:

Boost 文件系统是 Boost 库之一,由于 C++0x 或 C++11 导致函数签名更改存在一些 ABI 问题。 cf Boost 票:https://svn.boost.org/trac/boost/ticket/6779

你有三个解决方案:

  1. 使用#include(参见http://www.ridgesolutions.ie/index.php/2013/05/30/boost-link-error-undefined-reference-to-boostfilesystemdetailcopy_file/)在您的程序中包含的相关Boost 头文件中禁止C++11 范围的枚举:

    #define BOOST_NO_CXX11_SCOPED_ENUMS
    #include <boost/filesystem.hpp>
    #undef BOOST_NO_CXX11_SCOPED_ENUMS
    

    但是这个解决方案不是一个完整的解决方案,我读到它并不适合所有人。

  2. 使用 C++11 选项构建 BOOST(与您用于应用程序的选项相同):http://hnrkptrsn.github.io/2013/02/26/c11-and-boost-setup-guide

    我也读过它并不适合所有人。

  3. 设置专用于您的应用程序的交叉编译器,您可以在专用环境中重建您需要的所有库。这确保了连贯性、稳定性以及更多的可维护性,当然是值得推荐的解决方案。 我还没有读过它是否已经过测试-可能是的,而且可能有效。无论如何,交叉编译现在在计算机科学中得到了很好的掌握。你会发现很多很好的教程和支持。在 Linux Gentoo 中,他们有很棒的 sys-devel/crossdev 包,这使它非常容易。

在我自己的情况下,解决方案 1 解决了问题。遇到另一个我就切换到方案3。所以,我还没有测试过。

【讨论】:

  • 如果您使用低于 1.51 的 libboost,只需在上面进行一项改进,需要使用 #define BOOST_NO_SCOPED_ENUMS #include "boost/filesystem.hpp" #undef BOOST_NO_SCOPED_ENUMS
  • 请注意,对于选项 1,all Boost 包含必须定义 BOOST_NO_CXX11_SCOPED_ENUMS,否则肯定会出现 ODR 违规。
【解决方案2】:

链接时需要添加 libboost_filesystem 库。或者 libboost_filesystem-mt 如果您的应用程序是多线程的。像这样:

g++ -o file -lboost_filesystem-mt source_file.cpp

【讨论】:

  • 如果你使用的是 CMake,那就是 target_link_libraries (my_executable ${Boost_LIBRARIES})
【解决方案3】:

对我有用的解决方案是使用“-c”进行编译,然后像这样创建可执行文件:

g++ -c -o main.o main.cpp
g++ -o my_prog main.o -lboost_system -lboost_filesystem

【讨论】:

    【解决方案4】:

    对于某些 boost 模块,您必须编译库链接它们(使用 bootstrap.sh)。 在你的情况下,你必须编译和链接Filesystem,也可能是System

    看看here

    例如:

    • ./bootstrap.sh (bjam)
    • rm -rf bin.v2 阶段(在 2 个 bjam 命令之间)
    • ./bjam 发布工具集=gcc address-model=64 cxxflags=-fPIC
    • ./bjam 调试工具集=gcc address-model=64 cxxflags=-fPIC

    如果您在 Windows 上进行链接,则不必手动链接您的库,因为它们是使用 pragma 自动链接的。在 Linux 上,您必须这样做。

    根据文档,这些模块需要你获取或构建一个库:

    • Boost.文件系统
    • Boost.GraphParallel
    • Boost.IOStreams
    • Boost.MPI
    • Boost.ProgramOptions
    • Boost.Python
    • Boost.Regex
    • Boost.序列化
    • Boost.Signals
    • Boost.System
    • Boost.Thread
    • Boost.Wave

    【讨论】:

    • 这是在 linux 上,我希望 boost 会通过 ubuntu 中的包管理器安装。
    【解决方案5】:

    您需要添加以下库:

    g++ -o file -lboost_system -lboost_filesystem sourcefile.cpp
    

    如果您使用 Makefile:

    CC=gcc
    CXX=g++
    PROG = program
    CXXFLAGS := -std=c++1y -g -Wall
    LDFLAGS = -L/usr/local/lib -L/usr/lib/x86_64-linux-gnu
    LIBS= -lboost_system -lboost_filesystem
    
    SRCS= main.cpp
    
    OBJS=$(subst .cpp,.o,$(SRCS))
    
    all: $(OBJS)
         $(CXX) $(CXXFLAGS) -o $(PROG) $(OBJS) $(LIBS) $(LDFLAGS)
    

    【讨论】:

      猜你喜欢
      • 2015-08-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-12
      • 2021-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多