summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Auxiliary/vim/indent/cmake.vim48
-rw-r--r--Help/manual/cmake-policies.7.rst1
-rw-r--r--Help/policy/CMP0132.rst26
-rw-r--r--Help/release/dev/set-env-var-first-run.rst6
-rw-r--r--Help/variable/CMAKE_LINK_GROUP_USING_FEATURE.rst5
-rw-r--r--Help/variable/CMAKE_LINK_GROUP_USING_FEATURE_SUPPORTED.rst3
-rw-r--r--Help/variable/CMAKE_LINK_LIBRARY_USING_FEATURE.rst5
-rw-r--r--Help/variable/CMAKE_LINK_LIBRARY_USING_FEATURE_SUPPORTED.rst4
-rw-r--r--Modules/CMakeDetermineCompiler.cmake12
-rw-r--r--Modules/FindHDF5.cmake8
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/cmComputeLinkInformation.cxx22
-rw-r--r--Source/cmGlobalGenerator.cxx4
-rw-r--r--Source/cmIfCommand.cxx12
-rw-r--r--Source/cmMakefile.cxx15
-rw-r--r--Source/cmMakefile.h11
-rw-r--r--Source/cmPolicies.h5
-rw-r--r--Tests/RunCMake/CMP0132/CMP0132-Common.cmake15
-rw-r--r--Tests/RunCMake/CMP0132/CMP0132-NEW-stdout.txt1
-rw-r--r--Tests/RunCMake/CMP0132/CMP0132-NEW.cmake2
-rw-r--r--Tests/RunCMake/CMP0132/CMP0132-OLD-stdout.txt1
-rw-r--r--Tests/RunCMake/CMP0132/CMP0132-OLD.cmake2
-rw-r--r--Tests/RunCMake/CMP0132/CMP0132-WARN-stdout.txt1
-rw-r--r--Tests/RunCMake/CMP0132/CMP0132-WARN.cmake2
-rw-r--r--Tests/RunCMake/CMP0132/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CMP0132/RunCMakeTest.cmake7
-rw-r--r--Tests/RunCMake/CMakeLists.txt12
-rwxr-xr-xTests/RunCMake/CommandLine/trace-json-v1-check.py10
-rw-r--r--Tests/RunCMake/CommandLine/trace-json-v1-nested/CMakeLists.txt5
-rw-r--r--Tests/RunCMake/CommandLine/trace-json-v1.cmake1
-rw-r--r--Tests/RunCMake/CompilerArgs/C-stdout.txt1
-rw-r--r--Tests/RunCMake/CompilerArgs/C.cmake1
-rw-r--r--Tests/RunCMake/CompilerArgs/CXX-stdout.txt1
-rw-r--r--Tests/RunCMake/CompilerArgs/CXX.cmake1
-rw-r--r--Tests/RunCMake/CompilerArgs/RunCMakeTest.cmake27
-rw-r--r--Tests/RunCMake/Framework/FrameworkConsumption.cmake15
-rw-r--r--Tests/RunCMake/Framework/Gui.c5
-rw-r--r--Tests/RunCMake/Framework/Gui.h2
-rw-r--r--Tests/RunCMake/Framework/RunCMakeTest.cmake12
-rw-r--r--Tests/RunCMake/Framework/main.c9
-rw-r--r--Tests/RunCMake/GenEx-LINK_GROUP/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/GenEx-LINK_GROUP/multiple-definitions-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-LINK_GROUP/multiple-definitions-stderr.txt5
-rw-r--r--Tests/RunCMake/GenEx-LINK_GROUP/multiple-definitions.cmake12
-rw-r--r--Tests/RunCMake/GenEx-LINK_LIBRARY/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/GenEx-LINK_LIBRARY/multiple-definitions-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-LINK_LIBRARY/multiple-definitions-stderr.txt5
-rw-r--r--Tests/RunCMake/GenEx-LINK_LIBRARY/multiple-definitions.cmake12
-rw-r--r--Tests/RunCMake/target_link_libraries-LINK_GROUP/LINK_GROUP-multiple-definitions-result.txt1
-rw-r--r--Tests/RunCMake/target_link_libraries-LINK_GROUP/LINK_GROUP-mutiple-definitions-check.cmake4
-rw-r--r--Tests/RunCMake/target_link_libraries-LINK_GROUP/LINK_GROUP.cmake7
-rw-r--r--Tests/RunCMake/target_link_libraries-LINK_GROUP/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/target_link_libraries-LINK_LIBRARY/LINK_LIBRARY.cmake1
53 files changed, 302 insertions, 75 deletions
diff --git a/Auxiliary/vim/indent/cmake.vim b/Auxiliary/vim/indent/cmake.vim
index f7ab24a..672bdcc 100644
--- a/Auxiliary/vim/indent/cmake.vim
+++ b/Auxiliary/vim/indent/cmake.vim
@@ -3,7 +3,7 @@
" Author: Andy Cedilnik <andy.cedilnik@kitware.com>
" Maintainer: Dimitri Merejkowsky <d.merej@gmail.com>
" Former Maintainer: Karthik Krishnan <karthik.krishnan@kitware.com>
-" Last Change: 2017 Aug 30
+" Last Change: 2022 Mar 22
"
" License: The CMake license applies to this file. See
" https://cmake.org/licensing
@@ -14,9 +14,6 @@ if exists("b:did_indent")
endif
let b:did_indent = 1
-let s:keepcpo= &cpo
-set cpo&vim
-
setlocal indentexpr=CMakeGetIndent(v:lnum)
setlocal indentkeys+==ENDIF(,ENDFOREACH(,ENDMACRO(,ELSE(,ELSEIF(,ENDWHILE(
@@ -24,6 +21,8 @@ setlocal indentkeys+==ENDIF(,ENDFOREACH(,ENDMACRO(,ELSE(,ELSEIF(,ENDWHILE(
if exists("*CMakeGetIndent")
finish
endif
+let s:keepcpo= &cpo
+set cpo&vim
fun! CMakeGetIndent(lnum)
let this_line = getline(a:lnum)
@@ -54,32 +53,41 @@ fun! CMakeGetIndent(lnum)
let cmake_indent_open_regex = '^\s*' . cmake_regex_identifier .
\ '\s*(' . cmake_regex_arguments .
\ '\(' . cmake_regex_comment . '\)\?$'
-
let cmake_indent_close_regex = '^' . cmake_regex_arguments .
\ ')\s*' .
\ '\(' . cmake_regex_comment . '\)\?$'
+ let cmake_closing_parens_line = '^\s*\()\+\)\s*$'
+
let cmake_indent_begin_regex = '^\s*\(IF\|MACRO\|FOREACH\|ELSE\|ELSEIF\|WHILE\|FUNCTION\)\s*('
let cmake_indent_end_regex = '^\s*\(ENDIF\|ENDFOREACH\|ENDMACRO\|ELSE\|ELSEIF\|ENDWHILE\|ENDFUNCTION\)\s*('
- " Add
- if previous_line =~? cmake_indent_comment_line " Handle comments
- let ind = ind
- else
- if previous_line =~? cmake_indent_begin_regex
- let ind = ind + shiftwidth()
+ if this_line =~? cmake_closing_parens_line
+ if previous_line !~? cmake_indent_open_regex
+ let ind = ind - shiftwidth()
endif
- if previous_line =~? cmake_indent_open_regex
- let ind = ind + shiftwidth()
+ else
+ " Add
+ if previous_line =~? cmake_indent_comment_line " Handle comments
+ let ind = ind
+ else
+ if previous_line =~? cmake_indent_begin_regex
+ let ind = ind + shiftwidth()
+ endif
+ if previous_line =~? cmake_indent_open_regex
+ let ind = ind + shiftwidth()
+ endif
endif
- endif
- " Subtract
- if this_line =~? cmake_indent_end_regex
- let ind = ind - shiftwidth()
- endif
- if previous_line =~? cmake_indent_close_regex
- let ind = ind - shiftwidth()
+ " Subtract
+ if this_line =~? cmake_indent_end_regex
+ let ind = ind - shiftwidth()
+ endif
+ if previous_line !~? cmake_closing_parens_line
+ if previous_line =~? cmake_indent_close_regex
+ let ind = ind - shiftwidth()
+ endif
+ endif
endif
return ind
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index 9bf2913..17a3764 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -58,6 +58,7 @@ Policies Introduced by CMake 3.24
.. toctree::
:maxdepth: 1
+ CMP0132: Do not set compiler environment variables on first run. </policy/CMP0132>
CMP0131: LINK_LIBRARIES supports the LINK_ONLY generator expression. </policy/CMP0131>
CMP0130: while() diagnoses condition evaluation errors. </policy/CMP0130>
diff --git a/Help/policy/CMP0132.rst b/Help/policy/CMP0132.rst
new file mode 100644
index 0000000..fadbbdc
--- /dev/null
+++ b/Help/policy/CMP0132.rst
@@ -0,0 +1,26 @@
+CMP0132
+-------
+
+.. versionadded:: 3.24
+
+Apart from when using the Xcode generator and some Visual Studio generators,
+CMake 3.23 and below will set environment variables like :envvar:`CC`,
+:envvar:`CXX`, etc. when the corresponding language is enabled.
+This only occurs on the very first time CMake is run in a build directory,
+and the environment variables are only defined at configure time, not build
+time. On subsequent CMake runs, these environment variables are not set,
+opening up the opportunity for different behavior between the first and
+subsequent CMake runs. CMake 3.24 and above prefer to not set these
+environment variables when a language is enabled, even on the first run in
+a build directory.
+
+The ``OLD`` behavior for this policy sets the relevant environment variable
+on the first run when a language is enabled. The ``NEW`` behavior for this
+policy does not set any such environment variables.
+
+This policy was introduced in CMake version 3.24. Use the
+:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.
+Unlike many policies, CMake version |release| does *not* warn
+when this policy is not set and simply uses ``OLD`` behavior.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/release/dev/set-env-var-first-run.rst b/Help/release/dev/set-env-var-first-run.rst
new file mode 100644
index 0000000..c3f7d9f
--- /dev/null
+++ b/Help/release/dev/set-env-var-first-run.rst
@@ -0,0 +1,6 @@
+set-env-var-first-run
+---------------------
+
+* CMake no longer sets environment variables like :envvar:`CC`, :envvar:`CXX`,
+ etc. when enabling the corresponding language during the first CMake run in
+ a build directory. See policy :policy:`CMP0132`.
diff --git a/Help/variable/CMAKE_LINK_GROUP_USING_FEATURE.rst b/Help/variable/CMAKE_LINK_GROUP_USING_FEATURE.rst
index fad1837..692c099 100644
--- a/Help/variable/CMAKE_LINK_GROUP_USING_FEATURE.rst
+++ b/Help/variable/CMAKE_LINK_GROUP_USING_FEATURE.rst
@@ -19,8 +19,9 @@ of features dependent from the link language.
This variable will be used by :genex:`LINK_GROUP` generator expression if,
for the linker language, the variable
-:variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED` is false or not
-set.
+:variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED` is not defined
+and the variable :variable:`CMAKE_LINK_GROUP_USING_<FEATURE>_SUPPORTED` is
+``TRUE``..
.. include:: CMAKE_LINK_GROUP_USING_FEATURE.txt
diff --git a/Help/variable/CMAKE_LINK_GROUP_USING_FEATURE_SUPPORTED.rst b/Help/variable/CMAKE_LINK_GROUP_USING_FEATURE_SUPPORTED.rst
index 249ccbc..318892f 100644
--- a/Help/variable/CMAKE_LINK_GROUP_USING_FEATURE_SUPPORTED.rst
+++ b/Help/variable/CMAKE_LINK_GROUP_USING_FEATURE_SUPPORTED.rst
@@ -10,5 +10,4 @@ linker language.
.. note::
This variable is evaluated if, and only if, the variable
- :variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED` evaluates to
- ``FALSE``.
+ :variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED` is not defined.
diff --git a/Help/variable/CMAKE_LINK_LIBRARY_USING_FEATURE.rst b/Help/variable/CMAKE_LINK_LIBRARY_USING_FEATURE.rst
index 05de570..9f1cede 100644
--- a/Help/variable/CMAKE_LINK_LIBRARY_USING_FEATURE.rst
+++ b/Help/variable/CMAKE_LINK_LIBRARY_USING_FEATURE.rst
@@ -19,8 +19,9 @@ definition of features dependent from the link language.
This variable will be used by :genex:`LINK_LIBRARY` generator expression if,
for the linker language, the variable
-:variable:`CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED` is false or not
-set.
+:variable:`CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED` is not defined
+and the variable :variable:`CMAKE_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED` is
+``TRUE``.
.. include:: CMAKE_LINK_LIBRARY_USING_FEATURE.txt
diff --git a/Help/variable/CMAKE_LINK_LIBRARY_USING_FEATURE_SUPPORTED.rst b/Help/variable/CMAKE_LINK_LIBRARY_USING_FEATURE_SUPPORTED.rst
index 42b75fc..417724b 100644
--- a/Help/variable/CMAKE_LINK_LIBRARY_USING_FEATURE_SUPPORTED.rst
+++ b/Help/variable/CMAKE_LINK_LIBRARY_USING_FEATURE_SUPPORTED.rst
@@ -10,5 +10,5 @@ linker language.
.. note::
This variable is evaluated if, and only if, the variable
- :variable:`CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED` evaluates to
- ``FALSE``.
+ :variable:`CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED` is not
+ defined.
diff --git a/Modules/CMakeDetermineCompiler.cmake b/Modules/CMakeDetermineCompiler.cmake
index aec86d9..ec2a865 100644
--- a/Modules/CMakeDetermineCompiler.cmake
+++ b/Modules/CMakeDetermineCompiler.cmake
@@ -119,9 +119,15 @@ macro(_cmake_find_compiler_path lang)
# (e.g. via ctest) or set in CMAKE_TOOLCHAIN_FILE
# if CMAKE_${lang}_COMPILER is a list, use the first item as
# CMAKE_${lang}_COMPILER and the rest as CMAKE_${lang}_COMPILER_ARG1
- set(CMAKE_${lang}_COMPILER_ARG1 "${CMAKE_${lang}_COMPILER}")
- list(POP_FRONT CMAKE_${lang}_COMPILER_ARG1 CMAKE_${lang}_COMPILER)
- list(JOIN CMAKE_${lang}_COMPILER_ARG1 " " CMAKE_${lang}_COMPILER_ARG1)
+ # Otherwise, preserve any existing CMAKE_${lang}_COMPILER_ARG1 that might
+ # have been saved by CMakeDetermine${lang}Compiler in a previous run.
+ list(LENGTH CMAKE_${lang}_COMPILER _CMAKE_${lang}_COMPILER_LENGTH)
+ if(_CMAKE_${lang}_COMPILER_LENGTH GREATER 1)
+ set(CMAKE_${lang}_COMPILER_ARG1 "${CMAKE_${lang}_COMPILER}")
+ list(POP_FRONT CMAKE_${lang}_COMPILER_ARG1 CMAKE_${lang}_COMPILER)
+ list(JOIN CMAKE_${lang}_COMPILER_ARG1 " " CMAKE_${lang}_COMPILER_ARG1)
+ endif()
+ unset(_CMAKE_${lang}_COMPILER_LENGTH)
# find the compiler in the PATH if necessary
# if compiler (and arguments) comes from cache then synchronize cache with updated CMAKE_<LANG>_COMPILER
diff --git a/Modules/FindHDF5.cmake b/Modules/FindHDF5.cmake
index 40ed9a9..46ad015 100644
--- a/Modules/FindHDF5.cmake
+++ b/Modules/FindHDF5.cmake
@@ -555,8 +555,8 @@ if(NOT HDF5_FOUND AND NOT HDF5_NO_FIND_PACKAGE_CONFIG_FILE)
endif()
if( _hdf5_lang_location )
set(HDF5_${_lang}_LIBRARY ${_hdf5_lang_location})
- list(APPEND HDF5_LIBRARIES ${HDF5_${_lang}_TARGET}${_suffix})
- set(HDF5_${_lang}_LIBRARIES ${HDF5_${_lang}_TARGET}${_suffix})
+ list(APPEND HDF5_LIBRARIES ${HDF5_${_lang}_LIBRARY})
+ set(HDF5_${_lang}_LIBRARIES ${HDF5_${_lang}_LIBRARY})
set(HDF5_${_lang}_FOUND TRUE)
endif()
if(HDF5_FIND_HL)
@@ -569,8 +569,8 @@ if(NOT HDF5_FOUND AND NOT HDF5_NO_FIND_PACKAGE_CONFIG_FILE)
endif()
if( _hdf5_lang_hl_location )
set(HDF5_${_lang}_HL_LIBRARY ${_hdf5_lang_hl_location})
- list(APPEND HDF5_HL_LIBRARIES ${HDF5_${_lang}_HL_TARGET}${_suffix})
- set(HDF5_${_lang}_HL_LIBRARIES ${HDF5_${_lang}_HL_TARGET}${_suffix})
+ list(APPEND HDF5_HL_LIBRARIES ${HDF5_${_lang}_HL_LIBRARY})
+ set(HDF5_${_lang}_HL_LIBRARIES ${HDF5_${_lang}_HL_LIBRARY})
set(HDF5_HL_FOUND TRUE)
endif()
unset(_hdf5_lang_hl_location)
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 559b00d..1ea4df3 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,7 +1,7 @@
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
set(CMake_VERSION_MINOR 23)
-set(CMake_VERSION_PATCH 20220328)
+set(CMake_VERSION_PATCH 20220330)
#set(CMake_VERSION_RC 0)
set(CMake_VERSION_IS_DIRTY 0)
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index 67214f1..e156e3d 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -803,7 +803,9 @@ bool cmComputeLinkInformation::AddLibraryFeature(std::string const& feature)
cmStrCat("CMAKE_", this->LinkLanguage, "_LINK_LIBRARY_USING_", feature);
cmValue featureSupported =
this->Makefile->GetDefinition(cmStrCat(featureName, "_SUPPORTED"));
- if (!featureSupported.IsOn()) {
+ if (!featureSupported) {
+ // language specific variable is not defined, fallback to the more generic
+ // one
featureName = cmStrCat("CMAKE_LINK_LIBRARY_USING_", feature);
featureSupported =
this->Makefile->GetDefinition(cmStrCat(featureName, "_SUPPORTED"));
@@ -965,7 +967,9 @@ cmComputeLinkInformation::GetGroupFeature(std::string const& feature)
cmStrCat("CMAKE_", this->LinkLanguage, "_LINK_GROUP_USING_", feature);
cmValue featureSupported =
this->Makefile->GetDefinition(cmStrCat(featureName, "_SUPPORTED"));
- if (!featureSupported.IsOn()) {
+ if (!featureSupported) {
+ // language specific variable is not defined, fallback to the more generic
+ // one
featureName = cmStrCat("CMAKE_LINK_GROUP_USING_", feature);
featureSupported =
this->Makefile->GetDefinition(cmStrCat(featureName, "_SUPPORTED"));
@@ -1551,8 +1555,7 @@ void cmComputeLinkInformation::AddTargetItem(LinkEntry const& entry)
this->AddLibraryFeature("FRAMEWORK");
}
- if (cmHasSuffix(entry.Feature, "FRAMEWORK"_s) &&
- target->IsFrameworkOnApple() && !this->GlobalGenerator->IsXcode()) {
+ if (target->IsFrameworkOnApple() && !this->GlobalGenerator->IsXcode()) {
// Add the framework directory and the framework item itself
auto fwItems = this->GlobalGenerator->SplitFrameworkPath(item.Value, true);
if (!fwItems) {
@@ -1567,8 +1570,15 @@ void cmComputeLinkInformation::AddTargetItem(LinkEntry const& entry)
// Add the directory portion to the framework search path.
this->AddFrameworkPath(fwItems->first);
}
- this->Items.emplace_back(fwItems->second, ItemIsPath::Yes, target,
- this->FindLibraryFeature(entry.Feature));
+ if (cmHasSuffix(entry.Feature, "FRAMEWORK"_s)) {
+ this->Items.emplace_back(fwItems->second, ItemIsPath::Yes, target,
+ this->FindLibraryFeature(entry.Feature));
+ } else {
+ this->Items.emplace_back(
+ item, ItemIsPath::Yes, target,
+ this->FindLibraryFeature(
+ entry.Feature == DEFAULT ? "__CMAKE_LINK_LIBRARY" : entry.Feature));
+ }
} else {
// Now add the full path to the library.
this->Items.emplace_back(
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index b869308..3c31db1 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -759,7 +759,9 @@ void cmGlobalGenerator::EnableLanguage(
needTestLanguage[lang] = true;
// Some generators like visual studio should not use the env variables
// So the global generator can specify that in this variable
- if (!mf->GetDefinition("CMAKE_GENERATOR_NO_COMPILER_ENV")) {
+ if ((mf->GetPolicyStatus(cmPolicies::CMP0132) == cmPolicies::OLD ||
+ mf->GetPolicyStatus(cmPolicies::CMP0132) == cmPolicies::WARN) &&
+ !mf->GetDefinition("CMAKE_GENERATOR_NO_COMPILER_ENV")) {
// put ${CMake_(LANG)_COMPILER_ENV_VAR}=${CMAKE_(LANG)_COMPILER
// into the environment, in case user scripts want to run
// configure, or sub cmakes
diff --git a/Source/cmIfCommand.cxx b/Source/cmIfCommand.cxx
index 55f6453..9cd1943 100644
--- a/Source/cmIfCommand.cxx
+++ b/Source/cmIfCommand.cxx
@@ -73,11 +73,11 @@ bool cmIfFunctionBlocker::Replay(std::vector<cmListFileFunction> functions,
}
// watch for our state change
if (scopeDepth == 0 && func.LowerCaseName() == "else") {
+ cmListFileBacktrace elseBT = mf.GetBacktrace().Push(
+ cmListFileContext{ func.OriginalName(),
+ this->GetStartingContext().FilePath, func.Line() });
if (this->ElseSeen) {
- cmListFileBacktrace elseBT = mf.GetBacktrace().Push(cmListFileContext{
- func.OriginalName(), this->GetStartingContext().FilePath,
- func.Line() });
mf.GetCMakeInstance()->IssueMessage(
MessageType::FATAL_ERROR,
"A duplicate ELSE command was found inside an IF block.", elseBT);
@@ -92,7 +92,8 @@ bool cmIfFunctionBlocker::Replay(std::vector<cmListFileFunction> functions,
// if trace is enabled, print a (trivially) evaluated "else"
// statement
if (!this->IsBlocking && mf.GetCMakeInstance()->GetTrace()) {
- mf.PrintCommandTrace(func);
+ mf.PrintCommandTrace(func, elseBT,
+ cmMakefile::CommandMissingFromStack::Yes);
}
} else if (scopeDepth == 0 && func.LowerCaseName() == "elseif") {
cmListFileBacktrace elseifBT = mf.GetBacktrace().Push(
@@ -111,7 +112,8 @@ bool cmIfFunctionBlocker::Replay(std::vector<cmListFileFunction> functions,
} else {
// if trace is enabled, print the evaluated "elseif" statement
if (mf.GetCMakeInstance()->GetTrace()) {
- mf.PrintCommandTrace(func);
+ mf.PrintCommandTrace(func, elseifBT,
+ cmMakefile::CommandMissingFromStack::Yes);
}
std::string errorString;
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index f0a96a8..a781d59 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -241,14 +241,14 @@ cmListFileBacktrace cmMakefile::GetBacktrace() const
return this->Backtrace;
}
-void cmMakefile::PrintCommandTrace(
- cmListFileFunction const& lff,
- cm::optional<std::string> const& deferId) const
+void cmMakefile::PrintCommandTrace(cmListFileFunction const& lff,
+ cmListFileBacktrace const& bt,
+ CommandMissingFromStack missing) const
{
// Check if current file in the list of requested to trace...
std::vector<std::string> const& trace_only_this_files =
this->GetCMakeInstance()->GetTraceSources();
- std::string const& full_path = this->GetBacktrace().Top().FilePath;
+ std::string const& full_path = bt.Top().FilePath;
std::string const& only_filename = cmSystemTools::GetFilenameName(full_path);
bool trace = trace_only_this_files.empty();
if (!trace) {
@@ -282,6 +282,7 @@ void cmMakefile::PrintCommandTrace(
args.push_back(arg.Value);
}
}
+ cm::optional<std::string> const& deferId = bt.Top().DeferId;
switch (this->GetCMakeInstance()->GetTraceFormat()) {
case cmake::TraceFormat::TRACE_JSON_V1: {
@@ -303,9 +304,9 @@ void cmMakefile::PrintCommandTrace(
val["args"].append(arg);
}
val["time"] = cmSystemTools::GetTime();
- val["frame"] =
+ val["frame"] = (missing == CommandMissingFromStack::Yes ? 1 : 0) +
static_cast<Json::Value::UInt64>(this->ExecutionStatusStack.size());
- val["global_frame"] =
+ val["global_frame"] = (missing == CommandMissingFromStack::Yes ? 1 : 0) +
static_cast<Json::Value::UInt64>(this->RecursionDepth);
msg << Json::writeString(builder, val);
#endif
@@ -427,7 +428,7 @@ bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff,
if (!cmSystemTools::GetFatalErrorOccured()) {
// if trace is enabled, print out invoke information
if (this->GetCMakeInstance()->GetTrace()) {
- this->PrintCommandTrace(lff, this->Backtrace.Top().DeferId);
+ this->PrintCommandTrace(lff, this->Backtrace);
}
// Try invoking the command.
bool invokeSucceeded = command(lff.Arguments(), status);
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index 6d44e79..c8e1e83 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -674,11 +674,18 @@ public:
bool copyonly, bool atOnly, bool escapeQuotes,
mode_t permissions = 0, cmNewLineStyle = cmNewLineStyle());
+ enum class CommandMissingFromStack
+ {
+ No,
+ Yes,
+ };
+
/**
* Print a command's invocation
*/
- void PrintCommandTrace(cmListFileFunction const& lff,
- cm::optional<std::string> const& deferId = {}) const;
+ void PrintCommandTrace(
+ cmListFileFunction const& lff, cmListFileBacktrace const& bt,
+ CommandMissingFromStack missing = CommandMissingFromStack::No) const;
/**
* Set a callback that is invoked whenever ExecuteCommand is called.
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index 3b9d067..434c51c 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -393,7 +393,10 @@ class cmMakefile;
3, 24, 0, cmPolicies::WARN) \
SELECT(POLICY, CMP0131, \
"LINK_LIBRARIES supports the LINK_ONLY generator expression.", 3, \
- 24, 0, cmPolicies::WARN)
+ 24, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0132, \
+ "Do not set compiler environment variables on first run", 3, 24, 0, \
+ cmPolicies::WARN)
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
#define CM_FOR_EACH_POLICY_ID(POLICY) \
diff --git a/Tests/RunCMake/CMP0132/CMP0132-Common.cmake b/Tests/RunCMake/CMP0132/CMP0132-Common.cmake
new file mode 100644
index 0000000..796f61c
--- /dev/null
+++ b/Tests/RunCMake/CMP0132/CMP0132-Common.cmake
@@ -0,0 +1,15 @@
+if(NOT "$ENV{CC}" STREQUAL "")
+ message(STATUS "Test environment already sets CC, test being SKIPPED")
+ return()
+elseif(CMAKE_GENERATOR MATCHES "Xcode|Visual Studio")
+ message(STATUS "This generator never sets CC, test being SKIPPED")
+ return()
+endif()
+
+enable_language(C)
+
+if("$ENV{CC}" STREQUAL "")
+ message(STATUS "CC was left unset")
+else()
+ message(STATUS "CC was set to $ENV{CC}")
+endif()
diff --git a/Tests/RunCMake/CMP0132/CMP0132-NEW-stdout.txt b/Tests/RunCMake/CMP0132/CMP0132-NEW-stdout.txt
new file mode 100644
index 0000000..8056c2c
--- /dev/null
+++ b/Tests/RunCMake/CMP0132/CMP0132-NEW-stdout.txt
@@ -0,0 +1 @@
+SKIPPED|CC was left unset
diff --git a/Tests/RunCMake/CMP0132/CMP0132-NEW.cmake b/Tests/RunCMake/CMP0132/CMP0132-NEW.cmake
new file mode 100644
index 0000000..fabb419
--- /dev/null
+++ b/Tests/RunCMake/CMP0132/CMP0132-NEW.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0132 NEW)
+include(CMP0132-Common.cmake)
diff --git a/Tests/RunCMake/CMP0132/CMP0132-OLD-stdout.txt b/Tests/RunCMake/CMP0132/CMP0132-OLD-stdout.txt
new file mode 100644
index 0000000..c131428
--- /dev/null
+++ b/Tests/RunCMake/CMP0132/CMP0132-OLD-stdout.txt
@@ -0,0 +1 @@
+SKIPPED|CC was set
diff --git a/Tests/RunCMake/CMP0132/CMP0132-OLD.cmake b/Tests/RunCMake/CMP0132/CMP0132-OLD.cmake
new file mode 100644
index 0000000..aae4f2a
--- /dev/null
+++ b/Tests/RunCMake/CMP0132/CMP0132-OLD.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0132 OLD)
+include(CMP0132-Common.cmake)
diff --git a/Tests/RunCMake/CMP0132/CMP0132-WARN-stdout.txt b/Tests/RunCMake/CMP0132/CMP0132-WARN-stdout.txt
new file mode 100644
index 0000000..c131428
--- /dev/null
+++ b/Tests/RunCMake/CMP0132/CMP0132-WARN-stdout.txt
@@ -0,0 +1 @@
+SKIPPED|CC was set
diff --git a/Tests/RunCMake/CMP0132/CMP0132-WARN.cmake b/Tests/RunCMake/CMP0132/CMP0132-WARN.cmake
new file mode 100644
index 0000000..c07e5db
--- /dev/null
+++ b/Tests/RunCMake/CMP0132/CMP0132-WARN.cmake
@@ -0,0 +1,2 @@
+
+include(CMP0132-Common.cmake)
diff --git a/Tests/RunCMake/CMP0132/CMakeLists.txt b/Tests/RunCMake/CMP0132/CMakeLists.txt
new file mode 100644
index 0000000..5ff8d3e
--- /dev/null
+++ b/Tests/RunCMake/CMP0132/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.23)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0132/RunCMakeTest.cmake b/Tests/RunCMake/CMP0132/RunCMakeTest.cmake
new file mode 100644
index 0000000..db599ce
--- /dev/null
+++ b/Tests/RunCMake/CMP0132/RunCMakeTest.cmake
@@ -0,0 +1,7 @@
+include(RunCMake)
+
+if(NOT CMAKE_GENERATOR_NO_COMPILER_ENV)
+ run_cmake(CMP0132-WARN)
+ run_cmake(CMP0132-OLD)
+ run_cmake(CMP0132-NEW)
+endif()
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 8aba6c5..dbff293 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -142,6 +142,14 @@ if (CMAKE_SYSTEM_NAME MATCHES "(Linux|Darwin)")
endif()
add_RunCMake_test(CMP0126)
+if("${CMAKE_C_COMPILER_ID}" STREQUAL "LCC" OR
+ "${CMAKE_CXX_COMPILER_ID}" STREQUAL "LCC" OR
+ "${CMAKE_Fortran_COMPILER_ID}" STREQUAL "LCC")
+ add_RunCMake_test("CMP0129")
+endif()
+
+add_RunCMake_test(CMP0132)
+
# The test for Policy 65 requires the use of the
# CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS variable, which both the VS and Xcode
# generators ignore. The policy will have no effect on those generators.
@@ -979,7 +987,3 @@ endif()
if(WIN32)
add_RunCMake_test(Win32GenEx)
endif()
-
-if("${CMAKE_C_COMPILER_ID}" STREQUAL "LCC" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "LCC" OR "${CMAKE_Fortran_COMPILER_ID}" STREQUAL "LCC")
- add_RunCMake_test("CMP0129")
-endif()
diff --git a/Tests/RunCMake/CommandLine/trace-json-v1-check.py b/Tests/RunCMake/CommandLine/trace-json-v1-check.py
index 2ef1495..c4b95dc 100755
--- a/Tests/RunCMake/CommandLine/trace-json-v1-check.py
+++ b/Tests/RunCMake/CommandLine/trace-json-v1-check.py
@@ -56,6 +56,11 @@ required_traces = [
'cmd': 'message',
'frame': 3,
'global_frame': 6 if expand else 5
+ },
+ {
+ 'cmd': 'else',
+ 'global_frame': 4 if expand else 3,
+ 'line': 3
}
]
@@ -98,4 +103,7 @@ with open(trace_file, 'r') as fp:
if subset == j:
required_traces.remove(j)
-assert not required_traces
+assert not required_traces, (
+ "The following traces were expected to be part of the "
+ "output but weren't", required_traces
+)
diff --git a/Tests/RunCMake/CommandLine/trace-json-v1-nested/CMakeLists.txt b/Tests/RunCMake/CommandLine/trace-json-v1-nested/CMakeLists.txt
index 089a960..743f6de 100644
--- a/Tests/RunCMake/CommandLine/trace-json-v1-nested/CMakeLists.txt
+++ b/Tests/RunCMake/CommandLine/trace-json-v1-nested/CMakeLists.txt
@@ -1,3 +1,8 @@
+function(function_that_uses_else)
+ if(FALSE)
+ else()
+ endif()
+endfunction()
function(f)
message(STATUS "nested global_frame")
endfunction()
diff --git a/Tests/RunCMake/CommandLine/trace-json-v1.cmake b/Tests/RunCMake/CommandLine/trace-json-v1.cmake
index 4ed6160..464eb1f 100644
--- a/Tests/RunCMake/CommandLine/trace-json-v1.cmake
+++ b/Tests/RunCMake/CommandLine/trace-json-v1.cmake
@@ -8,3 +8,4 @@ set(FOO 42)
set(BAR " space in string!")
message(STATUS fff ${ASDF} " ${FOO} ${BAR}" " SPACES !!! ")
add_subdirectory(trace-json-v1-nested)
+function_that_uses_else()
diff --git a/Tests/RunCMake/CompilerArgs/C-stdout.txt b/Tests/RunCMake/CompilerArgs/C-stdout.txt
new file mode 100644
index 0000000..e553cbb
--- /dev/null
+++ b/Tests/RunCMake/CompilerArgs/C-stdout.txt
@@ -0,0 +1 @@
+-- CMAKE_C_COMPILER_ARG1=' ?-DFOO1 -DFOO2'
diff --git a/Tests/RunCMake/CompilerArgs/C.cmake b/Tests/RunCMake/CompilerArgs/C.cmake
index 96b004b..0fbfdd2 100644
--- a/Tests/RunCMake/CompilerArgs/C.cmake
+++ b/Tests/RunCMake/CompilerArgs/C.cmake
@@ -1,3 +1,4 @@
enable_language(C)
set(CMAKE_VERBOSE_MAKEFILE TRUE)
+message(STATUS "CMAKE_C_COMPILER_ARG1='${CMAKE_C_COMPILER_ARG1}'")
add_executable(main main.c)
diff --git a/Tests/RunCMake/CompilerArgs/CXX-stdout.txt b/Tests/RunCMake/CompilerArgs/CXX-stdout.txt
new file mode 100644
index 0000000..c543d3b
--- /dev/null
+++ b/Tests/RunCMake/CompilerArgs/CXX-stdout.txt
@@ -0,0 +1 @@
+-- CMAKE_CXX_COMPILER_ARG1=' ?-DFOO1 -DFOO2'
diff --git a/Tests/RunCMake/CompilerArgs/CXX.cmake b/Tests/RunCMake/CompilerArgs/CXX.cmake
index 3d2ee00..b6cf87e 100644
--- a/Tests/RunCMake/CompilerArgs/CXX.cmake
+++ b/Tests/RunCMake/CompilerArgs/CXX.cmake
@@ -1,3 +1,4 @@
enable_language(CXX)
set(CMAKE_VERBOSE_MAKEFILE TRUE)
+message(STATUS "CMAKE_CXX_COMPILER_ARG1='${CMAKE_CXX_COMPILER_ARG1}'")
add_executable(main main.cxx)
diff --git a/Tests/RunCMake/CompilerArgs/RunCMakeTest.cmake b/Tests/RunCMake/CompilerArgs/RunCMakeTest.cmake
index 9e5a18a..62294cd 100644
--- a/Tests/RunCMake/CompilerArgs/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CompilerArgs/RunCMakeTest.cmake
@@ -19,12 +19,6 @@ function(run_compiler_env lang)
# Use the correct compiler
include(${RunCMake_BINARY_DIR}/Find${lang}Compiler-build/${lang}_comp.cmake)
- # Use a single build tree for tests without cleaning.
- set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${lang}-env-build)
- set(RunCMake_TEST_NO_CLEAN 1)
- file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
- file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
-
# Set the compiler
if(lang STREQUAL "C")
set(ENV{CC} "'${temp_CMAKE_${lang}_COMPILER}' -DFOO1 -DFOO2")
@@ -32,19 +26,30 @@ function(run_compiler_env lang)
set(ENV{${lang}} "'${temp_CMAKE_${lang}_COMPILER}' -DFOO1 -DFOO2")
endif()
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${lang}-env-build)
+ set(RunCMake_TEST_VARIANT_DESCRIPTION "-env")
+ run_cmake(${lang})
+ set(RunCMake_TEST_NO_CLEAN 1)
+ run_cmake_command(${lang}-Build ${CMAKE_COMMAND} --build . ${verbose_args})
+
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}/CMakeFiles")
+ set(RunCMake_TEST_VARIANT_DESCRIPTION "-env-cached")
run_cmake(${lang})
run_cmake_command(${lang}-Build ${CMAKE_COMMAND} --build . ${verbose_args})
endfunction()
function(run_compiler_tc lang)
- # Use a single build tree for tests without cleaning.
+ set(RunCMake_TEST_OPTIONS
+ -DCMAKE_TOOLCHAIN_FILE=${RunCMake_BINARY_DIR}/Find${lang}Compiler-build/toolchain_${lang}_comp.cmake)
+
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${lang}-tc-build)
+ set(RunCMake_TEST_VARIANT_DESCRIPTION "-tc")
+ run_cmake(${lang})
set(RunCMake_TEST_NO_CLEAN 1)
- file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
- file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+ run_cmake_command(${lang}-Build ${CMAKE_COMMAND} --build . ${verbose_args})
- set(RunCMake_TEST_OPTIONS
- -DCMAKE_TOOLCHAIN_FILE=${RunCMake_BINARY_DIR}/Find${lang}Compiler-build/toolchain_${lang}_comp.cmake)
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}/CMakeFiles")
+ set(RunCMake_TEST_VARIANT_DESCRIPTION "-tc-cached")
run_cmake(${lang})
run_cmake_command(${lang}-Build ${CMAKE_COMMAND} --build . ${verbose_args})
endfunction()
diff --git a/Tests/RunCMake/Framework/FrameworkConsumption.cmake b/Tests/RunCMake/Framework/FrameworkConsumption.cmake
new file mode 100644
index 0000000..4663166
--- /dev/null
+++ b/Tests/RunCMake/Framework/FrameworkConsumption.cmake
@@ -0,0 +1,15 @@
+
+cmake_minimum_required(VERSION 3.22...3.24)
+enable_language(C)
+
+# Create framework and ensure header is placed in Headers
+set(input_header "${CMAKE_SOURCE_DIR}/Gui.h")
+add_library(Gui SHARED Gui.c "${input_header}")
+set_target_properties(Gui PROPERTIES
+ PUBLIC_HEADER "${input_header}"
+ FRAMEWORK TRUE
+)
+
+add_executable(app main.c)
+
+target_link_libraries(app PRIVATE Gui)
diff --git a/Tests/RunCMake/Framework/Gui.c b/Tests/RunCMake/Framework/Gui.c
new file mode 100644
index 0000000..f669327
--- /dev/null
+++ b/Tests/RunCMake/Framework/Gui.c
@@ -0,0 +1,5 @@
+
+int foo(void)
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/Framework/Gui.h b/Tests/RunCMake/Framework/Gui.h
new file mode 100644
index 0000000..5beae6d
--- /dev/null
+++ b/Tests/RunCMake/Framework/Gui.h
@@ -0,0 +1,2 @@
+
+int foo(void);
diff --git a/Tests/RunCMake/Framework/RunCMakeTest.cmake b/Tests/RunCMake/Framework/RunCMakeTest.cmake
index 2f8fdc7..a767130 100644
--- a/Tests/RunCMake/Framework/RunCMakeTest.cmake
+++ b/Tests/RunCMake/Framework/RunCMakeTest.cmake
@@ -105,3 +105,15 @@ function(framework_system_include_test)
endfunction()
framework_system_include_test()
+
+function(framework_consumption)
+ set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/FrameworkConsumption-build")
+ set(RunCMake_TEST_NO_CLEAN 1)
+
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+ run_cmake(FrameworkConsumption)
+ run_cmake_command(FrameworkConsumption-build ${CMAKE_COMMAND} --build .)
+endfunction()
+
+framework_consumption()
diff --git a/Tests/RunCMake/Framework/main.c b/Tests/RunCMake/Framework/main.c
new file mode 100644
index 0000000..fc09922
--- /dev/null
+++ b/Tests/RunCMake/Framework/main.c
@@ -0,0 +1,9 @@
+
+#include <Gui/Gui.h>
+
+int main()
+{
+ foo();
+
+ return 0;
+}
diff --git a/Tests/RunCMake/GenEx-LINK_GROUP/RunCMakeTest.cmake b/Tests/RunCMake/GenEx-LINK_GROUP/RunCMakeTest.cmake
index 98eef35..f20d225 100644
--- a/Tests/RunCMake/GenEx-LINK_GROUP/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GenEx-LINK_GROUP/RunCMakeTest.cmake
@@ -11,6 +11,7 @@ run_cmake(empty-arguments)
run_cmake(forbidden-arguments)
run_cmake(nested-incompatible-genex)
run_cmake(invalid-feature)
+run_cmake(multiple-definitions)
run_cmake(bad-feature1)
run_cmake(bad-feature2)
run_cmake(bad-feature3)
diff --git a/Tests/RunCMake/GenEx-LINK_GROUP/multiple-definitions-result.txt b/Tests/RunCMake/GenEx-LINK_GROUP/multiple-definitions-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_GROUP/multiple-definitions-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-LINK_GROUP/multiple-definitions-stderr.txt b/Tests/RunCMake/GenEx-LINK_GROUP/multiple-definitions-stderr.txt
new file mode 100644
index 0000000..995f363
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_GROUP/multiple-definitions-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at multiple-definitions.cmake:[0-9]+ \(add_library\):
+ Feature 'feat', specified through generator-expression '\$<LINK_GROUP>' to
+ link target 'lib', is not supported for the 'C' link language.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LINK_GROUP/multiple-definitions.cmake b/Tests/RunCMake/GenEx-LINK_GROUP/multiple-definitions.cmake
new file mode 100644
index 0000000..a021d44
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_GROUP/multiple-definitions.cmake
@@ -0,0 +1,12 @@
+enable_language(C)
+
+# Language specific definition takes precedence over more generic one
+set(CMAKE_C_LINK_GROUP_USING_feat "-BEFORE" "-AFTER")
+set(CMAKE_C_LINK_GROUP_USING_feat_SUPPORTED FALSE)
+set(CMAKE_LINK_GROUP_USING_feat "-BEFORE" "-AFTER")
+set(CMAKE_LINK_GROUP_USING_feat_SUPPORTED TRUE)
+
+add_library(dep SHARED empty.c)
+
+add_library(lib SHARED empty.c)
+target_link_libraries(lib PRIVATE "$<LINK_GROUP:feat,dep>")
diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/RunCMakeTest.cmake b/Tests/RunCMake/GenEx-LINK_LIBRARY/RunCMakeTest.cmake
index 9c266fe..3fb68d6 100644
--- a/Tests/RunCMake/GenEx-LINK_LIBRARY/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GenEx-LINK_LIBRARY/RunCMakeTest.cmake
@@ -10,6 +10,7 @@ run_cmake(no-arguments)
run_cmake(empty-arguments)
run_cmake(forbidden-arguments)
run_cmake(invalid-feature)
+run_cmake(multiple-definitions)
run_cmake(bad-feature1)
run_cmake(bad-feature2)
run_cmake(bad-feature3)
diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/multiple-definitions-result.txt b/Tests/RunCMake/GenEx-LINK_LIBRARY/multiple-definitions-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LIBRARY/multiple-definitions-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/multiple-definitions-stderr.txt b/Tests/RunCMake/GenEx-LINK_LIBRARY/multiple-definitions-stderr.txt
new file mode 100644
index 0000000..26b0bac
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LIBRARY/multiple-definitions-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at multiple-definitions.cmake:[0-9]+ \(add_library\):
+ Feature 'feat', specified through generator-expression '\$<LINK_LIBRARY>' to
+ link target 'lib', is not supported for the 'C' link language.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/multiple-definitions.cmake b/Tests/RunCMake/GenEx-LINK_LIBRARY/multiple-definitions.cmake
new file mode 100644
index 0000000..1bd1888
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LIBRARY/multiple-definitions.cmake
@@ -0,0 +1,12 @@
+enable_language(C)
+
+# Language specific definition takes precedence over more generic one
+set(CMAKE_C_LINK_LIBRARY_USING_feat "<LIBRARY>")
+set(CMAKE_C_LINK_LIBRARY_USING_feat_SUPPORTED FALSE)
+set(CMAKE_LINK_LIBRARY_USING_feat "<LIBRARY>")
+set(CMAKE_LINK_LIBRARY_USING_feat_SUPPORTED TRUE)
+
+add_library(dep SHARED empty.c)
+
+add_library(lib SHARED empty.c)
+target_link_libraries(lib PRIVATE "$<LINK_LIBRARY:feat,dep>")
diff --git a/Tests/RunCMake/target_link_libraries-LINK_GROUP/LINK_GROUP-multiple-definitions-result.txt b/Tests/RunCMake/target_link_libraries-LINK_GROUP/LINK_GROUP-multiple-definitions-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINK_GROUP/LINK_GROUP-multiple-definitions-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_libraries-LINK_GROUP/LINK_GROUP-mutiple-definitions-check.cmake b/Tests/RunCMake/target_link_libraries-LINK_GROUP/LINK_GROUP-mutiple-definitions-check.cmake
new file mode 100644
index 0000000..3e53d26
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINK_GROUP/LINK_GROUP-mutiple-definitions-check.cmake
@@ -0,0 +1,4 @@
+
+if (NOT actual_stdout MATCHES "(/|-)-START_GROUP\"? +.*${LINK_SHARED_LIBRARY_PREFIX}base1${LINK_SHARED_LIBRARY_SUFFIX} +.*${LINK_SHARED_LIBRARY_PREFIX}base2${LINK_SHARED_LIBRARY_SUFFIX} +\"?(/|-)-END_GROUP")
+ set (RunCMake_TEST_FAILED "Not found expected '--START_GROUP <base1> <base2> --END_GROUP'.")
+endif()
diff --git a/Tests/RunCMake/target_link_libraries-LINK_GROUP/LINK_GROUP.cmake b/Tests/RunCMake/target_link_libraries-LINK_GROUP/LINK_GROUP.cmake
index d08db16..31eb7e2 100644
--- a/Tests/RunCMake/target_link_libraries-LINK_GROUP/LINK_GROUP.cmake
+++ b/Tests/RunCMake/target_link_libraries-LINK_GROUP/LINK_GROUP.cmake
@@ -20,6 +20,9 @@ set(CMAKE_C_LINK_GROUP_USING_feat1_SUPPORTED TRUE)
set(CMAKE_C_LINK_LIBRARY_USING_feat1 "--LIBFLAG<LIBRARY>")
set(CMAKE_C_LINK_LIBRARY_USING_feat1_SUPPORTED TRUE)
+set(CMAKE_C_LINK_GROUP_USING_feat2 "--START_GROUP" "--END_GROUP")
+set(CMAKE_LINK_GROUP_USING_feat2 "--START_GROUP" "--END_GROUP")
+set(CMAKE_LINK_GROUP_USING_feat2_SUPPORTED TRUE)
add_library(LinkGroup_simple1 SHARED lib.c)
target_link_libraries(LinkGroup_simple1 PRIVATE "$<LINK_GROUP:feat1,base1,base2>")
@@ -31,6 +34,10 @@ add_library(LinkGroup_simple2 SHARED lib.c)
target_link_libraries(LinkGroup_simple2 PRIVATE "$<LINK_GROUP:feat1,base2,base3>")
+add_library(LinkGroup_multiple-definitions SHARED lib.c)
+target_link_libraries(LinkGroup_multiple-definitions PRIVATE "$<LINK_GROUP:feat2,base1,base2>")
+
+
add_library(base4 SHARED base.c)
target_link_libraries(base4 INTERFACE "$<LINK_GROUP:feat1,base1,base2>")
add_library(LinkGroup_multiple-groups SHARED lib.c)
diff --git a/Tests/RunCMake/target_link_libraries-LINK_GROUP/RunCMakeTest.cmake b/Tests/RunCMake/target_link_libraries-LINK_GROUP/RunCMakeTest.cmake
index 400905c..c1d74d0 100644
--- a/Tests/RunCMake/target_link_libraries-LINK_GROUP/RunCMakeTest.cmake
+++ b/Tests/RunCMake/target_link_libraries-LINK_GROUP/RunCMakeTest.cmake
@@ -42,6 +42,7 @@ if ((RunCMake_GENERATOR MATCHES "Makefiles|Ninja|Xcode"
run_cmake_target(LINK_GROUP simple1 LinkGroup_simple1)
run_cmake_target(LINK_GROUP simple2 LinkGroup_simple2)
+ run_cmake_target(LINK_GROUP multiple-definitions LinkGroup_multiple-definitions)
run_cmake_target(LINK_GROUP multiple-groups LinkGroup_multiple-groups)
run_cmake_target(LINK_GROUP group-and-single LinkGroup_group-and-single)
run_cmake_target(LINK_GROUP with-LINK_LIBRARY LinkGroup_with-LINK_LIBRARY)
diff --git a/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/LINK_LIBRARY.cmake b/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/LINK_LIBRARY.cmake
index 1581611..f19112a 100644
--- a/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/LINK_LIBRARY.cmake
+++ b/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/LINK_LIBRARY.cmake
@@ -16,7 +16,6 @@ set(CMAKE_C_LINK_LIBRARY_USING_feat1 "--LIBFLAG<LIBRARY>")
set(CMAKE_C_LINK_LIBRARY_USING_feat1_SUPPORTED TRUE)
set(CMAKE_C_LINK_LIBRARY_USING_feat1_1 "--LIBFLAG_C<LIBRARY>")
-set(CMAKE_C_LINK_LIBRARY_USING_feat1_1_SUPPORTED FALSE)
set(CMAKE_LINK_LIBRARY_USING_feat1_1 "--LIBFLAG<LIBRARY>")
set(CMAKE_LINK_LIBRARY_USING_feat1_1_SUPPORTED TRUE)