boost::filsystem impossible de compiler

Le problème exposé dans ce sujet a été résolu.

Bonjour,

Je suis débutant en programmation. je travaille avec VSCode, Cmake, MinGW 8.1. j’ai installé la bibliothèque Boost voici mon cmakelists.txt

cmake_minimum_required(VERSION 3.0.0)
project(bon_achat VERSION 0.1.0)

set(BOOST_ROOT "c:/local")

set(SOURCE main.cpp)

find_package(Boost 1.65.1 )
if(Boost_FOUND)
  include_directories(${Boost_INCLUDE_DIRS})
   endif()

include(CTest)
enable_testing()



# Les fichiers d'en-tête.
set (HEADERS
    C:/Users/Utilisateur/projets/cheques_cadeaux/Donnes/source/menu_.hpp
    C:/Users/Utilisateur/projets/cheques_cadeaux/Donnes/source/CODE.hpp
)

# Les fichiers sources.
set (SOURCES
    main.cpp
    C:/Users/Utilisateur/projets/cheques_cadeaux/Donnes/source/menu_.cpp
    C:/Users/Utilisateur/projets/cheques_cadeaux/Donnes/source/CODE.cpp
    
)

add_executable(bon_achat ${SOURCES} ${HEADERS})


set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack) 

je souhaiterais utiliser filecopy :

#include <boost/filesystem.hpp> dans le main : boost::filesystem::copy_file("test.txt","c:/test1.txt");

mais j’ai une erreur lors de la compilation :

`[build] CMakeFiles\bon_achat.dir/objects.a(main.cpp.obj): In function `boost::filesystem::path_traits::convert(char const*, char const*, std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >&)':
[build] C:/local/boost/filesystem/path.hpp:1005: undefined reference to `boost::filesystem::path::codecvt()'
[build] C:/local/boost/filesystem/path.hpp:1005: undefined reference to `boost::filesystem::path_traits::convert(char const*, char const*, std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >&, std::codecvt<wchar_t, char, int> const&)'
[build] CMakeFiles\bon_achat.dir/objects.a(main.cpp.obj): In function `boost::filesystem::copy_file(boost::filesystem::path const&, boost::filesystem::path const&)':
[build] C:/local/boost/filesystem/operations.hpp:329: undefined reference to `boost::filesystem::detail::copy_file(boost::filesystem::path const&, boost::filesystem::path const&, unsigned int, boost::system::error_code*)'
[build] collect2.exe: error: ld returned 1 exit status
[build] mingw32-make.exe[3]: *** [CMakeFiles\bon_achat.dir\build.make:137: bon_achat.exe] Error 1
[build] mingw32-make.exe[2]: *** [CMakeFiles\Makefile2:257: CMakeFiles/bon_achat.dir/all] Error 2
[build] mingw32-make.exe[1]: *** [CMakeFiles\Makefile2:264: CMakeFiles/bon_achat.dir/rule] Error 2
[build] mingw32-make.exe: *** [Makefile:234: bon_achat] Error 2
[build] La build s'est achevée avec le code de sortie 2`

je pense avoir oublié une étape ^^ pourriez vous m’aider ? merci ?

+0 -0

Ton erreur ne survient pas à la compilation mais au linkage. Pour résoudre ce problème, il faut que tu dises à CMake de rechercher Boost::filesystem et de le linker avec les fichiers objets qu’il a générés depuis tes fichiers sources.

find_package(Boost COMPONENTS system filesystem REQUIRED)
#...
target_link_libraries(mytarget 
  ${Boost_FILESYSTEM_LIBRARY}
  ${Boost_SYSTEM_LIBRARY}
)

C’est parce que Boost::filesystem n’est pas un morceau header-only. :)

Merci :)

j’ai fait la modification pour le CMAKELists.txt

cmake_minimum_required(VERSION 3.0.0)
project(bon_achat VERSION 0.1.0)

set(BOOST_ROOT "c:/local")

set(SOURCE main.cpp)

find_package(Boost COMPONENTS system filesystem REQUIRED)
if(Boost_FOUND)
  include_directories(${Boost_INCLUDE_DIRS})
  target_link_libraries(bon_achat 
  ${Boost_FILESYSTEM_LIBRARY}
  ${Boost_SYSTEM_LIBRARY}
)
   endif()

include(CTest)
enable_testing()



# Les fichiers d'en-tête.
set (HEADERS
    C:/Users/Utilisateur/projets/cheques_cadeaux/Donnes/source/menu_.hpp
    C:/Users/Utilisateur/projets/cheques_cadeaux/Donnes/source/CODE.hpp
)

# Les fichiers sources.
set (SOURCES
    main.cpp
    C:/Users/Utilisateur/projets/cheques_cadeaux/Donnes/source/menu_.cpp
    C:/Users/Utilisateur/projets/cheques_cadeaux/Donnes/source/CODE.cpp
    
)

add_executable(bon_achat ${SOURCES} ${HEADERS})


set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)

mais j’ai toujours un problème de link

