Skip to content

Commit

Permalink
Improved handling of FIND_PACKAGE_ARGS in declarations
Browse files Browse the repository at this point in the history
Allow the user to completely specify the additional find package arguments by implementing a "default to 'REQUIRED'" strategy: if nothing is specified a find_package(<content_name> REQUIRED) is run, otherwise the user has to specify the FULL argument set except <content_name>. For good measure a bit of validation is done. Updated the documentation accordingly.

CHANGELOG

- improved the handling of HFC's FIND_PACKAGE_ARGS in library declarations to allow more arguments to be passed (now search <version> can be specified among other things)

Change-Id: I213ae84308423de275bd701258b36ea7efcf0074
  • Loading branch information
pysco68 committed Feb 19, 2025
1 parent 8b24b07 commit 06c92db
Show file tree
Hide file tree
Showing 7 changed files with 185 additions and 32 deletions.
30 changes: 30 additions & 0 deletions cmake/HermeticFetchContent.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,36 @@ Commands
Set the base directory for all the hermetic dependency build directory and related folders
Fallback to system provided dependencies
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
For use-cases in which you want to have the option to revert to a system provided library but still have the ability
to build your own, you may set ``FORCE_SYSTEM_<content-name>`` to ``ON``. In this case Hermetic FetchContent will
execute a CMake ``find_package(<content-name> REQUIRED)`` call during targets discovery.
If you need to specify arguments to ``find_package()`` you may add the ``FIND_PACKAGE_ARGS`` to the content declaration.
.. code-block:: cmake
set(FORCE_SYSTEM_boost ON) # <- take boost from the system, toggle this to OFF to have Boost built by your project
FetchContent_Declare(
boost
GIT_REPOSITORY https://github.com/boostorg/boost.git
GIT_TAG ad09f667e61e18f5c31590941e748ac38e5a81bf # that's v1.84
)
FetchContent_MakeHermetic(
boost
HERMETIC_BUILD_SYSTEM cmake
FIND_PACKAGE_ARGS "1.84 EXACT REQUIRED" # <- makes sure we take a 1.84 only from the system!
)
HermeticFetchContent_MakeAvailableAtBuildTime(boost)
Note that in the special case of ``FORCE_SYSTEM_<content-name>=ON`` the context in which the find_package() will be
run, will be slightly different from the normal context for hermetic builds. One major difference is that the Hermetic
FetchContent will inject the project's ``CMAKE_MODULE_PATH`` into the toolchain extension in addition to forcing
``find_package()`` to search exclusively on the system through setting ``CMAKE_FIND_ROOT_PATH_MODE_*`` appropriately.
Build introspection
^^^^^^^^^^^^^^^^^^^
Expand Down
12 changes: 11 additions & 1 deletion cmake/modules/hfc_make_available_single.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -196,10 +196,20 @@ function(hfc_make_available_single content_name build_at_configure_time)
DESTINATION_TOOLCHAIN_PATH "${proxy_toolchain_path}"
)

if(__PARAMS_FIND_PACKAGE_ARGS)
set(findpackage_args "${__PARAMS_FIND_PACKAGE_ARGS}")
else()
set(findpackage_args "REQUIRED")
endif()

if(NOT findpackage_args MATCHES "REQUIRED")
hfc_log(WARNING "The FIND_PACKAGE_ARGS provided in the content declaration of ${content_name} do not contain the REQUIRED flag. This might cause the resulting targets to be empty if the dependency cannot be resolve. (Valud of FIND_PACKAGE_ARGS='${__PARAMS_FIND_PACKAGE_ARGS}')")
endif()

