2013-03-26 4 views
18

J'essaie d'exécuter le programme, en utilisant l'exemple de code de boost :: filesystem sur Ubuntu 12.10, mais il ne veut pas construire.Impossible de lier le programme en utilisant 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"; 
} 

et le 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, il 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?

+2

essayer de construire avec la version boost autodétectés: FIND_PACKAGE (Boost Système de fichiers système COMPONENTS OBLIGATOIRE) – podshumok

+0

J'ai ajouté cmake aux tags. Ce problème semble être lié à cmake. – drescherjm

+1

Le boost 1.53 est-il reconnu par votre version de CMake? Vous voudrez peut-être imprimer ce que $ {Boost_LIBRARIES} contient dans votre CMakeLists.txt pour mieux comprendre ce qui se passe. MESSAGE (status $ {Boost_LIBRARIES}) devrait le faire. – drescherjm

Répondre

1

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 probalbly System trop

Jetez un oeil here

Par exemple:

  • ./bootstrap.sh (bjam)
  • rm -rf bin.v2 stage (entre 2 commandes bjam)
  • ./bjam release outilset = gcc adresse-model = 64 cxxflags = -fPIC
  • jeu d'outils de débogage ./bjam = gcc adresse modèle = 64 CXXFLAGS = -fPIC

Si vous créez un lien sous Windows, vous ne devez pas lier manuellement vos bibliothèques, car ils sont automatiquement liés à l'aide pragma . Sous Linux, vous devez le faire.

Selon la documentation, ces modules vous besoin d'acquérir ou de construire une bibliothèque:

  • 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

Ceci est sur linux et je pense que boost aurait été installé via le gestionnaire de paquets dans Ubuntu. – drescherjm

22

système de fichiers Boost est l'un de la bibliothèque Boost qui ont un problème ABI par rapport à la modification de la signature de fonction due à C++ 0x ou C++ 11.cf billet Boost: https://svn.boost.org/trac/boost/ticket/6779

Vous avez trois solutions:

  1. Inhibit C++ 11 scope énumérations dans les fichiers concernés 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 ça ne marche pas pour tout le monde.

  2. Construire BOOST avec l'option C++ 11 (les mêmes options que vous utilisez pour votre application): http://hnrkptrsn.github.io/2013/02/26/c11-and-boost-setup-guide

    Je lis aussi cela ne fonctionne pas pour tout le monde.

  3. 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 la maintenabilité, et c'est certainement la solution à recommander. Je n'ai pas lu si elle a été testée - 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 beaucoup de bons tutoriels et de soutien pour cela. En 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. Donc, je ne l'ai pas encore testé.

+0

Juste une amélioration ci-dessus si vous utilisez libboost ci-dessous 1,51 besoin d'utiliser l'utilisation #define BOOST_NO_SCOPED_ENUMS #include "boost/filesystem.hpp" #undef BOOST_NO_SCOPED_ENUMS –

+2

Notez que pour l'option 1, ** tous ** Boost comprend must avez 'BOOST_NO_CXX11_SCOPED_ENUMS' défini, ou des violations ODR suivront sûrement. – ildjarn

5

Vous devez ajouter la bibliothèque libboost_filesystem lors de la liaison. Ou libboost_filesystem-mt si votre application est multithread. Comme ceci:

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

Et dans le cas où vous utilisez CMake ce serait 'target_link_libraries (mon_exécutable $ {Boost_LIBRARIES})' – Adrian

0

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) 
Questions connexes