[build] CMake Error at C:/Program Files/CMake/share/cmake-3.19/Modules/FindPackageHandleStandardArgs.cmake:218 (message):
[build]   Could NOT find Boost (missing: system filesystem) (found version "1.74.0")
[build] Call Stack (most recent call first):
[build]   C:/Program Files/CMake/share/cmake-3.19/Modules/FindPackageHandleStandardArgs.cmake:577 (_FPHSA_FAILURE_MESSAGE)
[build]   C:/Program Files/CMake/share/cmake-3.19/Modules/FindBoost.cmake:2193 (find_package_handle_standard_args)
[build]   CMakeLists.txt:13 (find_package)
[build] 
[build] 
[build] -- Configuring incomplete, errors occurred!
[build] See also "C:/Users/Utilisateur/projets/cheques_cadeaux/build/CMakeFiles/CMakeOutput.log".
[build] mingw32-make.exe: *** [Makefile:682: cmake_check_build_system] Error 1
[build] La build s'est achevée avec le code de sortie 2

Quand j’utilise la version intégrée c++17 j’ai aussi un pb :

#include <filesystem> 
std::filesystem::copy_file("C:/lcod.lib","C:/lcod.test"); 
 [build] C:\Users\Utilisateur\projets\cheques_cadeaux\main.cpp: In function 'int main()':
[build] C:\Users\Utilisateur\projets\cheques_cadeaux\main.cpp:26:6: error: 'std::filesystem' has not been declared
[build]  std::filesystem::copy_file("C:/Users/Utilisateur/projets/cheques_cadeaux/build/lcod.lib","C:/Users/Utilisateur/projets/cheques_cadeaux/build/lcod.test");
[build]       ^~~~~~~~~~
[build] mingw32-make.exe[3]: *** [CMakeFiles\bon_achat.dir\build.make:82: CMakeFiles/bon_achat.dir/main.cpp.obj] Error 1
[build] mingw32-make.exe[2]: *** [CMakeFiles\Makefile2:257: CMakeFiles/bon_achat.dir/all] Error 2
[build] mingw32-make.exe[1]: *** [CMakeFiles\Makefile2:264: CMakeFiles/bon_achat.dir/rule] Error 2
[build] mingw32-make.exe: *** [Makefile:234: bon_achat] Error 2
[build] La build s'est achevée avec le code de sortie 2
+0 -0

Sous Windows, il faut aussi que tu précises à CMake où se trouve Boost. Sinon il ne saura pas où chercher et donc ne va pas le trouver.

set (BOOST_ROOT "C:/Programmation/Boost.1.69/boost")
set (BOOST_INCLUDEDIR "C:/Programmation/Boost.1.69")

Pour ton erreur en C++17, déjà es-tu sûr de bien compiler en C++17 ? Si oui, peut-être que ton compilateur ne gère pas correctement ce point en particulier. Sur MinGW, ça semble être le cas, selon cette question StackOverflow. Tu as une potentielle solution, que je remet ci-dessous pour la postérité.

#ifndef __has_include
  static_assert(false, "__has_include not supported");
#else
#  if __has_include(<filesystem>)
#    include <filesystem>
     namespace fs = std::filesystem;
#  elif __has_include(<experimental/filesystem>)
#    include <experimental/filesystem>
     namespace fs = std::experimental::filesystem;
#  elif __has_include(<boost/filesystem.hpp>)
#    include <boost/filesystem.hpp>
     namespace fs = boost::filesystem;
#  endif
#endif

Avec une version inférieure à C++17, tu peux aussi utiliser filesystem, mais de façon "expérimental". :)

Utilise std::experimental::filesystem

Va voir la doc pour plus d’infos : https://docs.microsoft.com/fr-fr/cpp/standard-library/filesystem?view=msvc-160

Et oui, utilise Microsoft Visual Studio, il n’y a que du positif :

  • Une version gratuite
  • Tous les pros en C++ l’utilisent
  • Très puissant
  • Et ça t’évitera ce genre de problème ;)
+0 -0

Bonsoir,

IL faut toujours un peu se gaffer avec MinGW, il y a parfois des bibliothèques prétenduement standard qui sont en réalité absentes de la distribution.

La dernière fois que j’ai voulu essayer la version standard de filesystem, je n’ai pas réussi non plus. J’ai aussi eu des difficultés avec la bibliothèque filesystem de boost, car il utilise un autre composant absent de MinGW: codecvt.

Quand bien même j’ai MinGW-W64 avec GCC 8.1 qui supporte normalement C++17 et évidemment en utilisant l’option adéquate (-std=gnu++17), je ne peux pas utiliser ni std::filesystem, ni codecvt. J’obtiens des erreurs de link comparables aux tiennes.

ON peut tout de même utiliser boost::filesystem, mais à condition de ne pas avoir recours au sous-système qui convertit automatiquement l’encodage des noms de fichier dans l’encodage windows local. Cette conversion se fait avec codecvt (absent justement). Concrètement, ça veut dire grosso-modo, être forcé d’utiliser std::wstring à la place de std::string pour construire les paths. Mais attention, c’est pas si simple !

En l’absence de routines de conversion d’encodage, tu pourrais utiliser directement MultiByteToWideChar / WideCharToMultiByte, mais je te le déconseille fortement: c’est un nid à problèmes. JE te conseille plutôt de fonctionner par défaut en UTF-8 et de prendre une petite bibliothèque comme utf8cpp pour faire les conversions. Car en fait, seul windows (ou presque) n’est pas en UTF-8 par défaut (si on exclut les langues à alphabet non latin).

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte