try_compile: Propagating top level includes into whole-project calls

Fixes: #24151
This commit is contained in:
Craig Scott 2024-05-18 18:48:00 +10:00
parent ff12b19786
commit 4cb5bb014d
No known key found for this signature in database
GPG Key ID: 6FF37CBDCCADED9F
14 changed files with 187 additions and 5 deletions

View File

@ -271,6 +271,11 @@ Dependency Providers
:command:`project`. Calling ``cmake_language(SET_DEPENDENCY_PROVIDER)`` :command:`project`. Calling ``cmake_language(SET_DEPENDENCY_PROVIDER)``
outside of that context will result in an error. outside of that context will result in an error.
.. versionadded:: 3.30
The :prop_gbl:`PROPAGATE_TOP_LEVEL_INCLUDES_TO_TRY_COMPILE` global
property can be set if the dependency provider also wants to be enabled
in whole-project calls to :command:`try_compile`.
.. note:: .. note::
The choice of dependency provider should always be under the user's control. The choice of dependency provider should always be under the user's control.
As a convenience, a project may choose to provide a file that users can As a convenience, a project may choose to provide a file that users can

View File

@ -47,6 +47,11 @@ below for the meaning of other options.
:ref:`configure-log try_compile event <try_compile configure-log event>` :ref:`configure-log try_compile event <try_compile configure-log event>`
if the ``NO_LOG`` option is not specified. if the ``NO_LOG`` option is not specified.
.. versionadded:: 3.30
If the :prop_gbl:`PROPAGATE_TOP_LEVEL_INCLUDES_TO_TRY_COMPILE` global
property is set to true, :variable:`CMAKE_PROJECT_TOP_LEVEL_INCLUDES` is
propagated into the project's build configuration.
This command supports an alternate signature for CMake older than 3.25. This command supports an alternate signature for CMake older than 3.25.
The signature above is recommended for clarity. The signature above is recommended for clarity.
@ -388,6 +393,12 @@ configuration:
:variable:`CMAKE_MSVC_DEBUG_INFORMATION_FORMAT` to specify the MSVC debug :variable:`CMAKE_MSVC_DEBUG_INFORMATION_FORMAT` to specify the MSVC debug
information format. information format.
.. versionadded:: 3.30
If the :prop_gbl:`PROPAGATE_TOP_LEVEL_INCLUDES_TO_TRY_COMPILE` global
property is set to true, :variable:`CMAKE_PROJECT_TOP_LEVEL_INCLUDES` is
propagated into the test project's build configuration when using the
:ref:`whole-project signature <Try Compiling Whole Projects>`.
See Also See Also
^^^^^^^^ ^^^^^^^^

View File

@ -44,6 +44,7 @@ Properties of Global Scope
/prop_gbl/PACKAGES_FOUND /prop_gbl/PACKAGES_FOUND
/prop_gbl/PACKAGES_NOT_FOUND /prop_gbl/PACKAGES_NOT_FOUND
/prop_gbl/PREDEFINED_TARGETS_FOLDER /prop_gbl/PREDEFINED_TARGETS_FOLDER
/prop_gbl/PROPAGATE_TOP_LEVEL_INCLUDES_TO_TRY_COMPILE
/prop_gbl/REPORT_UNDEFINED_PROPERTIES /prop_gbl/REPORT_UNDEFINED_PROPERTIES
/prop_gbl/RULE_LAUNCH_COMPILE /prop_gbl/RULE_LAUNCH_COMPILE
/prop_gbl/RULE_LAUNCH_CUSTOM /prop_gbl/RULE_LAUNCH_CUSTOM

View File

@ -0,0 +1,19 @@
PROPAGATE_TOP_LEVEL_INCLUDES_TO_TRY_COMPILE
-------------------------------------------
.. versionadded:: 3.30
When this global property is set to true, the
:variable:`CMAKE_PROJECT_TOP_LEVEL_INCLUDES` variable is propagated into
:command:`try_compile` calls that use the
:ref:`whole-project signature <Try Compiling Whole Projects>`.
Calls to the :ref:`source file signature <Try Compiling Source Files>` are not
affected by this property.
``PROPAGATE_TOP_LEVEL_INCLUDES_TO_TRY_COMPILE`` is unset by default.
For :ref:`dependency providers <dependency_providers_overview>` that want to
be enabled in whole-project :command:`try_compile` calls, set this global
property to true just before or after registering the provider.
Note that all files listed in :variable:`CMAKE_PROJECT_TOP_LEVEL_INCLUDES`
will need to be able to handle being included in such :command:`try_compile`
calls, and it is the user's responsibility to ensure this.

