Skip to content

Commit

Permalink
Merge #6: build: Add CMake-based build system (2 of N)
Browse files Browse the repository at this point in the history
df89945 cmake: Build `leveldb` static library (Hennadii Stepanov)
2e2ce85 cmake: Build `crc32c` static library (Hennadii Stepanov)
4cd5efd cmake: Check compiler features (Hennadii Stepanov)
89be42f cmake: Check system symbols (Hennadii Stepanov)
64b1fd4 cmake: Check system headers (Hennadii Stepanov)
7b87a48 cmake: Add `cmake/introspection.cmake` file (Hennadii Stepanov)

Pull request description:

  The parent PR: bitcoin#25797.
  The previous PR in the staging branch: #5.

  This PR details:

  1. Added project-wide system introspection.

  | Autoconf macro | Symbols in `bitcoin-config.h` | CMake implementation |
  |---|---|---|
  | [`AC_INIT`](https://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.69/autoconf.html#Initializing-configure) | `PACKAGE_NAME` `PACKAGE_TARNAME` `PACKAGE_VERSION` `PACKAGE_STRING` `PACKAGE_BUGREPORT` `PACKAGE_URL` | Done in #5, except for `PACKAGE_TARNAME` and `PACKAGE_STRING`, which are not currently used |
  | [`AX_CXX_COMPILE_STDCXX`](https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html) | `HAVE_CXX17` `HAVE_CXX20` | CMake uses its own [implementation](https://cmake.org/cmake/help/latest/prop_tgt/CXX_STANDARD.html) |
  | [`AC_C_BIGENDIAN`](https://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.69/autoconf.html#index-AC_005fC_005fBIGENDIAN-892) | `AC_APPLE_UNIVERSAL_BUILD` `WORDS_BIGENDIAN` and C headers | CMake uses its own [implementation](https://cmake.org/cmake/help/latest/module/TestBigEndian.html) |
  | [`AX_PTHREAD`](https://www.gnu.org/software/autoconf-archive/ax_pthread.html) | `HAVE_PTHREAD` `HAVE_PTHREAD_PRIO_INHERIT` `PTHREAD_CREATE_JOINABLE` | CMake uses its own [implementation](https://cmake.org/cmake/help/latest/module/FindThreads.html) |
  | [`AC_SYS_LARGEFILE`](https://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.69/autoconf.html#index-AC_005fSYS_005fLARGEFILE-1103) | `_FILE_OFFSET_BITS` `_LARGE_FILES` | _Not implemented yet_ |
  | [`AC_FUNC_STRERROR_R`](https://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.69/autoconf.html#index-AC_005fFUNC_005fSTRERROR_005fR-517) | `HAVE_DECL_STRERROR_R` `HAVE_STRERROR_R` `STRERROR_R_CHAR_P` and C headers  | Implemented `STRERROR_R_CHAR_P`, others are not used
  | C headers |  `HAVE_INTTYPES_H` `HAVE_STDINT_H` `HAVE_STDIO_H` `HAVE_STDLIB_H` `HAVE_STRINGS_H` `HAVE_STRING_H` `HAVE_SYS_STAT_H` `HAVE_SYS_TYPES_H` `HAVE_UNISTD_H` `STDC_HEADERS` | Only `HAVE_STRING_H`, `HAVE_SYS_TYPES_H` and `HAVE_UNISTD_H` are evaluated for internal needs

  ---

  2. Added the `leveldb` build target (including its `crc32c` dependency):

  - on Linux / *BSD / macOS:
  ```sh
  cmake -S . -B build
  cmake --build build --target leveldb
  ```

  - on Windows:
  ```cmd
  cmake -G "Visual Studio 17 2022" -A x64 -S . -B build
  cmake --build build --config Debug --target leveldb  # or --config Release
  ```

  **NOTE**. On Windows (MSVC), the `leveldb` library now uses `crc32c` one. That is not the case when using the current build system from the `build_msvc` directory: https://github.com/hebasto/bitcoin/blob/fe1b3256888bd0e70d0c9655f565e139ec87b606/build_msvc/libleveldb/libleveldb.vcxproj#L53

ACKs for top commit:
  theuni:
    > ACK [df89945](df89945)
  TheCharlatan:
    ACK df89945

Tree-SHA512: 9a7a4e2d22d5e18af20fec937f64ce43b5c296576abde61db3e4420edadb87d2e830d331fabbf4e8c17e557bf9bd534f491b227d2554839651967f20707bba7b
  • Loading branch information
hebasto committed Feb 23, 2023
2 parents 3bc91d2 + df89945 commit 9c83f07
Show file tree
Hide file tree
Showing 6 changed files with 676 additions and 0 deletions.
8 changes: 8 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ set(COPYRIGHT_HOLDERS "The %s developers")
set(COPYRIGHT_HOLDERS_FINAL "The ${PROJECT_NAME} developers")
set(PACKAGE_BUGREPORT "https://github.com/bitcoin/bitcoin/issues")

list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/module)

# Configurable options.
# When adding a new option, end the <help_text> with a full stop for consistency.
include(CMakeDependentOption)
Expand All @@ -58,6 +60,12 @@ else()
endif()
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

include(CheckSourceCompilesAndLinks)
include(cmake/introspection.cmake)

include(cmake/crc32c.cmake)
include(cmake/leveldb.cmake)

add_subdirectory(src)

message("\n")
Expand Down
160 changes: 160 additions & 0 deletions cmake/bitcoin-config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@

#define BITCOIN_CONFIG_H

/* Define this symbol if type char equals int8_t */
#cmakedefine CHAR_EQUALS_INT8 1

/* Version Build */
#define CLIENT_VERSION_BUILD @PROJECT_VERSION_PATCH@

Expand All @@ -30,6 +33,156 @@
/* Copyright year */
#define COPYRIGHT_YEAR @COPYRIGHT_YEAR@

/* Define this symbol if you have __builtin_clzl */
#cmakedefine HAVE_BUILTIN_CLZL 1

/* Define this symbol if you have __builtin_clzll */
#cmakedefine HAVE_BUILTIN_CLZLL 1

/* Define to 1 if you have the <byteswap.h> header file. */
#cmakedefine HAVE_BYTESWAP_H 1

/* Define to 1 if you have the declaration of `be16toh', and to 0 if you
don't. */
#cmakedefine01 HAVE_DECL_BE16TOH

/* Define to 1 if you have the declaration of `be32toh', and to 0 if you
don't. */
#cmakedefine01 HAVE_DECL_BE32TOH

/* Define to 1 if you have the declaration of `be64toh', and to 0 if you
don't. */
#cmakedefine01 HAVE_DECL_BE64TOH

/* Define to 1 if you have the declaration of `bswap_16', and to 0 if you
don't. */
#cmakedefine01 HAVE_DECL_BSWAP_16

/* Define to 1 if you have the declaration of `bswap_32', and to 0 if you
don't. */
#cmakedefine01 HAVE_DECL_BSWAP_32

/* Define to 1 if you have the declaration of `bswap_64', and to 0 if you
don't. */
#cmakedefine01 HAVE_DECL_BSWAP_64

/* 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 `htobe16', and to 0 if you
don't. */
#cmakedefine01 HAVE_DECL_HTOBE16

/* Define to 1 if you have the declaration of `htobe32', and to 0 if you
don't. */
#cmakedefine01 HAVE_DECL_HTOBE32

/* Define to 1 if you have the declaration of `htobe64', and to 0 if you
don't. */
#cmakedefine01 HAVE_DECL_HTOBE64

/* Define to 1 if you have the declaration of `htole16', and to 0 if you
don't. */
#cmakedefine01 HAVE_DECL_HTOLE16

/* Define to 1 if you have the declaration of `htole32', and to 0 if you
don't. */
#cmakedefine01 HAVE_DECL_HTOLE32

/* Define to 1 if you have the declaration of `htole64', and to 0 if you
don't. */
#cmakedefine01 HAVE_DECL_HTOLE64

/* Define to 1 if you have the declaration of `le16toh', and to 0 if you
don't. */
#cmakedefine01 HAVE_DECL_LE16TOH

/* Define to 1 if you have the declaration of `le32toh', and to 0 if you
don't. */
#cmakedefine01 HAVE_DECL_LE32TOH

/* Define to 1 if you have the declaration of `le64toh', and to 0 if you
don't. */
#cmakedefine01 HAVE_DECL_LE64TOH

/* 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 if the visibility attribute is supported. */
#cmakedefine HAVE_DEFAULT_VISIBILITY_ATTRIBUTE 1

/* Define if the dllexport attribute is supported. */
#cmakedefine HAVE_DLLEXPORT_ATTRIBUTE 1

/* Define to 1 if you have the <endian.h> header file. */
#cmakedefine HAVE_ENDIAN_H 1

/* 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 gmtime_r is available */
#cmakedefine HAVE_GMTIME_R 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 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/endian.h> header file. */
#cmakedefine HAVE_SYS_ENDIAN_H 1

/* Define this symbol if the Linux getrandom system call is available */
#cmakedefine HAVE_SYS_GETRANDOM 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@"

Expand All @@ -42,4 +195,11 @@
/* Define to the version of this package. */
#define PACKAGE_VERSION "@PROJECT_VERSION@"

/* Define to 1 if strerror_r returns char *. */
#cmakedefine STRERROR_R_CHAR_P 1

/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#cmakedefine WORDS_BIGENDIAN 1

#endif //BITCOIN_CONFIG_H
113 changes: 113 additions & 0 deletions cmake/crc32c.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# Copyright (c) 2023 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.

# This file is part of the transition from Autotools to CMake. Once CMake
# support has been merged we should switch to using the upstream CMake
# buildsystem.

include(CheckCXXSourceCompiles)

# Check for __builtin_prefetch support in the compiler.
check_cxx_source_compiles("
int main() {
char data = 0;
const char* address = &data;
__builtin_prefetch(address, 0, 0);
return 0;
}
" HAVE_BUILTIN_PREFETCH
)

# Check for _mm_prefetch support in the compiler.
check_cxx_source_compiles("
#if defined(_MSC_VER)
#include <intrin.h>
#else
#include <xmmintrin.h>
#endif
int main() {
char data = 0;
const char* address = &data;
_mm_prefetch(address, _MM_HINT_NTA);
return 0;
}
" HAVE_MM_PREFETCH
)

# Check for SSE4.2 support in the compiler.
if(MSVC)
set(SSE42_CXXFLAGS /arch:AVX)
else()
set(SSE42_CXXFLAGS -msse4.2)
endif()
check_cxx_source_compiles_with_flags("${SSE42_CXXFLAGS}" "
#include <cstdint>
#if defined(_MSC_VER)
#include <intrin.h>
#elif defined(__GNUC__) && defined(__SSE4_2__)
#include <nmmintrin.h>
#endif
int main() {
uint64_t l = 0;
l = _mm_crc32_u8(l, 0);
l = _mm_crc32_u32(l, 0);
l = _mm_crc32_u64(l, 0);
return l;
}
" HAVE_SSE42
)

# Check for ARMv8 w/ CRC and CRYPTO extensions support in the compiler.
set(ARM_CRC_CXXFLAGS -march=armv8-a+crc)
check_cxx_source_compiles_with_flags("${ARM_CRC_CXXFLAGS}" "
#include <arm_acle.h>
#include <arm_neon.h>
int main() {
#ifdef __aarch64__
__crc32cb(0, 0); __crc32ch(0, 0); __crc32cw(0, 0); __crc32cd(0, 0);
vmull_p64(0, 0);
#else
#error crc32c library does not support hardware acceleration on 32-bit ARM
#endif
return 0;
}
" HAVE_ARM64_CRC32C
)

add_library(crc32c STATIC EXCLUDE_FROM_ALL
${PROJECT_SOURCE_DIR}/src/crc32c/src/crc32c.cc
${PROJECT_SOURCE_DIR}/src/crc32c/src/crc32c_portable.cc
)

target_compile_definitions(crc32c
PRIVATE
HAVE_BUILTIN_PREFETCH=$<BOOL:${HAVE_BUILTIN_PREFETCH}>
HAVE_MM_PREFETCH=$<BOOL:${HAVE_MM_PREFETCH}>
HAVE_STRONG_GETAUXVAL=$<BOOL:${HAVE_STRONG_GETAUXVAL}>
HAVE_SSE42=$<BOOL:${HAVE_SSE42}>
HAVE_ARM64_CRC32C=$<BOOL:${HAVE_ARM64_CRC32C}>
BYTE_ORDER_BIG_ENDIAN=${WORDS_BIGENDIAN}
)

target_include_directories(crc32c
PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src/crc32c/include>
)

if(HAVE_SSE42)
target_sources(crc32c PRIVATE ${PROJECT_SOURCE_DIR}/src/crc32c/src/crc32c_sse42.cc)
set_property(SOURCE ${PROJECT_SOURCE_DIR}/src/crc32c/src/crc32c_sse42.cc
APPEND PROPERTY COMPILE_OPTIONS ${SSE42_CXXFLAGS}
)
endif()

if(HAVE_ARM64_CRC32C)
target_sources(crc32c PRIVATE ${PROJECT_SOURCE_DIR}/src/crc32c/src/crc32c_arm64.cc)
set_property(SOURCE ${PROJECT_SOURCE_DIR}/src/crc32c/src/crc32c_arm64.cc
APPEND PROPERTY COMPILE_OPTIONS ${ARM_CRC_CXXFLAGS}
)
endif()
Loading

0 comments on commit 9c83f07

Please sign in to comment.