cmake: auto-detect if std::filesystem needs -lstdc++fs (fixes RHEL8/gcc-8.5)
Build and Deploy Documentation / build-and-deploy (push) Successful in 26s

On gcc-8 (e.g. RHEL8's system compiler, 8.5), std::filesystem is present
but still split out into a separate archive, libstdc++fs.a, so linking
msr2msr failed with undefined references such as
std::filesystem::remove(std::filesystem::__cxx11::path const&, std::error_code&).
gcc>=9 and clang/libc++ ship it in the main runtime library already.

Detect this via an actual compile+link try (first with no extra lib, then
with -lstdc++fs/-lc++fs) instead of guessing from compiler/OS, so
macOS, RHEL9/10, Ubuntu, etc. are unaffected.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-30 06:53:31 +02:00
co-authored by Claude Sonnet 5
parent 618e96fb00
commit 8e6f6d3752
2 changed files with 40 additions and 1 deletions
+39
View File
@@ -162,6 +162,45 @@ find_package(FFTW3 REQUIRED)
#--- check for libxml2 --------------------------------------------------------
find_package(LibXml2 REQUIRED)
#--- check whether <filesystem> needs an extra library to link ----------------
#--- On most current toolchains (gcc>=9, clang/libc++, MSVC, macOS) std::filesystem
#--- lives in the main runtime library and just works. On gcc-8 (e.g. RHEL8's
#--- system gcc, 8.5) it is present but still split out into a separate static
#--- archive, libstdc++fs.a, and needs an explicit -lstdc++fs, otherwise linking
#--- fails with 'undefined reference to std::filesystem::remove(...)' etc.
#--- Detected via an actual compile+link try, so this adapts automatically
#--- instead of guessing from compiler/OS name and risks affecting unrelated
#--- platforms. -----------------------------------------------------------
include(CheckCXXSourceCompiles)
set(STDFS_TEST_SRC "
#include <filesystem>
int main() {
std::filesystem::path p(\"foo\");
std::error_code ec;
std::filesystem::remove(p, ec);
return 0;
}
")
check_cxx_source_compiles("${STDFS_TEST_SRC}" HAVE_STD_FILESYSTEM_NOLIB)
set(STDFS_LIBRARY "")
if (NOT HAVE_STD_FILESYSTEM_NOLIB)
foreach (_stdfs_lib stdc++fs c++fs)
set(CMAKE_REQUIRED_LIBRARIES ${_stdfs_lib})
unset(HAVE_STD_FILESYSTEM_WITH_${_stdfs_lib} CACHE)
check_cxx_source_compiles("${STDFS_TEST_SRC}" HAVE_STD_FILESYSTEM_WITH_${_stdfs_lib})
unset(CMAKE_REQUIRED_LIBRARIES)
if (HAVE_STD_FILESYSTEM_WITH_${_stdfs_lib})
set(STDFS_LIBRARY ${_stdfs_lib})
break ()
endif ()
endforeach ()
if (NOT STDFS_LIBRARY)
message(FATAL_ERROR "std::filesystem is required but no linkable implementation could be found")
endif ()
message(STATUS "std::filesystem needs extra library: ${STDFS_LIBRARY}")
endif ()
#--- check for OpenMP ---------------------------------------------------------
if (try_OpenMP)
#--- AppleClang has no built-in OpenMP runtime; MacPorts' 'libomp' port
+1 -1
View File
@@ -76,7 +76,7 @@ target_include_directories(msr2msr
BEFORE PRIVATE
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/src/include>
)
target_link_libraries(msr2msr ${ROOT_LIBRARIES})
target_link_libraries(msr2msr ${ROOT_LIBRARIES} ${STDFS_LIBRARY})
add_executable(musrfit musrfit.cpp)
target_compile_options(musrfit BEFORE PRIVATE "-DHAVE_CONFIG_H" "${HAVE_GIT_REV_H}")