diff options
95 files changed, 867 insertions, 190 deletions
diff --git a/Help/command/foreach.rst b/Help/command/foreach.rst index ecbfed3..a01a104 100644 --- a/Help/command/foreach.rst +++ b/Help/command/foreach.rst @@ -82,3 +82,46 @@ yields -- X=6 -- X=7 -- X=8 + + +.. code-block:: cmake + + foreach(<loop_var>... IN ZIP_LISTS <lists>) + +In this variant, ``<lists>`` is a whitespace or semicolon +separated list of list-valued variables. The ``foreach`` +command iterates over each list simultaneously setting the +iteration variables as follows: + +- if the only ``loop_var`` given, then it sets a series of + ``loop_var_N`` variables to the current item from the + corresponding list; +- if multiple variable names passed, their count should match + the lists variables count; +- if any of the lists are shorter, the corresponding iteration + variable is not defined for the current iteration. + +.. code-block:: cmake + + list(APPEND English one two three four) + list(APPEND Bahasa satu dua tiga) + + foreach(num IN ZIP_LISTS English Bahasa) + message(STATUS "num_0=${num_0}, num_1=${num_1}") + endforeach() + + foreach(en ba IN ZIP_LISTS English Bahasa) + message(STATUS "en=${en}, ba=${ba}") + endforeach() + +yields +:: + + -- num_0=one, num_1=satu + -- num_0=two, num_1=dua + -- num_0=three, num_1=tiga + -- num_0=four, num_1= + -- en=one, ba=satu + -- en=two, ba=dua + -- en=three, ba=tiga + -- en=four, ba= diff --git a/Help/envvar/CMAKE_LANG_COMPILER_LAUNCHER.rst b/Help/envvar/CMAKE_LANG_COMPILER_LAUNCHER.rst new file mode 100644 index 0000000..4f91e9a --- /dev/null +++ b/Help/envvar/CMAKE_LANG_COMPILER_LAUNCHER.rst @@ -0,0 +1,10 @@ +CMAKE_<LANG>_COMPILER_LAUNCHER +------------------------------ + +.. include:: ENV_VAR.txt + +Default compiler launcher to use for the specified language. Will only be used +by CMake to initialize the variable on the first configuration. Afterwards, it +is available through the cache setting of the variable of the same name. For +any configuration run (including the first), the environment variable will be +ignored if the :variable:`CMAKE_<LANG>_COMPILER_LAUNCHER` variable is defined. diff --git a/Help/manual/cmake-env-variables.7.rst b/Help/manual/cmake-env-variables.7.rst index c98f18f..adfc39e 100644 --- a/Help/manual/cmake-env-variables.7.rst +++ b/Help/manual/cmake-env-variables.7.rst @@ -28,6 +28,7 @@ Environment Variables that Control the Build /envvar/CMAKE_GENERATOR_INSTANCE /envvar/CMAKE_GENERATOR_PLATFORM /envvar/CMAKE_GENERATOR_TOOLSET + /envvar/CMAKE_LANG_COMPILER_LAUNCHER /envvar/CMAKE_MSVCIDE_RUN_PATH /envvar/CMAKE_NO_VERBOSE /envvar/CMAKE_OSX_ARCHITECTURES diff --git a/Help/release/dev/FindLibArchive-target.rst b/Help/release/dev/FindLibArchive-target.rst new file mode 100644 index 0000000..8998dae --- /dev/null +++ b/Help/release/dev/FindLibArchive-target.rst @@ -0,0 +1,5 @@ +FindLibArchive-target +--------------------- + +* The :module:`FindLibArchive` module now returns an ``IMPORTED`` target + for libarchive. diff --git a/Help/release/dev/compiler-launcher-env.rst b/Help/release/dev/compiler-launcher-env.rst new file mode 100644 index 0000000..58519d9 --- /dev/null +++ b/Help/release/dev/compiler-launcher-env.rst @@ -0,0 +1,5 @@ +compiler-launcher-env +--------------------- + +* The :envvar:`CMAKE_<LANG>_COMPILER_LAUNCHER` environment variable may now be + used to initialize the :variable:`CMAKE_<LANG>_COMPILER_LAUNCHER` variable. diff --git a/Help/release/dev/foreach-ZIP_LISTS.rst b/Help/release/dev/foreach-ZIP_LISTS.rst new file mode 100644 index 0000000..d45d9b9 --- /dev/null +++ b/Help/release/dev/foreach-ZIP_LISTS.rst @@ -0,0 +1,5 @@ +foreach-ZIP_LISTS +----------------- + +* The :command:`foreach` learned a new option ``ZIP_LISTS`` to iterate + over multiple lists simultaneously. diff --git a/Help/variable/CMAKE_LANG_COMPILER_LAUNCHER.rst b/Help/variable/CMAKE_LANG_COMPILER_LAUNCHER.rst index e6c8bb5..e5dda60 100644 --- a/Help/variable/CMAKE_LANG_COMPILER_LAUNCHER.rst +++ b/Help/variable/CMAKE_LANG_COMPILER_LAUNCHER.rst @@ -5,3 +5,6 @@ Default value for :prop_tgt:`<LANG>_COMPILER_LAUNCHER` target property. This variable is used to initialize the property on each target as it is created. This is done only when ``<LANG>`` is ``C``, ``CXX``, ``Fortran``, or ``CUDA``. + +This variable is initialized to the :envvar:`CMAKE_<LANG>_COMPILER_LAUNCHER` +environment variable if it is set. diff --git a/Modules/CMakeCInformation.cmake b/Modules/CMakeCInformation.cmake index df43559..1e08bb7 100644 --- a/Modules/CMakeCInformation.cmake +++ b/Modules/CMakeCInformation.cmake @@ -110,6 +110,11 @@ if(CMAKE_C_STANDARD_LIBRARIES_INIT) mark_as_advanced(CMAKE_C_STANDARD_LIBRARIES) endif() +if(NOT CMAKE_C_COMPILER_LAUNCHER AND DEFINED ENV{CMAKE_C_COMPILER_LAUNCHER}) + set(CMAKE_C_COMPILER_LAUNCHER "$ENV{CMAKE_C_COMPILER_LAUNCHER}" + CACHE STRING "Compiler launcher for C.") +endif() + include(CMakeCommonLanguageInclude) # now define the following rule variables diff --git a/Modules/CMakeCUDAInformation.cmake b/Modules/CMakeCUDAInformation.cmake index b0d80d1..974f5fa 100644 --- a/Modules/CMakeCUDAInformation.cmake +++ b/Modules/CMakeCUDAInformation.cmake @@ -82,6 +82,11 @@ if(CMAKE_CUDA_STANDARD_LIBRARIES_INIT) mark_as_advanced(CMAKE_CUDA_STANDARD_LIBRARIES) endif() +if(NOT CMAKE_CUDA_COMPILER_LAUNCHER AND DEFINED ENV{CMAKE_CUDA_COMPILER_LAUNCHER}) + set(CMAKE_CUDA_COMPILER_LAUNCHER "$ENV{CMAKE_CUDA_COMPILER_LAUNCHER}" + CACHE STRING "Compiler launcher for CUDA.") +endif() + include(CMakeCommonLanguageInclude) # now define the following rules: @@ -93,9 +98,7 @@ include(CMakeCommonLanguageInclude) # CMAKE_CUDA_LINK_EXECUTABLE if(CMAKE_CUDA_HOST_COMPILER) - set(CMAKE_CUDA_HOST_FLAGS "-ccbin=<CMAKE_CUDA_HOST_COMPILER>") -else() - set(CMAKE_CUDA_HOST_FLAGS "") + string(APPEND _CMAKE_CUDA_EXTRA_FLAGS " -ccbin=<CMAKE_CUDA_HOST_COMPILER>") endif() set(__IMPLICT_LINKS ) @@ -135,26 +138,26 @@ endif() #Specify how to compile when ptx has been requested if(NOT CMAKE_CUDA_COMPILE_PTX_COMPILATION) set(CMAKE_CUDA_COMPILE_PTX_COMPILATION - "<CMAKE_CUDA_COMPILER> ${CMAKE_CUDA_HOST_FLAGS} <DEFINES> <INCLUDES> <FLAGS> -x cu -ptx <SOURCE> -o <OBJECT>") + "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <DEFINES> <INCLUDES> <FLAGS> -x cu -ptx <SOURCE> -o <OBJECT>") endif() #Specify how to compile when separable compilation has been requested if(NOT CMAKE_CUDA_COMPILE_SEPARABLE_COMPILATION) set(CMAKE_CUDA_COMPILE_SEPARABLE_COMPILATION - "<CMAKE_CUDA_COMPILER> ${CMAKE_CUDA_HOST_FLAGS} <DEFINES> <INCLUDES> <FLAGS> -x cu -dc <SOURCE> -o <OBJECT>") + "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <DEFINES> <INCLUDES> <FLAGS> -x cu -dc <SOURCE> -o <OBJECT>") endif() #Specify how to compile when whole compilation has been requested if(NOT CMAKE_CUDA_COMPILE_WHOLE_COMPILATION) set(CMAKE_CUDA_COMPILE_WHOLE_COMPILATION - "<CMAKE_CUDA_COMPILER> ${CMAKE_CUDA_HOST_FLAGS} <DEFINES> <INCLUDES> <FLAGS> -x cu -c <SOURCE> -o <OBJECT>") + "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <DEFINES> <INCLUDES> <FLAGS> -x cu -c <SOURCE> -o <OBJECT>") endif() -if(CMAKE_GENERATOR STREQUAL "Ninja") +if(CMAKE_GENERATOR STREQUAL "Ninja" AND NOT CMAKE_DEPFILE_FLAGS_CUDA ) set(CMAKE_CUDA_COMPILE_DEPENDENCY_DETECTION - "<CMAKE_CUDA_COMPILER> ${CMAKE_CUDA_HOST_FLAGS} <DEFINES> <INCLUDES> <FLAGS> -x cu -M <SOURCE> -MT <OBJECT> -o $DEP_FILE") + "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <DEFINES> <INCLUDES> <FLAGS> -x cu -M <SOURCE> -MT <OBJECT> -o $DEP_FILE") #The Ninja generator uses the make file dependency files to determine what - #files need to be recompiled. Unfortunately, nvcc doesn't support building + #files need to be recompiled. Unfortunately, nvcc < 10.2 doesn't support building #a source file and generating the dependencies of said file in a single #invocation. Instead we have to state that you need to chain two commands. # @@ -171,13 +174,6 @@ if(NOT CMAKE_CUDA_LINK_EXECUTABLE) "<CMAKE_CUDA_HOST_LINK_LAUNCHER> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>${__IMPLICT_LINKS}") endif() -if( CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA" AND - CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL "8.0.0") - set(_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS "-Wno-deprecated-gpu-targets") -else() - set(_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS "") -endif() - # Add implicit host link directories that contain device libraries # to the device link line. set(__IMPLICT_DLINK_DIRS ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES}) @@ -192,14 +188,15 @@ foreach(dir ${__IMPLICT_DLINK_DIRS}) endforeach() unset(__IMPLICT_DLINK_DIRS) + #These are used when linking relocatable (dc) cuda code if(NOT CMAKE_CUDA_DEVICE_LINK_LIBRARY) set(CMAKE_CUDA_DEVICE_LINK_LIBRARY - "<CMAKE_CUDA_COMPILER> ${CMAKE_CUDA_HOST_FLAGS} <LANGUAGE_COMPILE_FLAGS> ${CMAKE_CUDA_COMPILE_OPTIONS_PIC} ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES>${__IMPLICT_DLINK_FLAGS}") + "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <LANGUAGE_COMPILE_FLAGS> ${CMAKE_CUDA_COMPILE_OPTIONS_PIC} ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES>${__IMPLICT_DLINK_FLAGS}") endif() if(NOT CMAKE_CUDA_DEVICE_LINK_EXECUTABLE) set(CMAKE_CUDA_DEVICE_LINK_EXECUTABLE - "<CMAKE_CUDA_COMPILER> ${CMAKE_CUDA_HOST_FLAGS} <FLAGS> ${CMAKE_CUDA_COMPILE_OPTIONS_PIC} ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES>${__IMPLICT_DLINK_FLAGS}") + "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <FLAGS> ${CMAKE_CUDA_COMPILE_OPTIONS_PIC} ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES>${__IMPLICT_DLINK_FLAGS}") endif() unset(_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS) diff --git a/Modules/CMakeCXXInformation.cmake b/Modules/CMakeCXXInformation.cmake index a896b99..da7440a 100644 --- a/Modules/CMakeCXXInformation.cmake +++ b/Modules/CMakeCXXInformation.cmake @@ -207,6 +207,11 @@ if(CMAKE_CXX_STANDARD_LIBRARIES_INIT) mark_as_advanced(CMAKE_CXX_STANDARD_LIBRARIES) endif() +if(NOT CMAKE_CXX_COMPILER_LAUNCHER AND DEFINED ENV{CMAKE_CXX_COMPILER_LAUNCHER}) + set(CMAKE_CXX_COMPILER_LAUNCHER "$ENV{CMAKE_CXX_COMPILER_LAUNCHER}" + CACHE STRING "Compiler launcher for CXX.") +endif() + include(CMakeCommonLanguageInclude) # now define the following rules: diff --git a/Modules/CMakeFortranInformation.cmake b/Modules/CMakeFortranInformation.cmake index ffa6a24..e80716b 100644 --- a/Modules/CMakeFortranInformation.cmake +++ b/Modules/CMakeFortranInformation.cmake @@ -163,6 +163,11 @@ set(CMAKE_Fortran_FLAGS_INIT "$ENV{FFLAGS} ${CMAKE_Fortran_FLAGS_INIT}") cmake_initialize_per_config_variable(CMAKE_Fortran_FLAGS "Flags used by the Fortran compiler") +if(NOT CMAKE_Fortran_COMPILER_LAUNCHER AND DEFINED ENV{CMAKE_Fortran_COMPILER_LAUNCHER}) + set(CMAKE_Fortran_COMPILER_LAUNCHER "$ENV{CMAKE_Fortran_COMPILER_LAUNCHER}" + CACHE STRING "Compiler launcher for Fortran.") +endif() + include(CMakeCommonLanguageInclude) # now define the following rule variables diff --git a/Modules/Compiler/NVIDIA-CUDA.cmake b/Modules/Compiler/NVIDIA-CUDA.cmake index b59deda..2b24fa5 100644 --- a/Modules/Compiler/NVIDIA-CUDA.cmake +++ b/Modules/Compiler/NVIDIA-CUDA.cmake @@ -2,6 +2,29 @@ set(CMAKE_CUDA_COMPILER_HAS_DEVICE_LINK_PHASE True) set(CMAKE_CUDA_VERBOSE_FLAG "-v") set(CMAKE_CUDA_VERBOSE_COMPILE_FLAG "-Xcompiler=-v") +if (NOT CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 10.2) + # The -forward-unknown-to-host-compiler flag was only + # added to nvcc in 10.2 so before that we had no good + # way to invoke the CUDA compiler and propagate unknown + # flags such as -pthread to the host compiler + set(_CMAKE_CUDA_EXTRA_FLAGS "-forward-unknown-to-host-compiler") +else() + set(_CMAKE_CUDA_EXTRA_FLAGS "") +endif() + +if(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL "8.0.0") + set(_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS "-Wno-deprecated-gpu-targets") +else() + set(_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS "") +endif() + +if (NOT CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 10.2) + # The -MD flag was only added to nvcc in 10.2 so + # before that we had to invoke the compiler twice + # to get header dependency information + set(CMAKE_DEPFILE_FLAGS_CUDA "-MD -MT <OBJECT> -MF <DEPFILE>") +endif() + if(NOT "x${CMAKE_CUDA_SIMULATE_ID}" STREQUAL "xMSVC") set(CMAKE_CUDA_COMPILE_OPTIONS_PIE -Xcompiler=-fPIE) set(CMAKE_CUDA_COMPILE_OPTIONS_PIC -Xcompiler=-fPIC) diff --git a/Modules/FindLibArchive.cmake b/Modules/FindLibArchive.cmake index ef27b7d..ce3c8b8 100644 --- a/Modules/FindLibArchive.cmake +++ b/Modules/FindLibArchive.cmake @@ -16,18 +16,26 @@ The module defines the following variables: LibArchive_INCLUDE_DIRS - include search path LibArchive_LIBRARIES - libraries to link LibArchive_VERSION - libarchive 3-component version number + +The module defines the following ``IMPORTED`` targets: + +:: + + LibArchive::LibArchive - target for linking against libarchive #]=======================================================================] find_path(LibArchive_INCLUDE_DIR NAMES archive.h PATHS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\GnuWin32\\LibArchive;InstallPath]/include" + DOC "libarchive include directory" ) find_library(LibArchive_LIBRARY NAMES archive libarchive PATHS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\GnuWin32\\LibArchive;InstallPath]/lib" + DOC "libarchive library" ) mark_as_advanced(LibArchive_INCLUDE_DIR LibArchive_LIBRARY) @@ -58,4 +66,11 @@ unset(LIBARCHIVE_FOUND) if(LibArchive_FOUND) set(LibArchive_INCLUDE_DIRS ${LibArchive_INCLUDE_DIR}) set(LibArchive_LIBRARIES ${LibArchive_LIBRARY}) + + if (NOT TARGET LibArchive::LibArchive) + add_library(LibArchive::LibArchive UNKNOWN IMPORTED) + set_target_properties(LibArchive::LibArchive PROPERTIES + IMPORTED_LOCATION "${LibArchive_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${LibArchive_INCLUDE_DIR}") + endif () endif() diff --git a/Modules/Internal/CPack/CPackNuGet.cmake b/Modules/Internal/CPack/CPackNuGet.cmake index b46a7b1..1f4bcfd 100644 --- a/Modules/Internal/CPack/CPackNuGet.cmake +++ b/Modules/Internal/CPack/CPackNuGet.cmake @@ -239,20 +239,13 @@ function(_cpack_nuget_render_spec) if(_ver) _cpack_nuget_debug(" got `${_dep}` dependency version ${_ver}") - list(APPEND _collected_deps "<dependency id=\"${_dep}\" version=\"${_ver}\" />") + string(CONCAT _collected_deps "${_collected_deps}" " <dependency id=\"${_dep}\" version=\"${_ver}\" />\n") endif() endforeach() # Render deps into the variable if(_collected_deps) - set(_CPACK_NUGET_DEPENDENCIES_TAG "<dependencies>\n") - foreach(_line IN LISTS _collected_deps) - string( - APPEND _CPACK_NUGET_DEPENDENCIES_TAG - " ${_line}\n" - ) - endforeach() - string(APPEND _CPACK_NUGET_DEPENDENCIES_TAG " </dependencies>") + string(CONCAT _CPACK_NUGET_DEPENDENCIES_TAG "<dependencies>\n" "${_collected_deps}" " </dependencies>") endif() # Render the spec file diff --git a/Modules/Platform/Windows-NVIDIA-CUDA.cmake b/Modules/Platform/Windows-NVIDIA-CUDA.cmake index 94d77b9..30b5aa9 100644 --- a/Modules/Platform/Windows-NVIDIA-CUDA.cmake +++ b/Modules/Platform/Windows-NVIDIA-CUDA.cmake @@ -1,11 +1,11 @@ include(Platform/Windows-MSVC) set(CMAKE_CUDA_COMPILE_PTX_COMPILATION - "<CMAKE_CUDA_COMPILER> ${CMAKE_CUDA_HOST_FLAGS} <DEFINES> <INCLUDES> <FLAGS> -x cu -ptx <SOURCE> -o <OBJECT> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS") + "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <DEFINES> <INCLUDES> <FLAGS> -x cu -ptx <SOURCE> -o <OBJECT> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS") set(CMAKE_CUDA_COMPILE_SEPARABLE_COMPILATION - "<CMAKE_CUDA_COMPILER> ${CMAKE_CUDA_HOST_FLAGS} <DEFINES> <INCLUDES> <FLAGS> -x cu -dc <SOURCE> -o <OBJECT> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS") + "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <DEFINES> <INCLUDES> <FLAGS> -x cu -dc <SOURCE> -o <OBJECT> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS") set(CMAKE_CUDA_COMPILE_WHOLE_COMPILATION - "<CMAKE_CUDA_COMPILER> ${CMAKE_CUDA_HOST_FLAGS} <DEFINES> <INCLUDES> <FLAGS> -x cu -c <SOURCE> -o <OBJECT> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS") + "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <DEFINES> <INCLUDES> <FLAGS> -x cu -c <SOURCE> -o <OBJECT> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS") set(__IMPLICT_LINKS ) foreach(dir ${CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES}) @@ -30,11 +30,6 @@ set(CMAKE_CUDA_LINK_EXECUTABLE unset(_CMAKE_VS_LINK_EXE) unset(_CMAKE_VS_LINK_EXE) -if(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL "8.0.0") - set(_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS "-Wno-deprecated-gpu-targets") -else() - set(_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS "") -endif() # Add implicit host link directories that contain device libraries # to the device link line. @@ -51,11 +46,9 @@ endforeach() unset(__IMPLICT_DLINK_DIRS) set(CMAKE_CUDA_DEVICE_LINK_LIBRARY - "<CMAKE_CUDA_COMPILER> <LANGUAGE_COMPILE_FLAGS> ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS${__IMPLICT_DLINK_FLAGS}") + "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <LANGUAGE_COMPILE_FLAGS> ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS${__IMPLICT_DLINK_FLAGS}") set(CMAKE_CUDA_DEVICE_LINK_EXECUTABLE - "<CMAKE_CUDA_COMPILER> <FLAGS> ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS${__IMPLICT_DLINK_FLAGS}") - -unset(_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS) + "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <FLAGS> ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS${__IMPLICT_DLINK_FLAGS}") unset(__IMPLICT_DLINK_FLAGS) string(REPLACE "/D" "-D" _PLATFORM_DEFINES_CUDA "${_PLATFORM_DEFINES}${_PLATFORM_DEFINES_CXX}") diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index d050fb7..ff313d6 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -693,6 +693,8 @@ set(SRCS cmDuration.h cmDuration.cxx + + bindexplib.cxx ) SET_PROPERTY(SOURCE cmProcessOutput.cxx APPEND PROPERTY COMPILE_DEFINITIONS @@ -715,7 +717,6 @@ if (WIN32) set(SRCS ${SRCS} cmCallVisualStudioMacro.cxx cmCallVisualStudioMacro.h - bindexplib.cxx ) if(NOT UNIX) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index b373350..cdd0893 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 16) -set(CMake_VERSION_PATCH 20191207) +set(CMake_VERSION_PATCH 20191209) #set(CMake_VERSION_RC 0) set(CMake_VERSION_IS_DIRTY 0) diff --git a/Source/bindexplib.cxx b/Source/bindexplib.cxx index b85cc33..0b2750d 100644 --- a/Source/bindexplib.cxx +++ b/Source/bindexplib.cxx @@ -64,32 +64,36 @@ */ #include "bindexplib.h" -#include <iostream> +#include <cstddef> #include <sstream> #include <vector> -#include <windows.h> +#ifdef _WIN32 +# include <windows.h> + +# include "cmsys/Encoding.hxx" +#endif -#include "cmsys/Encoding.hxx" #include "cmsys/FStream.hxx" #include "cmSystemTools.h" -#ifndef IMAGE_FILE_MACHINE_ARM -# define IMAGE_FILE_MACHINE_ARM 0x01c0 // ARM Little-Endian -#endif +#ifdef _WIN32 +# ifndef IMAGE_FILE_MACHINE_ARM +# define IMAGE_FILE_MACHINE_ARM 0x01c0 // ARM Little-Endian +# endif -#ifndef IMAGE_FILE_MACHINE_THUMB -# define IMAGE_FILE_MACHINE_THUMB 0x01c2 // ARM Thumb/Thumb-2 Little-Endian -#endif +# ifndef IMAGE_FILE_MACHINE_THUMB +# define IMAGE_FILE_MACHINE_THUMB 0x01c2 // ARM Thumb/Thumb-2 Little-Endian +# endif -#ifndef IMAGE_FILE_MACHINE_ARMNT -# define IMAGE_FILE_MACHINE_ARMNT 0x01c4 // ARM Thumb-2 Little-Endian -#endif +# ifndef IMAGE_FILE_MACHINE_ARMNT +# define IMAGE_FILE_MACHINE_ARMNT 0x01c4 // ARM Thumb-2 Little-Endian +# endif -#ifndef IMAGE_FILE_MACHINE_ARM64 -# define IMAGE_FILE_MACHINE_ARM64 0xaa64 // ARM64 Little-Endian -#endif +# ifndef IMAGE_FILE_MACHINE_ARM64 +# define IMAGE_FILE_MACHINE_ARM64 0xaa64 // ARM64 Little-Endian +# endif typedef struct cmANON_OBJECT_HEADER_BIGOBJ { @@ -306,6 +310,7 @@ private: SymbolTableType* SymbolTable; bool IsI386; }; +#endif bool DumpFileWithLlvmNm(std::string const& nmPath, const char* filename, std::set<std::string>& symbols, @@ -315,15 +320,15 @@ bool DumpFileWithLlvmNm(std::string const& nmPath, const char* filename, // break up command line into a vector std::vector<std::string> command; command.push_back(nmPath); - command.push_back("--no-weak"); - command.push_back("--defined-only"); - command.push_back("--format=posix"); - command.push_back(filename); + command.emplace_back("--no-weak"); + command.emplace_back("--defined-only"); + command.emplace_back("--format=posix"); + command.emplace_back(filename); // run the command int exit_code = 0; - cmSystemTools::RunSingleCommand(command, &output, &output, &exit_code, "", - cmSystemTools::OUTPUT_NONE); + cmSystemTools::RunSingleCommand(command, &output, &output, &exit_code, + nullptr, cmSystemTools::OUTPUT_NONE); if (exit_code != 0) { fprintf(stderr, "llvm-nm returned an error: %s\n", output.c_str()); @@ -336,7 +341,7 @@ bool DumpFileWithLlvmNm(std::string const& nmPath, const char* filename, if (line.empty()) { // last line continue; } - size_t sym_end = line.find(" "); + size_t sym_end = line.find(' '); if (sym_end == std::string::npos) { fprintf(stderr, "Couldn't parse llvm-nm output line: %s\n", line.c_str()); @@ -366,6 +371,9 @@ bool DumpFile(std::string const& nmPath, const char* filename, std::set<std::string>& symbols, std::set<std::string>& dataSymbols) { +#ifndef _WIN32 + return DumpFileWithLlvmNm(nmPath, filename, symbols, dataSymbols); +#else HANDLE hFile; HANDLE hFileMapping; LPVOID lpFileBase; @@ -446,6 +454,7 @@ bool DumpFile(std::string const& nmPath, const char* filename, CloseHandle(hFileMapping); CloseHandle(hFile); return true; +#endif } bool bindexplib::AddObjectFile(const char* filename) diff --git a/Source/cmAlgorithms.h b/Source/cmAlgorithms.h index e83f160..def3ac7 100644 --- a/Source/cmAlgorithms.h +++ b/Source/cmAlgorithms.h @@ -146,6 +146,14 @@ void cmDeleteAll(Range const& r) } template <typename T> +void cmAppend(std::vector<std::unique_ptr<T>>& v, + std::vector<std::unique_ptr<T>>&& r) +{ + std::transform(r.begin(), r.end(), std::back_inserter(v), + [](std::unique_ptr<T>& item) { return std::move(item); }); +} + +template <typename T> void cmAppend(std::vector<T*>& v, std::vector<std::unique_ptr<T>> const& r) { std::transform(r.begin(), r.end(), std::back_inserter(v), diff --git a/Source/cmForEachCommand.cxx b/Source/cmForEachCommand.cxx index 91cd4ef..ac48287 100644 --- a/Source/cmForEachCommand.cxx +++ b/Source/cmForEachCommand.cxx @@ -3,12 +3,15 @@ #include "cmForEachCommand.h" #include <algorithm> +#include <cassert> #include <cstddef> // NOTE The declaration of `std::abs` has moved to `cmath` since C++17 // See https://en.cppreference.com/w/cpp/numeric/math/abs // ALERT But IWYU used to lint `#include`s do not "understand" // conditional compilation (i.e. `#if __cplusplus >= 201703L`) #include <cstdlib> +#include <iterator> +#include <map> #include <utility> #include <cm/memory> @@ -29,7 +32,7 @@ namespace { class cmForEachFunctionBlocker : public cmFunctionBlocker { public: - cmForEachFunctionBlocker(cmMakefile* mf); + explicit cmForEachFunctionBlocker(cmMakefile* mf); ~cmForEachFunctionBlocker() override; cm::string_view StartCommandName() const override { return "foreach"_s; } @@ -41,10 +44,33 @@ public: bool Replay(std::vector<cmListFileFunction> functions, cmExecutionStatus& inStatus) override; + void SetIterationVarsCount(const std::size_t varsCount) + { + this->IterationVarsCount = varsCount; + } + void SetZipLists() { this->ZipLists = true; } + std::vector<std::string> Args; private: + struct InvokeResult + { + bool Restore; + bool Break; + }; + + bool ReplayItems(std::vector<cmListFileFunction> const& functions, + cmExecutionStatus& inStatus); + + bool ReplayZipLists(std::vector<cmListFileFunction> const& functions, + cmExecutionStatus& inStatus); + + InvokeResult invoke(std::vector<cmListFileFunction> const& functions, + cmExecutionStatus& inStatus, cmMakefile& mf); + cmMakefile* Makefile; + std::size_t IterationVarsCount = 0u; + bool ZipLists = false; }; cmForEachFunctionBlocker::cmForEachFunctionBlocker(cmMakefile* mf) @@ -70,70 +96,240 @@ bool cmForEachFunctionBlocker::ArgumentsMatch(cmListFileFunction const& lff, bool cmForEachFunctionBlocker::Replay( std::vector<cmListFileFunction> functions, cmExecutionStatus& inStatus) { - cmMakefile& mf = inStatus.GetMakefile(); - // at end of for each execute recorded commands + return this->ZipLists ? this->ReplayZipLists(functions, inStatus) + : this->ReplayItems(functions, inStatus); +} + +bool cmForEachFunctionBlocker::ReplayItems( + std::vector<cmListFileFunction> const& functions, + cmExecutionStatus& inStatus) +{ + assert("Unexpected number of iteration variables" && + this->IterationVarsCount == 1); + + auto& mf = inStatus.GetMakefile(); + + // At end of for each execute recorded commands // store the old value std::string oldDef; if (mf.GetDefinition(this->Args.front())) { oldDef = mf.GetDefinition(this->Args.front()); } + auto restore = false; for (std::string const& arg : cmMakeRange(this->Args).advance(1)) { - // set the variable to the loop value + // Set the variable to the loop value mf.AddDefinition(this->Args.front(), arg); // Invoke all the functions that were collected in the block. - for (cmListFileFunction const& func : functions) { - cmExecutionStatus status(mf); - mf.ExecuteCommand(func, status); - if (status.GetReturnInvoked()) { - inStatus.SetReturnInvoked(); - // restore the variable to its prior value - mf.AddDefinition(this->Args.front(), oldDef); - return true; - } - if (status.GetBreakInvoked()) { - // restore the variable to its prior value - mf.AddDefinition(this->Args.front(), oldDef); - return true; - } - if (status.GetContinueInvoked()) { - break; - } - if (cmSystemTools::GetFatalErrorOccured()) { - return true; + auto r = this->invoke(functions, inStatus, mf); + restore = r.Restore; + if (r.Break) { + break; + } + } + + if (restore) { + // restore the variable to its prior value + mf.AddDefinition(this->Args.front(), oldDef); + } + return true; +} + +bool cmForEachFunctionBlocker::ReplayZipLists( + std::vector<cmListFileFunction> const& functions, + cmExecutionStatus& inStatus) +{ + assert("Unexpected number of iteration variables" && + this->IterationVarsCount >= 1); + + auto& mf = inStatus.GetMakefile(); + + // Expand the list of list-variables into a list of lists of strings + std::vector<std::vector<std::string>> values; + values.reserve(this->Args.size() - this->IterationVarsCount); + // Also track the longest list size + std::size_t maxItems = 0u; + for (auto const& var : + cmMakeRange(this->Args).advance(this->IterationVarsCount)) { + std::vector<std::string> items; + auto const& value = mf.GetSafeDefinition(var); + if (!value.empty()) { + cmExpandList(value, items, true); + } + maxItems = std::max(maxItems, items.size()); + values.emplace_back(std::move(items)); + } + + // Form the list of iteration variables + std::vector<std::string> iterationVars; + if (this->IterationVarsCount > 1) { + // If multiple iteration variables has given, + // just copy them to the `iterationVars` list. + iterationVars.reserve(values.size()); + std::copy(this->Args.begin(), + this->Args.begin() + this->IterationVarsCount, + std::back_inserter(iterationVars)); + } else { + // In case of the only iteration variable, + // generate names as `var_name_N`, + // where `N` is the count of lists to zip + iterationVars.resize(values.size()); + const auto iter_var_prefix = this->Args.front() + "_"; + auto i = 0u; + std::generate( + iterationVars.begin(), iterationVars.end(), + [&]() -> std::string { return iter_var_prefix + std::to_string(i++); }); + } + assert("Sanity check" && iterationVars.size() == values.size()); + + // Store old values for iteration variables + std::map<std::string, std::string> oldDefs; + for (auto i = 0u; i < values.size(); ++i) { + if (mf.GetDefinition(iterationVars[i])) { + oldDefs.emplace(iterationVars[i], mf.GetDefinition(iterationVars[i])); + } + } + + // Form a vector of current positions in all lists (Ok, vectors) of values + std::vector<decltype(values)::value_type::iterator> positions; + positions.reserve(values.size()); + std::transform( + values.begin(), values.end(), std::back_inserter(positions), + // Set the initial position to the beginning of every list + [](decltype(values)::value_type& list) { return list.begin(); }); + assert("Sanity check" && positions.size() == values.size()); + + auto restore = false; + // Iterate over all the lists simulateneously + for (auto i = 0u; i < maxItems; ++i) { + // Declare iteration variables + for (auto j = 0u; j < values.size(); ++j) { + // Define (or not) the iteration variable if the current position + // still not at the end... + if (positions[j] != values[j].end()) { + mf.AddDefinition(iterationVars[j], *positions[j]); + ++positions[j]; + } else { + mf.RemoveDefinition(iterationVars[j]); } } + // Invoke all the functions that were collected in the block. + auto r = this->invoke(functions, inStatus, mf); + restore = r.Restore; + if (r.Break) { + break; + } } - // restore the variable to its prior value - mf.AddDefinition(this->Args.front(), oldDef); + // Restore the variables to its prior value + if (restore) { + for (auto const& p : oldDefs) { + mf.AddDefinition(p.first, p.second); + } + } return true; } -bool HandleInMode(std::vector<std::string> const& args, cmMakefile& makefile) +auto cmForEachFunctionBlocker::invoke( + std::vector<cmListFileFunction> const& functions, + cmExecutionStatus& inStatus, cmMakefile& mf) -> InvokeResult +{ + InvokeResult result = { true, false }; + // Invoke all the functions that were collected in the block. + for (cmListFileFunction const& func : functions) { + cmExecutionStatus status(mf); + mf.ExecuteCommand(func, status); + if (status.GetReturnInvoked()) { + inStatus.SetReturnInvoked(); + result.Break = true; + break; + } + if (status.GetBreakInvoked()) { + result.Break = true; + break; + } + if (status.GetContinueInvoked()) { + break; + } + if (cmSystemTools::GetFatalErrorOccured()) { + result.Restore = false; + result.Break = true; + break; + } + } + return result; +} + +bool HandleInMode(std::vector<std::string> const& args, + std::vector<std::string>::const_iterator kwInIter, + cmMakefile& makefile) { + assert("A valid iterator expected" && kwInIter != args.end()); + auto fb = cm::make_unique<cmForEachFunctionBlocker>(&makefile); - fb->Args.push_back(args.front()); + + // Copy iteration variable names first + std::copy(args.begin(), kwInIter, std::back_inserter(fb->Args)); + // Remember the count of given iteration variable names + const auto varsCount = fb->Args.size(); + fb->SetIterationVarsCount(varsCount); enum Doing { DoingNone, DoingLists, - DoingItems + DoingItems, + DoingZipLists }; Doing doing = DoingNone; - for (std::string const& arg : cmMakeRange(args).advance(2)) { + // Iterate over arguments past the "IN" keyword + for (std::string const& arg : cmMakeRange(++kwInIter, args.end())) { if (arg == "LISTS") { + if (doing == DoingZipLists) { + makefile.IssueMessage(MessageType::FATAL_ERROR, + "ZIP_LISTS can not be used with LISTS or ITEMS"); + return true; + } + if (varsCount != 1u) { + makefile.IssueMessage( + MessageType::FATAL_ERROR, + "ITEMS or LISTS require exactly one iteration variable"); + return true; + } doing = DoingLists; + } else if (arg == "ITEMS") { + if (doing == DoingZipLists) { + makefile.IssueMessage(MessageType::FATAL_ERROR, + "ZIP_LISTS can not be used with LISTS or ITEMS"); + return true; + } + if (varsCount != 1u) { + makefile.IssueMessage( + MessageType::FATAL_ERROR, + "ITEMS or LISTS require exactly one iteration variable"); + return true; + } doing = DoingItems; + + } else if (arg == "ZIP_LISTS") { + if (doing != DoingNone) { + makefile.IssueMessage(MessageType::FATAL_ERROR, + "ZIP_LISTS can not be used with LISTS or ITEMS"); + return true; + } + doing = DoingZipLists; + fb->SetZipLists(); + } else if (doing == DoingLists) { auto const& value = makefile.GetSafeDefinition(arg); if (!value.empty()) { cmExpandList(value, fb->Args, true); } - } else if (doing == DoingItems) { + + } else if (doing == DoingItems || doing == DoingZipLists) { fb->Args.push_back(arg); + } else { makefile.IssueMessage(MessageType::FATAL_ERROR, cmStrCat("Unknown argument:\n", " ", arg, "\n")); @@ -141,6 +337,18 @@ bool HandleInMode(std::vector<std::string> const& args, cmMakefile& makefile) } } + // If `ZIP_LISTS` given and variables count more than 1, + // make sure the given lists count matches variables... + if (doing == DoingZipLists && varsCount > 1u && + (2u * varsCount) != fb->Args.size()) { + makefile.IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("Expected ", std::to_string(varsCount), + " list variables, but given ", + std::to_string(fb->Args.size() - varsCount))); + return true; + } + makefile.AddFunctionBlocker(std::move(fb)); return true; @@ -155,8 +363,9 @@ bool cmForEachCommand(std::vector<std::string> const& args, status.SetError("called with incorrect number of arguments"); return false; } - if (args.size() > 1 && args[1] == "IN") { - return HandleInMode(args, status.GetMakefile()); + auto kwInIter = std::find(args.begin(), args.end(), "IN"); + if (kwInIter != args.end()) { + return HandleInMode(args, kwInIter, status.GetMakefile()); } // create a function blocker @@ -216,6 +425,8 @@ bool cmForEachCommand(std::vector<std::string> const& args, } else { fb->Args = args; } + + fb->SetIterationVarsCount(1u); status.GetMakefile().AddFunctionBlocker(std::move(fb)); return true; diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx index de43d3e..81d1e46 100644 --- a/Source/cmGeneratorExpression.cxx +++ b/Source/cmGeneratorExpression.cxx @@ -8,7 +8,6 @@ #include "cmsys/RegularExpression.hxx" -#include "cmAlgorithms.h" #include "cmGeneratorExpressionContext.h" #include "cmGeneratorExpressionDAGChecker.h" #include "cmGeneratorExpressionEvaluator.h" @@ -22,6 +21,8 @@ cmGeneratorExpression::cmGeneratorExpression(cmListFileBacktrace backtrace) { } +cmCompiledGeneratorExpression::~cmCompiledGeneratorExpression() = default; + cmGeneratorExpression::~cmGeneratorExpression() = default; std::unique_ptr<cmCompiledGeneratorExpression> cmGeneratorExpression::Parse( @@ -86,7 +87,7 @@ const std::string& cmCompiledGeneratorExpression::EvaluateWithContext( this->Output.clear(); - for (const cmGeneratorExpressionEvaluator* it : this->Evaluators) { + for (const auto& it : this->Evaluators) { this->Output += it->Evaluate(&context, dagChecker); this->SeenTargetProperties.insert(context.SeenTargetProperties.cbegin(), @@ -129,11 +130,6 @@ cmCompiledGeneratorExpression::cmCompiledGeneratorExpression( } } -cmCompiledGeneratorExpression::~cmCompiledGeneratorExpression() -{ - cmDeleteAll(this->Evaluators); -} - std::string cmGeneratorExpression::StripEmptyListElements( const std::string& input) { diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h index cd35e1e..c4be3a1 100644 --- a/Source/cmGeneratorExpression.h +++ b/Source/cmGeneratorExpression.h @@ -163,7 +163,7 @@ private: friend class cmGeneratorExpression; cmListFileBacktrace Backtrace; - std::vector<cmGeneratorExpressionEvaluator*> Evaluators; + std::vector<std::unique_ptr<cmGeneratorExpressionEvaluator>> Evaluators; const std::string Input; bool NeedsEvaluation; bool EvaluateForBuildsystem; diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index e0ae170..4129a0c 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -2,10 +2,8 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmGeneratorExpressionEvaluator.h" -#include <algorithm> #include <sstream> -#include "cmAlgorithms.h" #include "cmGeneratorExpressionContext.h" #include "cmGeneratorExpressionNode.h" @@ -16,6 +14,8 @@ GeneratorExpressionContent::GeneratorExpressionContent( { } +GeneratorExpressionContent::~GeneratorExpressionContent() = default; + std::string GeneratorExpressionContent::GetOriginalExpression() const { return std::string(this->StartContent, this->ContentLength); @@ -25,14 +25,13 @@ std::string GeneratorExpressionContent::ProcessArbitraryContent( const cmGeneratorExpressionNode* node, const std::string& identifier, cmGeneratorExpressionContext* context, cmGeneratorExpressionDAGChecker* dagChecker, - std::vector<std::vector<cmGeneratorExpressionEvaluator*>>::const_iterator - pit) const + std::vector<cmGeneratorExpressionEvaluatorVector>::const_iterator pit) const { std::string result; const auto pend = this->ParamChildren.end(); for (; pit != pend; ++pit) { - for (cmGeneratorExpressionEvaluator* pExprEval : *pit) { + for (auto& pExprEval : *pit) { if (node->RequiresLiteralInput()) { if (pExprEval->GetType() != cmGeneratorExpressionEvaluator::Text) { reportError(context, this->GetOriginalExpression(), @@ -64,8 +63,7 @@ std::string GeneratorExpressionContent::Evaluate( { std::string identifier; { - for (cmGeneratorExpressionEvaluator* pExprEval : - this->IdentifierChildren) { + for (auto& pExprEval : this->IdentifierChildren) { identifier += pExprEval->Evaluate(context, dagChecker); if (context->HadError) { return std::string(); @@ -126,7 +124,7 @@ std::string GeneratorExpressionContent::EvaluateParameters( return std::string(); } std::string parameter; - for (cmGeneratorExpressionEvaluator* pExprEval : *pit) { + for (auto& pExprEval : *pit) { parameter += pExprEval->Evaluate(context, dagChecker); if (context->HadError) { return std::string(); @@ -174,10 +172,3 @@ std::string GeneratorExpressionContent::EvaluateParameters( } return std::string(); } - -GeneratorExpressionContent::~GeneratorExpressionContent() -{ - cmDeleteAll(this->IdentifierChildren); - std::for_each(this->ParamChildren.begin(), this->ParamChildren.end(), - cmDeleteAll<std::vector<cmGeneratorExpressionEvaluator*>>); -} diff --git a/Source/cmGeneratorExpressionEvaluator.h b/Source/cmGeneratorExpressionEvaluator.h index b10bb5b..10496fd 100644 --- a/Source/cmGeneratorExpressionEvaluator.h +++ b/Source/cmGeneratorExpressionEvaluator.h @@ -6,6 +6,7 @@ #include "cmConfigure.h" // IWYU pragma: keep #include <cstddef> +#include <memory> #include <string> #include <utility> #include <vector> @@ -36,6 +37,9 @@ struct cmGeneratorExpressionEvaluator cmGeneratorExpressionDAGChecker*) const = 0; }; +using cmGeneratorExpressionEvaluatorVector = + std::vector<std::unique_ptr<cmGeneratorExpressionEvaluator>>; + struct TextContent : public cmGeneratorExpressionEvaluator { TextContent(const char* start, size_t length) @@ -68,13 +72,13 @@ struct GeneratorExpressionContent : public cmGeneratorExpressionEvaluator { GeneratorExpressionContent(const char* startContent, size_t length); - void SetIdentifier(std::vector<cmGeneratorExpressionEvaluator*> identifier) + void SetIdentifier(cmGeneratorExpressionEvaluatorVector&& identifier) { this->IdentifierChildren = std::move(identifier); } void SetParameters( - std::vector<std::vector<cmGeneratorExpressionEvaluator*>> parameters) + std::vector<cmGeneratorExpressionEvaluatorVector>&& parameters) { this->ParamChildren = std::move(parameters); } @@ -102,12 +106,12 @@ private: const cmGeneratorExpressionNode* node, const std::string& identifier, cmGeneratorExpressionContext* context, cmGeneratorExpressionDAGChecker* dagChecker, - std::vector<std::vector<cmGeneratorExpressionEvaluator*>>::const_iterator - pit) const; + std::vector<cmGeneratorExpressionEvaluatorVector>::const_iterator pit) + const; private: - std::vector<cmGeneratorExpressionEvaluator*> IdentifierChildren; - std::vector<std::vector<cmGeneratorExpressionEvaluator*>> ParamChildren; + cmGeneratorExpressionEvaluatorVector IdentifierChildren; + std::vector<cmGeneratorExpressionEvaluatorVector> ParamChildren; const char* StartContent; size_t ContentLength; }; diff --git a/Source/cmGeneratorExpressionParser.cxx b/Source/cmGeneratorExpressionParser.cxx index d6cc6ab..4159a7b 100644 --- a/Source/cmGeneratorExpressionParser.cxx +++ b/Source/cmGeneratorExpressionParser.cxx @@ -6,6 +6,9 @@ #include <cstddef> #include <utility> +#include <cm/memory> +#include <cmext/memory> + #include "cmAlgorithms.h" #include "cmGeneratorExpressionEvaluator.h" @@ -17,7 +20,7 @@ cmGeneratorExpressionParser::cmGeneratorExpressionParser( } void cmGeneratorExpressionParser::Parse( - std::vector<cmGeneratorExpressionEvaluator*>& result) + cmGeneratorExpressionEvaluatorVector& result) { it = this->Tokens.begin(); @@ -27,40 +30,38 @@ void cmGeneratorExpressionParser::Parse( } static void extendText( - std::vector<cmGeneratorExpressionEvaluator*>& result, + cmGeneratorExpressionEvaluatorVector& result, std::vector<cmGeneratorExpressionToken>::const_iterator it) { if (!result.empty() && (*(result.end() - 1))->GetType() == cmGeneratorExpressionEvaluator::Text) { - TextContent* textContent = static_cast<TextContent*>(*(result.end() - 1)); - textContent->Extend(it->Length); + cm::static_reference_cast<TextContent>(*(result.end() - 1)) + .Extend(it->Length); } else { - TextContent* textContent = new TextContent(it->Content, it->Length); - result.push_back(textContent); + auto textContent = cm::make_unique<TextContent>(it->Content, it->Length); + result.push_back(std::move(textContent)); } } static void extendResult( - std::vector<cmGeneratorExpressionEvaluator*>& result, - const std::vector<cmGeneratorExpressionEvaluator*>& contents) + cmGeneratorExpressionParser::cmGeneratorExpressionEvaluatorVector& result, + cmGeneratorExpressionParser::cmGeneratorExpressionEvaluatorVector&& contents) { if (!result.empty() && (*(result.end() - 1))->GetType() == cmGeneratorExpressionEvaluator::Text && contents.front()->GetType() == cmGeneratorExpressionEvaluator::Text) { - TextContent* textContent = static_cast<TextContent*>(*(result.end() - 1)); - textContent->Extend( - static_cast<TextContent*>(contents.front())->GetLength()); - delete contents.front(); - cmAppend(result, contents.begin() + 1, contents.end()); - } else { - cmAppend(result, contents); + cm::static_reference_cast<TextContent>(*(result.end() - 1)) + .Extend( + cm::static_reference_cast<TextContent>(contents.front()).GetLength()); + contents.erase(contents.begin()); } + cmAppend(result, std::move(contents)); } void cmGeneratorExpressionParser::ParseGeneratorExpression( - std::vector<cmGeneratorExpressionEvaluator*>& result) + cmGeneratorExpressionEvaluatorVector& result) { assert(this->it != this->Tokens.end()); unsigned int nestedLevel = this->NestingLevel; @@ -68,7 +69,7 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression( auto startToken = this->it - 1; - std::vector<cmGeneratorExpressionEvaluator*> identifier; + cmGeneratorExpressionEvaluatorVector identifier; while (this->it->TokenType != cmGeneratorExpressionToken::EndExpression && this->it->TokenType != cmGeneratorExpressionToken::ColonSeparator) { if (this->it->TokenType == cmGeneratorExpressionToken::CommaSeparator) { @@ -87,18 +88,18 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression( if (this->it != this->Tokens.end() && this->it->TokenType == cmGeneratorExpressionToken::EndExpression) { - GeneratorExpressionContent* content = new GeneratorExpressionContent( + auto content = cm::make_unique<GeneratorExpressionContent>( startToken->Content, this->it->Content - startToken->Content + this->it->Length); assert(this->it != this->Tokens.end()); ++this->it; --this->NestingLevel; content->SetIdentifier(std::move(identifier)); - result.push_back(content); + result.push_back(std::move(content)); return; } - std::vector<std::vector<cmGeneratorExpressionEvaluator*>> parameters; + std::vector<cmGeneratorExpressionEvaluatorVector> parameters; std::vector<std::vector<cmGeneratorExpressionToken>::const_iterator> commaTokens; std::vector<cmGeneratorExpressionToken>::const_iterator colonToken; @@ -169,7 +170,7 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression( // treat the '$<' as having been plain text, along with the // corresponding : and , tokens that might have been found. extendText(result, startToken); - extendResult(result, identifier); + extendResult(result, std::move(identifier)); if (!parameters.empty()) { extendText(result, colonToken); @@ -179,7 +180,7 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression( assert(parameters.size() > commaTokens.size()); for (; pit != pend; ++pit, ++commaIt) { if (!pit->empty() && !emptyParamTermination) { - extendResult(result, *pit); + extendResult(result, std::move(*pit)); } if (commaIt != commaTokens.end()) { extendText(result, *commaIt); @@ -193,15 +194,15 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression( size_t contentLength = ((this->it - 1)->Content - startToken->Content) + (this->it - 1)->Length; - GeneratorExpressionContent* content = - new GeneratorExpressionContent(startToken->Content, contentLength); + auto content = cm::make_unique<GeneratorExpressionContent>( + startToken->Content, contentLength); content->SetIdentifier(std::move(identifier)); content->SetParameters(std::move(parameters)); - result.push_back(content); + result.push_back(std::move(content)); } void cmGeneratorExpressionParser::ParseContent( - std::vector<cmGeneratorExpressionEvaluator*>& result) + cmGeneratorExpressionEvaluatorVector& result) { assert(this->it != this->Tokens.end()); switch (this->it->TokenType) { @@ -213,17 +214,16 @@ void cmGeneratorExpressionParser::ParseContent( // A comma in 'plain text' could have split text that should // otherwise be continuous. Extend the last text content instead of // creating a new one. - TextContent* textContent = - static_cast<TextContent*>(*(result.end() - 1)); - textContent->Extend(this->it->Length); + cm::static_reference_cast<TextContent>(*(result.end() - 1)) + .Extend(this->it->Length); assert(this->it != this->Tokens.end()); ++this->it; return; } } - cmGeneratorExpressionEvaluator* n = - new TextContent(this->it->Content, this->it->Length); - result.push_back(n); + auto n = + cm::make_unique<TextContent>(this->it->Content, this->it->Length); + result.push_back(std::move(n)); assert(this->it != this->Tokens.end()); ++this->it; return; diff --git a/Source/cmGeneratorExpressionParser.h b/Source/cmGeneratorExpressionParser.h index e663496..1ba1654 100644 --- a/Source/cmGeneratorExpressionParser.h +++ b/Source/cmGeneratorExpressionParser.h @@ -5,6 +5,7 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include <memory> #include <vector> #include "cmGeneratorExpressionLexer.h" @@ -15,11 +16,14 @@ struct cmGeneratorExpressionParser { cmGeneratorExpressionParser(std::vector<cmGeneratorExpressionToken> tokens); - void Parse(std::vector<cmGeneratorExpressionEvaluator*>& result); + using cmGeneratorExpressionEvaluatorVector = + std::vector<std::unique_ptr<cmGeneratorExpressionEvaluator>>; + + void Parse(cmGeneratorExpressionEvaluatorVector& result); private: - void ParseContent(std::vector<cmGeneratorExpressionEvaluator*>&); - void ParseGeneratorExpression(std::vector<cmGeneratorExpressionEvaluator*>&); + void ParseContent(cmGeneratorExpressionEvaluatorVector&); + void ParseGeneratorExpression(cmGeneratorExpressionEvaluatorVector&); private: std::vector<cmGeneratorExpressionToken>::const_iterator it; diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 29593d9..a4a074f 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -2513,11 +2513,11 @@ void cmGeneratorTarget::ComputeModuleDefinitionInfo( info.WindowsExportAllSymbols = this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS") && this->GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS"); -#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP) +#if !defined(CMAKE_BOOTSTRAP) info.DefFileGenerated = info.WindowsExportAllSymbols || info.Sources.size() > 1; #else - // Our __create_def helper is only available on Windows. + // Our __create_def helper is not available during CMake bootstrap. info.DefFileGenerated = false; #endif if (info.DefFileGenerated) { diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 8dfc0ce..0e782f2 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -1566,13 +1566,24 @@ bool cmGlobalGenerator::AddAutomaticSources() for (cmLocalGenerator* lg : this->LocalGenerators) { lg->CreateEvaluationFileOutputs(); for (const auto& gt : lg->GetGeneratorTargets()) { - if (gt->GetType() == cmStateEnums::INTERFACE_LIBRARY) { + if (gt->GetType() == cmStateEnums::INTERFACE_LIBRARY || + gt->GetType() == cmStateEnums::UTILITY || + gt->GetType() == cmStateEnums::GLOBAL_TARGET) { continue; } lg->AddUnityBuild(gt.get()); lg->AddPchDependencies(gt.get()); } } + // The above transformations may have changed the classification of sources. + // Clear the source list and classification cache (KindedSources) of all + // targets so that it will be recomputed correctly by the generators later + // now that the above transformations are done for all targets. + for (cmLocalGenerator* lg : this->LocalGenerators) { + for (const auto& gt : lg->GetGeneratorTargets()) { + gt->ClearSourcesCache(); + } + } return true; } diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 7451ff3..c58603f 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -2393,6 +2393,7 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target) } const std::string buildType = cmSystemTools::UpperCase(config); + // FIXME: Refactor collection of sources to not evaluate object libraries. std::vector<cmSourceFile*> sources; target->GetSourceFiles(sources, buildType); @@ -2467,9 +2468,25 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target) target->GetLocalGenerator()->GetCurrentBinaryDirectory(), "/", target->GetName(), ".dir/${PDB_PREFIX}"); - file << "if (EXISTS \"" << from_file << "\")\n"; + const std::string to_file = + cmStrCat(to_dir, pchReuseFrom, extension); + + std::string dest_file = to_file; + + const std::string prefix = target->GetSafeProperty("PREFIX"); + if (!prefix.empty()) { + dest_file = cmStrCat(to_dir, prefix, pchReuseFrom, extension); + } + + file << "if (EXISTS \"" << from_file << "\" AND \"" << from_file + << "\" IS_NEWER_THAN \"" << dest_file << "\")\n"; file << " file(COPY \"" << from_file << "\"" << " DESTINATION \"" << to_dir << "\")\n"; + if (!prefix.empty()) { + file << " file(REMOVE \"" << dest_file << "\")\n"; + file << " file(RENAME \"" << to_file << "\" \"" << dest_file + << "\")\n"; + } file << "endif()\n"; } @@ -2549,6 +2566,7 @@ void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target) cmStrCat(this->GetCurrentBinaryDirectory(), "/CMakeFiles/", target->GetName(), ".dir/Unity/"); + // FIXME: Refactor collection of sources to not evaluate object libraries. std::vector<cmSourceFile*> sources; target->GetSourceFiles(sources, buildType); @@ -2598,12 +2616,7 @@ void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target) for (; begin != end; ++begin) { cmSourceFile* sf = filtered_sources[begin]; - // Only in Visual Studio generator we keep the source files - // for explicit processing. - if (!this->GetGlobalGenerator()->IsMultiConfig() || - this->GetGlobalGenerator()->IsXcode()) { - target->AddSourceFileToUnityBatch(sf->ResolveFullPath()); - } + target->AddSourceFileToUnityBatch(sf->ResolveFullPath()); sf->SetProperty("UNITY_SOURCE_FILE", filename.c_str()); if (beforeInclude) { diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 5ffa576..8fc40a79 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -2160,7 +2160,6 @@ void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0) this->WriteExtraSource(e1, si.Source); break; case cmGeneratorTarget::SourceKindHeader: - case cmGeneratorTarget::SourceKindUnityBatched: this->WriteHeaderSource(e1, si.Source); break; case cmGeneratorTarget::SourceKindIDL: @@ -2172,6 +2171,7 @@ void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0) case cmGeneratorTarget::SourceKindModuleDefinition: tool = "None"; break; + case cmGeneratorTarget::SourceKindUnityBatched: case cmGeneratorTarget::SourceKindObjectSource: { const std::string& lang = si.Source->GetLanguage(); if (lang == "C" || lang == "CXX") { diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index c2fbb43..d6df49c 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -21,16 +21,15 @@ #if !defined(CMAKE_BOOTSTRAP) # include "cmDependsFortran.h" // For -E cmake_copy_f90_mod callback. +# include "cmFileTime.h" # include "cmServer.h" # include "cmServerConnection.h" + +# include "bindexplib.h" #endif #if !defined(CMAKE_BOOTSTRAP) && defined(_WIN32) # include "cmsys/ConsoleBuf.hxx" - -# include "cmFileTime.h" - -# include "bindexplib.h" #endif #if !defined(CMAKE_BOOTSTRAP) && defined(_WIN32) && !defined(__CYGWIN__) @@ -581,11 +580,11 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args) return 0; } -#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP) - else if (args[1] == "__create_def") { +#if !defined(CMAKE_BOOTSTRAP) + if (args[1] == "__create_def") { if (args.size() < 4) { std::cerr << "__create_def Usage: -E __create_def outfile.def " - "objlistfile [-nm=nm-path]\n"; + "objlistfile [--nm=nm-path]\n"; return 1; } cmsys::ifstream fin(args[3].c_str(), std::ios::in | std::ios::binary); @@ -612,7 +611,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args) return 0; } } - FILE* fout = cmsys::SystemTools::Fopen(args[2].c_str(), "w+"); + FILE* fout = cmsys::SystemTools::Fopen(args[2], "w+"); if (!fout) { std::cerr << "could not open output .def file: " << args[2].c_str() << "\n"; diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index b45782e..0d9e43f 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1405,6 +1405,7 @@ ${CMake_SOURCE_DIR}/Utilities/Release/push.bash --dir dev -- '${CMake_BUILD_NIGH ICU JPEG JsonCpp + LibArchive LibLZMA LibRHash Libinput diff --git a/Tests/FindLibArchive/CMakeLists.txt b/Tests/FindLibArchive/CMakeLists.txt new file mode 100644 index 0000000..f532ef2 --- /dev/null +++ b/Tests/FindLibArchive/CMakeLists.txt @@ -0,0 +1,10 @@ +add_test(NAME FindLibArchive.Test COMMAND + ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> + --build-and-test + "${CMake_SOURCE_DIR}/Tests/FindLibArchive/Test" + "${CMake_BINARY_DIR}/Tests/FindLibArchive/Test" + ${build_generator_args} + --build-project TestFindLibArchive + --build-options ${build_options} + --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION> + ) diff --git a/Tests/FindLibArchive/Test/CMakeLists.txt b/Tests/FindLibArchive/Test/CMakeLists.txt new file mode 100644 index 0000000..35843bb --- /dev/null +++ b/Tests/FindLibArchive/Test/CMakeLists.txt @@ -0,0 +1,14 @@ +cmake_minimum_required(VERSION 3.12) +project(TestFindLibArchive C) +include(CTest) + +find_package(LibArchive REQUIRED) + +add_executable(test_libarchive_tgt main.c) +target_link_libraries(test_libarchive_tgt LibArchive::LibArchive) +add_test(NAME test_libarchive_tgt COMMAND test_libarchive_tgt) + +add_executable(test_libarchive_var main.c) +target_include_directories(test_libarchive_var PRIVATE ${LibArchive_INCLUDE_DIRS}) +target_link_libraries(test_libarchive_var PRIVATE ${LibArchive_LIBRARIES}) +add_test(NAME test_libarchive_var COMMAND test_libarchive_var) diff --git a/Tests/FindLibArchive/Test/main.c b/Tests/FindLibArchive/Test/main.c new file mode 100644 index 0000000..03e7ece --- /dev/null +++ b/Tests/FindLibArchive/Test/main.c @@ -0,0 +1,7 @@ +#include <archive.h> + +int main(void) +{ + archive_read_free(archive_read_new()); + return 0; +} diff --git a/Tests/RunCMake/CompilerLauncher/C-common.cmake b/Tests/RunCMake/CompilerLauncher/C-common.cmake new file mode 100644 index 0000000..96b004b --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/C-common.cmake @@ -0,0 +1,3 @@ +enable_language(C) +set(CMAKE_VERBOSE_MAKEFILE TRUE) +add_executable(main main.c) diff --git a/Tests/RunCMake/CompilerLauncher/C-env-Build-stdout.txt b/Tests/RunCMake/CompilerLauncher/C-env-Build-stdout.txt new file mode 100644 index 0000000..3313e31 --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/C-env-Build-stdout.txt @@ -0,0 +1 @@ +.*-E env USED_LAUNCHER=1.* diff --git a/Tests/RunCMake/CompilerLauncher/C-env-launch-Build-stdout.txt b/Tests/RunCMake/CompilerLauncher/C-env-launch-Build-stdout.txt new file mode 100644 index 0000000..3313e31 --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/C-env-launch-Build-stdout.txt @@ -0,0 +1 @@ +.*-E env USED_LAUNCHER=1.* diff --git a/Tests/RunCMake/CompilerLauncher/C-env.cmake b/Tests/RunCMake/CompilerLauncher/C-env.cmake new file mode 100644 index 0000000..09b5167 --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/C-env.cmake @@ -0,0 +1 @@ +include(C-common.cmake) diff --git a/Tests/RunCMake/CompilerLauncher/C-launch-env.cmake b/Tests/RunCMake/CompilerLauncher/C-launch-env.cmake new file mode 100644 index 0000000..68abcb5 --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/C-launch-env.cmake @@ -0,0 +1,3 @@ +set(CTEST_USE_LAUNCHERS 1) +include(CTestUseLaunchers) +include(C-env.cmake) diff --git a/Tests/RunCMake/CompilerLauncher/C.cmake b/Tests/RunCMake/CompilerLauncher/C.cmake index 67bf7c4..481e74d 100644 --- a/Tests/RunCMake/CompilerLauncher/C.cmake +++ b/Tests/RunCMake/CompilerLauncher/C.cmake @@ -1,4 +1,2 @@ -enable_language(C) set(CMAKE_C_COMPILER_LAUNCHER "${CMAKE_COMMAND};-E;env;USED_LAUNCHER=1") -set(CMAKE_VERBOSE_MAKEFILE TRUE) -add_executable(main main.c) +include(C-common.cmake) diff --git a/Tests/RunCMake/CompilerLauncher/CUDA-common.cmake b/Tests/RunCMake/CompilerLauncher/CUDA-common.cmake new file mode 100644 index 0000000..6f7fc86 --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/CUDA-common.cmake @@ -0,0 +1,3 @@ +enable_language(CUDA) +set(CMAKE_VERBOSE_MAKEFILE TRUE) +add_executable(main main.cu) diff --git a/Tests/RunCMake/CompilerLauncher/CUDA-env-Build-stdout.txt b/Tests/RunCMake/CompilerLauncher/CUDA-env-Build-stdout.txt new file mode 100644 index 0000000..3313e31 --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/CUDA-env-Build-stdout.txt @@ -0,0 +1 @@ +.*-E env USED_LAUNCHER=1.* diff --git a/Tests/RunCMake/CompilerLauncher/CUDA-env-launch-Build-stdout.txt b/Tests/RunCMake/CompilerLauncher/CUDA-env-launch-Build-stdout.txt new file mode 100644 index 0000000..3313e31 --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/CUDA-env-launch-Build-stdout.txt @@ -0,0 +1 @@ +.*-E env USED_LAUNCHER=1.* diff --git a/Tests/RunCMake/CompilerLauncher/CUDA-env.cmake b/Tests/RunCMake/CompilerLauncher/CUDA-env.cmake new file mode 100644 index 0000000..cefbe9e --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/CUDA-env.cmake @@ -0,0 +1 @@ +include(CUDA-common.cmake) diff --git a/Tests/RunCMake/CompilerLauncher/CUDA-launch-env.cmake b/Tests/RunCMake/CompilerLauncher/CUDA-launch-env.cmake new file mode 100644 index 0000000..d0d777a --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/CUDA-launch-env.cmake @@ -0,0 +1,3 @@ +set(CTEST_USE_LAUNCHERS 1) +include(CTestUseLaunchers) +include(CUDA-env.cmake) diff --git a/Tests/RunCMake/CompilerLauncher/CUDA.cmake b/Tests/RunCMake/CompilerLauncher/CUDA.cmake index fe5560b..7f1652b 100644 --- a/Tests/RunCMake/CompilerLauncher/CUDA.cmake +++ b/Tests/RunCMake/CompilerLauncher/CUDA.cmake @@ -1,4 +1,2 @@ -enable_language(CUDA) set(CMAKE_CUDA_COMPILER_LAUNCHER "${CMAKE_COMMAND};-E;env;USED_LAUNCHER=1") -set(CMAKE_VERBOSE_MAKEFILE TRUE) -add_executable(main main.cu) +include(CUDA-common.cmake) diff --git a/Tests/RunCMake/CompilerLauncher/CXX-common.cmake b/Tests/RunCMake/CompilerLauncher/CXX-common.cmake new file mode 100644 index 0000000..3d2ee00 --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/CXX-common.cmake @@ -0,0 +1,3 @@ +enable_language(CXX) +set(CMAKE_VERBOSE_MAKEFILE TRUE) +add_executable(main main.cxx) diff --git a/Tests/RunCMake/CompilerLauncher/CXX-env-Build-stdout.txt b/Tests/RunCMake/CompilerLauncher/CXX-env-Build-stdout.txt new file mode 100644 index 0000000..3313e31 --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/CXX-env-Build-stdout.txt @@ -0,0 +1 @@ +.*-E env USED_LAUNCHER=1.* diff --git a/Tests/RunCMake/CompilerLauncher/CXX-env-launch-Build-stdout.txt b/Tests/RunCMake/CompilerLauncher/CXX-env-launch-Build-stdout.txt new file mode 100644 index 0000000..3313e31 --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/CXX-env-launch-Build-stdout.txt @@ -0,0 +1 @@ +.*-E env USED_LAUNCHER=1.* diff --git a/Tests/RunCMake/CompilerLauncher/CXX-env.cmake b/Tests/RunCMake/CompilerLauncher/CXX-env.cmake new file mode 100644 index 0000000..db36956 --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/CXX-env.cmake @@ -0,0 +1 @@ +include(CXX-common.cmake) diff --git a/Tests/RunCMake/CompilerLauncher/CXX-launch-env.cmake b/Tests/RunCMake/CompilerLauncher/CXX-launch-env.cmake new file mode 100644 index 0000000..a65cc89 --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/CXX-launch-env.cmake @@ -0,0 +1,3 @@ +set(CTEST_USE_LAUNCHERS 1) +include(CTestUseLaunchers) +include(CXX-env.cmake) diff --git a/Tests/RunCMake/CompilerLauncher/CXX.cmake b/Tests/RunCMake/CompilerLauncher/CXX.cmake index cdd3478..1f9a12b 100644 --- a/Tests/RunCMake/CompilerLauncher/CXX.cmake +++ b/Tests/RunCMake/CompilerLauncher/CXX.cmake @@ -1,4 +1,2 @@ -enable_language(CXX) set(CMAKE_CXX_COMPILER_LAUNCHER "${CMAKE_COMMAND};-E;env;USED_LAUNCHER=1") -set(CMAKE_VERBOSE_MAKEFILE TRUE) -add_executable(main main.cxx) +include(CXX-common.cmake) diff --git a/Tests/RunCMake/CompilerLauncher/Fortran-common.cmake b/Tests/RunCMake/CompilerLauncher/Fortran-common.cmake new file mode 100644 index 0000000..e33c2ca --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/Fortran-common.cmake @@ -0,0 +1,3 @@ +enable_language(Fortran) +set(CMAKE_VERBOSE_MAKEFILE TRUE) +add_executable(main main.F) diff --git a/Tests/RunCMake/CompilerLauncher/Fortran-env-Build-stdout.txt b/Tests/RunCMake/CompilerLauncher/Fortran-env-Build-stdout.txt new file mode 100644 index 0000000..3313e31 --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/Fortran-env-Build-stdout.txt @@ -0,0 +1 @@ +.*-E env USED_LAUNCHER=1.* diff --git a/Tests/RunCMake/CompilerLauncher/Fortran-env-launch-Build-stdout.txt b/Tests/RunCMake/CompilerLauncher/Fortran-env-launch-Build-stdout.txt new file mode 100644 index 0000000..3313e31 --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/Fortran-env-launch-Build-stdout.txt @@ -0,0 +1 @@ +.*-E env USED_LAUNCHER=1.* diff --git a/Tests/RunCMake/CompilerLauncher/Fortran-env.cmake b/Tests/RunCMake/CompilerLauncher/Fortran-env.cmake new file mode 100644 index 0000000..3dc27c3 --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/Fortran-env.cmake @@ -0,0 +1 @@ +include(Fortran-common.cmake) diff --git a/Tests/RunCMake/CompilerLauncher/Fortran-launch-env.cmake b/Tests/RunCMake/CompilerLauncher/Fortran-launch-env.cmake new file mode 100644 index 0000000..30a196c --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/Fortran-launch-env.cmake @@ -0,0 +1,3 @@ +set(CTEST_USE_LAUNCHERS 1) +include(CTestUseLaunchers) +include(Fortran-env.cmake) diff --git a/Tests/RunCMake/CompilerLauncher/Fortran.cmake b/Tests/RunCMake/CompilerLauncher/Fortran.cmake index 72cc03e..dc46173 100644 --- a/Tests/RunCMake/CompilerLauncher/Fortran.cmake +++ b/Tests/RunCMake/CompilerLauncher/Fortran.cmake @@ -1,4 +1,2 @@ -enable_language(Fortran) set(CMAKE_Fortran_COMPILER_LAUNCHER "${CMAKE_COMMAND};-E;env;USED_LAUNCHER=1") -set(CMAKE_VERBOSE_MAKEFILE TRUE) -add_executable(main main.F) +include(Fortran-common.cmake) diff --git a/Tests/RunCMake/CompilerLauncher/RunCMakeTest.cmake b/Tests/RunCMake/CompilerLauncher/RunCMakeTest.cmake index bb8da03..f86e8ea 100644 --- a/Tests/RunCMake/CompilerLauncher/RunCMakeTest.cmake +++ b/Tests/RunCMake/CompilerLauncher/RunCMakeTest.cmake @@ -15,6 +15,13 @@ function(run_compiler_launcher lang) run_cmake_command(${lang}-Build ${CMAKE_COMMAND} --build . ${verbose_args}) endfunction() +function(run_compiler_launcher_env lang) + string(REGEX REPLACE "-.*" "" core_lang "${lang}") + set(ENV{CMAKE_${core_lang}_COMPILER_LAUNCHER} "${CMAKE_COMMAND};-E;env;USED_LAUNCHER=1") + run_compiler_launcher(${lang}) + unset(ENV{CMAKE_${core_lang}_COMPILER_LAUNCHER}) +endfunction() + set(langs C CXX) if(CMake_TEST_CUDA) list(APPEND langs CUDA) @@ -25,7 +32,9 @@ endif() foreach(lang ${langs}) run_compiler_launcher(${lang}) + run_compiler_launcher_env(${lang}-env) if (NOT RunCMake_GENERATOR STREQUAL "Watcom WMake") run_compiler_launcher(${lang}-launch) + run_compiler_launcher_env(${lang}-launch-env) endif() endforeach() diff --git a/Tests/RunCMake/ObjectLibrary/OwnSources-stderr.txt b/Tests/RunCMake/ObjectLibrary/OwnSources-stderr.txt index 208f3c9..cb1a2e5 100644 --- a/Tests/RunCMake/ObjectLibrary/OwnSources-stderr.txt +++ b/Tests/RunCMake/ObjectLibrary/OwnSources-stderr.txt @@ -4,4 +4,10 @@ Call Stack \(most recent call first\): CMakeLists.txt:[0-9]+ \(include\) + +CMake Error at OwnSources.cmake:[0-9]+ \(add_library\): + The SOURCES of "A" use a generator expression that depends on the SOURCES + themselves. +Call Stack \(most recent call first\): + CMakeLists.txt:[0-9]+ \(include\) ++ CMake Generate step failed\. Build files cannot be regenerated correctly\.$ diff --git a/Tests/RunCMake/PrecompileHeaders/PchReuseFromPrefixed-build-stderr.txt b/Tests/RunCMake/PrecompileHeaders/PchReuseFromPrefixed-build-stderr.txt new file mode 100644 index 0000000..8cdcfd9 --- /dev/null +++ b/Tests/RunCMake/PrecompileHeaders/PchReuseFromPrefixed-build-stderr.txt @@ -0,0 +1,2 @@ +^(|Warning #670: precompiled header file [^ +]* was not generated in this directory)$ diff --git a/Tests/RunCMake/PrecompileHeaders/PchReuseFromPrefixed.cmake b/Tests/RunCMake/PrecompileHeaders/PchReuseFromPrefixed.cmake new file mode 100644 index 0000000..e306d8e --- /dev/null +++ b/Tests/RunCMake/PrecompileHeaders/PchReuseFromPrefixed.cmake @@ -0,0 +1,29 @@ +cmake_minimum_required(VERSION 3.15) +project(PchReuseFromPrefixed C) + +if(CMAKE_C_COMPILE_OPTIONS_USE_PCH) + add_definitions(-DHAVE_PCH_SUPPORT) +endif() + +add_library(empty empty.c) +target_precompile_headers(empty PRIVATE + <stdio.h> + <string.h> +) +target_include_directories(empty PUBLIC include) + +add_library(foo foo.c) +target_include_directories(foo PUBLIC include) +target_precompile_headers(foo REUSE_FROM empty) + +# Visual Studio 2017 and greater +if (NOT (CMAKE_C_COMPILER_ID STREQUAL "MSVC" AND CMAKE_C_COMPILER_VERSION VERSION_LESS_EQUAL 19.10)) + set_target_properties(foo PROPERTIES PREFIX "lib" IMPORT_PREFIX "lib") +endif() + +add_executable(foobar foobar.c) +target_link_libraries(foobar foo ) +set_target_properties(foobar PROPERTIES PRECOMPILE_HEADERS_REUSE_FROM empty) + +enable_testing() +add_test(NAME foobar COMMAND foobar) diff --git a/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake b/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake index ec13663..8d2f4f9 100644 --- a/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake +++ b/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake @@ -17,5 +17,6 @@ run_test(PchInterface) run_cmake(PchPrologueEpilogue) run_test(SkipPrecompileHeaders) run_test(PchReuseFrom) +run_test(PchReuseFromPrefixed) run_test(PchReuseFromSubdir) run_cmake(PchMultilanguage) diff --git a/Tests/RunCMake/UnityBuild/RunCMakeTest.cmake b/Tests/RunCMake/UnityBuild/RunCMakeTest.cmake index 8e484d0..24daa64 100644 --- a/Tests/RunCMake/UnityBuild/RunCMakeTest.cmake +++ b/Tests/RunCMake/UnityBuild/RunCMakeTest.cmake @@ -21,3 +21,4 @@ function(run_test name) endfunction() run_test(unitybuild_runtest) +run_test(unitybuild_object_library) diff --git a/Tests/RunCMake/UnityBuild/unitybuild_object_library.cmake b/Tests/RunCMake/UnityBuild/unitybuild_object_library.cmake new file mode 100644 index 0000000..b400517 --- /dev/null +++ b/Tests/RunCMake/UnityBuild/unitybuild_object_library.cmake @@ -0,0 +1,13 @@ +project(unitybuild_object_library C) + +set(CMAKE_UNITY_BUILD ON) # This tests that the variable works in addition to the property + +add_library(lib OBJECT func.c) + +add_library(other-lib STATIC func.c) + +add_executable(main main.c) +target_link_libraries(main PRIVATE lib) + +enable_testing() +add_test(NAME main COMMAND main) diff --git a/Tests/RunCMake/foreach/RunCMakeTest.cmake b/Tests/RunCMake/foreach/RunCMakeTest.cmake index 0f1fdd4..8f50203 100644 --- a/Tests/RunCMake/foreach/RunCMakeTest.cmake +++ b/Tests/RunCMake/foreach/RunCMakeTest.cmake @@ -2,3 +2,13 @@ include(RunCMake) run_cmake(BadRangeInFunction) run_cmake(foreach-all-test) +run_cmake(foreach-ITEMS-multiple-iter-vars-test) +run_cmake(foreach-LISTS-multiple-iter-vars-test) +run_cmake(foreach-ZIP_LISTS-test) +run_cmake(foreach-ITEMS-with-ZIP_LISTS-mix-test) +run_cmake(foreach-LISTS-with-ZIP_LISTS-mix-test) +run_cmake(foreach-ZIP_LISTS-with-ITEMS-mix-test) +run_cmake(foreach-ZIP_LISTS-with-LISTS-mix-test) +run_cmake(foreach-ZIP_LISTS-multiple-iter-vars-test) +run_cmake(foreach-ZIP_LISTS-iter-vars-mismatch-test-1) +run_cmake(foreach-ZIP_LISTS-iter-vars-mismatch-test-2) diff --git a/Tests/RunCMake/foreach/foreach-ITEMS-multiple-iter-vars-test-result.txt b/Tests/RunCMake/foreach/foreach-ITEMS-multiple-iter-vars-test-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-ITEMS-multiple-iter-vars-test-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/foreach/foreach-ITEMS-multiple-iter-vars-test-stderr.txt b/Tests/RunCMake/foreach/foreach-ITEMS-multiple-iter-vars-test-stderr.txt new file mode 100644 index 0000000..d174bb1 --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-ITEMS-multiple-iter-vars-test-stderr.txt @@ -0,0 +1,4 @@ +^CMake Error at foreach-ITEMS-multiple-iter-vars-test.cmake:1 \(foreach\): + ITEMS or LISTS require exactly one iteration variable +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/foreach/foreach-ITEMS-multiple-iter-vars-test.cmake b/Tests/RunCMake/foreach/foreach-ITEMS-multiple-iter-vars-test.cmake new file mode 100644 index 0000000..55d33a8 --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-ITEMS-multiple-iter-vars-test.cmake @@ -0,0 +1,2 @@ +foreach(one two IN ITEMS one two) +endforeach() diff --git a/Tests/RunCMake/foreach/foreach-ITEMS-with-ZIP_LISTS-mix-test-result.txt b/Tests/RunCMake/foreach/foreach-ITEMS-with-ZIP_LISTS-mix-test-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-ITEMS-with-ZIP_LISTS-mix-test-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/foreach/foreach-ITEMS-with-ZIP_LISTS-mix-test-stderr.txt b/Tests/RunCMake/foreach/foreach-ITEMS-with-ZIP_LISTS-mix-test-stderr.txt new file mode 100644 index 0000000..f7d5ae7 --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-ITEMS-with-ZIP_LISTS-mix-test-stderr.txt @@ -0,0 +1,4 @@ +^CMake Error at foreach-ITEMS-with-ZIP_LISTS-mix-test.cmake:1 \(foreach\): + ZIP_LISTS can not be used with LISTS or ITEMS +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/foreach/foreach-ITEMS-with-ZIP_LISTS-mix-test.cmake b/Tests/RunCMake/foreach/foreach-ITEMS-with-ZIP_LISTS-mix-test.cmake new file mode 100644 index 0000000..28099a0 --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-ITEMS-with-ZIP_LISTS-mix-test.cmake @@ -0,0 +1,2 @@ +foreach(i IN ITEMS one two three ZIP_LISTS blah) +endforeach() diff --git a/Tests/RunCMake/foreach/foreach-LISTS-multiple-iter-vars-test-result.txt b/Tests/RunCMake/foreach/foreach-LISTS-multiple-iter-vars-test-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-LISTS-multiple-iter-vars-test-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/foreach/foreach-LISTS-multiple-iter-vars-test-stderr.txt b/Tests/RunCMake/foreach/foreach-LISTS-multiple-iter-vars-test-stderr.txt new file mode 100644 index 0000000..f2f83c2 --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-LISTS-multiple-iter-vars-test-stderr.txt @@ -0,0 +1,4 @@ +^CMake Error at foreach-LISTS-multiple-iter-vars-test.cmake:1 \(foreach\): + ITEMS or LISTS require exactly one iteration variable +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/foreach/foreach-LISTS-multiple-iter-vars-test.cmake b/Tests/RunCMake/foreach/foreach-LISTS-multiple-iter-vars-test.cmake new file mode 100644 index 0000000..78f3847 --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-LISTS-multiple-iter-vars-test.cmake @@ -0,0 +1,2 @@ +foreach(one two IN LISTS one two) +endforeach() diff --git a/Tests/RunCMake/foreach/foreach-LISTS-with-ZIP_LISTS-mix-test-result.txt b/Tests/RunCMake/foreach/foreach-LISTS-with-ZIP_LISTS-mix-test-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-LISTS-with-ZIP_LISTS-mix-test-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/foreach/foreach-LISTS-with-ZIP_LISTS-mix-test-stderr.txt b/Tests/RunCMake/foreach/foreach-LISTS-with-ZIP_LISTS-mix-test-stderr.txt new file mode 100644 index 0000000..42f8d1e --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-LISTS-with-ZIP_LISTS-mix-test-stderr.txt @@ -0,0 +1,4 @@ +^CMake Error at foreach-LISTS-with-ZIP_LISTS-mix-test.cmake:1 \(foreach\): + ZIP_LISTS can not be used with LISTS or ITEMS +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/foreach/foreach-LISTS-with-ZIP_LISTS-mix-test.cmake b/Tests/RunCMake/foreach/foreach-LISTS-with-ZIP_LISTS-mix-test.cmake new file mode 100644 index 0000000..8a919dd --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-LISTS-with-ZIP_LISTS-mix-test.cmake @@ -0,0 +1,2 @@ +foreach(i IN LISTS one two three ZIP_LISTS blah) +endforeach() diff --git a/Tests/RunCMake/foreach/foreach-ZIP_LISTS-iter-vars-mismatch-test-1-result.txt b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-iter-vars-mismatch-test-1-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-iter-vars-mismatch-test-1-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/foreach/foreach-ZIP_LISTS-iter-vars-mismatch-test-1-stderr.txt b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-iter-vars-mismatch-test-1-stderr.txt new file mode 100644 index 0000000..fa51e46 --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-iter-vars-mismatch-test-1-stderr.txt @@ -0,0 +1,4 @@ +^CMake Error at foreach-ZIP_LISTS-iter-vars-mismatch-test-1.cmake:1 \(foreach\): + Expected 3 list variables, but given 4 +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/foreach/foreach-ZIP_LISTS-iter-vars-mismatch-test-1.cmake b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-iter-vars-mismatch-test-1.cmake new file mode 100644 index 0000000..458b6ca --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-iter-vars-mismatch-test-1.cmake @@ -0,0 +1,2 @@ +foreach(less than lists IN ZIP_LISTS list_1 list_2 list_3 list_4) +endforeach() diff --git a/Tests/RunCMake/foreach/foreach-ZIP_LISTS-iter-vars-mismatch-test-2-result.txt b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-iter-vars-mismatch-test-2-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-iter-vars-mismatch-test-2-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/foreach/foreach-ZIP_LISTS-iter-vars-mismatch-test-2-stderr.txt b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-iter-vars-mismatch-test-2-stderr.txt new file mode 100644 index 0000000..7b6b484 --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-iter-vars-mismatch-test-2-stderr.txt @@ -0,0 +1,4 @@ +^CMake Error at foreach-ZIP_LISTS-iter-vars-mismatch-test-2.cmake:1 \(foreach\): + Expected 3 list variables, but given 2 +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/foreach/foreach-ZIP_LISTS-iter-vars-mismatch-test-2.cmake b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-iter-vars-mismatch-test-2.cmake new file mode 100644 index 0000000..d24d99c --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-iter-vars-mismatch-test-2.cmake @@ -0,0 +1,2 @@ +foreach(greater than lists IN ZIP_LISTS list_1 list_2) +endforeach() diff --git a/Tests/RunCMake/foreach/foreach-ZIP_LISTS-multiple-iter-vars-test-stdout.txt b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-multiple-iter-vars-test-stdout.txt new file mode 100644 index 0000000..e009d15 --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-multiple-iter-vars-test-stdout.txt @@ -0,0 +1,6 @@ +-- foreach\(\.\.\. IN ZIP_LISTS\): +-- Begin output +-- | one, satu, raz +-- | two, dua, dva +-- | three, tiga, tri +-- End output diff --git a/Tests/RunCMake/foreach/foreach-ZIP_LISTS-multiple-iter-vars-test.cmake b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-multiple-iter-vars-test.cmake new file mode 100644 index 0000000..9647dea --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-multiple-iter-vars-test.cmake @@ -0,0 +1,42 @@ +function(foreachTest result list_var_1 list_var_2 list_var_3) + set(_options MUTE) + set(_one_value_args) + set(_multi_value_args) + cmake_parse_arguments(PARSE_ARGV 3 _arg "${_options}" "${_one_value_args}" "${_multi_value_args}") + + set(_has_any_output FALSE) + list(APPEND CMAKE_MESSAGE_INDENT "| ") + foreach(first second third IN ZIP_LISTS ${list_var_1} ${list_var_2} ${list_var_3}) + if(NOT first) + set(first "[undefiend]") + endif() + if(NOT second) + set(second "[undefiend]") + endif() + if(NOT third) + set(third "[undefiend]") + endif() + if(NOT _arg_MUTE) + message(STATUS "${first}, ${second}, ${third}") + endif() + set(_has_any_output TRUE) + endforeach() + set(${result} ${_has_any_output} PARENT_SCOPE) +endfunction() + +function(foreachTestDecorated list_var_1 list_var_2 list_var_3) + list(APPEND CMAKE_MESSAGE_INDENT " ") + message(STATUS "Begin output") + foreachTest(_has_any_output ${list_var_1} ${list_var_2} ${list_var_3}) + if(NOT _has_any_output) + message(STATUS "--> empty-output <--") + endif() + message(STATUS "End output") +endfunction() + +list(APPEND english one two three) +list(APPEND bahasa satu dua tiga) +list(APPEND russian raz dva tri) + +message(STATUS "foreach(... IN ZIP_LISTS):") +foreachTestDecorated(english bahasa russian) diff --git a/Tests/RunCMake/foreach/foreach-ZIP_LISTS-test-stdout.txt b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-test-stdout.txt new file mode 100644 index 0000000..25433fd --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-test-stdout.txt @@ -0,0 +1,19 @@ +-- foreach\(IN ZIP_LISTS\): +-- <<< empty lists case >>> +-- Begin output +-- --> empty-output <-- +-- End output +-- <<< same lengths lists case >>> +-- Begin output +-- | one, satu, raz +-- | two, dua, dva +-- | three, tiga, tri +-- End output +-- <<< different lengths lists case >>> +-- Begin output +-- | one, satu, raz +-- | two, dua, dva +-- | three, tiga, tri +-- | \[undefiend\], empat, \[undefiend\] +-- End output +-- <<< test variable value restored -- PASSED >>> diff --git a/Tests/RunCMake/foreach/foreach-ZIP_LISTS-test.cmake b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-test.cmake new file mode 100644 index 0000000..56cfe64 --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-test.cmake @@ -0,0 +1,68 @@ +function(foreachTest result list_var_1 list_var_2 list_var_3) + set(_options MUTE) + set(_one_value_args) + set(_multi_value_args) + cmake_parse_arguments(PARSE_ARGV 3 _arg "${_options}" "${_one_value_args}" "${_multi_value_args}") + + set(_has_any_output FALSE) + list(APPEND CMAKE_MESSAGE_INDENT "| ") + foreach(num IN ZIP_LISTS ${list_var_1} ${list_var_2} ${list_var_3}) + foreach(i RANGE 2) + if(NOT num_${i}) + set(num_${i} "[undefiend]") + endif() + endforeach() + if(NOT _arg_MUTE) + message(STATUS "${num_0}, ${num_1}, ${num_2}") + endif() + set(_has_any_output TRUE) + endforeach() + set(${result} ${_has_any_output} PARENT_SCOPE) +endfunction() + +function(foreachTestDecorated list_var_1 list_var_2 list_var_3) + list(APPEND CMAKE_MESSAGE_INDENT " ") + message(STATUS "Begin output") + foreachTest(_has_any_output ${list_var_1} ${list_var_2} ${list_var_3}) + if(NOT _has_any_output) + message(STATUS "--> empty-output <--") + endif() + message(STATUS "End output") +endfunction() + +message(STATUS "foreach(IN ZIP_LISTS):") +list(APPEND CMAKE_MESSAGE_INDENT " ") + +set(english) +set(bahasa) +set(russian) + +message(STATUS "<<< empty lists case >>>") +foreachTestDecorated(english bahasa russian) + +list(APPEND english one two three) +list(APPEND bahasa satu dua tiga) +list(APPEND russian raz dva tri) + +message(STATUS "<<< same lengths lists case >>>") +foreachTestDecorated(english bahasa russian) + +list(APPEND bahasa empat) + +message(STATUS "<<< different lengths lists case >>>") +foreachTestDecorated(english bahasa russian) + +set(num_0 "old-0") +set(num_1 "old-1") +set(num_2 "old-2") +foreachTest(_ english bahasa russian MUTE) +set(check PASSED) +foreach(i RANGE 2) + if(NOT "${num_${i}}" STREQUAL "old-${i}") + message(SEND_ERROR "num_${i} value is corrupted") + set(check FAILED) + endif() +endforeach() +message(STATUS "<<< test variable value restored -- ${check} >>>") + +list(POP_BACK CMAKE_MESSAGE_INDENT) diff --git a/Tests/RunCMake/foreach/foreach-ZIP_LISTS-with-ITEMS-mix-test-result.txt b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-with-ITEMS-mix-test-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-with-ITEMS-mix-test-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/foreach/foreach-ZIP_LISTS-with-ITEMS-mix-test-stderr.txt b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-with-ITEMS-mix-test-stderr.txt new file mode 100644 index 0000000..0dcab01 --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-with-ITEMS-mix-test-stderr.txt @@ -0,0 +1,4 @@ +^CMake Error at foreach-ZIP_LISTS-with-ITEMS-mix-test.cmake:1 \(foreach\): + ZIP_LISTS can not be used with LISTS or ITEMS +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/foreach/foreach-ZIP_LISTS-with-ITEMS-mix-test.cmake b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-with-ITEMS-mix-test.cmake new file mode 100644 index 0000000..71ed842 --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-with-ITEMS-mix-test.cmake @@ -0,0 +1,2 @@ +foreach(i IN ZIP_LISTS blah ITEMS blah) +endforeach() diff --git a/Tests/RunCMake/foreach/foreach-ZIP_LISTS-with-LISTS-mix-test-result.txt b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-with-LISTS-mix-test-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-with-LISTS-mix-test-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/foreach/foreach-ZIP_LISTS-with-LISTS-mix-test-stderr.txt b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-with-LISTS-mix-test-stderr.txt new file mode 100644 index 0000000..a6b6e9c --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-with-LISTS-mix-test-stderr.txt @@ -0,0 +1,4 @@ +^CMake Error at foreach-ZIP_LISTS-with-LISTS-mix-test.cmake:1 \(foreach\): + ZIP_LISTS can not be used with LISTS or ITEMS +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/foreach/foreach-ZIP_LISTS-with-LISTS-mix-test.cmake b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-with-LISTS-mix-test.cmake new file mode 100644 index 0000000..11a97b2 --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-with-LISTS-mix-test.cmake @@ -0,0 +1,2 @@ +foreach(i IN ZIP_LISTS blah LISTS blah) +endforeach() |