mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-20 21:40:15 +08:00
@@ -8,6 +8,20 @@ If enabled, adds a flag to treat warnings on link as errors.
|
|||||||
If the :option:`cmake --link-no-warning-as-error` option is given
|
If the :option:`cmake --link-no-warning-as-error` option is given
|
||||||
on the :manual:`cmake(1)` command line, this property is ignored.
|
on the :manual:`cmake(1)` command line, this property is ignored.
|
||||||
|
|
||||||
|
This property takes a :ref:`semicolon-separated-list <CMake Language Lists>` of
|
||||||
|
the following values:
|
||||||
|
|
||||||
|
* ``LINKER``: treat the linker warnings as errors.
|
||||||
|
* ``DRIVER``: treat the compiler warnings as errors when used to drive the link
|
||||||
|
step. See the :prop_tgt:`COMPILE_WARNING_AS_ERROR` target property for more
|
||||||
|
information.
|
||||||
|
|
||||||
|
Moreover, for consistency with the :prop_tgt:`COMPILE_WARNING_AS_ERROR` target
|
||||||
|
property, a boolean value can be specified:
|
||||||
|
|
||||||
|
* ``True`` value: this is equivalent to ``LINKER`` and ``DRIVER`` values.
|
||||||
|
* ``False`` value: deactivate this feature for the target.
|
||||||
|
|
||||||
This property is not implemented for all linkers. It is silently 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
|
if there is no implementation for the linker being used. The currently
|
||||||
implemented :variable:`compiler linker IDs <CMAKE_<LANG>_COMPILER_LINKER_ID>`
|
implemented :variable:`compiler linker IDs <CMAKE_<LANG>_COMPILER_LINKER_ID>`
|
||||||
|
@@ -3608,14 +3608,54 @@ void cmLocalGenerator::AppendWarningAsErrorLinkerFlags(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const auto wError = target->GetProperty("LINK_WARNING_AS_ERROR");
|
const auto wError = target->GetProperty("LINK_WARNING_AS_ERROR");
|
||||||
const auto wErrorOpts = this->Makefile->GetDefinition(
|
if (wError.IsOff()) {
|
||||||
cmStrCat("CMAKE_", lang, "_LINK_OPTIONS_WARNING_AS_ERROR"));
|
return;
|
||||||
if (wError.IsOn() && wErrorOpts.IsSet()) {
|
}
|
||||||
auto items = cmExpandListWithBacktrace(wErrorOpts, target->GetBacktrace());
|
cmList wErrorOptions;
|
||||||
target->ResolveLinkerWrapper(items, lang);
|
if (wError.IsOn()) {
|
||||||
for (const auto& item : items) {
|
wErrorOptions = { "DRIVER", "LINKER" };
|
||||||
this->AppendFlagEscape(flags, item.Value);
|
} else {
|
||||||
|
wErrorOptions = wError;
|
||||||
|
std::sort(wErrorOptions.begin(), wErrorOptions.end());
|
||||||
|
wErrorOptions.erase(
|
||||||
|
std::unique(wErrorOptions.begin(), wErrorOptions.end()),
|
||||||
|
wErrorOptions.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto linkModeIsDriver =
|
||||||
|
this->Makefile->GetDefinition(cmStrCat("CMAKE_", lang, "_LINK_MODE")) ==
|
||||||
|
"DRIVER"_s;
|
||||||
|
std::string errorMessage;
|
||||||
|
for (const auto& option : wErrorOptions) {
|
||||||
|
if (option != "DRIVER"_s && option != "LINKER"_s) {
|
||||||
|
errorMessage += cmStrCat(" ", option, '\n');
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (option == "DRIVER"_s && !linkModeIsDriver) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto wErrorOpts = this->Makefile->GetDefinition(cmStrCat(
|
||||||
|
"CMAKE_", lang, '_', (option == "DRIVER"_s ? "COMPILE" : "LINK"),
|
||||||
|
"_OPTIONS_WARNING_AS_ERROR"));
|
||||||
|
if (wErrorOpts.IsSet()) {
|
||||||
|
auto items =
|
||||||
|
cmExpandListWithBacktrace(wErrorOpts, target->GetBacktrace());
|
||||||
|
if (option == "LINKER"_s) {
|
||||||
|
target->ResolveLinkerWrapper(items, lang);
|
||||||
|
}
|
||||||
|
for (const auto& item : items) {
|
||||||
|
this->AppendFlagEscape(flags, item.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!errorMessage.empty()) {
|
||||||
|
this->Makefile->GetCMakeInstance()->IssueMessage(
|
||||||
|
MessageType::FATAL_ERROR,
|
||||||
|
cmStrCat(
|
||||||
|
"Erroneous value(s) for 'LINK_WARNING_AS_ERROR' property of target '",
|
||||||
|
target->GetName(), "':\n", errorMessage));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -508,10 +508,11 @@ add_RunCMake_test(ToolchainFile)
|
|||||||
add_RunCMake_test(find_dependency)
|
add_RunCMake_test(find_dependency)
|
||||||
add_RunCMake_test(CompileDefinitions)
|
add_RunCMake_test(CompileDefinitions)
|
||||||
add_RunCMake_test(CompileWarningAsError -DCMake_TEST_CUDA=${CMake_TEST_CUDA})
|
add_RunCMake_test(CompileWarningAsError -DCMake_TEST_CUDA=${CMake_TEST_CUDA})
|
||||||
if(CMAKE_C_COMPILER_ID MATCHES "AppleClang|MSVC"
|
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 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 "SunOS" AND CMAKE_C_COMPILER_ID STREQUAL "SunPro")
|
||||||
OR (CMAKE_SYSTEM_NAME STREQUAL "AIX" AND CMAKE_C_COMPILER_ID STREQUAL "XL"))
|
OR (CMAKE_SYSTEM_NAME STREQUAL "AIX" AND CMAKE_C_COMPILER_ID STREQUAL "XL"))
|
||||||
|
AND CMAKE_C_COMPILER_LINKER_ID)
|
||||||
add_RunCMake_test(LinkWarningAsError)
|
add_RunCMake_test(LinkWarningAsError)
|
||||||
endif()
|
endif()
|
||||||
set_property(TEST RunCMake.CompileWarningAsError APPEND PROPERTY LABELS "CUDA")
|
set_property(TEST RunCMake.CompileWarningAsError APPEND PROPERTY LABELS "CUDA")
|
||||||
|
1
Tests/RunCMake/LinkWarningAsError/BadValue-result.txt
Normal file
1
Tests/RunCMake/LinkWarningAsError/BadValue-result.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
1
|
4
Tests/RunCMake/LinkWarningAsError/BadValue-stderr.txt
Normal file
4
Tests/RunCMake/LinkWarningAsError/BadValue-stderr.txt
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
CMake Error:
|
||||||
|
Erroneous value\(s\) for 'LINK_WARNING_AS_ERROR' property of target 'main':
|
||||||
|
|
||||||
|
FOO
|
4
Tests/RunCMake/LinkWarningAsError/BadValue.cmake
Normal file
4
Tests/RunCMake/LinkWarningAsError/BadValue.cmake
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
enable_language(C)
|
||||||
|
|
||||||
|
add_executable(main main.c)
|
||||||
|
set_property(TARGET main PROPERTY LINK_WARNING_AS_ERROR FOO)
|
@@ -1,5 +1,7 @@
|
|||||||
include(RunCMake)
|
include(RunCMake)
|
||||||
|
|
||||||
|
run_cmake(BadValue)
|
||||||
|
|
||||||
function(run_link_warn test)
|
function(run_link_warn test)
|
||||||
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build)
|
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build)
|
||||||
set(RunCMake_TEST_OUTPUT_MERGE 1)
|
set(RunCMake_TEST_OUTPUT_MERGE 1)
|
||||||
@@ -14,6 +16,8 @@ endfunction()
|
|||||||
|
|
||||||
run_link_warn(WarnErrorOn1)
|
run_link_warn(WarnErrorOn1)
|
||||||
run_link_warn(WarnErrorOn2)
|
run_link_warn(WarnErrorOn2)
|
||||||
|
run_link_warn(WarnErrorOn3)
|
||||||
|
run_link_warn(WarnErrorOn4)
|
||||||
run_link_warn(WarnErrorOff1)
|
run_link_warn(WarnErrorOff1)
|
||||||
run_link_warn(WarnErrorOff2)
|
run_link_warn(WarnErrorOff2)
|
||||||
run_link_warn(WarnErrorOnIgnore "--link-no-warning-as-error")
|
run_link_warn(WarnErrorOnIgnore "--link-no-warning-as-error")
|
||||||
|
@@ -4,17 +4,16 @@ if (NOT EXISTS "${reference_file}")
|
|||||||
set (RunCMake_TEST_FAILED "${reference_file}: Reference file not found.")
|
set (RunCMake_TEST_FAILED "${reference_file}: Reference file not found.")
|
||||||
return()
|
return()
|
||||||
endif()
|
endif()
|
||||||
file(READ "${reference_file}" linker_WarnError)
|
file(READ "${reference_file}" WarnErrorFlags)
|
||||||
|
|
||||||
if(NOT linker_WarnError STREQUAL "UNDEFINED")
|
if(NOT WarnErrorFlags STREQUAL "UNDEFINED")
|
||||||
if(WARNING_AS_ERROR)
|
if(WARNING_AS_ERROR)
|
||||||
# Add regex [^-] to avoid matching of MSVC compiler flag /WX-
|
if(NOT actual_stdout MATCHES "${WarnErrorFlags}")
|
||||||
if(NOT actual_stdout MATCHES "${linker_WarnError}[^-]")
|
|
||||||
set (RunCMake_TEST_FAILED "LINK_WARNING_AS_ERROR: flag is missing.")
|
set (RunCMake_TEST_FAILED "LINK_WARNING_AS_ERROR: flag is missing.")
|
||||||
endif()
|
endif()
|
||||||
else()
|
else()
|
||||||
if(actual_stdout MATCHES "${linker_WarnError}[^-]")
|
if(actual_stdout MATCHES "${WarnErrorFlags}")
|
||||||
set (RunCMake_TEST_FAILED "LINK_WARNING_AS_ERROR: flag unexpectedly present.")
|
set (RunCMake_TEST_FAILED "LINK_WARNING_AS_ERROR: flag unexpectedly present: '${WarnErrorFlags}'")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
@@ -1,6 +1,17 @@
|
|||||||
|
|
||||||
if(NOT CMAKE_C_LINK_OPTIONS_WARNING_AS_ERROR)
|
set(linkWarning "${link_warning_as_error}")
|
||||||
set(linker_WarnError "UNDEFINED")
|
if (DEFINED CMAKE_LINK_WARNING_AS_ERROR)
|
||||||
|
set(linkWarning "${CMAKE_LINK_WARNING_AS_ERROR}")
|
||||||
|
endif()
|
||||||
|
if (linkWarning STREQUAL "ON")
|
||||||
|
set (linkWarning DRIVER LINKER)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if((linkWarning STREQUAL "DRIVER;LINKER" AND NOT CMAKE_C_COMPILE_OPTIONS_WARNING_AS_ERROR
|
||||||
|
AND NOT CMAKE_C_LINK_OPTIONS_WARNING_AS_ERROR)
|
||||||
|
OR (linkWarning STREQUAL "DRIVER" AND NOT CMAKE_C_COMPILE_OPTIONS_WARNING_AS_ERROR)
|
||||||
|
OR (linkWarning STREQUAL "LINKER" AND NOT CMAKE_C_LINK_OPTIONS_WARNING_AS_ERROR))
|
||||||
|
set(WarnErrorFlags "UNDEFINED")
|
||||||
else()
|
else()
|
||||||
set(cfg_dir)
|
set(cfg_dir)
|
||||||
get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||||
@@ -26,8 +37,15 @@ else()
|
|||||||
|
|
||||||
add_dependencies(main dump)
|
add_dependencies(main dump)
|
||||||
|
|
||||||
|
|
||||||
# generate reference for WARNING_AS_ERROR flag
|
# generate reference for WARNING_AS_ERROR flag
|
||||||
|
unset(compiler_WarnError)
|
||||||
|
unset(linker_WarnError)
|
||||||
|
unset(WarnErrorFlags)
|
||||||
|
## DRIVER
|
||||||
|
if (CMAKE_C_LINK_MODE STREQUAL "DRIVER")
|
||||||
|
list(JOIN CMAKE_C_COMPILE_OPTIONS_WARNING_AS_ERROR " " compiler_WarnError)
|
||||||
|
endif()
|
||||||
|
## LINKER
|
||||||
string(REPLACE "LINKER:" "" linker_WarnError "${CMAKE_C_LINK_OPTIONS_WARNING_AS_ERROR}")
|
string(REPLACE "LINKER:" "" linker_WarnError "${CMAKE_C_LINK_OPTIONS_WARNING_AS_ERROR}")
|
||||||
if (CMAKE_C_LINKER_WRAPPER_FLAG)
|
if (CMAKE_C_LINKER_WRAPPER_FLAG)
|
||||||
set(linker_flag ${CMAKE_C_LINKER_WRAPPER_FLAG})
|
set(linker_flag ${CMAKE_C_LINKER_WRAPPER_FLAG})
|
||||||
@@ -50,5 +68,36 @@ else()
|
|||||||
else()
|
else()
|
||||||
string(REPLACE "," " " linker_WarnError "${linker_WarnError}")
|
string(REPLACE "," " " linker_WarnError "${linker_WarnError}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Add regex [^-] to avoid matching of MSVC compiler flag -WX-
|
||||||
|
if(linkWarning STREQUAL "DRIVER;LINKER")
|
||||||
|
set(WarnErrorFlags "${compiler_WarnError}")
|
||||||
|
if (WarnErrorFlags)
|
||||||
|
string(APPEND WarnErrorFlags " ${linker_WarnError}[^-]")
|
||||||
|
else()
|
||||||
|
set(WarnErrorFlags "${linker_WarnError}[^-]")
|
||||||
|
endif()
|
||||||
|
elseif(linkWarning STREQUAL "DRIVER")
|
||||||
|
set(WarnErrorFlags "${compiler_WarnError}[^-]")
|
||||||
|
elseif(linkWarning STREQUAL "LINKER")
|
||||||
|
set(WarnErrorFlags "${linker_WarnError}[^-]")
|
||||||
|
else()
|
||||||
|
# OFF value
|
||||||
|
if(compiler_WarnError AND linker_WarnError)
|
||||||
|
set(WarnErrorFlags "(${compiler_WarnError}[^-]|${linker_WarnError}[^-])+")
|
||||||
|
elseif(compiler_WarnError)
|
||||||
|
set(WarnErrorFlags "${compiler_WarnError}[^-]")
|
||||||
|
elseif(linker_WarnError)
|
||||||
|
set(WarnErrorFlags "${linker_WarnError}[^-]")
|
||||||
|
endif()
|
||||||
|
if(NOT WarnErrorFlags)
|
||||||
|
set(WarnErrorFlags "UNDEFINED")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/WARNING_AS_ERROR.txt" "${linker_WarnError}")
|
if(CMAKE_GENERATOR MATCHES "Visual Studio")
|
||||||
|
# replace '-' with '/' for options
|
||||||
|
string(REGEX REPLACE "-([A-Z]+)" "[-/]\\1" WarnErrorFlags "${WarnErrorFlags}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/WARNING_AS_ERROR.txt" "${WarnErrorFlags}")
|
||||||
|
@@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
set(WARNING_AS_ERROR ON)
|
||||||
|
|
||||||
|
include("${CMAKE_CURRENT_LIST_DIR}/WarnError-validation.cmake")
|
5
Tests/RunCMake/LinkWarningAsError/WarnErrorOn3.cmake
Normal file
5
Tests/RunCMake/LinkWarningAsError/WarnErrorOn3.cmake
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
enable_language(C)
|
||||||
|
|
||||||
|
set(link_warning_as_error DRIVER)
|
||||||
|
|
||||||
|
include(WarnError.cmake)
|
@@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
set(WARNING_AS_ERROR ON)
|
||||||
|
|
||||||
|
include("${CMAKE_CURRENT_LIST_DIR}/WarnError-validation.cmake")
|
5
Tests/RunCMake/LinkWarningAsError/WarnErrorOn4.cmake
Normal file
5
Tests/RunCMake/LinkWarningAsError/WarnErrorOn4.cmake
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
enable_language(C)
|
||||||
|
|
||||||
|
set(link_warning_as_error LINKER)
|
||||||
|
|
||||||
|
include(WarnError.cmake)
|
Reference in New Issue
Block a user