Merge topic 'save-restore-PACKAGE_PREFIX_DIR'

41f4e1c457 CMakePackageConfigHelpers: Document PACKAGE_PREFIX_DIR for public use
c5231ba29e find_package: Save/restore PACKAGE_PREFIX_DIR
8ac7958e3a generate_apple_*_selection_file: Save/restore PACKAGE_PREFIX_DIR
bf88879f1f generate_apple_architecture_selection_file: Avoid early returns
a4ac2c92f4 Help: Add missing section heading for apple architecture selection
b7fcc44be9 Help: Fix CMakePackageConfigHelpers typos, grammar and formatting
f1cacaa830 Tests/RunCMake/CMakePackage: Define variable closer to where it is used

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !9430
This commit is contained in:
Brad King
2024-04-22 12:41:59 +00:00
committed by Kitware Robot
9 changed files with 291 additions and 76 deletions

View File

@@ -5,7 +5,7 @@
CMakePackageConfigHelpers
-------------------------
Helpers functions for creating config files that can be included by other
Helper functions for creating config files that can be included by other
projects to find and use a package.
Generating a Package Configuration File
@@ -26,11 +26,11 @@ Generating a Package Configuration File
``configure_package_config_file()`` should be used instead of the plain
:command:`configure_file()` command when creating the ``<PackageName>Config.cmake``
or ``<PackageName>-config.cmake`` file for installing a project or library.
It helps making the resulting package relocatable by avoiding hardcoded paths
in the installed ``Config.cmake`` file.
It helps make the resulting package relocatable by avoiding hardcoded paths
in the installed ``<PackageName>Config.cmake`` file.
In a ``FooConfig.cmake`` file there may be code like this to make the install
destinations know to the using project:
destinations known to the using project:
.. code-block:: cmake
@@ -40,27 +40,25 @@ destinations know to the using project:
#...logic to determine installedPrefix from the own location...
set(FOO_CONFIG_DIR "${installedPrefix}/@CONFIG_INSTALL_DIR@" )
All 4 options shown above are not sufficient, since the first 3 hardcode the
absolute directory locations, and the 4th case works only if the logic to
All four options shown above are not sufficient The first three hardcode the
absolute directory locations. The fourth case works only if the logic to
determine the ``installedPrefix`` is correct, and if ``CONFIG_INSTALL_DIR``
contains a relative path, which in general cannot be guaranteed. This has the
effect that the resulting ``FooConfig.cmake`` file would work poorly under
Windows and OSX, where users are used to choose the install location of a
Windows and macOS, where users are used to choosing the install location of a
binary package at install time, independent from how
:variable:`CMAKE_INSTALL_PREFIX` was set at build/cmake time.
Using ``configure_package_config_file`` helps. If used correctly, it makes
Using ``configure_package_config_file()`` helps. If used correctly, it makes
the resulting ``FooConfig.cmake`` file relocatable. Usage:
1. write a ``FooConfig.cmake.in`` file as you are used to
2. insert a line containing only the string ``@PACKAGE_INIT@``
3. instead of ``set(FOO_DIR "@SOME_INSTALL_DIR@")``, use
1. Write a ``FooConfig.cmake.in`` file as you are used to.
2. Insert a line at the top containing only the string ``@PACKAGE_INIT@``.
3. Instead of ``set(FOO_DIR "@SOME_INSTALL_DIR@")``, use
``set(FOO_DIR "@PACKAGE_SOME_INSTALL_DIR@")`` (this must be after the
``@PACKAGE_INIT@`` line)
4. instead of using the normal :command:`configure_file()`, use
``configure_package_config_file()``
``@PACKAGE_INIT@`` line).
4. Instead of using the normal :command:`configure_file()` command, use
``configure_package_config_file()``.
The ``<input>`` and ``<output>`` arguments are the input and output file, the
same way as in :command:`configure_file()`.
@@ -70,48 +68,64 @@ the ``FooConfig.cmake`` file will be installed to. This path can either be
absolute, or relative to the ``INSTALL_PREFIX`` path.
The variables ``<var1>`` to ``<varN>`` given as ``PATH_VARS`` are the
variables which contain install destinations. For each of them the macro will
variables which contain install destinations. For each of them, the macro will
create a helper variable ``PACKAGE_<var...>``. These helper variables must be
used in the ``FooConfig.cmake.in`` file for setting the installed location.
They are calculated by ``configure_package_config_file`` so that they are
They are calculated by ``configure_package_config_file()`` so that they are
always relative to the installed location of the package. This works both for
relative and also for absolute locations. For absolute locations it works
relative and also for absolute locations. For absolute locations, it works
only if the absolute location is a subdirectory of ``INSTALL_PREFIX``.
.. versionadded:: 3.30
The variable ``PACKAGE_PREFIX_DIR`` will always be defined after the
``@PACKAGE_INIT@`` line. It will hold the value of the base install
location. In general, variables defined via the ``PATH_VARS`` mechanism
should be used instead, but ``PACKAGE_PREFIX_DIR`` can be used for those
cases not easily handled by ``PATH_VARS``, such as for files installed
directly to the base install location rather than a subdirectory of it.
.. note::
When consumers of the generated file use CMake 3.29 or older, the value
of ``PACKAGE_PREFIX_DIR`` can be changed by a call to
:command:`find_dependency` or :command:`find_package`.
If a project relies on ``PACKAGE_PREFIX_DIR``, it is the project's
responsibility to ensure that the value of ``PACKAGE_PREFIX_DIR`` is
preserved across any such calls, or any other calls which might include
another file generated by ``configure_package_config_file()``.
.. versionadded:: 3.1
If the ``INSTALL_PREFIX`` argument is passed, this is used as base path to
If the ``INSTALL_PREFIX`` argument is passed, this is used as the base path to
calculate all the relative paths. The ``<path>`` argument must be an absolute
path. If this argument is not passed, the :variable:`CMAKE_INSTALL_PREFIX`
variable will be used instead. The default value is good when generating a
FooConfig.cmake file to use your package from the install tree. When
generating a FooConfig.cmake file to use your package from the build tree this
option should be used.
``FooConfig.cmake`` file to use your package from the install tree. When
generating a ``FooConfig.cmake`` file to use your package from the build tree,
this option should be used.
By default ``configure_package_config_file`` also generates two helper macros,
``set_and_check()`` and ``check_required_components()`` into the
By default, ``configure_package_config_file()`` also generates two helper
macros, ``set_and_check()`` and ``check_required_components()``, into the
``FooConfig.cmake`` file.
``set_and_check()`` should be used instead of the normal ``set()`` command for
setting directories and file locations. Additionally to setting the variable
it also checks that the referenced file or directory actually exists and fails
with a ``FATAL_ERROR`` otherwise. This makes sure that the created
``set_and_check()`` should be used instead of the normal :command:`set` command
for setting directories and file locations. In addition to setting the
variable, it also checks that the referenced file or directory actually exists
and fails with a fatal error if it doesn't. This ensures that the generated
``FooConfig.cmake`` file does not contain wrong references.
When using the ``NO_SET_AND_CHECK_MACRO``, this macro is not generated
into the ``FooConfig.cmake`` file.
Add the ``NO_SET_AND_CHECK_MACRO`` option to prevent the generation of the
``set_and_check()`` macro in the ``FooConfig.cmake`` file.
``check_required_components(<PackageName>)`` should be called at the end of
the ``FooConfig.cmake`` file. This macro checks whether all requested,
non-optional components have been found, and if this is not the case, sets
the ``Foo_FOUND`` variable to ``FALSE``, so that the package is considered to
non-optional components have been found, and if this is not the case, it sets
the ``Foo_FOUND`` variable to ``FALSE`` so that the package is considered to
be not found. It does that by testing the ``Foo_<Component>_FOUND``
variables for all requested required components. This macro should be
called even if the package doesn't provide any components to make sure
users are not specifying components erroneously. When using the
``NO_CHECK_REQUIRED_COMPONENTS_MACRO`` option, this macro is not generated
into the ``FooConfig.cmake`` file.
users are not specifying components erroneously. Add the
``NO_CHECK_REQUIRED_COMPONENTS_MACRO`` option to prevent the generation of the
``check_required_components()`` macro in the ``FooConfig.cmake`` file.
For an example see below the documentation for
:command:`write_basic_package_version_file()`.
See also :ref:`CMakePackageConfigHelpers Examples`.
Generating a Package Version File
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -126,11 +140,11 @@ Generating a Package Version File
[ARCH_INDEPENDENT] )
Writes a file for use as ``<PackageName>ConfigVersion.cmake`` file to
Writes a file for use as a ``<PackageName>ConfigVersion.cmake`` file to
``<filename>``. See the documentation of :command:`find_package()` for
details on this.
details on such files.
``<filename>`` is the output filename, it should be in the build tree.
``<filename>`` is the output filename, which should be in the build tree.
``<major.minor.patch>`` is the version number of the project to be installed.
If no ``VERSION`` is given, the :variable:`PROJECT_VERSION` variable is used.
@@ -153,9 +167,9 @@ the requested version matches exactly its own version number (not considering
the tweak version). For example, version 1.2.3 of a package is only
considered compatible to requested version 1.2.3. This mode is for packages
without compatibility guarantees.
If your project has more elaborated version matching rules, you will need to
write your own custom ``ConfigVersion.cmake`` file instead of using this
macro.
If your project has more elaborate version matching rules, you will need to
write your own custom ``<PackageName>ConfigVersion.cmake`` file instead of
using this macro.
.. versionadded:: 3.11
The ``SameMinorVersion`` compatibility mode.
@@ -170,13 +184,13 @@ macro.
unless ``ARCH_INDEPENDENT`` is given, in which case the package is considered
compatible on any architecture.
.. note:: ``ARCH_INDEPENDENT`` is intended for header-only libraries or similar
packages with no binaries.
.. note:: ``ARCH_INDEPENDENT`` is intended for header-only libraries or
similar packages with no binaries.
.. versionadded:: 3.19
The version file generated by ``AnyNewerVersion``, ``SameMajorVersion`` and
``SameMinorVersion`` arguments of ``COMPATIBILITY`` handle the version range
if any is specified (see :command:`find_package` command for the details).
``SameMinorVersion`` arguments of ``COMPATIBILITY`` handle the version range,
if one is specified (see :command:`find_package` command for the details).
``ExactVersion`` mode is incompatible with version ranges and will display an
author warning if one is specified.
@@ -184,8 +198,9 @@ Internally, this macro executes :command:`configure_file()` to create the
resulting version file. Depending on the ``COMPATIBILITY``, the corresponding
``BasicConfigVersion-<COMPATIBILITY>.cmake.in`` file is used.
Please note that these files are internal to CMake and you should not call
:command:`configure_file()` on them yourself, but they can be used as starting
point to create more sophisticated custom ``ConfigVersion.cmake`` files.
:command:`configure_file()` on them yourself, but they can be used as a starting
point to create more sophisticated custom ``<PackageName>ConfigVersion.cmake``
files.
Generating an Apple Platform Selection File
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -268,6 +283,9 @@ Generating an Apple Platform Selection File
consider the platform to be unsupported. The behavior is determined
by the ``ERROR_VARIABLE`` option.
Generating an Apple Architecture Selection File
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. command:: generate_apple_architecture_selection_file
.. versionadded:: 3.29
@@ -328,15 +346,16 @@ Generating an Apple Platform Selection File
information to pretend the package was not found. If this option
is not given, the default behavior is to issue a fatal error.
.. _`CMakePackageConfigHelpers Examples`:
Example Generating Package Files
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Example using both :command:`configure_package_config_file` and
``write_basic_package_version_file()``:
``CMakeLists.txt``:
Example using both the :command:`configure_package_config_file` and
:command:`write_basic_package_version_file()` commands:
.. code-block:: cmake
:caption: ``CMakeLists.txt``
include(GNUInstallDirs)
set(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR}/Foo
@@ -357,9 +376,9 @@ Example using both :command:`configure_package_config_file` and
${CMAKE_CURRENT_BINARY_DIR}/FooConfigVersion.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Foo )
``FooConfig.cmake.in``:
::
.. code-block:: cmake
:caption: ``FooConfig.cmake.in``
:force:
set(FOO_VERSION x.y.z)
...
@@ -597,8 +616,15 @@ function(generate_apple_architecture_selection_file _output_file)
)
endif()
string(APPEND _branch_code
"endif()\n"
"endif()\n\n"
"set(_cmake_apple_archs \"\${CMAKE_OSX_ARCHITECTURES}\")\n"
)
if(NOT "${_gasf_UNIVERSAL_ARCHITECTURES}" STREQUAL "")
string(APPEND _branch_code "list(REMOVE_ITEM _cmake_apple_archs ${_gasf_UNIVERSAL_ARCHITECTURES})\n")
endif()
string(APPEND _branch_code "\n")
set(maybe_else "")
foreach(pair IN ZIP_LISTS _gasf_SINGLE_ARCHITECTURES _gasf_SINGLE_ARCHITECTURE_INCLUDE_FILES)
set(arch "${pair_0}")
@@ -607,40 +633,45 @@ function(generate_apple_architecture_selection_file _output_file)
string(PREPEND config_file [[${PACKAGE_PREFIX_DIR}/]])
endif()
string(APPEND _branch_code
"\n"
"if(CMAKE_OSX_ARCHITECTURES STREQUAL \"${arch}\")\n"
"${maybe_else}if(CMAKE_OSX_ARCHITECTURES STREQUAL \"${arch}\")\n"
" include(\"${config_file}\")\n"
" return()\n"
"endif()\n"
)
set(maybe_else else)
endforeach()
if(_gasf_UNIVERSAL_ARCHITECTURES AND _gasf_UNIVERSAL_INCLUDE_FILE)
string(JOIN " " universal_archs "${_gasf_UNIVERSAL_ARCHITECTURES}")
set(config_file "${_gasf_UNIVERSAL_INCLUDE_FILE}")
if(NOT IS_ABSOLUTE "${config_file}")
string(PREPEND config_file [[${PACKAGE_PREFIX_DIR}/]])
endif()
string(APPEND _branch_code
"\n"
"set(_cmake_apple_archs \"\${CMAKE_OSX_ARCHITECTURES}\")\n"
"list(REMOVE_ITEM _cmake_apple_archs ${universal_archs})\n"
"if(NOT _cmake_apple_archs)\n"
"${maybe_else}if(NOT _cmake_apple_archs)\n"
" include(\"${config_file}\")\n"
" return()\n"
"endif()\n"
)
set(maybe_else else)
elseif(_gasf_UNIVERSAL_ARCHITECTURES)
message(FATAL_ERROR "UNIVERSAL_INCLUDE_FILE requires UNIVERSAL_ARCHITECTURES")
elseif(_gasf_UNIVERSAL_INCLUDE_FILE)
message(FATAL_ERROR "UNIVERSAL_ARCHITECTURES requires UNIVERSAL_INCLUDE_FILE")
endif()
string(APPEND _branch_code "\n")
if(_gasf_ERROR_VARIABLE)
string(APPEND _branch_code "set(\"${_gasf_ERROR_VARIABLE}\" \"Architecture not supported\")")
if(maybe_else)
string(APPEND _branch_code "else()\n")
set(_indent " ")
else()
string(APPEND _branch_code "message(FATAL_ERROR \"Architecture not supported\")")
set(_indent "")
endif()
if(_gasf_ERROR_VARIABLE)
string(APPEND _branch_code
"${_indent}set(\"${_gasf_ERROR_VARIABLE}\" \"Architecture not supported\")\n"
)
else()
string(APPEND _branch_code
"${_indent}message(FATAL_ERROR \"Architecture not supported\")\n"
)
endif()
if(maybe_else)
string(APPEND _branch_code "endif()\n")
endif()
configure_package_config_file("${CMAKE_CURRENT_FUNCTION_LIST_DIR}/Internal/AppleArchitectureSelection.cmake.in" "${_output_file}"

View File

@@ -1,2 +1,23 @@
# Save this now so we can restore it before returning
if(NOT DEFINED PACKAGE_PREFIX_DIR)
list(APPEND _gasf_PACKAGE_PREFIX_DIR "<__CMAKE_UNDEFINED__>")
elseif("${PACKAGE_PREFIX_DIR}" STREQUAL "")
list(APPEND _gasf_PACKAGE_PREFIX_DIR "<__CMAKE_EMPTY__>")
else()
list(APPEND _gasf_PACKAGE_PREFIX_DIR "${PACKAGE_PREFIX_DIR}")
endif()
@PACKAGE_INIT@
@_branch_code@
# Restore PACKAGE_PREFIX_DIR
list(LENGTH _gasf_PACKAGE_PREFIX_DIR _gasf_tmp)
math(EXPR _gasf_tmp "${_gasf_tmp} - 1")
list(GET _gasf_PACKAGE_PREFIX_DIR ${_gasf_tmp} PACKAGE_PREFIX_DIR)
list(REMOVE_AT _gasf_PACKAGE_PREFIX_DIR ${_gasf_tmp})
unset(_gasf_tmp)
if("${PACKAGE_PREFIX_DIR}" STREQUAL "<__CMAKE_UNDEFINED__>")
unset(PACKAGE_PREFIX_DIR)
elseif("${PACKAGE_PREFIX_DIR}" STREQUAL "<__CMAKE_EMPTY__>")
set(PACKAGE_PREFIX_DIR "")
endif()

View File

@@ -1,3 +1,12 @@
# Save this now so we can restore it before returning
if(NOT DEFINED PACKAGE_PREFIX_DIR)
list(APPEND _gpsf_PACKAGE_PREFIX_DIR "<__CMAKE_UNDEFINED__>")
elseif("${PACKAGE_PREFIX_DIR}" STREQUAL "")
list(APPEND _gpsf_PACKAGE_PREFIX_DIR "<__CMAKE_EMPTY__>")
else()
list(APPEND _gpsf_PACKAGE_PREFIX_DIR "${PACKAGE_PREFIX_DIR}")
endif()
@PACKAGE_INIT@
string(TOLOWER "${CMAKE_OSX_SYSROOT}" _CMAKE_OSX_SYSROOT_LOWER)
@@ -23,3 +32,15 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
else()
@_branch_ELSE@
endif()
# Restore PACKAGE_PREFIX_DIR
list(LENGTH _gpsf_PACKAGE_PREFIX_DIR _gpsf_tmp)
math(EXPR _gpsf_tmp "${_gpsf_tmp} - 1")
list(GET _gpsf_PACKAGE_PREFIX_DIR ${_gpsf_tmp} PACKAGE_PREFIX_DIR)
list(REMOVE_AT _gpsf_PACKAGE_PREFIX_DIR ${_gpsf_tmp})
unset(_gpsf_tmp)
if("${PACKAGE_PREFIX_DIR}" STREQUAL "<__CMAKE_UNDEFINED__>")
unset(PACKAGE_PREFIX_DIR)
elseif("${PACKAGE_PREFIX_DIR}" STREQUAL "<__CMAKE_EMPTY__>")
set(PACKAGE_PREFIX_DIR "")
endif()

View File

@@ -982,6 +982,36 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
return true;
}
// Restore PACKAGE_PREFIX_DIR to its pre-call value when we return. If our
// caller is a file generated by configure_package_config_file(), and if
// the package we are about to load also has a config file created by that
// command, it will overwrite PACKAGE_PREFIX_DIR. We need to restore it in
// case something still refers to it in our caller's scope after we return.
class RestoreVariableOnLeavingScope
{
cmMakefile* makefile_;
cm::optional<std::string> value_;
public:
RestoreVariableOnLeavingScope(cmMakefile* makefile)
: makefile_(makefile)
{
cmValue v = makefile->GetDefinition("PACKAGE_PREFIX_DIR");
if (v) {
value_ = *v;
}
}
~RestoreVariableOnLeavingScope()
{
if (this->value_) {
makefile_->AddDefinition("PACKAGE_PREFIX_DIR", *value_);
} else {
makefile_->RemoveDefinition("PACKAGE_PREFIX_DIR");
}
}
};
RestoreVariableOnLeavingScope restorePackagePrefixDir(this->Makefile);
// Now choose what method(s) we will use to satisfy the request. Note that
// we still want all the above checking of arguments, etc. regardless of the
// method used. This will ensure ill-formed arguments are caught earlier,

