From 033247c8ca6904226495eebcbcd33aa697733b7d Mon Sep 17 00:00:00 2001 From: zachcran <15938371+zachcran@users.noreply.github.com> Date: Mon, 24 Nov 2025 11:13:23 -0700 Subject: [PATCH 1/3] Initial (almost) working implementation --- CMakeLists.txt | 12 ++++- cmake/cmaize_find_package.cmake | 83 +++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 cmake/cmaize_find_package.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index d86deb4e5..4579ceabb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,6 +25,7 @@ set(CMAKE_CXX_STANDARD 20) include(nwx_versions) include(get_cmaize) +include(cmake/cmaize_find_package.cmake) # Work out full paths to the project's include/source dirs set(project_inc_dir "${CMAKE_CURRENT_LIST_DIR}/include/${PROJECT_NAME}") @@ -72,9 +73,18 @@ set(pluginplay_depends utilities parallelzone libfort Boost::boost RocksDB) include(nwx_pybind11) if("${BUILD_PYBIND11_PYBINDINGS}") nwx_find_pybind11() + + cmaize_find_package(Python3 + COMPONENTS Interpreter Development + TARGETS + python Python::Python + ) + cmaize_wrap_target(pybind11_headers pybind11::headers) + cmaize_wrap_target(pybind11_embed pybind11::embed) + list( APPEND pluginplay_depends - pybind11::headers pybind11::embed Python::Python + pybind11_headers pybind11_embed python ) endif() diff --git a/cmake/cmaize_find_package.cmake b/cmake/cmaize_find_package.cmake new file mode 100644 index 000000000..434672b4b --- /dev/null +++ b/cmake/cmaize_find_package.cmake @@ -0,0 +1,83 @@ +include_guard() + +function(cmaize_wrap_target _cmaize_name _target) + # Prepare the new target to be added to the top-level project + cpp_get_global(_top_project CMAIZE_TOP_PROJECT) + CMaizeTarget(CTOR _tgt_obj "${_target}") + # install_path needs to be set to something or CMaize ignores the target + # during config file generation. This will be treated as a pre-installed + # target found by find_package(), but without a real install path + # CMaizeTarget(SET "${_tgt_obj}" install_path "tmp") + CMaizeProject(add_target "${_top_project}" "${_cmaize_name}" "${_tgt_obj}") + + # Create package specification objct + _fob_parse_arguments(_pkg_spec _pkg_name "${_cmaize_name}") + + # Register the dependency with the current CMake package manager + CMaizeProject(get_package_manager "${_top_project}" _pm "cmake") + CMakePackageManager(register_dependency + "${_pm}" __dep "${_pkg_spec}" + FIND_TARGET "${_target}" + BUILD_TARGET "${_target}" + ) +endfunction() + +function(cmaize_find_package _package_name) + set(_cfp_options "") + set(_cfp_one_value "") + # TARGETS option comes in pairs of "CMaize name" "CMake target" + set(_cfp_multi_value "TARGETS") + cmake_parse_arguments(_cfp "${_cfp_options}" "${_cfp_one_value}" "${_cfp_multi_value}" ${ARGN}) + + # If TARGETS is not given, default the pairing to "${_package_name}" "${_package_name}" + list(LENGTH _cfp_TARGETS _cfp_TARGETS_len) + if(_cfp_TARGETS_len LESS_EQUAL 0) + set(_cfp_TARGETS "${_package_name}" "${_package_name}") + list(LENGTH _cfp_TARGETS _cfp_TARGETS_len) + endif() + + # Validate that TARGETS is in the correct pair-wise form, simultaneously + # TODO: Assert that length is even + + # Turn TARGETS into a map of CMaize name -> CMake target + cpp_map(CTOR _cfp_target_map) + foreach(_cfp_i RANGE 0 "${_cfp_TARGETS_len}" 2) + # Grab the key-value pair of items + list(POP_FRONT _cfp_TARGETS _cfp_cmaize_name) + list(POP_FRONT _cfp_TARGETS _cfp_cmake_target) + + cpp_map(APPEND "${_cfp_target_map}" + "${_cfp_cmaize_name}" "${_cfp_cmake_target}" + ) + endforeach() + # Grab the keys for later usage + cpp_map(KEYS "${_cfp_target_map}" _cfp_cmaize_names) + + # Call find_package() to do the heavy lifting and find everything + message(STATUS "Searching for ${_package_name}") + find_package("${_package_name}" ${_cfp_UNPARSED_ARGUMENTS}) + + message(DEBUG "${_package_name}_FOUND: ${${_package_name}_FOUND}") + + # Make sure each expected target exists after the find_package() call + foreach(_cfp_cmaize_name ${_cfp_cmaize_names}) + cpp_map(GET "${_cfp_target_map}" + _cfp_cmake_target "${_cfp_cmaize_name}" + ) + + if(NOT TARGET "${_cfp_cmake_target}") + cpp_raise(TargetNotFound + "Could not find target (${_cfp_cmaize_name}, ${_cfp_cmake_target}) after find_package()" + ) + endif() + endforeach() + + # Add all targets to CMaize + foreach(_cfp_cmaize_name ${_cfp_cmaize_names}) + cpp_map(GET "${_cfp_target_map}" + _cfp_cmake_target "${_cfp_cmaize_name}" + ) + + cmaize_wrap_target("${_cfp_cmaize_name}" "${_cfp_cmake_target}") + endforeach() +endfunction() From 1b9a9c7261ab9a339f1b69788c5c9529a78d80eb Mon Sep 17 00:00:00 2001 From: zachcran <15938371+zachcran@users.noreply.github.com> Date: Mon, 24 Nov 2025 14:27:58 -0700 Subject: [PATCH 2/3] Seemingly functional first implementation --- CMakeLists.txt | 25 ++++++++++++++----- cmake/cmaize_find_package.cmake | 43 ++++++++++++++++++++++++++++++--- 2 files changed, 58 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4579ceabb..790bdea67 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,15 +72,28 @@ set(pluginplay_depends utilities parallelzone libfort Boost::boost RocksDB) # targets separately instead of a CMaize target include(nwx_pybind11) if("${BUILD_PYBIND11_PYBINDINGS}") - nwx_find_pybind11() + cmaize_find_package( + Python3 + # NOTE: Right now only the first component is added to find_dependency() + # so Development is listed first since it provides Python3::Python + COMPONENTS Development Interpreter + REQUIRED + TARGETS + python Python3::Python + ) - cmaize_find_package(Python3 - COMPONENTS Interpreter Development + nwx_find_pybind11() + cmaize_find_package( + pybind11 + # pybind11 won't be found if it is built in the above nwx_find_pybind11(). + # QUIET helps hide the error that would be output and even though + # pybind11 is REQUIRED, we will ignore the error here for now. + QUIET + # REQUIRED TARGETS - python Python::Python + pybind11_headers pybind11::headers + pybind11_embed pybind11::embed ) - cmaize_wrap_target(pybind11_headers pybind11::headers) - cmaize_wrap_target(pybind11_embed pybind11::embed) list( APPEND pluginplay_depends diff --git a/cmake/cmaize_find_package.cmake b/cmake/cmaize_find_package.cmake index 434672b4b..45c341d35 100644 --- a/cmake/cmaize_find_package.cmake +++ b/cmake/cmaize_find_package.cmake @@ -7,18 +7,21 @@ function(cmaize_wrap_target _cmaize_name _target) # install_path needs to be set to something or CMaize ignores the target # during config file generation. This will be treated as a pre-installed # target found by find_package(), but without a real install path - # CMaizeTarget(SET "${_tgt_obj}" install_path "tmp") + CMaizeTarget(SET "${_tgt_obj}" install_path "tmp") CMaizeProject(add_target "${_top_project}" "${_cmaize_name}" "${_tgt_obj}") # Create package specification objct - _fob_parse_arguments(_pkg_spec _pkg_name "${_cmaize_name}") + _fob_parse_arguments(_pkg_spec _pkg_name "${_cmaize_name}" ${ARGN}) # Register the dependency with the current CMake package manager CMaizeProject(get_package_manager "${_top_project}" _pm "cmake") + # TODO: Call this with NAME arg to handle components better CMakePackageManager(register_dependency "${_pm}" __dep "${_pkg_spec}" + # Set both find and built target to avoid having COMPONENTS "" added + # to every find_dependency() call generated FIND_TARGET "${_target}" - BUILD_TARGET "${_target}" + ${ARGN} ) endfunction() @@ -32,6 +35,7 @@ function(cmaize_find_package _package_name) # If TARGETS is not given, default the pairing to "${_package_name}" "${_package_name}" list(LENGTH _cfp_TARGETS _cfp_TARGETS_len) if(_cfp_TARGETS_len LESS_EQUAL 0) + message(WARNING "No targets provided. Using default dependency target \"${_package_name}\" for \"${_package_name}\"") set(_cfp_TARGETS "${_package_name}" "${_package_name}") list(LENGTH _cfp_TARGETS _cfp_TARGETS_len) endif() @@ -72,12 +76,43 @@ function(cmaize_find_package _package_name) endif() endforeach() + # Default to matching NAME and BUILD_TARGET so the find_dependency() call + # doesn't have components + set(_cfp_build_target "${_package_name}") + + # Handle components + set(_cfp_multi_value "COMPONENTS") + cmake_parse_arguments( + _cfp + "${_cfp_options}" "${_cfp_one_value}" "${_cfp_multi_value}" + ${_cfp_UNPARSED_ARGUMENTS} + ) + + # If components were given, we want find_dependency() called with them + if(NOT "${_cfp_COMPONENTS}" STREQUAL "") + set(_cfp_build_target "${_cfp_COMPONENTS}") + endif() + # Add all targets to CMaize foreach(_cfp_cmaize_name ${_cfp_cmaize_names}) cpp_map(GET "${_cfp_target_map}" _cfp_cmake_target "${_cfp_cmaize_name}" ) - cmaize_wrap_target("${_cfp_cmaize_name}" "${_cfp_cmake_target}") + # cmaize_wrap_target("${_cfp_cmaize_name}" "${_cfp_cmake_target}") + + cmaize_wrap_target("${_cfp_cmaize_name}" "${_cfp_cmake_target}" + NAME "${_package_name}" + BUILD_TARGET "${_cfp_build_target}" + ) endforeach() + + # foreach(_cfp_component ${_cfp_COMPONENTS}) + # set(_cfp_cmaize_name "${_package_name}_${_cfp_component}") + # cmaize_wrap_target("${_cfp_cmaize_name}" "${_cfp_component}" + # NAME "${_package_name}" + # BUILD_TARGET "${_cfp_component}" + # ) + # endforeach() + endfunction() From 7e67e5b83173e7e7b6e363995982eef90ad3acd0 Mon Sep 17 00:00:00 2001 From: zachcran <15938371+zachcran@users.noreply.github.com> Date: Mon, 15 Dec 2025 11:00:32 -0700 Subject: [PATCH 3/3] Switch to using external 'nwx_find_package()' --- CMakeLists.txt | 6 +- cmake/cmaize_find_package.cmake | 118 -------------------------------- 2 files changed, 3 insertions(+), 121 deletions(-) delete mode 100644 cmake/cmaize_find_package.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 790bdea67..6c539be2b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,7 +25,7 @@ set(CMAKE_CXX_STANDARD 20) include(nwx_versions) include(get_cmaize) -include(cmake/cmaize_find_package.cmake) +include(nwx_find_package) # Work out full paths to the project's include/source dirs set(project_inc_dir "${CMAKE_CURRENT_LIST_DIR}/include/${PROJECT_NAME}") @@ -72,7 +72,7 @@ set(pluginplay_depends utilities parallelzone libfort Boost::boost RocksDB) # targets separately instead of a CMaize target include(nwx_pybind11) if("${BUILD_PYBIND11_PYBINDINGS}") - cmaize_find_package( + nwx_find_package( Python3 # NOTE: Right now only the first component is added to find_dependency() # so Development is listed first since it provides Python3::Python @@ -83,7 +83,7 @@ if("${BUILD_PYBIND11_PYBINDINGS}") ) nwx_find_pybind11() - cmaize_find_package( + nwx_find_package( pybind11 # pybind11 won't be found if it is built in the above nwx_find_pybind11(). # QUIET helps hide the error that would be output and even though diff --git a/cmake/cmaize_find_package.cmake b/cmake/cmaize_find_package.cmake deleted file mode 100644 index 45c341d35..000000000 --- a/cmake/cmaize_find_package.cmake +++ /dev/null @@ -1,118 +0,0 @@ -include_guard() - -function(cmaize_wrap_target _cmaize_name _target) - # Prepare the new target to be added to the top-level project - cpp_get_global(_top_project CMAIZE_TOP_PROJECT) - CMaizeTarget(CTOR _tgt_obj "${_target}") - # install_path needs to be set to something or CMaize ignores the target - # during config file generation. This will be treated as a pre-installed - # target found by find_package(), but without a real install path - CMaizeTarget(SET "${_tgt_obj}" install_path "tmp") - CMaizeProject(add_target "${_top_project}" "${_cmaize_name}" "${_tgt_obj}") - - # Create package specification objct - _fob_parse_arguments(_pkg_spec _pkg_name "${_cmaize_name}" ${ARGN}) - - # Register the dependency with the current CMake package manager - CMaizeProject(get_package_manager "${_top_project}" _pm "cmake") - # TODO: Call this with NAME arg to handle components better - CMakePackageManager(register_dependency - "${_pm}" __dep "${_pkg_spec}" - # Set both find and built target to avoid having COMPONENTS "" added - # to every find_dependency() call generated - FIND_TARGET "${_target}" - ${ARGN} - ) -endfunction() - -function(cmaize_find_package _package_name) - set(_cfp_options "") - set(_cfp_one_value "") - # TARGETS option comes in pairs of "CMaize name" "CMake target" - set(_cfp_multi_value "TARGETS") - cmake_parse_arguments(_cfp "${_cfp_options}" "${_cfp_one_value}" "${_cfp_multi_value}" ${ARGN}) - - # If TARGETS is not given, default the pairing to "${_package_name}" "${_package_name}" - list(LENGTH _cfp_TARGETS _cfp_TARGETS_len) - if(_cfp_TARGETS_len LESS_EQUAL 0) - message(WARNING "No targets provided. Using default dependency target \"${_package_name}\" for \"${_package_name}\"") - set(_cfp_TARGETS "${_package_name}" "${_package_name}") - list(LENGTH _cfp_TARGETS _cfp_TARGETS_len) - endif() - - # Validate that TARGETS is in the correct pair-wise form, simultaneously - # TODO: Assert that length is even - - # Turn TARGETS into a map of CMaize name -> CMake target - cpp_map(CTOR _cfp_target_map) - foreach(_cfp_i RANGE 0 "${_cfp_TARGETS_len}" 2) - # Grab the key-value pair of items - list(POP_FRONT _cfp_TARGETS _cfp_cmaize_name) - list(POP_FRONT _cfp_TARGETS _cfp_cmake_target) - - cpp_map(APPEND "${_cfp_target_map}" - "${_cfp_cmaize_name}" "${_cfp_cmake_target}" - ) - endforeach() - # Grab the keys for later usage - cpp_map(KEYS "${_cfp_target_map}" _cfp_cmaize_names) - - # Call find_package() to do the heavy lifting and find everything - message(STATUS "Searching for ${_package_name}") - find_package("${_package_name}" ${_cfp_UNPARSED_ARGUMENTS}) - - message(DEBUG "${_package_name}_FOUND: ${${_package_name}_FOUND}") - - # Make sure each expected target exists after the find_package() call - foreach(_cfp_cmaize_name ${_cfp_cmaize_names}) - cpp_map(GET "${_cfp_target_map}" - _cfp_cmake_target "${_cfp_cmaize_name}" - ) - - if(NOT TARGET "${_cfp_cmake_target}") - cpp_raise(TargetNotFound - "Could not find target (${_cfp_cmaize_name}, ${_cfp_cmake_target}) after find_package()" - ) - endif() - endforeach() - - # Default to matching NAME and BUILD_TARGET so the find_dependency() call - # doesn't have components - set(_cfp_build_target "${_package_name}") - - # Handle components - set(_cfp_multi_value "COMPONENTS") - cmake_parse_arguments( - _cfp - "${_cfp_options}" "${_cfp_one_value}" "${_cfp_multi_value}" - ${_cfp_UNPARSED_ARGUMENTS} - ) - - # If components were given, we want find_dependency() called with them - if(NOT "${_cfp_COMPONENTS}" STREQUAL "") - set(_cfp_build_target "${_cfp_COMPONENTS}") - endif() - - # Add all targets to CMaize - foreach(_cfp_cmaize_name ${_cfp_cmaize_names}) - cpp_map(GET "${_cfp_target_map}" - _cfp_cmake_target "${_cfp_cmaize_name}" - ) - - # cmaize_wrap_target("${_cfp_cmaize_name}" "${_cfp_cmake_target}") - - cmaize_wrap_target("${_cfp_cmaize_name}" "${_cfp_cmake_target}" - NAME "${_package_name}" - BUILD_TARGET "${_cfp_build_target}" - ) - endforeach() - - # foreach(_cfp_component ${_cfp_COMPONENTS}) - # set(_cfp_cmaize_name "${_package_name}_${_cfp_component}") - # cmaize_wrap_target("${_cfp_cmaize_name}" "${_cfp_component}" - # NAME "${_package_name}" - # BUILD_TARGET "${_cfp_component}" - # ) - # endforeach() - -endfunction()