diff options
author | Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> | 2024-03-23 16:50:57 +0000 |
---|---|---|
committer | Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> | 2024-08-16 19:27:36 +0100 |
commit | 07069e2bb0bbdacf16cf34efd3a33390de030217 (patch) | |
tree | c578e1feefa8518d5c62ba045594b8bcef9baa2e /cmake | |
parent | 27d687fc1f6aceaed7725e1e904a093ead68d6e6 (diff) |
cmake: Add introspection module
Co-authored-by: Cory Fields <cory-nospam-@coryfields.com>
Co-authored-by: Vasil Dimov <vd@FreeBSD.org>
Diffstat (limited to 'cmake')
-rw-r--r-- | cmake/bitcoin-config.h.in | 72 | ||||
-rw-r--r-- | cmake/introspection.cmake | 160 | ||||
-rw-r--r-- | cmake/module/CheckSourceCompilesAndLinks.cmake | 39 | ||||
-rw-r--r-- | cmake/module/TestAppendRequiredLibraries.cmake | 92 |
4 files changed, 363 insertions, 0 deletions
diff --git a/cmake/bitcoin-config.h.in b/cmake/bitcoin-config.h.in index 9811939f4f..6b8f5d713d 100644 --- a/cmake/bitcoin-config.h.in +++ b/cmake/bitcoin-config.h.in @@ -29,6 +29,75 @@ /* Copyright year */ #define COPYRIGHT_YEAR @COPYRIGHT_YEAR@ +/* Define to 1 if you have the declaration of `fork', and to 0 if you don't. + */ +#cmakedefine01 HAVE_DECL_FORK + +/* Define to 1 if you have the declaration of `freeifaddrs', and to 0 if you + don't. */ +#cmakedefine01 HAVE_DECL_FREEIFADDRS + +/* Define to 1 if you have the declaration of `getifaddrs', and to 0 if you + don't. */ +#cmakedefine01 HAVE_DECL_GETIFADDRS + +/* Define to 1 if you have the declaration of `pipe2', and to 0 if you don't. + */ +#cmakedefine01 HAVE_DECL_PIPE2 + +/* Define to 1 if you have the declaration of `setsid', and to 0 if you don't. + */ +#cmakedefine01 HAVE_DECL_SETSID + +/* Define to 1 if fdatasync is available. */ +#cmakedefine HAVE_FDATASYNC 1 + +/* Define this symbol if the BSD getentropy system call is available with + sys/random.h */ +#cmakedefine HAVE_GETENTROPY_RAND 1 + +/* Define this symbol if the Linux getrandom function call is available */ +#cmakedefine HAVE_GETRANDOM 1 + +/* Define this symbol if you have malloc_info */ +#cmakedefine HAVE_MALLOC_INFO 1 + +/* Define this symbol if you have mallopt with M_ARENA_MAX */ +#cmakedefine HAVE_MALLOPT_ARENA_MAX 1 + +/* Define to 1 if O_CLOEXEC flag is available. */ +#cmakedefine01 HAVE_O_CLOEXEC + +/* Define this symbol if you have posix_fallocate */ +#cmakedefine HAVE_POSIX_FALLOCATE 1 + +/* Define this symbol if platform supports unix domain sockets */ +#cmakedefine HAVE_SOCKADDR_UN 1 + +/* Define this symbol to build code that uses getauxval */ +#cmakedefine HAVE_STRONG_GETAUXVAL 1 + +/* Define this symbol if the BSD sysctl() is available */ +#cmakedefine HAVE_SYSCTL 1 + +/* Define this symbol if the BSD sysctl(KERN_ARND) is available */ +#cmakedefine HAVE_SYSCTL_ARND 1 + +/* Define to 1 if std::system or ::wsystem is available. */ +#cmakedefine HAVE_SYSTEM 1 + +/* Define to 1 if you have the <sys/prctl.h> header file. */ +#cmakedefine HAVE_SYS_PRCTL_H 1 + +/* Define to 1 if you have the <sys/resources.h> header file. */ +#cmakedefine HAVE_SYS_RESOURCES_H 1 + +/* Define to 1 if you have the <sys/vmmeter.h> header file. */ +#cmakedefine HAVE_SYS_VMMETER_H 1 + +/* Define to 1 if you have the <vm/vm_param.h> header file. */ +#cmakedefine HAVE_VM_VM_PARAM_H 1 + /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "@PACKAGE_BUGREPORT@" @@ -41,4 +110,7 @@ /* Define to the version of this package. */ #define PACKAGE_VERSION "@PACKAGE_VERSION@" +/* Define to 1 if strerror_r returns char *. */ +#cmakedefine STRERROR_R_CHAR_P 1 + #endif //BITCOIN_CONFIG_H diff --git a/cmake/introspection.cmake b/cmake/introspection.cmake new file mode 100644 index 0000000000..8d385b7ccf --- /dev/null +++ b/cmake/introspection.cmake @@ -0,0 +1,160 @@ +# Copyright (c) 2023-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +include(CheckCXXSourceCompiles) +include(CheckCXXSymbolExists) +include(CheckIncludeFileCXX) + +# The following HAVE_{HEADER}_H variables go to the bitcoin-config.h header. +check_include_file_cxx(sys/prctl.h HAVE_SYS_PRCTL_H) +check_include_file_cxx(sys/resources.h HAVE_SYS_RESOURCES_H) +check_include_file_cxx(sys/vmmeter.h HAVE_SYS_VMMETER_H) +check_include_file_cxx(vm/vm_param.h HAVE_VM_VM_PARAM_H) + +check_cxx_symbol_exists(O_CLOEXEC "fcntl.h" HAVE_O_CLOEXEC) +check_cxx_symbol_exists(fdatasync "unistd.h" HAVE_FDATASYNC) +check_cxx_symbol_exists(fork "unistd.h" HAVE_DECL_FORK) +check_cxx_symbol_exists(pipe2 "unistd.h" HAVE_DECL_PIPE2) +check_cxx_symbol_exists(setsid "unistd.h" HAVE_DECL_SETSID) + +check_include_file_cxx(sys/types.h HAVE_SYS_TYPES_H) +check_include_file_cxx(ifaddrs.h HAVE_IFADDRS_H) +if(HAVE_SYS_TYPES_H AND HAVE_IFADDRS_H) + include(TestAppendRequiredLibraries) + test_append_socket_library(core_interface) +endif() + +include(TestAppendRequiredLibraries) +test_append_atomic_library(core_interface) + +check_cxx_symbol_exists(std::system "cstdlib" HAVE_STD_SYSTEM) +check_cxx_symbol_exists(::_wsystem "stdlib.h" HAVE__WSYSTEM) +if(HAVE_STD_SYSTEM OR HAVE__WSYSTEM) + set(HAVE_SYSTEM 1) +endif() + +check_cxx_source_compiles(" + #include <string.h> + + int main() + { + char buf[100]; + char* p{strerror_r(0, buf, sizeof buf)}; + (void)p; + } + " STRERROR_R_CHAR_P +) + +# Check for malloc_info (for memory statistics information in getmemoryinfo). +check_cxx_symbol_exists(malloc_info "malloc.h" HAVE_MALLOC_INFO) + +# Check for mallopt(M_ARENA_MAX) (to set glibc arenas). +check_cxx_source_compiles(" + #include <malloc.h> + + int main() + { + mallopt(M_ARENA_MAX, 1); + } + " HAVE_MALLOPT_ARENA_MAX +) + +# Check for posix_fallocate(). +check_cxx_source_compiles(" + // same as in src/util/fs_helpers.cpp + #ifdef __linux__ + #ifdef _POSIX_C_SOURCE + #undef _POSIX_C_SOURCE + #endif + #define _POSIX_C_SOURCE 200112L + #endif // __linux__ + #include <fcntl.h> + + int main() + { + return posix_fallocate(0, 0, 0); + } + " HAVE_POSIX_FALLOCATE +) + +# Check for strong getauxval() support in the system headers. +check_cxx_source_compiles(" + #include <sys/auxv.h> + + int main() + { + getauxval(AT_HWCAP); + } + " HAVE_STRONG_GETAUXVAL +) + +# Check for UNIX sockets. +check_cxx_source_compiles(" + #include <sys/socket.h> + #include <sys/un.h> + + int main() + { + struct sockaddr_un addr; + addr.sun_family = AF_UNIX; + } + " HAVE_SOCKADDR_UN +) + +# Check for different ways of gathering OS randomness: +# - Linux getrandom() +check_cxx_source_compiles(" + #include <sys/random.h> + + int main() + { + getrandom(nullptr, 32, 0); + } + " HAVE_GETRANDOM +) + +# - BSD getentropy() +check_cxx_source_compiles(" + #include <sys/random.h> + + int main() + { + getentropy(nullptr, 32); + } + " HAVE_GETENTROPY_RAND +) + + +# - BSD sysctl() +check_cxx_source_compiles(" + #include <sys/types.h> + #include <sys/sysctl.h> + + #ifdef __linux__ + #error Don't use sysctl on Linux, it's deprecated even when it works + #endif + + int main() + { + sysctl(nullptr, 2, nullptr, nullptr, nullptr, 0); + } + " HAVE_SYSCTL +) + +# - BSD sysctl(KERN_ARND) +check_cxx_source_compiles(" + #include <sys/types.h> + #include <sys/sysctl.h> + + #ifdef __linux__ + #error Don't use sysctl on Linux, it's deprecated even when it works + #endif + + int main() + { + static int name[2] = {CTL_KERN, KERN_ARND}; + sysctl(name, 2, nullptr, nullptr, nullptr, 0); + } + " HAVE_SYSCTL_ARND +) diff --git a/cmake/module/CheckSourceCompilesAndLinks.cmake b/cmake/module/CheckSourceCompilesAndLinks.cmake new file mode 100644 index 0000000000..88c897d524 --- /dev/null +++ b/cmake/module/CheckSourceCompilesAndLinks.cmake @@ -0,0 +1,39 @@ +# Copyright (c) 2023-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +include_guard(GLOBAL) +include(CheckCXXSourceCompiles) +include(CMakePushCheckState) + +# This avoids running the linker. +set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) + +macro(check_cxx_source_links source) + set(CMAKE_TRY_COMPILE_TARGET_TYPE EXECUTABLE) + check_cxx_source_compiles("${source}" ${ARGN}) + set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) +endmacro() + +macro(check_cxx_source_compiles_with_flags flags source) + cmake_push_check_state(RESET) + set(CMAKE_REQUIRED_FLAGS ${flags}) + list(JOIN CMAKE_REQUIRED_FLAGS " " CMAKE_REQUIRED_FLAGS) + check_cxx_source_compiles("${source}" ${ARGN}) + cmake_pop_check_state() +endmacro() + +macro(check_cxx_source_links_with_flags flags source) + cmake_push_check_state(RESET) + set(CMAKE_REQUIRED_FLAGS ${flags}) + list(JOIN CMAKE_REQUIRED_FLAGS " " CMAKE_REQUIRED_FLAGS) + check_cxx_source_links("${source}" ${ARGN}) + cmake_pop_check_state() +endmacro() + +macro(check_cxx_source_links_with_libs libs source) + cmake_push_check_state(RESET) + set(CMAKE_REQUIRED_LIBRARIES "${libs}") + check_cxx_source_links("${source}" ${ARGN}) + cmake_pop_check_state() +endmacro() diff --git a/cmake/module/TestAppendRequiredLibraries.cmake b/cmake/module/TestAppendRequiredLibraries.cmake new file mode 100644 index 0000000000..5352102c7a --- /dev/null +++ b/cmake/module/TestAppendRequiredLibraries.cmake @@ -0,0 +1,92 @@ +# Copyright (c) 2023-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit/. + +include_guard(GLOBAL) + +# Illumos/SmartOS requires linking with -lsocket if +# using getifaddrs & freeifaddrs. +# See: +# - https://github.com/bitcoin/bitcoin/pull/21486 +# - https://smartos.org/man/3socket/getifaddrs +function(test_append_socket_library target) + if (NOT TARGET ${target}) + message(FATAL_ERROR "${CMAKE_CURRENT_FUNCTION}() called with non-existent target \"${target}\".") + endif() + + set(check_socket_source " + #include <sys/types.h> + #include <ifaddrs.h> + + int main() { + struct ifaddrs* ifaddr; + getifaddrs(&ifaddr); + freeifaddrs(ifaddr); + } + ") + + include(CheckSourceCompilesAndLinks) + check_cxx_source_links("${check_socket_source}" IFADDR_LINKS_WITHOUT_LIBSOCKET) + if(NOT IFADDR_LINKS_WITHOUT_LIBSOCKET) + check_cxx_source_links_with_libs(socket "${check_socket_source}" IFADDR_NEEDS_LINK_TO_LIBSOCKET) + if(IFADDR_NEEDS_LINK_TO_LIBSOCKET) + target_link_libraries(${target} INTERFACE socket) + else() + message(FATAL_ERROR "Cannot figure out how to use getifaddrs/freeifaddrs.") + endif() + endif() + set(HAVE_DECL_GETIFADDRS TRUE PARENT_SCOPE) + set(HAVE_DECL_FREEIFADDRS TRUE PARENT_SCOPE) +endfunction() + +# Clang, when building for 32-bit, +# and linking against libstdc++, requires linking with +# -latomic if using the C++ atomic library. +# Can be tested with: clang++ -std=c++20 test.cpp -m32 +# +# Sourced from http://bugs.debian.org/797228 +function(test_append_atomic_library target) + if (NOT TARGET ${target}) + message(FATAL_ERROR "${CMAKE_CURRENT_FUNCTION}() called with non-existent target \"${target}\".") + endif() + + set(check_atomic_source " + #include <atomic> + #include <cstdint> + #include <chrono> + + using namespace std::chrono_literals; + + int main() { + std::atomic<bool> lock{true}; + lock.exchange(false); + + std::atomic<std::chrono::seconds> t{0s}; + t.store(2s); + auto t1 = t.load(); + t.compare_exchange_strong(t1, 3s); + + std::atomic<double> d{}; + d.store(3.14); + auto d1 = d.load(); + + std::atomic<int64_t> a{}; + int64_t v = 5; + int64_t r = a.fetch_add(v); + return static_cast<int>(r); + } + ") + + include(CheckSourceCompilesAndLinks) + check_cxx_source_links("${check_atomic_source}" STD_ATOMIC_LINKS_WITHOUT_LIBATOMIC) + if(STD_ATOMIC_LINKS_WITHOUT_LIBATOMIC) + return() + endif() + + check_cxx_source_links_with_libs(atomic "${check_atomic_source}" STD_ATOMIC_NEEDS_LINK_TO_LIBATOMIC) + if(STD_ATOMIC_NEEDS_LINK_TO_LIBATOMIC) + target_link_libraries(${target} INTERFACE atomic) + else() + message(FATAL_ERROR "Cannot figure out how to use std::atomic.") + endif() +endfunction() |