Проблема с добавлением std :: filesystem в проект CMake - PullRequest
0 голосов
/ 21 января 2019

Я новичок в проектах CMake и хочу использовать библиотеку файловой системы в своем проекте. Я использую Ubuntu 18.04 с GCC 8.2 и CMake 3.13. Чтобы добиться этого, я попробовал два варианта:

Вариант 1

cmake_minimum_required(VERSION 3.13)  
project(TheFsProject)  
set(CMAKE_CXX_STANDARD 17)  
set(CMAKE_CXX_FLAGS "-std=c++17 -lstdc++fs")  

Это не помогает, так как компилятор все еще не может найти файловую систему библиотека во время компиляции.

Вариант 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()

Это тоже не помогает, так как я получаю ошибку CMake, которую я не получаю понимать.

(CHECK_CXX_SYMBOL_EXISTS):  
 CHECK_CXX_SYMBOL_EXISTS Macro invoked with incorrect arguments for macro named: CHECK_CXX_SYMBOL_EXISTS

Мне не хватает глубины в этой теме, поэтому я и пришел сюда. Я не против дополнительной работы, чтобы узнать больше, но я не знаю, где искать. Любая помощь будет оценена!

РЕДАКТИРОВАТЬ 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)

К сожалению, это не решает мою проблему. Во время компиляции по-прежнему выдается ошибка, из-за которой не удается найти заголовок компиляции.

РЕДАКТИРОВАТЬ 2

Спасибо за все ответы до сих пор. Все это поможет. Я попробовал Ашкан его ответ последним (потому что он казался пугающим). Этот возвращает

Компилятору не хватает возможностей файловой системы.

так что я предполагаю, что с этой стороны что-то не так. Это полезно в том смысле, что я теперь знаю, что это, вероятно, не из-за моего файла CMake. Теперь мне нужно выяснить, почему компилятор поддерживает заголовок файловой системы, хотя ...

РЕДАКТИРОВАТЬ 3

Строго говоря, на этот вопрос дан ответ, потому что мой вопрос касается файла CMake. Я собираюсь отметить Ашкан его ответ как решение просто потому, что он произвел следующий шаг в моем поиске неисправностей. Если бы я мог, я бы также отметил Лубгр его ответ, потому что я думаю, что это действительно хороший ответ. Спасибо всем!

Ответы [ 3 ]

0 голосов
/ 21 января 2019

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)

Это должно привести к компиляции источников с -std=c++17 или -std=gnu++17 и добавлению -lstdc++fs при связывании.

Изменить: Обратите внимание, что, как указал @Ashkan в комментариях, установка CMAKE_CXX_STANDARD_REQUIRED в true приводит к немедленной ошибке во время настройки, если C ++ 17 не поддерживается компилятором, а неОшибка компиляции (из-за отсутствия заголовка <filesystem>) или во время соединения (из-за отсутствия общей библиотеки).Это может быть желательно.

0 голосов
/ 21 января 2019

Кроме того, от ответа @ lubgr. Я думаю, что более полный способ также состоит в том, чтобы сделать try_compile, чтобы увидеть, что вы действительно можете использовать заголовок файловой системы. Это, на мой взгляд, лучше, потому что некоторые компиляторы еще не поддерживают std :: filesystem. Также в gcc 7.x у вас есть файловая система в пространстве имен experimental. Таким образом, вы можете создать отдельный try_compile в предложении else и обнаружить его.

Вот соответствующий 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)

Файл tests / has_filesystem.cc очень прост

#include <filesystem>

namespace fs = std::filesystem;

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

    return 0;
}

Вы можете в своем предложении else try_compile для boost :: filesystem и передать директиву, которая может использоваться в вашем исходном файле, где вы решаете, хотите ли вы использовать файловую систему c ++ 17 или boost.

0 голосов
/ 21 января 2019

CHECK_CXX_SYMBOL_EXISTS принимает три аргумента, а не два:

CHECK_CXX_SYMBOL_EXISTS(std::filesystem::path::preferred_separator filesystem cxx17fs)

Вы забыли сообщить CMake, где искать символы (заголовок, который их объявляет).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...