View File

@@ -0,0 +1,3 @@
(-- )?Hello from platform switch
(-- )?Hello from arch switch
(-- )?Hello from pkg_a

View File

@@ -0,0 +1,50 @@
set(CMAKE_INSTALL_DATADIR share)
set(SWITCH_DIR platform/cmake)
include(CMakePackageConfigHelpers)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/pkg_a-config.cmake.in [[
@PACKAGE_INIT@
include("@PACKAGE_SWITCH_DIR@/platform-switch.cmake")
include("@PACKAGE_CMAKE_INSTALL_DATADIR@/pkg_a_included.cmake")
]])
configure_package_config_file(
${CMAKE_CURRENT_BINARY_DIR}/pkg_a-config.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/install/pkg_a-config.cmake
INSTALL_DESTINATION .
PATH_VARS CMAKE_INSTALL_DATADIR SWITCH_DIR
)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/install/${CMAKE_INSTALL_DATADIR}/pkg_a_included.cmake
[[message(STATUS "Hello from pkg_a")]]
)
# To expose re-using the same package prefix variable, we need to use a
# different install prefix. This is really contrived and not representative of
# what a package should do.
generate_apple_platform_selection_file(
${CMAKE_CURRENT_BINARY_DIR}/install/platform/cmake/platform-switch.cmake
INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}/platform
INSTALL_DESTINATION cmake
MACOS_INCLUDE_FILE cmake/switch_included.cmake # relative to install prefix
)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/install/platform/cmake/switch_included.cmake
[[
message(STATUS "Hello from platform switch")
include("${CMAKE_CURRENT_LIST_DIR}/../arch/cmake/arch-switch.cmake")
]]
)
generate_apple_architecture_selection_file(
${CMAKE_CURRENT_BINARY_DIR}/install/platform/arch/cmake/arch-switch.cmake
INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}/platform/arch
INSTALL_DESTINATION cmake
UNIVERSAL_ARCHITECTURES i386 x86_64 arm64 $(ARCHS_STANDARD)
UNIVERSAL_INCLUDE_FILE cmake/switch_included.cmake # relative to install prefix
)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/install/platform/arch/cmake/switch_included.cmake
[[message(STATUS "Hello from arch switch")]]
)
find_package(pkg_a REQUIRED NO_DEFAULT_PATH
PATHS ${CMAKE_CURRENT_BINARY_DIR}/install
)

