diff options
60 files changed, 1404 insertions, 297 deletions
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 7983be1..3006214 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -11,11 +11,11 @@ Community CMake is maintained and supported by `Kitware`_ and developed in collaboration with a productive community of contributors. -Please subscribe and post to the `CMake Developers List`_ to raise +Please post to the ``Development`` category of the `CMake Forum`_ to raise discussion of development topics. .. _`Kitware`: http://www.kitware.com/cmake -.. _`CMake Developers List`: https://cmake.org/mailman/listinfo/cmake-developers +.. _`CMake Forum`: https://discourse.cmake.org Patches ======= diff --git a/Help/envvar/ASM_DIALECTFLAGS.rst b/Help/envvar/ASM_DIALECTFLAGS.rst index 3c3b02a..2e1c6d2 100644 --- a/Help/envvar/ASM_DIALECTFLAGS.rst +++ b/Help/envvar/ASM_DIALECTFLAGS.rst @@ -11,3 +11,5 @@ flags, after which the value for ``ASM<DIALECT>FLAGS`` is stored in the cache as ``CMAKE_ASM<DIALECT>_FLAGS <CMAKE_<LANG>_FLAGS>``. For any configuration run (including the first), the environment variable will be ignored, if the ``CMAKE_ASM<DIALECT>_FLAGS <CMAKE_<LANG>_FLAGS>`` variable is defined. + +See also :variable:`CMAKE_ASM<DIALECT>_FLAGS_INIT <CMAKE_<LANG>_FLAGS_INIT>`. diff --git a/Help/envvar/CFLAGS.rst b/Help/envvar/CFLAGS.rst index fda9ccc..190b4f4 100644 --- a/Help/envvar/CFLAGS.rst +++ b/Help/envvar/CFLAGS.rst @@ -9,3 +9,5 @@ flags, after which the value for ``CFLAGS`` is stored in the cache as :variable:`CMAKE_C_FLAGS <CMAKE_<LANG>_FLAGS>`. For any configuration run (including the first), the environment variable will be ignored if the :variable:`CMAKE_C_FLAGS <CMAKE_<LANG>_FLAGS>` variable is defined. + +See also :variable:`CMAKE_C_FLAGS_INIT <CMAKE_<LANG>_FLAGS_INIT>`. diff --git a/Help/envvar/CSFLAGS.rst b/Help/envvar/CSFLAGS.rst index 404bb59..8762982 100644 --- a/Help/envvar/CSFLAGS.rst +++ b/Help/envvar/CSFLAGS.rst @@ -9,3 +9,5 @@ compilation flags, after which the value for ``CSFLAGS`` is stored in the cache as :variable:`CMAKE_CSharp_FLAGS <CMAKE_<LANG>_FLAGS>`. For any configuration run (including the first), the environment variable will be ignored if the :variable:`CMAKE_CSharp_FLAGS <CMAKE_<LANG>_FLAGS>` variable is defined. + +See also :variable:`CMAKE_CSharp_FLAGS_INIT <CMAKE_<LANG>_FLAGS_INIT>`. diff --git a/Help/envvar/CUDAFLAGS.rst b/Help/envvar/CUDAFLAGS.rst index 4456d6b..14c5d84 100644 --- a/Help/envvar/CUDAFLAGS.rst +++ b/Help/envvar/CUDAFLAGS.rst @@ -9,3 +9,5 @@ compilation flags, after which the value for ``CUDAFLAGS`` is stored in the cache as :variable:`CMAKE_CUDA_FLAGS <CMAKE_<LANG>_FLAGS>`. For any configuration run (including the first), the environment variable will be ignored if the :variable:`CMAKE_CUDA_FLAGS <CMAKE_<LANG>_FLAGS>` variable is defined. + +See also :variable:`CMAKE_CUDA_FLAGS_INIT <CMAKE_<LANG>_FLAGS_INIT>`. diff --git a/Help/envvar/CXXFLAGS.rst b/Help/envvar/CXXFLAGS.rst index d7296dc..460a347 100644 --- a/Help/envvar/CXXFLAGS.rst +++ b/Help/envvar/CXXFLAGS.rst @@ -9,3 +9,5 @@ compilation flags, after which the value for ``CXXFLAGS`` is stored in the cache as :variable:`CMAKE_CXX_FLAGS <CMAKE_<LANG>_FLAGS>`. For any configuration run ( including the first), the environment variable will be ignored if the :variable:`CMAKE_CXX_FLAGS <CMAKE_<LANG>_FLAGS>` variable is defined. + +See also :variable:`CMAKE_CXX_FLAGS_INIT <CMAKE_<LANG>_FLAGS_INIT>`. diff --git a/Help/envvar/FFLAGS.rst b/Help/envvar/FFLAGS.rst index 02d3c34..53bffb6 100644 --- a/Help/envvar/FFLAGS.rst +++ b/Help/envvar/FFLAGS.rst @@ -9,3 +9,5 @@ compilation flags, after which the value for ``FFLAGS`` is stored in the cache as :variable:`CMAKE_Fortran_FLAGS <CMAKE_<LANG>_FLAGS>`. For any configuration run (including the first), the environment variable will be ignored if the :variable:`CMAKE_Fortran_FLAGS <CMAKE_<LANG>_FLAGS>` variable is defined. + +See also :variable:`CMAKE_Fortran_FLAGS_INIT <CMAKE_<LANG>_FLAGS_INIT>`. diff --git a/Help/envvar/RCFLAGS.rst b/Help/envvar/RCFLAGS.rst index 45419fe..bc43cb2 100644 --- a/Help/envvar/RCFLAGS.rst +++ b/Help/envvar/RCFLAGS.rst @@ -9,3 +9,5 @@ default compilation flags, after which the value for ``RCFLAGS`` is stored in the cache as :variable:`CMAKE_RC_FLAGS <CMAKE_<LANG>_FLAGS>`. For any configuration run (including the first), the environment variable will be ignored if the :variable:`CMAKE_RC_FLAGS <CMAKE_<LANG>_FLAGS>` variable is defined. + +See also :variable:`CMAKE_RC_FLAGS_INIT <CMAKE_<LANG>_FLAGS_INIT>`. diff --git a/Help/manual/cmake-file-api.7.rst b/Help/manual/cmake-file-api.7.rst index 12eecd9..91be31d 100644 --- a/Help/manual/cmake-file-api.7.rst +++ b/Help/manual/cmake-file-api.7.rst @@ -899,6 +899,22 @@ with members: an unsigned integer 0-based index into the ``backtraceGraph`` member's ``nodes`` array. + ``precompileHeaders`` + Optional member that is present when :command:`target_precompile_headers` + or other command invocations set :prop_tgt:`PRECOMPILE_HEADERS` on the + target. The value is a JSON array with an entry for each header. Each + entry is a JSON object with members: + + ``header`` + Full path to the precompile header file. + + ``backtrace`` + Optional member that is present when a CMake language backtrace to + the :command:`target_precompile_headers` or other command invocation + that added this precompiled header is available. The value is an + unsigned integer 0-based index into the ``backtraceGraph`` member's + ``nodes`` array. + ``defines`` Optional member that is present when there are preprocessor definitions. The value is a JSON array with an entry for each definition. Each diff --git a/Help/manual/cmake-modules.7.rst b/Help/manual/cmake-modules.7.rst index be64112..50131e8 100644 --- a/Help/manual/cmake-modules.7.rst +++ b/Help/manual/cmake-modules.7.rst @@ -36,6 +36,7 @@ These modules are loaded using the :command:`include` command. /module/CheckIncludeFiles /module/CheckLanguage /module/CheckLibraryExists + /module/CheckLinkerFlag /module/CheckOBJCCompilerFlag /module/CheckOBJCSourceCompiles /module/CheckOBJCSourceRuns diff --git a/Help/module/CheckLinkerFlag.rst b/Help/module/CheckLinkerFlag.rst new file mode 100644 index 0000000..4005725 --- /dev/null +++ b/Help/module/CheckLinkerFlag.rst @@ -0,0 +1 @@ +.. cmake-module:: ../../Modules/CheckLinkerFlag.cmake diff --git a/Help/release/dev/CheckLinkerFlag.rst b/Help/release/dev/CheckLinkerFlag.rst new file mode 100644 index 0000000..fd48d99 --- /dev/null +++ b/Help/release/dev/CheckLinkerFlag.rst @@ -0,0 +1,5 @@ +CheckLinkerFlag +--------------- + +* New :module:`CheckLinkerFlag` module has been added to provide a facility to + check validity of link flags. diff --git a/Help/variable/CMAKE_LANG_FLAGS_INIT.rst b/Help/variable/CMAKE_LANG_FLAGS_INIT.rst index a88d122..4a034e8 100644 --- a/Help/variable/CMAKE_LANG_FLAGS_INIT.rst +++ b/Help/variable/CMAKE_LANG_FLAGS_INIT.rst @@ -5,7 +5,11 @@ Value used to initialize the :variable:`CMAKE_<LANG>_FLAGS` cache entry the first time a build tree is configured for language ``<LANG>``. This variable is meant to be set by a :variable:`toolchain file <CMAKE_TOOLCHAIN_FILE>`. CMake may prepend or append content to -the value based on the environment and target platform. +the value based on the environment and target platform. For example, +the contents of a ``xxxFLAGS`` environment variable will be prepended, +where ``xxx`` will be language-specific but not necessarily the same as +``<LANG>`` (e.g. :envvar:`CXXFLAGS` for ``CXX``, :envvar:`FFLAGS` for +``Fortran``, and so on). See also the configuration-specific :variable:`CMAKE_<LANG>_FLAGS_<CONFIG>_INIT` variable. diff --git a/Modules/CMakeDetermineCUDACompiler.cmake b/Modules/CMakeDetermineCUDACompiler.cmake index 427e5b5..4a8a268 100644 --- a/Modules/CMakeDetermineCUDACompiler.cmake +++ b/Modules/CMakeDetermineCUDACompiler.cmake @@ -137,22 +137,14 @@ elseif(CMAKE_CUDA_COMPILER_ID STREQUAL "Clang") endif() endif() - # Parsing implicit host linker info is as simple as for regular Clang. - CMAKE_PARSE_IMPLICIT_LINK_INFO("${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}" - CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES - CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES - CMAKE_CUDA_HOST_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES - log - "${CMAKE_CUDA_IMPLICIT_OBJECT_REGEX}") - - # Get SDK directory. - string(REGEX MATCH "Found CUDA installation: (.+), version" dont_care "${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}") - set(__cuda_directory "${CMAKE_MATCH_1}") - - # Clang doesn't add the SDK library directory to the implicit link path. Do it ourselves, so stuff works. + # Clang does not add any CUDA SDK libraries or directories when invoking the host linker. + # Add the CUDA toolkit library directory ourselves so that linking works. + # The CUDA runtime libraries are handled elsewhere by CMAKE_CUDA_RUNTIME_LIBRARY. include(Internal/CUDAToolkit) set(CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES "${CUDAToolkit_INCLUDE_DIR}") - list(APPEND CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES "${CUDAToolkit_LIBRARY_DIR}") + set(CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES "${CUDAToolkit_LIBRARY_DIR}") + set(CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES "") + set(CMAKE_CUDA_HOST_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "") elseif(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA") set(_nvcc_log "") string(REPLACE "\r" "" _nvcc_output_orig "${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}") @@ -269,6 +261,24 @@ elseif(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA") endif() endif() +# CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES is detected above as the list of +# libraries that the CUDA compiler implicitly passes to the host linker. +# CMake invokes the host linker directly and so needs to pass these libraries. +# We filter out those that should not be passed unconditionally both here +# and from CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES in CMakeTestCUDACompiler. +set(CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES_EXCLUDE + # The CUDA runtime libraries are controlled by CMAKE_CUDA_RUNTIME_LIBRARY. + cudart cudart.lib + cudart_static cudart_static.lib + cudadevrt cudadevrt.lib + + # Dependencies of the CUDA static runtime library on Linux hosts. + rt + pthread + dl + ) +list(REMOVE_ITEM CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES ${CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES_EXCLUDE}) + if(CMAKE_CUDA_COMPILER_SYSROOT) string(CONCAT _SET_CMAKE_CUDA_COMPILER_SYSROOT "set(CMAKE_CUDA_COMPILER_SYSROOT \"${CMAKE_CUDA_COMPILER_SYSROOT}\")\n" diff --git a/Modules/CMakeTestCUDACompiler.cmake b/Modules/CMakeTestCUDACompiler.cmake index b3b62bd..6d39d3e 100644 --- a/Modules/CMakeTestCUDACompiler.cmake +++ b/Modules/CMakeTestCUDACompiler.cmake @@ -67,21 +67,9 @@ else() set(CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES "${CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES}") endif() - # Remove the following libraries from CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES and - # CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES - # - # - cudart - # - cudart_static - # - cudadevrt - # - # Additionally on Linux: - # - rt - # - pthread - # - dl - # - # These are controlled by CMAKE_CUDA_RUNTIME_LIBRARY - list(REMOVE_ITEM CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES cudart cudart_static cudadevrt rt pthread dl) - list(REMOVE_ITEM CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES cudart cudart_static cudadevrt rt pthread dl) + # Filter out implicit link libraries that should not be passed unconditionally. + # See CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES_EXCLUDE in CMakeDetermineCUDACompiler. + list(REMOVE_ITEM CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES ${CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES_EXCLUDE}) if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA") # Remove the CUDA Toolkit include directories from the set of diff --git a/Modules/CheckLinkerFlag.cmake b/Modules/CheckLinkerFlag.cmake new file mode 100644 index 0000000..beda5fe --- /dev/null +++ b/Modules/CheckLinkerFlag.cmake @@ -0,0 +1,81 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +CheckLinkerFlag +--------------- + +Check whether the compiler supports a given link flag. + +.. command:: check_linker_flag + + .. code-block:: cmake + + check_linker_flag(<lang> <flag> <var>) + +Check that the link ``<flag>`` is accepted by the ``<lang>`` compiler without +a diagnostic. Stores the result in an internal cache entry named ``<var>``. + +This command temporarily sets the ``CMAKE_REQUIRED_LINK_OPTIONS`` variable +and calls the ``check_<lang>_source_compiles`` macro from the +``Check<lang>SourceCompiles`` module (:module:`CheckCSourceCompiles`, +:module:`CheckCSourceCompiles`, :module:`CheckCXXSourceCompiles`, +:module:`CheckOBJCSourceCompiles`, :module:`CheckOBJCXXSourceCompiles` or +:module:`CheckFortranSourceCompiles`). See documentation of these +modules for a listing of variables that can otherwise modify the build. + +The underlying implementation rely on :prop_tgt:`LINK_OPTIONS` property to +check the specified flag. The ``LINKER:`` prefix, as described in +:command:`target_link_options` command, can be used as well. + +A positive result from this check indicates only that the compiler did not +issue a diagnostic message when given the link flag. Whether the flag has any +effect or even a specific one is beyond the scope of this module. + +.. note:: + Since the :command:`try_compile` command forwards flags from variables + like :variable:`CMAKE_<LANG>_FLAGS`, unknown flags in such variables may + cause a false negative for this check. +#]=======================================================================] + +include_guard(GLOBAL) + +include(CMakeCheckCompilerFlagCommonPatterns) + +function(CHECK_LINKER_FLAG _lang _flag _var) + get_property (_supported_languages GLOBAL PROPERTY ENABLED_LANGUAGES) + if (NOT _lang IN_LIST _supported_languages) + message (SEND_ERROR "check_linker_flag: ${_lang}: unknown language.") + return() + endif() + + include (Check${_lang}SourceCompiles) + + set(CMAKE_REQUIRED_LINK_OPTIONS "${_flag}") + + # Normalize locale during test compilation. + set(_locale_vars LC_ALL LC_MESSAGES LANG) + foreach(v IN LISTS _locale_vars) + set(_locale_vars_saved_${v} "$ENV{${v}}") + set(ENV{${v}} C) + endforeach() + + if (_lang MATCHES "^(C|CXX)$") + set (_source "int main() { return 0; }") + elseif (_lang STREQUAL "Fortran") + set (_source " program test\n stop\n end program") + elseif (_lang MATCHES "^(OBJC|OBJCXX)$") + set (_source "#ifndef __OBJC__\n# error \"Not an Objective-C++ compiler\"\n#endif\nint main(void) { return 0; }") + else() + message (SEND_ERROR "check_linker_flag: ${_lang}: unsupported language.") + return() + endif() + check_compiler_flag_common_patterns(_common_patterns) + + cmake_language (CALL check_${_lang}_source_compiles "${_source}" ${_var} ${_common_patterns}) + + foreach(v IN LISTS _locale_vars) + set(ENV{${v}} ${_locale_vars_saved_${v}}) + endforeach() + set(${_var} "${${_var}}" PARENT_SCOPE) +endfunction() diff --git a/Modules/ExternalProject-gitupdate.cmake.in b/Modules/ExternalProject-gitupdate.cmake.in new file mode 100644 index 0000000..e993c3c --- /dev/null +++ b/Modules/ExternalProject-gitupdate.cmake.in @@ -0,0 +1,205 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +cmake_minimum_required(VERSION 3.5) + +execute_process( + COMMAND "@git_EXECUTABLE@" rev-list --max-count=1 HEAD + WORKING_DIRECTORY "@work_dir@" + RESULT_VARIABLE error_code + OUTPUT_VARIABLE head_sha + OUTPUT_STRIP_TRAILING_WHITESPACE + ) +if(error_code) + message(FATAL_ERROR "Failed to get the hash for HEAD") +endif() + +execute_process( + COMMAND "@git_EXECUTABLE@" show-ref "@git_tag@" + WORKING_DIRECTORY "@work_dir@" + OUTPUT_VARIABLE show_ref_output + ) +# If a remote ref is asked for, which can possibly move around, +# we must always do a fetch and checkout. +if("${show_ref_output}" MATCHES "remotes") + set(is_remote_ref 1) +else() + set(is_remote_ref 0) +endif() + +# Tag is in the form <remote>/<tag> (i.e. origin/master) we must strip +# the remote from the tag. +if("${show_ref_output}" MATCHES "refs/remotes/@git_tag@") + string(REGEX MATCH "^([^/]+)/(.+)$" _unused "@git_tag@") + set(git_remote "${CMAKE_MATCH_1}") + set(git_tag "${CMAKE_MATCH_2}") +else() + set(git_remote "@git_remote_name@") + set(git_tag "@git_tag@") +endif() + +# This will fail if the tag does not exist (it probably has not been fetched +# yet). +execute_process( + COMMAND "@git_EXECUTABLE@" rev-list --max-count=1 "${git_tag}" + WORKING_DIRECTORY "@work_dir@" + RESULT_VARIABLE error_code + OUTPUT_VARIABLE tag_sha + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + +# Is the hash checkout out that we want? +if(error_code OR is_remote_ref OR NOT ("${tag_sha}" STREQUAL "${head_sha}")) + execute_process( + COMMAND "@git_EXECUTABLE@" fetch + WORKING_DIRECTORY "@work_dir@" + RESULT_VARIABLE error_code + ) + if(error_code) + message(FATAL_ERROR "Failed to fetch repository '@git_repository@'") + endif() + + if(is_remote_ref AND NOT "@git_update_strategy@" STREQUAL "CHECKOUT") + # Check if stash is needed + execute_process( + COMMAND "@git_EXECUTABLE@" status --porcelain + WORKING_DIRECTORY "@work_dir@" + RESULT_VARIABLE error_code + OUTPUT_VARIABLE repo_status + ) + if(error_code) + message(FATAL_ERROR "Failed to get the status") + endif() + string(LENGTH "${repo_status}" need_stash) + + # If not in clean state, stash changes in order to be able to be able to + # perform git pull --rebase + if(need_stash) + execute_process( + COMMAND "@git_EXECUTABLE@" stash save @git_stash_save_options@ + WORKING_DIRECTORY "@work_dir@" + RESULT_VARIABLE error_code + ) + if(error_code) + message(FATAL_ERROR "Failed to stash changes") + endif() + endif() + + # Pull changes from the remote branch + execute_process( + COMMAND "@git_EXECUTABLE@" rebase "${git_remote}/${git_tag}" + WORKING_DIRECTORY "@work_dir@" + RESULT_VARIABLE error_code + OUTPUT_VARIABLE rebase_output + ERROR_VARIABLE rebase_output + ) + if(error_code) + # Rebase failed, undo the rebase attempt before continuing + execute_process( + COMMAND "@git_EXECUTABLE@" rebase --abort + WORKING_DIRECTORY "@work_dir@" + ) + + if(NOT "@git_update_strategy@" STREQUAL "REBASE_CHECKOUT") + # Not allowed to do a checkout as a fallback, so cannot proceed + if(need_stash) + execute_process( + COMMAND "@git_EXECUTABLE@" stash pop --index --quiet + WORKING_DIRECTORY "@work_dir@" + ) + endif() + message(FATAL_ERROR "\nFailed to rebase in: '@work_dir@'." + "\nOutput from the attempted rebase follows:" + "\n${rebase_output}" + "\n\nYou will have to resolve the conflicts manually") + endif() + + # Fall back to checkout. We create an annotated tag so that the user + # can manually inspect the situation and revert if required. + # We can't log the failed rebase output because MSVC sees it and + # intervenes, causing the build to fail even though it completes. + # Write it to a file instead. + string(TIMESTAMP tag_timestamp "%Y%m%dT%H%M%S" UTC) + set(tag_name _cmake_ExternalProject_moved_from_here_${tag_timestamp}Z) + set(error_log_file ${CMAKE_CURRENT_LIST_DIR}/rebase_error_${tag_timestamp}Z.log) + file(WRITE ${error_log_file} "${rebase_output}") + message(WARNING "Rebase failed, output has been saved to ${error_log_file}" + "\nFalling back to checkout, previous commit tagged as ${tag_name}") + execute_process( + COMMAND "@git_EXECUTABLE@" tag -a + -m "ExternalProject attempting to move from here to ${git_remote}/${git_tag}" + ${tag_name} + WORKING_DIRECTORY "@work_dir@" + RESULT_VARIABLE error_code + ) + if(error_code) + message(FATAL_ERROR "Failed to add marker tag") + endif() + + execute_process( + COMMAND "@git_EXECUTABLE@" checkout ${git_remote}/${git_tag} + WORKING_DIRECTORY "@work_dir@" + RESULT_VARIABLE error_code + ) + if(error_code) + message(FATAL_ERROR "Failed to checkout : '${git_remote}/${git_tag}'") + endif() + + endif() + + if(need_stash) + execute_process( + COMMAND "@git_EXECUTABLE@" stash pop --index --quiet + WORKING_DIRECTORY "@work_dir@" + RESULT_VARIABLE error_code + ) + if(error_code) + # Stash pop --index failed: Try again dropping the index + execute_process( + COMMAND "@git_EXECUTABLE@" reset --hard --quiet + WORKING_DIRECTORY "@work_dir@" + RESULT_VARIABLE error_code + ) + execute_process( + COMMAND "@git_EXECUTABLE@" stash pop --quiet + WORKING_DIRECTORY "@work_dir@" + RESULT_VARIABLE error_code + ) + if(error_code) + # Stash pop failed: Restore previous state. + execute_process( + COMMAND "@git_EXECUTABLE@" reset --hard --quiet ${head_sha} + WORKING_DIRECTORY "@work_dir@" + ) + execute_process( + COMMAND "@git_EXECUTABLE@" stash pop --index --quiet + WORKING_DIRECTORY "@work_dir@" + ) + message(FATAL_ERROR "\nFailed to unstash changes in: '@work_dir@'." + "\nYou will have to resolve the conflicts manually") + endif() + endif() + endif() + else() + execute_process( + COMMAND "@git_EXECUTABLE@" checkout "${git_tag}" + WORKING_DIRECTORY "@work_dir@" + RESULT_VARIABLE error_code + ) + if(error_code) + message(FATAL_ERROR "Failed to checkout tag: '${git_tag}'") + endif() + endif() + + set(init_submodules "@init_submodules@") + if(init_submodules) + execute_process( + COMMAND "@git_EXECUTABLE@" submodule update @git_submodules_recurse@ --init @git_submodules@ + WORKING_DIRECTORY "@work_dir@" + RESULT_VARIABLE error_code + ) + endif() + if(error_code) + message(FATAL_ERROR "Failed to update submodules in: '@work_dir@'") + endif() +endif() diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake index f9f7a4f..9b1963f 100644 --- a/Modules/ExternalProject.cmake +++ b/Modules/ExternalProject.cmake @@ -294,6 +294,42 @@ External Project Definition ``git clone`` command line, with each option required to be in the form ``key=value``. + ``GIT_REMOTE_UPDATE_STRATEGY <strategy>`` + When ``GIT_TAG`` refers to a remote branch, this option can be used to + specify how the update step behaves. The ``<strategy>`` must be one of + the following: + + ``CHECKOUT`` + Ignore the local branch and always checkout the branch specified by + ``GIT_TAG``. + + ``REBASE`` + Try to rebase the current branch to the one specified by ``GIT_TAG``. + If there are local uncommitted changes, they will be stashed first + and popped again after rebasing. If rebasing or popping stashed + changes fail, abort the rebase and halt with an error. + When ``GIT_REMOTE_UPDATE_STRATEGY`` is not present, this is the + default strategy unless the default has been overridden with + ``CMAKE_EP_GIT_REMOTE_UPDATE_STRATEGY`` (see below). + + ``REBASE_CHECKOUT`` + Same as ``REBASE`` except if the rebase fails, an annotated tag will + be created at the original ``HEAD`` position from before the rebase + and then checkout ``GIT_TAG`` just like the ``CHECKOUT`` strategy. + The message stored on the annotated tag will give information about + what was attempted and the tag name will include a timestamp so that + each failed run will add a new tag. This strategy ensures no changes + will be lost, but updates should always succeed if ``GIT_TAG`` refers + to a valid ref unless there are uncommitted changes that cannot be + popped successfully. + + The variable ``CMAKE_EP_GIT_REMOTE_UPDATE_STRATEGY`` can be set to + override the default strategy. This variable should not be set by a + project, it is intended for the user to set. It is primarily intended + for use in continuous integration scripts to ensure that when history + is rewritten on a remote branch, the build doesn't end up with unintended + changes or failed builds resulting from conflicts during rebase operations. + *Subversion* ``SVN_REPOSITORY <url>`` URL of the Subversion repository. @@ -938,6 +974,7 @@ The custom step could then be triggered from the main build like so:: cmake_policy(PUSH) cmake_policy(SET CMP0054 NEW) # if() quoted variables not dereferenced +cmake_policy(SET CMP0057 NEW) # if() supports IN_LIST # Pre-compute a regex to match documented keywords for each command. math(EXPR _ep_documentation_line_count "${CMAKE_CURRENT_LIST_LINE} - 4") @@ -1242,7 +1279,7 @@ endif() endfunction() -function(_ep_write_gitupdate_script script_filename git_EXECUTABLE git_tag git_remote_name init_submodules git_submodules_recurse git_submodules git_repository work_dir) +function(_ep_write_gitupdate_script script_filename git_EXECUTABLE git_tag git_remote_name init_submodules git_submodules_recurse git_submodules git_repository work_dir git_update_strategy) if("${git_tag}" STREQUAL "") message(FATAL_ERROR "Tag for git checkout should not be empty.") endif() @@ -1251,171 +1288,13 @@ function(_ep_write_gitupdate_script script_filename git_EXECUTABLE git_tag git_r else() set(git_stash_save_options --quiet) endif() - file(WRITE ${script_filename} -" -execute_process( - COMMAND \"${git_EXECUTABLE}\" rev-list --max-count=1 HEAD - WORKING_DIRECTORY \"${work_dir}\" - RESULT_VARIABLE error_code - OUTPUT_VARIABLE head_sha - OUTPUT_STRIP_TRAILING_WHITESPACE - ) -if(error_code) - message(FATAL_ERROR \"Failed to get the hash for HEAD\") -endif() - -execute_process( - COMMAND \"${git_EXECUTABLE}\" show-ref ${git_tag} - WORKING_DIRECTORY \"${work_dir}\" - OUTPUT_VARIABLE show_ref_output - ) -# If a remote ref is asked for, which can possibly move around, -# we must always do a fetch and checkout. -if(\"\${show_ref_output}\" MATCHES \"remotes\") - set(is_remote_ref 1) -else() - set(is_remote_ref 0) -endif() - -# Tag is in the form <remote>/<tag> (i.e. origin/master) we must strip -# the remote from the tag. -if(\"\${show_ref_output}\" MATCHES \"refs/remotes/${git_tag}\") - string(REGEX MATCH \"^([^/]+)/(.+)$\" _unused \"${git_tag}\") - set(git_remote \"\${CMAKE_MATCH_1}\") - set(git_tag \"\${CMAKE_MATCH_2}\") -else() - set(git_remote \"${git_remote_name}\") - set(git_tag \"${git_tag}\") -endif() -# This will fail if the tag does not exist (it probably has not been fetched -# yet). -execute_process( - COMMAND \"${git_EXECUTABLE}\" rev-list --max-count=1 ${git_tag} - WORKING_DIRECTORY \"${work_dir}\" - RESULT_VARIABLE error_code - OUTPUT_VARIABLE tag_sha - OUTPUT_STRIP_TRAILING_WHITESPACE + configure_file( + "${_ExternalProject_SELF_DIR}/ExternalProject-gitupdate.cmake.in" + "${script_filename}" + @ONLY ) - -# Is the hash checkout out that we want? -if(error_code OR is_remote_ref OR NOT (\"\${tag_sha}\" STREQUAL \"\${head_sha}\")) - execute_process( - COMMAND \"${git_EXECUTABLE}\" fetch - WORKING_DIRECTORY \"${work_dir}\" - RESULT_VARIABLE error_code - ) - if(error_code) - message(FATAL_ERROR \"Failed to fetch repository '${git_repository}'\") - endif() - - if(is_remote_ref) - # Check if stash is needed - execute_process( - COMMAND \"${git_EXECUTABLE}\" status --porcelain - WORKING_DIRECTORY \"${work_dir}\" - RESULT_VARIABLE error_code - OUTPUT_VARIABLE repo_status - ) - if(error_code) - message(FATAL_ERROR \"Failed to get the status\") - endif() - string(LENGTH \"\${repo_status}\" need_stash) - - # If not in clean state, stash changes in order to be able to be able to - # perform git pull --rebase - if(need_stash) - execute_process( - COMMAND \"${git_EXECUTABLE}\" stash save ${git_stash_save_options} - WORKING_DIRECTORY \"${work_dir}\" - RESULT_VARIABLE error_code - ) - if(error_code) - message(FATAL_ERROR \"Failed to stash changes\") - endif() - endif() - - # Pull changes from the remote branch - execute_process( - COMMAND \"${git_EXECUTABLE}\" rebase \${git_remote}/\${git_tag} - WORKING_DIRECTORY \"${work_dir}\" - RESULT_VARIABLE error_code - ) - if(error_code) - # Rebase failed: Restore previous state. - execute_process( - COMMAND \"${git_EXECUTABLE}\" rebase --abort - WORKING_DIRECTORY \"${work_dir}\" - ) - if(need_stash) - execute_process( - COMMAND \"${git_EXECUTABLE}\" stash pop --index --quiet - WORKING_DIRECTORY \"${work_dir}\" - ) - endif() - message(FATAL_ERROR \"\\nFailed to rebase in: '${work_dir}/${src_name}'.\\nYou will have to resolve the conflicts manually\") - endif() - - if(need_stash) - execute_process( - COMMAND \"${git_EXECUTABLE}\" stash pop --index --quiet - WORKING_DIRECTORY \"${work_dir}\" - RESULT_VARIABLE error_code - ) - if(error_code) - # Stash pop --index failed: Try again dropping the index - execute_process( - COMMAND \"${git_EXECUTABLE}\" reset --hard --quiet - WORKING_DIRECTORY \"${work_dir}\" - RESULT_VARIABLE error_code - ) - execute_process( - COMMAND \"${git_EXECUTABLE}\" stash pop --quiet - WORKING_DIRECTORY \"${work_dir}\" - RESULT_VARIABLE error_code - ) - if(error_code) - # Stash pop failed: Restore previous state. - execute_process( - COMMAND \"${git_EXECUTABLE}\" reset --hard --quiet \${head_sha} - WORKING_DIRECTORY \"${work_dir}\" - ) - execute_process( - COMMAND \"${git_EXECUTABLE}\" stash pop --index --quiet - WORKING_DIRECTORY \"${work_dir}\" - ) - message(FATAL_ERROR \"\\nFailed to unstash changes in: '${work_dir}/${src_name}'.\\nYou will have to resolve the conflicts manually\") - endif() - endif() - endif() - else() - execute_process( - COMMAND \"${git_EXECUTABLE}\" checkout ${git_tag} - WORKING_DIRECTORY \"${work_dir}\" - RESULT_VARIABLE error_code - ) - if(error_code) - message(FATAL_ERROR \"Failed to checkout tag: '${git_tag}'\") - endif() - endif() - - set(init_submodules ${init_submodules}) - if(init_submodules) - execute_process( - COMMAND \"${git_EXECUTABLE}\" submodule update ${git_submodules_recurse} --init ${git_submodules} - WORKING_DIRECTORY \"${work_dir}/${src_name}\" - RESULT_VARIABLE error_code - ) - endif() - if(error_code) - message(FATAL_ERROR \"Failed to update submodules in: '${work_dir}/${src_name}'\") - endif() -endif() - -" -) - -endfunction(_ep_write_gitupdate_script) +endfunction() function(_ep_write_downloadfile_script script_filename REMOTE LOCAL timeout no_progress hash tls_verify tls_cainfo userpwd http_headers netrc netrc_file) if(timeout) @@ -2789,10 +2668,22 @@ function(_ep_add_update_command name) endif() endif() + get_property(git_update_strategy TARGET ${name} PROPERTY _EP_GIT_REMOTE_UPDATE_STRATEGY) + if(NOT git_update_strategy) + set(git_update_strategy "${CMAKE_EP_GIT_REMOTE_UPDATE_STRATEGY}") + endif() + if(NOT git_update_strategy) + set(git_update_strategy REBASE) + endif() + set(strategies CHECKOUT REBASE REBASE_CHECKOUT) + if(NOT git_update_strategy IN_LIST strategies) + message(FATAL_ERROR "'${git_update_strategy}' is not one of the supported strategies: ${strategies}") + endif() + _ep_get_git_submodules_recurse(git_submodules_recurse) _ep_write_gitupdate_script(${tmp_dir}/${name}-gitupdate.cmake - ${GIT_EXECUTABLE} ${git_tag} ${git_remote_name} ${git_init_submodules} "${git_submodules_recurse}" "${git_submodules}" ${git_repository} ${work_dir} + ${GIT_EXECUTABLE} ${git_tag} ${git_remote_name} ${git_init_submodules} "${git_submodules_recurse}" "${git_submodules}" ${git_repository} ${work_dir} ${git_update_strategy} ) set(cmd ${CMAKE_COMMAND} -P ${tmp_dir}/${name}-gitupdate.cmake) set(always 1) diff --git a/Modules/FindSquish.cmake b/Modules/FindSquish.cmake index 16f5ab8..91d1410 100644 --- a/Modules/FindSquish.cmake +++ b/Modules/FindSquish.cmake @@ -65,8 +65,7 @@ The arguments have the following meaning: the name of the squish test, i.e. the name of the subdirectory of the test inside the suite directory. ``SETTINGSGROUP group`` - if specified, the given settings group will be used for executing the test. - If not specified, the groupname will be "CTest_<username>" + deprecated, this argument will be ignored. ``PRE_COMMAND command`` if specified, the given command will be executed before starting the squish test. ``POST_COMMAND command`` @@ -83,7 +82,6 @@ The arguments have the following meaning: AUT myApp SUITE ${CMAKE_SOURCE_DIR}/tests/mySuite TEST someSquishTest - SETTINGSGROUP myGroup ) endif () @@ -255,8 +253,8 @@ function(squish_v4_add_test testName) message(FATAL_ERROR "Could not find squish testcase ${_SQUISH_TEST} (checked ${absTestCase})") endif() - if(NOT _SQUISH_SETTINGSGROUP) - set(_SQUISH_SETTINGSGROUP "CTest_$ENV{LOGNAME}") + if(_SQUISH_SETTINGSGROUP) + message("SETTINGSGROUP is deprecated and will be ignored.") endif() add_test(NAME ${testName} @@ -272,7 +270,6 @@ function(squish_v4_add_test testName) "-Dsquish_env_vars:STRING=${envVars}" "-Dsquish_wrapper:STRING=${testWraper}" "-Dsquish_module_dir:STRING=${_SQUISH_MODULE_DIR}" - "-Dsquish_settingsgroup:STRING=${_SQUISH_SETTINGSGROUP}" "-Dsquish_pre_command:STRING=${_SQUISH_PRE_COMMAND}" "-Dsquish_post_command:STRING=${_SQUISH_POST_COMMAND}" -P "${_SQUISH_MODULE_DIR}/SquishTestScript.cmake" diff --git a/Modules/Squish4RunTestCase.bat b/Modules/Squish4RunTestCase.bat index 5bd815a..fe303b8 100755 --- a/Modules/Squish4RunTestCase.bat +++ b/Modules/Squish4RunTestCase.bat @@ -4,7 +4,6 @@ set TESTSUITE=%3 set TESTCASE=%4 set AUT=%5 set AUTDIR=%6 -set SETTINGSGROUP=%7 %SQUISHSERVER% --stop @@ -14,7 +13,7 @@ echo "Adding AUT... %SQUISHSERVER% --config addAUT %AUT% %AUTDIR%" echo "Starting the squish server... %SQUISHSERVER%" start /B "Squish Server" %SQUISHSERVER% -echo "Running the test case...%SQUISHRUNNER% --testsuite %TESTSUITE% --testcase %TESTCASE%" +echo "Running the test case... %SQUISHRUNNER% --testsuite %TESTSUITE% --testcase %TESTCASE%" %SQUISHRUNNER% --testsuite "%TESTSUITE%" --testcase "%TESTCASE%" set returnValue=%ERRORLEVEL% diff --git a/Modules/Squish4RunTestCase.sh b/Modules/Squish4RunTestCase.sh index 39a3907..4d1e382 100755 --- a/Modules/Squish4RunTestCase.sh +++ b/Modules/Squish4RunTestCase.sh @@ -6,20 +6,19 @@ TESTSUITE=$3 TESTCASE=$4 AUT=$5 AUTDIR=$6 -SETTINGSGROUP=$7 $SQUISHSERVER --stop > /dev/null 2>&1 -echo "Adding AUT... $SQUISHSERVER --settingsGroup $SETTINGSGROUP --config addAUT $AUT $AUTDIR" -$SQUISHSERVER --settingsGroup "$SETTINGSGROUP" --config addAUT "$AUT" "$AUTDIR" || exit 255 +echo "Adding AUT... $SQUISHSERVER --config addAUT $AUT $AUTDIR" +$SQUISHSERVER --config addAUT "$AUT" "$AUTDIR" || exit 255 # sleep 1 echo "Starting the squish server... $SQUISHSERVER --daemon" $SQUISHSERVER --daemon || exit 255 # sleep 2 -echo "Running the test case...$SQUISHRUNNER --settingsGroup $SETTINGSGROUP --testsuite $TESTSUITE --testcase $TESTCASE" -$SQUISHRUNNER --settingsGroup "$SETTINGSGROUP" --testsuite "$TESTSUITE" --testcase "$TESTCASE" +echo "Running the test case... $SQUISHRUNNER --testsuite $TESTSUITE --testcase $TESTCASE" +$SQUISHRUNNER --testsuite "$TESTSUITE" --testcase "$TESTCASE" returnValue=$? echo "Stopping the squish server... $SQUISHSERVER --stop" diff --git a/Modules/SquishTestScript.cmake b/Modules/SquishTestScript.cmake index 2a80be5..b0cb4af 100644 --- a/Modules/SquishTestScript.cmake +++ b/Modules/SquishTestScript.cmake @@ -31,7 +31,6 @@ message(STATUS "squish_test_case='${squish_test_case}'") message(STATUS "squish_wrapper='${squish_wrapper}'") message(STATUS "squish_env_vars='${squish_env_vars}'") message(STATUS "squish_module_dir='${squish_module_dir}'") -message(STATUS "squish_settingsgroup='${squish_settingsgroup}'") message(STATUS "squish_pre_command='${squish_pre_command}'") message(STATUS "squish_post_command='${squish_post_command}'") @@ -57,10 +56,10 @@ endif() # run the test if("${squish_version}" STREQUAL "4") if (WIN32) - execute_process(COMMAND ${squish_module_dir}/Squish4RunTestCase.bat ${squish_server_executable} ${squish_client_executable} ${squish_test_suite} ${squish_test_case} ${squish_aut} ${squish_aut_dir} ${squish_settingsgroup} + execute_process(COMMAND ${squish_module_dir}/Squish4RunTestCase.bat ${squish_server_executable} ${squish_client_executable} ${squish_test_suite} ${squish_test_case} ${squish_aut} ${squish_aut_dir} RESULT_VARIABLE test_rv ) elseif(UNIX) - execute_process(COMMAND ${squish_module_dir}/Squish4RunTestCase.sh ${squish_server_executable} ${squish_client_executable} ${squish_test_suite} ${squish_test_case} ${squish_aut} ${squish_aut_dir} ${squish_settingsgroup} + execute_process(COMMAND ${squish_module_dir}/Squish4RunTestCase.sh ${squish_server_executable} ${squish_client_executable} ${squish_test_suite} ${squish_test_case} ${squish_aut} ${squish_aut_dir} RESULT_VARIABLE test_rv ) endif () diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index fda9848..feb55e8 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 17) -set(CMake_VERSION_PATCH 20200522) +set(CMake_VERSION_PATCH 20200525) #set(CMake_VERSION_RC 0) set(CMake_VERSION_IS_DIRTY 0) diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index ea7ede4..8723d08 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -12,7 +12,6 @@ #include <cmext/algorithm> #include "cmComputeLinkDepends.h" -#include "cmGeneratorExpression.h" #include "cmGeneratorTarget.h" #include "cmGlobalGenerator.h" #include "cmListFileCache.h" @@ -587,32 +586,18 @@ void cmComputeLinkInformation::AddImplicitLinkInfo() } void cmComputeLinkInformation::AddRuntimeLinkLibrary(std::string const& lang) -{ // Add the lang runtime library flags. This is activated by the presence - // of a default selection whether or not it is overridden by a property. - std::string defaultVar = - cmStrCat("CMAKE_", lang, "_RUNTIME_LIBRARY_DEFAULT"); - cmProp langRuntimeLibraryDefault = this->Makefile->GetDef(defaultVar); - if (langRuntimeLibraryDefault && !langRuntimeLibraryDefault->empty()) { - cmProp runtimeLibraryValue = - this->Target->GetProperty(cmStrCat(lang, "_RUNTIME_LIBRARY")); - if (!runtimeLibraryValue) { - runtimeLibraryValue = langRuntimeLibraryDefault; - } - - std::string runtimeLibrary = - cmSystemTools::UpperCase(cmGeneratorExpression::Evaluate( - *runtimeLibraryValue, this->Target->GetLocalGenerator(), this->Config, - this->Target)); - if (!runtimeLibrary.empty()) { - if (const char* runtimeLinkOptions = this->Makefile->GetDefinition( - "CMAKE_" + lang + "_RUNTIME_LIBRARY_LINK_OPTIONS_" + - runtimeLibrary)) { - std::vector<std::string> libsVec = cmExpandedList(runtimeLinkOptions); - for (std::string const& i : libsVec) { - if (!cm::contains(this->ImplicitLinkLibs, i)) { - this->AddItem(i, nullptr); - } - } +{ + std::string const& runtimeLibrary = + this->Target->GetRuntimeLinkLibrary(lang, this->Config); + if (runtimeLibrary.empty()) { + return; + } + if (const char* runtimeLinkOptions = this->Makefile->GetDefinition( + "CMAKE_" + lang + "_RUNTIME_LIBRARY_LINK_OPTIONS_" + runtimeLibrary)) { + std::vector<std::string> libsVec = cmExpandedList(runtimeLinkOptions); + for (std::string const& i : libsVec) { + if (!cm::contains(this->ImplicitLinkLibs, i)) { + this->AddItem(i, nullptr); } } } diff --git a/Source/cmFileAPI.cxx b/Source/cmFileAPI.cxx index a56ad22..594969b 100644 --- a/Source/cmFileAPI.cxx +++ b/Source/cmFileAPI.cxx @@ -665,7 +665,7 @@ std::string cmFileAPI::NoSupportedVersion( // The "codemodel" object kind. -static unsigned int const CodeModelV2Minor = 0; +static unsigned int const CodeModelV2Minor = 1; void cmFileAPI::BuildClientRequestCodeModel( ClientRequest& r, std::vector<RequestVersion> const& versions) diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx index b983b21..b7daebe 100644 --- a/Source/cmFileAPICodemodel.cxx +++ b/Source/cmFileAPICodemodel.cxx @@ -278,12 +278,14 @@ struct CompileData std::string Sysroot; std::vector<JBT<std::string>> Flags; std::vector<JBT<std::string>> Defines; + std::vector<JBT<std::string>> PrecompileHeaders; std::vector<IncludeEntry> Includes; friend bool operator==(CompileData const& l, CompileData const& r) { return (l.Language == r.Language && l.Sysroot == r.Sysroot && l.Flags == r.Flags && l.Defines == r.Defines && + l.PrecompileHeaders == r.PrecompileHeaders && l.Includes == r.Includes); } }; @@ -313,6 +315,10 @@ struct hash<CompileData> result = result ^ hash<std::string>()(i.Value) ^ hash<Json::ArrayIndex>()(i.Backtrace.Index); } + for (auto const& i : in.PrecompileHeaders) { + result = result ^ hash<std::string>()(i.Value) ^ + hash<Json::ArrayIndex>()(i.Backtrace.Index); + } return result; } }; @@ -369,6 +375,7 @@ class Target Json::Value DumpPaths(); Json::Value DumpCompileData(CompileData const& cd); Json::Value DumpInclude(CompileData::IncludeEntry const& inc); + Json::Value DumpPrecompileHeader(JBT<std::string> const& header); Json::Value DumpDefine(JBT<std::string> const& def); Json::Value DumpSources(); Json::Value DumpSource(cmGeneratorTarget::SourceAndKind const& sk, @@ -825,6 +832,11 @@ void Target::ProcessLanguage(std::string const& lang) this->ToJBT(i), this->GT->IsSystemIncludeDirectory(i.Value, this->Config, lang)); } + std::vector<BT<std::string>> precompileHeaders = + this->GT->GetPrecompileHeaders(this->Config, lang); + for (BT<std::string> const& pch : precompileHeaders) { + cd.PrecompileHeaders.emplace_back(this->ToJBT(pch)); + } } Json::ArrayIndex Target::AddSourceGroup(cmSourceGroup* sg, Json::ArrayIndex si) @@ -980,6 +992,9 @@ CompileData Target::MergeCompileData(CompileData const& fd) // All compile groups share the sysroot of the target. cd.Sysroot = td.Sysroot; + // All compile groups share the precompile headers of the target. + cd.PrecompileHeaders = td.PrecompileHeaders; + // Use target-wide flags followed by source-specific flags. cd.Flags.reserve(td.Flags.size() + fd.Flags.size()); cd.Flags.insert(cd.Flags.end(), td.Flags.begin(), td.Flags.end()); @@ -1130,6 +1145,13 @@ Json::Value Target::DumpCompileData(CompileData const& cd) } result["defines"] = std::move(defines); } + if (!cd.PrecompileHeaders.empty()) { + Json::Value precompileHeaders = Json::arrayValue; + for (JBT<std::string> const& pch : cd.PrecompileHeaders) { + precompileHeaders.append(this->DumpPrecompileHeader(pch)); + } + result["precompileHeaders"] = std::move(precompileHeaders); + } return result; } @@ -1145,6 +1167,14 @@ Json::Value Target::DumpInclude(CompileData::IncludeEntry const& inc) return include; } +Json::Value Target::DumpPrecompileHeader(JBT<std::string> const& header) +{ + Json::Value precompileHeader = Json::objectValue; + precompileHeader["header"] = header.Value; + this->AddBacktrace(precompileHeader, header.Backtrace); + return precompileHeader; +} + Json::Value Target::DumpDefine(JBT<std::string> const& def) { Json::Value define = Json::objectValue; diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 917985a..f2a51ab 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -5710,6 +5710,25 @@ void cmGeneratorTarget::GetTargetVersion(const std::string& property, } } +std::string cmGeneratorTarget::GetRuntimeLinkLibrary( + std::string const& lang, std::string const& config) const +{ + // This is activated by the presence of a default selection whether or + // not it is overridden by a property. + cmProp runtimeLibraryDefault = this->Makefile->GetDef( + cmStrCat("CMAKE_", lang, "_RUNTIME_LIBRARY_DEFAULT")); + if (!runtimeLibraryDefault || runtimeLibraryDefault->empty()) { + return std::string(); + } + cmProp runtimeLibraryValue = + this->Target->GetProperty(cmStrCat(lang, "_RUNTIME_LIBRARY")); + if (!runtimeLibraryValue) { + runtimeLibraryValue = runtimeLibraryDefault; + } + return cmSystemTools::UpperCase(cmGeneratorExpression::Evaluate( + *runtimeLibraryValue, this->LocalGenerator, config, this)); +} + std::string cmGeneratorTarget::GetFortranModuleDirectory( std::string const& working_dir) const { diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index c8732bc..788fa23 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -783,6 +783,9 @@ public: const std::string& fallback_property, int& major, int& minor, int& patch) const; + std::string GetRuntimeLinkLibrary(std::string const& lang, + std::string const& config) const; + std::string GetFortranModuleDirectory(std::string const& working_dir) const; const std::string& GetSourcesProperty() const; diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index b89fb8f..44e632f 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -415,6 +415,11 @@ public: std::set<std::string> GetCrossConfigs(const std::string& config) const; + const std::set<std::string>& GetDefaultConfigs() const + { + return this->DefaultConfigs; + } + protected: void Generate() override; diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx index d1944a4..e52e0d3 100644 --- a/Source/cmLocalNinjaGenerator.cxx +++ b/Source/cmLocalNinjaGenerator.cxx @@ -97,6 +97,43 @@ void cmLocalNinjaGenerator::Generate() if (target->Target->IsPerConfig()) { for (auto const& config : this->GetConfigNames()) { tg->Generate(config); + if (target->GetType() == cmStateEnums::GLOBAL_TARGET && + this->GetGlobalGenerator()->IsMultiConfig()) { + cmNinjaBuild phonyAlias("phony"); + this->GetGlobalNinjaGenerator()->AppendTargetOutputs( + target.get(), phonyAlias.Outputs, ""); + this->GetGlobalNinjaGenerator()->AppendTargetOutputs( + target.get(), phonyAlias.ExplicitDeps, config); + this->GetGlobalNinjaGenerator()->WriteBuild( + *this->GetGlobalNinjaGenerator()->GetConfigFileStream(config), + phonyAlias); + } + } + if (target->GetType() == cmStateEnums::GLOBAL_TARGET && + this->GetGlobalGenerator()->IsMultiConfig()) { + if (!this->GetGlobalNinjaGenerator()->GetDefaultConfigs().empty()) { + cmNinjaBuild phonyAlias("phony"); + this->GetGlobalNinjaGenerator()->AppendTargetOutputs( + target.get(), phonyAlias.Outputs, ""); + for (auto const& config : + this->GetGlobalNinjaGenerator()->GetDefaultConfigs()) { + this->GetGlobalNinjaGenerator()->AppendTargetOutputs( + target.get(), phonyAlias.ExplicitDeps, config); + } + this->GetGlobalNinjaGenerator()->WriteBuild( + *this->GetGlobalNinjaGenerator()->GetDefaultFileStream(), + phonyAlias); + } + cmNinjaBuild phonyAlias("phony"); + this->GetGlobalNinjaGenerator()->AppendTargetOutputs( + target.get(), phonyAlias.Outputs, "all"); + for (auto const& config : this->GetConfigNames()) { + this->GetGlobalNinjaGenerator()->AppendTargetOutputs( + target.get(), phonyAlias.ExplicitDeps, config); + } + this->GetGlobalNinjaGenerator()->WriteBuild( + *this->GetGlobalNinjaGenerator()->GetDefaultFileStream(), + phonyAlias); } } else { tg->Generate(""); diff --git a/Source/cmNinjaUtilityTargetGenerator.cxx b/Source/cmNinjaUtilityTargetGenerator.cxx index 134924e..b0b7953 100644 --- a/Source/cmNinjaUtilityTargetGenerator.cxx +++ b/Source/cmNinjaUtilityTargetGenerator.cxx @@ -160,10 +160,5 @@ void cmNinjaUtilityTargetGenerator::Generate(const std::string& config) // be per-directory and have one at the top-level anyway. if (genTarget->GetType() != cmStateEnums::GLOBAL_TARGET) { gg->AddTargetAlias(this->GetTargetName(), genTarget, config); - } else if (gg->IsMultiConfig() && genTarget->Target->IsPerConfig()) { - cmNinjaBuild phonyAlias("phony"); - gg->AppendTargetOutputs(genTarget, phonyAlias.Outputs, ""); - phonyAlias.ExplicitDeps = phonyBuild.Outputs; - gg->WriteBuild(this->GetImplFileStream(config), phonyAlias); } } diff --git a/Source/cmSourceFile.h b/Source/cmSourceFile.h index e527069..e2dfdc1 100644 --- a/Source/cmSourceFile.h +++ b/Source/cmSourceFile.h @@ -159,7 +159,7 @@ private: "\\.(C|F|M|c|c\\+\\+|cc|cpp|cxx|cu|f|f90|for|fpp|ftn|m|mm|" \ "rc|def|r|odl|idl|hpj|bat)$" -#define CM_PCH_REGEX "cmake_pch\\.(h|hxx)$" +#define CM_PCH_REGEX "cmake_pch(_[^.]+)?\\.(h|hxx)$" #define CM_RESOURCE_REGEX "\\.(pdf|plist|png|jpeg|jpg|storyboard|xcassets)$" diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 97f7093..de88182 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -3130,6 +3130,17 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaOptions( cudaOptions.AddIncludes(this->GetIncludes(configName, "CUDA")); cudaOptions.AddFlag("UseHostInclude", "false"); + // Add runtime library selection flag. + std::string const& cudaRuntime = + this->GeneratorTarget->GetRuntimeLinkLibrary("CUDA", configName); + if (cudaRuntime == "STATIC") { + cudaOptions.AddFlag("CudaRuntime", "Static"); + } else if (cudaRuntime == "SHARED") { + cudaOptions.AddFlag("CudaRuntime", "Shared"); + } else if (cudaRuntime == "NONE") { + cudaOptions.AddFlag("CudaRuntime", "None"); + } + this->CudaOptions[configName] = std::move(pOptions); return true; } @@ -3644,10 +3655,6 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions( std::vector<std::string> libVec; std::vector<std::string> vsTargetVec; this->AddLibraries(cli, libVec, vsTargetVec, config); - if (cm::contains(linkClosure->Languages, "CUDA") && - this->CudaOptions[config] != nullptr) { - this->CudaOptions[config]->FixCudaRuntime(this->GeneratorTarget); - } std::string standardLibsVar = cmStrCat("CMAKE_", linkLanguage, "_STANDARD_LIBRARIES"); std::string const& libs = this->Makefile->GetSafeDefinition(standardLibsVar); diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx index 7775f62..937b4ce 100644 --- a/Source/cmVisualStudioGeneratorOptions.cxx +++ b/Source/cmVisualStudioGeneratorOptions.cxx @@ -151,34 +151,6 @@ bool cmVisualStudioGeneratorOptions::UsingSBCS() const return false; } -void cmVisualStudioGeneratorOptions::FixCudaRuntime(cmGeneratorTarget* target) -{ - std::map<std::string, FlagValue>::const_iterator i = - this->FlagMap.find("CudaRuntime"); - if (i == this->FlagMap.end()) { - // User didn't provide am override so get the property value - cmProp runtimeLibraryValue = target->GetProperty("CUDA_RUNTIME_LIBRARY"); - if (runtimeLibraryValue) { - std::string cudaRuntime = - cmSystemTools::UpperCase(cmGeneratorExpression::Evaluate( - *runtimeLibraryValue, this->LocalGenerator, this->Configuration, - target)); - if (cudaRuntime == "STATIC") { - this->AddFlag("CudaRuntime", "Static"); - } - if (cudaRuntime == "SHARED") { - this->AddFlag("CudaRuntime", "Shared"); - } - if (cudaRuntime == "NONE") { - this->AddFlag("CudaRuntime", "None"); - } - } else { - // nvcc default is static - this->AddFlag("CudaRuntime", "Static"); - } - } -} - void cmVisualStudioGeneratorOptions::FixCudaCodeGeneration() { // Extract temporary values stored by our flag table. diff --git a/Source/cmVisualStudioGeneratorOptions.h b/Source/cmVisualStudioGeneratorOptions.h index b335694..f9b50a7 100644 --- a/Source/cmVisualStudioGeneratorOptions.h +++ b/Source/cmVisualStudioGeneratorOptions.h @@ -63,7 +63,6 @@ public: bool UsingSBCS() const; void FixCudaCodeGeneration(); - void FixCudaRuntime(cmGeneratorTarget* target); void FixManifestUACFlags(); diff --git a/Tests/CheckFortran.cmake b/Tests/CheckFortran.cmake index 16a8ed2..33e1bfb 100644 --- a/Tests/CheckFortran.cmake +++ b/Tests/CheckFortran.cmake @@ -11,6 +11,7 @@ if(NOT DEFINED CMAKE_Fortran_COMPILER) project(CheckFortran Fortran) file(WRITE \"\${CMAKE_CURRENT_BINARY_DIR}/result.cmake\" \"set(CMAKE_Fortran_COMPILER \\\"\${CMAKE_Fortran_COMPILER}\\\")\\n\" + \"set(CMAKE_Fortran_COMPILER_ID \\\"\${CMAKE_Fortran_COMPILER_ID}\\\")\\n\" \"set(CMAKE_Fortran_FLAGS \\\"\${CMAKE_Fortran_FLAGS}\\\")\\n\" \"set(CMAKE_Fortran_COMPILER_SUPPORTS_F90 \\\"\${CMAKE_Fortran_COMPILER_SUPPORTS_F90}\\\")\\n\" ) @@ -45,6 +46,8 @@ file(WRITE \"\${CMAKE_CURRENT_BINARY_DIR}/result.cmake\" message(STATUS "${_desc} - ${CMAKE_Fortran_COMPILER}") set(CMAKE_Fortran_COMPILER "${CMAKE_Fortran_COMPILER}" CACHE FILEPATH "Fortran compiler") mark_as_advanced(CMAKE_Fortran_COMPILER) + set(CMAKE_Fortran_COMPILER_ID "${CMAKE_Fortran_COMPILER_ID}" CACHE STRING "Fortran compiler Id") + mark_as_advanced(CMAKE_Fortran_COMPILER_ID) set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" CACHE STRING "Fortran flags") mark_as_advanced(CMAKE_Fortran_FLAGS) set(CMAKE_Fortran_COMPILER_SUPPORTS_F90 "${CMAKE_Fortran_COMPILER_SUPPORTS_F90}" CACHE BOOL "Fortran compiler supports F90") diff --git a/Tests/ExternalProjectUpdate/CMakeLists.txt b/Tests/ExternalProjectUpdate/CMakeLists.txt index dbf26c8..9dddae2 100644 --- a/Tests/ExternalProjectUpdate/CMakeLists.txt +++ b/Tests/ExternalProjectUpdate/CMakeLists.txt @@ -78,6 +78,8 @@ if(do_git_tests) ExternalProject_Add(${proj} GIT_REPOSITORY "${local_git_repo}" GIT_TAG ${TEST_GIT_TAG} + GIT_CONFIG "user.email=testauthor@cmake.org" + "user.name=testauthor" CMAKE_GENERATOR "${CMAKE_GENERATOR}" CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> INSTALL_COMMAND "" diff --git a/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake b/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake index 8ea4452..ba0c598 100644 --- a/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake +++ b/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake @@ -2,7 +2,7 @@ # resulting checked out version is resulting_sha and rebuild. # This check's the correct behavior of the ExternalProject UPDATE_COMMAND. # Also verify that a fetch only occurs when fetch_expected is 1. -macro(check_a_tag desired_tag resulting_sha fetch_expected) +macro(check_a_tag desired_tag resulting_sha fetch_expected update_strategy) message( STATUS "Checking ExternalProjectUpdate to tag: ${desired_tag}" ) # Remove the FETCH_HEAD file, so we can check if it gets replaced with a 'git @@ -10,11 +10,16 @@ macro(check_a_tag desired_tag resulting_sha fetch_expected) set( FETCH_HEAD_file ${ExternalProjectUpdate_BINARY_DIR}/CMakeExternals/Source/TutorialStep1-GIT/.git/FETCH_HEAD ) file( REMOVE ${FETCH_HEAD_file} ) + # Give ourselves a marker in the output. It is difficult to tell where we + # are up to without this + message(STATUS "===> check_a_tag ${desired_tag} ${resulting_sha} ${fetch_expected} ${update_strategy}") + # Configure execute_process(COMMAND ${CMAKE_COMMAND} -G ${CMAKE_GENERATOR} -T "${CMAKE_GENERATOR_TOOLSET}" -A "${CMAKE_GENERATOR_PLATFORM}" -DTEST_GIT_TAG:STRING=${desired_tag} + -DCMAKE_EP_GIT_REMOTE_UPDATE_STRATEGY:STRING=${update_strategy} ${ExternalProjectUpdate_SOURCE_DIR} WORKING_DIRECTORY ${ExternalProjectUpdate_BINARY_DIR} RESULT_VARIABLE error_code @@ -176,16 +181,48 @@ if(GIT_EXECUTABLE) endif() endif() +# When re-running tests locally, this ensures we always start afresh +file(REMOVE_RECURSE ${ExternalProjectUpdate_BINARY_DIR}/CMakeExternals) + if(do_git_tests) - check_a_tag(origin/master 5842b503ba4113976d9bb28d57b5aee1ad2736b7 1) - check_a_tag(tag1 d1970730310fe8bc07e73f15dc570071f9f9654a 1) + check_a_tag(origin/master 5842b503ba4113976d9bb28d57b5aee1ad2736b7 1 REBASE) + check_a_tag(tag1 d1970730310fe8bc07e73f15dc570071f9f9654a 1 REBASE) # With the Git UPDATE_COMMAND performance patch, this will not required a # 'git fetch' - check_a_tag(tag1 d1970730310fe8bc07e73f15dc570071f9f9654a 0) - check_a_tag(tag2 5842b503ba4113976d9bb28d57b5aee1ad2736b7 1) - check_a_tag(d19707303 d1970730310fe8bc07e73f15dc570071f9f9654a 1) - check_a_tag(d19707303 d1970730310fe8bc07e73f15dc570071f9f9654a 0) - check_a_tag(origin/master 5842b503ba4113976d9bb28d57b5aee1ad2736b7 1) + check_a_tag(tag1 d1970730310fe8bc07e73f15dc570071f9f9654a 0 REBASE) + check_a_tag(tag2 5842b503ba4113976d9bb28d57b5aee1ad2736b7 1 REBASE) + check_a_tag(d19707303 d1970730310fe8bc07e73f15dc570071f9f9654a 1 REBASE) + check_a_tag(d19707303 d1970730310fe8bc07e73f15dc570071f9f9654a 0 REBASE) + check_a_tag(origin/master 5842b503ba4113976d9bb28d57b5aee1ad2736b7 1 REBASE) # This is a remote symbolic ref, so it will always trigger a 'git fetch' - check_a_tag(origin/master 5842b503ba4113976d9bb28d57b5aee1ad2736b7 1) + check_a_tag(origin/master 5842b503ba4113976d9bb28d57b5aee1ad2736b7 1 REBASE) + + foreach(strategy IN ITEMS CHECKOUT REBASE_CHECKOUT) + # Move local master back, then apply a change that will cause a conflict + # during rebase. We want to test the fallback to checkout. + check_a_tag(master 5842b503ba4113976d9bb28d57b5aee1ad2736b7 1 REBASE) + execute_process(COMMAND ${GIT_EXECUTABLE} reset --hard tag1 + WORKING_DIRECTORY ${ExternalProjectUpdate_BINARY_DIR}/CMakeExternals/Source/TutorialStep1-GIT + RESULT_VARIABLE error_code + ) + if(error_code) + message(FATAL_ERROR "Could not reset local master back to tag1.") + endif() + set(cmlFile ${ExternalProjectUpdate_BINARY_DIR}/CMakeExternals/Source/TutorialStep1-GIT/CMakeLists.txt) + file(READ ${cmlFile} contents) + string(REPLACE "find TutorialConfig.h" "find TutorialConfig.h (conflict here)" + conflictingContent "${contents}" + ) + file(WRITE ${cmlFile} "${conflictingContent}") + execute_process(COMMAND ${GIT_EXECUTABLE} commit -a -m "This should cause a conflict" + WORKING_DIRECTORY ${ExternalProjectUpdate_BINARY_DIR}/CMakeExternals/Source/TutorialStep1-GIT + RESULT_VARIABLE error_code + ) + if(error_code) + message(FATAL_ERROR "Could not commit conflicting change.") + endif() + # This should discard our commit but leave behind an annotated tag + check_a_tag(master 5842b503ba4113976d9bb28d57b5aee1ad2736b7 1 ${strategy}) + endforeach() + endif() diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 0f94e4e..983f7e4 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -203,7 +203,8 @@ endif() add_RunCMake_test(ExternalData) add_RunCMake_test(FeatureSummary) add_RunCMake_test(FPHSA) -add_RunCMake_test(FileAPI -DPYTHON_EXECUTABLE=${PYTHON_EXECUTABLE}) +add_RunCMake_test(FileAPI -DPYTHON_EXECUTABLE=${PYTHON_EXECUTABLE} + -DCMAKE_CXX_COMPILER_ID=${CMAKE_CXX_COMPILER_ID}) add_RunCMake_test(FindBoost) add_RunCMake_test(FindLua) add_RunCMake_test(FindOpenGL) @@ -487,6 +488,12 @@ add_RunCMake_test(target_include_directories) add_RunCMake_test(target_sources) add_RunCMake_test(CheckModules) add_RunCMake_test(CheckIPOSupported) +if (CMAKE_SYSTEM_NAME MATCHES "(Linux|Darwin)" + AND (CMAKE_C_COMPILER_ID MATCHES "Clang|GNU" OR CMAKE_Fortran_COMPILER_ID MATCHES "GNU")) + add_RunCMake_test(CheckLinkerFlag -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID} + -DCMAKE_Fortran_COMPILER_ID=${CMAKE_Fortran_COMPILER_ID}) +endif() + add_RunCMake_test(CommandLine -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME} -DCYGWIN=${CYGWIN} -DPYTHON_EXECUTABLE=${PYTHON_EXECUTABLE}) add_RunCMake_test(CommandLineTar) diff --git a/Tests/RunCMake/CheckLinkerFlag/CMakeLists.txt b/Tests/RunCMake/CheckLinkerFlag/CMakeLists.txt new file mode 100644 index 0000000..0421e28 --- /dev/null +++ b/Tests/RunCMake/CheckLinkerFlag/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.13) + +project(${RunCMake_TEST} LANGUAGES NONE) + +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/CheckLinkerFlag/CheckCLinkerFlag.cmake b/Tests/RunCMake/CheckLinkerFlag/CheckCLinkerFlag.cmake new file mode 100644 index 0000000..c8e87a4 --- /dev/null +++ b/Tests/RunCMake/CheckLinkerFlag/CheckCLinkerFlag.cmake @@ -0,0 +1,3 @@ + +set (CHECK_LANGUAGE C) +include ("${CMAKE_CURRENT_SOURCE_DIR}/CheckLinkerFlag.cmake") diff --git a/Tests/RunCMake/CheckLinkerFlag/CheckCXXLinkerFlag.cmake b/Tests/RunCMake/CheckLinkerFlag/CheckCXXLinkerFlag.cmake new file mode 100644 index 0000000..4e299b9 --- /dev/null +++ b/Tests/RunCMake/CheckLinkerFlag/CheckCXXLinkerFlag.cmake @@ -0,0 +1,3 @@ + +set (CHECK_LANGUAGE CXX) +include ("${CMAKE_CURRENT_SOURCE_DIR}/CheckLinkerFlag.cmake") diff --git a/Tests/RunCMake/CheckLinkerFlag/CheckFortranLinkerFlag.cmake b/Tests/RunCMake/CheckLinkerFlag/CheckFortranLinkerFlag.cmake new file mode 100644 index 0000000..bca288e --- /dev/null +++ b/Tests/RunCMake/CheckLinkerFlag/CheckFortranLinkerFlag.cmake @@ -0,0 +1,3 @@ + +set (CHECK_LANGUAGE Fortran) +include ("${CMAKE_CURRENT_SOURCE_DIR}/CheckLinkerFlag.cmake") diff --git a/Tests/RunCMake/CheckLinkerFlag/CheckLinkerFlag.cmake b/Tests/RunCMake/CheckLinkerFlag/CheckLinkerFlag.cmake new file mode 100644 index 0000000..c3bd465 --- /dev/null +++ b/Tests/RunCMake/CheckLinkerFlag/CheckLinkerFlag.cmake @@ -0,0 +1,14 @@ + +enable_language (${CHECK_LANGUAGE}) + +include(CheckLinkerFlag) + +check_linker_flag(${CHECK_LANGUAGE} "LINKER:-L,/dir" VALID_LINKER_FLAG) +if(NOT VALID_LINKER_FLAG) + message(SEND_ERROR "Test fail for valid linker flag.") +endif() + +check_linker_flag(${CHECK_LANGUAGE} "LINKER:-D" INVALID_LINKER_FLAG) +if(INVALID_LINKER_FLAG) + message(SEND_ERROR "Test fail for invalid linker flag.") +endif() diff --git a/Tests/RunCMake/CheckLinkerFlag/CheckOBJCLinkerFlag.cmake b/Tests/RunCMake/CheckLinkerFlag/CheckOBJCLinkerFlag.cmake new file mode 100644 index 0000000..fa1d18e --- /dev/null +++ b/Tests/RunCMake/CheckLinkerFlag/CheckOBJCLinkerFlag.cmake @@ -0,0 +1,3 @@ + +set (CHECK_LANGUAGE OBJC) +include ("${CMAKE_CURRENT_SOURCE_DIR}/CheckLinkerFlag.cmake") diff --git a/Tests/RunCMake/CheckLinkerFlag/CheckOBJCXXLinkerFlag.cmake b/Tests/RunCMake/CheckLinkerFlag/CheckOBJCXXLinkerFlag.cmake new file mode 100644 index 0000000..414efb8 --- /dev/null +++ b/Tests/RunCMake/CheckLinkerFlag/CheckOBJCXXLinkerFlag.cmake @@ -0,0 +1,3 @@ + +set (CHECK_LANGUAGE OBJCXX) +include ("${CMAKE_CURRENT_SOURCE_DIR}/CheckLinkerFlag.cmake") diff --git a/Tests/RunCMake/CheckLinkerFlag/RunCMakeTest.cmake b/Tests/RunCMake/CheckLinkerFlag/RunCMakeTest.cmake new file mode 100644 index 0000000..224a2a3 --- /dev/null +++ b/Tests/RunCMake/CheckLinkerFlag/RunCMakeTest.cmake @@ -0,0 +1,14 @@ +include(RunCMake) + +if (CMAKE_C_COMPILER_ID MATCHES "Clang|GNU") + run_cmake(CheckCLinkerFlag) + run_cmake(CheckCXXLinkerFlag) + if (APPLE) + run_cmake(CheckOBJCLinkerFlag) + run_cmake(CheckOBJCXXLinkerFlag) + endif() +endif() + +if (CMAKE_Fortran_COMPILER_ID MATCHES "GNU") + run_cmake(CheckFortranLinkerFlag) +endif() diff --git a/Tests/RunCMake/CommandLine/E_capabilities-stdout.txt b/Tests/RunCMake/CommandLine/E_capabilities-stdout.txt index b4b170e..03286f1 100644 --- a/Tests/RunCMake/CommandLine/E_capabilities-stdout.txt +++ b/Tests/RunCMake/CommandLine/E_capabilities-stdout.txt @@ -1 +1 @@ -^{"fileApi":{"requests":\[{"kind":"codemodel","version":\[{"major":2,"minor":0}]},{"kind":"cache","version":\[{"major":2,"minor":0}]},{"kind":"cmakeFiles","version":\[{"major":1,"minor":0}]}]},"generators":\[.*\],"serverMode":true,"version":{.*}}$ +^{"fileApi":{"requests":\[{"kind":"codemodel","version":\[{"major":2,"minor":1}]},{"kind":"cache","version":\[{"major":2,"minor":0}]},{"kind":"cmakeFiles","version":\[{"major":1,"minor":0}]}]},"generators":\[.*\],"serverMode":true,"version":{.*}}$ diff --git a/Tests/RunCMake/FileAPI/RunCMakeTest.cmake b/Tests/RunCMake/FileAPI/RunCMakeTest.cmake index 8cdc00c..4449ff1 100644 --- a/Tests/RunCMake/FileAPI/RunCMakeTest.cmake +++ b/Tests/RunCMake/FileAPI/RunCMakeTest.cmake @@ -23,7 +23,7 @@ function(check_python case) endif() file(GLOB index ${RunCMake_TEST_BINARY_DIR}/.cmake/api/v1/reply/index-*.json) execute_process( - COMMAND ${PYTHON_EXECUTABLE} "${RunCMake_SOURCE_DIR}/${case}-check.py" "${index}" + COMMAND ${PYTHON_EXECUTABLE} "${RunCMake_SOURCE_DIR}/${case}-check.py" "${index}" "${CMAKE_CXX_COMPILER_ID}" RESULT_VARIABLE result OUTPUT_VARIABLE output ERROR_VARIABLE output diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-check.py b/Tests/RunCMake/FileAPI/codemodel-v2-check.py index 9ee0c20..a3dd9ff 100644 --- a/Tests/RunCMake/FileAPI/codemodel-v2-check.py +++ b/Tests/RunCMake/FileAPI/codemodel-v2-check.py @@ -12,7 +12,7 @@ def read_codemodel_json_data(filename): def check_objects(o, g): assert is_list(o) assert len(o) == 1 - check_index_object(o[0], "codemodel", 2, 0, check_object_codemodel(g)) + check_index_object(o[0], "codemodel", 2, 1, check_object_codemodel(g)) def check_backtrace(t, b, backtrace): btg = t["backtraceGraph"] @@ -404,6 +404,23 @@ def check_target(c): missing_exception=lambda e: "Include path: %s" % e["path"], extra_exception=lambda a: "Include path: %s" % a["path"]) + if "precompileHeaders" in expected: + expected_keys.append("precompileHeaders") + + def check_precompile_header(actual, expected): + assert is_dict(actual) + expected_keys = ["backtrace", "header"] + check_backtrace(obj, actual["backtrace"], expected["backtrace"]) + + assert sorted(actual.keys()) == sorted(expected_keys) + + check_list_match(lambda a, e: matches(a["header"], e["header"]), + actual["precompileHeaders"], expected["precompileHeaders"], + check=check_precompile_header, + check_exception=lambda a, e: "Precompile header: %s" % a["header"], + missing_exception=lambda e: "Precompile header: %s" % e["header"], + extra_exception=lambda a: "Precompile header: %s" % a["header"]) + if expected["defines"] is not None: expected_keys.append("defines") @@ -561,6 +578,20 @@ def gen_check_targets(c, g, inSource): read_codemodel_json_data("targets/generated_exe.json"), ] + if cxx_compiler_id in ['Clang', 'AppleClang', 'GNU', 'Intel', 'MSVC', 'Embarcadero'] and g["name"] != "Xcode": + for e in expected: + if e["name"] == "cxx_exe": + if matches(g["name"], "^(Visual Studio |Ninja Multi-Config)"): + precompile_header_data = read_codemodel_json_data("targets/cxx_exe_precompileheader_multigen.json") + else: + if ';' in os.environ.get("CMAKE_OSX_ARCHITECTURES", ""): + precompile_header_data = read_codemodel_json_data("targets/cxx_exe_precompileheader_2arch.json") + else: + precompile_header_data = read_codemodel_json_data("targets/cxx_exe_precompileheader.json") + e["compileGroups"] = precompile_header_data["compileGroups"] + e["sources"] = precompile_header_data["sources"] + e["sourceGroups"] = precompile_header_data["sourceGroups"] + if not os.path.exists(os.path.join(reply_dir, "..", "..", "..", "..", "ipo_enabled.txt")): for e in expected: try: @@ -715,6 +746,7 @@ def check_object_codemodel(g): check_object_codemodel_configuration(c, g, inSource) return _check +cxx_compiler_id = sys.argv[2] assert is_dict(index) assert sorted(index.keys()) == ["cmake", "objects", "reply"] check_objects(index["objects"], index["cmake"]["generator"]) diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe.json index 7631837..e7ab55b 100644 --- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe.json +++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe.json @@ -43,17 +43,36 @@ ], "includes": null, "defines": null, + "precompileHeaders": [ + { + "header": ".*empty\\.h$", + "backtrace": [ + { + "file": "^cxx/CMakeLists\\.txt$", + "line": 21, + "command": "target_precompile_headers", + "hasParent": true + }, + { + "file": "^cxx/CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + } + ], "compileCommandFragments": [ { "fragment" : "TargetCompileOptions", - "backtrace": [ + "backtrace": [ { "file": "^cxx/CMakeLists\\.txt$", "line": 17, "command": "target_compile_options", "hasParent": true }, - { + { "file" : "^cxx/CMakeLists\\.txt$", "line": null, "command": null, diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader.json new file mode 100644 index 0000000..5a0f770 --- /dev/null +++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader.json @@ -0,0 +1,161 @@ +{ + "compileGroups": [ + { + "language": "CXX", + "sourcePaths": [ + ".*cmake_pch(_[^.]+)?(\\.hxx)?\\.cxx$" + ], + "includes": null, + "defines": null, + "precompileHeaders": [ + { + "header": ".*empty\\.h$", + "backtrace": [ + { + "file": "^cxx/CMakeLists\\.txt$", + "line": 21, + "command": "target_precompile_headers", + "hasParent": true + }, + { + "file": "^cxx/CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + } + ], + "compileCommandFragments": [ + { + "fragment": "TargetCompileOptions", + "backtrace": [ + { + "file": "^cxx/CMakeLists\\.txt$", + "line": 17, + "command": "target_compile_options", + "hasParent": true + }, + { + "file": "^cxx/CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + } + ] + }, + { + "language": "CXX", + "sourcePaths": [ + "^empty\\.cxx$" + ], + "includes": null, + "defines": null, + "precompileHeaders": [ + { + "header": ".*empty\\.h$", + "backtrace": [ + { + "file": "^cxx/CMakeLists\\.txt$", + "line": 21, + "command": "target_precompile_headers", + "hasParent": true + }, + { + "file": "^cxx/CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + } + ], + "compileCommandFragments": [ + { + "fragment": "TargetCompileOptions", + "backtrace": [ + { + "file": "^cxx/CMakeLists\\.txt$", + "line": 17, + "command": "target_compile_options", + "hasParent": true + }, + { + "file": "^cxx/CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + } + ] + } + ], + "sources": [ + { + "path": ".*cmake_pch(_[^.]+)?(\\.hxx)?\\.cxx$", + "isGenerated": null, + "sourceGroupName": "Source Files", + "compileGroupLanguage": "CXX", + "backtrace": [ + { + "file": "^cxx/CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + }, + { + "path": "^empty\\.cxx$", + "isGenerated": null, + "sourceGroupName": "Source Files", + "compileGroupLanguage": "CXX", + "backtrace": [ + { + "file": "^cxx/CMakeLists\\.txt$", + "line": 5, + "command": "add_executable", + "hasParent": true + }, + { + "file": "^cxx/CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + }, + { + "path": ".*/cmake_pch(_[^.]+)?\\.hxx$", + "isGenerated": null, + "sourceGroupName": "Precompile Header File", + "compileGroupLanguage": null, + "backtrace": [ + { + "file": "^cxx/CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + } + ], + "sourceGroups": [ + { + "name": "Source Files", + "sourcePaths": [ + ".*cmake_pch(_[^.]+)?(\\.hxx)?\\.cxx$", + "^empty\\.cxx$" + ] + }, + { + "name": "Precompile Header File", + "sourcePaths": [ + ".*/cmake_pch(_[^.]+)?\\.hxx$" + ] + } + ] +} diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader_2arch.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader_2arch.json new file mode 100644 index 0000000..9455748 --- /dev/null +++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader_2arch.json @@ -0,0 +1,237 @@ +{ + "compileGroups": [ + { + "language": "CXX", + "sourcePaths": [ + ".*cmake_pch(_[^.]+)?(\\.hxx)?\\.cxx$" + ], + "includes": null, + "defines": null, + "precompileHeaders": [ + { + "header": ".*empty\\.h$", + "backtrace": [ + { + "file": "^cxx/CMakeLists\\.txt$", + "line": 21, + "command": "target_precompile_headers", + "hasParent": true + }, + { + "file": "^cxx/CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + } + ], + "compileCommandFragments": [ + { + "fragment": "TargetCompileOptions", + "backtrace": [ + { + "file": "^cxx/CMakeLists\\.txt$", + "line": 17, + "command": "target_compile_options", + "hasParent": true + }, + { + "file": "^cxx/CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + } + ] + }, + { + "language": "CXX", + "sourcePaths": [ + ".*cmake_pch(_[^.]+)?(\\.hxx)?\\.cxx$" + ], + "includes": null, + "defines": null, + "precompileHeaders": [ + { + "header": ".*empty\\.h$", + "backtrace": [ + { + "file": "^cxx/CMakeLists\\.txt$", + "line": 21, + "command": "target_precompile_headers", + "hasParent": true + }, + { + "file": "^cxx/CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + } + ], + "compileCommandFragments": [ + { + "fragment": "TargetCompileOptions", + "backtrace": [ + { + "file": "^cxx/CMakeLists\\.txt$", + "line": 17, + "command": "target_compile_options", + "hasParent": true + }, + { + "file": "^cxx/CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + } + ] + }, + { + "language": "CXX", + "sourcePaths": [ + "^empty\\.cxx$" + ], + "includes": null, + "defines": null, + "precompileHeaders": [ + { + "header": ".*empty\\.h$", + "backtrace": [ + { + "file": "^cxx/CMakeLists\\.txt$", + "line": 21, + "command": "target_precompile_headers", + "hasParent": true + }, + { + "file": "^cxx/CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + } + ], + "compileCommandFragments": [ + { + "fragment": "TargetCompileOptions", + "backtrace": [ + { + "file": "^cxx/CMakeLists\\.txt$", + "line": 17, + "command": "target_compile_options", + "hasParent": true + }, + { + "file": "^cxx/CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + } + ] + } + ], + "sources": [ + { + "path": ".*cmake_pch(_[^.]+)?(\\.hxx)?\\.cxx$", + "isGenerated": null, + "sourceGroupName": "Source Files", + "compileGroupLanguage": "CXX", + "backtrace": [ + { + "file": "^cxx/CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + }, + { + "path": ".*cmake_pch(_[^.]+)?(\\.hxx)?\\.cxx$", + "isGenerated": null, + "sourceGroupName": "Source Files", + "compileGroupLanguage": "CXX", + "backtrace": [ + { + "file": "^cxx/CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + }, + { + "path": "^empty\\.cxx$", + "isGenerated": null, + "sourceGroupName": "Source Files", + "compileGroupLanguage": "CXX", + "backtrace": [ + { + "file": "^cxx/CMakeLists\\.txt$", + "line": 5, + "command": "add_executable", + "hasParent": true + }, + { + "file": "^cxx/CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + }, + { + "path": ".*/cmake_pch(_[^.]+)?\\.hxx$", + "isGenerated": null, + "sourceGroupName": "Precompile Header File", + "compileGroupLanguage": null, + "backtrace": [ + { + "file": "^cxx/CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + }, + { + "path": ".*/cmake_pch(_[^.]+)?\\.hxx$", + "isGenerated": null, + "sourceGroupName": "Precompile Header File", + "compileGroupLanguage": null, + "backtrace": [ + { + "file": "^cxx/CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + } + ], + "sourceGroups": [ + { + "name": "Source Files", + "sourcePaths": [ + ".*cmake_pch(_[^.]+)?(\\.hxx)?\\.cxx$", + ".*cmake_pch(_[^.]+)?(\\.hxx)?\\.cxx$", + "^empty\\.cxx$" + ] + }, + { + "name": "Precompile Header File", + "sourcePaths": [ + ".*/cmake_pch(_[^.]+)?\\.hxx$", + ".*/cmake_pch(_[^.]+)?\\.hxx$" + ] + } + ] +} diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader_multigen.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader_multigen.json new file mode 100644 index 0000000..9f6ffcc --- /dev/null +++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader_multigen.json @@ -0,0 +1,206 @@ +{ + "compileGroups": [ + { + "language": "CXX", + "sourcePaths": [ + ".*cmake_pch(_[^.]+)?(\\.hxx)?\\.cxx$" + ], + "includes": null, + "defines": null, + "precompileHeaders": [ + { + "header": ".*empty\\.h$", + "backtrace": [ + { + "file": "^cxx/CMakeLists\\.txt$", + "line": 21, + "command": "target_precompile_headers", + "hasParent": true + }, + { + "file": "^cxx/CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + } + ], + "compileCommandFragments": [ + { + "fragment": "TargetCompileOptions", + "backtrace": [ + { + "file": "^cxx/CMakeLists\\.txt$", + "line": 17, + "command": "target_compile_options", + "hasParent": true + }, + { + "file": "^cxx/CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + } + ] + }, + { + "language": "CXX", + "sourcePaths": [ + "^empty\\.cxx$" + ], + "includes": null, + "defines": null, + "precompileHeaders": [ + { + "header": ".*empty\\.h$", + "backtrace": [ + { + "file": "^cxx/CMakeLists\\.txt$", + "line": 21, + "command": "target_precompile_headers", + "hasParent": true + }, + { + "file": "^cxx/CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + } + ], + "compileCommandFragments": [ + { + "fragment": "TargetCompileOptions", + "backtrace": [ + { + "file": "^cxx/CMakeLists\\.txt$", + "line": 17, + "command": "target_compile_options", + "hasParent": true + }, + { + "file": "^cxx/CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + } + ] + } + ], + "sources": [ + { + "path": ".*cmake_pch(_[^.]+)?(\\.hxx)?\\.cxx$", + "isGenerated": null, + "sourceGroupName": "Source Files", + "compileGroupLanguage": "CXX", + "backtrace": [ + { + "file": "^cxx/CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + }, + { + "path": "^empty\\.cxx$", + "isGenerated": null, + "sourceGroupName": "Source Files", + "compileGroupLanguage": "CXX", + "backtrace": [ + { + "file": "^cxx/CMakeLists\\.txt$", + "line": 5, + "command": "add_executable", + "hasParent": true + }, + { + "file": "^cxx/CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + }, + { + "path": ".*/Debug/cmake_pch(_[^.]+)?\\.hxx$", + "isGenerated": null, + "sourceGroupName": "Precompile Header File", + "compileGroupLanguage": null, + "backtrace": [ + { + "file": "^cxx/CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + }, + { + "path": ".*/Release/cmake_pch(_[^.]+)?\\.hxx$", + "isGenerated": null, + "sourceGroupName": "Precompile Header File", + "compileGroupLanguage": null, + "backtrace": [ + { + "file": "^cxx/CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + }, + { + "path": ".*/MinSizeRel/cmake_pch(_[^.]+)?\\.hxx$", + "isGenerated": null, + "sourceGroupName": "Precompile Header File", + "compileGroupLanguage": null, + "backtrace": [ + { + "file": "^cxx/CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + }, + { + "path": ".*/RelWithDebInfo/cmake_pch(_[^.]+)?\\.hxx$", + "isGenerated": null, + "sourceGroupName": "Precompile Header File", + "compileGroupLanguage": null, + "backtrace": [ + { + "file": "^cxx/CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] + } + ], + "sourceGroups": [ + { + "name": "Source Files", + "sourcePaths": [ + ".*cmake_pch(_[^.]+)?(\\.hxx)?\\.cxx$", + "^empty\\.cxx$" + ] + }, + { + "name": "Precompile Header File", + "sourcePaths": [ + ".*/Debug/cmake_pch(_[^.]+)?\\.hxx$", + ".*/Release/cmake_pch(_[^.]+)?\\.hxx$", + ".*/MinSizeRel/cmake_pch(_[^.]+)?\\.hxx$", + ".*/RelWithDebInfo/cmake_pch(_[^.]+)?\\.hxx$" + ] + } + ] +} diff --git a/Tests/RunCMake/FileAPI/cxx/CMakeLists.txt b/Tests/RunCMake/FileAPI/cxx/CMakeLists.txt index b0564f5..fa51195 100644 --- a/Tests/RunCMake/FileAPI/cxx/CMakeLists.txt +++ b/Tests/RunCMake/FileAPI/cxx/CMakeLists.txt @@ -17,3 +17,5 @@ target_link_libraries(cxx_static_exe PRIVATE cxx_static_lib) target_compile_options(cxx_exe PUBLIC TargetCompileOptions) target_link_options(cxx_exe PUBLIC TargetLinkOptions) target_link_directories(cxx_exe PUBLIC "${CMAKE_BINARY_DIR}/TargetLinkDir") + +target_precompile_headers(cxx_exe PUBLIC ../empty.h) diff --git a/Tests/RunCMake/FileAPI/empty.h b/Tests/RunCMake/FileAPI/empty.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tests/RunCMake/FileAPI/empty.h diff --git a/Tests/RunCMake/NinjaMultiConfig/Install-all-install-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/Install-all-install-ninja-check.cmake new file mode 100644 index 0000000..c588aac --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/Install-all-install-ninja-check.cmake @@ -0,0 +1,39 @@ +check_files("${RunCMake_TEST_BINARY_DIR}" + INCLUDE + ${TARGET_FILE_exe_Debug} + ${TARGET_OBJECT_FILES_exe_Debug} + + ${TARGET_FILE_mylib_Release} + ${TARGET_LINKER_FILE_mylib_Debug} + ${TARGET_OBJECT_FILES_mylib_Debug} + + ${RunCMake_TEST_BINARY_DIR}/install/bin/Debug/${TARGET_FILE_NAME_exe_Debug} + ${RunCMake_TEST_BINARY_DIR}/install/lib/Debug/${TARGET_FILE_NAME_mylib_Debug} + ${RunCMake_TEST_BINARY_DIR}/install/lib/Debug/${TARGET_LINKER_FILE_NAME_mylib_Debug} + + ${TARGET_FILE_exe_Release} + ${TARGET_OBJECT_FILES_exe_Release} + + ${TARGET_FILE_mylib_Release} + ${TARGET_LINKER_FILE_mylib_Release} + ${TARGET_OBJECT_FILES_mylib_Release} + + ${RunCMake_TEST_BINARY_DIR}/install/bin/Release/${TARGET_FILE_NAME_exe_Release} + ${RunCMake_TEST_BINARY_DIR}/install/lib/Release/${TARGET_FILE_NAME_mylib_Release} + ${RunCMake_TEST_BINARY_DIR}/install/lib/Release/${TARGET_LINKER_FILE_NAME_mylib_Release} + + ${TARGET_FILE_exe_RelWithDebInfo} + ${TARGET_OBJECT_FILES_exe_RelWithDebInfo} + + ${TARGET_FILE_mylib_RelWithDebInfo} + ${TARGET_LINKER_FILE_mylib_RelWithDebInfo} + ${TARGET_OBJECT_FILES_mylib_RelWithDebInfo} + + ${RunCMake_TEST_BINARY_DIR}/install/bin/RelWithDebInfo/${TARGET_FILE_NAME_exe_RelWithDebInfo} + ${RunCMake_TEST_BINARY_DIR}/install/lib/RelWithDebInfo/${TARGET_FILE_NAME_mylib_RelWithDebInfo} + ${RunCMake_TEST_BINARY_DIR}/install/lib/RelWithDebInfo/${TARGET_LINKER_FILE_NAME_mylib_RelWithDebInfo} + + EXCLUDE + ${TARGET_OBJECT_FILES_exe_MinSizeRel} + ${TARGET_OBJECT_FILES_mylib_MinSizeRel} + ) diff --git a/Tests/RunCMake/NinjaMultiConfig/Install-default-install-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/Install-default-install-ninja-check.cmake new file mode 100644 index 0000000..bc15a25 --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/Install-default-install-ninja-check.cmake @@ -0,0 +1,31 @@ +check_files("${RunCMake_TEST_BINARY_DIR}" + INCLUDE + ${TARGET_FILE_exe_Debug} + ${TARGET_OBJECT_FILES_exe_Debug} + + ${TARGET_FILE_mylib_Release} + ${TARGET_LINKER_FILE_mylib_Debug} + ${TARGET_OBJECT_FILES_mylib_Debug} + + ${RunCMake_TEST_BINARY_DIR}/install/bin/Debug/${TARGET_FILE_NAME_exe_Debug} + ${RunCMake_TEST_BINARY_DIR}/install/lib/Debug/${TARGET_FILE_NAME_mylib_Debug} + ${RunCMake_TEST_BINARY_DIR}/install/lib/Debug/${TARGET_LINKER_FILE_NAME_mylib_Debug} + + ${TARGET_FILE_exe_Release} + ${TARGET_OBJECT_FILES_exe_Release} + + ${TARGET_FILE_mylib_Release} + ${TARGET_LINKER_FILE_mylib_Release} + ${TARGET_OBJECT_FILES_mylib_Release} + + ${RunCMake_TEST_BINARY_DIR}/install/bin/Release/${TARGET_FILE_NAME_exe_Release} + ${RunCMake_TEST_BINARY_DIR}/install/lib/Release/${TARGET_FILE_NAME_mylib_Release} + ${RunCMake_TEST_BINARY_DIR}/install/lib/Release/${TARGET_LINKER_FILE_NAME_mylib_Release} + + EXCLUDE + ${TARGET_OBJECT_FILES_exe_MinSizeRel} + ${TARGET_OBJECT_FILES_mylib_MinSizeRel} + + ${TARGET_OBJECT_FILES_exe_RelWithDebInfo} + ${TARGET_OBJECT_FILES_mylib_RelWithDebInfo} + ) diff --git a/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake b/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake index 23b89d3..76b488e 100644 --- a/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake +++ b/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake @@ -263,12 +263,16 @@ run_cmake_build(AdditionalCleanFiles release-clean Release clean) run_ninja(AdditionalCleanFiles all-clean build-Debug.ninja clean:all) set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Install-build) -set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX=${RunCMake_TEST_BINARY_DIR}/install;-DCMAKE_CROSS_CONFIGS=all") +set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX=${RunCMake_TEST_BINARY_DIR}/install;-DCMAKE_CROSS_CONFIGS=all;-DCMAKE_DEFAULT_CONFIGS=Debug\\;Release") run_cmake_configure(Install) unset(RunCMake_TEST_OPTIONS) include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake) run_cmake_build(Install release-install Release install) run_ninja(Install debug-in-release-graph-install build-Release.ninja install:Debug) +file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}/install") +run_ninja(Install default-install build.ninja install) +file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}/install") +run_ninja(Install all-install build.ninja install:all) # FIXME Get this working #set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/AutoMocExecutable-build) diff --git a/Utilities/cmcurl/CMake/OtherTests.cmake b/Utilities/cmcurl/CMake/OtherTests.cmake index 8b15029..30315dc 100644 --- a/Utilities/cmcurl/CMake/OtherTests.cmake +++ b/Utilities/cmcurl/CMake/OtherTests.cmake @@ -26,6 +26,13 @@ endif() set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) +if(1) # CMake hard-codes these + set(RECV_TYPE_ARG1 "curl_socket_t") + set(RECV_TYPE_ARG2 "char *") + set(RECV_TYPE_ARG3 "size_t") + set(RECV_TYPE_ARG4 "int") + set(RECV_TYPE_RETV "ssize_t") +else() check_c_source_compiles("${_source_epilogue} int main(void) { recv(0, 0, 0, 0); @@ -88,8 +95,17 @@ else() message(FATAL_ERROR "Unable to link function recv") endif() set(curl_cv_func_recv_args "${curl_cv_func_recv_args}" CACHE INTERNAL "Arguments for recv") +endif() set(HAVE_RECV 1) +if(1) # CMake hard-codes these + set(SEND_QUAL_ARG2 " ") + set(SEND_TYPE_ARG1 "curl_socket_t") + set(SEND_TYPE_ARG2 "char *") + set(SEND_TYPE_ARG3 "size_t") + set(SEND_TYPE_ARG4 "int") + set(SEND_TYPE_RETV "ssize_t") +else() check_c_source_compiles("${_source_epilogue} int main(void) { send(0, 0, 0, 0); @@ -156,6 +172,7 @@ else() message(FATAL_ERROR "Unable to link function send") endif() set(curl_cv_func_send_args "${curl_cv_func_send_args}" CACHE INTERNAL "Arguments for send") +endif() set(HAVE_SEND 1) check_c_source_compiles("${_source_epilogue} |