View File

@ -0,0 +1,9 @@
dep-provider-try_compile
------------------------
* The :prop_gbl:`PROPAGATE_TOP_LEVEL_INCLUDES_TO_TRY_COMPILE` global property
can be used to propagate :variable:`CMAKE_PROJECT_TOP_LEVEL_INCLUDES` into
:command:`try_compile` calls that use the
:ref:`whole-project signature <Try Compiling Whole Projects>`.
This is primarily intended as a way for dependency providers to be enabled
in such :command:`try_compile` calls.

View File

@ -25,7 +25,10 @@ details (use :variable:`CMAKE_TOOLCHAIN_FILE` for that).
By default, this variable is empty. It is intended to be set by the user. By default, this variable is empty. It is intended to be set by the user.
See also the :variable:`CMAKE_PROJECT_INCLUDE`, See also:
:variable:`CMAKE_PROJECT_INCLUDE_BEFORE`,
:variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE`, and * :variable:`CMAKE_PROJECT_INCLUDE`
:variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE` variables. * :variable:`CMAKE_PROJECT_INCLUDE_BEFORE`
* :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE`
* :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE`
* :prop_gbl:`PROPAGATE_TOP_LEVEL_INCLUDES_TO_TRY_COMPILE`

View File

@ -1240,6 +1240,17 @@ cm::optional<cmTryCompileResult> cmCoreTryCompile::TryCompileCode(
} }
} }
if (!this->SrcFileSignature &&
this->Makefile->GetState()->GetGlobalPropertyAsBool(
"PROPAGATE_TOP_LEVEL_INCLUDES_TO_TRY_COMPILE")) {
const std::string var = "CMAKE_PROJECT_TOP_LEVEL_INCLUDES";
if (cmValue val = this->Makefile->GetDefinition(var)) {
std::string flag = cmStrCat("-D", var, "=\'", *val, '\'');
arguments.CMakeFlags.emplace_back(std::move(flag));
cmakeVariables.emplace(var, *val);
}
}
if (this->Makefile->GetState()->UseGhsMultiIDE()) { if (this->Makefile->GetState()->UseGhsMultiIDE()) {
// Forward the GHS variables to the inner project cache. // Forward the GHS variables to the inner project cache.
for (std::string const& var : ghs_platform_vars) { for (std::string const& var : ghs_platform_vars) {

View File

@ -16,6 +16,7 @@ run_cmake_with_options(Inspect
include("${RunCMake_BINARY_DIR}/Inspect-build/info.cmake") include("${RunCMake_BINARY_DIR}/Inspect-build/info.cmake")
run_cmake(ConfigureLog) run_cmake(ConfigureLog)
run_cmake(TopIncludes)
run_cmake(NoArgs) run_cmake(NoArgs)
run_cmake(OneArg) run_cmake(OneArg)
run_cmake(TwoArgs) run_cmake(TwoArgs)

View File

@ -0,0 +1,85 @@
^
---
events:(
-
kind: "message-v1"
backtrace:(
- "[^"]+")+
message: \|(
+ [^
]*)*)+
-
kind: "try_compile-v1"
backtrace:
- "[^"]*/Modules/CMakeDetermineCompilerABI.cmake:[0-9]+ \(try_compile\)"
- "[^"]*/Modules/CMakeTestCCompiler.cmake:[0-9]+ \(CMAKE_DETERMINE_COMPILER_ABI\)"
- "TopIncludes.cmake:[0-9]+ \(enable_language\)"
- "CMakeLists.txt:[0-9]+ \(include\)"
checks:
- "Detecting C compiler ABI info"
directories:
source: "[^"]*/Tests/RunCMake/try_compile/TopIncludes-build/CMakeFiles/CMakeScratch/TryCompile-[^/"]+"
binary: "[^"]*/Tests/RunCMake/try_compile/TopIncludes-build/CMakeFiles/CMakeScratch/TryCompile-[^/"]+"
cmakeVariables:(
CMAKE_[^
]*)+
buildResult:
variable: "CMAKE_C_ABI_COMPILED"
cached: true
stdout: \|.*
exitCode: 0(
-
kind: "message-v1"
backtrace:(
- "[^"]+")+
message: \|(
+ [^
]*)*)*
-
kind: "try_compile-v1"
backtrace:
- "TopIncludes.cmake:[0-9]+ \(try_compile\)"
- "CMakeLists.txt:[0-9]+ \(include\)"
description: "Project without property set\."
directories:
source: "[^"]*/Tests/RunCMake/try_compile/proj"
binary: "[^"]*/Tests/RunCMake/try_compile/TopIncludes-build/CMakeFiles/CMakeScratch/TryCompile-[^/"]+"
buildResult:
variable: "result"
cached: true
stdout: \|.*
exitCode: 0
-
kind: "try_compile-v1"
backtrace:
- "TopIncludes.cmake:[0-9]+ \(try_compile\)"
- "CMakeLists.txt:[0-9]+ \(include\)"
description: "Project with property set\."
directories:
source: "[^"]*/Tests/RunCMake/try_compile/proj"
binary: "[^"]*/Tests/RunCMake/try_compile/TopIncludes-build/CMakeFiles/CMakeScratch/TryCompile-[^/"]+"
cmakeVariables:
CMAKE_PROJECT_TOP_LEVEL_INCLUDES: "[^"]*/Tests/RunCMake/try_compile/include_pass1.cmake;[^"]*/Tests/RunCMake/try_compile/include_pass2.cmake"
buildResult:
variable: "result"
cached: true
stdout: \|.*
exitCode: 0
-
kind: "try_compile-v1"
backtrace:
- "TopIncludes.cmake:[0-9]+ \(try_compile\)"
- "CMakeLists.txt:[0-9]+ \(include\)"
description: "Source file with property set\."
directories:
source: "[^"]*/Tests/RunCMake/try_compile/TopIncludes-build/CMakeFiles/CMakeScratch/TryCompile-[^/"]+"
binary: "[^"]*/Tests/RunCMake/try_compile/TopIncludes-build/CMakeFiles/CMakeScratch/TryCompile-[^/"]+"
cmakeVariables:(
CMAKE_[^
]*)+
buildResult:
variable: "result"
cached: true
stdout: \|.*
exitCode: 0
\.\.\.$

View File

@ -0,0 +1,34 @@
enable_language(C)
# Normally CMAKE_PROJECT_TOP_LEVEL_INCLUDES must be set before the first
# project() call. We don't care about the variable's usual effects here, we
# only care whether the variable is propagated to try_compile() project calls.
set(CMAKE_PROJECT_TOP_LEVEL_INCLUDES
${CMAKE_CURRENT_LIST_DIR}/include_error.cmake
)
try_compile(result
PROJECT TestProject
SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/proj
LOG_DESCRIPTION "Project without property set."
)
set_property(GLOBAL PROPERTY PROPAGATE_TOP_LEVEL_INCLUDES_TO_TRY_COMPILE YES)
set(CMAKE_PROJECT_TOP_LEVEL_INCLUDES
${CMAKE_CURRENT_LIST_DIR}/include_pass1.cmake
${CMAKE_CURRENT_LIST_DIR}/include_pass2.cmake
)
try_compile(result
PROJECT TestProject
SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/proj
LOG_DESCRIPTION "Project with property set."
)
# Confirm the property only affects whole project signature
set(CMAKE_PROJECT_TOP_LEVEL_INCLUDES
${CMAKE_CURRENT_LIST_DIR}/include_error.cmake
)
try_compile(result
SOURCES ${CMAKE_CURRENT_LIST_DIR}/src.c
LOG_DESCRIPTION "Source file with property set."
)

View File

@ -0,0 +1 @@
message(FATAL_ERROR "Unexpectedly read top level include file")

View File

@ -0,0 +1 @@
message(STATUS "Top level include file was read - pass 1")

View File

@ -0,0 +1 @@
message(STATUS "Top level include file was read - pass 2")

View File

@ -1,2 +1,2 @@
cmake_minimum_required(VERSION 3.3) cmake_minimum_required(VERSION 3.5)
project(TestProject NONE) project(TestProject NONE)