Невозможно связать программу с помощью Boost.Filesystem
Я пытаюсь запустить программу, используя пример кода boost:: filesystem на Ubuntu 12.10, но он не хочет строить.
#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
В чем причина этой проблемы и как ее решить?
Ответы
Ответ 1
Boost файловая система является одной из библиотеки Boost, у которой есть проблема с ABI относительно изменения сигнатуры функции из-за С++ 0x или С++ 11. cf Boost ticket: https://svn.boost.org/trac/boost/ticket/6779
У вас есть три решения:
-
Запретить перечисления С++ 11 в соответствующих заголовочных файлах Boost, включенных в ваши программы, С#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
Но это решение не является полным, и я читал, что он не работает для всех.
-
Постройте BOOST с параметром С++ 11 (те же параметры, которые вы используете для своего приложения): http://hnrkptrsn.github.io/2013/02/26/c11-and-boost-setup-guide
Я читаю, что это не работает для всех.
-
Настройте кросс-компилятор, посвященный вашему приложению, где вы перестраиваете все библиотеки, которые вам нужны, в выделенной среде. Это обеспечивает согласованность плюс стабильность плюс более ремонтопригодность и, безусловно, является решением для рекомендации.
Я не читал, если он был протестирован - возможно, да, и, вероятно, он работает. Во всяком случае, кросс-компиляция хорошо освоена сейчас в области информатики. Вы найдете много хороших учебных пособий и поддержки. В Linux Gentoo у них есть чудесный пакет sys-devel/crossdev, который делает его очень легким.
В моем собственном случае решение 1 решило проблему. Как только я столкнулся с другим, я переключусь на решение 3. Итак, я еще не тестировал его.
Ответ 2
При связывании вам нужно добавить библиотеку libboost_filesystem. Или libboost_filesystem-mt, если ваше приложение многопоточное. Вот так:
g++ -o file -lboost_filesystem-mt source_file.cpp
Ответ 3
Для некоторых модулей boost вам необходимо скомпилировать библиотеки и, используя их (используя bootstrap.sh).
В вашем случае вам нужно скомпилировать и связать Filesystem
и probalbly System
тоже
Посмотрите здесь
Например:
- ./bootstrap.sh(bjam)
- rm -rf bin.v2 stage (между двумя командами bjam)
- ./bjam release toolset = gcc address-model = 64 cxxflags = -fPIC
- ./bjam debug toolset = gcc address-model = 64 cxxflags = -fPIC
Если вы подключаетесь к Windows, вам не нужно вручную связывать свои библиотеки, поскольку они автоматически связаны с помощью прагмы. В Linux вы должны это сделать.
В соответствии с документацией эти модули требуют, чтобы вы приобрели или создали библиотеку:
- Boost.Filesystem
- Boost.GraphParallel
- Boost.IOStreams
- Boost.MPI
- Boost.ProgramOptions
- Boost.Python
- библиотека Boost.regex
- Boost.Serialization
- Boost.Signals
- Boost.System
- Boost.Thread
- Boost.Wave
Ответ 4
Вам нужно добавить следующие библиотеки:
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)