Я (переключаюсь на) использую <std::experimental::filesystem>
в моем коде C ++ 14, и мне нужно иметь возможность построить его, используя GCC 5.x в Linux (и любой компилятор с поддержкой C ++ 14 или, по крайней мере, соответствующие версии clang, msvc и, возможно, icc) ,
Теперь, когда я делаю ссылку, я получаю ошибки об отсутствии всех символов, связанных с файловой системой, например:
foo.cpp:(.text+0x9cd): undefined reference to `std::experimental::filesystem::v1::__cxx11::path::_M_split_cmpts()'
Теперь, если я «вручную» добавить зависимость от libstdc++fs
:
target_link_libraries(foo other_lib stdc++fs)
тогда все нормально связывается — но как мне обобщить это на любой компилятор с поддержкой C ++ 14?
Примечание: соответствующие части моего CMakeLists.txt
выглядеть примерно так:
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall" )
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
add_library(bar src/bar.cpp)
add_executable(foo src/foo.cpp)
target_link_libraries(foo bar other_lib)
*
(Когда я использовал boost::filesystem
это было парадоксально проще — мне просто нужно использовать что угодно FindBoost.cmake
производится.)
** С помощью -Wall
Я думаю, это проблема и для других компиляторов.
К сожалению, это именно то, как он предназначен для использования. Увидеть соответствующая часть документации libstdc ++:
GCC 5.3 включает в себя реализацию библиотеки файловой системы, определенной
согласно технической спецификации ISO / IEC TS 18822: 2015. Потому что это
экспериментальное расширение библиотеки, не являющееся частью стандарта C ++, это
реализован в отдельной библиотеке libstdc ++ fs.a, и нет
общая библиотека для него. Чтобы использовать библиотеку, вы должны включить
и связать с -lstdc ++ fs. Библиотека
реализация не завершена на не POSIX платформах, особенно
Поддержка Windows находится в зачаточном состоянии.Из-за экспериментального характера библиотеки файловой системы обычный
гарантии о стабильности ABI и обратной совместимости не
применить к этому. Там нет никакой гарантии, что компоненты в любом
заголовок останется совместимым между разными GCC
релизы.
(акцент мой)
Связывать libstdc++fs
только в GCC, вы можете использовать соответствующая переменная CMake:
target_link_libraries(foo other_lib)
if (CMAKE_CXX_COMPILER_ID STREQUAL GNU)
target_link_libraries(foo stdc++fs)
endif()
Или, немного более причудливо,
if (CMAKE_CXX_COMPILER_ID STREQUAL GNU)
set(CXX_FILESYSTEM_LIBRARIES stdc++fs)
else()
set(CXX_FILESYSTEM_LIBRARIES)
endif()
target_link_libraries(foo other_lib ${CXX_FILESYSTEM_LIBRARIES})
Других решений пока нет …