build, core: check for experimental std::filesystem and link the additional library if needed

This commit is contained in:
Gabriel Ferreira
2022-09-11 12:18:33 -03:00
parent 26eff936a5
commit 3bb39bd746
3 changed files with 54 additions and 11 deletions

View File

@@ -48,3 +48,29 @@ if(${MISSING_OSTREAM_NULLPTR_OPERATOR})
${CMAKE_CURRENT_SOURCE_DIR}/build-support/compiler-workarounds/ostream-operator-nullptr.h
)
endif()
# Some compilers (e.g. GCC < 9.1 and Clang < 9) do not link
# std::filesystem/std::experimental::filesystem by default.
# If the sample program can be linked, it means it is
# indeed linked by default. Otherwise, we link it manually.
# https://en.cppreference.com/w/cpp/filesystem
check_cxx_source_compiles(
"
# ifdef __cpp_lib_filesystem
#include <filesystem>
namespace fs = std::filesystem;
#else
#include <experimental/filesystem>
namespace fs = std::experimental::filesystem;
#endif
int main()
{
std::string path = \"/\";
return !fs::exists (path);
}
"
FILESYSTEM_LIBRARY_IS_LINKED
)
if(NOT FILESYSTEM_LIBRARY_IS_LINKED)
link_libraries(-lstdc++fs)
endif()

View File

@@ -221,6 +221,12 @@ if(${CLANG} AND APPLE)
set(STATIC_LINK_FLAGS)
endif()
# Include CMake files used for compiler checks
include(CheckIncludeFile) # Used to check a single C header at a time
include(CheckIncludeFileCXX) # Used to check a single C++ header at a time
include(CheckIncludeFiles) # Used to check multiple headers at once
include(CheckFunctionExists)
macro(SUBDIRLIST result curdir)
file(GLOB children RELATIVE ${curdir} ${curdir}/*)
set(dirlist "")
@@ -1078,11 +1084,6 @@ macro(process_options)
set(INT64X64_USE_CAIRO TRUE)
endif()
include(CheckIncludeFile) # Used to check a single C header at a time
include(CheckIncludeFileCXX) # Used to check a single C++ header at a time
include(CheckIncludeFiles) # Used to check multiple headers at once
include(CheckFunctionExists)
# Check for required headers and functions, set flags if they're found or warn
# if they're not found
check_include_file("stdint.h" "HAVE_STDINT_H")

View File

@@ -25,12 +25,28 @@
#include <algorithm>
#include <cstdlib> // getenv
#include <cstring> // strlen
#include <filesystem>
#include <tuple>
#include <sstream>
#include <ctime>
#include <regex>
// Some compilers such as GCC < 8 (Ubuntu 18.04
// ships with GCC 7) do not ship with the
// std::filesystem header, but with the
// std::experimental::filesystem header.
// Since Clang reuses these headers and the libstdc++
// from GCC, we need to either use the experimental
// version or require a more up-to-date GCC.
// we use the "fs" namespace to prevent collisions
// with musl libc.
# ifdef __cpp_lib_filesystem
#include <filesystem>
namespace fs = std::filesystem;
#else
#include <experimental/filesystem>
namespace fs = std::experimental::filesystem;
#endif
#ifdef __APPLE__
#include <mach-o/dyld.h>
#endif /* __APPLE__ */
@@ -84,13 +100,13 @@ ReadFilesNoThrow (std::string path)
{
NS_LOG_FUNCTION (path);
std::list<std::string> files;
if (!std::filesystem::exists (path))
if (!fs::exists (path))
{
return std::make_tuple (files, true);
}
for (auto &it : std::filesystem::directory_iterator (path))
for (auto &it : fs::directory_iterator (path))
{
if (!it.is_directory ())
if (!fs::is_directory(it.path()))
{
files.push_back (it.path ().filename ().string ());
}
@@ -341,9 +357,9 @@ MakeDirectories (std::string path)
NS_LOG_FUNCTION (path);
std::error_code ec;
if (!std::filesystem::exists (path))
if (!fs::exists (path))
{
std::filesystem::create_directories (path, ec);
fs::create_directories (path, ec);
}
if (ec.value ())