J'essaie de lancer un programme en utilisant un exemple de code de boost :: filesystem sur Ubuntu 12.10, mais il ne veut pas construire.
#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";
}
Et code 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})
Malheureusement, cela génère des erreurs
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
Quelle est la raison de ce problème et comment le résoudre?
Le système de fichiers Boost est l’une des bibliothèques Boost qui présente un problème ABI relatif au changement de signature de fonction dû à C++ 0x ou C++ 11. cf Boost ticket: https://svn.boost.org/trac/boost/ticket/6779
Vous avez trois solutions:
Inhibez Cums 11 étendues énumérées dans les fichiers d'en-tête Boost inclus dans vos programmes avec #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
Mais cette solution n’est pas complète et j’ai lu que cela ne fonctionnait pas pour tout le monde.
Construisez BOOST avec l'option C++ 11 (les mêmes options que pour votre application): http://hnrkptrsn.github.io/2013/02/26/c11-and-boost-setup-guide
Je lis aussi que ça ne marche pas pour tout le monde.
Configurez un compilateur croisé dédié à votre application, dans lequel vous reconstruisez toutes les bibliothèques dont vous avez besoin dans un environnement dédié. Cela garantit la cohérence, la stabilité et une plus grande facilité de maintenance. C’est certainement la solution à recommander. Je n’ai pas lu s’il a été testé - probablement oui, et probablement cela fonctionne. Quoi qu'il en soit, la compilation croisée est maintenant bien maîtrisée en informatique. Vous trouverez de nombreux bons tutoriels et un support pour cela. Dans Linux Gentoo, ils ont le merveilleux paquet sys-devel/crossdev qui le rend très facile.
Dans mon cas, la solution 1 a résolu le problème. Dès que j'en rencontrerai un autre, je passerai à la solution 3. Je ne l'ai donc pas encore testée.
Vous devez ajouter la bibliothèque libboost_filesystem lors de la liaison. Ou libboost_filesystem-mt si votre application est multi-threadée. Comme ça:
g++ -o file -lboost_filesystem-mt source_file.cpp
Vous devez ajouter les bibliothèques suivantes:
g++ -o file -lboost_system -lboost_filesystem sourcefile.cpp
Si vous utilisez un 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)
Pour certains modules de boost, vous devez compiler les bibliothèques et les lier (en utilisant bootstrap.sh). Dans votre cas, vous devez compiler et lier Filesystem
et probablement aussi System
Regardez ici
Par exemple:
Si vous liez sur Windows, vous n'avez pas à lier manuellement vos bibliothèques, car elles sont automatiquement liées à l'aide de pragma. Sous Linux, vous devez le faire.
Selon la documentation, ces modules nécessitent l’acquisition ou la construction d’une bibliothèque:
La solution qui a fonctionné pour moi est de compiler avec "-c" puis de créer l'exécutable comme ceci:
g++ -c -o main.o main.cpp
g++ -o my_prog main.o -lboost_system -lboost_filesystem