mirror of
https://github.com/Kitware/CMake.git
synced 2025-05-08 14:29:03 +08:00
ASM: Guard exclusion of MSVC C/CXX compiler with a policy
Since commit 6baf65ec46 (ASM: Do not consider MSVC C/CXX compiler for generic ASM, 2025-04-08) we no longer mistake `cl` for an assembler. However, some projects unconditionally enable ``ASM``, which worked on Windows only due to that bug. Restore compatibility with such projects by guarding the change behind a new policy ``CMP0194``. Fixes: #26907 Issue: #26617
This commit is contained in:
parent
3c992e336b
commit
14212494bb
@ -98,6 +98,7 @@ Policies Introduced by CMake 4.1
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
CMP0194: MSVC is not an assembler for language ASM. </policy/CMP0194>
|
||||
CMP0193: GNUInstallDirs caches CMAKE_INSTALL_* with leading 'usr/' for install prefix '/'. </policy/CMP0193>
|
||||
CMP0192: GNUInstallDirs uses absolute SYSCONFDIR, LOCALSTATEDIR, and RUNSTATEDIR in special prefixes. </policy/CMP0192>
|
||||
CMP0191: The FindCABLE module is removed. </policy/CMP0191>
|
||||
|
27
Help/policy/CMP0194.rst
Normal file
27
Help/policy/CMP0194.rst
Normal file
@ -0,0 +1,27 @@
|
||||
CMP0194
|
||||
-------
|
||||
|
||||
.. versionadded:: 4.1
|
||||
|
||||
MSVC is not an assembler for language ASM.
|
||||
|
||||
When enabling the ``ASM`` language, CMake considers C compiler drivers
|
||||
as assembler candidates. CMake 4.0 and below accidentally selected
|
||||
MSVC's ``cl`` compiler as the ``CMAKE_ASM_COMPILER``, allowing the ``ASM``
|
||||
language to be enabled on Windows even though ``cl`` does not support
|
||||
assembler sources. CMake 4.1 and above prefer to reject ``cl`` as an
|
||||
assembler candidate, but some existing projects unconditionally enable
|
||||
``ASM`` on Windows even though they add no assembler sources. This
|
||||
policy provides compatibility for such projects to allow them to
|
||||
configure as before.
|
||||
|
||||
The ``OLD`` behavior for this policy is to successfully enable ``ASM``
|
||||
even if ``cl`` is the only available candidate. The ``NEW`` behavior
|
||||
for this policy is to not consider ``cl`` as a candidate assembler
|
||||
for the ``ASM`` language.
|
||||
|
||||
.. |INTRODUCED_IN_CMAKE_VERSION| replace:: 4.1
|
||||
.. |WARNS_OR_DOES_NOT_WARN| replace:: warns
|
||||
.. include:: include/STANDARD_ADVICE.rst
|
||||
|
||||
.. include:: include/DEPRECATED.rst
|
5
Help/release/dev/asm-no-msvc.rst
Normal file
5
Help/release/dev/asm-no-msvc.rst
Normal file
@ -0,0 +1,5 @@
|
||||
asm-no-msvc
|
||||
-----------
|
||||
|
||||
* Enabling ``ASM`` no longer accidentally succeeds using ``MSVC``'s ``cl``
|
||||
C compiler as an assembler. See policy :policy:`CMP0194`.
|
@ -22,7 +22,7 @@ if(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID)
|
||||
include(Compiler/${CMAKE_ASM${ASM_DIALECT}_COMPILER_ID}-ASM${ASM_DIALECT} OPTIONAL RESULT_VARIABLE _INCLUDED_FILE)
|
||||
endif()
|
||||
if(NOT _INCLUDED_FILE)
|
||||
if("ASM${ASM_DIALECT}" STREQUAL "ASM")
|
||||
if("ASM${ASM_DIALECT}" STREQUAL "ASM" AND CMAKE_ASM${ASM_DIALECT}_COMPILER_ID)
|
||||
message(STATUS "Warning: Did not find file Compiler/${CMAKE_ASM${ASM_DIALECT}_COMPILER_ID}-ASM${ASM_DIALECT}")
|
||||
endif()
|
||||
include(Platform/${CMAKE_BASE_NAME} OPTIONAL)
|
||||
|
@ -6,6 +6,8 @@
|
||||
|
||||
include(${CMAKE_ROOT}/Modules/CMakeDetermineCompiler.cmake)
|
||||
|
||||
cmake_policy(GET CMP0194 _CMAKE_ASM_CMP0194)
|
||||
|
||||
if(NOT CMAKE_ASM${ASM_DIALECT}_COMPILER)
|
||||
# prefer the environment variable ASM
|
||||
if(NOT $ENV{ASM${ASM_DIALECT}} STREQUAL "")
|
||||
@ -21,19 +23,32 @@ if(NOT CMAKE_ASM${ASM_DIALECT}_COMPILER)
|
||||
# finally list compilers to try
|
||||
if("ASM${ASM_DIALECT}" STREQUAL "ASM") # the generic assembler support
|
||||
if(NOT CMAKE_ASM_COMPILER_INIT)
|
||||
if(CMAKE_C_COMPILER_LOADED AND NOT CMAKE_C_COMPILER_ID MATCHES "^(MSVC)$")
|
||||
if(_CMAKE_ASM_CMP0194 STREQUAL "NEW")
|
||||
set(_CMAKE_ASM_REGEX_MSVC "^(MSVC)$")
|
||||
set(_CMAKE_ASM_REGEX_CL "(^|/)[Cc][Ll](\\.|$)")
|
||||
set(_CMAKE_ASM_MAYBE_CL "")
|
||||
else()
|
||||
set(_CMAKE_ASM_REGEX_MSVC "CMP0194_OLD_MSVC_NOT_EXCLUDED")
|
||||
set(_CMAKE_ASM_REGEX_CL "CMP0194_OLD_MSVC_NOT_EXCLUDED")
|
||||
set(_CMAKE_ASM_MAYBE_CL "cl")
|
||||
endif()
|
||||
if(CMAKE_C_COMPILER_LOADED AND NOT CMAKE_C_COMPILER_ID MATCHES "${_CMAKE_ASM_REGEX_MSVC}")
|
||||
set(CMAKE_ASM_COMPILER_LIST ${CMAKE_C_COMPILER})
|
||||
elseif(NOT CMAKE_C_COMPILER_LOADED AND CMAKE_C_COMPILER AND NOT CMAKE_C_COMPILER MATCHES "(^|/)[Cc][Ll](\\.|$)")
|
||||
elseif(NOT CMAKE_C_COMPILER_LOADED AND CMAKE_C_COMPILER AND NOT CMAKE_C_COMPILER MATCHES "${_CMAKE_ASM_REGEX_CL}")
|
||||
set(CMAKE_ASM_COMPILER_LIST ${CMAKE_C_COMPILER})
|
||||
elseif(CMAKE_CXX_COMPILER_LOADED AND NOT CMAKE_CXX_COMPILER_ID MATCHES "^(MSVC)$")
|
||||
elseif(CMAKE_CXX_COMPILER_LOADED AND NOT CMAKE_CXX_COMPILER_ID MATCHES "${_CMAKE_ASM_REGEX_MSVC}")
|
||||
set(CMAKE_ASM_COMPILER_LIST ${CMAKE_CXX_COMPILER})
|
||||
elseif(NOT CMAKE_CXX_COMPILER_LOADED AND CMAKE_CXX_COMPILER AND NOT CMAKE_CXX_COMPILER MATCHES "(^|/)[Cc][Ll](\\.|$)")
|
||||
elseif(NOT CMAKE_CXX_COMPILER_LOADED AND CMAKE_CXX_COMPILER AND NOT CMAKE_CXX_COMPILER MATCHES "${_CMAKE_ASM_REGEX_CL}")
|
||||
set(CMAKE_ASM_COMPILER_LIST ${CMAKE_CXX_COMPILER})
|
||||
else()
|
||||
# List all default C and CXX compilers
|
||||
set(CMAKE_ASM_COMPILER_LIST
|
||||
${_CMAKE_TOOLCHAIN_PREFIX}cc ${_CMAKE_TOOLCHAIN_PREFIX}gcc xlc
|
||||
${_CMAKE_ASM_MAYBE_CL}
|
||||
CC ${_CMAKE_TOOLCHAIN_PREFIX}c++ ${_CMAKE_TOOLCHAIN_PREFIX}g++ xlC)
|
||||
unset(_CMAKE_ASM_MAYBE_CL)
|
||||
unset(_CMAKE_ASM_REGEX_CL)
|
||||
unset(_CMAKE_ASM_REGEX_MSVC)
|
||||
endif()
|
||||
endif()
|
||||
else() # some specific assembler "dialect"
|
||||
@ -100,7 +115,11 @@ if(NOT CMAKE_ASM${ASM_DIALECT}_COMPILER_ID)
|
||||
|
||||
list(APPEND CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDORS MSVC )
|
||||
set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_FLAGS_MSVC "-?")
|
||||
set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_REGEX_MSVC "Microsoft.*Macro Assembler")
|
||||
if(_CMAKE_ASM_CMP0194 STREQUAL "NEW")
|
||||
set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_REGEX_MSVC "Microsoft.*Macro Assembler")
|
||||
else()
|
||||
set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_REGEX_MSVC "Microsoft")
|
||||
endif()
|
||||
|
||||
list(APPEND CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDORS TI )
|
||||
set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_FLAGS_TI "-h")
|
||||
@ -200,6 +219,11 @@ else()
|
||||
message(STATUS "The ASM${ASM_DIALECT} compiler identification is unknown")
|
||||
endif()
|
||||
|
||||
if("ASM${ASM_DIALECT}" STREQUAL "ASM" AND CMAKE_ASM_COMPILER_ID STREQUAL "MSVC" AND _CMAKE_ASM_CMP0194 STREQUAL "")
|
||||
cmake_policy(GET_WARNING CMP0194 _CMAKE_ASM_CMP0194_WARNING)
|
||||
message(AUTHOR_WARNING "${_CMAKE_ASM_CMP0194_WARNING}")
|
||||
endif()
|
||||
|
||||
# If we have a gas/as cross compiler, they have usually some prefix, like
|
||||
# e.g. powerpc-linux-gas, arm-elf-gas or i586-mingw32msvc-gas , optionally
|
||||
# with a 3-component version number at the end
|
||||
|
@ -578,7 +578,9 @@ class cmMakefile;
|
||||
SELECT(POLICY, CMP0193, \
|
||||
"GNUInstallDirs caches CMAKE_INSTALL_* with leading 'usr/' for " \
|
||||
"install prefix '/'.", \
|
||||
4, 1, 0, WARN)
|
||||
4, 1, 0, WARN) \
|
||||
SELECT(POLICY, CMP194, "MSVC is not an assembler for language ASM.", 4, 1, \
|
||||
0, WARN)
|
||||
|
||||
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
|
||||
#define CM_FOR_EACH_POLICY_ID(POLICY) \
|
||||
|
1
Tests/RunCMake/CMP0194/CMP0194-NEW-result.txt
Normal file
1
Tests/RunCMake/CMP0194/CMP0194-NEW-result.txt
Normal file
@ -0,0 +1 @@
|
||||
1
|
9
Tests/RunCMake/CMP0194/CMP0194-NEW-stderr.txt
Normal file
9
Tests/RunCMake/CMP0194/CMP0194-NEW-stderr.txt
Normal file
@ -0,0 +1,9 @@
|
||||
^CMake Error at CMP0194-common\.cmake:[0-9]+ \(enable_language\):
|
||||
No CMAKE_ASM_COMPILER could be found\.
|
||||
(
|
||||
Tell CMake where to find the compiler by setting either the environment
|
||||
variable "ASM" or the CMake cache entry CMAKE_ASM_COMPILER to the full path
|
||||
to the compiler, or to the compiler name if it is in the PATH\.)?
|
||||
Call Stack \(most recent call first\):
|
||||
CMP0194-NEW\.cmake:[0-9]+ \(include\)
|
||||
CMakeLists\.txt:[0-9]+ \(include\)$
|
2
Tests/RunCMake/CMP0194/CMP0194-NEW-stdout.txt
Normal file
2
Tests/RunCMake/CMP0194/CMP0194-NEW-stdout.txt
Normal file
@ -0,0 +1,2 @@
|
||||
-- The ASM compiler identification is unknown
|
||||
-- Didn't find assembler
|
2
Tests/RunCMake/CMP0194/CMP0194-NEW.cmake
Normal file
2
Tests/RunCMake/CMP0194/CMP0194-NEW.cmake
Normal file
@ -0,0 +1,2 @@
|
||||
cmake_policy(SET CMP0194 NEW)
|
||||
include(CMP0194-common.cmake)
|
3
Tests/RunCMake/CMP0194/CMP0194-OLD-stdout.txt
Normal file
3
Tests/RunCMake/CMP0194/CMP0194-OLD-stdout.txt
Normal file
@ -0,0 +1,3 @@
|
||||
-- The ASM compiler identification is MSVC
|
||||
-- Found assembler: [^
|
||||
]*/cl\.exe
|
2
Tests/RunCMake/CMP0194/CMP0194-OLD.cmake
Normal file
2
Tests/RunCMake/CMP0194/CMP0194-OLD.cmake
Normal file
@ -0,0 +1,2 @@
|
||||
cmake_policy(SET CMP0194 OLD)
|
||||
include(CMP0194-common.cmake)
|
10
Tests/RunCMake/CMP0194/CMP0194-WARN-stderr.txt
Normal file
10
Tests/RunCMake/CMP0194/CMP0194-WARN-stderr.txt
Normal file
@ -0,0 +1,10 @@
|
||||
^CMake Warning \(dev\) at [^
|
||||
]*/Modules/CMakeDetermineASMCompiler.cmake:[0-9]+ \(message\):
|
||||
Policy CMP194 is not set: MSVC is not an assembler for language ASM\. Run
|
||||
"cmake --help-policy CMP194" for policy details\. Use the cmake_policy
|
||||
command to set the policy and suppress this warning\.
|
||||
Call Stack \(most recent call first\):
|
||||
CMP0194-common\.cmake:[0-9]+ \(enable_language\)
|
||||
CMP0194-WARN\.cmake:[0-9]+ \(include\)
|
||||
CMakeLists.txt:[0-9]+ \(include\)
|
||||
This warning is for project developers\. Use -Wno-dev to suppress it\.$
|
3
Tests/RunCMake/CMP0194/CMP0194-WARN-stdout.txt
Normal file
3
Tests/RunCMake/CMP0194/CMP0194-WARN-stdout.txt
Normal file
@ -0,0 +1,3 @@
|
||||
-- The ASM compiler identification is MSVC
|
||||
-- Found assembler: [^
|
||||
]*/cl\.exe
|
2
Tests/RunCMake/CMP0194/CMP0194-WARN.cmake
Normal file
2
Tests/RunCMake/CMP0194/CMP0194-WARN.cmake
Normal file
@ -0,0 +1,2 @@
|
||||
# CMP0194 is unset
|
||||
include(CMP0194-common.cmake)
|
3
Tests/RunCMake/CMP0194/CMP0194-common.cmake
Normal file
3
Tests/RunCMake/CMP0194/CMP0194-common.cmake
Normal file
@ -0,0 +1,3 @@
|
||||
enable_language(C)
|
||||
set(ENV{PATH} "")
|
||||
enable_language(ASM)
|
3
Tests/RunCMake/CMP0194/CMakeLists.txt
Normal file
3
Tests/RunCMake/CMP0194/CMakeLists.txt
Normal file
@ -0,0 +1,3 @@
|
||||
cmake_minimum_required(VERSION 4.0)
|
||||
project(${RunCMake_TEST} NONE)
|
||||
include(${RunCMake_TEST}.cmake)
|
10
Tests/RunCMake/CMP0194/RunCMakeTest.cmake
Normal file
10
Tests/RunCMake/CMP0194/RunCMakeTest.cmake
Normal file
@ -0,0 +1,10 @@
|
||||
include(RunCMake)
|
||||
|
||||
# The test cases empty the PATH before enabling ASM to avoid finding
|
||||
# another assembler in the caller's environment. However, old
|
||||
# versions of MSVC do not support running `cl` without the PATH set.
|
||||
if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 16)
|
||||
run_cmake(CMP0194-WARN)
|
||||
run_cmake(CMP0194-OLD)
|
||||
endif()
|
||||
run_cmake(CMP0194-NEW)
|
@ -181,6 +181,10 @@ add_RunCMake_test(CMP0171)
|
||||
add_RunCMake_test(CMP0173)
|
||||
add_RunCMake_test(CMP0187)
|
||||
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
|
||||
add_RunCMake_test(CMP0194 -DCMAKE_C_COMPILER_VERSION=${CMAKE_C_COMPILER_VERSION})
|
||||
endif()
|
||||
|
||||
# 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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user