Как использовать cmake для обеспечения связи компилятора C ++ 14 с экспериментальной библиотекой TS файловой системы? - PullRequest
0 голосов
/ 04 мая 2018

Я (переключаюсь на) использую <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 также является проблемой для других компиляторов.

1 Ответ

0 голосов
/ 04 мая 2018

К сожалению, это именно то, как он предназначен для использования. См. соответствующую часть документации 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})
...