From a8c78a0574d394d6a46edc0924a85180087dc9fa Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Fri, 21 Feb 2025 11:11:29 +0000 Subject: [PATCH 1/2] cmake: Revamp handling of data files This change introduces new functions `target_json_data_sources()` and `target_raw_data_sources()`. --- cmake/module/GenerateHeaders.cmake | 29 ----- cmake/module/TargetDataSources.cmake | 45 +++++++ src/bench/CMakeLists.txt | 9 +- src/test/CMakeLists.txt | 38 +++--- src/univalue/CMakeLists.txt | 169 +++++++++------------------ 5 files changed, 124 insertions(+), 166 deletions(-) delete mode 100644 cmake/module/GenerateHeaders.cmake create mode 100644 cmake/module/TargetDataSources.cmake diff --git a/cmake/module/GenerateHeaders.cmake b/cmake/module/GenerateHeaders.cmake deleted file mode 100644 index 53b211f245c..00000000000 --- a/cmake/module/GenerateHeaders.cmake +++ /dev/null @@ -1,29 +0,0 @@ -# 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/. - -if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.27) - set(DEPENDS_EXPLICIT_OPT DEPENDS_EXPLICIT_ONLY) -else() - set(DEPENDS_EXPLICIT_OPT) -endif() - -function(generate_header_from_json json_source_relpath) - add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${json_source_relpath}.h - COMMAND ${CMAKE_COMMAND} -DJSON_SOURCE_PATH=${CMAKE_CURRENT_SOURCE_DIR}/${json_source_relpath} -DHEADER_PATH=${CMAKE_CURRENT_BINARY_DIR}/${json_source_relpath}.h -P ${PROJECT_SOURCE_DIR}/cmake/script/GenerateHeaderFromJson.cmake - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${json_source_relpath} ${PROJECT_SOURCE_DIR}/cmake/script/GenerateHeaderFromJson.cmake - VERBATIM - ${DEPENDS_EXPLICIT_OPT} - ) -endfunction() - -function(generate_header_from_raw raw_source_relpath raw_namespace) - add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${raw_source_relpath}.h - COMMAND ${CMAKE_COMMAND} -DRAW_SOURCE_PATH=${CMAKE_CURRENT_SOURCE_DIR}/${raw_source_relpath} -DHEADER_PATH=${CMAKE_CURRENT_BINARY_DIR}/${raw_source_relpath}.h -DRAW_NAMESPACE=${raw_namespace} -P ${PROJECT_SOURCE_DIR}/cmake/script/GenerateHeaderFromRaw.cmake - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${raw_source_relpath} ${PROJECT_SOURCE_DIR}/cmake/script/GenerateHeaderFromRaw.cmake - VERBATIM - ${DEPENDS_EXPLICIT_OPT} - ) -endfunction() diff --git a/cmake/module/TargetDataSources.cmake b/cmake/module/TargetDataSources.cmake new file mode 100644 index 00000000000..a1abd25a7c6 --- /dev/null +++ b/cmake/module/TargetDataSources.cmake @@ -0,0 +1,45 @@ +# 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/. + +macro(set_add_custom_command_options) + set(DEPENDS_EXPLICIT_OPT "") + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.27) + set(DEPENDS_EXPLICIT_OPT DEPENDS_EXPLICIT_ONLY) + endif() +endmacro() + +# Specifies JSON data files to be processed into corresponding +# header files for inclusion when building a target. +function(target_json_data_sources target) + set_add_custom_command_options() + foreach(json_file IN LISTS ARGN) + set(header ${CMAKE_CURRENT_BINARY_DIR}/${json_file}.h) + add_custom_command( + OUTPUT ${header} + COMMAND ${CMAKE_COMMAND} -DJSON_SOURCE_PATH=${CMAKE_CURRENT_SOURCE_DIR}/${json_file} -DHEADER_PATH=${header} -P ${PROJECT_SOURCE_DIR}/cmake/script/GenerateHeaderFromJson.cmake + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${json_file} ${PROJECT_SOURCE_DIR}/cmake/script/GenerateHeaderFromJson.cmake + VERBATIM + ${DEPENDS_EXPLICIT_OPT} + ) + target_sources(${target} PRIVATE ${header}) + endforeach() +endfunction() + +# Specifies raw binary data files to be processed into corresponding +# header files for inclusion when building a target. +function(target_raw_data_sources target) + cmake_parse_arguments(PARSE_ARGV 1 _ "" "NAMESPACE" "") + set_add_custom_command_options() + foreach(raw_file IN LISTS __UNPARSED_ARGUMENTS) + set(header ${CMAKE_CURRENT_BINARY_DIR}/${raw_file}.h) + add_custom_command( + OUTPUT ${header} + COMMAND ${CMAKE_COMMAND} -DRAW_SOURCE_PATH=${CMAKE_CURRENT_SOURCE_DIR}/${raw_file} -DHEADER_PATH=${header} -DRAW_NAMESPACE=${__NAMESPACE} -P ${PROJECT_SOURCE_DIR}/cmake/script/GenerateHeaderFromRaw.cmake + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${raw_file} ${PROJECT_SOURCE_DIR}/cmake/script/GenerateHeaderFromRaw.cmake + VERBATIM + ${DEPENDS_EXPLICIT_OPT} + ) + target_sources(${target} PRIVATE ${header}) + endforeach() +endfunction() diff --git a/src/bench/CMakeLists.txt b/src/bench/CMakeLists.txt index 43b0dcdabe6..16eb29250f5 100644 --- a/src/bench/CMakeLists.txt +++ b/src/bench/CMakeLists.txt @@ -2,14 +2,10 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or https://opensource.org/license/mit/. -include(GenerateHeaders) -generate_header_from_raw(data/block413567.raw benchmark::data) - add_executable(bench_bitcoin bench_bitcoin.cpp bench.cpp nanobench.cpp - ${CMAKE_CURRENT_BINARY_DIR}/data/block413567.raw.h # Benchmarks: addrman.cpp base58.cpp @@ -56,6 +52,11 @@ add_executable(bench_bitcoin xor.cpp ) +include(TargetDataSources) +target_raw_data_sources(bench_bitcoin NAMESPACE benchmark::data + data/block413567.raw +) + target_link_libraries(bench_bitcoin core_interface test_util diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index b0dd27894d3..6d75344194f 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -2,32 +2,10 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or https://opensource.org/license/mit/. -include(GenerateHeaders) -generate_header_from_json(data/base58_encode_decode.json) -generate_header_from_json(data/bip341_wallet_vectors.json) -generate_header_from_json(data/blockfilters.json) -generate_header_from_json(data/key_io_invalid.json) -generate_header_from_json(data/key_io_valid.json) -generate_header_from_json(data/script_tests.json) -generate_header_from_json(data/sighash.json) -generate_header_from_json(data/tx_invalid.json) -generate_header_from_json(data/tx_valid.json) -generate_header_from_raw(data/asmap.raw test::data) - # Do not use generator expressions in test sources because the # SOURCES property is processed to gather test suite macros. add_executable(test_bitcoin main.cpp - ${CMAKE_CURRENT_BINARY_DIR}/data/asmap.raw.h - ${CMAKE_CURRENT_BINARY_DIR}/data/base58_encode_decode.json.h - ${CMAKE_CURRENT_BINARY_DIR}/data/bip341_wallet_vectors.json.h - ${CMAKE_CURRENT_BINARY_DIR}/data/blockfilters.json.h - ${CMAKE_CURRENT_BINARY_DIR}/data/key_io_invalid.json.h - ${CMAKE_CURRENT_BINARY_DIR}/data/key_io_valid.json.h - ${CMAKE_CURRENT_BINARY_DIR}/data/script_tests.json.h - ${CMAKE_CURRENT_BINARY_DIR}/data/sighash.json.h - ${CMAKE_CURRENT_BINARY_DIR}/data/tx_invalid.json.h - ${CMAKE_CURRENT_BINARY_DIR}/data/tx_valid.json.h addrman_tests.cpp allocator_tests.cpp amount_tests.cpp @@ -146,6 +124,22 @@ add_executable(test_bitcoin versionbits_tests.cpp ) +include(TargetDataSources) +target_json_data_sources(test_bitcoin + data/base58_encode_decode.json + data/bip341_wallet_vectors.json + data/blockfilters.json + data/key_io_invalid.json + data/key_io_valid.json + data/script_tests.json + data/sighash.json + data/tx_invalid.json + data/tx_valid.json +) +target_raw_data_sources(test_bitcoin NAMESPACE test::data + data/asmap.raw +) + target_link_libraries(test_bitcoin core_interface test_util diff --git a/src/univalue/CMakeLists.txt b/src/univalue/CMakeLists.txt index c31e82cadcc..83cb4f12263 100644 --- a/src/univalue/CMakeLists.txt +++ b/src/univalue/CMakeLists.txt @@ -15,120 +15,67 @@ target_include_directories(univalue target_link_libraries(univalue PRIVATE core_interface) if(BUILD_TESTS) - include(GenerateHeaders) - generate_header_from_json(test/fail1.json) - generate_header_from_json(test/fail10.json) - generate_header_from_json(test/fail11.json) - generate_header_from_json(test/fail12.json) - generate_header_from_json(test/fail13.json) - generate_header_from_json(test/fail14.json) - generate_header_from_json(test/fail15.json) - generate_header_from_json(test/fail16.json) - generate_header_from_json(test/fail17.json) - generate_header_from_json(test/fail18.json) - generate_header_from_json(test/fail19.json) - generate_header_from_json(test/fail2.json) - generate_header_from_json(test/fail20.json) - generate_header_from_json(test/fail21.json) - generate_header_from_json(test/fail22.json) - generate_header_from_json(test/fail23.json) - generate_header_from_json(test/fail24.json) - generate_header_from_json(test/fail25.json) - generate_header_from_json(test/fail26.json) - generate_header_from_json(test/fail27.json) - generate_header_from_json(test/fail28.json) - generate_header_from_json(test/fail29.json) - generate_header_from_json(test/fail3.json) - generate_header_from_json(test/fail30.json) - generate_header_from_json(test/fail31.json) - generate_header_from_json(test/fail32.json) - generate_header_from_json(test/fail33.json) - generate_header_from_json(test/fail34.json) - generate_header_from_json(test/fail35.json) - generate_header_from_json(test/fail36.json) - generate_header_from_json(test/fail37.json) - generate_header_from_json(test/fail38.json) - generate_header_from_json(test/fail39.json) - generate_header_from_json(test/fail4.json) - generate_header_from_json(test/fail40.json) - generate_header_from_json(test/fail41.json) - generate_header_from_json(test/fail42.json) - generate_header_from_json(test/fail44.json) - generate_header_from_json(test/fail45.json) - generate_header_from_json(test/fail5.json) - generate_header_from_json(test/fail6.json) - generate_header_from_json(test/fail7.json) - generate_header_from_json(test/fail8.json) - generate_header_from_json(test/fail9.json) - generate_header_from_json(test/pass1.json) - generate_header_from_json(test/pass2.json) - generate_header_from_json(test/pass3.json) - generate_header_from_json(test/pass4.json) - generate_header_from_json(test/round1.json) - generate_header_from_json(test/round2.json) - generate_header_from_json(test/round3.json) - generate_header_from_json(test/round4.json) - generate_header_from_json(test/round5.json) - generate_header_from_json(test/round6.json) - generate_header_from_json(test/round7.json) add_executable(unitester - ${CMAKE_CURRENT_BINARY_DIR}/test/fail1.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/fail10.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/fail11.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/fail12.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/fail13.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/fail14.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/fail15.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/fail16.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/fail17.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/fail18.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/fail19.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/fail2.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/fail20.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/fail21.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/fail22.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/fail23.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/fail24.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/fail25.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/fail26.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/fail27.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/fail28.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/fail29.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/fail3.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/fail30.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/fail31.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/fail32.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/fail33.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/fail34.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/fail35.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/fail36.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/fail37.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/fail38.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/fail39.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/fail4.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/fail40.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/fail41.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/fail42.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/fail44.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/fail45.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/fail5.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/fail6.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/fail7.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/fail8.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/fail9.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/pass1.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/pass2.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/pass3.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/pass4.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/round1.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/round2.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/round3.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/round4.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/round5.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/round6.json.h - ${CMAKE_CURRENT_BINARY_DIR}/test/round7.json.h test/unitester.cpp ) + include(TargetDataSources) + target_json_data_sources(unitester + test/fail1.json + test/fail10.json + test/fail11.json + test/fail12.json + test/fail13.json + test/fail14.json + test/fail15.json + test/fail16.json + test/fail17.json + test/fail18.json + test/fail19.json + test/fail2.json + test/fail20.json + test/fail21.json + test/fail22.json + test/fail23.json + test/fail24.json + test/fail25.json + test/fail26.json + test/fail27.json + test/fail28.json + test/fail29.json + test/fail3.json + test/fail30.json + test/fail31.json + test/fail32.json + test/fail33.json + test/fail34.json + test/fail35.json + test/fail36.json + test/fail37.json + test/fail38.json + test/fail39.json + test/fail4.json + test/fail40.json + test/fail41.json + test/fail42.json + test/fail44.json + test/fail45.json + test/fail5.json + test/fail6.json + test/fail7.json + test/fail8.json + test/fail9.json + test/pass1.json + test/pass2.json + test/pass3.json + test/pass4.json + test/round1.json + test/round2.json + test/round3.json + test/round4.json + test/round5.json + test/round6.json + test/round7.json + ) target_link_libraries(unitester PRIVATE core_interface From ecf54a32ed26a50e861fca559e43ec1f9dee93b7 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Thu, 13 Feb 2025 12:29:53 +0000 Subject: [PATCH 2/2] cmake: Add support for builtin `codegen` target Additionally, this change removes unnecessary braces in the `if()` command for improved robustness, readability and consistency with CMake guidelines. --- CMakeLists.txt | 8 +++++++- cmake/module/TargetDataSources.cmake | 10 ++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 94464907de1..7a51c3e4fcd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,10 +9,16 @@ # - CMake 3.26.5, https://mirror.stream.centos.org/9-stream/AppStream/x86_64/os/Packages/ cmake_minimum_required(VERSION 3.22) -if (${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR}) +if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR) message(FATAL_ERROR "In-source builds are not allowed.") endif() +if(POLICY CMP0171) + # `codegen` is a reserved target name. + # See: https://cmake.org/cmake/help/latest/policy/CMP0171.html + cmake_policy(SET CMP0171 NEW) +endif() + #============================= # Project / Package metadata #============================= diff --git a/cmake/module/TargetDataSources.cmake b/cmake/module/TargetDataSources.cmake index a1abd25a7c6..a549f9a2dfc 100644 --- a/cmake/module/TargetDataSources.cmake +++ b/cmake/module/TargetDataSources.cmake @@ -7,6 +7,14 @@ macro(set_add_custom_command_options) if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.27) set(DEPENDS_EXPLICIT_OPT DEPENDS_EXPLICIT_ONLY) endif() + set(CODEGEN_OPT "") + if(POLICY CMP0171) + cmake_policy(GET CMP0171 _cmp0171_status) + if(_cmp0171_status STREQUAL "NEW") + set(CODEGEN_OPT CODEGEN) + endif() + unset(_cmp0171_status) + endif() endmacro() # Specifies JSON data files to be processed into corresponding @@ -20,6 +28,7 @@ function(target_json_data_sources target) COMMAND ${CMAKE_COMMAND} -DJSON_SOURCE_PATH=${CMAKE_CURRENT_SOURCE_DIR}/${json_file} -DHEADER_PATH=${header} -P ${PROJECT_SOURCE_DIR}/cmake/script/GenerateHeaderFromJson.cmake DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${json_file} ${PROJECT_SOURCE_DIR}/cmake/script/GenerateHeaderFromJson.cmake VERBATIM + ${CODEGEN_OPT} ${DEPENDS_EXPLICIT_OPT} ) target_sources(${target} PRIVATE ${header}) @@ -38,6 +47,7 @@ function(target_raw_data_sources target) COMMAND ${CMAKE_COMMAND} -DRAW_SOURCE_PATH=${CMAKE_CURRENT_SOURCE_DIR}/${raw_file} -DHEADER_PATH=${header} -DRAW_NAMESPACE=${__NAMESPACE} -P ${PROJECT_SOURCE_DIR}/cmake/script/GenerateHeaderFromRaw.cmake DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${raw_file} ${PROJECT_SOURCE_DIR}/cmake/script/GenerateHeaderFromRaw.cmake VERBATIM + ${CODEGEN_OPT} ${DEPENDS_EXPLICIT_OPT} ) target_sources(${target} PRIVATE ${header})