get_hermetic_target_cache_file_path(${content_name} target_cache_file)
hfc_targets_cache_create_isolated(
${content_name}
LOAD_TARGETS_CMAKE "[==[find_package(${content_name} REQUIRED ${__PARAMS_FIND_PACKAGE_ARGS} ) \n]==]"
LOAD_TARGETS_CMAKE "[==[find_package(${content_name} ${findpackage_args}) \n]==]"
CACHE_DESTINATION_FILE "${target_cache_file}"
TEMP_DIR "${HERMETIC_FETCHCONTENT_INSTALL_DIR}/targets_dump_tmp"
TOOLCHAIN_FILE ${proxy_toolchain_path}
Expand Down
73 changes: 44 additions & 29 deletions docs/modules/HermeticFetchContent.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/searchindex.js

Large diffs are not rendered by default.

10 changes: 9 additions & 1 deletion test/targets_cache_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,15 @@ namespace hfc::test {
targets_cache_test_data_set{ "hfc_targets_cache/autotools_export_declaration", "Iconv.cmake", true },
targets_cache_test_data_set{ "hfc_targets_cache/cmake_no_install", "mathslib.cmake", false },
targets_cache_test_data_set{ "hfc_targets_cache/alternate_exports_naming", "mathslib.cmake", true },
targets_cache_test_data_set{ "hfc_targets_cache/alternate_exports_naming", "mathslib.cmake", false, false /* expect configure failure */, false, "-DHFCTEST_NEGATIVE_CASE=ON" /* enable the negative test in the project */ }
targets_cache_test_data_set{ "hfc_targets_cache/alternate_exports_naming", "mathslib.cmake", false, false /* expect configure failure */, false, "-DHFCTEST_NEGATIVE_CASE=ON" /* enable the negative test in the project */ },

// check that FIND_PACKAGE_ARGS are correctly forwarded to the underlying find_package() call
// > the cases below are just FORCE_SYSTEM_Iconv[ON;OFF] * TEST_INJECT_FIND_PACKAGE_ARGS[ON;OFF]
// > to have the neg cases to validate the test code behavior IRT to expected outcomes
targets_cache_test_data_set{ "hfc_targets_cache/FORCE_SYSTEM_find_pagacke_args", "Iconv.cmake", false, false, false, "-DFORCE_SYSTEM_Iconv=OFF -DTEST_INJECT_FIND_PACKAGE_ARGS=ON" }, // neg test
targets_cache_test_data_set{ "hfc_targets_cache/FORCE_SYSTEM_find_pagacke_args", "Iconv.cmake", false, false, false, "-DFORCE_SYSTEM_Iconv=ON -DTEST_INJECT_FIND_PACKAGE_ARGS=OFF" }, // neg test
targets_cache_test_data_set{ "hfc_targets_cache/FORCE_SYSTEM_find_pagacke_args", "Iconv.cmake", false, false, false, "-DFORCE_SYSTEM_Iconv=OFF -DTEST_INJECT_FIND_PACKAGE_ARGS=OFF" }, // neg test
targets_cache_test_data_set{ "hfc_targets_cache/FORCE_SYSTEM_find_pagacke_args", "Iconv.cmake", true, true, true, "-DFORCE_SYSTEM_Iconv=ON -DTEST_INJECT_FIND_PACKAGE_ARGS=ON" }
};

static auto TEST_DATA_hfc_makeAvailableAt_type = {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#
# Check if arguments injected through HFC's FIND_PACKAGE_ARGS make it
# to the underlying find_package() call
#
# WORD OF CAUTION:
# ================
# we're overriding the find_package() function in the toolchain extension to this end.
# The whole execution is fundamentally broken for any other purpose than checking the
# arguments being forwarded!
#

cmake_minimum_required(VERSION 3.27.6)
project(
ModernCMakeExample
VERSION 1.0
LANGUAGES CXX)


set(CMAKE_MODULE_PATH
"${CMAKE_CURRENT_SOURCE_DIR}/cmake"
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules"
${CMAKE_MODULE_PATH}
)

include(FetchContent)
include(HermeticFetchContent)


# this is set by the test program, just making sure we have a value
# when set to ON this should ensure we get to use the FindIconv.cmake module found under ./projectCmakeModules/
if(NOT DEFINED FORCE_SYSTEM_Iconv)
message(FATAL_ERROR "FORCE_SYSTEM_Iconv not defined")
endif()


if(NOT DEFINED TEST_INJECT_FIND_PACKAGE_ARGS)
message(FATAL_ERROR "TEST_INJECT_FIND_PACKAGE_ARGS not defined")
endif()

if(TEST_INJECT_FIND_PACKAGE_ARGS)
set(find_package_args_value "REQUIRED HFC_TEST_FLAG")
else()
set(find_package_args_value "REQUIRED")
endif()


FetchContent_Declare(
Iconv
GIT_REPOSITORY "https://github.com/tipi-build/unittest-autotools-sample.git"
GIT_TAG "ad80b024eeda8f4c0a96eedf669dc453ed33a094"
)

FetchContent_MakeHermetic(
Iconv
FIND_PACKAGE_ARGS "${find_package_args_value}"
HERMETIC_TOOLCHAIN_EXTENSION
[=[

# override find_package with one that can check if HFC_TEST_FLAG was set
function(find_package)
# check if HFC_TEST_FLAG was set
if(NOT "HFC_TEST_FLAG" IN_LIST ARGN)
message(FATAL_ERROR "Flag HFC_TEST_FLAG was not passed...")
endif()

include(FindIconv) # yeah...

#_find_package(${ARGN})
endfunction()

]=]
HERMETIC_CMAKE_EXPORT_LIBRARY_DECLARATION
[=[
message(FATAL_ERROR "This should never be run in this test")
]=]
HERMETIC_BUILD_SYSTEM autotools
)

HermeticFetchContent_MakeAvailableAtConfigureTime("Iconv")


if(NOT TARGET Iconv::Iconv)
message(FATAL_ERROR "Could not find target Iconv::Iconv")
endif()

add_executable(MyExample simple_example.cpp)
target_link_libraries(MyExample PRIVATE Iconv::Iconv)
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
int main() {
return 0;
}

0 comments on commit 06c92db

Please sign in to comment.