View File

@@ -0,0 +1,6 @@
(-- )?Before find_dependency: PACKAGE_PREFIX_DIR = .*/Tests/RunCMake/CMakePackage/NestedConfigFile-build/install_pkg_b
(-- )?Hello from pkg_a
(-- )?Leaving pkg_a-config\.cmake with PACKAGE_PREFIX_DIR = .*/Tests/RunCMake/CMakePackage/NestedConfigFile-build/install_pkg_a
(-- )?After find_dependency: PACKAGE_PREFIX_DIR = .*/Tests/RunCMake/CMakePackage/NestedConfigFile-build/install_pkg_b
(-- )?Hello from pkg_b
(-- )?Leaving pkg_b-config\.cmake with PACKAGE_PREFIX_DIR = .*/Tests/RunCMake/CMakePackage/NestedConfigFile-build/install_pkg_b

View File

@@ -0,0 +1,43 @@
set(CMAKE_INSTALL_DATADIR share)
include(CMakePackageConfigHelpers)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/pkg_a-config.cmake.in [[
@PACKAGE_INIT@
include("@PACKAGE_CMAKE_INSTALL_DATADIR@/pkg_a_included.cmake")
message(STATUS "Leaving pkg_a-config.cmake with PACKAGE_PREFIX_DIR = ${PACKAGE_PREFIX_DIR}")
]])
configure_package_config_file(
${CMAKE_CURRENT_BINARY_DIR}/pkg_a-config.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/install_pkg_a/pkg_a-config.cmake
INSTALL_DESTINATION .
PATH_VARS CMAKE_INSTALL_DATADIR
)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/install_pkg_a/share/pkg_a_included.cmake
[[message(STATUS "Hello from pkg_a")]]
)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/pkg_b-config.cmake.in [[
@PACKAGE_INIT@
include(CMakeFindDependencyMacro)
message(STATUS "Before find_dependency: PACKAGE_PREFIX_DIR = ${PACKAGE_PREFIX_DIR}")
find_dependency(pkg_a NO_DEFAULT_PATH
PATHS "@CMAKE_CURRENT_BINARY_DIR@/install_pkg_a"
)
message(STATUS "After find_dependency: PACKAGE_PREFIX_DIR = ${PACKAGE_PREFIX_DIR}")
include("@PACKAGE_CMAKE_INSTALL_DATADIR@/pkg_b_included.cmake")
message(STATUS "Leaving pkg_b-config.cmake with PACKAGE_PREFIX_DIR = ${PACKAGE_PREFIX_DIR}")
]])
configure_package_config_file(
${CMAKE_CURRENT_BINARY_DIR}/pkg_b-config.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/install_pkg_b/pkg_b-config.cmake
INSTALL_DESTINATION .
PATH_VARS CMAKE_INSTALL_DATADIR
)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/install_pkg_b/share/pkg_b_included.cmake
[[message(STATUS "Hello from pkg_b")]]
)
find_package(pkg_b REQUIRED NO_DEFAULT_PATH
PATHS ${CMAKE_CURRENT_BINARY_DIR}/install_pkg_b
)

