web-dev-qa-db-ja.com

Mac OS X High Sierraでは、C ++ 17の「ファイルシステム」が機能しません

私はこのチュートリアルに従っています:

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

新しいc ++ filesystem機能をチェックアウトします。しかし、私は自分のマシンで最小限の例をコンパイルすることはできません:

_#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;
}
_

XCode、CLion、およびコマンドラインを使用してコンパイルしようとしていましたが、何も機能しません。バージョン9.3(9E145)に(見たところ適切な)プロジェクト設定があり、どれも機能しません。

enter image description hereenter image description here

以下は、CLion用の_CMakeLists.txt_ファイルです。

_cmake_minimum_required(VERSION 3.8)

project(FileSystem2)

set(CMAKE_CXX_STANDARD 17)

add_executable(FileSystem2 main.cpp)
_

以下は_> gxx --version_からの出力です。

enter image description here

それにもかかわらず、これは私のIDEからの出力として得られるものです:

enter image description hereenter image description hereenter image description here

私が間違っているのは何ですか、私のコンパイラはc ++ 17をサポートする必要があるように見えますか?


編集

Owen Morganの回答によると、clangをインストールしました(実際のインストールコマンドは_brew install llvm_でした)が、今では_string.h_がないことに不満を言っています。何かご意見は?

17
Lu4

Xcodeに付属するコンパイラは、C++ 17language機能をサポートしていますが、C++ 17標準ライブラリ機能はサポートしていません。スクリーンショットを見ると、標準ライブラリのサポートがC++ 11に移行し、AppleがC++ 14またはC++ 17のいずれかをstdlibをサポートするバージョンのclangをまだ出荷していないことがわかります。 。

しかし、希望は失われません! brew package managerから最新バージョンのclangをダウンロードできます。

brew install clang

次に、cmakeコンパイラフラグをカスタムbrewバージョンに設定して実行します。

これを行う方法のリンクは次のとおりです。 http://antonmenshov.com/2017/09/09/clang-openmp-setup-in-xcode/

編集:

llvmをインストールしたら、llvmパスを現在のシェルにリンクする必要があります。これを適切にセットアップするために職場で使用するシェルスクリプトがあります。お役に立てれば。

#!/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.

編集2:

Clang 6.0にはmacOSに<filesystem>がまだ含まれていませんが、<experimental/filesystem>を取得し、-lc++experimentalに対してリンクし、std::experimental::filesystemの代わりにstd::filesystemを使用できます。

最終的なコマンドライン呼び出し:

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

編集3:

現在のclangバージョン7.0.1は、<filesystem>または<experimental/filesystem>のいずれかをサポートしています。いずれの場合でも、コンパイラーのコマンドラインはわずかに異なる必要があります。

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

-lc++fsの代わりに-lc++experimentalを使用します。オプションで、-std=c++1z-std=c++17に置き換えることもできます。

14
Owen Morgan

Std :: filesystemを使用するようにコンパイラーを変更したくない場合(苦痛のため)、別のオプションは Boost Filesystem ライブラリーを使用することです。 Boost Filesystemはstd :: filesystemの基礎であったため、ほとんどの用途ではstd :: filesystemと完全に互換性があります。

CMakeを使用している場合、Boostのセットアップは非常に簡単です。ただbrew install boostし、CMakeLists.txtで次のようなことをします:

# 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})

Boostを見つける際の余分な冗長性は、CMakeがそうでなければあなたに投げかけるいくつかの警告を抑制するのに役立つと思います。

次に、C++コードで:

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

あなたが非常に空想を感じているなら、__has_include defineを使用して、標準ファイルシステムインクルードが利用可能かどうかを確認できます。そうであれば、namespace fs = std::filesystemを設定し、stdバージョンがそうでない場合にのみBoostにフォールバックします利用できます。

8
aiusepsi