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)``
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::
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

View File

@ -47,6 +47,11 @@ below for the meaning of other options.
:ref:`configure-log try_compile event <try_compile configure-log event>`
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.
The signature above is recommended for clarity.
@ -388,6 +393,12 @@ configuration:
:variable:`CMAKE_MSVC_DEBUG_INFORMATION_FORMAT` to specify the MSVC debug
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
^^^^^^^^

View File

@ -44,6 +44,7 @@ Properties of Global Scope
/prop_gbl/PACKAGES_FOUND
/prop_gbl/PACKAGES_NOT_FOUND
/prop_gbl/PREDEFINED_TARGETS_FOLDER
/prop_gbl/PROPAGATE_TOP_LEVEL_INCLUDES_TO_TRY_COMPILE
/prop_gbl/REPORT_UNDEFINED_PROPERTIES
/prop_gbl/RULE_LAUNCH_COMPILE
/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.
See also the :variable:`CMAKE_PROJECT_INCLUDE`,
:variable:`CMAKE_PROJECT_INCLUDE_BEFORE`,
:variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE`, and
:variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE` variables.
See also:
* :variable:`CMAKE_PROJECT_INCLUDE`
* :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()) {
// Forward the GHS variables to the inner project cache.
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")
run_cmake(ConfigureLog)
run_cmake(TopIncludes)
run_cmake(NoArgs)
run_cmake(OneArg)
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)