2013-03-26 19 views
18

Tôi đang cố gắng chạy chương trình, sử dụng mã mẫu của tệp boost :: filesystem trên Ubuntu 12.10, nhưng nó không muốn xây dựng.Không thể liên kết chương trình bằng cách sử dụng 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"; 
} 

Và CMake mã:

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}) 

Đáng tiếc là nó tạo ra lỗi

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 

lý do của vấn đề này là gì và làm thế nào để giải quyết nó?

+2

cố gắng để xây dựng với phiên bản tăng tính năng tự động phát hiện: FIND_PACKAGE (Boost LINH KIỆN hệ thống tập tin YÊU CẦU) – podshumok

+0

Tôi đã thêm cmake vào các thẻ. Vấn đề này dường như liên quan đến cmake. – drescherjm

+1

Boost 1.53 có được nhận dạng bởi phiên bản CMake của bạn không? Bạn có thể muốn in ra những gì $ {Boost_LIBRARIES} chứa trong CMakeLists.txt của bạn để hiểu rõ hơn những gì đang xảy ra. MESSAGE (trạng thái $ {Boost_LIBRARIES}) nên làm điều đó. – drescherjm

Trả lời

1

Đối với một số mô-đun tăng, bạn phải biên dịch thư viện liên kết chúng (sử dụng bootstrap.sh). Trong trường hợp của bạn, bạn cần phải biên dịch và liên kết Filesystem, và probalbly System quá

Có một cái nhìn here

Ví dụ:

  • ./bootstrap.sh (bjam)
  • giai đoạn rm -rf bin.v2 (giữa 2 lệnh bjam)
  • ./bjam release toolset = gcc address-model = 64 cxxflags = -fPIC
  • ./bjam debug công cụ = gcc address-mô hình = 64 CXXFLAGS = -fPIC

Nếu bạn đang liên kết trên Windows, bạn không phải tự liên kết các thư viện của bạn, vì họ sẽ được tự động liên kết sử dụng pragma . Trên Linux, bạn phải làm điều đó.

Theo tài liệu, các mô-đun cần bạn hiểu rõ hoặc xây dựng một thư viện:

  • Boost.Filesystem
  • Boost.GraphParallel
  • Boost.IOStreams
  • Boost.MPI
  • Boost .ProgramOptions
  • Boost.Python
  • Boost.R egex
  • Boost.Serialization
  • Boost.Signals
  • Boost.System
  • Boost.Thread
  • Boost.Wave
+1

Đây là trên linux và tôi hy vọng tăng sẽ được cài đặt thông qua trình quản lý gói trong ubuntu. – drescherjm

22

Boost hệ thống tập tin là một trong những thư viện Boost rằng có một số vấn đề ABI liên quan đến thay đổi chữ ký hàm do C++ 0x hoặc C++ 11.cf vé Boost: https://svn.boost.org/trac/boost/ticket/6779

Bạn có ba giải pháp:

  1. ức chế C++ 11 scoped enums trong Boost có liên quan tập tin tiêu đề bao gồm trong chương trình của bạn với #include (cf http://www.ridgesolutions.ie/index.php/2013/05/30/boost-link-error-undefined-reference-to-boostfilesystemdetailcopy_file/):

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

    Nhưng giải pháp này không phải là một giải pháp hoàn chỉnh và tôi đọc nó không hoạt động cho tất cả mọi người.

  2. Build BOOST với các tùy chọn C++ 11 (các tùy chọn tương tự như bạn sử dụng cho các ứng dụng của bạn): http://hnrkptrsn.github.io/2013/02/26/c11-and-boost-setup-guide

    Tôi cũng đọc nó không làm việc cho tất cả mọi người.

  3. Thiết lập trình biên dịch chéo dành riêng cho ứng dụng của bạn nơi bạn xây dựng lại tất cả các thư viện bạn cần trong môi trường chuyên dụng. Điều đó đảm bảo sự gắn kết cộng với sự ổn định cộng thêm khả năng bảo trì, và chắc chắn là giải pháp để đề xuất. Tôi chưa đọc nếu nó đã được kiểm tra - có thể là có, và có lẽ nó hoạt động. Dù sao, việc biên dịch chéo cũng đã thành thạo trong khoa học máy tính. Bạn sẽ tìm thấy nhiều hướng dẫn và hỗ trợ tốt cho nó. Trong Gentoo Linux, chúng có gói sys-devel/crossdev tuyệt vời khiến nó trở nên rất dễ dàng.

Trong trường hợp của riêng tôi, giải pháp 1 đã giải quyết được sự cố. Ngay sau khi tôi gặp một số khác, tôi sẽ chuyển sang giải pháp 3. Vì vậy, tôi chưa thử nghiệm nó.

+0

Chỉ cần một sự cải tiến trong ở trên nếu bạn đang sử dụng libboost dưới 1,51 sử dụng cần phải sử dụng BOOST_NO_SCOPED_ENUMS #define #include "tăng/filesystem.hpp" BOOST_NO_SCOPED_ENUMS #undef –

+2

Lưu ý rằng đối với phương án 1, ** tất cả ** Boost bao gồm bắt buộc có 'BOOST_NO_CXX11_SCOPED_ENUMS' được xác định, hoặc vi phạm ODR chắc chắn sẽ làm theo. – ildjarn

5

Bạn cần thêm thư viện hệ thống libboost_files khi liên kết. Hoặc libboost_filesystem-mt nếu ứng dụng của bạn là đa luồng. Như thế này:

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

Và trong trường hợp bạn đang sử dụng CMake, hãy là 'target_link_libraries (my_executable $ {Boost_LIBRARIES})' – Adrian

0

Bạn cần phải thêm các thư viện sau:

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

Nếu bạn sử dụng một 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) 
Các vấn đề liên quan