web-dev-qa-db-fra.com

`système de fichiers` avec c ++ 17 ne fonctionne pas sur mon mac os x high sierra

Je suis ce tutoriel:

http://www.bfilipek.com/2017/08/cpp17-details-filesystem.html

pour extraire la nouvelle fonctionnalité c ++ filesystem. Cependant, je ne peux pas compiler un exemple, même minime, sur ma machine:

#include <string>
#include <iostream>
#include <filesystem>

namespace fs = std::filesystem;

int main()
{
    std::string path = "/";

    for (auto & p : fs::directory_iterator(path))
        std::cout << p << std::endl;
}

J'utilisais XCode, CLion et la ligne de commande en essayant de le compiler mais rien ne fonctionne, j'ai la version 9.3 (9E145) avec des paramètres de projet (apparemment appropriés), dont aucun ne fonctionne:

enter image description hereenter image description here

Voici mon CMakeLists.txt fichier pour CLion:

cmake_minimum_required(VERSION 3.8)

project(FileSystem2)

set(CMAKE_CXX_STANDARD 17)

add_executable(FileSystem2 main.cpp)

Voici une sortie de > gxx --version:

enter image description here

Néanmoins, c'est ce que j'obtiens en sortie de mes IDE:

enter image description hereenter image description hereenter image description here

Que fais-je de mal, il me semble que mon compilateur devrait prendre en charge c ++ 17?


Modifier

Selon la réponse d'Owen Morgan, j'ai installé clang (la commande d'installation réelle était brew install llvm) mais il se plaint maintenant de l'absence de string.h. Des pensées?

17
Lu4

Le compilateur fourni avec Xcode prend en charge les fonctionnalités du langage C++ 17 mais pas les fonctionnalités de bibliothèque standard C++ 17. En regardant votre capture d'écran, vous verrez que le support de bibliothèque standard va jusqu'à C++ 11, et Apple n'a pas encore livré une version de clang qui prend en charge stdlib pour C++ 14 ou C++ 17.

Mais l'espoir n'est pas perdu! Vous pouvez télécharger la dernière version de clang depuis le gestionnaire de paquets de brassage.

brew install clang

Ensuite, vous pouvez compiler en définissant vos indicateurs de compilateur cmake comme votre version de brassage personnalisée, puis en exécutant cela.

Voici un lien pour y parvenir: http://antonmenshov.com/2017/09/09/clang-openmp-setup-in-xcode/

Modifier:

Après avoir installé llvm, vous devrez lier votre chemin llvm à votre shell actuel. J'ai un script Shell que j'utilise au travail pour configurer correctement cela. J'espère que cela t'aides.

#!/bin/bash
brew update
brew install --with-toolchain llvm # llvm but with all the headers
xcode-select --install # installs additional headers that you might be mimssing.
echo 'export PATH="/usr/local/opt/llvm/bin:$PATH"' >> ~/.bash_profile # exports the custom llvm path into the Shell 
Sudo ln -s /usr/local/opt/llvm/bin/clang++ /usr/local/bin/clang++-brew # optional but I like to have a symlink set.

Modifier 2:

Clang 6.0 n'a pas <filesystem> encore inclus sur macOS, mais vous pouvez obtenir <experimental/filesystem>, et un lien contre -lc++experimental, et utilise std::experimental::filesystem au lieu de std::filesystem.

Appel final de la ligne de commande:

Owen$ /usr/local/Cellar/llvm/6.0.0/bin/clang++ fs.cpp -std=c++1z -L /usr/local/Cellar/llvm/6.0.0/lib/ -lc++experimental

Modifier 3:

La version actuelle de clang 7.0.1 prend en charge <filesystem> ou <experimental/filesystem>. Dans tous les cas, la ligne de commande du compilateur doit être légèrement différente:

Owen$ /usr/local/Cellar/llvm/7.0.1/bin/clang++ main.cpp -std=c++1z -L /usr/local/Cellar/llvm/7.0.1/lib/ -lc++fs

avec -lc++fs au lieu de -lc++experimental. Facultativement, vous pouvez remplacer-std=c++1z avec -std=c++17 ainsi que.

14
Owen Morgan

Si vous ne voulez pas changer le compilateur pour utiliser std :: filesystem (parce que c'est pénible), une autre option est d'utiliser la bibliothèque Boost Filesystem . Boost Filesystem était la base de std :: filesystem, donc pour la plupart des utilisations, il est complètement compatible avec std :: filesystem.

La configuration de Boost est assez simple si vous utilisez CMake. Juste brew install boost puis dans votre CMakeLists.txt faites quelque chose comme:

# Boost
set(boost_min_ver 1.50.0)
set(boost_libs system filesystem)
find_package(Boost ${boost_min_ver})

if(Boost_FOUND)
    find_package(Boost ${boost_min_ver} COMPONENTS ${boost_libs})
endif()

target_link_libraries(your_target ${Boost_LIBRARIES})

La verbosité supplémentaire dans la recherche de Boost aide, je trouve, à supprimer certains avertissements que CMake vous lancerait autrement.

Puis dans votre code C++:

#include <boost/filesystem.hpp>
namespace fs = boost::filesystem;

Si vous vous sentez très chic, vous pouvez utiliser le __has_include définir pour vérifier si l'inclusion de système de fichiers standard est disponible, et si oui, définissez namespace fs = std::filesystem et retour à Boost uniquement si la version std n'est pas disponible.

8
aiusepsi