From aebd324cf4990101940bdda48994ec17959eb5ed Mon Sep 17 00:00:00 2001 From: Martchus Date: Wed, 5 Jun 2019 23:48:01 +0200 Subject: [PATCH] Add CMake function to use std::filesystem --- cmake/modules/3rdParty.cmake | 54 ++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/cmake/modules/3rdParty.cmake b/cmake/modules/3rdParty.cmake index 616e711..ad5fbf6 100644 --- a/cmake/modules/3rdParty.cmake +++ b/cmake/modules/3rdParty.cmake @@ -6,6 +6,8 @@ if (DEFINED THIRD_PARTY_MODULE_LOADED) endif () set(THIRD_PARTY_MODULE_LOADED YES) +include(CheckCXXSourceCompiles) + macro (save_default_library_suffixes) set(DEFAULT_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) endmacro () @@ -266,6 +268,58 @@ function (use_pkg_config_module) set("PKG_CONFIG_${TARGET_VARNAME}" "${ARGS_PKG_CONFIG_MODULES}" PARENT_SCOPE) endfunction () +function (use_standard_filesystem) + # parse and validate arguments + parse_arguments_for_use_functions(${ARGN}) + + # check whether an additional library for std::filesystem support is required + set(TEST_PROGRAM [[ + #include + int main() { + auto cwd = std::filesystem::current_path(); + return static_cast(cwd.string().size()); + } + ]]) + set(DEFAULT_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES}) + set(CMAKE_REQUIRED_FLAGS -std=c++17) + set(REQUIRED_LIBRARY FAILED) + set(INDEX 0) + foreach (LIBRARY "" "stdc++fs" "c++fs") + set(CMAKE_REQUIRED_LIBRARIES ${DEFAULT_REQUIRED_LIBRARIES} -l${LIBRARY}) + check_cxx_source_compiles("${TEST_PROGRAM}" COULD_COMPILE_${INDEX}) + if (COULD_COMPILE_${INDEX}) + set(REQUIRED_LIBRARY "${LIBRARY}") + break() + endif () + math(EXPR INDEX "${INDEX}+1") + endforeach () + + # handle error + if (REQUIRED_LIBRARY STREQUAL "FAILED") + message(FATAL_ERROR "Unable to compile a simple std::filesystem example. A compiler supporting C++17 is required to build this project.") + return () + endif () + + # handle case when no library is required + if (REQUIRED_LIBRARY STREQUAL "") + message(STATUS "Linking ${META_PROJECT_NAME} against special library for std::filesystem support is not required.") + return () + endif () + + # find the static version of the library + # note: Preferring the static version here because the ABI might not be stable. (stdc++fs seems to be only available as static lib anyways.) + configure_static_library_suffixes() + set(USED_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) + find_library(STANDARD_FILE_SYSTEM_LIBRARY "${REQUIRED_LIBRARY}") + configure_dynamic_library_suffixes() + if (NOT STANDARD_FILE_SYSTEM_LIBRARY) + message(FATAL_ERROR "Unable to find standard file system library \"${REQUIRED_LIBRARY}\" using CMAKE_FIND_LIBRARY_SUFFIXES \"${USED_SUFFIXES}\".") + endif () + + message(STATUS "Linking ${META_PROJECT_NAME} against library \"${STANDARD_FILE_SYSTEM_LIBRARY}\" for std::filesystem support.") + set("${ARGS_LIBRARIES_VARIABLE}" "${${ARGS_LIBRARIES_VARIABLE}};${STANDARD_FILE_SYSTEM_LIBRARY}" PARENT_SCOPE) +endfunction () + # skip subsequent configuration if only the function includes are wanted if (META_NO_3RDPARTY_CONFIG) return()