mirror of
https://github.com/isar/libmdbx.git
synced 2024-12-28 18:38:48 +08:00
mdbx-cmake: rework linking detection for std::filesystem
.
This commit is contained in:
parent
39a4a89650
commit
5ebcb90620
@ -527,6 +527,11 @@ if(MDBX_BUILD_CXX AND NOT CMAKE_CXX_COMPILER_LOADED)
|
||||
message(FATAL_ERROR "MDBX_BUILD_CXX=${MDBX_BUILD_CXX}: The C++ compiler is required to build the C++API.")
|
||||
endif()
|
||||
|
||||
if(MDBX_BUILD_CXX)
|
||||
# determine library for C++ std::filesystem
|
||||
probe_libcxx_filesystem()
|
||||
endif()
|
||||
|
||||
# Get version
|
||||
fetch_version(MDBX "${CMAKE_CURRENT_SOURCE_DIR}" FALSE)
|
||||
message(STATUS "libmdbx version is ${MDBX_VERSION}")
|
||||
|
18
GNUmakefile
18
GNUmakefile
@ -12,13 +12,21 @@ $(info // The GNU Make $(MAKE_VERSION))
|
||||
SHELL := $(shell env bash -c 'echo $$BASH')
|
||||
MAKE_VERx3 := $(shell printf "%3s%3s%3s" $(subst ., ,$(MAKE_VERSION)))
|
||||
make_lt_3_81 := $(shell expr "$(MAKE_VERx3)" "<" " 3 81")
|
||||
ifeq ($(make_lt_3_81),1)
|
||||
ifneq ($(make_lt_3_81),0)
|
||||
$(error Please use GNU Make 3.81 or above)
|
||||
endif
|
||||
make_lt_4_1 := $(shell expr "$(MAKE_VERx3)" "<" " 4 1")
|
||||
make_ge_4_1 := $(shell expr "$(MAKE_VERx3)" ">=" " 4 1")
|
||||
SRC_PROBE_C := $(shell [ -f mdbx.c ] && echo mdbx.c || echo src/osal.c)
|
||||
SRC_PROBE_CXX := $(shell [ -f mdbx.c++ ] && echo mdbx.c++ || echo src/mdbx.c++)
|
||||
UNAME := $(shell uname -s 2>/dev/null || echo Unknown)
|
||||
|
||||
define cxx_filesystem_probe
|
||||
int main(int argc, const char*argv[]) {
|
||||
mdbx::filesystem::path probe(argv[0]);
|
||||
if (argc != 1) throw mdbx::filesystem::filesystem_error(std::string("fake"), std::error_code());
|
||||
return mdbx::filesystem::is_directory(probe.relative_path());
|
||||
}
|
||||
endef
|
||||
#
|
||||
################################################################################
|
||||
#
|
||||
@ -57,16 +65,16 @@ CXXFLAGS ?= $(strip $(CXXSTD) $(filter-out -std=gnu11,$(CFLAGS)))
|
||||
|
||||
# libraries adn options for linking
|
||||
EXE_LDFLAGS ?= -pthread
|
||||
ifeq ($(make_lt_4_1),1)
|
||||
ifneq ($(make_ge_4_1),1)
|
||||
# don't use variable expansion trick as workaround for bugs of GNU Make before 4.1
|
||||
LIBS ?= $(shell $(uname2libs))
|
||||
LDFLAGS ?= $(shell $(uname2ldflags))
|
||||
LIB_STDCXXFS ?= $(shell echo 'int main(void) { MDBX_STD_FILESYSTEM_PATH probe; return probe.is_absolute(); }' | cat mdbx.h++ - | sed $$'1s/\xef\xbb\xbf//' | $(CXX) -x c++ $(CXXFLAGS) -Wno-error - -Wl,--allow-multiple-definition -lstdc++fs $(LIBS) $(LDFLAGS) $(EXE_LDFLAGS) -o /dev/null 2>probe4lstdfs.err >/dev/null && echo '-Wl,--allow-multiple-definition -lstdc++fs')
|
||||
LIB_STDCXXFS ?= $(shell echo '$(cxx_filesystem_probe)' | cat mdbx.h++ - | sed $$'1s/\xef\xbb\xbf//' | $(CXX) -x c++ $(CXXFLAGS) -Wno-error - -Wl,--allow-multiple-definition -lstdc++fs $(LIBS) $(LDFLAGS) $(EXE_LDFLAGS) -o /dev/null 2>probe4lstdfs.err >/dev/null && echo '-Wl,--allow-multiple-definition -lstdc++fs')
|
||||
else
|
||||
# using variable expansion trick to avoid repeaded probes
|
||||
LIBS ?= $(eval LIBS := $$(shell $$(uname2libs)))$(LIBS)
|
||||
LDFLAGS ?= $(eval LDFLAGS := $$(shell $$(uname2ldflags)))$(LDFLAGS)
|
||||
LIB_STDCXXFS ?= $(eval LIB_STDCXXFS := $$(shell echo 'int main(void) { MDBX_STD_FILESYSTEM_PATH probe; return probe.is_absolute(); }' | cat mdbx.h++ - | sed $$$$'1s/\xef\xbb\xbf//' | $(CXX) -x c++ $(CXXFLAGS) -Wno-error - -Wl,--allow-multiple-definition -lstdc++fs $(LIBS) $(LDFLAGS) $(EXE_LDFLAGS) -o /dev/null 2>probe4lstdfs.err >/dev/null && echo '-Wl,--allow-multiple-definition -lstdc++fs'))$(LIB_STDCXXFS)
|
||||
LIB_STDCXXFS ?= $(eval LIB_STDCXXFS := $$(shell echo '$$(cxx_filesystem_probe)' | cat mdbx.h++ - | sed $$$$'1s/\xef\xbb\xbf//' | $(CXX) -x c++ $(CXXFLAGS) -Wno-error - -Wl,--allow-multiple-definition -lstdc++fs $(LIBS) $(LDFLAGS) $(EXE_LDFLAGS) -o /dev/null 2>probe4lstdfs.err >/dev/null && echo '-Wl,--allow-multiple-definition -lstdc++fs'))$(LIB_STDCXXFS)
|
||||
endif
|
||||
|
||||
################################################################################
|
||||
|
@ -826,24 +826,106 @@ macro(setup_compile_flags)
|
||||
unset(MODULE_LINKER_FLAGS)
|
||||
endmacro(setup_compile_flags)
|
||||
|
||||
if(CMAKE_CXX_COMPILER_LOADED)
|
||||
# determine library for std::filesystem
|
||||
set(LIBCXX_FILESYSTEM "")
|
||||
if(CMAKE_COMPILER_IS_ELBRUSCXX)
|
||||
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 1.26.0)
|
||||
set(LIBCXX_FILESYSTEM "stdc++fs")
|
||||
endif()
|
||||
elseif(CMAKE_COMPILER_IS_CLANG)
|
||||
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
|
||||
set(LIBCXX_FILESYSTEM "c++experimental")
|
||||
elseif(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.0)
|
||||
set(LIBCXX_FILESYSTEM "stdc++fs")
|
||||
endif()
|
||||
elseif(CMAKE_COMPILER_IS_GNUCXX AND NOT MINGW)
|
||||
if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.3 AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.0)
|
||||
set(LIBCXX_FILESYSTEM "stdc++fs")
|
||||
macro(probe_libcxx_filesystem)
|
||||
if(CMAKE_CXX_COMPILER_LOADED AND NOT DEFINED LIBCXX_FILESYSTEM)
|
||||
list(FIND CMAKE_CXX_COMPILE_FEATURES cxx_std_11 HAS_CXX11)
|
||||
if(NOT HAS_CXX11 LESS 0)
|
||||
include(CMakePushCheckState)
|
||||
include(CheckCXXSourceCompiles)
|
||||
cmake_push_check_state()
|
||||
set(stdfs_probe_save_libraries ${CMAKE_REQUIRED_LIBRARIES})
|
||||
unset(stdfs_probe_clear_cxx_standard)
|
||||
if(NOT DEFINED CMAKE_CXX_STANDARD)
|
||||
list(FIND CMAKE_CXX_COMPILE_FEATURES cxx_std_14 HAS_CXX14)
|
||||
list(FIND CMAKE_CXX_COMPILE_FEATURES cxx_std_17 HAS_CXX17)
|
||||
if(NOT HAS_CXX17 LESS 0
|
||||
AND NOT (CMAKE_COMPILER_IS_CLANG AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5))
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
elseif(NOT HAS_CXX14 LESS 0)
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
else()
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
endif()
|
||||
set(stdfs_probe_clear_cxx_standard ON)
|
||||
endif()
|
||||
|
||||
set(stdfs_probe_code [[
|
||||
#if defined(__SIZEOF_INT128__) && !defined(__GLIBCXX_TYPE_INT_N_0) && defined(__clang__) && __clang_major__ < 4
|
||||
#define __GLIBCXX_BITSIZE_INT_N_0 128
|
||||
#define __GLIBCXX_TYPE_INT_N_0 __int128
|
||||
#endif
|
||||
|
||||
#ifndef __has_include
|
||||
#define __has_include(header) (0)
|
||||
#endif
|
||||
#if __has_include(<version>)
|
||||
#include <version>
|
||||
#endif
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#if defined(__cpp_lib_string_view) && __cpp_lib_string_view >= 201606L
|
||||
#include <string_view>
|
||||
#endif
|
||||
|
||||
#if defined(__cpp_lib_filesystem) && __cpp_lib_filesystem >= 201703L
|
||||
#include <filesystem>
|
||||
#else
|
||||
#include <experimental/filesystem>
|
||||
#endif
|
||||
|
||||
#if (defined(__cpp_lib_filesystem) && __cpp_lib_filesystem >= 201703L && (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101500) && (!defined(__IPHONE_OS_VERSION_MIN_REQUIRED) || __IPHONE_OS_VERSION_MIN_REQUIRED >= 130100))
|
||||
namespace fs = ::std::filesystem;
|
||||
#elif defined(__cpp_lib_experimental_filesystem) && __cpp_lib_experimental_filesystem >= 201406L
|
||||
namespace fs = ::std::experimental::filesystem;
|
||||
#endif
|
||||
|
||||
int main(int argc, const char*argv[]) {
|
||||
fs::path probe(argv[0]);
|
||||
if (argc != 1) throw fs::filesystem_error(std::string("fake"), std::error_code());
|
||||
return fs::is_directory(probe.relative_path());
|
||||
}
|
||||
]])
|
||||
set(LIBCXX_FILESYSTEM "")
|
||||
|
||||
check_cxx_source_compiles("${stdfs_probe_code}" LIBCXX_FILESYSTEM_none)
|
||||
if(LIBCXX_FILESYSTEM_none)
|
||||
message(STATUS "No linking with additional library needed for std::filesystem")
|
||||
else()
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${stdfs_probe_save_libraries} "stdc++fs")
|
||||
check_cxx_source_compiles("${stdfs_probe_code}" LIBCXX_FILESYSTEM_stdcxxfs)
|
||||
if(LIBCXX_FILESYSTEM_stdcxxfs)
|
||||
set(LIBCXX_FILESYSTEM "stdc++fs")
|
||||
message(STATUS "Linking with ${LIBCXX_FILESYSTEM} is required for std::filesystem")
|
||||
else()
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${stdfs_probe_save_libraries} "c++fs")
|
||||
check_cxx_source_compiles("${stdfs_probe_code}" LIBCXX_FILESYSTEM_cxxfs)
|
||||
if(LIBCXX_FILESYSTEM_cxxfs)
|
||||
set(LIBCXX_FILESYSTEM "c++fs")
|
||||
message(STATUS "Linking with ${LIBCXX_FILESYSTEM} is required for std::filesystem")
|
||||
else()
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${stdfs_probe_save_libraries} "c++experimental")
|
||||
check_cxx_source_compiles("${stdfs_probe_code}" LIBCXX_FILESYSTEM_cxxexperimental)
|
||||
if(LIBCXX_FILESYSTEM_cxxexperimental)
|
||||
set(LIBCXX_FILESYSTEM "c++experimental")
|
||||
message(STATUS "Linking with ${LIBCXX_FILESYSTEM} is required for std::filesystem")
|
||||
else()
|
||||
message(STATUS "No support for std::filesystem")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${stdfs_probe_save_libraries})
|
||||
if(stdfs_probe_clear_cxx_standard)
|
||||
unset(CMAKE_CXX_STANDARD)
|
||||
endif()
|
||||
unset(stdfs_probe_clear_cxx_standard)
|
||||
unset(stdfs_probe_save_libraries)
|
||||
unset(stdfs_probe_code)
|
||||
unset(stdfs_probe_rc)
|
||||
cmake_pop_check_state()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endmacro(probe_libcxx_filesystem)
|
||||
|
||||
cmake_policy(POP)
|
||||
|
@ -31,6 +31,7 @@ set(LIBMDBX_TEST_SOURCES
|
||||
)
|
||||
|
||||
if(NOT MDBX_BUILD_CXX)
|
||||
probe_libcxx_filesystem()
|
||||
list(APPEND LIBMDBX_TEST_SOURCES "${MDBX_SOURCE_DIR}/mdbx.c++" ../mdbx.h++)
|
||||
endif()
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user