将std :: filesystem添加到CMake项目时出现问题

Mae*_*aus 3 c++ cmake

我是CMake项目的新手,我想在项目中使用文件系统库。我正在使用GCC 8.2和CMake 3.13运行Ubuntu 18.04。为了实现这一点,我尝试了两种选择:

选项1

cmake_minimum_required(VERSION 3.13)  
project(TheFsProject)  
set(CMAKE_CXX_STANDARD 17)  
set(CMAKE_CXX_FLAGS "-std=c++17 -lstdc++fs")  
Run Code Online (Sandbox Code Playgroud)

这无济于事,因为编译器在编译期间仍找不到文件系统库。

选项2(复制自:https : //www.scivision.co/cmake-cpp-17-filesystem/

make_minimum_required(VERSION 3.13)
project(TheFsProject)

set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(CMAKE_REQUIRED_FLAGS -std=c++17)
include(CheckCXXSymbolExists)
CHECK_CXX_SYMBOL_EXISTS(std::filesystem::path::preferred_separator cxx17fs)

if(cxx17fs)
  add_executable(TheFsProject main.cpp)
  set_property(TARGET TheFsProject PROPERTY CXX_STANDARD 17)
endif()
Run Code Online (Sandbox Code Playgroud)

这也无济于事,因为我收到了我不理解的CMake错误。

(CHECK_CXX_SYMBOL_EXISTS):  
 CHECK_CXX_SYMBOL_EXISTS Macro invoked with incorrect arguments for macro named: CHECK_CXX_SYMBOL_EXISTS
Run Code Online (Sandbox Code Playgroud)

我对这个话题不感兴趣,这就是为什么我来这里。我不介意花更多的精力去寻找更多的东西,但是我不知道该去哪里。任何帮助,将不胜感激!

编辑1

感谢到目前为止的答复!我根据您的反馈做出了选择3

cmake_minimum_required(VERSION 3.13)
project(TheFsProject)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

add_executable(TheFsProject main.cpp)
target_link_libraries(TheFsProject stdc++fs)
Run Code Online (Sandbox Code Playgroud)

不幸的是,这不能解决我的问题。它仍然在编译期间发出一个错误,即找不到编译头。

编辑2

谢谢您到目前为止的所有回复。所有这些帮助。我上次尝试了Ashkan的回答(因为它似乎令人生畏)。这回

编译器缺少文件系统功能。

所以我猜想那是错误的。从我现在知道可能不是由于我的CMake文件的意义上来说,这很有用。我现在必须找出为什么编译器确实支持文件系统标头...

编辑3

严格来说,回答此问题是因为我的问题与CMake文件有关。我将把Ashkan的答案标记为解决方案,只是因为它产生了我的故障排除搜索的下一步。如果可以的话,我也将他的答案标记为lubgr,因为我认为这也是一个很好的答案。感谢大家!

Ash*_*kan 8

除了@lubgr 的回答。我认为更完整的方法是也执行 try_compile 以查看您是否可以实际使用文件系统标头。我认为这更好,因为有些编译器还不支持 std::filesystem。同样在 gcc 7.x 中,您在experimental命名空间下拥有文件系统。这样你就可以在else子句中有一个单独的 try_compile并检测它。

这是它的相关 cmake

# set everything up for c++ 17 features
set(CMAKE_CXX_STANDARD 17)
# Don't add this line if you will try_compile with boost.
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# test that filesystem header actually is there and works
try_compile(HAS_FS "${CMAKE_BINARY_DIR}/temp" 
"${CMAKE_SOURCE_DIR}/tests/has_filesystem.cc" 
            CMAKE_FLAGS -DCMAKE_CXX_STANDARD=17 -DCMAKE_CXX_STANDARD_REQUIRED=ON
            LINK_LIBRARIES stdc++fs)
if(HAS_FS)
    message(STATUS "Compiler has filesystem support")
else()
#   .... You could also try searching for boost::filesystem here.
    message(FATAL_ERROR "Compiler is missing filesystem capabilities")
endif(HAS_FS)
Run Code Online (Sandbox Code Playgroud)

文件 tests/has_filesystem.cc 非常简单

#include <filesystem>

namespace fs = std::filesystem;

int main()
{
    fs::path aPath {"../"};

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

你可以在你的 else 子句中 try_compile for boost::filesystem 并传递一个可以在你的源文件中使用的指令,你可以在其中决定是使用 c++17 文件系统还是 boost。


lub*_*bgr 6

Gcc 8.2。随附<filesystem>,因此无需调查可用性。接下来,选项1已足够,但需要解决:

set(CMAKE_CXX_STANDARD 17) # no need to manually adjust the CXXFLAGS

add_executable(yourExecutable yourSourceFile.cpp)

target_link_libraries(yourExecutable stdc++fs)
Run Code Online (Sandbox Code Playgroud)

这将导致使用-std=c++17或编译源,-std=gnu++17-lstdc++fs在链接时添加源。

编辑:请注意,正如@Ashkan在注释中指出的那样,如果编译器不支持C ++ 17 ,则将CMAKE_CXX_STANDARD_REQUIRED设置为true在配置时立即导致错误,而不是编译错误(由于缺少<filesystem>标头)或在链接时(由于缺少共享库)。这可能是理想的。

  • 是的,但是如果您可以在正确的位置得到错误,则更容易解决。这样,cmake将退出而不是让make给出编译错误。 (3认同)