View File

@@ -4,6 +4,8 @@ if(NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
set(maybe_CMAKE_BUILD_TYPE -DCMAKE_BUILD_TYPE=Release)
endif()
run_cmake_with_options(NestedConfigFile ${maybe_CMAKE_BUILD_TYPE})
function(apple_export platform system_name archs sysroot)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/apple-export-${platform}-build)
string(REPLACE ";" "\\;" archs "${archs}")
@@ -48,9 +50,6 @@ if(APPLE)
endif()
if(APPLE AND CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
set(apple_install ${RunCMake_BINARY_DIR}/apple-install)
file(REMOVE_RECURSE "${apple_install}")
if(CMake_TEST_XCODE_VERSION VERSION_GREATER_EQUAL 12)
set(macos_archs "x86_64;arm64")
set(tvos_sim_archs "x86_64;arm64")
@@ -78,6 +77,17 @@ if(APPLE AND CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
set(enable_visionos 1)
endif()
string(REPLACE ";" "\\;" macos_archs_for_cmd "${macos_archs}")
run_cmake_with_options(ApplePlatformGenSubdir
"-DCMAKE_OSX_ARCHITECTURES=${macos_archs_for_cmd}"
${maybe_CMAKE_BUILD_TYPE}
)
unset(macos_archs_for_cmd)
# Place all export/import steps in a single install prefix.
set(apple_install ${RunCMake_BINARY_DIR}/apple-install)
file(REMOVE_RECURSE "${apple_install}")
apple_export(macos Darwin "${macos_archs}" macosx)
apple_export(ios iOS "arm64" iphoneos)
apple_export(tvos tvOS "arm64" appletvos)