Link step: Add LINK_WARNING_AS_ERROR target property

Add a way to specify, in a portable way, to raise an error for any
warning during the link step. For that purpose, define:
* CMAKE_LINK_WARNING_AS_ERROR variable
* LINK_WARNING_AS_ERROR target property

Fixes: #25343
This commit is contained in:
Marc Chevrier
2024-11-06 11:53:59 +01:00
parent 656267c871
commit 7907c83175
58 changed files with 421 additions and 28 deletions
+1
View File
@@ -342,6 +342,7 @@ Properties on Targets
/prop_tgt/LINK_OPTIONS
/prop_tgt/LINK_SEARCH_END_STATIC
/prop_tgt/LINK_SEARCH_START_STATIC
/prop_tgt/LINK_WARNING_AS_ERROR
/prop_tgt/LINK_WHAT_YOU_USE
/prop_tgt/LINKER_LANGUAGE
/prop_tgt/LINKER_TYPE
+1
View File
@@ -499,6 +499,7 @@ Variables that Control the Build
/variable/CMAKE_LINK_LIBRARY_FLAG
/variable/CMAKE_LINK_LIBRARY_USING_FEATURE
/variable/CMAKE_LINK_LIBRARY_USING_FEATURE_SUPPORTED
/variable/CMAKE_LINK_WARNING_AS_ERROR
/variable/CMAKE_LINK_WHAT_YOU_USE
/variable/CMAKE_LINK_WHAT_YOU_USE_CHECK
/variable/CMAKE_LINKER_TYPE
+8
View File
@@ -513,6 +513,14 @@ Options
:variable:`CMAKE_COMPILE_WARNING_AS_ERROR`, preventing warnings from being
treated as errors on compile.
.. option:: --link-no-warning-as-error
.. versionadded:: 3.32
Ignore target property :prop_tgt:`LINK_WARNING_AS_ERROR` and variable
:variable:`CMAKE_LINK_WARNING_AS_ERROR`, preventing warnings from being
treated as errors on link.
.. option:: --profiling-output=<path>
.. versionadded:: 3.18
+27
View File
@@ -0,0 +1,27 @@
LINK_WARNING_AS_ERROR
---------------------
.. versionadded:: 3.32
Specify whether to treat warnings on link as errors.
If enabled, adds a flag to treat warnings on link as errors.
If the :option:`cmake --link-no-warning-as-error` option is given
on the :manual:`cmake(1)` command line, this property is ignored.
This property is not implemented for all linkers. It is silently ignored
if there is no implementation for the linker being used. The currently
implemented :variable:`compiler linker IDs <CMAKE_<LANG>_COMPILER_LINKER_ID>`
are:
* ``AIX``
* ``AppleClang``
* ``GNU``
* ``GNUgold``
* ``LLD``
* ``MOLD``
* ``MSVC``
* ``Solaris``
This property is initialized by the value of the variable
:variable:`CMAKE_LINK_WARNING_AS_ERROR` if it is set when a target is
created.
@@ -0,0 +1,11 @@
link-warning-as-error
---------------------
* The :variable:`CMAKE_LINK_WARNING_AS_ERROR` variable and corresponding
:prop_tgt:`LINK_WARNING_AS_ERROR` target property were added to enable
link with a linker-specific flag to treat warnings as errors.
* The :manual:`cmake(1)` command line gained the
:option:`--link-no-warning-as-error <cmake --link-no-warning-as-error>`
option which causes the effects of the :prop_tgt:`LINK_WARNING_AS_ERROR`
target property and :variable:`CMAKE_LINK_WARNING_AS_ERROR` variable to be
ignored.
@@ -0,0 +1,9 @@
CMAKE_LINK_WARNING_AS_ERROR
---------------------------
.. versionadded:: 3.32
Specify whether to treat warnings on link as errors.
This variable is used to initialize the
:prop_tgt:`LINK_WARNING_AS_ERROR` property on all the targets.
+2
View File
@@ -6,4 +6,6 @@
include_guard()
macro(__linker_aix lang)
# Linker warning as error
set(CMAKE_${lang}_LINK_OPTIONS_WARNING_AS_ERROR "LINKER:-bhalt:0")
endmacro()
+2
View File
@@ -7,4 +7,6 @@
include_guard()
macro(__linker_appleclang lang)
# Linker warning as error
set(CMAKE_${lang}_LINK_OPTIONS_WARNING_AS_ERROR "LINKER:-fatal_warnings")
endmacro()
+5 -1
View File
@@ -65,10 +65,14 @@ function(__linker_gnu lang)
set(CMAKE_${lang}_LINK_DEPENDS_USE_LINKER FALSE)
endif()
# Linker warning as error
set(CMAKE_${lang}_LINK_OPTIONS_WARNING_AS_ERROR "LINKER:--fatal-warnings")
return(PROPAGATE CMAKE_${lang}_LINKER_DEPFILE_FLAGS
CMAKE_${lang}_LINKER_DEPFILE_FORMAT
CMAKE_${lang}_LINKER_DEPFILE_SUPPORTED
CMAKE_${lang}_LINK_DEPENDS_USE_LINKER)
CMAKE_${lang}_LINK_DEPENDS_USE_LINKER
CMAKE_${lang}_LINK_OPTIONS_WARNING_AS_ERROR)
endfunction()
endblock()
+14 -2
View File
@@ -3,8 +3,20 @@
include_guard()
include(Linker/GNU)
block(SCOPE_FOR POLICIES)
cmake_policy(SET CMP0054 NEW)
macro(__linker_lld lang)
__linker_gnu(${lang})
if(CMAKE_${lang}_COMPILER_LINKER_FRONTEND_VARIANT STREQUAL "MSVC")
include(Linker/MSVC)
__linker_msvc(${lang})
else()
include(Linker/GNU)
__linker_gnu(${lang})
endif()
endmacro()
endblock()
+2 -2
View File
@@ -1,6 +1,6 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
include(Linker/GNU)
include(Linker/MOLD)
__linker_gnu(ASM)
__linker_mold(ASM)
+2 -2
View File
@@ -1,6 +1,6 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
include(Linker/GNU)
include(Linker/MOLD)
__linker_gnu(C)
__linker_mold(C)
+2 -2
View File
@@ -1,6 +1,6 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
include(Linker/GNU)
include(Linker/MOLD)
__linker_gnu(CUDA)
__linker_mold(CUDA)
+2 -2
View File
@@ -1,6 +1,6 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
include(Linker/GNU)
include(Linker/MOLD)
__linker_gnu(CXX)
__linker_mold(CXX)
+2 -2
View File
@@ -1,6 +1,6 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
include(Linker/GNU)
include(Linker/MOLD)
__linker_gnu(Fortran)
__linker_mold(Fortran)
+2 -2
View File
@@ -1,6 +1,6 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
include(Linker/GNU)
include(Linker/MOLD)
__linker_gnu(HIP)
__linker_mold(HIP)
+2 -2
View File
@@ -1,6 +1,6 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
include(Linker/GNU)
include(Linker/MOLD)
__linker_gnu(OBJC)
__linker_mold(OBJC)
+2 -2
View File
@@ -1,6 +1,6 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
include(Linker/GNU)
include(Linker/MOLD)
__linker_gnu(OBJCXX)
__linker_mold(OBJCXX)
+23
View File
@@ -0,0 +1,23 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
# This module is shared by multiple linkers; use include blocker.
include_guard()
block(SCOPE_FOR POLICIES)
cmake_policy(SET CMP0054 NEW)
macro(__linker_mold lang)
if(CMAKE_EFFECTIVE_SYSTEM_NAME STREQUAL "Apple")
include(Linker/AppleClang)
__linker_appleclang(${lang})
else()
include(Linker/GNU)
__linker_gnu(${lang})
endif()
endmacro()
endblock()
+6
View File
@@ -0,0 +1,6 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
include(Linker/MSVC)
__linker_msvc(ASM)
+6
View File
@@ -0,0 +1,6 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
include(Linker/MSVC)
__linker_msvc(C)
+6
View File
@@ -0,0 +1,6 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
include(Linker/MSVC)
__linker_msvc(CUDA)
+6
View File
@@ -0,0 +1,6 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
include(Linker/MSVC)
__linker_msvc(CXX)
+6
View File
@@ -0,0 +1,6 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
include(Linker/MSVC)
__linker_msvc(Fortran)
+6
View File
@@ -0,0 +1,6 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
include(Linker/MSVC)
__linker_msvc(HIP)
+12
View File
@@ -0,0 +1,12 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
# This module is shared by multiple linkers; use include blocker.
include_guard()
macro(__linker_msvc lang)
# Linker warning as error
set(CMAKE_${lang}_LINK_OPTIONS_WARNING_AS_ERROR "LINKER:/WX")
endmacro()
+2
View File
@@ -6,4 +6,6 @@
include_guard()
macro(__linker_solaris lang)
# Linker warning as error
set(CMAKE_${lang}_LINK_OPTIONS_WARNING_AS_ERROR "LINKER:-z,fatal-warnings")
endmacro()
+6
View File
@@ -3069,6 +3069,9 @@ void cmGlobalGenerator::AddGlobalTarget_EditCache(
if (this->GetCMakeInstance()->GetIgnoreCompileWarningAsError()) {
singleLine.push_back("--compile-no-warning-as-error");
}
if (this->GetCMakeInstance()->GetIgnoreLinkWarningAsError()) {
singleLine.push_back("--link-no-warning-as-error");
}
singleLine.push_back("-S$(CMAKE_SOURCE_DIR)");
singleLine.push_back("-B$(CMAKE_BINARY_DIR)");
gti.Message = "Running CMake cache editor...";
@@ -3105,6 +3108,9 @@ void cmGlobalGenerator::AddGlobalTarget_RebuildCache(
if (this->GetCMakeInstance()->GetIgnoreCompileWarningAsError()) {
singleLine.push_back("--compile-no-warning-as-error");
}
if (this->GetCMakeInstance()->GetIgnoreLinkWarningAsError()) {
singleLine.push_back("--link-no-warning-as-error");
}
singleLine.push_back("-S$(CMAKE_SOURCE_DIR)");
singleLine.push_back("-B$(CMAKE_BINARY_DIR)");
gti.CommandLines.push_back(std::move(singleLine));
+1
View File
@@ -1958,6 +1958,7 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
this->CMakeCmd(), " --regenerate-during-build",
cm->GetIgnoreCompileWarningAsError() ? " --compile-no-warning-as-error"
: "",
cm->GetIgnoreLinkWarningAsError() ? " --link-no-warning-as-error" : "",
" -S",
lg->ConvertToOutputFormat(lg->GetSourceDirectory(),
cmOutputConverter::SHELL),
@@ -328,6 +328,9 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
if (cm->GetIgnoreCompileWarningAsError()) {
commandLines[0].emplace_back("--compile-no-warning-as-error");
}
if (cm->GetIgnoreLinkWarningAsError()) {
commandLines[0].emplace_back("--link-no-warning-as-error");
}
// Add the rule. Note that we cannot use the CMakeLists.txt
// file as the main dependency because it would get
+10 -8
View File
@@ -777,14 +777,14 @@ void cmGlobalXCodeGenerator::CreateReRunCMakeFile(
}
makefileStream << ConvertToMakefilePath(checkCache) << ": $(TARGETS)\n";
makefileStream << '\t'
<< ConvertToMakefilePath(cmSystemTools::GetCMakeCommand())
<< " -S" << ConvertToMakefilePath(root->GetSourceDirectory())
<< " -B" << ConvertToMakefilePath(root->GetBinaryDirectory())
<< (cm->GetIgnoreCompileWarningAsError()
? " --compile-no-warning-as-error"
: "")
<< '\n';
makefileStream
<< '\t' << ConvertToMakefilePath(cmSystemTools::GetCMakeCommand()) << " -S"
<< ConvertToMakefilePath(root->GetSourceDirectory()) << " -B"
<< ConvertToMakefilePath(root->GetBinaryDirectory())
<< (cm->GetIgnoreCompileWarningAsError() ? " --compile-no-warning-as-error"
: "")
<< (cm->GetIgnoreLinkWarningAsError() ? " --link-no-warning-as-error" : "")
<< '\n';
}
static bool objectIdLessThan(const std::unique_ptr<cmXCodeObject>& l,
@@ -2551,6 +2551,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
} else {
this->CurrentLocalGenerator->AppendLinkerTypeFlags(extraLinkOptions, gtgt,
configName, llang);
this->CurrentLocalGenerator->AppendWarningAsErrorLinkerFlags(
extraLinkOptions, gtgt, llang);
cmValue targetLinkFlags = gtgt->GetProperty("LINK_FLAGS");
if (targetLinkFlags) {
+29
View File
@@ -1675,6 +1675,7 @@ void cmLocalGenerator::GetTargetFlags(
this->AppendLinkerTypeFlags(extraLinkFlags, target, config, linkLanguage);
this->AppendPositionIndependentLinkerFlags(extraLinkFlags, target, config,
linkLanguage);
this->AppendWarningAsErrorLinkerFlags(extraLinkFlags, target, linkLanguage);
this->AppendIPOLinkerFlags(extraLinkFlags, target, config, linkLanguage);
this->AppendDependencyInfoLinkerFlags(extraLinkFlags, target, config,
linkLanguage);
@@ -3609,6 +3610,34 @@ void cmLocalGenerator::AppendPositionIndependentLinkerFlags(
}
}
void cmLocalGenerator::AppendWarningAsErrorLinkerFlags(
std::string& flags, cmGeneratorTarget* target, const std::string& lang)
{
if (this->GetCMakeInstance()->GetIgnoreLinkWarningAsError()) {
return;
}
switch (target->GetType()) {
case cmStateEnums::EXECUTABLE:
case cmStateEnums::SHARED_LIBRARY:
case cmStateEnums::MODULE_LIBRARY:
break;
default:
return;
}
const auto wError = target->GetProperty("LINK_WARNING_AS_ERROR");
const auto wErrorOpts = this->Makefile->GetDefinition(
cmStrCat("CMAKE_", lang, "_LINK_OPTIONS_WARNING_AS_ERROR"));
if (wError.IsOn() && wErrorOpts.IsSet()) {
auto items = cmExpandListWithBacktrace(wErrorOpts, target->GetBacktrace());
target->ResolveLinkerWrapper(items, lang);
for (const auto& item : items) {
this->AppendFlagEscape(flags, item.Value);
}
}
}
void cmLocalGenerator::AppendDependencyInfoLinkerFlags(
std::string& flags, cmGeneratorTarget* target, const std::string& config,
const std::string& linkLanguage)
+3
View File
@@ -185,6 +185,9 @@ public:
cmGeneratorTarget* target,
const std::string& config,
const std::string& lang);
void AppendWarningAsErrorLinkerFlags(std::string& flags,
cmGeneratorTarget* target,
const std::string& lang);
void AppendDependencyInfoLinkerFlags(std::string& flags,
cmGeneratorTarget* target,
const std::string& config,
+2
View File
@@ -831,6 +831,7 @@ void cmLocalUnixMakefileGenerator3::WriteSpecialTargetsBottom(
"$(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) ",
cm->GetIgnoreCompileWarningAsError() ? "--compile-no-warning-as-error "
: "",
cm->GetIgnoreLinkWarningAsError() ? "--link-no-warning-as-error " : "",
"--check-build-system ",
this->ConvertToOutputFormat(cmakefileName, cmOutputConverter::SHELL),
" 0");
@@ -1834,6 +1835,7 @@ void cmLocalUnixMakefileGenerator3::WriteLocalAllRules(
"$(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) ",
cm->GetIgnoreCompileWarningAsError() ? "--compile-no-warning-as-error "
: "",
cm->GetIgnoreLinkWarningAsError() ? "--link-no-warning-as-error " : "",
"--check-build-system ",
this->ConvertToOutputFormat(cmakefileName, cmOutputConverter::SHELL),
" 1");
+6
View File
@@ -262,6 +262,9 @@ cmSourceFile* cmLocalVisualStudio7Generator::CreateVCProjBuildRule()
if (cm->GetIgnoreCompileWarningAsError()) {
commandLines[0].emplace_back("--compile-no-warning-as-error");
}
if (cm->GetIgnoreLinkWarningAsError()) {
commandLines[0].emplace_back("--link-no-warning-as-error");
}
std::string comment = cmStrCat("Building Custom Rule ", makefileIn);
auto cc = cm::make_unique<cmCustomCommand>();
cc->SetOutputs(stampName);
@@ -1007,6 +1010,9 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
// LINK_OPTIONS are escaped.
this->AppendCompileOptions(extraLinkOptions, opts);
this->AppendWarningAsErrorLinkerFlags(extraLinkOptions, target,
linkLanguage);
Options linkOptions(this, Options::Linker);
if (this->FortranProject) {
linkOptions.AddTable(cmLocalVisualStudio7GeneratorFortranLinkFlagTable);
+2
View File
@@ -158,6 +158,8 @@ void cmMakefileTargetGenerator::GetTargetLinkFlags(
flags, this->GeneratorTarget, this->GetConfigName(), linkLanguage);
this->LocalGenerator->AppendPositionIndependentLinkerFlags(
flags, this->GeneratorTarget, this->GetConfigName(), linkLanguage);
this->LocalGenerator->AppendWarningAsErrorLinkerFlags(
flags, this->GeneratorTarget, linkLanguage);
this->LocalGenerator->AppendDependencyInfoLinkerFlags(
flags, this->GeneratorTarget, this->GetConfigName(), linkLanguage);
}
+1
View File
@@ -466,6 +466,7 @@ TargetProperty const StaticTargetProperties[] = {
// Linking properties
{ "LINKER_TYPE"_s, IC::CanCompileSources },
{ "LINK_WARNING_AS_ERROR"_s, IC::CanCompileSources },
{ "ENABLE_EXPORTS"_s, IC::TargetWithSymbolExports },
{ "LINK_LIBRARIES_ONLY_TARGETS"_s, IC::NormalNonImportedTarget },
{ "LINK_LIBRARIES_STRATEGY"_s, IC::NormalNonImportedTarget },
@@ -4448,6 +4448,9 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions(
// LINK_OPTIONS are escaped.
this->LocalGenerator->AppendCompileOptions(flags, opts);
this->LocalGenerator->AppendWarningAsErrorLinkerFlags(
flags, this->GeneratorTarget, linkLanguage);
cmComputeLinkInformation* pcli =
this->GeneratorTarget->GetLinkInformation(config);
if (!pcli) {
+8
View File
@@ -1244,6 +1244,14 @@ void cmake::SetArgs(const std::vector<std::string>& args)
state->SetIgnoreCompileWarningAsError(true);
return true;
} },
CommandArgument{
"--link-no-warning-as-error", CommandArgument::Values::Zero,
[](std::string const&, cmake* state) -> bool {
std::cout << "Ignoring LINK_WARNING_AS_ERROR target property and "
"CMAKE_LINK_WARNING_AS_ERROR variable.\n";
state->SetIgnoreLinkWarningAsError(true);
return true;
} },
CommandArgument{ "--debugger", CommandArgument::Values::Zero,
[](std::string const&, cmake* state) -> bool {
#ifdef CMake_ENABLE_DEBUGGER
+9
View File
@@ -550,6 +550,14 @@ public:
{
this->IgnoreCompileWarningAsError = b;
}
bool GetIgnoreLinkWarningAsError() const
{
return this->IgnoreLinkWarningAsError;
}
void SetIgnoreLinkWarningAsError(bool b)
{
this->IgnoreLinkWarningAsError = b;
}
void MarkCliAsUsed(const std::string& variable);
@@ -760,6 +768,7 @@ private:
bool WarnUnusedCli = true;
bool CheckSystemVars = false;
bool IgnoreCompileWarningAsError = false;
bool IgnoreLinkWarningAsError = false;
std::map<std::string, bool> UsedCliVariables;
std::string CMakeEditCommand;
std::string CXXEnvironment;
+4 -1
View File
@@ -71,7 +71,7 @@ const cmDocumentationEntry cmDocumentationUsageNote = {
"Run 'cmake --help' for more information."
};
const cmDocumentationEntry cmDocumentationOptions[34] = {
const cmDocumentationEntry cmDocumentationOptions[35] = {
{ "--preset <preset>,--preset=<preset>", "Specify a configure preset." },
{ "--list-presets[=<type>]", "List available presets." },
{ "--workflow [<options>]", "Run a workflow preset." },
@@ -123,6 +123,9 @@ const cmDocumentationEntry cmDocumentationOptions[34] = {
{ "--compile-no-warning-as-error",
"Ignore COMPILE_WARNING_AS_ERROR property and "
"CMAKE_COMPILE_WARNING_AS_ERROR variable." },
{ "--link-no-warning-as-error",
"Ignore LINK_WARNING_AS_ERROR property and "
"CMAKE_LINK_WARNING_AS_ERROR variable." },
{ "--profiling-format=<fmt>",
"Output data for profiling CMake scripts. Supported formats: "
"google-trace" },
+6
View File
@@ -506,6 +506,12 @@ add_RunCMake_test(ToolchainFile)
add_RunCMake_test(find_dependency)
add_RunCMake_test(CompileDefinitions)
add_RunCMake_test(CompileWarningAsError -DCMake_TEST_CUDA=${CMake_TEST_CUDA})
if(CMAKE_C_COMPILER_ID MATCHES "AppleClang|MSVC"
OR (CMAKE_SYSTEM_NAME MATCHES "Linux|Windows" AND CMAKE_C_COMPILER_ID MATCHES "Clang|GNU")
OR (CMAKE_SYSTEM_NAME STREQUAL "SunOS" AND CMAKE_C_COMPILER_ID STREQUAL "SunPro")
OR (CMAKE_SYSTEM_NAME STREQUAL "AIX" AND CMAKE_C_COMPILER_ID STREQUAL "XL"))
add_RunCMake_test(LinkWarningAsError)
endif()
set_property(TEST RunCMake.CompileWarningAsError APPEND PROPERTY LABELS "CUDA")
add_RunCMake_test(CompileFeatures -DCMake_NO_C_STANDARD=${CMake_NO_C_STANDARD} -DCMake_NO_CXX_STANDARD=${CMake_NO_CXX_STANDARD})
add_RunCMake_test(Policy)
@@ -0,0 +1,3 @@
cmake_minimum_required(VERSION 3.31...3.32)
project(${RunCMake_TEST} NONE)
include(${RunCMake_TEST}.cmake)
@@ -0,0 +1,19 @@
include(RunCMake)
function(run_link_warn test)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build)
set(RunCMake_TEST_OUTPUT_MERGE 1)
run_cmake_with_options(${test} ${ARGN})
set(RunCMake_TEST_NO_CLEAN 1)
if(ARGN MATCHES "--link-no-warning-as-error")
# Cause the build system to re-run CMake to verify that this option is preserved.
run_cmake_command(${test}-Touch ${CMAKE_COMMAND} -E touch_nocreate CMakeCache.txt)
endif()
run_cmake_command(${test}-Build ${CMAKE_COMMAND} --build . --verbose)
endfunction()
run_link_warn(WarnErrorOn1)
run_link_warn(WarnErrorOn2)
run_link_warn(WarnErrorOff1)
run_link_warn(WarnErrorOff2)
run_link_warn(WarnErrorOnIgnore "--link-no-warning-as-error")
@@ -0,0 +1,20 @@
set(reference_file "${RunCMake_TEST_BINARY_DIR}/WARNING_AS_ERROR.txt")
if (NOT EXISTS "${reference_file}")
set (RunCMake_TEST_FAILED "${reference_file}: Reference file not found.")
return()
endif()
file(READ "${reference_file}" linker_WarnError)
if(NOT linker_WarnError STREQUAL "UNDEFINED")
if(WARNING_AS_ERROR)
# Add regex [^-] to avoid matching of MSVC compiler flag /WX-
if(NOT actual_stdout MATCHES "${linker_WarnError}[^-]")
set (RunCMake_TEST_FAILED "LINK_WARNING_AS_ERROR: flag is missing.")
endif()
else()
if(actual_stdout MATCHES "${linker_WarnError}[^-]")
set (RunCMake_TEST_FAILED "LINK_WARNING_AS_ERROR: flag unexpectedly present.")
endif()
endif()
endif()
@@ -0,0 +1,54 @@
if(NOT CMAKE_C_LINK_OPTIONS_WARNING_AS_ERROR)
set(linker_WarnError "UNDEFINED")
else()
set(cfg_dir)
get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(_isMultiConfig)
set(cfg_dir /Debug)
endif()
set(DUMP_EXE "${CMAKE_CURRENT_BINARY_DIR}${cfg_dir}/dump${CMAKE_EXECUTABLE_SUFFIX}")
add_executable(dump dump.c)
set_property(TARGET dump PROPERTY LINK_WARNING_AS_ERROR OFF)
# ensure no temp file nor response file will be used
set(CMAKE_C_USE_RESPONSE_FILE_FOR_LIBRARIES 0)
string(REPLACE "${CMAKE_START_TEMP_FILE}" "" CMAKE_C_LINK_EXECUTABLE "${CMAKE_C_LINK_EXECUTABLE}")
string(REPLACE "${CMAKE_END_TEMP_FILE}" "" CMAKE_C_LINK_EXECUTABLE "${CMAKE_C_LINK_EXECUTABLE}")
add_executable(main main.c)
if (NOT DEFINED CMAKE_LINK_WARNING_AS_ERROR)
set_property(TARGET main PROPERTY LINK_WARNING_AS_ERROR ${link_warning_as_error})
endif()
# use LAUNCH facility to dump linker command
set_property(TARGET main PROPERTY RULE_LAUNCH_LINK "\"${DUMP_EXE}\"")
add_dependencies(main dump)
# generate reference for WARNING_AS_ERROR flag
string(REPLACE "LINKER:" "" linker_WarnError "${CMAKE_C_LINK_OPTIONS_WARNING_AS_ERROR}")
if (CMAKE_C_LINKER_WRAPPER_FLAG)
set(linker_flag ${CMAKE_C_LINKER_WRAPPER_FLAG})
list(GET linker_flag -1 linker_space)
if (linker_space STREQUAL " ")
list(REMOVE_AT linker_flag -1)
else()
set(linker_space)
endif()
list(JOIN linker_flag " " linker_flag)
if (CMAKE_C_LINKER_WRAPPER_FLAG_SEP)
string(REPLACE "," "${CMAKE_C_LINKER_WRAPPER_FLAG_SEP}" linker_WarnError "${linker_WarnError}")
set(linker_WarnError "${linker_flag}${linker_space}${linker_WarnError}")
else()
set(linker_prefix "${linker_flag}${linker_space}")
string(REPLACE "," ";" linker_WarnError "${linker_WarnError}")
list(TRANSFORM linker_WarnError PREPEND "${linker_prefix}")
list(JOIN linker_WarnError " " linker_WarnError)
endif()
else()
string(REPLACE "," " " linker_WarnError "${linker_WarnError}")
endif()
endif()
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/WARNING_AS_ERROR.txt" "${linker_WarnError}")
@@ -0,0 +1,4 @@
set(WARNING_AS_ERROR OFF)
include("${CMAKE_CURRENT_LIST_DIR}/WarnError-validation.cmake")
@@ -0,0 +1,5 @@
enable_language(C)
set(link_warning_as_error OFF)
include(WarnError.cmake)
@@ -0,0 +1,4 @@
set(WARNING_AS_ERROR OFF)
include("${CMAKE_CURRENT_LIST_DIR}/WarnError-validation.cmake")
@@ -0,0 +1,5 @@
enable_language(C)
set(CMAKE_LINK_WARNING_AS_ERROR OFF)
include(WarnError.cmake)
@@ -0,0 +1,4 @@
set(WARNING_AS_ERROR ON)
include("${CMAKE_CURRENT_LIST_DIR}/WarnError-validation.cmake")
@@ -0,0 +1,5 @@
enable_language(C)
set(link_warning_as_error ON)
include(WarnError.cmake)
@@ -0,0 +1,4 @@
set(WARNING_AS_ERROR ON)
include("${CMAKE_CURRENT_LIST_DIR}/WarnError-validation.cmake")
@@ -0,0 +1,5 @@
enable_language(C)
set(CMAKE_LINK_WARNING_AS_ERROR ON)
include(WarnError.cmake)
@@ -0,0 +1,4 @@
set(WARNING_AS_ERROR OFF)
include("${CMAKE_CURRENT_LIST_DIR}/WarnError-validation.cmake")
@@ -0,0 +1,5 @@
enable_language(C)
set(link_warning_as_error ON)
include(WarnError.cmake)
+13
View File
@@ -0,0 +1,13 @@
#include "stdio.h"
int main(int argc, char* argv[])
{
int i;
for (i = 1; i < argc; i++)
printf("%s ", argv[i]);
printf("\n");
return 0;
}
+5
View File
@@ -0,0 +1,5 @@
int main(void)
{
return 0;
}