diff options
21 files changed, 406 insertions, 77 deletions
diff --git a/Help/prop_sf/SKIP_LINTING.rst b/Help/prop_sf/SKIP_LINTING.rst index 19592a8..0e0a616 100644 --- a/Help/prop_sf/SKIP_LINTING.rst +++ b/Help/prop_sf/SKIP_LINTING.rst @@ -7,8 +7,9 @@ This property allows you to exclude a specific source file from the linting process. The linting process involves running tools such as :prop_tgt:`<LANG>_CPPLINT`, :prop_tgt:`<LANG>_CLANG_TIDY`, :prop_tgt:`<LANG>_CPPCHECK`, and :prop_tgt:`<LANG>_INCLUDE_WHAT_YOU_USE` -on the source files. By setting ``SKIP_LINTING`` on a source file, -the mentioned linting tools will not be executed for that +on the source files, as well as compiling header files as part of +:prop_tgt:`VERIFY_INTERFACE_HEADER_SETS`. By setting ``SKIP_LINTING`` on a +source file, the mentioned linting tools will not be executed for that particular file. Example diff --git a/Help/prop_tgt/VERIFY_INTERFACE_HEADER_SETS.rst b/Help/prop_tgt/VERIFY_INTERFACE_HEADER_SETS.rst index dd415c8..bdd7792 100644 --- a/Help/prop_tgt/VERIFY_INTERFACE_HEADER_SETS.rst +++ b/Help/prop_tgt/VERIFY_INTERFACE_HEADER_SETS.rst @@ -26,6 +26,9 @@ Otherwise, if C++ is enabled globally, the header is compiled as C++. Otherwise, if C is enabled globally, the header is compiled as C. Otherwise, the header file is not compiled. +If the header's :prop_sf:`SKIP_LINTING` property is set to true, the file is +not compiled. + If any verification targets are created, a top-level target called ``all_verify_interface_header_sets`` is created which depends on all verification targets. diff --git a/Modules/CMakeDetermineASMCompiler.cmake b/Modules/CMakeDetermineASMCompiler.cmake index 5ec2972..8ec6c66 100644 --- a/Modules/CMakeDetermineASMCompiler.cmake +++ b/Modules/CMakeDetermineASMCompiler.cmake @@ -58,14 +58,14 @@ if(NOT CMAKE_ASM${ASM_DIALECT}_COMPILER_ID) set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_FLAGS_GNU "--version") set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_REGEX_GNU "(GNU assembler)|(GCC)|(Free Software Foundation)") + list(APPEND CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDORS AppleClang ) + set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_FLAGS_AppleClang "--version") + set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_REGEX_AppleClang "(Apple (clang|LLVM) version)") + list(APPEND CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDORS Clang ) set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_FLAGS_Clang "--version") set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_REGEX_Clang "(clang version)") - list(APPEND CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDORS AppleClang ) - set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_FLAGS_AppleClang "--version") - set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_REGEX_AppleClang "(Apple LLVM version)") - list(APPEND CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDORS ARMClang ) set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_FLAGS_ARMClang "--version") set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_REGEX_ARMClang "armclang") diff --git a/Modules/FindPython.cmake b/Modules/FindPython.cmake index e6f44e0..19b6c2a 100644 --- a/Modules/FindPython.cmake +++ b/Modules/FindPython.cmake @@ -125,38 +125,28 @@ This module will set the following variables in your project ``Python_STDLIB`` Standard platform independent installation directory. - Information returned by - ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=True)`` - or else ``sysconfig.get_path('stdlib')``. + Information returned by ``sysconfig.get_path('stdlib')``. ``Python_STDARCH`` Standard platform dependent installation directory. - Information returned by - ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=True)`` - or else ``sysconfig.get_path('platstdlib')``. + Information returned by ``sysconfig.get_path('platstdlib')``. ``Python_SITELIB`` Third-party platform independent installation directory. - Information returned by - ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=False)`` - or else ``sysconfig.get_path('purelib')``. + Information returned by ``sysconfig.get_path('purelib')``. ``Python_SITEARCH`` Third-party platform dependent installation directory. - Information returned by - ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=False)`` - or else ``sysconfig.get_path('platlib')``. + Information returned by ``sysconfig.get_path('platlib')``. ``Python_SOABI`` .. versionadded:: 3.17 Extension suffix for modules. - Information computed from ``distutils.sysconfig.get_config_var('EXT_SUFFIX')`` - or ``distutils.sysconfig.get_config_var('SOABI')`` or - ``python3-config --extension-suffix``. If package ``distutils.sysconfig`` is - not available, ``sysconfig.get_config_var('EXT_SUFFIX')`` or - ``sysconfig.get_config_var('SOABI')`` are used. + Information computed from ``sysconfig.get_config_var('EXT_SUFFIX')`` or + ``sysconfig.get_config_var('SOABI')`` or + ``python3-config --extension-suffix``. ``Python_SOSABI`` .. versionadded:: 3.26 diff --git a/Modules/FindPython/Support.cmake b/Modules/FindPython/Support.cmake index 7f35e07..76d4a9b 100644 --- a/Modules/FindPython/Support.cmake +++ b/Modules/FindPython/Support.cmake @@ -500,7 +500,7 @@ function (_PYTHON_GET_CONFIG_VAR _PYTHON_PGCV_VALUE NAME) if (_${_PYTHON_PREFIX}_EXECUTABLE AND NOT CMAKE_CROSSCOMPILING) if (NAME STREQUAL "PREFIX") - execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys\ntry:\n from distutils import sysconfig\n sys.stdout.write(';'.join([sysconfig.PREFIX,sysconfig.EXEC_PREFIX,sysconfig.BASE_EXEC_PREFIX]))\nexcept Exception:\n import sysconfig\n sys.stdout.write(';'.join([sysconfig.get_config_var('base') or '', sysconfig.get_config_var('installed_base') or '']))" + execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys\ntry:\n import sysconfig\n sys.stdout.write(';'.join([sysconfig.get_config_var('base') or '', sysconfig.get_config_var('installed_base') or '']))\nexcept Exception:\n from distutils import sysconfig\n sys.stdout.write(';'.join([sysconfig.PREFIX,sysconfig.EXEC_PREFIX,sysconfig.BASE_EXEC_PREFIX]))" RESULT_VARIABLE _result OUTPUT_VARIABLE _values ERROR_QUIET @@ -517,7 +517,7 @@ function (_PYTHON_GET_CONFIG_VAR _PYTHON_PGCV_VALUE NAME) set (_scheme "posix_prefix") endif() execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys\ntry:\n from distutils import sysconfig\n sys.stdout.write(';'.join([sysconfig.get_python_inc(plat_specific=True),sysconfig.get_python_inc(plat_specific=False)]))\nexcept Exception:\n import sysconfig\n sys.stdout.write(';'.join([sysconfig.get_path('platinclude'),sysconfig.get_path('platinclude','${_scheme}'),sysconfig.get_path('include'),sysconfig.get_path('include','${_scheme}')]))" + "import sys\ntry:\n import sysconfig\n sys.stdout.write(';'.join([sysconfig.get_path('platinclude'),sysconfig.get_path('platinclude','${_scheme}'),sysconfig.get_path('include'),sysconfig.get_path('include','${_scheme}')]))\nexcept Exception:\n from distutils import sysconfig\n sys.stdout.write(';'.join([sysconfig.get_python_inc(plat_specific=True),sysconfig.get_python_inc(plat_specific=False)]))" RESULT_VARIABLE _result OUTPUT_VARIABLE _values ERROR_QUIET @@ -530,7 +530,7 @@ function (_PYTHON_GET_CONFIG_VAR _PYTHON_PGCV_VALUE NAME) elseif (NAME STREQUAL "SOABI") # first step: compute SOABI form EXT_SUFFIX config variable execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys\ntry:\n from distutils import sysconfig\n sys.stdout.write(sysconfig.get_config_var('EXT_SUFFIX') or '')\nexcept Exception:\n import sysconfig;sys.stdout.write(sysconfig.get_config_var('EXT_SUFFIX') or '')" + "import sys\ntry:\n import sysconfig\n sys.stdout.write(sysconfig.get_config_var('EXT_SUFFIX') or '')\nexcept Exception:\n from distutils import sysconfig;sys.stdout.write(sysconfig.get_config_var('EXT_SUFFIX') or '')" RESULT_VARIABLE _result OUTPUT_VARIABLE _values ERROR_QUIET @@ -551,7 +551,7 @@ function (_PYTHON_GET_CONFIG_VAR _PYTHON_PGCV_VALUE NAME) # second step: use SOABI or SO config variables as fallback if (NOT _values) execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys\ntry:\n from distutils import sysconfig\n sys.stdout.write(';'.join([sysconfig.get_config_var('SOABI') or '',sysconfig.get_config_var('SO') or '']))\nexcept Exception:\n import sysconfig;sys.stdout.write(';'.join([sysconfig.get_config_var('SOABI') or '',sysconfig.get_config_var('SO') or '']))" + "import sys\ntry:\n import sysconfig\n sys.stdout.write(';'.join([sysconfig.get_config_var('SOABI') or '',sysconfig.get_config_var('SO') or '']))\nexcept Exception:\n from distutils import sysconfig;sys.stdout.write(';'.join([sysconfig.get_config_var('SOABI') or '',sysconfig.get_config_var('SO') or '']))" RESULT_VARIABLE _result OUTPUT_VARIABLE _soabi ERROR_QUIET @@ -592,7 +592,7 @@ function (_PYTHON_GET_CONFIG_VAR _PYTHON_PGCV_VALUE NAME) set (config_flag "LIBPL") endif() execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys\ntry:\n from distutils import sysconfig\n sys.stdout.write(sysconfig.get_config_var('${config_flag}'))\nexcept Exception:\n import sysconfig\n sys.stdout.write(sysconfig.get_config_var('${config_flag}'))" + "import sys\ntry:\n import sysconfig\n sys.stdout.write(sysconfig.get_config_var('${config_flag}'))\nexcept Exception:\n from distutils import sysconfig\n sys.stdout.write(sysconfig.get_config_var('${config_flag}'))" RESULT_VARIABLE _result OUTPUT_VARIABLE _values ERROR_QUIET @@ -2197,7 +2197,7 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) # retrieve various package installation directories execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys\ntry:\n from distutils import sysconfig\n sys.stdout.write(';'.join([sysconfig.get_python_lib(plat_specific=False,standard_lib=True),sysconfig.get_python_lib(plat_specific=True,standard_lib=True),sysconfig.get_python_lib(plat_specific=False,standard_lib=False),sysconfig.get_python_lib(plat_specific=True,standard_lib=False)]))\nexcept Exception:\n import sysconfig\n sys.stdout.write(';'.join([sysconfig.get_path('stdlib'),sysconfig.get_path('platstdlib'),sysconfig.get_path('purelib'),sysconfig.get_path('platlib')]))" + "import sys\ntry:\n import sysconfig\n sys.stdout.write(';'.join([sysconfig.get_path('stdlib'),sysconfig.get_path('platstdlib'),sysconfig.get_path('purelib'),sysconfig.get_path('platlib')]))\nexcept Exception:\n from distutils import sysconfig\n sys.stdout.write(';'.join([sysconfig.get_python_lib(plat_specific=False,standard_lib=True),sysconfig.get_python_lib(plat_specific=True,standard_lib=True),sysconfig.get_python_lib(plat_specific=False,standard_lib=False),sysconfig.get_python_lib(plat_specific=True,standard_lib=False)]))" RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT OUTPUT_VARIABLE _${_PYTHON_PREFIX}_LIBPATHS ERROR_QUIET) diff --git a/Modules/FindPython2.cmake b/Modules/FindPython2.cmake index 0575ea5..4c7ab5c 100644 --- a/Modules/FindPython2.cmake +++ b/Modules/FindPython2.cmake @@ -112,27 +112,23 @@ This module will set the following variables in your project ``Python2_STDLIB`` Standard platform independent installation directory. - Information returned by - ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=True)`` - or else ``sysconfig.get_path('stdlib')``. + Information returned by ``sysconfig.get_path('stdlib')`` or else + ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=True)``. ``Python2_STDARCH`` Standard platform dependent installation directory. - Information returned by - ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=True)`` - or else ``sysconfig.get_path('platstdlib')``. + Information returned by ``sysconfig.get_path('platstdlib')`` or else + ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=True)``. ``Python2_SITELIB`` Third-party platform independent installation directory. - Information returned by - ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=False)`` - or else ``sysconfig.get_path('purelib')``. + Information returned by ``sysconfig.get_path('purelib')`` or else + ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=False)``. ``Python2_SITEARCH`` Third-party platform dependent installation directory. - Information returned by - ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=False)`` - or else ``sysconfig.get_path('platlib')``. + Information returned by ``sysconfig.get_path('platlib')`` or else + ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=False)``. ``Python2_Compiler_FOUND`` System has the Python 2 compiler. ``Python2_COMPILER`` diff --git a/Modules/FindPython3.cmake b/Modules/FindPython3.cmake index 18929b2..901565b 100644 --- a/Modules/FindPython3.cmake +++ b/Modules/FindPython3.cmake @@ -126,38 +126,28 @@ This module will set the following variables in your project ``Python3_STDLIB`` Standard platform independent installation directory. - Information returned by - ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=True)`` - or else ``sysconfig.get_path('stdlib')``. + Information returned by ``sysconfig.get_path('stdlib')``. ``Python3_STDARCH`` Standard platform dependent installation directory. - Information returned by - ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=True)`` - or else ``sysconfig.get_path('platstdlib')``. + Information returned by ``sysconfig.get_path('platstdlib')``. ``Python3_SITELIB`` Third-party platform independent installation directory. - Information returned by - ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=False)`` - or else ``sysconfig.get_path('purelib')``. + Information returned by ``sysconfig.get_path('purelib')``. ``Python3_SITEARCH`` Third-party platform dependent installation directory. - Information returned by - ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=False)`` - or else ``sysconfig.get_path('platlib')``. + Information returned by ``sysconfig.get_path('platlib')``. ``Python3_SOABI`` .. versionadded:: 3.17 Extension suffix for modules. - Information computed from ``distutils.sysconfig.get_config_var('EXT_SUFFIX')`` - or ``distutils.sysconfig.get_config_var('SOABI')`` or - ``python3-config --extension-suffix``. If package ``distutils.sysconfig`` is - not available, ``sysconfig.get_config_var('EXT_SUFFIX')`` or - ``sysconfig.get_config_var('SOABI')`` are used. + Information computed from ``sysconfig.get_config_var('EXT_SUFFIX')`` or + ``sysconfig.get_config_var('SOABI')`` or + ``python3-config --extension-suffix``. ``Python3_SOSABI`` .. versionadded:: 3.26 diff --git a/Modules/Platform/Apple-AppleClang-ASM.cmake b/Modules/Platform/Apple-AppleClang-ASM.cmake new file mode 100644 index 0000000..c8ff470 --- /dev/null +++ b/Modules/Platform/Apple-AppleClang-ASM.cmake @@ -0,0 +1 @@ +include(Platform/Apple-Clang-ASM) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index e2f28c1..c29a09e 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 26) -set(CMake_VERSION_PATCH 20230605) +set(CMake_VERSION_PATCH 20230606) #set(CMake_VERSION_RC 0) set(CMake_VERSION_IS_DIRTY 0) diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index 5d44a6a..b80b3cb 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -1175,7 +1175,14 @@ void cmComputeLinkInformation::AddItem(LinkEntry const& entry) LinkEntry libEntry{ entry }; libEntry.Item = lib; this->AddTargetItem(libEntry); - this->AddLibraryRuntimeInfo(lib.Value, tgt); + if (tgt->IsApple() && tgt->HasImportLibrary(config)) { + // Use the library rather than the tbd file for runpath computation + this->AddLibraryRuntimeInfo( + tgt->GetFullPath(config, cmStateEnums::RuntimeBinaryArtifact, true), + tgt); + } else { + this->AddLibraryRuntimeInfo(lib.Value, tgt); + } if (tgt && tgt->GetType() == cmStateEnums::SHARED_LIBRARY && this->Target->IsDLLPlatform()) { this->AddRuntimeDLL(tgt); @@ -1261,7 +1268,15 @@ void cmComputeLinkInformation::AddSharedDepItem(LinkEntry const& entry) ? cmStateEnums::ImportLibraryArtifact : cmStateEnums::RuntimeBinaryArtifact; lib = tgt->GetFullPath(this->Config, artifact); - this->AddLibraryRuntimeInfo(lib, tgt); + if (tgt->IsApple() && tgt->HasImportLibrary(this->Config)) { + // Use the library rather than the tbd file for runpath computation + this->AddLibraryRuntimeInfo( + tgt->GetFullPath(this->Config, cmStateEnums::RuntimeBinaryArtifact, + true), + tgt); + } else { + this->AddLibraryRuntimeInfo(lib, tgt); + } } else { lib = item.Value; this->AddLibraryRuntimeInfo(lib); diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 3cefeda..357d0a6 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -8796,6 +8796,10 @@ std::string cmGeneratorTarget::GenerateHeaderSetVerificationFile( std::string extension; std::string language = source.GetOrDetermineLanguage(); + if (source.GetPropertyAsBool("SKIP_LINTING")) { + return std::string{}; + } + if (language.empty()) { if (!languages) { languages.emplace(); diff --git a/Source/cmUVProcessChain.cxx b/Source/cmUVProcessChain.cxx index c2bb11e..ed5f38b 100644 --- a/Source/cmUVProcessChain.cxx +++ b/Source/cmUVProcessChain.cxx @@ -1,10 +1,16 @@ /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmConfigure.h" + #include "cmUVProcessChain.h" +#include <array> #include <cassert> +#include <csignal> +#include <cstdio> #include <istream> // IWYU pragma: keep #include <iterator> +#include <type_traits> #include <utility> #include <cm/memory> @@ -425,3 +431,245 @@ bool cmUVProcessChain::Finished() const { return this->Data->ProcessesCompleted >= this->Data->Processes.size(); } + +std::pair<cmUVProcessChain::ExceptionCode, std::string> +cmUVProcessChain::Status::GetException() const +{ +#ifdef _WIN32 + if ((this->ExitStatus & 0xF0000000) == 0xC0000000) { + // Child terminated due to exceptional behavior. + switch (this->ExitStatus) { + case STATUS_CONTROL_C_EXIT: + return std::make_pair(ExceptionCode::Interrupt, "User interrupt"); + + case STATUS_FLOAT_DENORMAL_OPERAND: + return std::make_pair(ExceptionCode::Numerical, + "Floating-point exception (denormal operand)"); + case STATUS_FLOAT_DIVIDE_BY_ZERO: + return std::make_pair(ExceptionCode::Numerical, "Divide-by-zero"); + case STATUS_FLOAT_INEXACT_RESULT: + return std::make_pair(ExceptionCode::Numerical, + "Floating-point exception (inexact result)"); + case STATUS_FLOAT_INVALID_OPERATION: + return std::make_pair(ExceptionCode::Numerical, + "Invalid floating-point operation"); + case STATUS_FLOAT_OVERFLOW: + return std::make_pair(ExceptionCode::Numerical, + "Floating-point overflow"); + case STATUS_FLOAT_STACK_CHECK: + return std::make_pair(ExceptionCode::Numerical, + "Floating-point stack check failed"); + case STATUS_FLOAT_UNDERFLOW: + return std::make_pair(ExceptionCode::Numerical, + "Floating-point underflow"); +# ifdef STATUS_FLOAT_MULTIPLE_FAULTS + case STATUS_FLOAT_MULTIPLE_FAULTS: + return std::make_pair(ExceptionCode::Numerical, + "Floating-point exception (multiple faults)"); +# endif +# ifdef STATUS_FLOAT_MULTIPLE_TRAPS + case STATUS_FLOAT_MULTIPLE_TRAPS: + return std::make_pair(ExceptionCode::Numerical, + "Floating-point exception (multiple traps)"); +# endif + case STATUS_INTEGER_DIVIDE_BY_ZERO: + return std::make_pair(ExceptionCode::Numerical, + "Integer divide-by-zero"); + case STATUS_INTEGER_OVERFLOW: + return std::make_pair(ExceptionCode::Numerical, "Integer overflow"); + + case STATUS_DATATYPE_MISALIGNMENT: + return std::make_pair(ExceptionCode::Fault, "Datatype misalignment"); + case STATUS_ACCESS_VIOLATION: + return std::make_pair(ExceptionCode::Fault, "Access violation"); + case STATUS_IN_PAGE_ERROR: + return std::make_pair(ExceptionCode::Fault, "In-page error"); + case STATUS_INVALID_HANDLE: + return std::make_pair(ExceptionCode::Fault, "Invalid handle"); + case STATUS_NONCONTINUABLE_EXCEPTION: + return std::make_pair(ExceptionCode::Fault, + "Noncontinuable exception"); + case STATUS_INVALID_DISPOSITION: + return std::make_pair(ExceptionCode::Fault, "Invalid disposition"); + case STATUS_ARRAY_BOUNDS_EXCEEDED: + return std::make_pair(ExceptionCode::Fault, "Array bounds exceeded"); + case STATUS_STACK_OVERFLOW: + return std::make_pair(ExceptionCode::Fault, "Stack overflow"); + + case STATUS_ILLEGAL_INSTRUCTION: + return std::make_pair(ExceptionCode::Illegal, "Illegal instruction"); + case STATUS_PRIVILEGED_INSTRUCTION: + return std::make_pair(ExceptionCode::Illegal, + "Privileged instruction"); + + case STATUS_NO_MEMORY: + default: { + char buf[256]; + snprintf(buf, sizeof(buf), "Exit code 0x%x\n", + static_cast<unsigned int>(this->ExitStatus)); + return std::make_pair(ExceptionCode::Other, buf); + } + } + } + return std::make_pair(ExceptionCode::None, ""); +#else + if (this->TermSignal) { + switch (this->TermSignal) { +# ifdef SIGSEGV + case SIGSEGV: + return std::make_pair(ExceptionCode::Fault, "Segmentation fault"); +# endif +# ifdef SIGBUS +# if !defined(SIGSEGV) || SIGBUS != SIGSEGV + case SIGBUS: + return std::make_pair(ExceptionCode::Fault, "Bus error"); +# endif +# endif +# ifdef SIGFPE + case SIGFPE: + return std::make_pair(ExceptionCode::Numerical, + "Floating-point exception"); +# endif +# ifdef SIGILL + case SIGILL: + return std::make_pair(ExceptionCode::Illegal, "Illegal instruction"); +# endif +# ifdef SIGINT + case SIGINT: + return std::make_pair(ExceptionCode::Interrupt, "User interrupt"); +# endif +# ifdef SIGABRT + case SIGABRT: + return std::make_pair(ExceptionCode::Other, "Subprocess aborted"); +# endif +# ifdef SIGKILL + case SIGKILL: + return std::make_pair(ExceptionCode::Other, "Subprocess killed"); +# endif +# ifdef SIGTERM + case SIGTERM: + return std::make_pair(ExceptionCode::Other, "Subprocess terminated"); +# endif +# ifdef SIGHUP + case SIGHUP: + return std::make_pair(ExceptionCode::Other, "SIGHUP"); +# endif +# ifdef SIGQUIT + case SIGQUIT: + return std::make_pair(ExceptionCode::Other, "SIGQUIT"); +# endif +# ifdef SIGTRAP + case SIGTRAP: + return std::make_pair(ExceptionCode::Other, "SIGTRAP"); +# endif +# ifdef SIGIOT +# if !defined(SIGABRT) || SIGIOT != SIGABRT + case SIGIOT: + return std::make_pair(ExceptionCode::Other, "SIGIOT"); +# endif +# endif +# ifdef SIGUSR1 + case SIGUSR1: + return std::make_pair(ExceptionCode::Other, "SIGUSR1"); +# endif +# ifdef SIGUSR2 + case SIGUSR2: + return std::make_pair(ExceptionCode::Other, "SIGUSR2"); +# endif +# ifdef SIGPIPE + case SIGPIPE: + return std::make_pair(ExceptionCode::Other, "SIGPIPE"); +# endif +# ifdef SIGALRM + case SIGALRM: + return std::make_pair(ExceptionCode::Other, "SIGALRM"); +# endif +# ifdef SIGSTKFLT + case SIGSTKFLT: + return std::make_pair(ExceptionCode::Other, "SIGSTKFLT"); +# endif +# ifdef SIGCHLD + case SIGCHLD: + return std::make_pair(ExceptionCode::Other, "SIGCHLD"); +# elif defined(SIGCLD) + case SIGCLD: + return std::make_pair(ExceptionCode::Other, "SIGCLD"); +# endif +# ifdef SIGCONT + case SIGCONT: + return std::make_pair(ExceptionCode::Other, "SIGCONT"); +# endif +# ifdef SIGSTOP + case SIGSTOP: + return std::make_pair(ExceptionCode::Other, "SIGSTOP"); +# endif +# ifdef SIGTSTP + case SIGTSTP: + return std::make_pair(ExceptionCode::Other, "SIGTSTP"); +# endif +# ifdef SIGTTIN + case SIGTTIN: + return std::make_pair(ExceptionCode::Other, "SIGTTIN"); +# endif +# ifdef SIGTTOU + case SIGTTOU: + return std::make_pair(ExceptionCode::Other, "SIGTTOU"); +# endif +# ifdef SIGURG + case SIGURG: + return std::make_pair(ExceptionCode::Other, "SIGURG"); +# endif +# ifdef SIGXCPU + case SIGXCPU: + return std::make_pair(ExceptionCode::Other, "SIGXCPU"); +# endif +# ifdef SIGXFSZ + case SIGXFSZ: + return std::make_pair(ExceptionCode::Other, "SIGXFSZ"); +# endif +# ifdef SIGVTALRM + case SIGVTALRM: + return std::make_pair(ExceptionCode::Other, "SIGVTALRM"); +# endif +# ifdef SIGPROF + case SIGPROF: + return std::make_pair(ExceptionCode::Other, "SIGPROF"); +# endif +# ifdef SIGWINCH + case SIGWINCH: + return std::make_pair(ExceptionCode::Other, "SIGWINCH"); +# endif +# ifdef SIGPOLL + case SIGPOLL: + return std::make_pair(ExceptionCode::Other, "SIGPOLL"); +# endif +# ifdef SIGIO +# if !defined(SIGPOLL) || SIGIO != SIGPOLL + case SIGIO: + return std::make_pair(ExceptionCode::Other, "SIGIO"); +# endif +# endif +# ifdef SIGPWR + case SIGPWR: + return std::make_pair(ExceptionCode::Other, "SIGPWR"); +# endif +# ifdef SIGSYS + case SIGSYS: + return std::make_pair(ExceptionCode::Other, "SIGSYS"); +# endif +# ifdef SIGUNUSED +# if !defined(SIGSYS) || SIGUNUSED != SIGSYS + case SIGUNUSED: + return std::make_pair(ExceptionCode::Other, "SIGUNUSED"); +# endif +# endif + default: { + char buf[256]; + snprintf(buf, sizeof(buf), "Signal %d", this->TermSignal); + return std::make_pair(ExceptionCode::Other, buf); + } + } + } + return std::make_pair(ExceptionCode::None, ""); +#endif +} diff --git a/Source/cmUVProcessChain.h b/Source/cmUVProcessChain.h index 9e4558e..f92742f 100644 --- a/Source/cmUVProcessChain.h +++ b/Source/cmUVProcessChain.h @@ -8,6 +8,7 @@ #include <iosfwd> #include <memory> #include <string> +#include <utility> #include <vector> #include <cm3p/uv.h> @@ -66,10 +67,22 @@ private: class cmUVProcessChain { public: + enum class ExceptionCode + { + None, + Fault, + Illegal, + Interrupt, + Numerical, + Other, + }; + struct Status { int64_t ExitStatus; int TermSignal; + + std::pair<ExceptionCode, std::string> GetException() const; }; cmUVProcessChain(const cmUVProcessChain& other) = delete; diff --git a/Tests/Assembler/CMakeLists.txt b/Tests/Assembler/CMakeLists.txt index 8f6b355..4635f03 100644 --- a/Tests/Assembler/CMakeLists.txt +++ b/Tests/Assembler/CMakeLists.txt @@ -24,7 +24,7 @@ if("${CMAKE_GENERATOR}" MATCHES "Makefile|Xcode|Ninja" AND elseif("${CMAKE_SYSTEM_NAME};${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "Darwin;arm64") list(APPEND C_FLAGS -arch arm64) endif() - if(CMAKE_C_COMPILER_ID STREQUAL "Clang") + if(CMAKE_C_COMPILER_ID MATCHES "Clang") # Just in case the user is passing -flto, we need to pass -fno-lto to # clang when generating the assembly file, or else clang will generate # LLVM IR instead of assembly. diff --git a/Tests/CMakeLib/testUVProcessChain.cxx b/Tests/CMakeLib/testUVProcessChain.cxx index ce6cd6d..7027689 100644 --- a/Tests/CMakeLib/testUVProcessChain.cxx +++ b/Tests/CMakeLib/testUVProcessChain.cxx @@ -4,6 +4,8 @@ #include <iostream> #include <sstream> #include <string> +#include <type_traits> +#include <utility> #include <vector> #include <cm/memory> @@ -22,30 +24,62 @@ struct ExpectedStatus bool MatchExitStatus; bool MatchTermSignal; cmUVProcessChain::Status Status; + cmUVProcessChain::ExceptionCode ExceptionCode; + std::string ExceptionString; }; static const std::vector<ExpectedStatus> status1 = { - { false, false, false, { 0, 0 } }, - { false, false, false, { 0, 0 } }, - { false, false, false, { 0, 0 } }, + { false, false, false, { 0, 0 }, cmUVProcessChain::ExceptionCode::None, "" }, + { false, false, false, { 0, 0 }, cmUVProcessChain::ExceptionCode::None, "" }, + { false, false, false, { 0, 0 }, cmUVProcessChain::ExceptionCode::None, "" }, }; static const std::vector<ExpectedStatus> status2 = { - { true, true, true, { 0, 0 } }, - { false, false, false, { 0, 0 } }, - { false, false, false, { 0, 0 } }, + { true, true, true, { 0, 0 }, cmUVProcessChain::ExceptionCode::None, "" }, + { false, false, false, { 0, 0 }, cmUVProcessChain::ExceptionCode::None, "" }, + { false, false, false, { 0, 0 }, cmUVProcessChain::ExceptionCode::None, "" }, }; static const std::vector<ExpectedStatus> status3 = { - { true, true, true, { 0, 0 } }, - { true, true, true, { 1, 0 } }, + { true, true, true, { 0, 0 }, cmUVProcessChain::ExceptionCode::None, "" }, + { true, true, true, { 1, 0 }, cmUVProcessChain::ExceptionCode::None, "" }, #ifdef _WIN32 - { true, true, true, { 2, 0 } }, + { true, + true, + true, + { STATUS_ACCESS_VIOLATION, 0 }, + cmUVProcessChain::ExceptionCode::Fault, + "Access violation" }, #else - { true, false, true, { 0, SIGABRT } }, + { true, + false, + true, + { 0, SIGABRT }, + cmUVProcessChain::ExceptionCode::Other, + "Subprocess aborted" }, #endif }; +static const char* ExceptionCodeToString(cmUVProcessChain::ExceptionCode code) +{ + switch (code) { + case cmUVProcessChain::ExceptionCode::None: + return "None"; + case cmUVProcessChain::ExceptionCode::Fault: + return "Fault"; + case cmUVProcessChain::ExceptionCode::Illegal: + return "Illegal"; + case cmUVProcessChain::ExceptionCode::Interrupt: + return "Interrupt"; + case cmUVProcessChain::ExceptionCode::Numerical: + return "Numerical"; + case cmUVProcessChain::ExceptionCode::Other: + return "Other"; + default: + return ""; + } +} + bool operator==(const cmUVProcessChain::Status* actual, const ExpectedStatus& expected) { @@ -62,6 +96,11 @@ bool operator==(const cmUVProcessChain::Status* actual, expected.Status.TermSignal != actual->TermSignal) { return false; } + if (expected.Finished && + std::make_pair(expected.ExceptionCode, expected.ExceptionString) != + actual->GetException()) { + return false; + } return true; } @@ -116,6 +155,11 @@ static void printResults( << printExpected(e.MatchExitStatus, e.Status.ExitStatus) << ", TermSignal: " << printExpected(e.MatchTermSignal, e.Status.TermSignal) + << ", ExceptionCode: " + << printExpected(e.Finished, + ExceptionCodeToString(e.ExceptionCode)) + << ", ExceptionString: \"" + << printExpected(e.Finished, e.ExceptionString) << '"' << std::endl; } else { std::cout << " null" << std::endl; @@ -124,8 +168,12 @@ static void printResults( std::cout << "Actual:" << std::endl; for (auto const& a : actual) { if (a) { + auto exception = a->GetException(); std::cout << " ExitStatus: " << a->ExitStatus - << ", TermSignal: " << a->TermSignal << std::endl; + << ", TermSignal: " << a->TermSignal << ", ExceptionCode: " + << ExceptionCodeToString(exception.first) + << ", ExceptionString: \"" << exception.second << '"' + << std::endl; } else { std::cout << " null" << std::endl; } diff --git a/Tests/CMakeLib/testUVProcessChainHelper.cxx b/Tests/CMakeLib/testUVProcessChainHelper.cxx index 82dafd2..99743e7 100644 --- a/Tests/CMakeLib/testUVProcessChainHelper.cxx +++ b/Tests/CMakeLib/testUVProcessChainHelper.cxx @@ -7,6 +7,10 @@ #include <string> #include <thread> +#ifdef _WIN32 +# include <windows.h> +#endif + #include "cmSystemTools.h" static std::string getStdin() @@ -61,10 +65,9 @@ int main(int argc, char** argv) } // On Windows, the exit code of abort() is different between debug and - // release builds, and does not yield a term_signal in libuv in either - // case. For the sake of simplicity, we just return another non-zero code. + // release builds. Instead, simulate an access violation. #ifdef _WIN32 - return 2; + return STATUS_ACCESS_VIOLATION; #else std::abort(); #endif diff --git a/Tests/RunCMake/AppleTextStubs/LibraryWithOutputs.cmake b/Tests/RunCMake/AppleTextStubs/LibraryWithOutputs.cmake index f61c8f2..9c7107a 100644 --- a/Tests/RunCMake/AppleTextStubs/LibraryWithOutputs.cmake +++ b/Tests/RunCMake/AppleTextStubs/LibraryWithOutputs.cmake @@ -7,6 +7,9 @@ set_property(TARGET foo PROPERTY ARCHIVE_OUTPUT_NAME "tbd") add_executable(main main.c) target_link_libraries(main PRIVATE foo) +set_property(TARGET main PROPERTY RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/$<CONFIG>") + +add_custom_target(run COMMAND "$<TARGET_FILE:main>") set (GENERATE_CONTENT "if (\"${CMAKE_TAPI}\") diff --git a/Tests/RunCMake/AppleTextStubs/RunCMakeTest.cmake b/Tests/RunCMake/AppleTextStubs/RunCMakeTest.cmake index 9ccd685..7687106 100644 --- a/Tests/RunCMake/AppleTextStubs/RunCMakeTest.cmake +++ b/Tests/RunCMake/AppleTextStubs/RunCMakeTest.cmake @@ -19,7 +19,12 @@ endfunction() build_project(Simple) build_project(Framework) -build_project(LibraryWithOutputs) + +function(LibraryWithOutputs-run) + run_cmake_command(${test}-run ${CMAKE_COMMAND} --build . --target run --config Release) +endfunction() + +build_project(LibraryWithOutputs LibraryWithOutputs-run) function(LibraryWithVersions-install) diff --git a/Tests/RunCMake/VerifyHeaderSets/RunCMakeTest.cmake b/Tests/RunCMake/VerifyHeaderSets/RunCMakeTest.cmake index b4fe720..982087f 100644 --- a/Tests/RunCMake/VerifyHeaderSets/RunCMakeTest.cmake +++ b/Tests/RunCMake/VerifyHeaderSets/RunCMakeTest.cmake @@ -42,6 +42,7 @@ run_cmake_build(VerifyHeaderSets lang_test_c_verify_interface_header_sets) run_cmake_build(VerifyHeaderSets lang_test_cxx_verify_interface_header_sets) run_cmake_build(VerifyHeaderSets interface_lang_test_cxx_verify_interface_header_sets) run_cmake_build(VerifyHeaderSets list_verify_interface_header_sets) +run_cmake_build(VerifyHeaderSets skip_linting_verify_interface_header_sets) set(RunCMake_TEST_OPTIONS -DCMAKE_VERIFY_INTERFACE_HEADER_SETS=ON) run_cmake(AllVerifyInterfaceHeaderSets) diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets.cmake b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets.cmake index f260609..7de9f1e 100644 --- a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets.cmake +++ b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets.cmake @@ -74,3 +74,8 @@ target_sources(list INTERFACE FILE_SET error TYPE HEADERS FILES error.h ) set_property(TARGET list PROPERTY INTERFACE_HEADER_SETS_TO_VERIFY "a;c") + +add_library(skip_linting STATIC lib.c) +target_sources(skip_linting INTERFACE FILE_SET HEADERS FILES lang_test.h skip_linting.h) +set_property(SOURCE skip_linting.h PROPERTY LANGUAGE C) +set_property(SOURCE skip_linting.h PROPERTY SKIP_LINTING TRUE) diff --git a/Tests/RunCMake/VerifyHeaderSets/skip_linting.h b/Tests/RunCMake/VerifyHeaderSets/skip_linting.h new file mode 100644 index 0000000..908ca95 --- /dev/null +++ b/Tests/RunCMake/VerifyHeaderSets/skip_linting.h @@ -0,0 +1,3 @@ +#error "This file should not be included" + +extern void skip_linting_h(void); |