diff options
168 files changed, 2568 insertions, 1013 deletions
diff --git a/Help/command/FIND_XXX.txt b/Help/command/FIND_XXX.txt index cebe051..4a62c5b 100644 --- a/Help/command/FIND_XXX.txt +++ b/Help/command/FIND_XXX.txt @@ -143,6 +143,10 @@ If ``NO_DEFAULT_PATH`` is not specified, the search process is as follows: * |CMAKE_SYSTEM_XXX_PATH| * |CMAKE_SYSTEM_XXX_MAC_PATH| + The platform paths that these variables contain are locations that + typically include installed software. An example being ``/usr/local`` for + UNIX based platforms. + 7. Search the paths specified by the PATHS option or in the short-hand version of the command. These are typically hard-coded guesses. diff --git a/Help/command/add_compile_options.rst b/Help/command/add_compile_options.rst index 43805c3..36f403c 100644 --- a/Help/command/add_compile_options.rst +++ b/Help/command/add_compile_options.rst @@ -46,3 +46,6 @@ to use the more specific commands :command:`add_compile_definitions` and :command:`include_directories`. The command :command:`target_compile_options` adds target-specific options. + +The source file property :prop_sf:`COMPILE_OPTIONS` adds options to one +source file. diff --git a/Help/command/add_test.rst b/Help/command/add_test.rst index a77ba37..c0677d2 100644 --- a/Help/command/add_test.rst +++ b/Help/command/add_test.rst @@ -10,8 +10,9 @@ Add a test to the project to be run by :manual:`ctest(1)`. [WORKING_DIRECTORY <dir>] [COMMAND_EXPAND_LISTS]) -Adds a test called ``<name>``. The test name may not contain spaces, -quotes, or other characters special in CMake syntax. The options are: +Adds a test called ``<name>``. The test name may contain arbitrary +characters except for double-quotes. However, if it contains spaces +or semicolons it must be enclosed in double-quotes. The options are: ``COMMAND`` Specify the test command-line. If ``<command>`` specifies an diff --git a/Help/command/find_package.rst b/Help/command/find_package.rst index 6753268..dcc0225 100644 --- a/Help/command/find_package.rst +++ b/Help/command/find_package.rst @@ -329,9 +329,9 @@ enabled. skipped if ``NO_SYSTEM_ENVIRONMENT_PATH`` is passed or by setting the :variable:`CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH` to ``FALSE``. Path entries ending in ``/bin`` or ``/sbin`` are automatically converted to their - parent directories:: + parent directories: - PATH + * ``PATH`` 6. Search paths stored in the CMake :ref:`User Package Registry`. This can be skipped if ``NO_CMAKE_PACKAGE_REGISTRY`` is passed or by @@ -345,11 +345,15 @@ enabled. 7. Search cmake variables defined in the Platform files for the current system. This can be skipped if ``NO_CMAKE_SYSTEM_PATH`` is passed or by setting the :variable:`CMAKE_FIND_USE_CMAKE_SYSTEM_PATH` - to ``FALSE``:: + to ``FALSE``: - CMAKE_SYSTEM_PREFIX_PATH - CMAKE_SYSTEM_FRAMEWORK_PATH - CMAKE_SYSTEM_APPBUNDLE_PATH + * :variable:`CMAKE_SYSTEM_PREFIX_PATH` + * :variable:`CMAKE_SYSTEM_FRAMEWORK_PATH` + * :variable:`CMAKE_SYSTEM_APPBUNDLE_PATH` + + The platform paths that these variables contain are locations that + typically include installed software. An example being ``/usr/local`` for + UNIX based platforms. 8. Search paths stored in the CMake :ref:`System Package Registry`. This can be skipped if ``NO_CMAKE_SYSTEM_PACKAGE_REGISTRY`` is passed diff --git a/Help/command/get_property.rst b/Help/command/get_property.rst index c0f9b46..80d97fd 100644 --- a/Help/command/get_property.rst +++ b/Help/command/get_property.rst @@ -10,6 +10,7 @@ Get a property. DIRECTORY [<dir>] | TARGET <target> | SOURCE <source> | + [<TARGET_DIRECTORY ... | DIRECTORY ...>] | INSTALL <file> | TEST <test> | CACHE <entry> | @@ -49,6 +50,15 @@ It must be one of the following: ``VARIABLE`` Scope is unique and does not accept a name. +In the ``SOURCE`` case, the queried source file scope can be changed by +specifying one of the additional options: ``DIRECTORY`` or ``TARGET_DIRECTORY``. + +``DIRECTORY`` takes a path to a processed directory, and the source file property +will be read from that directory scope. + +``TARGET_DIRECTORY`` takes the name of an existing target. The source file +property will be read from this target's directory scope. + The required ``PROPERTY`` option is immediately followed by the name of the property to get. If the property is not set an empty value is returned, although some properties support inheriting from a parent scope diff --git a/Help/command/get_source_file_property.rst b/Help/command/get_source_file_property.rst index decec19..893a1b6 100644 --- a/Help/command/get_source_file_property.rst +++ b/Help/command/get_source_file_property.rst @@ -5,7 +5,7 @@ Get a property for a source file. .. code-block:: cmake - get_source_file_property(VAR file property) + get_source_file_property(VAR file [<TARGET_DIRECTORY ... | DIRECTORY ...>] property) Gets a property from a source file. The value of the property is stored in the variable ``VAR``. If the source property is not found, the @@ -15,6 +15,15 @@ or not (see :command:`define_property`). Non-inherited properties will set parent scope as described for the :command:`define_property` command and if still unable to find the property, ``VAR`` will be set to an empty string. +The queried source file scope can be changed by specifying one of the +additional options: ``DIRECTORY`` or ``TARGET_DIRECTORY``. + +``DIRECTORY`` takes a path to a processed directory, and the source file property +will be read from that directory scope. + +``TARGET_DIRECTORY`` takes the name of an existing target. The source file +property will be read from this target's directory scope. + Use :command:`set_source_files_properties` to set property values. Source file properties usually control how the file is built. One property that is always there is :prop_sf:`LOCATION`. diff --git a/Help/command/set_property.rst b/Help/command/set_property.rst index 1728c98..de28be3 100644 --- a/Help/command/set_property.rst +++ b/Help/command/set_property.rst @@ -8,7 +8,8 @@ Set a named property in a given scope. set_property(<GLOBAL | DIRECTORY [<dir>] | TARGET [<target1> ...] | - SOURCE [<src1> ...] | + SOURCE [<src1> ...] + [<TARGET_DIRECTORY ... | DIRECTORY ...>] | INSTALL [<file1> ...] | TEST [<test1> ...] | CACHE [<entry1> ...] > @@ -34,8 +35,16 @@ It must be one of the following: ``SOURCE`` Scope may name zero or more source files. Note that source - file properties are visible only to targets added in the same + file properties are by default visible only to targets added in the same directory (``CMakeLists.txt``). + The file properties can be made visible in a different directory by specifying + one of the additional options: ``TARGET_DIRECTORY`` or ``DIRECTORY``. + + ``DIRECTORY`` takes a list of processed directories paths, and sets the file + properties in those directory scopes. + + ``TARGET_DIRECTORY`` takes a list of existing targets. The file + properties will be set in these targets' directory scopes. See also the :command:`set_source_files_properties` command. ``INSTALL`` diff --git a/Help/command/set_source_files_properties.rst b/Help/command/set_source_files_properties.rst index ab95d70..8adfb9e 100644 --- a/Help/command/set_source_files_properties.rst +++ b/Help/command/set_source_files_properties.rst @@ -6,12 +6,25 @@ Source files can have properties that affect how they are built. .. code-block:: cmake set_source_files_properties([file1 [file2 [...]]] + [<TARGET_DIRECTORY ... | DIRECTORY ...>] PROPERTIES prop1 value1 [prop2 value2 [...]]) Sets properties associated with source files using a key/value paired list. +Note that source file properties are by default visible only to +targets added in the same directory (``CMakeLists.txt``). + +The file properties can be made visible in a different directory by specifying +one of the additional options: ``TARGET_DIRECTORY`` or ``DIRECTORY``. + +``DIRECTORY`` takes a list of processed directories paths, and sets the file +properties in those directory scopes. + +``TARGET_DIRECTORY`` takes a list of existing targets. The file +properties will be set in these targets' directory scopes. + See also the :command:`set_property(SOURCE)` command. See :ref:`Source File Properties` for the list of properties known diff --git a/Help/command/target_compile_options.rst b/Help/command/target_compile_options.rst index 47e7d86..3c733c5 100644 --- a/Help/command/target_compile_options.rst +++ b/Help/command/target_compile_options.rst @@ -46,3 +46,5 @@ to use the more specific commands :command:`target_compile_definitions` and :command:`target_include_directories`. For directory-wide settings, there is the command :command:`add_compile_options`. + +For file-specific settings, there is the source file property :prop_sf:`COMPILE_OPTIONS`. diff --git a/Help/envvar/OBJC.rst b/Help/envvar/OBJC.rst new file mode 100644 index 0000000..30c0d13 --- /dev/null +++ b/Help/envvar/OBJC.rst @@ -0,0 +1,14 @@ +OBJC +---- + +.. include:: ENV_VAR.txt + +Preferred executable for compiling ``OBJC`` language files. Will only be used +by CMake on the first configuration to determine ``OBJC`` compiler, after +which the value for ``OBJC`` is stored in the cache as +:variable:`CMAKE_OBJC_COMPILER <CMAKE_<LANG>_COMPILER>`. For any configuration +run (including the first), the environment variable will be ignored if the +:variable:`CMAKE_OBJC_COMPILER <CMAKE_<LANG>_COMPILER>` variable is defined. + +If ``OBJC`` is not defined, the :envvar:`CC` environment variable will +be checked instead. diff --git a/Help/envvar/OBJCXX.rst b/Help/envvar/OBJCXX.rst new file mode 100644 index 0000000..a72f7e7 --- /dev/null +++ b/Help/envvar/OBJCXX.rst @@ -0,0 +1,14 @@ +OBJCXX +------ + +.. include:: ENV_VAR.txt + +Preferred executable for compiling ``OBJCXX`` language files. Will only be used +by CMake on the first configuration to determine ``OBJCXX`` compiler, after +which the value for ``OBJCXX`` is stored in the cache as +:variable:`CMAKE_OBJCXX_COMPILER <CMAKE_<LANG>_COMPILER>`. For any configuration +run (including the first), the environment variable will be ignored if the +:variable:`CMAKE_OBJCXX_COMPILER <CMAKE_<LANG>_COMPILER>` variable is defined. + +If ``OBJCXX`` is not defined, the :envvar:`CXX` environment variable will +be checked instead. diff --git a/Help/manual/cmake-env-variables.7.rst b/Help/manual/cmake-env-variables.7.rst index ee83799..ce1e360 100644 --- a/Help/manual/cmake-env-variables.7.rst +++ b/Help/manual/cmake-env-variables.7.rst @@ -63,6 +63,8 @@ Environment Variables for Languages /envvar/CXXFLAGS /envvar/FC /envvar/FFLAGS + /envvar/OBJC + /envvar/OBJCXX /envvar/RC /envvar/RCFLAGS /envvar/SWIFTC diff --git a/Help/prop_sf/COMPILE_OPTIONS.rst b/Help/prop_sf/COMPILE_OPTIONS.rst index 7e48271..537dcec 100644 --- a/Help/prop_sf/COMPILE_OPTIONS.rst +++ b/Help/prop_sf/COMPILE_OPTIONS.rst @@ -5,9 +5,7 @@ List of additional options to pass to the compiler. This property holds a :ref:`semicolon-separated list <CMake Language Lists>` of options and will be added to the list of compile flags when this -source file builds. Use :prop_sf:`COMPILE_DEFINITIONS` to pass -additional preprocessor definitions and :prop_sf:`INCLUDE_DIRECTORIES` to pass -additional include directories. +source file builds. Contents of ``COMPILE_OPTIONS`` may use "generator expressions" with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` manual @@ -16,6 +14,19 @@ does not support per-config per-source settings, so expressions that depend on the build configuration are not allowed with that generator. -.. note:: +Usage example: - This property should be preferred over the :prop_sf:`COMPILE_FLAGS` property. +.. code-block:: cmake + + set_source_files_properties(foo.cpp PROPERTIES COMPILE_OPTIONS "-Wno-unused-parameter;-Wno-missing-field-initializer") + +Related properties: + +* Prefer this property over :prop_sf:`COMPILE_FLAGS`. +* Use :prop_sf:`COMPILE_DEFINITIONS` to pass additional preprocessor definitions. +* Use :prop_sf:`INCLUDE_DIRECTORIES` to pass additional include directories. + +Related commands: + +* :command:`add_compile_options` for directory-wide settings +* :command:`target_compile_options` for target-specific settings diff --git a/Help/prop_tgt/CUDA_STANDARD.rst b/Help/prop_tgt/CUDA_STANDARD.rst index a3a2f56..6d6774e 100644 --- a/Help/prop_tgt/CUDA_STANDARD.rst +++ b/Help/prop_tgt/CUDA_STANDARD.rst @@ -7,7 +7,7 @@ This property specifies the CUDA/C++ standard whose features are requested to build this target. For some compilers, this results in adding a flag such as ``-std=gnu++11`` to the compile line. -Supported values are ``98``, ``11``, ``14``. +Supported values are ``98``, ``03``, ``11``, ``14``, ``17``, ``20``. If the value requested does not result in a compile flag being added for the compiler in use, a previous standard flag will be added instead. This diff --git a/Help/release/3.16.rst b/Help/release/3.16.rst index e2d6788..f3fdb08 100644 --- a/Help/release/3.16.rst +++ b/Help/release/3.16.rst @@ -303,3 +303,16 @@ Changes made since CMake 3.16.0 include the following. Additionally, the modules no longer expose their internal ``_Python*`` cache entries publicly. CMake 3.16.0 through 3.16.4 accidentally made them visible as advanced cache entries. + +3.16.7 +------ + +* Selection of the Objective C or C++ compiler now considers the + :envvar:`CC` or :envvar:`CXX` environment variable if the + :envvar:`OBJC` or :envvar:`OBJCXX` environment variable is not set. + +* The :module:`FindPkgConfig` module now extracts include directories + prefixed with ``-isystem`` into the ``*_INCLUDE_DIRS`` variables and + :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` target properties. + Previously they would be places in ``*_CFLAGS_OTHER`` variables and + :prop_tgt:`INTERFACE_COMPILE_OPTIONS` target properties. diff --git a/Help/release/3.17.rst b/Help/release/3.17.rst index 91e2463..b7c66d8 100644 --- a/Help/release/3.17.rst +++ b/Help/release/3.17.rst @@ -337,6 +337,10 @@ Changes made since CMake 3.17.0 include the following. 3.17.3 ------ +* Selection of the Objective C or C++ compiler now considers the + :envvar:`CC` or :envvar:`CXX` environment variable if the + :envvar:`OBJC` or :envvar:`OBJCXX` environment variable is not set. + * The :module:`FindPkgConfig` module now extracts include directories prefixed with ``-isystem`` into the ``*_INCLUDE_DIRS`` variables and :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` target properties. diff --git a/Help/release/dev/ctest-log-environment.rst b/Help/release/dev/ctest-log-environment.rst new file mode 100644 index 0000000..0636a25 --- /dev/null +++ b/Help/release/dev/ctest-log-environment.rst @@ -0,0 +1,8 @@ +ctest-log-environment +--------------------- + +* :manual:`ctest(1)` now logs environment variables that it sets for each test, + either due to the :prop_test:`ENVIRONMENT` property or the + :ref:`resource allocation <ctest-resource-allocation>` feature, and submits + this log to CDash. It does not log environment variables that were set + outside of CTest. diff --git a/Help/release/dev/cuda-clang.rst b/Help/release/dev/cuda-clang.rst new file mode 100644 index 0000000..fa5cd5a --- /dev/null +++ b/Help/release/dev/cuda-clang.rst @@ -0,0 +1,4 @@ +cuda-clang +---------- + +* The ``CUDA`` language now supports Clang as a compiler. diff --git a/Help/release/dev/fetchcontent-SOURCE_SUBDIR.rst b/Help/release/dev/fetchcontent-SOURCE_SUBDIR.rst new file mode 100644 index 0000000..e9e185c --- /dev/null +++ b/Help/release/dev/fetchcontent-SOURCE_SUBDIR.rst @@ -0,0 +1,6 @@ +fetchcontent-SOURCE_SUBDIR +-------------------------- + +* The :command:`FetchContent_Declare` command now supports a ``SOURCE_SUBDIR`` + option. It can be used to direct :command:`FetchContent_MakeAvailable` + to look in a different location for the ``CMakeLists.txt`` file. diff --git a/Help/release/dev/sf-property-scopes.rst b/Help/release/dev/sf-property-scopes.rst new file mode 100644 index 0000000..0b61625 --- /dev/null +++ b/Help/release/dev/sf-property-scopes.rst @@ -0,0 +1,15 @@ +sf-property-scopes +------------------ + +* The :command:`set_property` with the ``SOURCE`` scope gained the + ``DIRECTORY`` and ``TARGET_DIRECTORY`` options to set properties + in the provided directory scopes. +* The :command:`set_source_files_properties` gained the ``DIRECTORY`` + and ``TARGET_DIRECTORY`` options to set properties in the provided + directory scopes. +* The :command:`get_property` with ``SOURCE`` scope gained the + ``DIRECTORY`` and ``TARGET_DIRECTORY`` options to get a property + from the provided directory scope. +* The :command:`get_source_file_property` gained the ``DIRECTORY`` + and ``TARGET_DIRECTORY`` options to get a property from the + provided directory scope. diff --git a/Help/variable/CMAKE_SYSTEM_PREFIX_PATH.rst b/Help/variable/CMAKE_SYSTEM_PREFIX_PATH.rst index 87a9d06..e0ee979 100644 --- a/Help/variable/CMAKE_SYSTEM_PREFIX_PATH.rst +++ b/Help/variable/CMAKE_SYSTEM_PREFIX_PATH.rst @@ -8,11 +8,40 @@ CMAKE_SYSTEM_PREFIX_PATH subdirectories (like ``bin``, ``lib``, or ``include``) as specified in its own documentation. -By default this contains the standard directories for the current system, the +By default this contains the system directories for the current system, the :variable:`CMAKE_INSTALL_PREFIX`, and the :variable:`CMAKE_STAGING_PREFIX`. The installation and staging prefixes may be excluded by setting the :variable:`CMAKE_FIND_NO_INSTALL_PREFIX` variable. +The system directories that are contained in ``CMAKE_SYSTEM_PREFIX_PATH`` are +locations that typically include installed software. An example being +``/usr/local`` for UNIX based platforms. In addition to standard platform +locations, CMake will also add values to ``CMAKE_SYSTEM_PREFIX_PATH`` based on +environment variables. The environment variables and search locations that +CMake uses may evolve over time, as platforms and their conventions also +evolve. The following provides an indicative list of environment variables +and locations that CMake searches, but they are subject to change: + + +CrayLinuxEnvironment: + * ``ENV{SYSROOT_DIR}/`` + * ``ENV{SYSROOT_DIR}/usr`` + * ``ENV{SYSROOT_DIR}/usr/local`` + +Darwin: + * ``ENV{SDKROOT}/usr`` When ``CMAKE_OSX_SYSROOT`` is not explicitly specified. + +OpenBSD: + * ``ENV{LOCALBASE}`` + +Windows: + * ``ENV{ProgramW6432}`` + * ``ENV{ProgramFiles}`` + * ``ENV{ProgramFiles(x86)}`` + * ``ENV{SystemDrive}/Program Files`` + * ``ENV{SystemDrive}/Program Files (x86)`` + + ``CMAKE_SYSTEM_PREFIX_PATH`` is *not* intended to be modified by the project; use :variable:`CMAKE_PREFIX_PATH` for this. diff --git a/Modules/CMakeCUDAInformation.cmake b/Modules/CMakeCUDAInformation.cmake index e8b60b6..f9f7574 100644 --- a/Modules/CMakeCUDAInformation.cmake +++ b/Modules/CMakeCUDAInformation.cmake @@ -8,6 +8,19 @@ else() endif() set(CMAKE_INCLUDE_FLAG_CUDA "-I") +# Set implicit links early so compiler-specific modules can use them. +set(__IMPLICT_LINKS ) +foreach(dir ${CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES}) + string(APPEND __IMPLICT_LINKS " -L\"${dir}\"") +endforeach() +foreach(lib ${CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES}) + if(${lib} MATCHES "/") + string(APPEND __IMPLICT_LINKS " \"${lib}\"") + else() + string(APPEND __IMPLICT_LINKS " -l${lib}") + endif() +endforeach() + # Load compiler-specific information. if(CMAKE_CUDA_COMPILER_ID) include(Compiler/${CMAKE_CUDA_COMPILER_ID}-CUDA OPTIONAL) @@ -97,22 +110,10 @@ include(CMakeCommonLanguageInclude) # CMAKE_CUDA_COMPILE_SEPARABLE_COMPILATION # CMAKE_CUDA_LINK_EXECUTABLE -if(CMAKE_CUDA_HOST_COMPILER) +if(CMAKE_CUDA_HOST_COMPILER AND CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA") string(APPEND _CMAKE_CUDA_EXTRA_FLAGS " -ccbin=<CMAKE_CUDA_HOST_COMPILER>") endif() -set(__IMPLICT_LINKS ) -foreach(dir ${CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES}) - string(APPEND __IMPLICT_LINKS " -L\"${dir}\"") -endforeach() -foreach(lib ${CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES}) - if(${lib} MATCHES "/") - string(APPEND __IMPLICT_LINKS " \"${lib}\"") - else() - string(APPEND __IMPLICT_LINKS " -l${lib}") - endif() -endforeach() - # create a shared library if(NOT CMAKE_CUDA_CREATE_SHARED_LIBRARY) set(CMAKE_CUDA_CREATE_SHARED_LIBRARY diff --git a/Modules/CMakeCompilerIdDetection.cmake b/Modules/CMakeCompilerIdDetection.cmake index bb573b7..acd15df 100644 --- a/Modules/CMakeCompilerIdDetection.cmake +++ b/Modules/CMakeCompilerIdDetection.cmake @@ -89,9 +89,8 @@ function(compiler_id_detection outvar lang) ) endif() - #Currently the only CUDA compilers are NVIDIA if(lang STREQUAL CUDA) - set(ordered_compilers NVIDIA) + set(ordered_compilers NVIDIA Clang) endif() if(CID_ID_DEFINE) diff --git a/Modules/CMakeDetermineCUDACompiler.cmake b/Modules/CMakeDetermineCUDACompiler.cmake index ead4125..af36688 100644 --- a/Modules/CMakeDetermineCUDACompiler.cmake +++ b/Modules/CMakeDetermineCUDACompiler.cmake @@ -2,7 +2,7 @@ # file Copyright.txt or https://cmake.org/licensing for details. include(${CMAKE_ROOT}/Modules/CMakeDetermineCompiler.cmake) -include(${CMAKE_ROOT}/Modules//CMakeParseImplicitLinkInfo.cmake) +include(${CMAKE_ROOT}/Modules/CMakeParseImplicitLinkInfo.cmake) if( NOT ( ("${CMAKE_GENERATOR}" MATCHES "Make") OR ("${CMAKE_GENERATOR}" MATCHES "Ninja") OR @@ -57,16 +57,39 @@ if(NOT CMAKE_CUDA_COMPILER_ID_RUN) file(READ ${CMAKE_ROOT}/Modules/CMakePlatformId.h.in CMAKE_CUDA_COMPILER_ID_PLATFORM_CONTENT) - list(APPEND CMAKE_CUDA_COMPILER_ID_MATCH_VENDORS NVIDIA) - set(CMAKE_CUDA_COMPILER_ID_MATCH_VENDOR_REGEX_NVIDIA "nvcc: NVIDIA \(R\) Cuda compiler driver") + list(APPEND CMAKE_CUDA_COMPILER_ID_VENDORS NVIDIA Clang) + set(CMAKE_CUDA_COMPILER_ID_VENDOR_REGEX_NVIDIA "nvcc: NVIDIA \\(R\\) Cuda compiler driver") + set(CMAKE_CUDA_COMPILER_ID_VENDOR_REGEX_Clang "(clang version)") set(CMAKE_CXX_COMPILER_ID_TOOL_MATCH_REGEX "\nLd[^\n]*(\n[ \t]+[^\n]*)*\n[ \t]+([^ \t\r\n]+)[^\r\n]*-o[^\r\n]*CompilerIdCUDA/(\\./)?(CompilerIdCUDA.xctest/)?CompilerIdCUDA[ \t\n\\\"]") set(CMAKE_CXX_COMPILER_ID_TOOL_MATCH_INDEX 2) + set(CMAKE_CUDA_COMPILER_ID_FLAGS_ALWAYS "-v") - set(CMAKE_CUDA_COMPILER_ID_FLAGS_ALWAYS -v --keep --keep-dir tmp) + # nvcc + set(nvcc_test_flags "--keep --keep-dir tmp") if(CMAKE_CUDA_HOST_COMPILER) - list(APPEND CMAKE_CUDA_COMPILER_ID_FLAGS_ALWAYS "-ccbin=${CMAKE_CUDA_HOST_COMPILER}") + string(APPEND nvcc_test_flags " -ccbin=${CMAKE_CUDA_HOST_COMPILER}") endif() + list(APPEND CMAKE_CUDA_COMPILER_ID_TEST_FLAGS_FIRST ${nvcc_test_flags}) + + # Clang + if(CMAKE_CROSSCOMPILING) + # Need to pass the host target and include directories if we're crosscompiling. + set(clang_test_flags "--sysroot=\"${CMAKE_SYSROOT}\" --target=${CMAKE_CUDA_COMPILER_TARGET}") + else() + set(clang_test_flags) + endif() + + # Clang doesn't automatically select an architecture supported by the SDK. + # Try in reverse order of deprecation with the most recent at front (i.e. the most likely to work for new setups). + foreach(arch ${CMAKE_CUDA_ARCHITECTURES} "20" "30" "52") + # Strip specifiers. + string(REGEX MATCH "[0-9]+" arch_name "${arch}") + list(APPEND CMAKE_CUDA_COMPILER_ID_TEST_FLAGS_FIRST "${clang_test_flags} --cuda-gpu-arch=sm_${arch_name}") + endforeach() + + # Finally also try the default. + list(APPEND CMAKE_CUDA_COMPILER_ID_TEST_FLAGS_FIRST "${clang_test_flags}") include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake) CMAKE_DETERMINE_COMPILER_ID(CUDA CUDAFLAGS CMakeCUDACompilerId.cu) @@ -89,6 +112,33 @@ if(${CMAKE_GENERATOR} MATCHES "Visual Studio") set(CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES "") set(CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES "") set(CMAKE_CUDA_HOST_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "") +elseif(CMAKE_CUDA_COMPILER_ID STREQUAL "Clang") + # Parse default CUDA architecture. + if(NOT CMAKE_CUDA_ARCHITECTURES) + string(REGEX MATCH "-target-cpu sm_([0-9]+)" dont_care "${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}") + set(CMAKE_CUDA_ARCHITECTURES "${CMAKE_MATCH_1}" CACHE STRING "CUDA architectures") + + if(NOT CMAKE_CUDA_ARCHITECTURES) + message(FATAL_ERROR "Failed to find default CUDA architecture.") + 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. + include(Internal/CUDAToolkit) + set(CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES "${CUDAToolkit_INCLUDE_DIR}") + list(APPEND CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES "${CUDAToolkit_LIBRARY_DIR}") elseif(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA") set(_nvcc_log "") string(REPLACE "\r" "" _nvcc_output_orig "${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}") diff --git a/Modules/CMakeDetermineOBJCCompiler.cmake b/Modules/CMakeDetermineOBJCCompiler.cmake index ad13eab..11b47fd 100644 --- a/Modules/CMakeDetermineOBJCCompiler.cmake +++ b/Modules/CMakeDetermineOBJCCompiler.cmake @@ -34,16 +34,19 @@ else() if(NOT CMAKE_OBJC_COMPILER) set(CMAKE_OBJC_COMPILER_INIT NOTFOUND) - # prefer the environment variable OBJC - if($ENV{OBJC} MATCHES ".+") - get_filename_component(CMAKE_OBJC_COMPILER_INIT $ENV{OBJC} PROGRAM PROGRAM_ARGS CMAKE_OBJC_FLAGS_ENV_INIT) - if(CMAKE_OBJC_FLAGS_ENV_INIT) - set(CMAKE_OBJC_COMPILER_ARG1 "${CMAKE_OBJC_FLAGS_ENV_INIT}" CACHE STRING "First argument to Objective-C compiler") + # prefer the environment variable OBJC or CC + foreach(var OBJC CC) + if($ENV{${var}} MATCHES ".+") + get_filename_component(CMAKE_OBJC_COMPILER_INIT $ENV{${var}} PROGRAM PROGRAM_ARGS CMAKE_OBJC_FLAGS_ENV_INIT) + if(CMAKE_OBJC_FLAGS_ENV_INIT) + set(CMAKE_OBJC_COMPILER_ARG1 "${CMAKE_OBJC_FLAGS_ENV_INIT}" CACHE STRING "First argument to Objective-C compiler") + endif() + if(NOT EXISTS ${CMAKE_OBJC_COMPILER_INIT}) + message(FATAL_ERROR "Could not find compiler set in environment variable ${var}:\n $ENV{${var}}") + endif() + break() endif() - if(NOT EXISTS ${CMAKE_OBJC_COMPILER_INIT}) - message(FATAL_ERROR "Could not find compiler set in environment variable OBJC:\n$ENV{OBJC}.") - endif() - endif() + endforeach() # next try prefer the compiler specified by the generator if(CMAKE_GENERATOR_OBJC) diff --git a/Modules/CMakeDetermineOBJCXXCompiler.cmake b/Modules/CMakeDetermineOBJCXXCompiler.cmake index 2cf5119..99ad6c3 100644 --- a/Modules/CMakeDetermineOBJCXXCompiler.cmake +++ b/Modules/CMakeDetermineOBJCXXCompiler.cmake @@ -36,16 +36,19 @@ else() if(NOT CMAKE_OBJCXX_COMPILER) set(CMAKE_OBJCXX_COMPILER_INIT NOTFOUND) - # prefer the environment variable OBJCXX - if($ENV{OBJCXX} MATCHES ".+") - get_filename_component(CMAKE_OBJCXX_COMPILER_INIT $ENV{OBJCXX} PROGRAM PROGRAM_ARGS CMAKE_OBJCXX_FLAGS_ENV_INIT) - if(CMAKE_OBJCXX_FLAGS_ENV_INIT) - set(CMAKE_OBJCXX_COMPILER_ARG1 "${CMAKE_OBJCXX_FLAGS_ENV_INIT}" CACHE STRING "First argument to Objective-C++ compiler") + # prefer the environment variable OBJCXX or CXX + foreach(var OBJCXX CXX) + if($ENV{${var}} MATCHES ".+") + get_filename_component(CMAKE_OBJCXX_COMPILER_INIT $ENV{${var}} PROGRAM PROGRAM_ARGS CMAKE_OBJCXX_FLAGS_ENV_INIT) + if(CMAKE_OBJCXX_FLAGS_ENV_INIT) + set(CMAKE_OBJCXX_COMPILER_ARG1 "${CMAKE_OBJCXX_FLAGS_ENV_INIT}" CACHE STRING "First argument to Objective-C++ compiler") + endif() + if(NOT EXISTS ${CMAKE_OBJCXX_COMPILER_INIT}) + message(FATAL_ERROR "Could not find compiler set in environment variable ${var}:\n $ENV{${var}}") + endif() + break() endif() - if(NOT EXISTS ${CMAKE_OBJCXX_COMPILER_INIT}) - message(FATAL_ERROR "Could not find compiler set in environment variable OBJCXX:\n$ENV{OBJCXX}.\n${CMAKE_OBJCXX_COMPILER_INIT}") - endif() - endif() + endforeach() # next prefer the generator specified compiler if(CMAKE_GENERATOR_OBJCXX) diff --git a/Modules/CMakeTestCUDACompiler.cmake b/Modules/CMakeTestCUDACompiler.cmake index 05811a8..b3b62bd 100644 --- a/Modules/CMakeTestCUDACompiler.cmake +++ b/Modules/CMakeTestCUDACompiler.cmake @@ -74,20 +74,27 @@ else() # - 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) - list(REMOVE_ITEM CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES cudart cudart_static cudadevrt) + 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) - # Remove the CUDA Toolkit include directories from the set of - # implicit system include directories. - # This resolves the issue that NVCC doesn't specify these - # includes as SYSTEM includes when compiling device code, and sometimes - # they contain headers that generate warnings, so let users mark them - # as SYSTEM explicitly - if(CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES) - list(REMOVE_ITEM CMAKE_CUDA_IMPLICIT_INCLUDE_DIRECTORIES - ${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES} - ) + if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA") + # Remove the CUDA Toolkit include directories from the set of + # implicit system include directories. + # This resolves the issue that NVCC doesn't specify these + # includes as SYSTEM includes when compiling device code, and sometimes + # they contain headers that generate warnings, so let users mark them + # as SYSTEM explicitly + if(CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES) + list(REMOVE_ITEM CMAKE_CUDA_IMPLICIT_INCLUDE_DIRECTORIES + ${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES} + ) + endif() endif() # Re-configure to save learned information. diff --git a/Modules/Compiler/Clang-CUDA.cmake b/Modules/Compiler/Clang-CUDA.cmake new file mode 100644 index 0000000..a970985 --- /dev/null +++ b/Modules/Compiler/Clang-CUDA.cmake @@ -0,0 +1,25 @@ +include(Compiler/Clang) +__compiler_clang(CUDA) + +# C++03 isn't supported for CXX, but is for CUDA, so we need to set these manually. +# Do this before __compiler_clang_cxx_standards() since that adds the feature. +set(CMAKE_CUDA03_STANDARD_COMPILE_OPTION "-std=c++03") +set(CMAKE_CUDA03_EXTENSION_COMPILE_OPTION "-std=gnu++03") +__compiler_clang_cxx_standards(CUDA) + +set(CMAKE_CUDA_COMPILER_HAS_DEVICE_LINK_PHASE TRUE) +set(_CMAKE_COMPILE_AS_CUDA_FLAG "-x cuda") +set(_CMAKE_CUDA_PTX_FLAG "--cuda-device-only -S") + +# RulePlaceholderExpander expands crosscompile variables like sysroot and target only for CMAKE_<LANG>_COMPILER. Override the default. +set(CMAKE_CUDA_LINK_EXECUTABLE "<CMAKE_CUDA_COMPILER> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>${__IMPLICT_LINKS}") +set(CMAKE_CUDA_CREATE_SHARED_LIBRARY "<CMAKE_CUDA_COMPILER> <CMAKE_SHARED_LIBRARY_CUDA_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CUDA_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>${__IMPLICT_LINKS}") + +set(CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT "STATIC") +set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_STATIC "cudadevrt;cudart_static") +set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_SHARED "cudadevrt;cudart") +set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_NONE "") + +if(UNIX) + list(APPEND CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_STATIC "rt" "pthread" "dl") +endif() diff --git a/Modules/Compiler/NVIDIA-CUDA.cmake b/Modules/Compiler/NVIDIA-CUDA.cmake index 4b09e6f..eb8d55c 100644 --- a/Modules/Compiler/NVIDIA-CUDA.cmake +++ b/Modules/Compiler/NVIDIA-CUDA.cmake @@ -64,6 +64,10 @@ set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_STATIC "cudadevrt;cudart_static") set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_SHARED "cudadevrt;cudart") set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_NONE "") +if(UNIX) + list(APPEND CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_STATIC "rt" "pthread" "dl") +endif() + if("x${CMAKE_CUDA_SIMULATE_ID}" STREQUAL "xMSVC") set(CMAKE_CUDA03_STANDARD_COMPILE_OPTION "") set(CMAKE_CUDA03_EXTENSION_COMPILE_OPTION "") diff --git a/Modules/FetchContent.cmake b/Modules/FetchContent.cmake index 400754c..45b50d4 100644 --- a/Modules/FetchContent.cmake +++ b/Modules/FetchContent.cmake @@ -108,9 +108,13 @@ Declaring Content Details The ``<contentOptions>`` can be any of the download or update/patch options that the :command:`ExternalProject_Add` command understands. The configure, build, install and test steps are explicitly disabled and therefore options - related to them will be ignored. In most cases, ``<contentOptions>`` will - just be a couple of options defining the download method and method-specific - details like a commit tag or archive hash. For example: + related to them will be ignored. The ``SOURCE_SUBDIR`` option is an + exception, see :command:`FetchContent_MakeAvailable` for details on how that + affects behavior. + + In most cases, ``<contentOptions>`` will just be a couple of options defining + the download method and method-specific details like a commit tag or archive + hash. For example: .. code-block:: cmake @@ -164,8 +168,9 @@ approach. The former generally follows this canonical pattern: The above is such a common pattern that, where no custom steps are needed between the calls to :command:`FetchContent_Populate` and :command:`add_subdirectory`, equivalent logic can be obtained by calling -:command:`FetchContent_MakeAvailable` instead (and should be preferred where -it meets the needs of the project). +:command:`FetchContent_MakeAvailable` instead. Where it meets the needs of +the project, :command:`FetchContent_MakeAvailable` should be preferred, as it +is simpler and provides additional features over the pattern above. .. command:: FetchContent_Populate @@ -335,6 +340,8 @@ it meets the needs of the project). ``${CMAKE_CURRENT_BINARY_DIR}/<lcName>-subbuild`` and it would be unusual to need to override this default. If a relative path is specified, it will be interpreted as relative to :variable:`CMAKE_CURRENT_BINARY_DIR`. + This option should not be confused with the ``SOURCE_SUBDIR`` option which + only affects the :command:`FetchContent_MakeAvailable` command. ``SOURCE_DIR``, ``BINARY_DIR`` The ``SOURCE_DIR`` and ``BINARY_DIR`` arguments are supported by @@ -409,15 +416,22 @@ it meets the needs of the project). This command implements the common pattern typically needed for most dependencies. It iterates over each of the named dependencies in turn - and for each one it loosely follows the same + and for each one it loosely follows the :ref:`canonical pattern <fetch-content-canonical-pattern>` as - presented at the beginning of this section. One small difference to - that pattern is that it will only call :command:`add_subdirectory` on the + presented at the beginning of this section. An important difference is + that :command:`add_subdirectory` will only be called on the populated content if there is a ``CMakeLists.txt`` file in its top level source directory. This allows the command to be used for dependencies that make downloaded content available at a known location but which do not need or support being added directly to the build. + The ``SOURCE_SUBDIR`` option can be given in the declared details to + instruct ``FetchContent_MakeAvailable()`` to look for a ``CMakeLists.txt`` + file in a subdirectory below the top level (i.e. the same way that + ``SOURCE_SUBDIR`` is used by the :command:`ExternalProject_Add` command). + ``SOURCE_SUBDIR`` must always be a relative path. See the next section + for an example of this option. + .. _`fetch-content-examples`: @@ -445,6 +459,23 @@ frameworks are available to the main build: # Catch2 will be defined and available to the rest of the build FetchContent_MakeAvailable(googletest Catch2) +If the sub-project's ``CMakeLists.txt`` file is not at the top level of its +source tree, the ``SOURCE_SUBDIR`` option can be used to tell ``FetchContent`` +where to find it. The following example shows how to use that option and +it also sets a variable which is meaningful to the subproject before pulling +it into the main build: + +.. code-block:: cmake + + include(FetchContent) + FetchContent_Declare( + protobuf + GIT_REPOSITORY https://github.com/protocolbuffers/protobuf.git + GIT_TAG v3.12.0 + SOURCE_SUBDIR cmake + ) + set(protobuf_BUILD_TESTS OFF) + FetchContent_MakeAvailable(protobuf) In more complex project hierarchies, the dependency relationships can be more complicated. Consider a hierarchy where ``projA`` is the top level project and @@ -1072,11 +1103,26 @@ macro(FetchContent_MakeAvailable) # can be treated that way. Protecting the call with the check # allows this function to be used for projects that just want # to ensure the content exists, such as to provide content at - # a known location. - if(EXISTS ${${contentNameLower}_SOURCE_DIR}/CMakeLists.txt) - add_subdirectory(${${contentNameLower}_SOURCE_DIR} - ${${contentNameLower}_BINARY_DIR}) + # a known location. We check the saved details for an optional + # SOURCE_SUBDIR which can be used in the same way as its meaning + # for ExternalProject. It won't matter if it was passed through + # to the ExternalProject sub-build, since it would have been + # ignored there. + set(__fc_srcdir "${${contentNameLower}_SOURCE_DIR}") + __FetchContent_getSavedDetails(${contentName} contentDetails) + if("${contentDetails}" STREQUAL "") + message(FATAL_ERROR "No details have been set for content: ${contentName}") + endif() + cmake_parse_arguments(__fc_arg "" "SOURCE_SUBDIR" "" ${contentDetails}) + if(NOT "${__fc_arg_SOURCE_SUBDIR}" STREQUAL "") + string(APPEND __fc_srcdir "/${__fc_arg_SOURCE_SUBDIR}") endif() + + if(EXISTS ${__fc_srcdir}/CMakeLists.txt) + add_subdirectory(${__fc_srcdir} ${${contentNameLower}_BINARY_DIR}) + endif() + + unset(__fc_srcdir) endif() endforeach() diff --git a/Modules/FindCUDAToolkit.cmake b/Modules/FindCUDAToolkit.cmake index 8d20ff9..b28892e 100644 --- a/Modules/FindCUDAToolkit.cmake +++ b/Modules/FindCUDAToolkit.cmake @@ -473,168 +473,8 @@ Result variables # ############################################################################### -# For NVCC we can easily deduce the SDK binary directory from the compiler path. -if(CMAKE_CUDA_COMPILER_LOADED AND NOT CUDAToolkit_BIN_DIR AND CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA") - get_filename_component(cuda_dir "${CMAKE_CUDA_COMPILER}" DIRECTORY) - set(CUDAToolkit_BIN_DIR "${cuda_dir}" CACHE PATH "") - mark_as_advanced(CUDAToolkit_BIN_DIR) - unset(cuda_dir) -endif() - -# Try language- or user-provided path first. -if(CUDAToolkit_BIN_DIR) - find_program(CUDAToolkit_NVCC_EXECUTABLE - NAMES nvcc nvcc.exe - PATHS ${CUDAToolkit_BIN_DIR} - NO_DEFAULT_PATH - ) -endif() - -# Search using CUDAToolkit_ROOT -find_program(CUDAToolkit_NVCC_EXECUTABLE - NAMES nvcc nvcc.exe - PATHS ENV CUDA_PATH - PATH_SUFFIXES bin -) - -# If the user specified CUDAToolkit_ROOT but nvcc could not be found, this is an error. -if (NOT CUDAToolkit_NVCC_EXECUTABLE AND (DEFINED CUDAToolkit_ROOT OR DEFINED ENV{CUDAToolkit_ROOT})) - # Declare error messages now, print later depending on find_package args. - set(fail_base "Could not find nvcc executable in path specified by") - set(cuda_root_fail "${fail_base} CUDAToolkit_ROOT=${CUDAToolkit_ROOT}") - set(env_cuda_root_fail "${fail_base} environment variable CUDAToolkit_ROOT=$ENV{CUDAToolkit_ROOT}") - - if (CUDAToolkit_FIND_REQUIRED) - if (DEFINED CUDAToolkit_ROOT) - message(FATAL_ERROR ${cuda_root_fail}) - elseif (DEFINED ENV{CUDAToolkit_ROOT}) - message(FATAL_ERROR ${env_cuda_root_fail}) - endif() - else() - if (NOT CUDAToolkit_FIND_QUIETLY) - if (DEFINED CUDAToolkit_ROOT) - message(STATUS ${cuda_root_fail}) - elseif (DEFINED ENV{CUDAToolkit_ROOT}) - message(STATUS ${env_cuda_root_fail}) - endif() - endif() - set(CUDAToolkit_FOUND FALSE) - unset(fail_base) - unset(cuda_root_fail) - unset(env_cuda_root_fail) - return() - endif() -endif() - -# CUDAToolkit_ROOT cmake / env variable not specified, try platform defaults. -# -# - Linux: /usr/local/cuda-X.Y -# - macOS: /Developer/NVIDIA/CUDA-X.Y -# - Windows: C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\vX.Y -# -# We will also search the default symlink location /usr/local/cuda first since -# if CUDAToolkit_ROOT is not specified, it is assumed that the symlinked -# directory is the desired location. -if (NOT CUDAToolkit_NVCC_EXECUTABLE) - if (UNIX) - if (NOT APPLE) - set(platform_base "/usr/local/cuda-") - else() - set(platform_base "/Developer/NVIDIA/CUDA-") - endif() - else() - set(platform_base "C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\v") - endif() - - # Build out a descending list of possible cuda installations, e.g. - file(GLOB possible_paths "${platform_base}*") - # Iterate the glob results and create a descending list. - set(possible_versions) - foreach (p ${possible_paths}) - # Extract version number from end of string - string(REGEX MATCH "[0-9][0-9]?\\.[0-9]$" p_version ${p}) - if (IS_DIRECTORY ${p} AND p_version) - list(APPEND possible_versions ${p_version}) - endif() - endforeach() - - # Cannot use list(SORT) because that is alphabetical, we need numerical. - # NOTE: this is not an efficient sorting strategy. But even if a user had - # every possible version of CUDA installed, this wouldn't create any - # significant overhead. - set(versions) - foreach (v ${possible_versions}) - list(LENGTH versions num_versions) - # First version, nothing to compare with so just append. - if (num_versions EQUAL 0) - list(APPEND versions ${v}) - else() - # Loop through list. Insert at an index when comparison is - # VERSION_GREATER since we want a descending list. Duplicates will not - # happen since this came from a glob list of directories. - set(i 0) - set(early_terminate FALSE) - while (i LESS num_versions) - list(GET versions ${i} curr) - if (v VERSION_GREATER curr) - list(INSERT versions ${i} ${v}) - set(early_terminate TRUE) - break() - endif() - math(EXPR i "${i} + 1") - endwhile() - # If it did not get inserted, place it at the end. - if (NOT early_terminate) - list(APPEND versions ${v}) - endif() - endif() - endforeach() - - # With a descending list of versions, populate possible paths to search. - set(search_paths) - foreach (v ${versions}) - list(APPEND search_paths "${platform_base}${v}") - endforeach() - - # Force the global default /usr/local/cuda to the front on Unix. - if (UNIX) - list(INSERT search_paths 0 "/usr/local/cuda") - endif() - - # Now search for nvcc again using the platform default search paths. - find_program(CUDAToolkit_NVCC_EXECUTABLE - NAMES nvcc nvcc.exe - PATHS ${search_paths} - PATH_SUFFIXES bin - ) - - # We are done with these variables now, cleanup for caller. - unset(platform_base) - unset(possible_paths) - unset(possible_versions) - unset(versions) - unset(i) - unset(early_terminate) - unset(search_paths) - - if (NOT CUDAToolkit_NVCC_EXECUTABLE) - if (CUDAToolkit_FIND_REQUIRED) - message(FATAL_ERROR "Could not find nvcc, please set CUDAToolkit_ROOT.") - elseif(NOT CUDAToolkit_FIND_QUIETLY) - message(STATUS "Could not find nvcc, please set CUDAToolkit_ROOT.") - endif() - - set(CUDAToolkit_FOUND FALSE) - return() - endif() -endif() - -if(NOT CUDAToolkit_BIN_DIR AND CUDAToolkit_NVCC_EXECUTABLE) - get_filename_component(cuda_dir "${CUDAToolkit_NVCC_EXECUTABLE}" DIRECTORY) - set(CUDAToolkit_BIN_DIR "${cuda_dir}" CACHE PATH "" FORCE) - mark_as_advanced(CUDAToolkit_BIN_DIR) - unset(cuda_dir) -endif() +# Include shared CUDA toolkit location code. +include(Internal/CUDAToolkit) if(CUDAToolkit_NVCC_EXECUTABLE AND CUDAToolkit_NVCC_EXECUTABLE STREQUAL CMAKE_CUDA_COMPILER) @@ -658,72 +498,22 @@ else() unset(NVCC_OUT) endif() - -get_filename_component(CUDAToolkit_ROOT_DIR ${CUDAToolkit_BIN_DIR} DIRECTORY ABSOLUTE) - -# Handle cross compilation -if(CMAKE_CROSSCOMPILING) - if(CMAKE_SYSTEM_PROCESSOR STREQUAL "armv7-a") - # Support for NVPACK - set (CUDAToolkit_TARGET_NAME "armv7-linux-androideabi") - elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "arm") - # Support for arm cross compilation - set(CUDAToolkit_TARGET_NAME "armv7-linux-gnueabihf") - elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64") - # Support for aarch64 cross compilation - if (ANDROID_ARCH_NAME STREQUAL "arm64") - set(CUDAToolkit_TARGET_NAME "aarch64-linux-androideabi") - else() - set(CUDAToolkit_TARGET_NAME "aarch64-linux") - endif (ANDROID_ARCH_NAME STREQUAL "arm64") - elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") - set(CUDAToolkit_TARGET_NAME "x86_64-linux") - endif() - - if (EXISTS "${CUDAToolkit_ROOT_DIR}/targets/${CUDAToolkit_TARGET_NAME}") - set(CUDAToolkit_TARGET_DIR "${CUDAToolkit_ROOT_DIR}/targets/${CUDAToolkit_TARGET_NAME}") - # add known CUDA target root path to the set of directories we search for programs, libraries and headers - list(PREPEND CMAKE_FIND_ROOT_PATH "${CUDAToolkit_TARGET_DIR}") - - # Mark that we need to pop the root search path changes after we have - # found all cuda libraries so that searches for our cross-compilation - # libraries work when another cuda sdk is in CMAKE_PREFIX_PATH or - # PATh - set(_CUDAToolkit_Pop_ROOT_PATH True) - endif() -else() - # Not cross compiling - set(CUDAToolkit_TARGET_DIR "${CUDAToolkit_ROOT_DIR}") - # Now that we have the real ROOT_DIR, find components inside it. - list(APPEND CMAKE_PREFIX_PATH ${CUDAToolkit_ROOT_DIR}) - - # Mark that we need to pop the prefix path changes after we have - # found the cudart library. - set(_CUDAToolkit_Pop_Prefix True) +if(NOT CUDA_CUDART AND NOT CUDAToolkit_FIND_QUIETLY) + message(STATUS "Unable to find cudart library.") endif() - -# Find the include/ directory -find_path(CUDAToolkit_INCLUDE_DIR - NAMES cuda_runtime.h -) - -# And find the CUDA Runtime Library libcudart +# Find the CUDA Runtime Library libcudart find_library(CUDA_CUDART NAMES cudart PATH_SUFFIXES lib64 lib/x64 ) -if (NOT CUDA_CUDART) +if(NOT CUDA_CUDART) find_library(CUDA_CUDART NAMES cudart PATH_SUFFIXES lib64/stubs lib/x64/stubs ) endif() -if (NOT CUDA_CUDART AND NOT CUDAToolkit_FIND_QUIETLY) - message(STATUS "Unable to find cudart library.") -endif() - unset(CUDAToolkit_ROOT_DIR) if(_CUDAToolkit_Pop_Prefix) list(REMOVE_AT CMAKE_PREFIX_PATH -1) @@ -749,8 +539,8 @@ mark_as_advanced(CUDA_CUDART #----------------------------------------------------------------------------- # Construct result variables if(CUDAToolkit_FOUND) - set(CUDAToolkit_INCLUDE_DIRS ${CUDAToolkit_INCLUDE_DIR}) - get_filename_component(CUDAToolkit_LIBRARY_DIR ${CUDA_CUDART} DIRECTORY ABSOLUTE) + set(CUDAToolkit_INCLUDE_DIRS ${CUDAToolkit_INCLUDE_DIR}) + get_filename_component(CUDAToolkit_LIBRARY_DIR ${CUDA_CUDART} DIRECTORY ABSOLUTE) endif() #----------------------------------------------------------------------------- diff --git a/Modules/FindHDF5.cmake b/Modules/FindHDF5.cmake index c1888a4..8d71d27 100644 --- a/Modules/FindHDF5.cmake +++ b/Modules/FindHDF5.cmake @@ -36,7 +36,7 @@ Both the serial and parallel ``HDF5`` wrappers are considered and the first directory to contain either one will be used. In the event that both appear in the same directory the serial version is preferentially selected. This behavior can be reversed by setting the variable ``HDF5_PREFER_PARALLEL`` to -``True``. +``TRUE``. In addition to finding the includes and libraries required to compile an ``HDF5`` client application, this module also makes an effort to find @@ -139,28 +139,30 @@ if(NOT HDF5_FIND_COMPONENTS) else() set(HDF5_LANGUAGE_BINDINGS) # add the extra specified components, ensuring that they are valid. - set(FIND_HL OFF) - foreach(component IN LISTS HDF5_FIND_COMPONENTS) - list(FIND HDF5_VALID_LANGUAGE_BINDINGS ${component} component_location) - if(NOT component_location EQUAL -1) - list(APPEND HDF5_LANGUAGE_BINDINGS ${component}) - elseif(component STREQUAL "HL") - set(FIND_HL ON) - elseif(component STREQUAL "Fortran_HL") # only for compatibility + set(HDF5_FIND_HL OFF) + foreach(_component IN LISTS HDF5_FIND_COMPONENTS) + list(FIND HDF5_VALID_LANGUAGE_BINDINGS ${_component} _component_location) + if(NOT _component_location EQUAL -1) + list(APPEND HDF5_LANGUAGE_BINDINGS ${_component}) + elseif(_component STREQUAL "HL") + set(HDF5_FIND_HL ON) + elseif(_component STREQUAL "Fortran_HL") # only for compatibility list(APPEND HDF5_LANGUAGE_BINDINGS Fortran) - set(FIND_HL ON) - set(HDF5_FIND_REQUIRED_Fortran_HL False) - set(HDF5_FIND_REQUIRED_Fortran True) - set(HDF5_FIND_REQUIRED_HL True) + set(HDF5_FIND_HL ON) + set(HDF5_FIND_REQUIRED_Fortran_HL FALSE) + set(HDF5_FIND_REQUIRED_Fortran TRUE) + set(HDF5_FIND_REQUIRED_HL TRUE) else() - message(FATAL_ERROR "${component} is not a valid HDF5 component.") + message(FATAL_ERROR "${_component} is not a valid HDF5 component.") endif() endforeach() + unset(_component) + unset(_component_location) if(NOT HDF5_LANGUAGE_BINDINGS) - get_property(__langs GLOBAL PROPERTY ENABLED_LANGUAGES) - foreach(__lang IN LISTS __langs) - if(__lang MATCHES "^(C|CXX|Fortran)$") - list(APPEND HDF5_LANGUAGE_BINDINGS ${__lang}) + get_property(_langs GLOBAL PROPERTY ENABLED_LANGUAGES) + foreach(_lang IN LISTS _langs) + if(_lang MATCHES "^(C|CXX|Fortran)$") + list(APPEND HDF5_LANGUAGE_BINDINGS ${_lang}) endif() endforeach() endif() @@ -326,108 +328,109 @@ endfunction() # Invoke the HDF5 wrapper compiler. The compiler return value is stored to the # return_value argument, the text output is stored to the output variable. -macro( _HDF5_invoke_compiler language output return_value version is_parallel) - set(${version}) - if(HDF5_USE_STATIC_LIBRARIES) - set(lib_type_args -noshlib) - else() - set(lib_type_args -shlib) - endif() - set(scratch_dir ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/hdf5) - if("${language}" STREQUAL "C") - set(test_file ${scratch_dir}/cmake_hdf5_test.c) - elseif("${language}" STREQUAL "CXX") - set(test_file ${scratch_dir}/cmake_hdf5_test.cxx) - elseif("${language}" STREQUAL "Fortran") - set(test_file ${scratch_dir}/cmake_hdf5_test.f90) +function( _HDF5_invoke_compiler language output_var return_value_var version_var is_parallel_var) + set(is_parallel FALSE) + if(HDF5_USE_STATIC_LIBRARIES) + set(lib_type_args -noshlib) + else() + set(lib_type_args -shlib) + endif() + set(scratch_dir ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/hdf5) + if("${language}" STREQUAL "C") + set(test_file ${scratch_dir}/cmake_hdf5_test.c) + elseif("${language}" STREQUAL "CXX") + set(test_file ${scratch_dir}/cmake_hdf5_test.cxx) + elseif("${language}" STREQUAL "Fortran") + set(test_file ${scratch_dir}/cmake_hdf5_test.f90) + endif() + # Verify that the compiler wrapper can actually compile: sometimes the compiler + # wrapper exists, but not the compiler. E.g. Miniconda / Anaconda Python + execute_process( + COMMAND ${HDF5_${language}_COMPILER_EXECUTABLE} ${test_file} + RESULT_VARIABLE return_value + ) + if(return_value) + message(STATUS + "HDF5 ${language} compiler wrapper is unable to compile a minimal HDF5 program.") + else() + execute_process( + COMMAND ${HDF5_${language}_COMPILER_EXECUTABLE} -show ${lib_type_args} ${test_file} + OUTPUT_VARIABLE output + ERROR_VARIABLE output + RESULT_VARIABLE return_value + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if(return_value) + message(STATUS + "Unable to determine HDF5 ${language} flags from HDF5 wrapper.") endif() - # Verify that the compiler wrapper can actually compile: sometimes the compiler - # wrapper exists, but not the compiler. E.g. Miniconda / Anaconda Python execute_process( - COMMAND ${HDF5_${language}_COMPILER_EXECUTABLE} ${test_file} - RESULT_VARIABLE ${return_value} + COMMAND ${HDF5_${language}_COMPILER_EXECUTABLE} -showconfig + OUTPUT_VARIABLE config_output + ERROR_VARIABLE config_output + RESULT_VARIABLE return_value + OUTPUT_STRIP_TRAILING_WHITESPACE ) - if(NOT ${${return_value}} EQUAL 0) + if(return_value) message(STATUS - "HDF5 ${language} compiler wrapper is unable to compile a minimal HDF5 program.") - else() - execute_process( - COMMAND ${HDF5_${language}_COMPILER_EXECUTABLE} -show ${lib_type_args} ${test_file} - OUTPUT_VARIABLE ${output} - ERROR_VARIABLE ${output} - RESULT_VARIABLE ${return_value} - ) - if(NOT ${${return_value}} EQUAL 0) - message(STATUS - "Unable to determine HDF5 ${language} flags from HDF5 wrapper.") - endif() - execute_process( - COMMAND ${HDF5_${language}_COMPILER_EXECUTABLE} -showconfig - OUTPUT_VARIABLE config_output - ERROR_VARIABLE config_output - RESULT_VARIABLE config_return - ) - if(NOT ${return_value} EQUAL 0) - message( STATUS - "Unable to determine HDF5 ${language} version from HDF5 wrapper.") - endif() - string(REGEX MATCH "HDF5 Version: ([a-zA-Z0-9\\.\\-]*)" version_match "${config_output}") - if(version_match) - string(REPLACE "HDF5 Version: " "" ${version} "${version_match}") - string(REPLACE "-patch" "." ${version} "${${version}}") - endif() - if(config_output MATCHES "Parallel HDF5: yes") - set(${is_parallel} TRUE) - else() - set(${is_parallel} FALSE) - endif() + "Unable to determine HDF5 ${language} version_var from HDF5 wrapper.") endif() -endmacro() + string(REGEX MATCH "HDF5 Version: ([a-zA-Z0-9\\.\\-]*)" version "${config_output}") + if(version) + string(REPLACE "HDF5 Version: " "" version "${version}") + string(REPLACE "-patch" "." version "${version}") + endif() + if(config_output MATCHES "Parallel HDF5: yes") + set(is_parallel TRUE) + endif() + endif() + foreach(var output return_value version is_parallel) + set(${${var}_var} ${${var}} PARENT_SCOPE) + endforeach() +endfunction() # Parse a compile line for definitions, includes, library paths, and libraries. -macro( _HDF5_parse_compile_line - compile_line_var - include_paths - definitions - library_paths - libraries - libraries_hl) - - separate_arguments(_HDF5_COMPILE_ARGS NATIVE_COMMAND "${${compile_line_var}}") - - foreach(arg IN LISTS _HDF5_COMPILE_ARGS) - if("${arg}" MATCHES "^-I(.*)$") +function(_HDF5_parse_compile_line compile_line_var include_paths definitions + library_paths libraries libraries_hl) + + separate_arguments(_compile_args NATIVE_COMMAND "${${compile_line_var}}") + + foreach(_arg IN LISTS _compile_args) + if("${_arg}" MATCHES "^-I(.*)$") # include directory - list(APPEND ${include_paths} "${CMAKE_MATCH_1}") - elseif("${arg}" MATCHES "^-D(.*)$") + list(APPEND include_paths "${CMAKE_MATCH_1}") + elseif("${_arg}" MATCHES "^-D(.*)$") # compile definition - list(APPEND ${definitions} "-D${CMAKE_MATCH_1}") - elseif("${arg}" MATCHES "^-L(.*)$") + list(APPEND definitions "-D${CMAKE_MATCH_1}") + elseif("${_arg}" MATCHES "^-L(.*)$") # library search path - list(APPEND ${library_paths} "${CMAKE_MATCH_1}") - elseif("${arg}" MATCHES "^-l(hdf5.*hl.*)$") + list(APPEND library_paths "${CMAKE_MATCH_1}") + elseif("${_arg}" MATCHES "^-l(hdf5.*hl.*)$") # library name (hl) - list(APPEND ${libraries_hl} "${CMAKE_MATCH_1}") - elseif("${arg}" MATCHES "^-l(.*)$") + list(APPEND libraries_hl "${CMAKE_MATCH_1}") + elseif("${_arg}" MATCHES "^-l(.*)$") # library name - list(APPEND ${libraries} "${CMAKE_MATCH_1}") - elseif("${arg}" MATCHES "^(.:)?[/\\].*\\.(a|so|dylib|sl|lib)$") + list(APPEND libraries "${CMAKE_MATCH_1}") + elseif("${_arg}" MATCHES "^(.:)?[/\\].*\\.(a|so|dylib|sl|lib)$") # library file - if(NOT EXISTS "${arg}") + if(NOT EXISTS "${_arg}") continue() endif() - get_filename_component(_HDF5_LPATH "${arg}" DIRECTORY) - get_filename_component(_HDF5_LNAME "${arg}" NAME_WE) - string(REGEX REPLACE "^lib" "" _HDF5_LNAME "${_HDF5_LNAME}") - list(APPEND ${library_paths} "${_HDF5_LPATH}") - if(_HDF5_LNAME MATCHES "hdf5.*hl") - list(APPEND ${libraries_hl} "${_HDF5_LNAME}") + get_filename_component(_lpath "${_arg}" DIRECTORY) + get_filename_component(_lname "${_arg}" NAME_WE) + string(REGEX REPLACE "^lib" "" _lname "${_lname}") + list(APPEND library_paths "${_lpath}") + if(_lname MATCHES "hdf5.*hl") + list(APPEND libraries_hl "${_lname}") else() - list(APPEND ${libraries} "${_HDF5_LNAME}") + list(APPEND libraries "${_lname}") endif() endif() endforeach() -endmacro() + foreach(var include_paths definitions library_paths libraries libraries_hl) + set(${${var}_var} ${${var}} PARENT_SCOPE) + endforeach() +endfunction() # Select a preferred imported configuration from a target function(_HDF5_select_imported_config target imported_conf) @@ -537,10 +540,10 @@ if(NOT HDF5_FOUND AND NOT HDF5_NO_FIND_PACKAGE_CONFIG_FILE) set(HDF5_${_lang}_LIBRARY ${_hdf5_lang_location}) list(APPEND HDF5_LIBRARIES ${HDF5_${_lang}_TARGET}${_suffix}) set(HDF5_${_lang}_LIBRARIES ${HDF5_${_lang}_TARGET}${_suffix}) - set(HDF5_${_lang}_FOUND True) + set(HDF5_${_lang}_FOUND TRUE) endif() - if(FIND_HL) - get_target_property(__lang_hl_location ${HDF5_${_lang}_HL_TARGET}${_suffix} IMPORTED_IMPLIB_${_hdf5_imported_conf} ) + if(HDF5_FIND_HL) + get_target_property(_lang_hl_location ${HDF5_${_lang}_HL_TARGET}${_suffix} IMPORTED_IMPLIB_${_hdf5_imported_conf} ) if (NOT _hdf5_lang_hl_location) get_target_property(_hdf5_lang_hl_location ${HDF5_${_lang}_HL_TARGET}${_suffix} LOCATION_${_hdf5_imported_conf}) if (NOT _hdf5_hl_lang_location) @@ -551,7 +554,7 @@ if(NOT HDF5_FOUND AND NOT HDF5_NO_FIND_PACKAGE_CONFIG_FILE) set(HDF5_${_lang}_HL_LIBRARY ${_hdf5_lang_hl_location}) list(APPEND HDF5_HL_LIBRARIES ${HDF5_${_lang}_HL_TARGET}${_suffix}) set(HDF5_${_lang}_HL_LIBRARIES ${HDF5_${_lang}_HL_TARGET}${_suffix}) - set(HDF5_HL_FOUND True) + set(HDF5_HL_FOUND TRUE) endif() unset(_hdf5_lang_hl_location) endif() @@ -562,172 +565,177 @@ if(NOT HDF5_FOUND AND NOT HDF5_NO_FIND_PACKAGE_CONFIG_FILE) endif() if(NOT HDF5_FOUND) - set(_HDF5_NEED_TO_SEARCH False) - set(HDF5_COMPILER_NO_INTERROGATE True) + set(_HDF5_NEED_TO_SEARCH FALSE) + set(HDF5_COMPILER_NO_INTERROGATE TRUE) # Only search for languages we've enabled - foreach(__lang IN LISTS HDF5_LANGUAGE_BINDINGS) + foreach(_lang IN LISTS HDF5_LANGUAGE_BINDINGS) # First check to see if our regular compiler is one of wrappers - if(__lang STREQUAL "C") + if(_lang STREQUAL "C") _HDF5_test_regular_compiler_C( - HDF5_${__lang}_COMPILER_NO_INTERROGATE - HDF5_${__lang}_VERSION - HDF5_${__lang}_IS_PARALLEL) - elseif(__lang STREQUAL "CXX") + HDF5_${_lang}_COMPILER_NO_INTERROGATE + HDF5_${_lang}_VERSION + HDF5_${_lang}_IS_PARALLEL) + elseif(_lang STREQUAL "CXX") _HDF5_test_regular_compiler_CXX( - HDF5_${__lang}_COMPILER_NO_INTERROGATE - HDF5_${__lang}_VERSION - HDF5_${__lang}_IS_PARALLEL) - elseif(__lang STREQUAL "Fortran") + HDF5_${_lang}_COMPILER_NO_INTERROGATE + HDF5_${_lang}_VERSION + HDF5_${_lang}_IS_PARALLEL) + elseif(_lang STREQUAL "Fortran") _HDF5_test_regular_compiler_Fortran( - HDF5_${__lang}_COMPILER_NO_INTERROGATE - HDF5_${__lang}_IS_PARALLEL) + HDF5_${_lang}_COMPILER_NO_INTERROGATE + HDF5_${_lang}_IS_PARALLEL) else() continue() endif() - if(HDF5_${__lang}_COMPILER_NO_INTERROGATE) - message(STATUS "HDF5: Using hdf5 compiler wrapper for all ${__lang} compiling") - set(HDF5_${__lang}_FOUND True) - set(HDF5_${__lang}_COMPILER_EXECUTABLE_NO_INTERROGATE - "${CMAKE_${__lang}_COMPILER}" - CACHE FILEPATH "HDF5 ${__lang} compiler wrapper") - set(HDF5_${__lang}_DEFINITIONS) - set(HDF5_${__lang}_INCLUDE_DIRS) - set(HDF5_${__lang}_LIBRARIES) - set(HDF5_${__lang}_HL_LIBRARIES) - - mark_as_advanced(HDF5_${__lang}_COMPILER_EXECUTABLE_NO_INTERROGATE) - - set(HDF5_${__lang}_FOUND True) - set(HDF5_HL_FOUND True) + if(HDF5_${_lang}_COMPILER_NO_INTERROGATE) + if(HDF5_FIND_DEBUG) + message(STATUS "HDF5: Using hdf5 compiler wrapper for all ${_lang} compiling") + endif() + set(HDF5_${_lang}_FOUND TRUE) + set(HDF5_${_lang}_COMPILER_EXECUTABLE_NO_INTERROGATE + "${CMAKE_${_lang}_COMPILER}" + CACHE FILEPATH "HDF5 ${_lang} compiler wrapper") + set(HDF5_${_lang}_DEFINITIONS) + set(HDF5_${_lang}_INCLUDE_DIRS) + set(HDF5_${_lang}_LIBRARIES) + set(HDF5_${_lang}_HL_LIBRARIES) + + mark_as_advanced(HDF5_${_lang}_COMPILER_EXECUTABLE_NO_INTERROGATE) + + set(HDF5_${_lang}_FOUND TRUE) + set(HDF5_HL_FOUND TRUE) else() - set(HDF5_COMPILER_NO_INTERROGATE False) + set(HDF5_COMPILER_NO_INTERROGATE FALSE) # If this language isn't using the wrapper, then try to seed the # search options with the wrapper - find_program(HDF5_${__lang}_COMPILER_EXECUTABLE - NAMES ${HDF5_${__lang}_COMPILER_NAMES} NAMES_PER_DIR + find_program(HDF5_${_lang}_COMPILER_EXECUTABLE + NAMES ${HDF5_${_lang}_COMPILER_NAMES} NAMES_PER_DIR HINTS ${HDF5_ROOT} PATH_SUFFIXES bin Bin - DOC "HDF5 ${__lang} Wrapper compiler. Used only to detect HDF5 compile flags." + DOC "HDF5 ${_lang} Wrapper compiler. Used only to detect HDF5 compile flags." ${_HDF5_SEARCH_OPTS} ) - mark_as_advanced( HDF5_${__lang}_COMPILER_EXECUTABLE ) - unset(HDF5_${__lang}_COMPILER_NAMES) - - if(HDF5_${__lang}_COMPILER_EXECUTABLE) - _HDF5_invoke_compiler(${__lang} HDF5_${__lang}_COMPILE_LINE - HDF5_${__lang}_RETURN_VALUE HDF5_${__lang}_VERSION HDF5_${__lang}_IS_PARALLEL) - if(HDF5_${__lang}_RETURN_VALUE EQUAL 0) - message(STATUS "HDF5: Using hdf5 compiler wrapper to determine ${__lang} configuration") - _HDF5_parse_compile_line( HDF5_${__lang}_COMPILE_LINE - HDF5_${__lang}_INCLUDE_DIRS - HDF5_${__lang}_DEFINITIONS - HDF5_${__lang}_LIBRARY_DIRS - HDF5_${__lang}_LIBRARY_NAMES - HDF5_${__lang}_HL_LIBRARY_NAMES + mark_as_advanced( HDF5_${_lang}_COMPILER_EXECUTABLE ) + unset(HDF5_${_lang}_COMPILER_NAMES) + + if(HDF5_${_lang}_COMPILER_EXECUTABLE) + _HDF5_invoke_compiler(${_lang} HDF5_${_lang}_COMPILE_LINE + HDF5_${_lang}_RETURN_VALUE HDF5_${_lang}_VERSION HDF5_${_lang}_IS_PARALLEL) + if(HDF5_${_lang}_RETURN_VALUE EQUAL 0) + if(HDF5_FIND_DEBUG) + message(STATUS "HDF5: Using hdf5 compiler wrapper to determine ${_lang} configuration") + endif() + _HDF5_parse_compile_line( HDF5_${_lang}_COMPILE_LINE + HDF5_${_lang}_INCLUDE_DIRS + HDF5_${_lang}_DEFINITIONS + HDF5_${_lang}_LIBRARY_DIRS + HDF5_${_lang}_LIBRARY_NAMES + HDF5_${_lang}_HL_LIBRARY_NAMES ) - set(HDF5_${__lang}_LIBRARIES) + set(HDF5_${_lang}_LIBRARIES) - foreach(L IN LISTS HDF5_${__lang}_LIBRARY_NAMES) + foreach(_lib IN LISTS HDF5_${_lang}_LIBRARY_NAMES) set(_HDF5_SEARCH_NAMES_LOCAL) - if("x${L}" MATCHES "hdf5") + if("x${_lib}" MATCHES "hdf5") # hdf5 library set(_HDF5_SEARCH_OPTS_LOCAL ${_HDF5_SEARCH_OPTS}) if(HDF5_USE_STATIC_LIBRARIES) if(WIN32) - set(_HDF5_SEARCH_NAMES_LOCAL lib${L}) + set(_HDF5_SEARCH_NAMES_LOCAL lib${_lib}) else() - set(_HDF5_SEARCH_NAMES_LOCAL lib${L}.a) + set(_HDF5_SEARCH_NAMES_LOCAL lib${_lib}.a) endif() endif() else() # external library set(_HDF5_SEARCH_OPTS_LOCAL) endif() - find_library(HDF5_${__lang}_LIBRARY_${L} - NAMES ${_HDF5_SEARCH_NAMES_LOCAL} ${L} NAMES_PER_DIR - HINTS ${HDF5_${__lang}_LIBRARY_DIRS} + find_library(HDF5_${_lang}_LIBRARY_${_lib} + NAMES ${_HDF5_SEARCH_NAMES_LOCAL} ${_lib} NAMES_PER_DIR + HINTS ${HDF5_${_lang}_LIBRARY_DIRS} ${HDF5_ROOT} ${_HDF5_SEARCH_OPTS_LOCAL} ) unset(_HDF5_SEARCH_OPTS_LOCAL) unset(_HDF5_SEARCH_NAMES_LOCAL) - if(HDF5_${__lang}_LIBRARY_${L}) - list(APPEND HDF5_${__lang}_LIBRARIES ${HDF5_${__lang}_LIBRARY_${L}}) + if(HDF5_${_lang}_LIBRARY_${_lib}) + list(APPEND HDF5_${_lang}_LIBRARIES ${HDF5_${_lang}_LIBRARY_${_lib}}) else() - list(APPEND HDF5_${__lang}_LIBRARIES ${L}) + list(APPEND HDF5_${_lang}_LIBRARIES ${_lib}) endif() endforeach() - if(FIND_HL) - set(HDF5_${__lang}_HL_LIBRARIES) - foreach(L IN LISTS HDF5_${__lang}_HL_LIBRARY_NAMES) + if(HDF5_FIND_HL) + set(HDF5_${_lang}_HL_LIBRARIES) + foreach(_lib IN LISTS HDF5_${_lang}_HL_LIBRARY_NAMES) set(_HDF5_SEARCH_NAMES_LOCAL) - if("x${L}" MATCHES "hdf5") + if("x${_lib}" MATCHES "hdf5") # hdf5 library set(_HDF5_SEARCH_OPTS_LOCAL ${_HDF5_SEARCH_OPTS}) if(HDF5_USE_STATIC_LIBRARIES) if(WIN32) - set(_HDF5_SEARCH_NAMES_LOCAL lib${L}) + set(_HDF5_SEARCH_NAMES_LOCAL lib${_lib}) else() - set(_HDF5_SEARCH_NAMES_LOCAL lib${L}.a) + set(_HDF5_SEARCH_NAMES_LOCAL lib${_lib}.a) endif() endif() else() # external library set(_HDF5_SEARCH_OPTS_LOCAL) endif() - find_library(HDF5_${__lang}_LIBRARY_${L} - NAMES ${_HDF5_SEARCH_NAMES_LOCAL} ${L} NAMES_PER_DIR - HINTS ${HDF5_${__lang}_LIBRARY_DIRS} + find_library(HDF5_${_lang}_LIBRARY_${_lib} + NAMES ${_HDF5_SEARCH_NAMES_LOCAL} ${_lib} NAMES_PER_DIR + HINTS ${HDF5_${_lang}_LIBRARY_DIRS} ${HDF5_ROOT} ${_HDF5_SEARCH_OPTS_LOCAL} ) unset(_HDF5_SEARCH_OPTS_LOCAL) unset(_HDF5_SEARCH_NAMES_LOCAL) - if(HDF5_${__lang}_LIBRARY_${L}) - list(APPEND HDF5_${__lang}_HL_LIBRARIES ${HDF5_${__lang}_LIBRARY_${L}}) + if(HDF5_${_lang}_LIBRARY_${_lib}) + list(APPEND HDF5_${_lang}_HL_LIBRARIES ${HDF5_${_lang}_LIBRARY_${_lib}}) else() - list(APPEND HDF5_${__lang}_HL_LIBRARIES ${L}) + list(APPEND HDF5_${_lang}_HL_LIBRARIES ${_lib}) endif() endforeach() - set(HDF5_HL_FOUND True) + set(HDF5_HL_FOUND TRUE) endif() - set(HDF5_${__lang}_FOUND True) - _HDF5_remove_duplicates_from_beginning(HDF5_${__lang}_DEFINITIONS) - _HDF5_remove_duplicates_from_beginning(HDF5_${__lang}_INCLUDE_DIRS) - _HDF5_remove_duplicates_from_beginning(HDF5_${__lang}_LIBRARIES) - _HDF5_remove_duplicates_from_beginning(HDF5_${__lang}_HL_LIBRARIES) + set(HDF5_${_lang}_FOUND TRUE) + _HDF5_remove_duplicates_from_beginning(HDF5_${_lang}_DEFINITIONS) + _HDF5_remove_duplicates_from_beginning(HDF5_${_lang}_INCLUDE_DIRS) + _HDF5_remove_duplicates_from_beginning(HDF5_${_lang}_LIBRARIES) + _HDF5_remove_duplicates_from_beginning(HDF5_${_lang}_HL_LIBRARIES) else() - set(_HDF5_NEED_TO_SEARCH True) + set(_HDF5_NEED_TO_SEARCH TRUE) endif() else() - set(_HDF5_NEED_TO_SEARCH True) + set(_HDF5_NEED_TO_SEARCH TRUE) endif() endif() - if(HDF5_${__lang}_VERSION) + if(HDF5_${_lang}_VERSION) if(NOT HDF5_VERSION) - set(HDF5_VERSION ${HDF5_${__lang}_VERSION}) - elseif(NOT HDF5_VERSION VERSION_EQUAL HDF5_${__lang}_VERSION) - message(WARNING "HDF5 Version found for language ${__lang}, ${HDF5_${__lang}_VERSION} is different than previously found version ${HDF5_VERSION}") + set(HDF5_VERSION ${HDF5_${_lang}_VERSION}) + elseif(NOT HDF5_VERSION VERSION_EQUAL HDF5_${_lang}_VERSION) + message(WARNING "HDF5 Version found for language ${_lang}, ${HDF5_${_lang}_VERSION} is different than previously found version ${HDF5_VERSION}") endif() endif() - if(DEFINED HDF5_${__lang}_IS_PARALLEL) + if(DEFINED HDF5_${_lang}_IS_PARALLEL) if(NOT DEFINED HDF5_IS_PARALLEL) - set(HDF5_IS_PARALLEL ${HDF5_${__lang}_IS_PARALLEL}) - elseif(NOT HDF5_IS_PARALLEL AND HDF5_${__lang}_IS_PARALLEL) - message(WARNING "HDF5 found for language ${__lang} is parallel but previously found language is not parallel.") - elseif(HDF5_IS_PARALLEL AND NOT HDF5_${__lang}_IS_PARALLEL) - message(WARNING "HDF5 found for language ${__lang} is not parallel but previously found language is parallel.") + set(HDF5_IS_PARALLEL ${HDF5_${_lang}_IS_PARALLEL}) + elseif(NOT HDF5_IS_PARALLEL AND HDF5_${_lang}_IS_PARALLEL) + message(WARNING "HDF5 found for language ${_lang} is parallel but previously found language is not parallel.") + elseif(HDF5_IS_PARALLEL AND NOT HDF5_${_lang}_IS_PARALLEL) + message(WARNING "HDF5 found for language ${_lang} is not parallel but previously found language is parallel.") endif() endif() endforeach() + unset(_lib) else() - set(_HDF5_NEED_TO_SEARCH True) + set(_HDF5_NEED_TO_SEARCH TRUE) endif() if(NOT HDF5_FOUND AND HDF5_COMPILER_NO_INTERROGATE) # No arguments necessary, all languages can use the compiler wrappers - set(HDF5_FOUND True) + set(HDF5_FOUND TRUE) set(HDF5_METHOD "Included by compiler wrappers") set(HDF5_REQUIRED_VARS HDF5_METHOD) elseif(NOT HDF5_FOUND AND NOT _HDF5_NEED_TO_SEARCH) @@ -736,14 +744,14 @@ elseif(NOT HDF5_FOUND AND NOT _HDF5_NEED_TO_SEARCH) set(HDF5_INCLUDE_DIRS) set(HDF5_LIBRARIES) set(HDF5_HL_LIBRARIES) - foreach(__lang IN LISTS HDF5_LANGUAGE_BINDINGS) - if(HDF5_${__lang}_FOUND) - if(NOT HDF5_${__lang}_COMPILER_NO_INTERROGATE) - list(APPEND HDF5_DEFINITIONS ${HDF5_${__lang}_DEFINITIONS}) - list(APPEND HDF5_INCLUDE_DIRS ${HDF5_${__lang}_INCLUDE_DIRS}) - list(APPEND HDF5_LIBRARIES ${HDF5_${__lang}_LIBRARIES}) - if(FIND_HL) - list(APPEND HDF5_HL_LIBRARIES ${HDF5_${__lang}_HL_LIBRARIES}) + foreach(_lang IN LISTS HDF5_LANGUAGE_BINDINGS) + if(HDF5_${_lang}_FOUND) + if(NOT HDF5_${_lang}_COMPILER_NO_INTERROGATE) + list(APPEND HDF5_DEFINITIONS ${HDF5_${_lang}_DEFINITIONS}) + list(APPEND HDF5_INCLUDE_DIRS ${HDF5_${_lang}_INCLUDE_DIRS}) + list(APPEND HDF5_LIBRARIES ${HDF5_${_lang}_LIBRARIES}) + if(HDF5_FIND_HL) + list(APPEND HDF5_HL_LIBRARIES ${HDF5_${_lang}_HL_LIBRARIES}) endif() endif() endif() @@ -752,9 +760,9 @@ elseif(NOT HDF5_FOUND AND NOT _HDF5_NEED_TO_SEARCH) _HDF5_remove_duplicates_from_beginning(HDF5_INCLUDE_DIRS) _HDF5_remove_duplicates_from_beginning(HDF5_LIBRARIES) _HDF5_remove_duplicates_from_beginning(HDF5_HL_LIBRARIES) - set(HDF5_FOUND True) + set(HDF5_FOUND TRUE) set(HDF5_REQUIRED_VARS HDF5_LIBRARIES) - if(FIND_HL) + if(HDF5_FIND_HL) list(APPEND HDF5_REQUIRED_VARS HDF5_HL_LIBRARIES) endif() endif() @@ -789,29 +797,29 @@ if( NOT HDF5_FOUND ) set(_inc_suffixes include/shared) endif() - foreach(__lang IN LISTS HDF5_LANGUAGE_BINDINGS) + foreach(_lang IN LISTS HDF5_LANGUAGE_BINDINGS) # find the HDF5 include directories - if("${__lang}" STREQUAL "Fortran") + if("${_lang}" STREQUAL "Fortran") set(HDF5_INCLUDE_FILENAME hdf5.mod HDF5.mod) - elseif("${__lang}" STREQUAL "CXX") + elseif("${_lang}" STREQUAL "CXX") set(HDF5_INCLUDE_FILENAME H5Cpp.h) else() set(HDF5_INCLUDE_FILENAME hdf5.h) endif() - find_path(HDF5_${__lang}_INCLUDE_DIR ${HDF5_INCLUDE_FILENAME} + find_path(HDF5_${_lang}_INCLUDE_DIR ${HDF5_INCLUDE_FILENAME} HINTS ${HDF5_ROOT} PATHS $ENV{HOME}/.local/include PATH_SUFFIXES include Include ${_inc_suffixes} ${_lib_suffixes} ${_HDF5_SEARCH_OPTS} ) - mark_as_advanced(HDF5_${__lang}_INCLUDE_DIR) + mark_as_advanced(HDF5_${_lang}_INCLUDE_DIR) # set the _DIRS variable as this is what the user will normally use - set(HDF5_${__lang}_INCLUDE_DIRS ${HDF5_${__lang}_INCLUDE_DIR}) - list(APPEND HDF5_INCLUDE_DIRS ${HDF5_${__lang}_INCLUDE_DIR}) + set(HDF5_${_lang}_INCLUDE_DIRS ${HDF5_${_lang}_INCLUDE_DIR}) + list(APPEND HDF5_INCLUDE_DIRS ${HDF5_${_lang}_INCLUDE_DIR}) # find the HDF5 libraries - foreach(LIB IN LISTS HDF5_${__lang}_LIBRARY_NAMES) + foreach(LIB IN LISTS HDF5_${_lang}_LIBRARY_NAMES) if(HDF5_USE_STATIC_LIBRARIES) # According to bug 1643 on the CMake bug tracker, this is the # preferred method for searching for a static library. @@ -841,18 +849,18 @@ if( NOT HDF5_FOUND ) ) select_library_configurations( HDF5_${LIB} ) - list(APPEND HDF5_${__lang}_LIBRARIES ${HDF5_${LIB}_LIBRARY}) + list(APPEND HDF5_${_lang}_LIBRARIES ${HDF5_${LIB}_LIBRARY}) endforeach() - if(HDF5_${__lang}_LIBRARIES) - set(HDF5_${__lang}_FOUND True) + if(HDF5_${_lang}_LIBRARIES) + set(HDF5_${_lang}_FOUND TRUE) endif() # Append the libraries for this language binding to the list of all # required libraries. - list(APPEND HDF5_LIBRARIES ${HDF5_${__lang}_LIBRARIES}) + list(APPEND HDF5_LIBRARIES ${HDF5_${_lang}_LIBRARIES}) - if(FIND_HL) - foreach(LIB IN LISTS HDF5_${__lang}_HL_LIBRARY_NAMES) + if(HDF5_FIND_HL) + foreach(LIB IN LISTS HDF5_${_lang}_HL_LIBRARY_NAMES) if(HDF5_USE_STATIC_LIBRARIES) # According to bug 1643 on the CMake bug tracker, this is the # preferred method for searching for a static library. @@ -879,16 +887,16 @@ if( NOT HDF5_FOUND ) ) select_library_configurations( HDF5_${LIB} ) - list(APPEND HDF5_${__lang}_HL_LIBRARIES ${HDF5_${LIB}_LIBRARY}) + list(APPEND HDF5_${_lang}_HL_LIBRARIES ${HDF5_${LIB}_LIBRARY}) endforeach() # Append the libraries for this language binding to the list of all # required libraries. - list(APPEND HDF5_HL_LIBRARIES ${HDF5_${__lang}_HL_LIBRARIES}) + list(APPEND HDF5_HL_LIBRARIES ${HDF5_${_lang}_HL_LIBRARIES}) endif() endforeach() - if(FIND_HL AND HDF5_HL_LIBRARIES) - set(HDF5_HL_FOUND True) + if(HDF5_FIND_HL AND HDF5_HL_LIBRARIES) + set(HDF5_HL_FOUND TRUE) endif() _HDF5_remove_duplicates_from_beginning(HDF5_DEFINITIONS) @@ -925,12 +933,14 @@ if( NOT HDF5_FOUND ) endif() endforeach() endforeach() + unset(_hdr) + unset(_dir) set( HDF5_IS_PARALLEL ${HDF5_IS_PARALLEL} CACHE BOOL "HDF5 library compiled with parallel IO support" ) mark_as_advanced( HDF5_IS_PARALLEL ) set(HDF5_REQUIRED_VARS HDF5_LIBRARIES HDF5_INCLUDE_DIRS) - if(FIND_HL) + if(HDF5_FIND_HL) list(APPEND HDF5_REQUIRED_VARS HDF5_HL_LIBRARIES) endif() endif() @@ -968,13 +978,15 @@ if (HDF5_FIND_DEBUG) message(STATUS "HDF5_INCLUDE_DIRS: ${HDF5_INCLUDE_DIRS}") message(STATUS "HDF5_LIBRARIES: ${HDF5_LIBRARIES}") message(STATUS "HDF5_HL_LIBRARIES: ${HDF5_HL_LIBRARIES}") - foreach(__lang IN LISTS HDF5_LANGUAGE_BINDINGS) - message(STATUS "HDF5_${__lang}_DEFINITIONS: ${HDF5_${__lang}_DEFINITIONS}") - message(STATUS "HDF5_${__lang}_INCLUDE_DIR: ${HDF5_${__lang}_INCLUDE_DIR}") - message(STATUS "HDF5_${__lang}_INCLUDE_DIRS: ${HDF5_${__lang}_INCLUDE_DIRS}") - message(STATUS "HDF5_${__lang}_LIBRARY: ${HDF5_${__lang}_LIBRARY}") - message(STATUS "HDF5_${__lang}_LIBRARIES: ${HDF5_${__lang}_LIBRARIES}") - message(STATUS "HDF5_${__lang}_HL_LIBRARY: ${HDF5_${__lang}_HL_LIBRARY}") - message(STATUS "HDF5_${__lang}_HL_LIBRARIES: ${HDF5_${__lang}_HL_LIBRARIES}") + foreach(_lang IN LISTS HDF5_LANGUAGE_BINDINGS) + message(STATUS "HDF5_${_lang}_DEFINITIONS: ${HDF5_${_lang}_DEFINITIONS}") + message(STATUS "HDF5_${_lang}_INCLUDE_DIR: ${HDF5_${_lang}_INCLUDE_DIR}") + message(STATUS "HDF5_${_lang}_INCLUDE_DIRS: ${HDF5_${_lang}_INCLUDE_DIRS}") + message(STATUS "HDF5_${_lang}_LIBRARY: ${HDF5_${_lang}_LIBRARY}") + message(STATUS "HDF5_${_lang}_LIBRARIES: ${HDF5_${_lang}_LIBRARIES}") + message(STATUS "HDF5_${_lang}_HL_LIBRARY: ${HDF5_${_lang}_HL_LIBRARY}") + message(STATUS "HDF5_${_lang}_HL_LIBRARIES: ${HDF5_${_lang}_HL_LIBRARIES}") endforeach() endif() +unset(_lang) +unset(_HDF5_NEED_TO_SEARCH) diff --git a/Modules/FindOpenSSL.cmake b/Modules/FindOpenSSL.cmake index af713d6..a813ab5 100644 --- a/Modules/FindOpenSSL.cmake +++ b/Modules/FindOpenSSL.cmake @@ -22,6 +22,27 @@ This module defines the following :prop_tgt:`IMPORTED` targets: The OpenSSL ``ssl`` library, if found. ``OpenSSL::Crypto`` The OpenSSL ``crypto`` library, if found. +``OpenSSL::applink`` + The OpenSSL ``applink`` components that might be need to be compiled into + projects under MSVC. This target is available only if found OpenSSL version + is not less than 0.9.8. By linking this target the above OpenSSL targets can + be linked even if the project has different MSVC runtime configurations with + the above OpenSSL targets. This target has no effect on plaforms other than + MSVC. + +NOTE: Due to how ``INTERFACE_SOURCES`` are consumed by the consuming target, +unless you certainly know what you are doing, it is always prefered to link +``OpenSSL::applink`` target as ``PRIVATE`` and to make sure that this target is +linked at most once for the whole dependency graph of any library or +executable: + +.. code-block:: cmake + + target_link_libraries(myTarget PRIVATE OpenSSL::applink) + +Otherwise you would probably encounter unexpected random problems when building +and linking, as both the ISO C and the ISO C++ standard claims almost nothing +about what a link process should be. Result Variables ^^^^^^^^^^^^^^^^ @@ -45,6 +66,10 @@ This module will set the following variables in your project: All OpenSSL libraries and their dependencies. ``OPENSSL_VERSION`` This is set to ``$major.$minor.$revision$patch`` (e.g. ``0.9.8s``). +``OPENSSL_APPLINK_SOURCE`` + The sources in the target ``OpenSSL::applink`` that is mentioned above. This + variable shall always be undefined if found openssl version is less than + 0.9.8 or if platform is not MSVC. Hints ^^^^^ @@ -524,6 +549,28 @@ if(OPENSSL_FOUND) endif() _OpenSSL_target_add_dependencies(OpenSSL::SSL) endif() + + if("${OPENSSL_VERSION_MAJOR}.${OPENSSL_VERSION_MAJOR}.${OPENSSL_VERSION_FIX}" VERSION_GREATER_EQUAL "0.9.8") + if(MSVC) + if(EXISTS "${OPENSSL_INCLUDE_DIR}") + set(_OPENSSL_applink_paths PATHS ${OPENSSL_INCLUDE_DIR}) + endif() + find_file(OPENSSL_APPLINK_SOURCE + NAMES + openssl/applink.c + ${_OPENSSL_applink_paths} + NO_DEFAULT_PATH) + if(OPENSSL_APPLINK_SOURCE) + set(_OPENSSL_applink_interface_srcs ${OPENSSL_APPLINK_SOURCE}) + endif() + endif() + if(NOT TARGET OpenSSL::applink) + add_library(OpenSSL::applink INTERFACE IMPORTED) + set_property(TARGET OpenSSL::applink APPEND + PROPERTY INTERFACE_SOURCES + ${_OPENSSL_applink_interface_srcs}) + endif() + endif() endif() # Restore the original find library ordering diff --git a/Modules/FindPython/Support.cmake b/Modules/FindPython/Support.cmake index cb400a5..1be0625 100644 --- a/Modules/FindPython/Support.cmake +++ b/Modules/FindPython/Support.cmake @@ -2600,6 +2600,12 @@ if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS NAMES_PER_DIR HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS} NO_DEFAULT_PATH) + # second try including CMAKE variables to catch-up non conventional layouts + find_library (_${_PYTHON_PREFIX}_LIBRARY_DEBUG + NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG} + NAMES_PER_DIR + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) endif() # retrieve runtime libraries diff --git a/Modules/FindSquish.cmake b/Modules/FindSquish.cmake index f4d4f29..16f5ab8 100644 --- a/Modules/FindSquish.cmake +++ b/Modules/FindSquish.cmake @@ -9,8 +9,7 @@ FindSquish -This module can be used to find Squish. Currently Squish versions 3 -and 4 are supported. +This module can be used to find Squish. :: @@ -39,12 +38,12 @@ and 4 are supported. -It provides the function squish_v4_add_test() for adding a squish test -to cmake using Squish 4.x: +It provides the function squish_add_test() for adding a squish test +to cmake using Squish >= 4.x: :: - squish_v4_add_test(cmakeTestName + squish_add_test(cmakeTestName AUT targetName SUITE suiteName TEST squishTestName [SETTINGSGROUP group] [PRE_COMMAND command] [POST_COMMAND command] ) @@ -78,9 +77,9 @@ The arguments have the following meaning: :: enable_testing() - find_package(Squish 4.0) + find_package(Squish 6.5) if (SQUISH_FOUND) - squish_v4_add_test(myTestName + squish_add_test(myTestName AUT myApp SUITE ${CMAKE_SOURCE_DIR}/tests/mySuite TEST someSquishTest @@ -105,19 +104,12 @@ provided: :: enable_testing() - find_package(Squish) + find_package(Squish 3.0) if (SQUISH_FOUND) squish_v3_add_test(myTestName myApplication testCase envVars testWrapper) endif () - -macro SQUISH_ADD_TEST(testName applicationUnderTest testCase envVars -testWrapper) - -:: - - This is deprecated. Use SQUISH_V3_ADD_TEST() if you are using Squish 3.x instead. #]=======================================================================] set(SQUISH_INSTALL_DIR_STRING "Directory containing the bin, doc, and lib directories for Squish; this should be the root of the installation directory.") @@ -170,9 +162,9 @@ endif() set(SQUISH_VERSION) -set(SQUISH_VERSION_MAJOR ) -set(SQUISH_VERSION_MINOR ) -set(SQUISH_VERSION_PATCH ) +set(SQUISH_VERSION_MAJOR) +set(SQUISH_VERSION_MINOR) +set(SQUISH_VERSION_PATCH) # record if executables are set if(SQUISH_CLIENT_EXECUTABLE) @@ -204,8 +196,8 @@ find_package_handle_standard_args(Squish REQUIRED_VARS SQUISH_INSTALL_DIR SQUI set(_SQUISH_MODULE_DIR "${CMAKE_CURRENT_LIST_DIR}") -macro(SQUISH_V3_ADD_TEST testName testAUT testCase envVars testWraper) - if("${SQUISH_VERSION_MAJOR}" STREQUAL "4") +macro(squish_v3_add_test testName testAUT testCase envVars testWraper) + if("${SQUISH_VERSION_MAJOR}" STRGREATER "3") message(STATUS "Using squish_v3_add_test(), but SQUISH_VERSION_MAJOR is ${SQUISH_VERSION_MAJOR}.\nThis may not work.") endif() @@ -228,16 +220,9 @@ macro(SQUISH_V3_ADD_TEST testName testAUT testCase envVars testWraper) endmacro() -macro(SQUISH_ADD_TEST) - message(STATUS "Using squish_add_test() is deprecated, use squish_v3_add_test() instead.") - squish_v3_add_test(${ARGV}) -endmacro() - - -function(SQUISH_V4_ADD_TEST testName) - - if(NOT "${SQUISH_VERSION_MAJOR}" STREQUAL "4") - message(STATUS "Using squish_v4_add_test(), but SQUISH_VERSION_MAJOR is ${SQUISH_VERSION_MAJOR}.\nThis may not work.") +function(squish_v4_add_test testName) + if(NOT "${SQUISH_VERSION_MAJOR}" STRGREATER "3") + message(STATUS "Using squish_add_test(), but SQUISH_VERSION_MAJOR is ${SQUISH_VERSION_MAJOR}.\nThis may not work.") endif() set(oneValueArgs AUT SUITE TEST SETTINGSGROUP PRE_COMMAND POST_COMMAND) @@ -296,3 +281,11 @@ function(SQUISH_V4_ADD_TEST testName) PROPERTIES FAIL_REGULAR_EXPRESSION "FAIL;FAILED;ERROR;FATAL" ) endfunction() + +macro(squish_add_test) + if("${SQUISH_VERSION_MAJOR}" STRGREATER "3") + squish_v4_add_test(${ARGV}) + else() + squish_v3_add_test(${ARGV}) + endif() +endmacro() diff --git a/Modules/Internal/CUDAToolkit.cmake b/Modules/Internal/CUDAToolkit.cmake new file mode 100644 index 0000000..ab1e568 --- /dev/null +++ b/Modules/Internal/CUDAToolkit.cmake @@ -0,0 +1,225 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +# This file is for sharing code for finding basic CUDA toolkit information between +# CMakeDetermineCUDACompiler.cmake and FindCUDAToolkit.cmake. + +# For NVCC we can easily deduce the SDK binary directory from the compiler path. +if(CMAKE_CUDA_COMPILER_LOADED AND NOT CUDAToolkit_BIN_DIR AND CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA") + get_filename_component(cuda_dir "${CMAKE_CUDA_COMPILER}" DIRECTORY) + set(CUDAToolkit_BIN_DIR "${cuda_dir}" CACHE PATH "") + mark_as_advanced(CUDAToolkit_BIN_DIR) + unset(cuda_dir) +endif() + +# Try language- or user-provided path first. +if(CUDAToolkit_BIN_DIR) + find_program(CUDAToolkit_NVCC_EXECUTABLE + NAMES nvcc nvcc.exe + PATHS ${CUDAToolkit_BIN_DIR} + NO_DEFAULT_PATH + ) +endif() + +# Search using CUDAToolkit_ROOT +find_program(CUDAToolkit_NVCC_EXECUTABLE + NAMES nvcc nvcc.exe + PATHS ENV CUDA_PATH + PATH_SUFFIXES bin +) + +# If the user specified CUDAToolkit_ROOT but nvcc could not be found, this is an error. +if(NOT CUDAToolkit_NVCC_EXECUTABLE AND (DEFINED CUDAToolkit_ROOT OR DEFINED ENV{CUDAToolkit_ROOT})) + # Declare error messages now, print later depending on find_package args. + set(fail_base "Could not find nvcc executable in path specified by") + set(cuda_root_fail "${fail_base} CUDAToolkit_ROOT=${CUDAToolkit_ROOT}") + set(env_cuda_root_fail "${fail_base} environment variable CUDAToolkit_ROOT=$ENV{CUDAToolkit_ROOT}") + + if(CUDAToolkit_FIND_REQUIRED) + if(DEFINED CUDAToolkit_ROOT) + message(FATAL_ERROR ${cuda_root_fail}) + elseif(DEFINED ENV{CUDAToolkit_ROOT}) + message(FATAL_ERROR ${env_cuda_root_fail}) + endif() + else() + if(NOT CUDAToolkit_FIND_QUIETLY) + if(DEFINED CUDAToolkit_ROOT) + message(STATUS ${cuda_root_fail}) + elseif(DEFINED ENV{CUDAToolkit_ROOT}) + message(STATUS ${env_cuda_root_fail}) + endif() + endif() + set(CUDAToolkit_FOUND FALSE) + unset(fail_base) + unset(cuda_root_fail) + unset(env_cuda_root_fail) + return() + endif() +endif() + +# CUDAToolkit_ROOT cmake / env variable not specified, try platform defaults. +# +# - Linux: /usr/local/cuda-X.Y +# - macOS: /Developer/NVIDIA/CUDA-X.Y +# - Windows: C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\vX.Y +# +# We will also search the default symlink location /usr/local/cuda first since +# if CUDAToolkit_ROOT is not specified, it is assumed that the symlinked +# directory is the desired location. +if(NOT CUDAToolkit_NVCC_EXECUTABLE) + if(UNIX) + if(NOT APPLE) + set(platform_base "/usr/local/cuda-") + else() + set(platform_base "/Developer/NVIDIA/CUDA-") + endif() + else() + set(platform_base "C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\v") + endif() + + # Build out a descending list of possible cuda installations, e.g. + file(GLOB possible_paths "${platform_base}*") + # Iterate the glob results and create a descending list. + set(possible_versions) + foreach (p ${possible_paths}) + # Extract version number from end of string + string(REGEX MATCH "[0-9][0-9]?\\.[0-9]$" p_version ${p}) + if(IS_DIRECTORY ${p} AND p_version) + list(APPEND possible_versions ${p_version}) + endif() + endforeach() + + # Cannot use list(SORT) because that is alphabetical, we need numerical. + # NOTE: this is not an efficient sorting strategy. But even if a user had + # every possible version of CUDA installed, this wouldn't create any + # significant overhead. + set(versions) + foreach (v ${possible_versions}) + list(LENGTH versions num_versions) + # First version, nothing to compare with so just append. + if(num_versions EQUAL 0) + list(APPEND versions ${v}) + else() + # Loop through list. Insert at an index when comparison is + # VERSION_GREATER since we want a descending list. Duplicates will not + # happen since this came from a glob list of directories. + set(i 0) + set(early_terminate FALSE) + while (i LESS num_versions) + list(GET versions ${i} curr) + if(v VERSION_GREATER curr) + list(INSERT versions ${i} ${v}) + set(early_terminate TRUE) + break() + endif() + math(EXPR i "${i} + 1") + endwhile() + # If it did not get inserted, place it at the end. + if(NOT early_terminate) + list(APPEND versions ${v}) + endif() + endif() + endforeach() + + # With a descending list of versions, populate possible paths to search. + set(search_paths) + foreach (v ${versions}) + list(APPEND search_paths "${platform_base}${v}") + endforeach() + + # Force the global default /usr/local/cuda to the front on Unix. + if(UNIX) + list(INSERT search_paths 0 "/usr/local/cuda") + endif() + + # Now search for nvcc again using the platform default search paths. + find_program(CUDAToolkit_NVCC_EXECUTABLE + NAMES nvcc nvcc.exe + PATHS ${search_paths} + PATH_SUFFIXES bin + ) + + # We are done with these variables now, cleanup for caller. + unset(platform_base) + unset(possible_paths) + unset(possible_versions) + unset(versions) + unset(i) + unset(early_terminate) + unset(search_paths) + + if(NOT CUDAToolkit_NVCC_EXECUTABLE) + if(CUDAToolkit_FIND_REQUIRED) + message(FATAL_ERROR "Could not find nvcc, please set CUDAToolkit_ROOT.") + elseif(NOT CUDAToolkit_FIND_QUIETLY) + message(STATUS "Could not find nvcc, please set CUDAToolkit_ROOT.") + endif() + + set(CUDAToolkit_FOUND FALSE) + return() + endif() +endif() + +if(NOT CUDAToolkit_BIN_DIR AND CUDAToolkit_NVCC_EXECUTABLE) + get_filename_component(cuda_dir "${CUDAToolkit_NVCC_EXECUTABLE}" DIRECTORY) + set(CUDAToolkit_BIN_DIR "${cuda_dir}" CACHE PATH "" FORCE) + mark_as_advanced(CUDAToolkit_BIN_DIR) + unset(cuda_dir) +endif() + +get_filename_component(CUDAToolkit_ROOT_DIR ${CUDAToolkit_BIN_DIR} DIRECTORY ABSOLUTE) + +# Handle cross compilation +if(CMAKE_CROSSCOMPILING) + if(CMAKE_SYSTEM_PROCESSOR STREQUAL "armv7-a") + # Support for NVPACK + set(CUDAToolkit_TARGET_NAME "armv7-linux-androideabi") + elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "arm") + # Support for arm cross compilation + set(CUDAToolkit_TARGET_NAME "armv7-linux-gnueabihf") + elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64") + # Support for aarch64 cross compilation + if(ANDROID_ARCH_NAME STREQUAL "arm64") + set(CUDAToolkit_TARGET_NAME "aarch64-linux-androideabi") + else() + set(CUDAToolkit_TARGET_NAME "aarch64-linux") + endif(ANDROID_ARCH_NAME STREQUAL "arm64") + elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") + set(CUDAToolkit_TARGET_NAME "x86_64-linux") + endif() + + if(EXISTS "${CUDAToolkit_ROOT_DIR}/targets/${CUDAToolkit_TARGET_NAME}") + set(CUDAToolkit_TARGET_DIR "${CUDAToolkit_ROOT_DIR}/targets/${CUDAToolkit_TARGET_NAME}") + # add known CUDA target root path to the set of directories we search for programs, libraries and headers + list(PREPEND CMAKE_FIND_ROOT_PATH "${CUDAToolkit_TARGET_DIR}") + + # Mark that we need to pop the root search path changes after we have + # found all cuda libraries so that searches for our cross-compilation + # libraries work when another cuda sdk is in CMAKE_PREFIX_PATH or + # PATh + set(_CUDAToolkit_Pop_ROOT_PATH True) + endif() +else() + # Not cross compiling + set(CUDAToolkit_TARGET_DIR "${CUDAToolkit_ROOT_DIR}") + # Now that we have the real ROOT_DIR, find components inside it. + list(APPEND CMAKE_PREFIX_PATH ${CUDAToolkit_ROOT_DIR}) + + # Mark that we need to pop the prefix path changes after we have + # found the cudart library. + set(_CUDAToolkit_Pop_Prefix True) +endif() + +# Find the include/ directory +find_path(CUDAToolkit_INCLUDE_DIR + NAMES cuda_runtime.h +) + +# Find a tentative CUDAToolkit_LIBRARY_DIR. FindCUDAToolkit overrides it by searching for the CUDA runtime, +# but we can't do that here, as CMakeDetermineCUDACompiler wants to use it before the variables necessary +# for find_library() have been initialized. +if(EXISTS "${CUDAToolkit_TARGET_DIR}/lib64") + set(CUDAToolkit_LIBRARY_DIR "${CUDAToolkit_TARGET_DIR}/lib64") +elseif(EXISTS "${CUDAToolkit_TARGET_DIR}/lib") + set(CUDAToolkit_LIBRARY_DIR "${CUDAToolkit_TARGET_DIR}/lib") +endif() diff --git a/Modules/Platform/UnixPaths.cmake b/Modules/Platform/UnixPaths.cmake index 98c83aa..7fe64cb 100644 --- a/Modules/Platform/UnixPaths.cmake +++ b/Modules/Platform/UnixPaths.cmake @@ -21,6 +21,10 @@ get_filename_component(_CMAKE_INSTALL_DIR "${_CMAKE_INSTALL_DIR}" PATH) # List common installation prefixes. These will be used for all # search types. +# +# Reminder when adding new locations computed from environment variables +# please make sure to keep Help/variable/CMAKE_SYSTEM_PREFIX_PATH.rst +# synchronized list(APPEND CMAKE_SYSTEM_PREFIX_PATH # Standard /usr/local /usr / @@ -86,6 +90,9 @@ set(_CMAKE_CUDA_IMPLICIT_INCLUDE_DIRECTORIES_INIT unset(_cmake_sysroot_compile) +# Reminder when adding new locations computed from environment variables +# please make sure to keep Help/variable/CMAKE_SYSTEM_PREFIX_PATH.rst +# synchronized if(CMAKE_COMPILER_SYSROOT) list(PREPEND CMAKE_SYSTEM_PREFIX_PATH "${CMAKE_COMPILER_SYSROOT}") endif() diff --git a/Modules/Platform/Windows-NVIDIA-CUDA.cmake b/Modules/Platform/Windows-NVIDIA-CUDA.cmake index f425cf8..f887594 100644 --- a/Modules/Platform/Windows-NVIDIA-CUDA.cmake +++ b/Modules/Platform/Windows-NVIDIA-CUDA.cmake @@ -74,6 +74,10 @@ set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_STATIC "cudadevrt;cudart_static") set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_SHARED "cudadevrt;cudart") set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_NONE "") +if(UNIX) + list(APPEND CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_STATIC "rt" "pthread" "dl") +endif() + string(APPEND CMAKE_CUDA_FLAGS_INIT " ${PLATFORM_DEFINES_CUDA} -D_WINDOWS -Xcompiler=\"${_W3}${_FLAGS_CXX}\"") string(APPEND CMAKE_CUDA_FLAGS_DEBUG_INIT " -Xcompiler=\"${_MDd}-Zi -Ob0 -Od ${_RTC1}\"") string(APPEND CMAKE_CUDA_FLAGS_RELEASE_INIT " -Xcompiler=\"${_MD}-O2 -Ob2\" -DNDEBUG") diff --git a/Modules/Platform/WindowsPaths.cmake b/Modules/Platform/WindowsPaths.cmake index 71cc609..b9e2f17 100644 --- a/Modules/Platform/WindowsPaths.cmake +++ b/Modules/Platform/WindowsPaths.cmake @@ -24,6 +24,10 @@ set(__WINDOWS_PATHS_INCLUDED 1) # ENV{ProgramFiles(x86)} = [C:\Program Files (x86)] # ENV{ProgramFiles} = [C:\Program Files (x86)] # ENV{ProgramW6432} = [C:\Program Files] +# +# Reminder when adding new locations computed from environment variables +# please make sure to keep Help/variable/CMAKE_SYSTEM_PREFIX_PATH.rst +# synchronized set(_programfiles "") foreach(v "ProgramW6432" "ProgramFiles" "ProgramFiles(x86)") if(DEFINED "ENV{${v}}") diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index ec473d2..6d585ee 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -383,8 +383,6 @@ set(SRCS cmProperty.h cmPropertyDefinition.cxx cmPropertyDefinition.h - cmPropertyDefinitionMap.cxx - cmPropertyDefinitionMap.h cmPropertyMap.cxx cmPropertyMap.h cmQtAutoGen.cxx diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index b820d73..f283497 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 20200515) +set(CMake_VERSION_PATCH 20200521) #set(CMake_VERSION_RC 0) set(CMake_VERSION_IS_DIRTY 0) diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx index 7674d7a..ba7d47e 100644 --- a/Source/CTest/cmCTestRunTest.cxx +++ b/Source/CTest/cmCTestRunTest.cxx @@ -429,6 +429,7 @@ void cmCTestRunTest::StartFailure(std::string const& output, this->TestResult.Path = this->TestProperties->Directory; this->TestResult.Output = output; this->TestResult.FullCommandLine.clear(); + this->TestResult.Environment.clear(); } std::string cmCTestRunTest::GetTestPrefix(size_t completed, size_t total) const @@ -500,6 +501,7 @@ bool cmCTestRunTest::StartTest(size_t completed, size_t total) this->TestResult.Status = cmCTestTestHandler::NOT_RUN; this->TestResult.Output = "Disabled"; this->TestResult.FullCommandLine.clear(); + this->TestResult.Environment.clear(); return false; } @@ -519,6 +521,7 @@ bool cmCTestRunTest::StartTest(size_t completed, size_t total) cmCTestLog(this->CTest, HANDLER_OUTPUT, msg << std::endl); this->TestResult.Output = msg; this->TestResult.FullCommandLine.clear(); + this->TestResult.Environment.clear(); this->TestResult.CompletionStatus = "Fixture dependency failed"; this->TestResult.Status = cmCTestTestHandler::NOT_RUN; return false; @@ -539,6 +542,7 @@ bool cmCTestRunTest::StartTest(size_t completed, size_t total) cmCTestLog(this->CTest, ERROR_MESSAGE, msg << std::endl); this->TestResult.Output = msg; this->TestResult.FullCommandLine.clear(); + this->TestResult.Environment.clear(); this->TestResult.CompletionStatus = "Missing Configuration"; this->TestResult.Status = cmCTestTestHandler::NOT_RUN; return false; @@ -554,6 +558,7 @@ bool cmCTestRunTest::StartTest(size_t completed, size_t total) "Unable to find required file: " << file << std::endl); this->TestResult.Output = "Unable to find required file: " + file; this->TestResult.FullCommandLine.clear(); + this->TestResult.Environment.clear(); this->TestResult.CompletionStatus = "Required Files Missing"; this->TestResult.Status = cmCTestTestHandler::NOT_RUN; return false; @@ -569,6 +574,7 @@ bool cmCTestRunTest::StartTest(size_t completed, size_t total) "Unable to find executable: " << args[1] << std::endl); this->TestResult.Output = "Unable to find executable: " + args[1]; this->TestResult.FullCommandLine.clear(); + this->TestResult.Environment.clear(); this->TestResult.CompletionStatus = "Unable to find executable"; this->TestResult.Status = cmCTestTestHandler::NOT_RUN; return false; @@ -713,25 +719,43 @@ bool cmCTestRunTest::ForkProcess(cmDuration testTimeOut, bool explicitTimeout, cmSystemTools::SaveRestoreEnvironment sre; #endif + std::ostringstream envMeasurement; if (environment && !environment->empty()) { cmSystemTools::AppendEnv(*environment); + for (auto const& var : *environment) { + envMeasurement << var << std::endl; + } } if (this->UseAllocatedResources) { - this->SetupResourcesEnvironment(); + std::vector<std::string> envLog; + this->SetupResourcesEnvironment(&envLog); + for (auto const& var : envLog) { + envMeasurement << var << std::endl; + } } else { cmSystemTools::UnsetEnv("CTEST_RESOURCE_GROUP_COUNT"); + // Signify that this variable is being actively unset + envMeasurement << "#CTEST_RESOURCE_GROUP_COUNT=" << std::endl; } + this->TestResult.Environment = envMeasurement.str(); + // Remove last newline + this->TestResult.Environment.erase(this->TestResult.Environment.length() - + 1); + return this->TestProcess->StartProcess(this->MultiTestHandler.Loop, affinity); } -void cmCTestRunTest::SetupResourcesEnvironment() +void cmCTestRunTest::SetupResourcesEnvironment(std::vector<std::string>* log) { std::string processCount = "CTEST_RESOURCE_GROUP_COUNT="; processCount += std::to_string(this->AllocatedResources.size()); cmSystemTools::PutEnv(processCount); + if (log) { + log->push_back(processCount); + } std::size_t i = 0; for (auto const& process : this->AllocatedResources) { @@ -757,8 +781,14 @@ void cmCTestRunTest::SetupResourcesEnvironment() var += "id:" + it2.Id + ",slots:" + std::to_string(it2.Slots); } cmSystemTools::PutEnv(var); + if (log) { + log->push_back(var); + } } cmSystemTools::PutEnv(resourceList); + if (log) { + log->push_back(resourceList); + } ++i; } } diff --git a/Source/CTest/cmCTestRunTest.h b/Source/CTest/cmCTestRunTest.h index b1d188a..d831247 100644 --- a/Source/CTest/cmCTestRunTest.h +++ b/Source/CTest/cmCTestRunTest.h @@ -119,7 +119,7 @@ private: // Run post processing of the process output for MemCheck void MemCheckPostProcess(); - void SetupResourcesEnvironment(); + void SetupResourcesEnvironment(std::vector<std::string>* log = nullptr); // Returns "completed/total Test #Index: " std::string GetTestPrefix(size_t completed, size_t total) const; diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx index 8fc5cd6..d0dbaae 100644 --- a/Source/CTest/cmCTestTestHandler.cxx +++ b/Source/CTest/cmCTestTestHandler.cxx @@ -1432,6 +1432,12 @@ void cmCTestTestHandler::GenerateDartOutput(cmXMLWriter& xml) xml.Attribute("name", "Command Line"); xml.Element("Value", result.FullCommandLine); xml.EndElement(); // NamedMeasurement + + xml.StartElement("NamedMeasurement"); + xml.Attribute("type", "text/string"); + xml.Attribute("name", "Environment"); + xml.Element("Value", result.Environment); + xml.EndElement(); // NamedMeasurement for (auto const& measure : result.Properties->Measurements) { xml.StartElement("NamedMeasurement"); xml.Attribute("type", "text/string"); diff --git a/Source/CTest/cmCTestTestHandler.h b/Source/CTest/cmCTestTestHandler.h index 55cecb6..0d88c30 100644 --- a/Source/CTest/cmCTestTestHandler.h +++ b/Source/CTest/cmCTestTestHandler.h @@ -169,6 +169,7 @@ public: std::string Path; std::string Reason; std::string FullCommandLine; + std::string Environment; cmDuration ExecutionTime; std::int64_t ReturnValue; int Status; diff --git a/Source/CursesDialog/cmCursesLongMessageForm.cxx b/Source/CursesDialog/cmCursesLongMessageForm.cxx index 664ba2f..591c546 100644 --- a/Source/CursesDialog/cmCursesLongMessageForm.cxx +++ b/Source/CursesDialog/cmCursesLongMessageForm.cxx @@ -68,7 +68,7 @@ void cmCursesLongMessageForm::UpdateStatusBar() bar[i] = ' '; } int width; - if (x < cmCursesMainForm::MAX_WIDTH) { + if (x >= 0 && x < cmCursesMainForm::MAX_WIDTH) { width = x; } else { width = cmCursesMainForm::MAX_WIDTH - 1; diff --git a/Source/cmExportBuildAndroidMKGenerator.cxx b/Source/cmExportBuildAndroidMKGenerator.cxx index 0ee1259..3641cb2 100644 --- a/Source/cmExportBuildAndroidMKGenerator.cxx +++ b/Source/cmExportBuildAndroidMKGenerator.cxx @@ -47,7 +47,9 @@ void cmExportBuildAndroidMKGenerator::GenerateImportTargetCode( os << "LOCAL_MODULE := "; os << targetName << "\n"; os << "LOCAL_SRC_FILES := "; - std::string path = cmSystemTools::ConvertToOutputPath(target->GetFullPath()); + std::string const noConfig; // FIXME: What config to use here? + std::string path = + cmSystemTools::ConvertToOutputPath(target->GetFullPath(noConfig)); os << path << "\n"; } diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index 28037c6..ed0689a 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -923,12 +923,14 @@ void cmExportFileGenerator::GeneratePolicyHeaderCode(std::ostream& os) /* clang-format on */ // Isolate the file policy level. - // We use 2.6 here instead of the current version because newer - // versions of CMake should be able to export files imported by 2.6 - // until the import format changes. + // Support CMake versions as far back as 2.6 but also support using NEW + // policy settings for up to CMake 3.17 (this upper limit may be reviewed + // and increased from time to time). This reduces the opportunity for CMake + // warnings when an older export file is later used with newer CMake + // versions. /* clang-format off */ os << "cmake_policy(PUSH)\n" - << "cmake_policy(VERSION 2.6)\n"; + << "cmake_policy(VERSION 2.6...3.17)\n"; /* clang-format on */ } diff --git a/Source/cmExportTryCompileFileGenerator.cxx b/Source/cmExportTryCompileFileGenerator.cxx index 6212667..46056c1 100644 --- a/Source/cmExportTryCompileFileGenerator.cxx +++ b/Source/cmExportTryCompileFileGenerator.cxx @@ -71,7 +71,7 @@ std::string cmExportTryCompileFileGenerator::FindTargets( cmTarget dummyHead("try_compile_dummy_exe", cmStateEnums::EXECUTABLE, cmTarget::VisibilityNormal, tgt->Target->GetMakefile(), - true); + cmTarget::PerConfig::Yes); cmGeneratorTarget gDummyHead(&dummyHead, tgt->GetLocalGenerator()); diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index f3d49c3..268c5d1 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -677,12 +677,12 @@ bool HandleGlobImpl(std::vector<std::string> const& args, bool recurse, } } + cmake* cm = status.GetMakefile().GetCMakeInstance(); std::vector<std::string> files; bool configureDepends = false; bool warnConfigureLate = false; bool warnFollowedSymlinks = false; - const cmake::WorkingMode workingMode = - status.GetMakefile().GetCMakeInstance()->GetWorkingMode(); + const cmake::WorkingMode workingMode = cm->GetWorkingMode(); while (i != args.end()) { if (*i == "LIST_DIRECTORIES") { ++i; // skip LIST_DIRECTORIES @@ -770,12 +770,17 @@ bool HandleGlobImpl(std::vector<std::string> const& args, bool recurse, MessageType::AUTHOR_WARNING, "Cyclic recursion detected while globbing for '" + *i + "':\n" + globMessage.content); - } else { + } else if (globMessage.type == cmsys::Glob::error) { status.GetMakefile().IssueMessage( MessageType::FATAL_ERROR, "Error has occurred while globbing for '" + *i + "' - " + globMessage.content); shouldExit = true; + } else if (cm->GetDebugOutput() || cm->GetTrace()) { + status.GetMakefile().IssueMessage( + MessageType::LOG, + cmStrCat("Globbing for\n ", *i, "\nEncountered an error:\n ", + globMessage.content)); } } if (shouldExit) { @@ -795,7 +800,7 @@ bool HandleGlobImpl(std::vector<std::string> const& args, bool recurse, std::sort(foundFiles.begin(), foundFiles.end()); foundFiles.erase(std::unique(foundFiles.begin(), foundFiles.end()), foundFiles.end()); - status.GetMakefile().GetCMakeInstance()->AddGlobCacheEntry( + cm->AddGlobCacheEntry( recurse, (recurse ? g.GetRecurseListDirs() : g.GetListDirs()), (recurse ? g.GetRecurseThroughSymlinks() : false), (g.GetRelative() ? g.GetRelative() : ""), expr, foundFiles, variable, diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index a44126c..2f9da1c 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -693,6 +693,7 @@ const char* cmGeneratorTarget::GetFileSuffixInternal( void cmGeneratorTarget::ClearSourcesCache() { + this->AllConfigSources.clear(); this->KindedSourcesMap.clear(); this->LinkImplementationLanguageIsContextDependent = true; this->Objects.clear(); @@ -975,51 +976,12 @@ void cmGeneratorTarget::GetExternalObjects( IMPLEMENT_VISIT(SourceKindExternalObject); } -void cmGeneratorTarget::GetExpectedResxHeaders(std::set<std::string>& headers, - const std::string& config) const -{ - KindedSources const& kinded = this->GetKindedSources(config); - headers = kinded.ExpectedResxHeaders; -} - -void cmGeneratorTarget::GetResxSources(std::vector<cmSourceFile const*>& data, - const std::string& config) const -{ - IMPLEMENT_VISIT(SourceKindResx); -} - -void cmGeneratorTarget::GetAppManifest(std::vector<cmSourceFile const*>& data, - const std::string& config) const -{ - IMPLEMENT_VISIT(SourceKindAppManifest); -} - void cmGeneratorTarget::GetManifests(std::vector<cmSourceFile const*>& data, const std::string& config) const { IMPLEMENT_VISIT(SourceKindManifest); } -void cmGeneratorTarget::GetCertificates(std::vector<cmSourceFile const*>& data, - const std::string& config) const -{ - IMPLEMENT_VISIT(SourceKindCertificate); -} - -void cmGeneratorTarget::GetExpectedXamlHeaders(std::set<std::string>& headers, - const std::string& config) const -{ - KindedSources const& kinded = this->GetKindedSources(config); - headers = kinded.ExpectedXamlHeaders; -} - -void cmGeneratorTarget::GetExpectedXamlSources(std::set<std::string>& srcs, - const std::string& config) const -{ - KindedSources const& kinded = this->GetKindedSources(config); - srcs = kinded.ExpectedXamlSources; -} - std::set<cmLinkItem> const& cmGeneratorTarget::GetUtilityItems() const { if (!this->UtilityItemsDone) { @@ -1039,12 +1001,6 @@ std::set<cmLinkItem> const& cmGeneratorTarget::GetUtilityItems() const return this->UtilityItems; } -void cmGeneratorTarget::GetXamlSources(std::vector<cmSourceFile const*>& data, - const std::string& config) const -{ - IMPLEMENT_VISIT(SourceKindXaml); -} - const std::string& cmGeneratorTarget::GetLocation( const std::string& config) const { @@ -1096,7 +1052,8 @@ const std::string& cmGeneratorTarget::GetLocationForBuild() const } // Now handle the deprecated build-time configuration location. - location = this->GetDirectory(); + std::string const noConfig; + location = this->GetDirectory(noConfig); const char* cfgid = this->Makefile->GetDefinition("CMAKE_CFG_INTDIR"); if (cfgid && strcmp(cfgid, ".") != 0) { location += "/"; @@ -1726,14 +1683,6 @@ void cmGeneratorTarget::ComputeKindedSources(KindedSources& files, } } else if (ext == "resx") { kind = SourceKindResx; - // Build and save the name of the corresponding .h file - // This relationship will be used later when building the project files. - // Both names would have been auto generated from Visual Studio - // where the user supplied the file name and Visual Studio - // appended the suffix. - std::string resx = sf->ResolveFullPath(); - std::string hFileName = resx.substr(0, resx.find_last_of('.')) + ".h"; - files.ExpectedResxHeaders.insert(hFileName); } else if (ext == "appxmanifest") { kind = SourceKindAppManifest; } else if (ext == "manifest") { @@ -1742,16 +1691,6 @@ void cmGeneratorTarget::ComputeKindedSources(KindedSources& files, kind = SourceKindCertificate; } else if (ext == "xaml") { kind = SourceKindXaml; - // Build and save the name of the corresponding .h and .cpp file - // This relationship will be used later when building the project files. - // Both names would have been auto generated from Visual Studio - // where the user supplied the file name and Visual Studio - // appended the suffix. - std::string xaml = sf->ResolveFullPath(); - std::string hFileName = xaml + ".h"; - std::string cppFileName = xaml + ".cpp"; - files.ExpectedXamlHeaders.insert(hFileName); - files.ExpectedXamlSources.insert(cppFileName); } else if (header_regex.find(sf->ResolveFullPath())) { kind = SourceKindHeader; } else { @@ -1809,6 +1748,18 @@ void cmGeneratorTarget::ComputeAllConfigSources() const } } +std::vector<cmGeneratorTarget::AllConfigSource> +cmGeneratorTarget::GetAllConfigSources(SourceKind kind) const +{ + std::vector<AllConfigSource> result; + for (AllConfigSource const& source : this->GetAllConfigSources()) { + if (source.Kind == kind) { + result.push_back(source); + } + } + return result; +} + std::set<std::string> cmGeneratorTarget::GetAllConfigCompileLanguages() const { std::set<std::string> languages; @@ -3179,6 +3130,20 @@ void cmGeneratorTarget::AddCUDAArchitectureFlags(std::string& flags) const flags += "]"; } + } else if (compiler == "Clang") { + for (CudaArchitecture& architecture : architectures) { + flags += " --cuda-gpu-arch=sm_" + architecture.name; + + if (!architecture.real) { + Makefile->IssueMessage( + MessageType::WARNING, + "Clang doesn't support disabling CUDA real code generation."); + } + + if (!architecture.virtual_) { + flags += " --no-cuda-include-ptx=sm_" + architecture.name; + } + } } } diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index ff03914..c8732bc 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -117,9 +117,6 @@ public: struct KindedSources { std::vector<SourceAndKind> Sources; - std::set<std::string> ExpectedResxHeaders; - std::set<std::string> ExpectedXamlHeaders; - std::set<std::string> ExpectedXamlSources; bool Initialized = false; }; @@ -137,6 +134,9 @@ public: per-source configurations assigned. */ std::vector<AllConfigSource> const& GetAllConfigSources() const; + /** Get all sources needed for all configurations with given kind. */ + std::vector<AllConfigSource> GetAllConfigSources(SourceKind kind) const; + /** Get all languages used to compile sources in any configuration. This excludes the languages of objects from object libraries. */ std::set<std::string> GetAllConfigCompileLanguages() const; @@ -151,8 +151,6 @@ public: void GetModuleDefinitionSources(std::vector<cmSourceFile const*>&, const std::string& config) const; - void GetResxSources(std::vector<cmSourceFile const*>&, - const std::string& config) const; void GetExternalObjects(std::vector<cmSourceFile const*>&, const std::string& config) const; void GetHeaderSources(std::vector<cmSourceFile const*>&, @@ -161,20 +159,8 @@ public: const std::string& config) const; void GetCustomCommands(std::vector<cmSourceFile const*>&, const std::string& config) const; - void GetExpectedResxHeaders(std::set<std::string>&, - const std::string& config) const; - void GetAppManifest(std::vector<cmSourceFile const*>&, - const std::string& config) const; void GetManifests(std::vector<cmSourceFile const*>&, const std::string& config) const; - void GetCertificates(std::vector<cmSourceFile const*>&, - const std::string& config) const; - void GetXamlSources(std::vector<cmSourceFile const*>&, - const std::string& config) const; - void GetExpectedXamlHeaders(std::set<std::string>&, - const std::string& config) const; - void GetExpectedXamlSources(std::set<std::string>&, - const std::string& config) const; std::set<cmLinkItem> const& GetUtilityItems() const; @@ -245,7 +231,7 @@ public: /** Get the full path to the target according to the settings in its makefile and the configuration type. */ std::string GetFullPath( - const std::string& config = "", + const std::string& config, cmStateEnums::ArtifactType artifact = cmStateEnums::RuntimeBinaryArtifact, bool realname = false) const; std::string NormalGetFullPath(const std::string& config, @@ -283,7 +269,7 @@ public: /** Get the full name of the target according to the settings in its makefile. */ - std::string GetFullName(const std::string& config = "", + std::string GetFullName(const std::string& config, cmStateEnums::ArtifactType artifact = cmStateEnums::RuntimeBinaryArtifact) const; @@ -326,8 +312,7 @@ public: std::string GetSOName(const std::string& config) const; void GetFullNameComponents(std::string& prefix, std::string& base, - std::string& suffix, - const std::string& config = "", + std::string& suffix, const std::string& config, cmStateEnums::ArtifactType artifact = cmStateEnums::RuntimeBinaryArtifact) const; @@ -540,7 +525,7 @@ public: configuration name is given then the generator will add its subdirectory for that configuration. Otherwise just the canonical output directory is given. */ - std::string GetDirectory(const std::string& config = "", + std::string GetDirectory(const std::string& config, cmStateEnums::ArtifactType artifact = cmStateEnums::RuntimeBinaryArtifact) const; @@ -548,7 +533,7 @@ public: If the configuration name is given then the generator will add its subdirectory for that configuration. Otherwise just the canonical compiler pdb output directory is given. */ - std::string GetCompilePDBDirectory(const std::string& config = "") const; + std::string GetCompilePDBDirectory(const std::string& config) const; /** Get sources that must be built before the given source. */ std::vector<cmSourceFile*> const* GetSourceDepends( @@ -577,7 +562,7 @@ public: std::string GetPDBOutputName(const std::string& config) const; /** Get the name of the pdb file for the target. */ - std::string GetPDBName(const std::string& config = "") const; + std::string GetPDBName(const std::string& config) const; /** Whether this library has soname enabled and platform supports it. */ bool HasSOName(const std::string& config) const; @@ -595,10 +580,10 @@ public: bool IsNullImpliedByLinkLibraries(const std::string& p) const; /** Get the name of the compiler pdb file for the target. */ - std::string GetCompilePDBName(const std::string& config = "") const; + std::string GetCompilePDBName(const std::string& config) const; /** Get the path for the MSVC /Fd option for this target. */ - std::string GetCompilePDBPath(const std::string& config = "") const; + std::string GetCompilePDBPath(const std::string& config) const; // Get the target base name. std::string GetOutputName(const std::string& config, diff --git a/Source/cmGetPropertyCommand.cxx b/Source/cmGetPropertyCommand.cxx index c3ac672..851f426 100644 --- a/Source/cmGetPropertyCommand.cxx +++ b/Source/cmGetPropertyCommand.cxx @@ -11,6 +11,7 @@ #include "cmPolicies.h" #include "cmProperty.h" #include "cmPropertyDefinition.h" +#include "cmSetPropertyCommand.h" #include "cmSourceFile.h" #include "cmState.h" #include "cmStringAlgorithms.h" @@ -48,7 +49,9 @@ bool HandleTargetMode(cmExecutionStatus& status, const std::string& name, const std::string& propertyName); bool HandleSourceMode(cmExecutionStatus& status, const std::string& name, OutType infoType, const std::string& variable, - const std::string& propertyName); + const std::string& propertyName, + cmMakefile& directory_makefile, + bool source_file_paths_should_be_absolute); bool HandleTestMode(cmExecutionStatus& status, const std::string& name, OutType infoType, const std::string& variable, const std::string& propertyName); @@ -78,6 +81,11 @@ bool cmGetPropertyCommand(std::vector<std::string> const& args, std::string name; std::string propertyName; + std::vector<std::string> source_file_directories; + std::vector<std::string> source_file_target_directories; + bool source_file_directory_option_enabled = false; + bool source_file_target_option_enabled = false; + // Get the scope from which to get the property. cmProperty::ScopeType scope; if (args[1] == "GLOBAL") { @@ -111,7 +119,9 @@ bool cmGetPropertyCommand(std::vector<std::string> const& args, DoingNone, DoingName, DoingProperty, - DoingType + DoingType, + DoingSourceDirectory, + DoingSourceTargetDirectory }; Doing doing = DoingName; for (unsigned int i = 2; i < args.size(); ++i) { @@ -132,6 +142,20 @@ bool cmGetPropertyCommand(std::vector<std::string> const& args, } else if (doing == DoingName) { doing = DoingNone; name = args[i]; + } else if (doing == DoingNone && scope == cmProperty::SOURCE_FILE && + args[i] == "DIRECTORY") { + doing = DoingSourceDirectory; + source_file_directory_option_enabled = true; + } else if (doing == DoingNone && scope == cmProperty::SOURCE_FILE && + args[i] == "TARGET_DIRECTORY") { + doing = DoingSourceTargetDirectory; + source_file_target_option_enabled = true; + } else if (doing == DoingSourceDirectory) { + source_file_directories.push_back(args[i]); + doing = DoingNone; + } else if (doing == DoingSourceTargetDirectory) { + source_file_target_directories.push_back(args[i]); + doing = DoingNone; } else if (doing == DoingProperty) { doing = DoingNone; propertyName = args[i]; @@ -147,6 +171,16 @@ bool cmGetPropertyCommand(std::vector<std::string> const& args, return false; } + std::vector<cmMakefile*> source_file_directory_makefiles; + bool file_scopes_handled = + SetPropertyCommand::HandleAndValidateSourceFileDirectortoryScopes( + status, source_file_directory_option_enabled, + source_file_target_option_enabled, source_file_directories, + source_file_target_directories, source_file_directory_makefiles); + if (!file_scopes_handled) { + return false; + } + // Compute requested output. if (infoType == OutBriefDoc) { // Lookup brief documentation. @@ -180,6 +214,11 @@ bool cmGetPropertyCommand(std::vector<std::string> const& args, } } else { // Dispatch property getting. + cmMakefile& directory_scope_mf = *(source_file_directory_makefiles[0]); + bool source_file_paths_should_be_absolute = + source_file_directory_option_enabled || + source_file_target_option_enabled; + switch (scope) { case cmProperty::GLOBAL: return HandleGlobalMode(status, name, infoType, variable, @@ -191,8 +230,9 @@ bool cmGetPropertyCommand(std::vector<std::string> const& args, return HandleTargetMode(status, name, infoType, variable, propertyName); case cmProperty::SOURCE_FILE: - return HandleSourceMode(status, name, infoType, variable, - propertyName); + return HandleSourceMode(status, name, infoType, variable, propertyName, + directory_scope_mf, + source_file_paths_should_be_absolute); case cmProperty::TEST: return HandleTestMode(status, name, infoType, variable, propertyName); case cmProperty::VARIABLE: @@ -331,7 +371,9 @@ bool HandleTargetMode(cmExecutionStatus& status, const std::string& name, bool HandleSourceMode(cmExecutionStatus& status, const std::string& name, OutType infoType, const std::string& variable, - const std::string& propertyName) + const std::string& propertyName, + cmMakefile& directory_makefile, + const bool source_file_paths_should_be_absolute) { if (name.empty()) { status.SetError("not given name for SOURCE scope."); @@ -339,12 +381,17 @@ bool HandleSourceMode(cmExecutionStatus& status, const std::string& name, } // Get the source file. - if (cmSourceFile* sf = status.GetMakefile().GetOrCreateSource(name)) { + const std::string source_file_absolute_path = + SetPropertyCommand::MakeSourceFilePathAbsoluteIfNeeded( + status, name, source_file_paths_should_be_absolute); + if (cmSourceFile* sf = + directory_makefile.GetOrCreateSource(source_file_absolute_path)) { return StoreResult(infoType, status.GetMakefile(), variable, sf->GetPropertyForUser(propertyName)); } status.SetError( - cmStrCat("given SOURCE name that could not be found or created: ", name)); + cmStrCat("given SOURCE name that could not be found or created: ", + source_file_absolute_path)); return false; } diff --git a/Source/cmGetSourceFilePropertyCommand.cxx b/Source/cmGetSourceFilePropertyCommand.cxx index eefdc6c..5395bc8 100644 --- a/Source/cmGetSourceFilePropertyCommand.cxx +++ b/Source/cmGetSourceFilePropertyCommand.cxx @@ -4,35 +4,71 @@ #include "cmExecutionStatus.h" #include "cmMakefile.h" +#include "cmSetPropertyCommand.h" #include "cmSourceFile.h" bool cmGetSourceFilePropertyCommand(std::vector<std::string> const& args, cmExecutionStatus& status) { - if (args.size() != 3) { + std::vector<std::string>::size_type args_size = args.size(); + if (args_size != 3 && args_size != 5) { status.SetError("called with incorrect number of arguments"); return false; } + + std::vector<std::string> source_file_directories; + std::vector<std::string> source_file_target_directories; + bool source_file_directory_option_enabled = false; + bool source_file_target_option_enabled = false; + + int property_arg_index = 2; + if (args[2] == "DIRECTORY" && args_size == 5) { + property_arg_index = 4; + source_file_directory_option_enabled = true; + source_file_directories.push_back(args[3]); + } else if (args[2] == "TARGET_DIRECTORY" && args_size == 5) { + property_arg_index = 4; + source_file_target_option_enabled = true; + source_file_target_directories.push_back(args[3]); + } + + std::vector<cmMakefile*> source_file_directory_makefiles; + bool file_scopes_handled = + SetPropertyCommand::HandleAndValidateSourceFileDirectortoryScopes( + status, source_file_directory_option_enabled, + source_file_target_option_enabled, source_file_directories, + source_file_target_directories, source_file_directory_makefiles); + if (!file_scopes_handled) { + return false; + } + std::string const& var = args[0]; - std::string const& file = args[1]; - cmMakefile& mf = status.GetMakefile(); + bool source_file_paths_should_be_absolute = + source_file_directory_option_enabled || source_file_target_option_enabled; + std::string const file = + SetPropertyCommand::MakeSourceFilePathAbsoluteIfNeeded( + status, args[1], source_file_paths_should_be_absolute); + cmMakefile& mf = *source_file_directory_makefiles[0]; cmSourceFile* sf = mf.GetSource(file); // for the location we must create a source file first - if (!sf && args[2] == "LOCATION") { + if (!sf && args[property_arg_index] == "LOCATION") { sf = mf.CreateSource(file); } + if (sf) { const char* prop = nullptr; - if (!args[2].empty()) { - prop = sf->GetPropertyForUser(args[2]); + if (!args[property_arg_index].empty()) { + prop = sf->GetPropertyForUser(args[property_arg_index]); } if (prop) { - mf.AddDefinition(var, prop); + // Set the value on the original Makefile scope, not the scope of the + // requested directory. + status.GetMakefile().AddDefinition(var, prop); return true; } } - mf.AddDefinition(var, "NOTFOUND"); + status.GetMakefile().AddDefinition(var, "NOTFOUND"); return true; } diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 6370ed2..0b7ba04 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -320,7 +320,7 @@ bool cmGlobalGenerator::CheckTargetsForMissingSources() const } else { for (std::string const& config : configs) { target->GetSourceFiles(srcs, config); - if (srcs.empty()) { + if (!srcs.empty()) { break; } } @@ -2535,7 +2535,7 @@ void cmGlobalGenerator::AddGlobalTarget_EditCache( } GlobalTargetInfo gti; gti.Name = editCacheTargetName; - gti.PerConfig = false; + gti.PerConfig = cmTarget::PerConfig::No; cmCustomCommandLine singleLine; // Use generator preference for the edit_cache rule if it is defined. @@ -2571,7 +2571,7 @@ void cmGlobalGenerator::AddGlobalTarget_RebuildCache( gti.Name = rebuildCacheTargetName; gti.Message = "Running CMake to regenerate build system..."; gti.UsesTerminal = true; - gti.PerConfig = false; + gti.PerConfig = cmTarget::PerConfig::No; cmCustomCommandLine singleLine; singleLine.push_back(cmSystemTools::GetCMakeCommand()); singleLine.push_back("--regenerate-during-build"); diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index dcd5a66..57c7808 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -553,7 +553,7 @@ protected: std::vector<std::string> Depends; std::string WorkingDir; bool UsesTerminal = false; - bool PerConfig = true; + cmTarget::PerConfig PerConfig = cmTarget::PerConfig::Yes; bool StdPipesUTF8 = false; }; diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx index 28bd1ca..0932d06 100644 --- a/Source/cmGlobalVisualStudioGenerator.cxx +++ b/Source/cmGlobalVisualStudioGenerator.cxx @@ -112,6 +112,7 @@ void cmGlobalVisualStudioGenerator::WriteSLNHeader(std::ostream& fout) { char utf8bom[] = { char(0xEF), char(0xBB), char(0xBF) }; fout.write(utf8bom, 3); + fout << '\n'; switch (this->Version) { case cmGlobalVisualStudioGenerator::VS9: diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 6f05d45..154da50 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -2081,11 +2081,11 @@ cmTarget* cmMakefile::AddExecutable(const std::string& exeName, cmTarget* cmMakefile::AddNewTarget(cmStateEnums::TargetType type, const std::string& name) { - auto it = - this->Targets - .emplace(name, - cmTarget(name, type, cmTarget::VisibilityNormal, this, true)) - .first; + auto it = this->Targets + .emplace(name, + cmTarget(name, type, cmTarget::VisibilityNormal, this, + cmTarget::PerConfig::Yes)) + .first; this->OrderedTargets.push_back(&it->second); this->GetGlobalGenerator()->IndexTarget(&it->second); this->GetStateSnapshot().GetDirectory().AddNormalTargetName(name); @@ -4261,7 +4261,7 @@ cmTarget* cmMakefile::AddImportedTarget(const std::string& name, new cmTarget(name, type, global ? cmTarget::VisibilityImportedGlobally : cmTarget::VisibilityImported, - this, true)); + this, cmTarget::PerConfig::Yes)); // Add to the set of available imported targets. this->ImportedTargets[name] = target.get(); diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index db069ed..f87eba7 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -1024,7 +1024,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement( std::string prefix; std::string base; std::string suffix; - gt->GetFullNameComponents(prefix, base, suffix); + gt->GetFullNameComponents(prefix, base, suffix, config); std::string dbg_suffix = ".dbg"; // TODO: Where to document? if (mf->GetDefinition("CMAKE_DEBUG_SYMBOL_SUFFIX")) { diff --git a/Source/cmPropertyDefinition.cxx b/Source/cmPropertyDefinition.cxx index c8efaf6..1796bb8 100644 --- a/Source/cmPropertyDefinition.cxx +++ b/Source/cmPropertyDefinition.cxx @@ -2,17 +2,38 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmPropertyDefinition.h" -#include <utility> +#include <tuple> -cmPropertyDefinition::cmPropertyDefinition(std::string name, - cmProperty::ScopeType scope, - std::string shortDescription, +cmPropertyDefinition::cmPropertyDefinition(std::string shortDescription, std::string fullDescription, - bool chain) - : Name(std::move(name)) - , ShortDescription(std::move(shortDescription)) + bool chained) + : ShortDescription(std::move(shortDescription)) , FullDescription(std::move(fullDescription)) - , Scope(scope) - , Chained(chain) + , Chained(chained) { } + +void cmPropertyDefinitionMap::DefineProperty( + const std::string& name, cmProperty::ScopeType scope, + const std::string& ShortDescription, const std::string& FullDescription, + bool chain) +{ + auto it = this->Map_.find(key_type(name, scope)); + if (it == this->Map_.end()) { + // try_emplace() since C++17 + this->Map_.emplace( + std::piecewise_construct, std::forward_as_tuple(name, scope), + std::forward_as_tuple(ShortDescription, FullDescription, chain)); + } +} + +cmPropertyDefinition const* cmPropertyDefinitionMap::GetPropertyDefinition( + const std::string& name, cmProperty::ScopeType scope) const +{ + auto it = this->Map_.find(key_type(name, scope)); + if (it != this->Map_.end()) { + return &it->second; + } + + return nullptr; +} diff --git a/Source/cmPropertyDefinition.h b/Source/cmPropertyDefinition.h index d2e4467..f83bc4f 100644 --- a/Source/cmPropertyDefinition.h +++ b/Source/cmPropertyDefinition.h @@ -5,7 +5,9 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include <map> #include <string> +#include <utility> #include "cmProperty.h" @@ -13,25 +15,19 @@ * \brief Property meta-information * * This class contains the following meta-information about property: - * - Name; * - Various documentation strings; - * - The scope of the property; * - If the property is chained. */ class cmPropertyDefinition { public: /// Constructor - cmPropertyDefinition(std::string name, cmProperty::ScopeType scope, - std::string ShortDescription, - std::string FullDescription, bool chained = false); + cmPropertyDefinition(std::string shortDescription, + std::string fullDescription, bool chained); /// Is the property chained? bool IsChained() const { return this->Chained; } - /// Get the scope - cmProperty::ScopeType GetScope() const { return this->Scope; } - /// Get the documentation (short version) const std::string& GetShortDescription() const { @@ -44,12 +40,30 @@ public: return this->FullDescription; } -protected: - std::string Name; +private: std::string ShortDescription; std::string FullDescription; - cmProperty::ScopeType Scope; bool Chained; }; +/** \class cmPropertyDefinitionMap + * \brief Map property name and scope to their definition + */ +class cmPropertyDefinitionMap +{ +public: + // define the property + void DefineProperty(const std::string& name, cmProperty::ScopeType scope, + const std::string& ShortDescription, + const std::string& FullDescription, bool chain); + + // get the property definition if present, otherwise nullptr + cmPropertyDefinition const* GetPropertyDefinition( + const std::string& name, cmProperty::ScopeType scope) const; + +private: + using key_type = std::pair<std::string, cmProperty::ScopeType>; + std::map<key_type, cmPropertyDefinition> Map_; +}; + #endif diff --git a/Source/cmPropertyDefinitionMap.cxx b/Source/cmPropertyDefinitionMap.cxx deleted file mode 100644 index 614d5a4..0000000 --- a/Source/cmPropertyDefinitionMap.cxx +++ /dev/null @@ -1,35 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing for details. */ -#include "cmPropertyDefinitionMap.h" - -#include <tuple> -#include <utility> - -void cmPropertyDefinitionMap::DefineProperty( - const std::string& name, cmProperty::ScopeType scope, - const std::string& ShortDescription, const std::string& FullDescription, - bool chain) -{ - auto it = this->find(name); - if (it == this->end()) { - // try_emplace() since C++17 - this->emplace(std::piecewise_construct, std::forward_as_tuple(name), - std::forward_as_tuple(name, scope, ShortDescription, - FullDescription, chain)); - } -} - -bool cmPropertyDefinitionMap::IsPropertyDefined(const std::string& name) const -{ - return this->find(name) != this->end(); -} - -bool cmPropertyDefinitionMap::IsPropertyChained(const std::string& name) const -{ - auto it = this->find(name); - if (it == this->end()) { - return false; - } - - return it->second.IsChained(); -} diff --git a/Source/cmPropertyDefinitionMap.h b/Source/cmPropertyDefinitionMap.h deleted file mode 100644 index 2ae6efb..0000000 --- a/Source/cmPropertyDefinitionMap.h +++ /dev/null @@ -1,30 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing for details. */ -#ifndef cmPropertyDefinitionMap_h -#define cmPropertyDefinitionMap_h - -#include "cmConfigure.h" // IWYU pragma: keep - -#include <map> -#include <string> - -#include "cmProperty.h" -#include "cmPropertyDefinition.h" - -class cmPropertyDefinitionMap - : public std::map<std::string, cmPropertyDefinition> -{ -public: - // define the property - void DefineProperty(const std::string& name, cmProperty::ScopeType scope, - const std::string& ShortDescription, - const std::string& FullDescription, bool chain); - - // has a named property been defined - bool IsPropertyDefined(const std::string& name) const; - - // is a named property set to chain - bool IsPropertyChained(const std::string& name) const; -}; - -#endif diff --git a/Source/cmSetPropertyCommand.cxx b/Source/cmSetPropertyCommand.cxx index 4dbbbd7..07cb7c9 100644 --- a/Source/cmSetPropertyCommand.cxx +++ b/Source/cmSetPropertyCommand.cxx @@ -43,7 +43,9 @@ bool HandleSourceMode(cmExecutionStatus& status, const std::set<std::string>& names, const std::string& propertyName, const std::string& propertyValue, bool appendAsString, - bool appendMode, bool remove); + bool appendMode, bool remove, + const std::vector<cmMakefile*>& directory_makefiles, + bool source_file_paths_should_be_absolute); bool HandleSource(cmSourceFile* sf, const std::string& propertyName, const std::string& propertyValue, bool appendAsString, bool appendMode, bool remove); @@ -74,6 +76,131 @@ bool HandleInstall(cmInstalledFile* file, cmMakefile& makefile, bool appendMode, bool remove); } +namespace SetPropertyCommand { +bool HandleSourceFileDirectoryScopes( + cmExecutionStatus& status, std::vector<std::string>& source_file_directories, + std::vector<std::string>& source_file_target_directories, + std::vector<cmMakefile*>& directory_makefiles) +{ + cmMakefile* current_dir_mf = &status.GetMakefile(); + if (!source_file_directories.empty()) { + for (const std::string& dir_path : source_file_directories) { + const std::string absolute_dir_path = cmSystemTools::CollapseFullPath( + dir_path, current_dir_mf->GetCurrentSourceDirectory()); + cmMakefile* dir_mf = + status.GetMakefile().GetGlobalGenerator()->FindMakefile( + absolute_dir_path); + if (!dir_mf) { + status.SetError(cmStrCat("given non-existent DIRECTORY ", dir_path)); + return false; + } + directory_makefiles.push_back(dir_mf); + } + } else if (!source_file_target_directories.empty()) { + for (const std::string& target_name : source_file_target_directories) { + cmTarget* target = current_dir_mf->FindTargetToUse(target_name); + if (!target) { + status.SetError(cmStrCat( + "given non-existent target for DIRECTORY_TARGET ", target_name)); + return false; + } + cmProp target_source_dir = target->GetProperty("SOURCE_DIR"); + cmMakefile* target_dir_mf = + status.GetMakefile().GetGlobalGenerator()->FindMakefile( + *target_source_dir); + directory_makefiles.push_back(target_dir_mf); + } + } else { + directory_makefiles.push_back(current_dir_mf); + } + return true; +} + +bool HandleSourceFileDirectoryScopeValidation( + cmExecutionStatus& status, bool source_file_directory_option_enabled, + bool source_file_target_option_enabled, + std::vector<std::string>& source_file_directories, + std::vector<std::string>& source_file_target_directories) +{ + // Validate source file directory scopes. + if (source_file_directory_option_enabled && + source_file_directories.empty()) { + std::string errors = "called with incorrect number of arguments " + "no value provided to the DIRECTORY option"; + status.SetError(errors); + return false; + } + if (source_file_target_option_enabled && + source_file_target_directories.empty()) { + std::string errors = "called with incorrect number of arguments " + "no value provided to the TARGET_DIRECTORY option"; + status.SetError(errors); + return false; + } + return true; +} + +bool HandleAndValidateSourceFileDirectortoryScopes( + cmExecutionStatus& status, bool source_file_directory_option_enabled, + bool source_file_target_option_enabled, + std::vector<std::string>& source_file_directories, + std::vector<std::string>& source_file_target_directories, + std::vector<cmMakefile*>& source_file_directory_makefiles) +{ + bool scope_options_valid = + SetPropertyCommand::HandleSourceFileDirectoryScopeValidation( + status, source_file_directory_option_enabled, + source_file_target_option_enabled, source_file_directories, + source_file_target_directories); + if (!scope_options_valid) { + return false; + } + + scope_options_valid = SetPropertyCommand::HandleSourceFileDirectoryScopes( + status, source_file_directories, source_file_target_directories, + source_file_directory_makefiles); + return scope_options_valid; +} + +std::string MakeSourceFilePathAbsoluteIfNeeded( + cmExecutionStatus& status, const std::string& source_file_path, + const bool needed) +{ + if (!needed) { + return source_file_path; + } + const std::string absolute_file_path = cmSystemTools::CollapseFullPath( + source_file_path, status.GetMakefile().GetCurrentSourceDirectory()); + return absolute_file_path; +} + +void MakeSourceFilePathsAbsoluteIfNeeded( + cmExecutionStatus& status, + std::vector<std::string>& source_files_absolute_paths, + std::vector<std::string>::const_iterator files_it_begin, + std::vector<std::string>::const_iterator files_it_end, const bool needed) +{ + + // Make the file paths absolute, so that relative source file paths are + // picked up relative to the command calling site, regardless of the + // directory scope. + std::vector<std::string>::difference_type num_files = + files_it_end - files_it_begin; + source_files_absolute_paths.reserve(num_files); + + if (!needed) { + source_files_absolute_paths.assign(files_it_begin, files_it_end); + return; + } + + for (; files_it_begin != files_it_end; ++files_it_begin) { + const std::string absolute_file_path = + MakeSourceFilePathAbsoluteIfNeeded(status, *files_it_begin, true); + source_files_absolute_paths.push_back(absolute_file_path); + } +} +} + bool cmSetPropertyCommand(std::vector<std::string> const& args, cmExecutionStatus& status) { @@ -114,13 +241,20 @@ bool cmSetPropertyCommand(std::vector<std::string> const& args, std::string propertyName; std::string propertyValue; + std::vector<std::string> source_file_directories; + std::vector<std::string> source_file_target_directories; + bool source_file_directory_option_enabled = false; + bool source_file_target_option_enabled = false; + // Parse the rest of the arguments up to the values. enum Doing { DoingNone, DoingNames, DoingProperty, - DoingValues + DoingValues, + DoingSourceDirectory, + DoingSourceTargetDirectory }; Doing doing = DoingNames; const char* sep = ""; @@ -137,8 +271,20 @@ bool cmSetPropertyCommand(std::vector<std::string> const& args, appendMode = true; remove = false; appendAsString = true; + } else if (doing == DoingNames && scope == cmProperty::SOURCE_FILE && + arg == "DIRECTORY") { + doing = DoingSourceDirectory; + source_file_directory_option_enabled = true; + } else if (doing == DoingNames && scope == cmProperty::SOURCE_FILE && + arg == "TARGET_DIRECTORY") { + doing = DoingSourceTargetDirectory; + source_file_target_option_enabled = true; } else if (doing == DoingNames) { names.insert(arg); + } else if (doing == DoingSourceDirectory) { + source_file_directories.push_back(arg); + } else if (doing == DoingSourceTargetDirectory) { + source_file_target_directories.push_back(arg); } else if (doing == DoingProperty) { propertyName = arg; doing = DoingValues; @@ -159,6 +305,18 @@ bool cmSetPropertyCommand(std::vector<std::string> const& args, return false; } + std::vector<cmMakefile*> source_file_directory_makefiles; + bool file_scopes_handled = + SetPropertyCommand::HandleAndValidateSourceFileDirectortoryScopes( + status, source_file_directory_option_enabled, + source_file_target_option_enabled, source_file_directories, + source_file_target_directories, source_file_directory_makefiles); + if (!file_scopes_handled) { + return false; + } + bool source_file_paths_should_be_absolute = + source_file_directory_option_enabled || source_file_target_option_enabled; + // Dispatch property setting. switch (scope) { case cmProperty::GLOBAL: @@ -172,7 +330,9 @@ bool cmSetPropertyCommand(std::vector<std::string> const& args, appendAsString, appendMode, remove); case cmProperty::SOURCE_FILE: return HandleSourceMode(status, names, propertyName, propertyValue, - appendAsString, appendMode, remove); + appendAsString, appendMode, remove, + source_file_directory_makefiles, + source_file_paths_should_be_absolute); case cmProperty::TEST: return HandleTestMode(status, names, propertyName, propertyValue, appendAsString, appendMode, remove); @@ -315,21 +475,32 @@ bool HandleSourceMode(cmExecutionStatus& status, const std::set<std::string>& names, const std::string& propertyName, const std::string& propertyValue, bool appendAsString, - bool appendMode, bool remove) + bool appendMode, bool remove, + const std::vector<cmMakefile*>& directory_makefiles, + const bool source_file_paths_should_be_absolute) { - for (std::string const& name : names) { - // Get the source file. - if (cmSourceFile* sf = status.GetMakefile().GetOrCreateSource(name)) { - if (!HandleSource(sf, propertyName, propertyValue, appendAsString, - appendMode, remove)) { + std::vector<std::string> files_absolute; + std::vector<std::string> unique_files(names.begin(), names.end()); + SetPropertyCommand::MakeSourceFilePathsAbsoluteIfNeeded( + status, files_absolute, unique_files.begin(), unique_files.end(), + source_file_paths_should_be_absolute); + + for (const auto mf : directory_makefiles) { + for (std::string const& name : files_absolute) { + // Get the source file. + if (cmSourceFile* sf = mf->GetOrCreateSource(name)) { + if (!HandleSource(sf, propertyName, propertyValue, appendAsString, + appendMode, remove)) { + return false; + } + } else { + status.SetError(cmStrCat( + "given SOURCE name that could not be found or created: ", name)); return false; } - } else { - status.SetError(cmStrCat( - "given SOURCE name that could not be found or created: ", name)); - return false; } } + return true; } diff --git a/Source/cmSetPropertyCommand.h b/Source/cmSetPropertyCommand.h index ec36f84..af566a3 100644 --- a/Source/cmSetPropertyCommand.h +++ b/Source/cmSetPropertyCommand.h @@ -8,9 +8,38 @@ #include <string> #include <vector> +class cmMakefile; class cmExecutionStatus; bool cmSetPropertyCommand(std::vector<std::string> const& args, cmExecutionStatus& status); +namespace SetPropertyCommand { +bool HandleSourceFileDirectoryScopes( + cmExecutionStatus& status, std::vector<std::string>& source_file_directories, + std::vector<std::string>& source_file_target_directories, + std::vector<cmMakefile*>& directory_makefiles); + +bool HandleSourceFileDirectoryScopeValidation( + cmExecutionStatus& status, bool source_file_directory_option_enabled, + bool source_file_target_option_enabled, + std::vector<std::string>& source_file_directories, + std::vector<std::string>& source_file_target_directories); + +bool HandleAndValidateSourceFileDirectortoryScopes( + cmExecutionStatus& status, bool source_directories_option_encountered, + bool source_target_directories_option_encountered, + std::vector<std::string>& source_directories, + std::vector<std::string>& source_target_directories, + std::vector<cmMakefile*>& source_file_directory_makefiles); + +std::string MakeSourceFilePathAbsoluteIfNeeded( + cmExecutionStatus& status, const std::string& source_file_path, bool needed); +void MakeSourceFilePathsAbsoluteIfNeeded( + cmExecutionStatus& status, + std::vector<std::string>& source_files_absolute_paths, + std::vector<std::string>::const_iterator files_it_begin, + std::vector<std::string>::const_iterator files_it_end, bool needed); +} + #endif diff --git a/Source/cmSetSourceFilesPropertiesCommand.cxx b/Source/cmSetSourceFilesPropertiesCommand.cxx index 7a53a1d..3135a06 100644 --- a/Source/cmSetSourceFilesPropertiesCommand.cxx +++ b/Source/cmSetSourceFilesPropertiesCommand.cxx @@ -10,9 +10,16 @@ #include "cmExecutionStatus.h" #include "cmMakefile.h" +#include "cmSetPropertyCommand.h" #include "cmSourceFile.h" #include "cmStringAlgorithms.h" +static bool RunCommandForScope( + cmMakefile* mf, std::vector<std::string>::const_iterator file_begin, + std::vector<std::string>::const_iterator file_end, + std::vector<std::string>::const_iterator prop_begin, + std::vector<std::string>::const_iterator prop_end, std::string& errors); + bool cmSetSourceFilesPropertiesCommand(std::vector<std::string> const& args, cmExecutionStatus& status) { @@ -23,16 +30,86 @@ bool cmSetSourceFilesPropertiesCommand(std::vector<std::string> const& args, // break the arguments into source file names and properties // old style allows for specifier before PROPERTIES keyword - static const cm::string_view propNames[] = { - "ABSTRACT", "GENERATED", "WRAP_EXCLUDE", - "COMPILE_FLAGS", "OBJECT_DEPENDS", "PROPERTIES" + static const cm::string_view prop_names[] = { + "ABSTRACT", "GENERATED", "WRAP_EXCLUDE", "COMPILE_FLAGS", + "OBJECT_DEPENDS", "PROPERTIES", "DIRECTORY", "TARGET_DIRECTORY" }; - auto propsBegin = std::find_first_of( - args.begin(), args.end(), std::begin(propNames), std::end(propNames)); + auto isNotAPropertyKeyword = + [](const std::vector<std::string>::const_iterator& arg_it) { + return std::all_of( + std::begin(prop_names), std::end(prop_names), + [&arg_it](cm::string_view prop_name) { return *arg_it != prop_name; }); + }; + + auto options_begin = std::find_first_of( + args.begin(), args.end(), std::begin(prop_names), std::end(prop_names)); + auto options_it = options_begin; + + // Handle directory options. + std::vector<std::string> source_file_directories; + std::vector<std::string> source_file_target_directories; + bool source_file_directory_option_enabled = false; + bool source_file_target_option_enabled = false; + std::vector<cmMakefile*> source_file_directory_makefiles; + + if (options_it != args.end() && *options_it == "DIRECTORY") { + source_file_directory_option_enabled = true; + ++options_it; + while (options_it != args.end() && isNotAPropertyKeyword(options_it)) { + source_file_directories.push_back(*options_it); + ++options_it; + } + } else if (options_it != args.end() && *options_it == "TARGET_DIRECTORY") { + source_file_target_option_enabled = true; + ++options_it; + while (options_it != args.end() && isNotAPropertyKeyword(options_it)) { + source_file_target_directories.push_back(*options_it); + ++options_it; + } + } + const auto props_begin = options_it; + + bool file_scopes_handled = + SetPropertyCommand::HandleAndValidateSourceFileDirectortoryScopes( + status, source_file_directory_option_enabled, + source_file_target_option_enabled, source_file_directories, + source_file_target_directories, source_file_directory_makefiles); + if (!file_scopes_handled) { + return false; + } + + std::vector<std::string> files; + bool source_file_paths_should_be_absolute = + source_file_directory_option_enabled || source_file_target_option_enabled; + SetPropertyCommand::MakeSourceFilePathsAbsoluteIfNeeded( + status, files, args.begin(), options_begin, + source_file_paths_should_be_absolute); + + // Now call the worker function for each directory scope represented by a + // cmMakefile instance. + std::string errors; + for (const auto mf : source_file_directory_makefiles) { + bool ret = RunCommandForScope(mf, files.begin(), files.end(), props_begin, + args.end(), errors); + if (!ret) { + status.SetError(errors); + return ret; + } + } + + return true; +} + +static bool RunCommandForScope( + cmMakefile* mf, std::vector<std::string>::const_iterator file_begin, + std::vector<std::string>::const_iterator file_end, + std::vector<std::string>::const_iterator prop_begin, + std::vector<std::string>::const_iterator prop_end, std::string& errors) +{ std::vector<std::string> propertyPairs; // build the property pairs - for (auto j = propsBegin; j != args.end(); ++j) { + for (auto j = prop_begin; j != prop_end; ++j) { // consume old style options if (*j == "ABSTRACT" || *j == "GENERATED" || *j == "WRAP_EXCLUDE") { propertyPairs.emplace_back(*j); @@ -40,26 +117,26 @@ bool cmSetSourceFilesPropertiesCommand(std::vector<std::string> const& args, } else if (*j == "COMPILE_FLAGS") { propertyPairs.emplace_back("COMPILE_FLAGS"); ++j; - if (j == args.end()) { - status.SetError("called with incorrect number of arguments " - "COMPILE_FLAGS with no flags"); + if (j == prop_end) { + errors = "called with incorrect number of arguments " + "COMPILE_FLAGS with no flags"; return false; } propertyPairs.push_back(*j); } else if (*j == "OBJECT_DEPENDS") { propertyPairs.emplace_back("OBJECT_DEPENDS"); ++j; - if (j == args.end()) { - status.SetError("called with incorrect number of arguments " - "OBJECT_DEPENDS with no dependencies"); + if (j == prop_end) { + errors = "called with incorrect number of arguments " + "OBJECT_DEPENDS with no dependencies"; return false; } propertyPairs.push_back(*j); } else if (*j == "PROPERTIES") { // PROPERTIES is followed by new style prop value pairs - cmStringRange newStyleProps{ j + 1, args.end() }; + cmStringRange newStyleProps{ j + 1, prop_end }; if (newStyleProps.size() % 2 != 0) { - status.SetError("called with incorrect number of arguments."); + errors = "called with incorrect number of arguments."; return false; } // set newStyleProps as is. @@ -67,16 +144,16 @@ bool cmSetSourceFilesPropertiesCommand(std::vector<std::string> const& args, // break out of the loop. break; } else { - status.SetError("called with illegal arguments, maybe missing a " - "PROPERTIES specifier?"); + errors = "called with illegal arguments, maybe missing a " + "PROPERTIES specifier?"; return false; } } // loop over all the files - for (const std::string& sfname : cmStringRange{ args.begin(), propsBegin }) { + for (const std::string& sfname : cmStringRange{ file_begin, file_end }) { // get the source file - if (cmSourceFile* sf = status.GetMakefile().GetOrCreateSource(sfname)) { + if (cmSourceFile* sf = mf->GetOrCreateSource(sfname)) { // loop through the props and set them for (auto k = propertyPairs.begin(); k != propertyPairs.end(); k += 2) { sf->SetProperty(*k, (k + 1)->c_str()); diff --git a/Source/cmState.cxx b/Source/cmState.cxx index df013f4..18d8537 100644 --- a/Source/cmState.cxx +++ b/Source/cmState.cxx @@ -265,7 +265,7 @@ void cmState::RemoveCacheEntryProperty(std::string const& key, cmStateSnapshot cmState::Reset() { this->GlobalProperties.Clear(); - this->PropertyDefinitions.clear(); + this->PropertyDefinitions = {}; this->GlobVerificationManager->Reset(); cmStateDetail::PositionType pos = this->SnapshotData.Truncate(); @@ -331,39 +331,23 @@ void cmState::DefineProperty(const std::string& name, const std::string& ShortDescription, const std::string& FullDescription, bool chained) { - this->PropertyDefinitions[scope].DefineProperty( - name, scope, ShortDescription, FullDescription, chained); + this->PropertyDefinitions.DefineProperty(name, scope, ShortDescription, + FullDescription, chained); } cmPropertyDefinition const* cmState::GetPropertyDefinition( const std::string& name, cmProperty::ScopeType scope) const { - if (this->IsPropertyDefined(name, scope)) { - cmPropertyDefinitionMap const& defs = - this->PropertyDefinitions.find(scope)->second; - return &defs.find(name)->second; - } - return nullptr; -} - -bool cmState::IsPropertyDefined(const std::string& name, - cmProperty::ScopeType scope) const -{ - auto it = this->PropertyDefinitions.find(scope); - if (it == this->PropertyDefinitions.end()) { - return false; - } - return it->second.IsPropertyDefined(name); + return this->PropertyDefinitions.GetPropertyDefinition(name, scope); } bool cmState::IsPropertyChained(const std::string& name, cmProperty::ScopeType scope) const { - auto it = this->PropertyDefinitions.find(scope); - if (it == this->PropertyDefinitions.end()) { - return false; + if (auto def = this->GetPropertyDefinition(name, scope)) { + return def->IsChained(); } - return it->second.IsPropertyChained(name); + return false; } void cmState::SetLanguageEnabled(std::string const& l) diff --git a/Source/cmState.h b/Source/cmState.h index e966935..f2bd32a 100644 --- a/Source/cmState.h +++ b/Source/cmState.h @@ -17,7 +17,7 @@ #include "cmListFileCache.h" #include "cmPolicies.h" #include "cmProperty.h" -#include "cmPropertyDefinitionMap.h" +#include "cmPropertyDefinition.h" #include "cmPropertyMap.h" #include "cmStatePrivate.h" #include "cmStateTypes.h" @@ -25,7 +25,6 @@ class cmCacheManager; class cmCommand; class cmGlobVerificationManager; -class cmPropertyDefinition; class cmStateSnapshot; class cmMessenger; class cmExecutionStatus; @@ -131,9 +130,6 @@ public: cmPropertyDefinition const* GetPropertyDefinition( const std::string& name, cmProperty::ScopeType scope) const; - // Is a property defined? - bool IsPropertyDefined(const std::string& name, - cmProperty::ScopeType scope) const; bool IsPropertyChained(const std::string& name, cmProperty::ScopeType scope) const; @@ -225,7 +221,7 @@ private: const std::string& variable, cmListFileBacktrace const& bt); - std::map<cmProperty::ScopeType, cmPropertyDefinitionMap> PropertyDefinitions; + cmPropertyDefinitionMap PropertyDefinitions; std::vector<std::string> EnabledLanguages; std::map<std::string, Command> BuiltinCommands; std::map<std::string, Command> ScriptedCommands; diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index d43fbe5..e165f4c 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -215,7 +215,7 @@ public: }; cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, - Visibility vis, cmMakefile* mf, bool perConfig) + Visibility vis, cmMakefile* mf, PerConfig perConfig) : impl(cm::make_unique<cmTargetInternals>()) { assert(mf); @@ -231,7 +231,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, (vis == VisibilityImported || vis == VisibilityImportedGlobally); impl->ImportedGloballyVisible = vis == VisibilityImportedGlobally; impl->BuildInterfaceIncludesAppended = false; - impl->PerConfig = perConfig; + impl->PerConfig = (perConfig == PerConfig::Yes); // Check whether this is a DLL platform. impl->IsDLLPlatform = diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 8fecd41..6bd47f7 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -45,8 +45,14 @@ public: VisibilityImportedGlobally }; + enum class PerConfig + { + Yes, + No + }; + cmTarget(std::string const& name, cmStateEnums::TargetType type, - Visibility vis, cmMakefile* mf, bool perConfig); + Visibility vis, cmMakefile* mf, PerConfig perConfig); cmTarget(cmTarget const&) = delete; cmTarget(cmTarget&&) noexcept; diff --git a/Source/cmTestGenerator.cxx b/Source/cmTestGenerator.cxx index 025a7b3..4e41993 100644 --- a/Source/cmTestGenerator.cxx +++ b/Source/cmTestGenerator.cxx @@ -76,7 +76,7 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os, cmGeneratorExpression ge(this->Test->GetBacktrace()); // Start the test command. - os << indent << "add_test(" << this->Test->GetName() << " "; + os << indent << "add_test(\"" << this->Test->GetName() << "\" "; // Evaluate command line arguments std::vector<std::string> argv = @@ -126,8 +126,8 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os, os << ")\n"; // Output properties for the test. - os << indent << "set_tests_properties(" << this->Test->GetName() - << " PROPERTIES "; + os << indent << "set_tests_properties(\"" << this->Test->GetName() + << "\" PROPERTIES "; for (auto const& i : this->Test->GetProperties().GetList()) { os << " " << i.first << " " << cmOutputConverter::EscapeForCMake( @@ -139,7 +139,8 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os, void cmTestGenerator::GenerateScriptNoConfig(std::ostream& os, Indent indent) { - os << indent << "add_test(" << this->Test->GetName() << " NOT_AVAILABLE)\n"; + os << indent << "add_test(\"" << this->Test->GetName() + << "\" NOT_AVAILABLE)\n"; } bool cmTestGenerator::NeedsScriptNoConfig() const @@ -159,9 +160,8 @@ void cmTestGenerator::GenerateOldStyle(std::ostream& fout, Indent indent) std::string exe = command[0]; cmSystemTools::ConvertToUnixSlashes(exe); - fout << indent; - fout << "add_test("; - fout << this->Test->GetName() << " \"" << exe << "\""; + fout << indent << "add_test(\"" << this->Test->GetName() << "\" \"" << exe + << "\""; for (std::string const& arg : cmMakeRange(command).advance(1)) { // Just double-quote all arguments so they are re-parsed diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 93c09fe..97f7093 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -248,6 +248,7 @@ cmVisualStudio10TargetGenerator::cmVisualStudio10TargetGenerator( this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget); this->InSourceBuild = (this->Makefile->GetCurrentSourceDirectory() == this->Makefile->GetCurrentBinaryDirectory()); + this->ClassifyAllConfigSources(); } cmVisualStudio10TargetGenerator::~cmVisualStudio10TargetGenerator() @@ -921,13 +922,11 @@ void cmVisualStudio10TargetGenerator::WriteDotNetDocumentationFile(Elem& e0) void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup(Elem& e0) { - std::vector<cmSourceFile const*> resxObjs; - this->GeneratorTarget->GetResxSources(resxObjs, ""); - if (!resxObjs.empty()) { + if (!this->ResxObjs.empty()) { Elem e1(e0, "ItemGroup"); std::string srcDir = this->Makefile->GetCurrentSourceDirectory(); ConvertToWindowsSlash(srcDir); - for (cmSourceFile const* oi : resxObjs) { + for (cmSourceFile const* oi : this->ResxObjs) { std::string obj = oi->GetFullPath(); ConvertToWindowsSlash(obj); bool useRelativePath = false; @@ -1016,11 +1015,9 @@ void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup(Elem& e0) void cmVisualStudio10TargetGenerator::WriteXamlFilesGroup(Elem& e0) { - std::vector<cmSourceFile const*> xamlObjs; - this->GeneratorTarget->GetXamlSources(xamlObjs, ""); - if (!xamlObjs.empty()) { + if (!this->XamlObjs.empty()) { Elem e1(e0, "ItemGroup"); - for (cmSourceFile const* oi : xamlObjs) { + for (cmSourceFile const* oi : this->XamlObjs) { std::string obj = oi->GetFullPath(); std::string xamlType; cmProp xamlTypeProperty = oi->GetProperty("VS_XAML_TYPE"); @@ -1329,21 +1326,27 @@ void cmVisualStudio10TargetGenerator::WriteNsightTegraConfigurationValues( void cmVisualStudio10TargetGenerator::WriteCustomCommands(Elem& e0) { this->CSharpCustomCommandNames.clear(); - std::vector<cmSourceFile const*> customCommands; - this->GeneratorTarget->GetCustomCommands(customCommands, ""); - for (cmSourceFile const* si : customCommands) { - this->WriteCustomCommand(e0, si); + + cmSourceFile const* srcCMakeLists = + this->LocalGenerator->CreateVCProjBuildRule(); + + for (cmGeneratorTarget::AllConfigSource const& si : + this->GeneratorTarget->GetAllConfigSources()) { + if (si.Source == srcCMakeLists) { + // Skip explicit reference to CMakeLists.txt source. + continue; + } + this->WriteCustomCommand(e0, si.Source); } // Add CMakeLists.txt file with rule to re-run CMake for user convenience. if (this->GeneratorTarget->GetType() != cmStateEnums::GLOBAL_TARGET && this->GeneratorTarget->GetName() != CMAKE_CHECK_BUILD_SYSTEM_TARGET) { - if (cmSourceFile const* sf = - this->LocalGenerator->CreateVCProjBuildRule()) { + if (srcCMakeLists) { // Write directly rather than through WriteCustomCommand because // we do not want the de-duplication and it has no dependencies. - if (cmCustomCommand const* command = sf->GetCustomCommand()) { - this->WriteCustomRule(e0, sf, *command); + if (cmCustomCommand const* command = srcCMakeLists->GetCustomCommand()) { + this->WriteCustomRule(e0, srcCMakeLists, *command); } } } @@ -1624,11 +1627,9 @@ void cmVisualStudio10TargetGenerator::WriteGroups() } } - std::vector<cmSourceFile const*> resxObjs; - this->GeneratorTarget->GetResxSources(resxObjs, ""); - if (!resxObjs.empty()) { + if (!this->ResxObjs.empty()) { Elem e1(e0, "ItemGroup"); - for (cmSourceFile const* oi : resxObjs) { + for (cmSourceFile const* oi : this->ResxObjs) { std::string obj = oi->GetFullPath(); ConvertToWindowsSlash(obj); Elem e2(e1, "EmbeddedResource"); @@ -1656,7 +1657,7 @@ void cmVisualStudio10TargetGenerator::WriteGroups() } } - if (!resxObjs.empty() || !this->AddedFiles.empty()) { + if (!this->ResxObjs.empty() || !this->AddedFiles.empty()) { std::string guidName = "SG_Filter_Resource Files"; std::string guid = this->GlobalGenerator->GetGUID(guidName); Elem e2(e1, "Filter"); @@ -2209,10 +2210,10 @@ void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0) } } break; case cmGeneratorTarget::SourceKindResx: - // Handled elsewhere. + this->ResxObjs.push_back(si.Source); break; case cmGeneratorTarget::SourceKindXaml: - // Handled elsewhere. + this->XamlObjs.push_back(si.Source); break; } @@ -2317,21 +2318,13 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags( cmGeneratorExpression::Find(*cincludes) != std::string::npos; includes += *cincludes; } - std::string lang = - this->GlobalGenerator->GetLanguageFromExtension(sf.GetExtension().c_str()); - std::string sourceLang = this->LocalGenerator->GetSourceFileLanguage(sf); - const std::string& linkLanguage = - this->GeneratorTarget->GetLinkerLanguage(""); - bool needForceLang = false; - // source file does not match its extension language - if (lang != sourceLang) { - needForceLang = true; - lang = sourceLang; - } - // if the source file does not match the linker language - // then force c or c++ + + // Force language if the file extension does not match. + std::string lang = this->LocalGenerator->GetSourceFileLanguage(sf); const char* compileAs = 0; - if (needForceLang || (linkLanguage != lang)) { + if (lang != + this->GlobalGenerator->GetLanguageFromExtension( + sf.GetExtension().c_str())) { if (lang == "CXX") { // force a C++ file type compileAs = "CompileAsCpp"; @@ -2340,6 +2333,7 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags( compileAs = "CompileAsC"; } } + bool noWinRT = this->TargetCompileAsWinRT && lang == "C"; // for the first time we need a new line if there is something // produced here. @@ -2736,13 +2730,6 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions( this->LocalGenerator->AddCompileOptions(flags, this->GeneratorTarget, langForClCompile, configName); } - // set the correct language - if (linkLanguage == "C") { - clOptions.AddFlag("CompileAs", "CompileAsC"); - } - if (linkLanguage == "CXX") { - clOptions.AddFlag("CompileAs", "CompileAsCpp"); - } // Put the IPO enabled configurations into a set. if (this->GeneratorTarget->IsIPOEnabled(linkLanguage, configName)) { @@ -3493,12 +3480,12 @@ void cmVisualStudio10TargetGenerator::WriteAntBuildOptions( // its location as the root source directory. std::string rootDir = this->LocalGenerator->GetCurrentSourceDirectory(); { - std::vector<cmSourceFile const*> extraSources; - this->GeneratorTarget->GetExtraSources(extraSources, ""); - for (cmSourceFile const* si : extraSources) { - if ("androidmanifest.xml" == - cmSystemTools::LowerCase(si->GetLocation().GetName())) { - rootDir = si->GetLocation().GetDirectory(); + for (cmGeneratorTarget::AllConfigSource const& source : + this->GeneratorTarget->GetAllConfigSources()) { + if (source.Kind == cmGeneratorTarget::SourceKindExtra && + "androidmanifest.xml" == + cmSystemTools::LowerCase(source.Source->GetLocation().GetName())) { + rootDir = source.Source->GetLocation().GetDirectory(); break; } } @@ -4133,7 +4120,8 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences(Elem& e0) } // Don't reference targets that don't produce any output. - if (dt->GetManagedType("") == cmGeneratorTarget::ManagedType::Undefined) { + if (dt->GetManagedType(this->Configurations[0]) == + cmGeneratorTarget::ManagedType::Undefined) { e2.Element("ReferenceOutputAssembly", "false"); e2.Element("CopyToOutputDirectory", "Never"); } @@ -4234,12 +4222,13 @@ void cmVisualStudio10TargetGenerator::WriteWinRTPackageCertificateKeyFile( this->GlobalGenerator->TargetsWindowsPhone()) && (cmStateEnums::EXECUTABLE == this->GeneratorTarget->GetType())) { std::string pfxFile; - std::vector<cmSourceFile const*> certificates; - this->GeneratorTarget->GetCertificates(certificates, ""); - for (cmSourceFile const* si : certificates) { - pfxFile = this->ConvertPath(si->GetFullPath(), false); - ConvertToWindowsSlash(pfxFile); - break; + for (cmGeneratorTarget::AllConfigSource const& source : + this->GeneratorTarget->GetAllConfigSources()) { + if (source.Kind == cmGeneratorTarget::SourceKindCertificate) { + pfxFile = this->ConvertPath(source.Source->GetFullPath(), false); + ConvertToWindowsSlash(pfxFile); + break; + } } if (this->IsMissingFiles && @@ -4285,28 +4274,61 @@ void cmVisualStudio10TargetGenerator::WriteWinRTPackageCertificateKeyFile( } } +void cmVisualStudio10TargetGenerator::ClassifyAllConfigSources() +{ + for (cmGeneratorTarget::AllConfigSource const& source : + this->GeneratorTarget->GetAllConfigSources()) { + this->ClassifyAllConfigSource(source); + } +} + +void cmVisualStudio10TargetGenerator::ClassifyAllConfigSource( + cmGeneratorTarget::AllConfigSource const& acs) +{ + switch (acs.Kind) { + case cmGeneratorTarget::SourceKindResx: { + // Build and save the name of the corresponding .h file + // This relationship will be used later when building the project files. + // Both names would have been auto generated from Visual Studio + // where the user supplied the file name and Visual Studio + // appended the suffix. + std::string resx = acs.Source->ResolveFullPath(); + std::string hFileName = resx.substr(0, resx.find_last_of('.')) + ".h"; + this->ExpectedResxHeaders.insert(hFileName); + } break; + case cmGeneratorTarget::SourceKindXaml: { + // Build and save the name of the corresponding .h and .cpp file + // This relationship will be used later when building the project files. + // Both names would have been auto generated from Visual Studio + // where the user supplied the file name and Visual Studio + // appended the suffix. + std::string xaml = acs.Source->ResolveFullPath(); + std::string hFileName = xaml + ".h"; + std::string cppFileName = xaml + ".cpp"; + this->ExpectedXamlHeaders.insert(hFileName); + this->ExpectedXamlSources.insert(cppFileName); + } break; + default: + break; + } +} + bool cmVisualStudio10TargetGenerator::IsResxHeader( const std::string& headerFile) { - std::set<std::string> expectedResxHeaders; - this->GeneratorTarget->GetExpectedResxHeaders(expectedResxHeaders, ""); - return expectedResxHeaders.count(headerFile) > 0; + return this->ExpectedResxHeaders.count(headerFile) > 0; } bool cmVisualStudio10TargetGenerator::IsXamlHeader( const std::string& headerFile) { - std::set<std::string> expectedXamlHeaders; - this->GeneratorTarget->GetExpectedXamlHeaders(expectedXamlHeaders, ""); - return expectedXamlHeaders.count(headerFile) > 0; + return this->ExpectedXamlHeaders.count(headerFile) > 0; } bool cmVisualStudio10TargetGenerator::IsXamlSource( const std::string& sourceFile) { - std::set<std::string> expectedXamlSources; - this->GeneratorTarget->GetExpectedXamlSources(expectedXamlSources, ""); - return expectedXamlSources.count(sourceFile) > 0; + return this->ExpectedXamlSources.count(sourceFile) > 0; } void cmVisualStudio10TargetGenerator::WriteApplicationTypeSettings(Elem& e1) @@ -4387,39 +4409,38 @@ void cmVisualStudio10TargetGenerator::VerifyNecessaryFiles() // For Windows and Windows Phone executables, we will assume that if a // manifest is not present that we need to add all the necessary files if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE) { - std::vector<cmSourceFile const*> manifestSources; - this->GeneratorTarget->GetAppManifest(manifestSources, ""); - { - std::string const& v = this->GlobalGenerator->GetSystemVersion(); - if (this->GlobalGenerator->TargetsWindowsPhone()) { - if (v == "8.0") { - // Look through the sources for WMAppManifest.xml - std::vector<cmSourceFile const*> extraSources; - this->GeneratorTarget->GetExtraSources(extraSources, ""); - bool foundManifest = false; - for (cmSourceFile const* si : extraSources) { - // Need to do a lowercase comparison on the filename - if ("wmappmanifest.xml" == - cmSystemTools::LowerCase(si->GetLocation().GetName())) { - foundManifest = true; - break; - } - } - if (!foundManifest) { - this->IsMissingFiles = true; - } - } else if (v == "8.1") { - if (manifestSources.empty()) { - this->IsMissingFiles = true; + std::vector<cmGeneratorTarget::AllConfigSource> manifestSources = + this->GeneratorTarget->GetAllConfigSources( + cmGeneratorTarget::SourceKindAppManifest); + std::string const& v = this->GlobalGenerator->GetSystemVersion(); + if (this->GlobalGenerator->TargetsWindowsPhone()) { + if (v == "8.0") { + // Look through the sources for WMAppManifest.xml + bool foundManifest = false; + for (cmGeneratorTarget::AllConfigSource const& source : + this->GeneratorTarget->GetAllConfigSources()) { + if (source.Kind == cmGeneratorTarget::SourceKindExtra && + "wmappmanifest.xml" == + cmSystemTools::LowerCase( + source.Source->GetLocation().GetName())) { + foundManifest = true; + break; } } - } else if (this->GlobalGenerator->TargetsWindowsStore()) { + if (!foundManifest) { + this->IsMissingFiles = true; + } + } else if (v == "8.1") { if (manifestSources.empty()) { - if (v == "8.0") { - this->IsMissingFiles = true; - } else if (v == "8.1" || cmHasLiteralPrefix(v, "10.0")) { - this->IsMissingFiles = true; - } + this->IsMissingFiles = true; + } + } + } else if (this->GlobalGenerator->TargetsWindowsStore()) { + if (manifestSources.empty()) { + if (v == "8.0") { + this->IsMissingFiles = true; + } else if (v == "8.1" || cmHasLiteralPrefix(v, "10.0")) { + this->IsMissingFiles = true; } } } diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h index e3782f4..7c71de3 100644 --- a/Source/cmVisualStudio10TargetGenerator.h +++ b/Source/cmVisualStudio10TargetGenerator.h @@ -13,10 +13,11 @@ #include <unordered_map> #include <vector> +#include "cmGeneratorTarget.h" + class cmComputeLinkInformation; class cmCustomCommand; class cmGeneratedFileStream; -class cmGeneratorTarget; class cmGlobalVisualStudio10Generator; class cmLocalVisualStudio10Generator; class cmMakefile; @@ -238,6 +239,14 @@ private: using ToolSourceMap = std::map<std::string, ToolSources>; ToolSourceMap Tools; + std::set<std::string> ExpectedResxHeaders; + std::set<std::string> ExpectedXamlHeaders; + std::set<std::string> ExpectedXamlSources; + std::vector<cmSourceFile const*> ResxObjs; + std::vector<cmSourceFile const*> XamlObjs; + void ClassifyAllConfigSources(); + void ClassifyAllConfigSource(cmGeneratorTarget::AllConfigSource const& acs); + using ConfigToSettings = std::unordered_map<std::string, std::unordered_map<std::string, std::string>>; diff --git a/Source/cmXCodeScheme.cxx b/Source/cmXCodeScheme.cxx index 9ac1457..f4c2f2d 100644 --- a/Source/cmXCodeScheme.cxx +++ b/Source/cmXCodeScheme.cxx @@ -396,7 +396,8 @@ void cmXCodeScheme::WriteBuildableReference(cmXMLWriter& xout, xout.BreakAttributes(); xout.Attribute("BuildableIdentifier", "primary"); xout.Attribute("BlueprintIdentifier", xcObj->GetId()); - xout.Attribute("BuildableName", xcObj->GetTarget()->GetFullName()); + std::string const noConfig; // FIXME: What config to use here? + xout.Attribute("BuildableName", xcObj->GetTarget()->GetFullName(noConfig)); xout.Attribute("BlueprintName", xcObj->GetTarget()->GetName()); xout.Attribute("ReferencedContainer", "container:" + container); xout.EndElement(); diff --git a/Source/kwsys/Directory.cxx b/Source/kwsys/Directory.cxx index d640948..be9158e 100644 --- a/Source/kwsys/Directory.cxx +++ b/Source/kwsys/Directory.cxx @@ -103,7 +103,7 @@ void Directory::Clear() namespace KWSYS_NAMESPACE { -bool Directory::Load(const std::string& name) +bool Directory::Load(const std::string& name, std::string* errorMessage) { this->Clear(); # if (defined(_MSC_VER) && _MSC_VER < 1300) || defined(__BORLANDC__) @@ -146,7 +146,8 @@ bool Directory::Load(const std::string& name) return _findclose(srchHandle) != -1; } -unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name) +unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name, + std::string* errorMessage) { # if (defined(_MSC_VER) && _MSC_VER < 1300) || defined(__BORLANDC__) // Older Visual C++ and Embarcadero compilers. @@ -192,6 +193,8 @@ unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name) # include <sys/types.h> # include <dirent.h> +# include <errno.h> +# include <string.h> // PGI with glibc has trouble with dirent and large file support: // http://www.pgroup.com/userforum/viewtopic.php? @@ -209,29 +212,46 @@ unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name) namespace KWSYS_NAMESPACE { -bool Directory::Load(const std::string& name) +bool Directory::Load(const std::string& name, std::string* errorMessage) { this->Clear(); + errno = 0; DIR* dir = opendir(name.c_str()); if (!dir) { + if (errorMessage != nullptr) { + *errorMessage = std::string(strerror(errno)); + } return false; } + errno = 0; for (kwsys_dirent* d = readdir(dir); d; d = readdir(dir)) { this->Internal->Files.emplace_back(d->d_name); } + if (errno != 0) { + if (errorMessage != nullptr) { + *errorMessage = std::string(strerror(errno)); + } + return false; + } + this->Internal->Path = name; closedir(dir); return true; } -unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name) +unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name, + std::string* errorMessage) { + errno = 0; DIR* dir = opendir(name.c_str()); if (!dir) { + if (errorMessage != nullptr) { + *errorMessage = std::string(strerror(errno)); + } return 0; } @@ -239,6 +259,13 @@ unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name) for (kwsys_dirent* d = readdir(dir); d; d = readdir(dir)) { count++; } + if (errno != 0) { + if (errorMessage != nullptr) { + *errorMessage = std::string(strerror(errno)); + } + return false; + } + closedir(dir); return count; } diff --git a/Source/kwsys/Directory.hxx.in b/Source/kwsys/Directory.hxx.in index 9b0f4c3..7bc9db0 100644 --- a/Source/kwsys/Directory.hxx.in +++ b/Source/kwsys/Directory.hxx.in @@ -35,7 +35,7 @@ public: * in that directory. 0 is returned if the directory can not be * opened, 1 if it is opened. */ - bool Load(const std::string&); + bool Load(const std::string&, std::string* errorMessage = nullptr); /** * Return the number of files in the current directory. @@ -46,7 +46,8 @@ public: * Return the number of files in the specified directory. * A higher performance static method. */ - static unsigned long GetNumberOfFilesInDirectory(const std::string&); + static unsigned long GetNumberOfFilesInDirectory( + const std::string&, std::string* errorMessage = nullptr); /** * Return the file at the given index, the indexing is 0 based diff --git a/Source/kwsys/Glob.cxx b/Source/kwsys/Glob.cxx index fad6ee1..5452f73 100644 --- a/Source/kwsys/Glob.cxx +++ b/Source/kwsys/Glob.cxx @@ -182,7 +182,15 @@ bool Glob::RecurseDirectory(std::string::size_type start, const std::string& dir, GlobMessages* messages) { kwsys::Directory d; - if (!d.Load(dir)) { + std::string errorMessage; + if (!d.Load(dir, &errorMessage)) { + if (messages) { + if (!errorMessage.empty()) { + messages->push_back(Message(Glob::warning, + "Error listing directory '" + dir + + "'! Reason: '" + errorMessage + "'")); + } + } return true; } unsigned long cc; @@ -278,7 +286,9 @@ void Glob::ProcessDirectory(std::string::size_type start, // std::cout << "ProcessDirectory: " << dir << std::endl; bool last = (start == this->Internals->Expressions.size() - 1); if (last && this->Recurse) { - this->RecurseDirectory(start, dir, messages); + if (kwsys::SystemTools::FileIsDirectory(dir)) { + this->RecurseDirectory(start, dir, messages); + } return; } diff --git a/Source/kwsys/Glob.hxx.in b/Source/kwsys/Glob.hxx.in index 170766f..b5a34d5 100644 --- a/Source/kwsys/Glob.hxx.in +++ b/Source/kwsys/Glob.hxx.in @@ -28,6 +28,7 @@ public: enum MessageType { error, + warning, cyclicRecursion }; diff --git a/Source/kwsys/testDirectory.cxx b/Source/kwsys/testDirectory.cxx index b1ab0c8..eb3ca32 100644 --- a/Source/kwsys/testDirectory.cxx +++ b/Source/kwsys/testDirectory.cxx @@ -57,7 +57,11 @@ int _doLongPathTest() Directory testdir; // Set res to failure if the directory doesn't load - res += !testdir.Load(testdirpath); + std::string errorMessage = ""; + res += !testdir.Load(testdirpath, &errorMessage); + if (errorMessage != "") { + std::cerr << "Failed to list directory: " << errorMessage << std::endl; + } // Increment res failure if the directory appears empty res += testdir.GetNumberOfFiles() == 0; // Increment res failures if the path has changed from @@ -73,6 +77,34 @@ int _doLongPathTest() return res; } +int _nonExistentDirectoryTest() +{ + using namespace kwsys; + int res = 0; + std::string testdirpath(TEST_SYSTEMTOOLS_BINARY_DIR + "/directory_testing/doesnt_exist/"); + std::string errorMessage; + Directory testdir; + + errorMessage = "foo"; + // Increment res failure if directory lists + res += testdir.Load(testdirpath, &errorMessage); +#if !defined(_WIN32) || defined(__CYGWIN__) + // Increment res failure if errorMessage is unmodified + res += (errorMessage == "foo"); +#endif + + errorMessage = "foo"; + // Increment res failure if directory has files + res += (testdir.GetNumberOfFilesInDirectory(testdirpath, &errorMessage) > 0); +#if !defined(_WIN32) || defined(__CYGWIN__) + // Increment res failure if errorMessage is unmodified + res += (errorMessage == "foo"); +#endif + + return res; +} + int _copyDirectoryTest() { using namespace kwsys; @@ -106,5 +138,6 @@ int _copyDirectoryTest() int testDirectory(int, char* []) { - return _doLongPathTest() + _copyDirectoryTest(); + return _doLongPathTest() + _nonExistentDirectoryTest() + + _copyDirectoryTest(); } diff --git a/Tests/ConfigSources/CMakeLists.txt b/Tests/ConfigSources/CMakeLists.txt index 21f923e..6e69e8b 100644 --- a/Tests/ConfigSources/CMakeLists.txt +++ b/Tests/ConfigSources/CMakeLists.txt @@ -1,6 +1,16 @@ cmake_minimum_required(VERSION 3.0) +get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) +if(NOT _isMultiConfig AND NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build") +endif() project(ConfigSources CXX) +# Source file(s) named with the configuration(s). +file(GENERATE + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/config_$<CONFIG>.cpp" + CONTENT "void config_$<CONFIG>() {}\n" + ) + # Per-config sources via INTERFACE_SOURCES. add_library(iface INTERFACE) target_sources(iface INTERFACE @@ -17,6 +27,7 @@ add_executable(ConfigSources $<$<CONFIG:Debug>:main_debug.cpp> $<$<NOT:$<CONFIG:Debug>>:main_other.cpp> $<$<CONFIG:NotAConfig>:does_not_exist.cpp> + ${CMAKE_CURRENT_BINARY_DIR}/config_$<CONFIG>.cpp ) target_link_libraries(ConfigSources iface) @@ -55,3 +66,13 @@ target_compile_definitions(ConfigSourcesLinkIface PRIVATE "$<$<NOT:$<CONFIG:Debug>>:CFG_OTHER>" ) target_link_libraries(ConfigSourcesLinkIface ConfigSourcesIface) + +# A target with sources in only one configuration that is not the +# first in CMAKE_CONFIGURATION_TYPES. +if(CMAKE_CONFIGURATION_TYPES MATCHES ";([^;]+)") + set(one_config "${CMAKE_MATCH_1}") +else() + set(one_config "${CMAKE_BUILD_TYPE}") +endif() +add_library(OneConfigOnly OBJECT "$<$<CONFIG:${one_config}>:${CMAKE_CURRENT_SOURCE_DIR}/iface_src.cpp>") +set_property(TARGET OneConfigOnly PROPERTY LINKER_LANGUAGE CXX) diff --git a/Tests/Cuda/CMakeLists.txt b/Tests/Cuda/CMakeLists.txt index 58b9b03..630cea2 100644 --- a/Tests/Cuda/CMakeLists.txt +++ b/Tests/Cuda/CMakeLists.txt @@ -1,5 +1,4 @@ -ADD_TEST_MACRO(Cuda.Complex CudaComplex) ADD_TEST_MACRO(Cuda.ConsumeCompileFeatures CudaConsumeCompileFeatures) ADD_TEST_MACRO(Cuda.CXXStandardSetTwice CXXStandardSetTwice) ADD_TEST_MACRO(Cuda.ObjectLibrary CudaObjectLibrary) @@ -12,10 +11,16 @@ ADD_TEST_MACRO(Cuda.NotEnabled CudaNotEnabled) ADD_TEST_MACRO(Cuda.SeparableCompCXXOnly SeparableCompCXXOnly) ADD_TEST_MACRO(Cuda.Toolkit Toolkit) ADD_TEST_MACRO(Cuda.IncludePathNoToolkit IncludePathNoToolkit) -ADD_TEST_MACRO(Cuda.ProperDeviceLibraries ProperDeviceLibraries) -ADD_TEST_MACRO(Cuda.ProperLinkFlags ProperLinkFlags) ADD_TEST_MACRO(Cuda.SharedRuntimePlusToolkit SharedRuntimePlusToolkit) +# Separable compilation is currently only supported on NVCC. Disable tests +# using it for other compilers. +if(CMake_TEST_CUDA AND NOT CMake_TEST_CUDA STREQUAL "Clang") + ADD_TEST_MACRO(Cuda.Complex CudaComplex) + ADD_TEST_MACRO(Cuda.ProperDeviceLibraries ProperDeviceLibraries) + ADD_TEST_MACRO(Cuda.ProperLinkFlags ProperLinkFlags) +endif() + # The CUDA only ships the shared version of the toolkit libraries # on windows if(NOT WIN32) diff --git a/Tests/Cuda/ProperLinkFlags/CMakeLists.txt b/Tests/Cuda/ProperLinkFlags/CMakeLists.txt index b6e0e39..d38da6d 100644 --- a/Tests/Cuda/ProperLinkFlags/CMakeLists.txt +++ b/Tests/Cuda/ProperLinkFlags/CMakeLists.txt @@ -9,11 +9,17 @@ project (ProperLinkFlags CUDA CXX) #Specify a set of valid CUDA flags and an invalid set of CXX flags ( for CUDA ) #to make sure we don't use the CXX flags when linking CUDA executables -string(APPEND CMAKE_CUDA_FLAGS " -arch=sm_35 --use_fast_math") +if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA") + string(APPEND CMAKE_CUDA_FLAGS "--use_fast_math") +elseif(CMAKE_CUDA_COMPILER_ID STREQUAL "Clang") + string(APPEND CMAKE_CUDA_FLAGS "-ffast-math") +endif() + set(CMAKE_CXX_FLAGS "-Wall") set(CMAKE_CXX_STANDARD 11) set(CMAKE_CUDA_STANDARD 11) +set(CMAKE_CUDA_ARCHITECTURES 35) add_executable(ProperLinkFlags file1.cu main.cxx) set_target_properties( ProperLinkFlags diff --git a/Tests/CudaOnly/CMakeLists.txt b/Tests/CudaOnly/CMakeLists.txt index d74e810..69190c7 100644 --- a/Tests/CudaOnly/CMakeLists.txt +++ b/Tests/CudaOnly/CMakeLists.txt @@ -1,17 +1,35 @@ ADD_TEST_MACRO(CudaOnly.Architecture Architecture) -ADD_TEST_MACRO(CudaOnly.CircularLinkLine CudaOnlyCircularLinkLine) ADD_TEST_MACRO(CudaOnly.CompileFlags CudaOnlyCompileFlags) ADD_TEST_MACRO(CudaOnly.EnableStandard CudaOnlyEnableStandard) ADD_TEST_MACRO(CudaOnly.ExportPTX CudaOnlyExportPTX) -ADD_TEST_MACRO(CudaOnly.GPUDebugFlag CudaOnlyGPUDebugFlag) -ADD_TEST_MACRO(CudaOnly.ResolveDeviceSymbols CudaOnlyResolveDeviceSymbols) -ADD_TEST_MACRO(CudaOnly.SeparateCompilation CudaOnlySeparateCompilation) ADD_TEST_MACRO(CudaOnly.SharedRuntimePlusToolkit CudaOnlySharedRuntimePlusToolkit) ADD_TEST_MACRO(CudaOnly.Standard98 CudaOnlyStandard98) ADD_TEST_MACRO(CudaOnly.Toolkit CudaOnlyToolkit) ADD_TEST_MACRO(CudaOnly.WithDefs CudaOnlyWithDefs) +if(CMake_TEST_CUDA AND NOT CMake_TEST_CUDA STREQUAL "Clang") + # Separable compilation is currently only supported on NVCC. Disable tests + # using it for other compilers. + ADD_TEST_MACRO(CudaOnly.CircularLinkLine CudaOnlyCircularLinkLine) + ADD_TEST_MACRO(CudaOnly.ResolveDeviceSymbols CudaOnlyResolveDeviceSymbols) + ADD_TEST_MACRO(CudaOnly.SeparateCompilation CudaOnlySeparateCompilation) + + add_test(NAME CudaOnly.DontResolveDeviceSymbols COMMAND + ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> + --build-and-test + "${CMAKE_CURRENT_SOURCE_DIR}/DontResolveDeviceSymbols/" + "${CMAKE_CURRENT_BINARY_DIR}/DontResolveDeviceSymbols/" + ${build_generator_args} + --build-project DontResolveDeviceSymbols + --build-options ${build_options} + --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION> + ) + + # Only NVCC defines __CUDACC_DEBUG__ when compiling in debug mode. + ADD_TEST_MACRO(CudaOnly.GPUDebugFlag CudaOnlyGPUDebugFlag) +endif() + # The CUDA only ships the shared version of the toolkit libraries # on windows if(NOT WIN32) @@ -22,17 +40,6 @@ if(MSVC) ADD_TEST_MACRO(CudaOnly.PDB CudaOnlyPDB) endif() -add_test(NAME CudaOnly.DontResolveDeviceSymbols COMMAND - ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> - --build-and-test - "${CMAKE_CURRENT_SOURCE_DIR}/DontResolveDeviceSymbols/" - "${CMAKE_CURRENT_BINARY_DIR}/DontResolveDeviceSymbols/" - ${build_generator_args} - --build-project DontResolveDeviceSymbols - --build-options ${build_options} - --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION> - ) - add_test(NAME CudaOnly.RuntimeControls COMMAND ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> --build-and-test diff --git a/Tests/CudaOnly/CompileFlags/CMakeLists.txt b/Tests/CudaOnly/CompileFlags/CMakeLists.txt index cbce7d6..5e8a8e4 100644 --- a/Tests/CudaOnly/CompileFlags/CMakeLists.txt +++ b/Tests/CudaOnly/CompileFlags/CMakeLists.txt @@ -1,16 +1,15 @@ cmake_minimum_required(VERSION 3.17) -cmake_policy(SET CMP0104 OLD) project(CompileFlags CUDA) -# Clear defaults. -set(CMAKE_CUDA_ARCHITECTURES) - add_executable(CudaOnlyCompileFlags main.cu) # Try passing CUDA architecture flags explicitly. if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA") target_compile_options(CudaOnlyCompileFlags PRIVATE -gencode arch=compute_50,code=compute_50 - --compiler-options=-DHOST_DEFINE ) +else() + set_property(TARGET CudaOnlyCompileFlags PROPERTY CUDA_ARCHITECTURES 50-real) endif() + +target_compile_options(CudaOnlyCompileFlags PRIVATE -DALWAYS_DEFINE) diff --git a/Tests/CudaOnly/CompileFlags/main.cu b/Tests/CudaOnly/CompileFlags/main.cu index 573d230..999c056 100644 --- a/Tests/CudaOnly/CompileFlags/main.cu +++ b/Tests/CudaOnly/CompileFlags/main.cu @@ -4,11 +4,8 @@ # endif #endif -// Check HOST_DEFINE only for nvcc -#ifndef __CUDA__ -# ifndef HOST_DEFINE -# error "HOST_DEFINE not defined!" -# endif +#ifndef ALWAYS_DEFINE +# error "ALWAYS_DEFINE not defined!" #endif int main() diff --git a/Tests/CudaOnly/ExportPTX/CMakeLists.txt b/Tests/CudaOnly/ExportPTX/CMakeLists.txt index ff6e77c..ee5f54d 100644 --- a/Tests/CudaOnly/ExportPTX/CMakeLists.txt +++ b/Tests/CudaOnly/ExportPTX/CMakeLists.txt @@ -34,16 +34,15 @@ static std::string ptx_paths = "$<TARGET_OBJECTS:CudaPTX>"; # need to also pass the --name option set(output_file ${CMAKE_CURRENT_BINARY_DIR}/embedded_objs.h) -get_filename_component(cuda_compiler_bin "${CMAKE_CUDA_COMPILER}" DIRECTORY) +find_package(CUDAToolkit REQUIRED) find_program(bin_to_c NAMES bin2c - PATHS ${cuda_compiler_bin} + PATHS ${CUDAToolkit_BIN_DIR} ) if(NOT bin_to_c) message(FATAL_ERROR "bin2c not found:\n" - " CMAKE_CUDA_COMPILER='${CMAKE_CUDA_COMPILER}'\n" - " cuda_compiler_bin='${cuda_compiler_bin}'\n" + " CUDAToolkit_BIN_DIR='${CUDAToolkit_BIN_DIR}'\n" ) endif() diff --git a/Tests/CudaOnly/GPUDebugFlag/CMakeLists.txt b/Tests/CudaOnly/GPUDebugFlag/CMakeLists.txt index fbef15f..6675655 100644 --- a/Tests/CudaOnly/GPUDebugFlag/CMakeLists.txt +++ b/Tests/CudaOnly/GPUDebugFlag/CMakeLists.txt @@ -2,18 +2,19 @@ cmake_minimum_required(VERSION 3.7) project (GPUDebugFlag CUDA) -#Goal for this example: -#verify that -G enables gpu debug flags -string(APPEND CMAKE_CUDA_FLAGS " -gencode=arch=compute_30,code=compute_30") -string(APPEND CMAKE_CUDA_FLAGS " -G") set(CMAKE_CUDA_STANDARD 11) +set(CMAKE_CUDA_ARCHITECTURES 30) + +# Goal for this example: +# Verify that enabling device debug works. +string(APPEND CMAKE_CUDA_FLAGS " -G") add_executable(CudaOnlyGPUDebugFlag main.cu) +#CUDA's __CUDACC_DEBUG__ define was added in NVCC 9.0 +#so if we are below 9.0.0 we will manually add the define so that the test +#passes if(CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 9.0.0) - #CUDA's __CUDACC_DEBUG__ define was added in 9.0 - #so if we are below 9.0.0 we will manually add the define so that the test - #passes target_compile_definitions(CudaOnlyGPUDebugFlag PRIVATE "__CUDACC_DEBUG__") endif() diff --git a/Tests/CudaOnly/WithDefs/CMakeLists.txt b/Tests/CudaOnly/WithDefs/CMakeLists.txt index add8131..0ed81d8 100644 --- a/Tests/CudaOnly/WithDefs/CMakeLists.txt +++ b/Tests/CudaOnly/WithDefs/CMakeLists.txt @@ -18,7 +18,7 @@ target_compile_options(CudaOnlyWithDefs PRIVATE -DFLAG_COMPILE_LANG_$<COMPILE_LANGUAGE> -DFLAG_LANG_IS_CUDA=$<COMPILE_LANGUAGE:CUDA> - --compiler-options=-DHOST_DEFINE + $<$<CUDA_COMPILER_ID:NVIDIA>:--compiler-options=-DHOST_DEFINE> # Host-only defines are possible only on NVCC. ) target_compile_definitions(CudaOnlyWithDefs diff --git a/Tests/CudaOnly/WithDefs/main.notcu b/Tests/CudaOnly/WithDefs/main.notcu index a5f4ed6..9119eba 100644 --- a/Tests/CudaOnly/WithDefs/main.notcu +++ b/Tests/CudaOnly/WithDefs/main.notcu @@ -7,8 +7,10 @@ # error "INC_CUDA not defined!" #endif -#ifndef HOST_DEFINE -# error "HOST_DEFINE not defined!" +#ifdef __NVCC__ +# ifndef HOST_DEFINE +# error "HOST_DEFINE not defined!" +# endif #endif #ifndef PACKED_DEFINE diff --git a/Tests/FindDoxygen/SimpleTest/CMakeLists.txt b/Tests/FindDoxygen/SimpleTest/CMakeLists.txt index 332cecc..deec4fd 100644 --- a/Tests/FindDoxygen/SimpleTest/CMakeLists.txt +++ b/Tests/FindDoxygen/SimpleTest/CMakeLists.txt @@ -22,6 +22,7 @@ else() message(FATAL_ERROR "Import target Doxygen::doxygen not defined") endif() +set(DOXYGEN_OUTPUT_DIRECTORY noArgs) doxygen_add_docs(docsNoArgs) if(NOT EXISTS "${PROJECT_BINARY_DIR}/Doxyfile.docsNoArgs") message(FATAL_ERROR "Missing generated file: Doxyfile.docsNoArgs") @@ -30,6 +31,7 @@ if(NOT TARGET docsNoArgs) message(FATAL_ERROR "Target docsNoArgs not created") endif() +set(DOXYGEN_OUTPUT_DIRECTORY withArgs) configure_file(spaces_in_name.cpp.in "spaces in name.cpp" COPYONLY) doxygen_add_docs(docsWithArgs "${CMAKE_CURRENT_BINARY_DIR}/spaces in name.cpp" diff --git a/Tests/Properties/CMakeLists.txt b/Tests/Properties/CMakeLists.txt index a263061..f93f553 100644 --- a/Tests/Properties/CMakeLists.txt +++ b/Tests/Properties/CMakeLists.txt @@ -144,4 +144,143 @@ set_property(CACHE SOME_ENTRY PROPERTY ADVANCED "${expect_ADVANCED}") set_property(CACHE SOME_ENTRY PROPERTY STRINGS "${expect_STRINGS}") check_cache_props() +function(generate_file_for_set_property_test i target_name) + set(src_path "${CMAKE_CURRENT_BINARY_DIR}/src${i}.cpp") + file(GENERATE OUTPUT "${src_path}" CONTENT + "#ifndef def${i}\n\ + #error Expected def${i}\n\ + #endif\n\ + #ifdef _WIN32\n\ + __declspec(dllexport)\n\ + #endif\n\ + void dummy_symbol${i}() {}\n") + target_sources(${target_name} PRIVATE "${src_path}") +endfunction() + +add_library(maindirtest SHARED) add_subdirectory(SubDir2) + +set(src_prefix "${CMAKE_CURRENT_BINARY_DIR}/SubDir2/") + +# Set property + target directory +set_property(SOURCE "${src_prefix}/src1.cpp" + TARGET_DIRECTORY set_prop_lib_1 + PROPERTY COMPILE_DEFINITIONS def1) + +# Append property + target directory +set_property(SOURCE "${src_prefix}/src2.cpp" + TARGET_DIRECTORY set_prop_lib_1 + APPEND PROPERTY COMPILE_DEFINITIONS def2) + +# Set property + relative directory path +set_property(SOURCE "${src_prefix}/src3.cpp" + DIRECTORY SubDir2 + PROPERTY COMPILE_DEFINITIONS def3) + +# Set property + absolute directory path +set_property(SOURCE "${src_prefix}/src4.cpp" + DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/SubDir2" + PROPERTY COMPILE_DEFINITIONS def4) + +# Append property + relative directory path +set_property(SOURCE "${src_prefix}/src5.cpp" + DIRECTORY SubDir2 + APPEND PROPERTY COMPILE_DEFINITIONS def5) + +# Append property + absolute directory path +set_property(SOURCE "${src_prefix}/src6.cpp" + DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/SubDir2" + APPEND PROPERTY COMPILE_DEFINITIONS def6) + + +# Target directory +set_source_files_properties("${CMAKE_CURRENT_BINARY_DIR}/SubDir2/src10.cpp" + TARGET_DIRECTORY set_prop_lib_1 + PROPERTIES COMPILE_DEFINITIONS def10) + +# Relative directory path +set_source_files_properties("${CMAKE_CURRENT_BINARY_DIR}/SubDir2/src11.cpp" + DIRECTORY SubDir2 + PROPERTIES COMPILE_DEFINITIONS def11) + +# Absolute directory path +set_source_files_properties("${CMAKE_CURRENT_BINARY_DIR}/SubDir2/src12.cpp" + DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/SubDir2" + PROPERTIES COMPILE_DEFINITIONS def12) + + +# Multiple files + absolute directory path +set_source_files_properties("${CMAKE_CURRENT_BINARY_DIR}/SubDir2/src20.cpp" + "${CMAKE_CURRENT_BINARY_DIR}/SubDir2/src21.cpp" + DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/SubDir2" + PROPERTIES COMPILE_DEFINITIONS "def20;def21") + +# Multiple files + multiple target directories +set_source_files_properties("${CMAKE_CURRENT_BINARY_DIR}/SubDir2/src22.cpp" + "${CMAKE_CURRENT_BINARY_DIR}/SubDir2/src23.cpp" + TARGET_DIRECTORY set_prop_lib_2 set_prop_lib_3 + PROPERTIES COMPILE_DEFINITIONS "def22;def23") + + +# Multiple files in multiple relative directories +generate_file_for_set_property_test(30 maindirtest) +set_source_files_properties("${CMAKE_CURRENT_BINARY_DIR}/src30.cpp" + "${CMAKE_CURRENT_BINARY_DIR}/SubDir2/src31.cpp" + DIRECTORY . SubDir2 + PROPERTIES COMPILE_DEFINITIONS "def30;def31") + +# Check that specifying files without any properties doesn't crash. +set_source_files_properties("${CMAKE_CURRENT_BINARY_DIR}/src30.cpp" + "${CMAKE_CURRENT_BINARY_DIR}/SubDir2/src31.cpp") + +function(check_get_property_value expected) + if(NOT actual STREQUAL expected) + message(SEND_ERROR "Error: get_property returned unexpected value\n" + "actual: ${actual}\n" + "expected: ${expected}") + endif() +endfunction() + +# Get property + target directory +get_property(actual + SOURCE "${src_prefix}/src1.cpp" + TARGET_DIRECTORY set_prop_lib_1 + PROPERTY COMPILE_DEFINITIONS) +check_get_property_value("def1") + +# Get property + relative directory path +get_property(actual + SOURCE "${src_prefix}/src3.cpp" + DIRECTORY SubDir2 + PROPERTY COMPILE_DEFINITIONS) +check_get_property_value("def3") + +# Get property + absolute directory path +get_property(actual + SOURCE "${src_prefix}/src4.cpp" + DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/SubDir2" + PROPERTY COMPILE_DEFINITIONS) +check_get_property_value("def4") + + +# Get property + target directory +unset(actual) +get_source_file_property(actual + "${CMAKE_CURRENT_BINARY_DIR}/SubDir2/src10.cpp" + TARGET_DIRECTORY set_prop_lib_1 + COMPILE_DEFINITIONS) +check_get_property_value("def10") + +# Get property + relative directory path +get_source_file_property(actual + "${CMAKE_CURRENT_BINARY_DIR}/SubDir2/src11.cpp" + DIRECTORY SubDir2 + COMPILE_DEFINITIONS) +check_get_property_value("def11") + +# Get property + absolute directory path +get_source_file_property(actual + "${CMAKE_CURRENT_BINARY_DIR}/SubDir2/src12.cpp" + DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/SubDir2" + COMPILE_DEFINITIONS) +check_get_property_value("def12") diff --git a/Tests/Properties/SubDir2/CMakeLists.txt b/Tests/Properties/SubDir2/CMakeLists.txt index 377dc83..9b2c79e 100644 --- a/Tests/Properties/SubDir2/CMakeLists.txt +++ b/Tests/Properties/SubDir2/CMakeLists.txt @@ -3,3 +3,28 @@ set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/../subdirtest.cxx" PROPERTIES COMPILE_DEFINITIONS SUBDIR_TEST) add_executable(subdirtest "${CMAKE_CURRENT_SOURCE_DIR}/../subdirtest.cxx") + +# For set_property +add_library(set_prop_lib_1 SHARED) +foreach(i RANGE 1 6) + generate_file_for_set_property_test(${i} set_prop_lib_1) +endforeach() + +# For set_source_files_properties +foreach(i RANGE 10 12) + generate_file_for_set_property_test(${i} set_prop_lib_1) +endforeach() + +# For set_source_files_properties + multiple files + absolute directory path +add_library(set_prop_lib_2 SHARED) +foreach(i RANGE 20 21) + generate_file_for_set_property_test(${i} set_prop_lib_1) +endforeach() + +# For set_source_files_properties + multiple files + multiple target directories +add_library(set_prop_lib_3 SHARED) +generate_file_for_set_property_test(22 set_prop_lib_2) +generate_file_for_set_property_test(23 set_prop_lib_3) + +# For set_source_files_properties + multiple files in multiple directories +generate_file_for_set_property_test(31 set_prop_lib_3) diff --git a/Tests/RunCMake/AndroidTestUtilities/check.cmake b/Tests/RunCMake/AndroidTestUtilities/check.cmake index ccd4d74..c24a3cd 100644 --- a/Tests/RunCMake/AndroidTestUtilities/check.cmake +++ b/Tests/RunCMake/AndroidTestUtilities/check.cmake @@ -13,7 +13,7 @@ function(compare_build_to_expected) endfunction() function(check_for_setup_test) - file(STRINGS "${RunCMake_TEST_BINARY_DIR}/CTestTestfile.cmake" output_var REGEX "add_test\\(setup_test.*") + file(STRINGS "${RunCMake_TEST_BINARY_DIR}/CTestTestfile.cmake" output_var REGEX "add_test\\(\"setup_test\".*") if(NOT output_var) set(RunCMake_TEST_FAILED "Could not find the test: setup_test" PARENT_SCOPE) endif() diff --git a/Tests/RunCMake/CMP0104/CMP0104-WARN.cmake b/Tests/RunCMake/CMP0104/CMP0104-WARN.cmake index 841d0a8..2b4a8f5 100644 --- a/Tests/RunCMake/CMP0104/CMP0104-WARN.cmake +++ b/Tests/RunCMake/CMP0104/CMP0104-WARN.cmake @@ -1 +1,2 @@ include(CMP0104-Common.cmake) +set_property(TARGET cuda PROPERTY CUDA_ARCHITECTURES) diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 8aeb412..230f168 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -272,6 +272,7 @@ add_RunCMake_test(add_dependencies) add_RunCMake_test(add_executable) add_RunCMake_test(add_library) add_RunCMake_test(add_subdirectory) +add_RunCMake_test(add_test) add_RunCMake_test(build_command) add_executable(exit_code exit_code.c) set(execute_process_ARGS -DEXIT_CODE_EXE=$<TARGET_FILE:exit_code>) diff --git a/Tests/RunCMake/CTestResourceAllocation/RunCMakeTest.cmake b/Tests/RunCMake/CTestResourceAllocation/RunCMakeTest.cmake index 777f192..e9aa3a4 100644 --- a/Tests/RunCMake/CTestResourceAllocation/RunCMakeTest.cmake +++ b/Tests/RunCMake/CTestResourceAllocation/RunCMakeTest.cmake @@ -38,6 +38,13 @@ function(run_ctresalloc_verify name tests) run_cmake_command(${name} "${CTRESALLOC_COMMAND}" verify "${RunCMake_SOURCE_DIR}/${name}.log" "${CMAKE_CURRENT_LIST_DIR}/resspec.json" "${tests}") endfunction() +function(read_testing_file filename variable) + file(READ "${RunCMake_TEST_BINARY_DIR}/Testing/TAG" _tag) + string(REGEX REPLACE "^([^\n]*)\n.*$" "\\1" _date "${_tag}") + file(READ "${RunCMake_TEST_BINARY_DIR}/Testing/${_date}/${filename}" _contents) + set("${variable}" "${_contents}" PARENT_SCOPE) +endfunction() + unset(ENV{CTEST_RESOURCE_GROUP_COUNT}) set(RunCMake_TEST_NO_CLEAN 1) file(REMOVE_RECURSE "${RunCMake_BINARY_DIR}/ctresalloc-write-proc-good1-build") diff --git a/Tests/RunCMake/CTestResourceAllocation/process_count-ctest-s-nores-check.cmake b/Tests/RunCMake/CTestResourceAllocation/process_count-ctest-s-nores-check.cmake new file mode 100644 index 0000000..c6e72bd --- /dev/null +++ b/Tests/RunCMake/CTestResourceAllocation/process_count-ctest-s-nores-check.cmake @@ -0,0 +1,4 @@ +read_testing_file("Test.xml" _test_contents) +if(NOT _test_contents MATCHES "#CTEST_RESOURCE_GROUP_COUNT=") + string(APPEND RunCMake_TEST_FAILED "Could not find unset variable CTEST_RESOURCE_GROUP_COUNT in test measurements\n") +endif() diff --git a/Tests/RunCMake/CTestResourceAllocation/process_count-ctest-s-res-check.cmake b/Tests/RunCMake/CTestResourceAllocation/process_count-ctest-s-res-check.cmake index ceda72e..585c36b 100644 --- a/Tests/RunCMake/CTestResourceAllocation/process_count-ctest-s-res-check.cmake +++ b/Tests/RunCMake/CTestResourceAllocation/process_count-ctest-s-res-check.cmake @@ -1 +1,9 @@ verify_ctest_resources() + +read_testing_file("Test.xml" _test_contents) +if(NOT _test_contents MATCHES "\nCTEST_RESOURCE_GROUP_0=widgets") + string(APPEND RunCMake_TEST_FAILED "Could not find variable CTEST_RESOURCE_GROUP_0 in test measurements\n") +endif() +if(NOT _test_contents MATCHES "\nCTEST_RESOURCE_GROUP_0_WIDGETS=id:") + string(APPEND RunCMake_TEST_FAILED "Could not find variable CTEST_RESOURCE_GROUP_0_WIDGETS in test measurements\n") +endif() diff --git a/Tests/RunCMake/CrosscompilingEmulator/AddTest-check.cmake b/Tests/RunCMake/CrosscompilingEmulator/AddTest-check.cmake index 588b77b..3cbbc07 100644 --- a/Tests/RunCMake/CrosscompilingEmulator/AddTest-check.cmake +++ b/Tests/RunCMake/CrosscompilingEmulator/AddTest-check.cmake @@ -7,22 +7,22 @@ endif() set(error_details "There is a problem with generated test file: ${testfile}") -if(testfile_contents MATCHES "add_test[(]DoesNotUseEmulator [^\n]+pseudo_emulator[^\n]+\n") +if(testfile_contents MATCHES "add_test[(][\"]DoesNotUseEmulator[\"] [^\n]+pseudo_emulator[^\n]+\n") message(SEND_ERROR "Used emulator when it should not be used. ${error_details}") endif() -if(NOT testfile_contents MATCHES "add_test[(]UsesEmulator [^\n]+pseudo_emulator[^\n]+\n") +if(NOT testfile_contents MATCHES "add_test[(][\"]UsesEmulator[\"] [^\n]+pseudo_emulator[^\n]+\n") message(SEND_ERROR "Did not use emulator when it should be used. ${error_details}") endif() -if(testfile_contents MATCHES "add_test[(]DoesNotUseEmulatorWithGenex [^\n]+pseudo_emulator[^\n]+\n") +if(testfile_contents MATCHES "add_test[(][\"]DoesNotUseEmulatorWithGenex[\"] [^\n]+pseudo_emulator[^\n]+\n") message(SEND_ERROR "Used emulator when it should not be used. ${error_details}") endif() -if(NOT testfile_contents MATCHES "add_test[(]UsesEmulatorWithExecTargetFromSubdirAddedWithoutGenex [^\n]+pseudo_emulator[^\n]+\n") +if(NOT testfile_contents MATCHES "add_test[(][\"]UsesEmulatorWithExecTargetFromSubdirAddedWithoutGenex[\"] [^\n]+pseudo_emulator[^\n]+\n") message(SEND_ERROR "Did not use emulator when it should be used. ${error_details}") endif() -if(testfile_contents MATCHES "add_test[(]DoesNotUseEmulatorWithExecTargetFromSubdirAddedWithGenex [^\n]+pseudo_emulator[^\n]+\n") +if(testfile_contents MATCHES "add_test[(][\"]DoesNotUseEmulatorWithExecTargetFromSubdirAddedWithGenex[\"] [^\n]+pseudo_emulator[^\n]+\n") message(SEND_ERROR "Used emulator when it should not be used. ${error_details}") endif() diff --git a/Tests/RunCMake/FetchContent/MakeAvailable-stdout.txt b/Tests/RunCMake/FetchContent/MakeAvailable-stdout.txt index 6e6c730..711de6b 100644 --- a/Tests/RunCMake/FetchContent/MakeAvailable-stdout.txt +++ b/Tests/RunCMake/FetchContent/MakeAvailable-stdout.txt @@ -1,2 +1,3 @@ Confirmation project has been added +.*Confirmation subproject has been added .*Confirmation script has been called diff --git a/Tests/RunCMake/FetchContent/MakeAvailable.cmake b/Tests/RunCMake/FetchContent/MakeAvailable.cmake index a93f1f7..d7fc55c 100644 --- a/Tests/RunCMake/FetchContent/MakeAvailable.cmake +++ b/Tests/RunCMake/FetchContent/MakeAvailable.cmake @@ -8,13 +8,22 @@ FetchContent_Declare( WithoutProject SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/WithoutProject ) +FetchContent_Declare( + ProjectSubdir + SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/WithoutProject + SOURCE_SUBDIR ProjectSubdir +) # Order is important and will be verified by test output -FetchContent_MakeAvailable(WithProject WithoutProject) +FetchContent_MakeAvailable(WithProject WithoutProject ProjectSubdir) get_property(addedWith GLOBAL PROPERTY FetchWithProject SET) if(NOT addedWith) - message(SEND_ERROR "Subdir with CMakeLists.txt not added") + message(SEND_ERROR "Project with top level CMakeLists.txt not added") +endif() +get_property(addedSubdir GLOBAL PROPERTY FetchWithSubProject SET) +if(NOT addedSubdir) + message(SEND_ERROR "Project with CMakeLists.txt in subdir not added") endif() include(${withoutproject_SOURCE_DIR}/confirmMessage.cmake) diff --git a/Tests/RunCMake/FetchContent/WithoutProject/ProjectSubdir/CMakeLists.txt b/Tests/RunCMake/FetchContent/WithoutProject/ProjectSubdir/CMakeLists.txt new file mode 100644 index 0000000..216eeb1 --- /dev/null +++ b/Tests/RunCMake/FetchContent/WithoutProject/ProjectSubdir/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.13) +project(ProjectSubdir LANGUAGES NONE) + +set_property(GLOBAL PROPERTY FetchWithSubProject YES) +message(STATUS "Confirmation subproject has been added") diff --git a/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake b/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake index 6472f46..23b89d3 100644 --- a/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake +++ b/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake @@ -285,7 +285,8 @@ run_cmake_command(NoUnusedVariables ${CMAKE_COMMAND} ${CMAKE_CURRENT_LIST_DIR} "-DCMAKE_DEFAULT_CONFIGS=all" ) -if(CMake_TEST_CUDA) +# CudaSimple uses separable compilation, which is currently only supported on NVCC. +if(CMake_TEST_CUDA AND NOT CMake_TEST_CUDA STREQUAL "Clang") set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CudaSimple-build) run_cmake_configure(CudaSimple) include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake) diff --git a/Tests/RunCMake/add_test/CMakeLists.txt.in b/Tests/RunCMake/add_test/CMakeLists.txt.in new file mode 100644 index 0000000..495240d --- /dev/null +++ b/Tests/RunCMake/add_test/CMakeLists.txt.in @@ -0,0 +1,27 @@ +if (NOT DEFINED RUN_AS_SCRIPT) + + cmake_minimum_required(VERSION 3.7) + project(@CASE_NAME@ NONE) + include(CTest) + + # Two fallback tests for set_tests_properties. + add_test(NAME PrefixTest COMMAND "${CMAKE_COMMAND}" --version) + add_test(NAME SuffixTest COMMAND "${CMAKE_COMMAND}" --version) + + add_test( + NAME @CASE_CMAKELISTS_NAME_1@ + COMMAND "${CMAKE_COMMAND}" -D RUN_AS_SCRIPT=1 -P "${CMAKE_CURRENT_LIST_FILE}" + ) + set_tests_properties( + @CASE_CMAKELISTS_NAME_2@ + PROPERTIES + ENVIRONMENT CMAKE_add_test_ENVVAR=1 + ) + +else() + + if(NOT DEFINED ENV{CMAKE_add_test_ENVVAR}) + message(FATAL_ERROR "Setting property on test did not succeed!") + endif() + +endif() diff --git a/Tests/RunCMake/add_test/NameContainsBracketArgument1-stdout.txt b/Tests/RunCMake/add_test/NameContainsBracketArgument1-stdout.txt new file mode 100644 index 0000000..00865d0 --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsBracketArgument1-stdout.txt @@ -0,0 +1 @@ +Test #[0-9]+: \[=\[BracketArgument;SuffixTest\]=\] \.+[ ]+Passed diff --git a/Tests/RunCMake/add_test/NameContainsBracketArgument2-stdout.txt b/Tests/RunCMake/add_test/NameContainsBracketArgument2-stdout.txt new file mode 100644 index 0000000..a744beb --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsBracketArgument2-stdout.txt @@ -0,0 +1 @@ +Test #[0-9]+: BracketArgument;SuffixTest \.+[ ]+Passed diff --git a/Tests/RunCMake/add_test/NameContainsBracketArgument3-result.txt b/Tests/RunCMake/add_test/NameContainsBracketArgument3-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsBracketArgument3-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/add_test/NameContainsBracketArgument3-stderr.txt b/Tests/RunCMake/add_test/NameContainsBracketArgument3-stderr.txt new file mode 100644 index 0000000..32c2112 --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsBracketArgument3-stderr.txt @@ -0,0 +1,2 @@ +Error\(s\) when configuring the project +No tests were found!!! diff --git a/Tests/RunCMake/add_test/NameContainsBracketArgument4-result.txt b/Tests/RunCMake/add_test/NameContainsBracketArgument4-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsBracketArgument4-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/add_test/NameContainsBracketArgument4-stderr.txt b/Tests/RunCMake/add_test/NameContainsBracketArgument4-stderr.txt new file mode 100644 index 0000000..32c2112 --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsBracketArgument4-stderr.txt @@ -0,0 +1,2 @@ +Error\(s\) when configuring the project +No tests were found!!! diff --git a/Tests/RunCMake/add_test/NameContainsEscapedQuote1-result.txt b/Tests/RunCMake/add_test/NameContainsEscapedQuote1-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsEscapedQuote1-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/add_test/NameContainsEscapedQuote1-stderr.txt b/Tests/RunCMake/add_test/NameContainsEscapedQuote1-stderr.txt new file mode 100644 index 0000000..0661945 --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsEscapedQuote1-stderr.txt @@ -0,0 +1 @@ +Unable to find executable: SuffixTest diff --git a/Tests/RunCMake/add_test/NameContainsEscapedQuote1-stdout.txt b/Tests/RunCMake/add_test/NameContainsEscapedQuote1-stdout.txt new file mode 100644 index 0000000..4875409 --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsEscapedQuote1-stdout.txt @@ -0,0 +1 @@ +Test #[0-9]+: EscapedQuote \.+\*\*\*Not Run diff --git a/Tests/RunCMake/add_test/NameContainsEscapedQuote2-result.txt b/Tests/RunCMake/add_test/NameContainsEscapedQuote2-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsEscapedQuote2-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/add_test/NameContainsEscapedQuote2-stderr.txt b/Tests/RunCMake/add_test/NameContainsEscapedQuote2-stderr.txt new file mode 100644 index 0000000..0661945 --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsEscapedQuote2-stderr.txt @@ -0,0 +1 @@ +Unable to find executable: SuffixTest diff --git a/Tests/RunCMake/add_test/NameContainsEscapedQuote2-stdout.txt b/Tests/RunCMake/add_test/NameContainsEscapedQuote2-stdout.txt new file mode 100644 index 0000000..4875409 --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsEscapedQuote2-stdout.txt @@ -0,0 +1 @@ +Test #[0-9]+: EscapedQuote \.+\*\*\*Not Run diff --git a/Tests/RunCMake/add_test/NameContainsEscapedQuote3-result.txt b/Tests/RunCMake/add_test/NameContainsEscapedQuote3-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsEscapedQuote3-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/add_test/NameContainsEscapedQuote3-stderr.txt b/Tests/RunCMake/add_test/NameContainsEscapedQuote3-stderr.txt new file mode 100644 index 0000000..0661945 --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsEscapedQuote3-stderr.txt @@ -0,0 +1 @@ +Unable to find executable: SuffixTest diff --git a/Tests/RunCMake/add_test/NameContainsEscapedQuote3-stdout.txt b/Tests/RunCMake/add_test/NameContainsEscapedQuote3-stdout.txt new file mode 100644 index 0000000..4875409 --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsEscapedQuote3-stdout.txt @@ -0,0 +1 @@ +Test #[0-9]+: EscapedQuote \.+\*\*\*Not Run diff --git a/Tests/RunCMake/add_test/NameContainsEscapedQuote4-result.txt b/Tests/RunCMake/add_test/NameContainsEscapedQuote4-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsEscapedQuote4-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/add_test/NameContainsEscapedQuote4-stderr.txt b/Tests/RunCMake/add_test/NameContainsEscapedQuote4-stderr.txt new file mode 100644 index 0000000..0661945 --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsEscapedQuote4-stderr.txt @@ -0,0 +1 @@ +Unable to find executable: SuffixTest diff --git a/Tests/RunCMake/add_test/NameContainsEscapedQuote4-stdout.txt b/Tests/RunCMake/add_test/NameContainsEscapedQuote4-stdout.txt new file mode 100644 index 0000000..4875409 --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsEscapedQuote4-stdout.txt @@ -0,0 +1 @@ +Test #[0-9]+: EscapedQuote \.+\*\*\*Not Run diff --git a/Tests/RunCMake/add_test/NameContainsEscapedSpecialChars1-stdout.txt b/Tests/RunCMake/add_test/NameContainsEscapedSpecialChars1-stdout.txt new file mode 100644 index 0000000..80435b6 --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsEscapedSpecialChars1-stdout.txt @@ -0,0 +1 @@ +Test #[0-9]+: \(\) # \.+[ ]*Passed diff --git a/Tests/RunCMake/add_test/NameContainsEscapedSpecialChars2-stdout.txt b/Tests/RunCMake/add_test/NameContainsEscapedSpecialChars2-stdout.txt new file mode 100644 index 0000000..80435b6 --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsEscapedSpecialChars2-stdout.txt @@ -0,0 +1 @@ +Test #[0-9]+: \(\) # \.+[ ]*Passed diff --git a/Tests/RunCMake/add_test/NameContainsEscapedSpecialChars3-stdout.txt b/Tests/RunCMake/add_test/NameContainsEscapedSpecialChars3-stdout.txt new file mode 100644 index 0000000..80435b6 --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsEscapedSpecialChars3-stdout.txt @@ -0,0 +1 @@ +Test #[0-9]+: \(\) # \.+[ ]*Passed diff --git a/Tests/RunCMake/add_test/NameContainsEscapedSpecialChars4-stdout.txt b/Tests/RunCMake/add_test/NameContainsEscapedSpecialChars4-stdout.txt new file mode 100644 index 0000000..80435b6 --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsEscapedSpecialChars4-stdout.txt @@ -0,0 +1 @@ +Test #[0-9]+: \(\) # \.+[ ]*Passed diff --git a/Tests/RunCMake/add_test/NameContainsGeneratorExpressionSyntax1-stdout.txt b/Tests/RunCMake/add_test/NameContainsGeneratorExpressionSyntax1-stdout.txt new file mode 100644 index 0000000..172ff99 --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsGeneratorExpressionSyntax1-stdout.txt @@ -0,0 +1 @@ +Test #[0-9]+: \$<BOOL:0> \.+[ ]*Passed diff --git a/Tests/RunCMake/add_test/NameContainsGeneratorExpressionSyntax2-stdout.txt b/Tests/RunCMake/add_test/NameContainsGeneratorExpressionSyntax2-stdout.txt new file mode 100644 index 0000000..172ff99 --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsGeneratorExpressionSyntax2-stdout.txt @@ -0,0 +1 @@ +Test #[0-9]+: \$<BOOL:0> \.+[ ]*Passed diff --git a/Tests/RunCMake/add_test/NameContainsGeneratorExpressionSyntax3-stdout.txt b/Tests/RunCMake/add_test/NameContainsGeneratorExpressionSyntax3-stdout.txt new file mode 100644 index 0000000..172ff99 --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsGeneratorExpressionSyntax3-stdout.txt @@ -0,0 +1 @@ +Test #[0-9]+: \$<BOOL:0> \.+[ ]*Passed diff --git a/Tests/RunCMake/add_test/NameContainsGeneratorExpressionSyntax4-stdout.txt b/Tests/RunCMake/add_test/NameContainsGeneratorExpressionSyntax4-stdout.txt new file mode 100644 index 0000000..172ff99 --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsGeneratorExpressionSyntax4-stdout.txt @@ -0,0 +1 @@ +Test #[0-9]+: \$<BOOL:0> \.+[ ]*Passed diff --git a/Tests/RunCMake/add_test/NameContainsOtherSpecialChars1-stdout.txt b/Tests/RunCMake/add_test/NameContainsOtherSpecialChars1-stdout.txt new file mode 100644 index 0000000..83e3f86 --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsOtherSpecialChars1-stdout.txt @@ -0,0 +1 @@ +Test #[0-9]+: !§\$%&/ü:\*😤~ \.+[ ]*Passed diff --git a/Tests/RunCMake/add_test/NameContainsOtherSpecialChars2-stdout.txt b/Tests/RunCMake/add_test/NameContainsOtherSpecialChars2-stdout.txt new file mode 100644 index 0000000..83e3f86 --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsOtherSpecialChars2-stdout.txt @@ -0,0 +1 @@ +Test #[0-9]+: !§\$%&/ü:\*😤~ \.+[ ]*Passed diff --git a/Tests/RunCMake/add_test/NameContainsOtherSpecialChars3-stdout.txt b/Tests/RunCMake/add_test/NameContainsOtherSpecialChars3-stdout.txt new file mode 100644 index 0000000..83e3f86 --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsOtherSpecialChars3-stdout.txt @@ -0,0 +1 @@ +Test #[0-9]+: !§\$%&/ü:\*😤~ \.+[ ]*Passed diff --git a/Tests/RunCMake/add_test/NameContainsOtherSpecialChars4-stdout.txt b/Tests/RunCMake/add_test/NameContainsOtherSpecialChars4-stdout.txt new file mode 100644 index 0000000..83e3f86 --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsOtherSpecialChars4-stdout.txt @@ -0,0 +1 @@ +Test #[0-9]+: !§\$%&/ü:\*😤~ \.+[ ]*Passed diff --git a/Tests/RunCMake/add_test/NameContainsSemicolon1-stdout.txt b/Tests/RunCMake/add_test/NameContainsSemicolon1-stdout.txt new file mode 100644 index 0000000..0fbf486 --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsSemicolon1-stdout.txt @@ -0,0 +1 @@ +Test #[0-9]+: PrefixTest;SuffixTest \.+[ ]*Passed diff --git a/Tests/RunCMake/add_test/NameContainsSemicolon2-result.txt b/Tests/RunCMake/add_test/NameContainsSemicolon2-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsSemicolon2-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/add_test/NameContainsSemicolon2-stderr.txt b/Tests/RunCMake/add_test/NameContainsSemicolon2-stderr.txt new file mode 100644 index 0000000..32c2112 --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsSemicolon2-stderr.txt @@ -0,0 +1,2 @@ +Error\(s\) when configuring the project +No tests were found!!! diff --git a/Tests/RunCMake/add_test/NameContainsSemicolon3-stdout.txt b/Tests/RunCMake/add_test/NameContainsSemicolon3-stdout.txt new file mode 100644 index 0000000..c5ab1d8 --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsSemicolon3-stdout.txt @@ -0,0 +1,3 @@ +3/3 Test #3: PrefixTest;SuffixTest \.+\*\*\*Failed.* +CMake Error at .+/CMakeLists.txt:[0-9]+ \(message\): +[ ]*Setting property on test did not succeed! diff --git a/Tests/RunCMake/add_test/NameContainsSemicolon4-result.txt b/Tests/RunCMake/add_test/NameContainsSemicolon4-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsSemicolon4-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/add_test/NameContainsSemicolon4-stderr.txt b/Tests/RunCMake/add_test/NameContainsSemicolon4-stderr.txt new file mode 100644 index 0000000..32c2112 --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsSemicolon4-stderr.txt @@ -0,0 +1,2 @@ +Error\(s\) when configuring the project +No tests were found!!! diff --git a/Tests/RunCMake/add_test/NameContainsSpaces1-stdout.txt b/Tests/RunCMake/add_test/NameContainsSpaces1-stdout.txt new file mode 100644 index 0000000..a255fb1 --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsSpaces1-stdout.txt @@ -0,0 +1 @@ +Test #[0-9]+: PrefixTest SuffixTest \.+[ ]*Passed diff --git a/Tests/RunCMake/add_test/NameContainsSpaces2-result.txt b/Tests/RunCMake/add_test/NameContainsSpaces2-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsSpaces2-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/add_test/NameContainsSpaces2-stderr.txt b/Tests/RunCMake/add_test/NameContainsSpaces2-stderr.txt new file mode 100644 index 0000000..32c2112 --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsSpaces2-stderr.txt @@ -0,0 +1,2 @@ +Error\(s\) when configuring the project +No tests were found!!! diff --git a/Tests/RunCMake/add_test/NameContainsSpaces3-stdout.txt b/Tests/RunCMake/add_test/NameContainsSpaces3-stdout.txt new file mode 100644 index 0000000..3d42b0b --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsSpaces3-stdout.txt @@ -0,0 +1,3 @@ +3/3 Test #3: PrefixTest SuffixTest \.+\*\*\*Failed.* +CMake Error at .+/CMakeLists.txt:[0-9]+ \(message\): +[ ]*Setting property on test did not succeed! diff --git a/Tests/RunCMake/add_test/NameContainsSpaces4-result.txt b/Tests/RunCMake/add_test/NameContainsSpaces4-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsSpaces4-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/add_test/NameContainsSpaces4-stderr.txt b/Tests/RunCMake/add_test/NameContainsSpaces4-stderr.txt new file mode 100644 index 0000000..32c2112 --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsSpaces4-stderr.txt @@ -0,0 +1,2 @@ +Error\(s\) when configuring the project +No tests were found!!! diff --git a/Tests/RunCMake/add_test/NameContainsValidSpecialChars1-stdout.txt b/Tests/RunCMake/add_test/NameContainsValidSpecialChars1-stdout.txt new file mode 100644 index 0000000..ae1a0b1 --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsValidSpecialChars1-stdout.txt @@ -0,0 +1 @@ +Test #[0-9]+: abc_\.\+-012 \.+[ ]*Passed diff --git a/Tests/RunCMake/add_test/NameContainsValidSpecialChars2-stdout.txt b/Tests/RunCMake/add_test/NameContainsValidSpecialChars2-stdout.txt new file mode 100644 index 0000000..ae1a0b1 --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsValidSpecialChars2-stdout.txt @@ -0,0 +1 @@ +Test #[0-9]+: abc_\.\+-012 \.+[ ]*Passed diff --git a/Tests/RunCMake/add_test/NameContainsValidSpecialChars3-stdout.txt b/Tests/RunCMake/add_test/NameContainsValidSpecialChars3-stdout.txt new file mode 100644 index 0000000..ae1a0b1 --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsValidSpecialChars3-stdout.txt @@ -0,0 +1 @@ +Test #[0-9]+: abc_\.\+-012 \.+[ ]*Passed diff --git a/Tests/RunCMake/add_test/NameContainsValidSpecialChars4-stdout.txt b/Tests/RunCMake/add_test/NameContainsValidSpecialChars4-stdout.txt new file mode 100644 index 0000000..ae1a0b1 --- /dev/null +++ b/Tests/RunCMake/add_test/NameContainsValidSpecialChars4-stdout.txt @@ -0,0 +1 @@ +Test #[0-9]+: abc_\.\+-012 \.+[ ]*Passed diff --git a/Tests/RunCMake/add_test/NameIsAlphaNumeric1-stdout.txt b/Tests/RunCMake/add_test/NameIsAlphaNumeric1-stdout.txt new file mode 100644 index 0000000..ed939bf --- /dev/null +++ b/Tests/RunCMake/add_test/NameIsAlphaNumeric1-stdout.txt @@ -0,0 +1 @@ +Test #[0-9]+: abcdefghijklmnopqrstuvwxyz0123456789 \.+[ ]*Passed diff --git a/Tests/RunCMake/add_test/NameIsAlphaNumeric2-stdout.txt b/Tests/RunCMake/add_test/NameIsAlphaNumeric2-stdout.txt new file mode 100644 index 0000000..ed939bf --- /dev/null +++ b/Tests/RunCMake/add_test/NameIsAlphaNumeric2-stdout.txt @@ -0,0 +1 @@ +Test #[0-9]+: abcdefghijklmnopqrstuvwxyz0123456789 \.+[ ]*Passed diff --git a/Tests/RunCMake/add_test/NameIsAlphaNumeric3-stdout.txt b/Tests/RunCMake/add_test/NameIsAlphaNumeric3-stdout.txt new file mode 100644 index 0000000..ed939bf --- /dev/null +++ b/Tests/RunCMake/add_test/NameIsAlphaNumeric3-stdout.txt @@ -0,0 +1 @@ +Test #[0-9]+: abcdefghijklmnopqrstuvwxyz0123456789 \.+[ ]*Passed diff --git a/Tests/RunCMake/add_test/NameIsAlphaNumeric4-stdout.txt b/Tests/RunCMake/add_test/NameIsAlphaNumeric4-stdout.txt new file mode 100644 index 0000000..ed939bf --- /dev/null +++ b/Tests/RunCMake/add_test/NameIsAlphaNumeric4-stdout.txt @@ -0,0 +1 @@ +Test #[0-9]+: abcdefghijklmnopqrstuvwxyz0123456789 \.+[ ]*Passed diff --git a/Tests/RunCMake/add_test/RunCMakeTest.cmake b/Tests/RunCMake/add_test/RunCMakeTest.cmake new file mode 100644 index 0000000..6e9edda --- /dev/null +++ b/Tests/RunCMake/add_test/RunCMakeTest.cmake @@ -0,0 +1,263 @@ +include(RunCTest) + +set(ENV{CTEST_OUTPUT_ON_FAILURE} 1) + +function(run_NameIsAlphaNumeric1_test) + set(CASE_CMAKELISTS_NAME_1 [==[ abcdefghijklmnopqrstuvwxyz0123456789 ]==]) + set(CASE_CMAKELISTS_NAME_2 [==[ abcdefghijklmnopqrstuvwxyz0123456789 ]==]) + run_ctest(NameIsAlphaNumeric1) +endfunction() +run_NameIsAlphaNumeric1_test() + +function(run_NameIsAlphaNumeric2_test) + set(CASE_CMAKELISTS_NAME_1 [==["abcdefghijklmnopqrstuvwxyz0123456789"]==]) + set(CASE_CMAKELISTS_NAME_2 [==["abcdefghijklmnopqrstuvwxyz0123456789"]==]) + run_ctest(NameIsAlphaNumeric2) +endfunction() +run_NameIsAlphaNumeric2_test() + +function(run_NameIsAlphaNumeric3_test) + set(CASE_CMAKELISTS_NAME_1 [==["abcdefghijklmnopqrstuvwxyz0123456789"]==]) + set(CASE_CMAKELISTS_NAME_2 [==[ abcdefghijklmnopqrstuvwxyz0123456789 ]==]) + run_ctest(NameIsAlphaNumeric3) +endfunction() +run_NameIsAlphaNumeric3_test() + +function(run_NameIsAlphaNumeric4_test) + set(CASE_CMAKELISTS_NAME_1 [==[ abcdefghijklmnopqrstuvwxyz0123456789 ]==]) + set(CASE_CMAKELISTS_NAME_2 [==["abcdefghijklmnopqrstuvwxyz0123456789"]==]) + run_ctest(NameIsAlphaNumeric4) +endfunction() +run_NameIsAlphaNumeric4_test() + + +function(run_NameContainsValidSpecialChars1_test) + set(CASE_CMAKELISTS_NAME_1 [==[ abc_.+-012 ]==]) + set(CASE_CMAKELISTS_NAME_2 [==[ abc_.+-012 ]==]) + run_ctest(NameContainsValidSpecialChars1) +endfunction() +run_NameContainsValidSpecialChars1_test() + +function(run_NameContainsValidSpecialChars2_test) + set(CASE_CMAKELISTS_NAME_1 [==["abc_.+-012"]==]) + set(CASE_CMAKELISTS_NAME_2 [==["abc_.+-012"]==]) + run_ctest(NameContainsValidSpecialChars2) +endfunction() +run_NameContainsValidSpecialChars2_test() + +function(run_NameContainsValidSpecialChars3_test) + set(CASE_CMAKELISTS_NAME_1 [==["abc_.+-012"]==]) + set(CASE_CMAKELISTS_NAME_2 [==[ abc_.+-012 ]==]) + run_ctest(NameContainsValidSpecialChars3) +endfunction() +run_NameContainsValidSpecialChars3_test() + +function(run_NameContainsValidSpecialChars4_test) + set(CASE_CMAKELISTS_NAME_1 [==[ abc_.+-012 ]==]) + set(CASE_CMAKELISTS_NAME_2 [==["abc_.+-012"]==]) + run_ctest(NameContainsValidSpecialChars4) +endfunction() +run_NameContainsValidSpecialChars4_test() + + +function(run_NameContainsOtherSpecialChars1_test) + set(CASE_CMAKELISTS_NAME_1 [==[ !§$%&/ü:*😤~ ]==]) + set(CASE_CMAKELISTS_NAME_2 [==[ !§$%&/ü:*😤~ ]==]) + run_ctest(NameContainsOtherSpecialChars1) +endfunction() +run_NameContainsOtherSpecialChars1_test() + +function(run_NameContainsOtherSpecialChars2_test) + set(CASE_CMAKELISTS_NAME_1 [==["!§$%&/ü:*😤~"]==]) + set(CASE_CMAKELISTS_NAME_2 [==["!§$%&/ü:*😤~"]==]) + run_ctest(NameContainsOtherSpecialChars2) +endfunction() +run_NameContainsOtherSpecialChars2_test() + +function(run_NameContainsOtherSpecialChars3_test) + set(CASE_CMAKELISTS_NAME_1 [==["!§$%&/ü:*😤~"]==]) + set(CASE_CMAKELISTS_NAME_2 [==[ !§$%&/ü:*😤~ ]==]) + run_ctest(NameContainsOtherSpecialChars3) +endfunction() +run_NameContainsOtherSpecialChars3_test() + +function(run_NameContainsOtherSpecialChars4_test) + set(CASE_CMAKELISTS_NAME_1 [==[ !§$%&/ü:*😤~ ]==]) + set(CASE_CMAKELISTS_NAME_2 [==["!§$%&/ü:*😤~"]==]) + run_ctest(NameContainsOtherSpecialChars4) +endfunction() +run_NameContainsOtherSpecialChars4_test() + + +function(run_NameContainsEscapedSpecialChars1_test) + set(CASE_CMAKELISTS_NAME_1 [==[ \(\)\ \# ]==]) + set(CASE_CMAKELISTS_NAME_2 [==[ \(\)\ \# ]==]) + run_ctest(NameContainsEscapedSpecialChars1) +endfunction() +run_NameContainsEscapedSpecialChars1_test() + +function(run_NameContainsEscapedSpecialChars2_test) + set(CASE_CMAKELISTS_NAME_1 [==["\(\)\ \#"]==]) + set(CASE_CMAKELISTS_NAME_2 [==["\(\)\ \#"]==]) + run_ctest(NameContainsEscapedSpecialChars2) +endfunction() +run_NameContainsEscapedSpecialChars2_test() + +function(run_NameContainsEscapedSpecialChars3_test) + set(CASE_CMAKELISTS_NAME_1 [==["\(\)\ \#"]==]) + set(CASE_CMAKELISTS_NAME_2 [==[ \(\)\ \# ]==]) + run_ctest(NameContainsEscapedSpecialChars3) +endfunction() +run_NameContainsEscapedSpecialChars3_test() + +function(run_NameContainsEscapedSpecialChars4_test) + set(CASE_CMAKELISTS_NAME_1 [==[ \(\)\ \# ]==]) + set(CASE_CMAKELISTS_NAME_2 [==["\(\)\ \#"]==]) + run_ctest(NameContainsEscapedSpecialChars4) +endfunction() +run_NameContainsEscapedSpecialChars4_test() + + +function(run_NameContainsGeneratorExpressionSyntax1_test) + set(CASE_CMAKELISTS_NAME_1 [==[ $<BOOL:0> ]==]) + set(CASE_CMAKELISTS_NAME_2 [==[ $<BOOL:0> ]==]) + run_ctest(NameContainsGeneratorExpressionSyntax1) +endfunction() +run_NameContainsGeneratorExpressionSyntax1_test() + +function(run_NameContainsGeneratorExpressionSyntax2_test) + set(CASE_CMAKELISTS_NAME_1 [==["$<BOOL:0>"]==]) + set(CASE_CMAKELISTS_NAME_2 [==["$<BOOL:0>"]==]) + run_ctest(NameContainsGeneratorExpressionSyntax2) +endfunction() +run_NameContainsGeneratorExpressionSyntax2_test() + +function(run_NameContainsGeneratorExpressionSyntax3_test) + set(CASE_CMAKELISTS_NAME_1 [==["$<BOOL:0>"]==]) + set(CASE_CMAKELISTS_NAME_2 [==[ $<BOOL:0> ]==]) + run_ctest(NameContainsGeneratorExpressionSyntax3) +endfunction() +run_NameContainsGeneratorExpressionSyntax3_test() + +function(run_NameContainsGeneratorExpressionSyntax4_test) + set(CASE_CMAKELISTS_NAME_1 [==[ $<BOOL:0> ]==]) + set(CASE_CMAKELISTS_NAME_2 [==["$<BOOL:0>"]==]) + run_ctest(NameContainsGeneratorExpressionSyntax4) +endfunction() +run_NameContainsGeneratorExpressionSyntax4_test() + + +function(run_NameContainsSpaces1_test) + set(CASE_CMAKELISTS_NAME_1 [==["PrefixTest SuffixTest"]==]) + set(CASE_CMAKELISTS_NAME_2 [==["PrefixTest SuffixTest"]==]) + run_ctest(NameContainsSpaces1) +endfunction() +run_NameContainsSpaces1_test() + +function(run_NameContainsSpaces2_test) + set(CASE_CMAKELISTS_NAME_1 [==[ PrefixTest SuffixTest ]==]) + set(CASE_CMAKELISTS_NAME_2 [==[ PrefixTest SuffixTest ]==]) + run_ctest(NameContainsSpaces2) +endfunction() +run_NameContainsSpaces2_test() + +function(run_NameContainsSpaces3_test) + set(CASE_CMAKELISTS_NAME_1 [==["PrefixTest SuffixTest"]==]) + set(CASE_CMAKELISTS_NAME_2 [==[ PrefixTest SuffixTest ]==]) + run_ctest(NameContainsSpaces3) +endfunction() +run_NameContainsSpaces3_test() + +function(run_NameContainsSpaces4_test) + set(CASE_CMAKELISTS_NAME_1 [==[ PrefixTest SuffixTest ]==]) + set(CASE_CMAKELISTS_NAME_2 [==["PrefixTest SuffixTest"]==]) + run_ctest(NameContainsSpaces4) +endfunction() +run_NameContainsSpaces4_test() + + +function(run_NameContainsSemicolon1_test) + set(CASE_CMAKELISTS_NAME_1 [==["PrefixTest;SuffixTest"]==]) + set(CASE_CMAKELISTS_NAME_2 [==["PrefixTest;SuffixTest"]==]) + run_ctest(NameContainsSemicolon1) +endfunction() +run_NameContainsSemicolon1_test() + +function(run_NameContainsSemicolon2_test) + set(CASE_CMAKELISTS_NAME_1 [==[ PrefixTest;SuffixTest ]==]) + set(CASE_CMAKELISTS_NAME_2 [==[ PrefixTest;SuffixTest ]==]) + run_ctest(NameContainsSemicolon2) +endfunction() +run_NameContainsSemicolon2_test() + +function(run_NameContainsSemicolon3_test) + set(CASE_CMAKELISTS_NAME_1 [==["PrefixTest;SuffixTest"]==]) + set(CASE_CMAKELISTS_NAME_2 [==[ PrefixTest;SuffixTest ]==]) + run_ctest(NameContainsSemicolon3) +endfunction() +run_NameContainsSemicolon3_test() + +function(run_NameContainsSemicolon4_test) + set(CASE_CMAKELISTS_NAME_1 [==[ PrefixTest;SuffixTest ]==]) + set(CASE_CMAKELISTS_NAME_2 [==["PrefixTest;SuffixTest"]==]) + run_ctest(NameContainsSemicolon4) +endfunction() +run_NameContainsSemicolon4_test() + + +function(run_NameContainsEscapedQuote1_test) + set(CASE_CMAKELISTS_NAME_1 [==["EscapedQuote\"\"SuffixTest"]==]) + set(CASE_CMAKELISTS_NAME_2 [==["EscapedQuote\"\"SuffixTest"]==]) + run_ctest(NameContainsEscapedQuote1) +endfunction() +run_NameContainsEscapedQuote1_test() + +function(run_NameContainsEscapedQuote2_test) + set(CASE_CMAKELISTS_NAME_1 [==[ EscapedQuote\"\"SuffixTest ]==]) + set(CASE_CMAKELISTS_NAME_2 [==[ EscapedQuote\"\"SuffixTest ]==]) + run_ctest(NameContainsEscapedQuote2) +endfunction() +run_NameContainsEscapedQuote2_test() + +function(run_NameContainsEscapedQuote3_test) + set(CASE_CMAKELISTS_NAME_1 [==["EscapedQuote\"\"SuffixTest"]==]) + set(CASE_CMAKELISTS_NAME_2 [==[ EscapedQuote\"\"SuffixTest ]==]) + run_ctest(NameContainsEscapedQuote3) +endfunction() +run_NameContainsEscapedQuote3_test() + +function(run_NameContainsEscapedQuote4_test) + set(CASE_CMAKELISTS_NAME_1 [==[ EscapedQuote\"\"SuffixTest ]==]) + set(CASE_CMAKELISTS_NAME_2 [==["EscapedQuote\"\"SuffixTest"]==]) + run_ctest(NameContainsEscapedQuote4) +endfunction() +run_NameContainsEscapedQuote4_test() + + +function(run_NameContainsBracketArgument1_test) + set(CASE_CMAKELISTS_NAME_1 [==["[=[BracketArgument;SuffixTest]=]"]==]) + set(CASE_CMAKELISTS_NAME_2 [==["[=[BracketArgument;SuffixTest]=]"]==]) + run_ctest(NameContainsBracketArgument1) +endfunction() +run_NameContainsBracketArgument1_test() + +function(run_NameContainsBracketArgument2_test) + set(CASE_CMAKELISTS_NAME_1 [==[ [=[BracketArgument;SuffixTest]=] ]==]) + set(CASE_CMAKELISTS_NAME_2 [==[ [=[BracketArgument;SuffixTest]=] ]==]) + run_ctest(NameContainsBracketArgument2) +endfunction() +run_NameContainsBracketArgument2_test() + +function(run_NameContainsBracketArgument3_test) + set(CASE_CMAKELISTS_NAME_1 [==["[=[BracketArgument;SuffixTest]=]"]==]) + set(CASE_CMAKELISTS_NAME_2 [==[ [=[BracketArgument;SuffixTest]=] ]==]) + run_ctest(NameContainsBracketArgument3) +endfunction() +run_NameContainsBracketArgument3_test() + +function(run_NameContainsBracketArgument4_test) + set(CASE_CMAKELISTS_NAME_1 [==[ [=[BracketArgument;SuffixTest]=] ]==]) + set(CASE_CMAKELISTS_NAME_2 [==["[=[BracketArgument;SuffixTest]=]"]==]) + run_ctest(NameContainsBracketArgument4) +endfunction() +run_NameContainsBracketArgument4_test() diff --git a/Tests/RunCMake/add_test/test.cmake.in b/Tests/RunCMake/add_test/test.cmake.in new file mode 100644 index 0000000..9821c1c --- /dev/null +++ b/Tests/RunCMake/add_test/test.cmake.in @@ -0,0 +1,16 @@ +cmake_minimum_required(VERSION 3.17) + +set(CTEST_SITE "test-site") +set(CTEST_BUILD_NAME "test-build-name") +set(CTEST_SOURCE_DIRECTORY "@RunCMake_BINARY_DIR@/@CASE_NAME@") +set(CTEST_BINARY_DIRECTORY "@RunCMake_BINARY_DIR@/@CASE_NAME@-build") +set(CTEST_CMAKE_GENERATOR "@RunCMake_GENERATOR@") +set(CTEST_CMAKE_GENERATOR_PLATFORM "@RunCMake_GENERATOR_PLATFORM@") +set(CTEST_CMAKE_GENERATOR_TOOLSET "@RunCMake_GENERATOR_TOOLSET@") +set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}") + +set(ctest_test_args "@CASE_CTEST_TEST_ARGS@") +ctest_start(Experimental) +ctest_configure() +#ctest_build() +ctest_test(${ctest_test_args}) diff --git a/Tests/RunCMake/ctest_test/RunCMakeTest.cmake b/Tests/RunCMake/ctest_test/RunCMakeTest.cmake index 34d4020..18ae793 100644 --- a/Tests/RunCMake/ctest_test/RunCMakeTest.cmake +++ b/Tests/RunCMake/ctest_test/RunCMakeTest.cmake @@ -107,3 +107,14 @@ add_test(NAME NotRunTest COMMAND ${CMAKE_COMMAND} -E true) run_ctest_test(stop-on-failure STOP_ON_FAILURE) endfunction() run_stop_on_failure() + +# Make sure environment gets logged +function(run_environment) + set(ENV{BAD_ENVIRONMENT_VARIABLE} "Bad environment variable") + set(CASE_CMAKELISTS_SUFFIX_CODE [[ +set_property(TEST RunCMakeVersion PROPERTY ENVIRONMENT "ENV1=env1;ENV2=env2") + ]]) + + run_ctest(TestEnvironment) +endfunction() +run_environment() diff --git a/Tests/RunCMake/ctest_test/TestEnvironment-check.cmake b/Tests/RunCMake/ctest_test/TestEnvironment-check.cmake new file mode 100644 index 0000000..91c9731 --- /dev/null +++ b/Tests/RunCMake/ctest_test/TestEnvironment-check.cmake @@ -0,0 +1,10 @@ +file(READ "${RunCMake_TEST_BINARY_DIR}/Testing/TAG" _tag) +string(REGEX REPLACE "^([^\n]*)\n.*$" "\\1" _date "${_tag}") +file(READ "${RunCMake_TEST_BINARY_DIR}/Testing/${_date}/Test.xml" _test_contents) + +if(NOT _test_contents MATCHES "<Value>ENV1=env1\nENV2=env2\n#CTEST_RESOURCE_GROUP_COUNT=</Value>") + string(APPEND RunCMake_TEST_FAILED "Could not find expected environment variables in Test.xml") +endif() +if(_test_contents MATCHES "BAD_ENVIRONMENT_VARIABLE") + string(APPEND RunCMake_TEST_FAILED "Found BAD_ENVIRONMENT_VARIABLE in Test.xml") +endif() diff --git a/Tests/RunCMake/get_property/RunCMakeTest.cmake b/Tests/RunCMake/get_property/RunCMakeTest.cmake index 6e36473..c4ee53d 100644 --- a/Tests/RunCMake/get_property/RunCMakeTest.cmake +++ b/Tests/RunCMake/get_property/RunCMakeTest.cmake @@ -5,6 +5,7 @@ run_cmake(directory_properties) run_cmake(global_properties) run_cmake(install_properties) run_cmake(source_properties) +run_cmake(source_properties_failures) run_cmake(target_properties) run_cmake(test_properties) run_cmake(DebugConfigurations) diff --git a/Tests/RunCMake/get_property/source_properties_failures-result.txt b/Tests/RunCMake/get_property/source_properties_failures-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/get_property/source_properties_failures-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/get_property/source_properties_failures-stderr.txt b/Tests/RunCMake/get_property/source_properties_failures-stderr.txt new file mode 100644 index 0000000..a500e2e --- /dev/null +++ b/Tests/RunCMake/get_property/source_properties_failures-stderr.txt @@ -0,0 +1,66 @@ +^CMake Error at source_properties_failures.cmake:1 \(set_source_files_properties\): + set_source_files_properties called with incorrect number of arguments no + value provided to the DIRECTORY option +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\) ++ +CMake Error at source_properties_failures.cmake:2 \(set_source_files_properties\): + set_source_files_properties given non-existent DIRECTORY non_existing_dir +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\) ++ +CMake Error at source_properties_failures.cmake:3 \(set_source_files_properties\): + set_source_files_properties called with incorrect number of arguments no + value provided to the TARGET_DIRECTORY option +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\) ++ +CMake Error at source_properties_failures.cmake:4 \(set_source_files_properties\): + set_source_files_properties given non-existent target for DIRECTORY_TARGET + non_existing_target +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\) ++ +CMake Error at source_properties_failures.cmake:6 \(get_property\): + get_property called with incorrect number of arguments no value provided to + the DIRECTORY option +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\) ++ +CMake Error at source_properties_failures.cmake:7 \(get_property\): + get_property given non-existent DIRECTORY non_existing_dir +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\) ++ +CMake Error at source_properties_failures.cmake:8 \(get_property\): + get_property called with incorrect number of arguments no value provided to + the TARGET_DIRECTORY option +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\) ++ +CMake Error at source_properties_failures.cmake:9 \(get_property\): + get_property given non-existent target for DIRECTORY_TARGET + non_existing_dir +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\) ++ +CMake Error at source_properties_failures.cmake:11 \(get_source_file_property\): + get_source_file_property given non-existent DIRECTORY PROPERTY +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\) ++ +CMake Error at source_properties_failures.cmake:12 \(get_source_file_property\): + get_source_file_property called with incorrect number of arguments +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\) ++ +CMake Error at source_properties_failures.cmake:13 \(get_source_file_property\): + get_source_file_property given non-existent target for DIRECTORY_TARGET + PROPERTY +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\) ++ +CMake Error at source_properties_failures.cmake:14 \(get_source_file_property\): + get_source_file_property called with incorrect number of arguments +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/get_property/source_properties_failures.cmake b/Tests/RunCMake/get_property/source_properties_failures.cmake new file mode 100644 index 0000000..f4b87f9 --- /dev/null +++ b/Tests/RunCMake/get_property/source_properties_failures.cmake @@ -0,0 +1,14 @@ +set_source_files_properties(a.txt DIRECTORY PROPERTIES COMPILE_DEFINITIONS "def") +set_source_files_properties(a.txt DIRECTORY non_existing_dir PROPERTIES COMPILE_DEFINITIONS "def") +set_source_files_properties(a.txt TARGET_DIRECTORY PROPERTIES COMPILE_DEFINITIONS "def") +set_source_files_properties(a.txt TARGET_DIRECTORY non_existing_target PROPERTIES COMPILE_DEFINITIONS "def") + +get_property(in_var SOURCE a.txt DIRECTORY PROPERTY COMPILE_DEFINITIONS) +get_property(in_var SOURCE a.txt DIRECTORY non_existing_dir PROPERTY COMPILE_DEFINITIONS) +get_property(in_var SOURCE a.txt TARGET_DIRECTORY PROPERTY COMPILE_DEFINITIONS) +get_property(in_var SOURCE a.txt TARGET_DIRECTORY non_existing_dir PROPERTY COMPILE_DEFINITIONS) + +get_source_file_property(in_var a.txt DIRECTORY PROPERTY COMPILE_DEFINITIONS) +get_source_file_property(in_var a.txt DIRECTORY non_existing_dir PROPERTY COMPILE_DEFINITIONS) +get_source_file_property(in_var a.txt TARGET_DIRECTORY PROPERTY COMPILE_DEFINITIONS) +get_source_file_property(in_var a.txt TARGET_DIRECTORY non_existing_dir PROPERTY COMPILE_DEFINITIONS) diff --git a/Tests/RunCMake/set_property/RunCMakeTest.cmake b/Tests/RunCMake/set_property/RunCMakeTest.cmake index 8d4614c..692c6b9 100644 --- a/Tests/RunCMake/set_property/RunCMakeTest.cmake +++ b/Tests/RunCMake/set_property/RunCMakeTest.cmake @@ -9,6 +9,7 @@ run_cmake(LINK_OPTIONS) run_cmake(LINK_DIRECTORIES) run_cmake(LINK_LIBRARIES) run_cmake(SOURCES) +run_cmake(SOURCE_FILE) run_cmake(TYPE) run_cmake(USER_PROP) run_cmake(USER_PROP_INHERITED) diff --git a/Tests/RunCMake/set_property/SOURCE_FILE-result.txt b/Tests/RunCMake/set_property/SOURCE_FILE-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/set_property/SOURCE_FILE-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/set_property/SOURCE_FILE-stderr.txt b/Tests/RunCMake/set_property/SOURCE_FILE-stderr.txt new file mode 100644 index 0000000..2e0b238 --- /dev/null +++ b/Tests/RunCMake/set_property/SOURCE_FILE-stderr.txt @@ -0,0 +1,22 @@ +^CMake Error at SOURCE_FILE.cmake:1 \(set_property\): + set_property called with incorrect number of arguments no value provided to + the DIRECTORY option +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\) ++ +CMake Error at SOURCE_FILE.cmake:2 \(set_property\): + set_property given non-existent DIRECTORY non_existing_dir +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\) ++ +CMake Error at SOURCE_FILE.cmake:3 \(set_property\): + set_property called with incorrect number of arguments no value provided to + the TARGET_DIRECTORY option +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\) ++ +CMake Error at SOURCE_FILE.cmake:4 \(set_property\): + set_property given non-existent target for DIRECTORY_TARGET + non_existing_target +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/set_property/SOURCE_FILE.cmake b/Tests/RunCMake/set_property/SOURCE_FILE.cmake new file mode 100644 index 0000000..b1d78bd --- /dev/null +++ b/Tests/RunCMake/set_property/SOURCE_FILE.cmake @@ -0,0 +1,4 @@ +set_property(SOURCE a.txt DIRECTORY PROPERTY COMPILE_DEFINITIONS "def") +set_property(SOURCE a.txt DIRECTORY non_existing_dir PROPERTY COMPILE_DEFINITIONS "def") +set_property(SOURCE a.txt TARGET_DIRECTORY PROPERTY COMPILE_DEFINITIONS "def") +set_property(SOURCE a.txt TARGET_DIRECTORY non_existing_target PROPERTY COMPILE_DEFINITIONS "def") diff --git a/Tests/RunCMake/target_link_options/RunCMakeTest.cmake b/Tests/RunCMake/target_link_options/RunCMakeTest.cmake index b919f48..8ef13f9 100644 --- a/Tests/RunCMake/target_link_options/RunCMakeTest.cmake +++ b/Tests/RunCMake/target_link_options/RunCMakeTest.cmake @@ -50,10 +50,14 @@ if (NOT CMAKE_C_COMPILER_ID STREQUAL "Intel") run_cmake_target(genex_DEVICE_LINK interface LinkOptions_shared_interface --config Release) run_cmake_target(genex_DEVICE_LINK private LinkOptions_private --config Release) if (CMake_TEST_CUDA) - run_cmake_target(genex_DEVICE_LINK CMP0105_UNSET LinkOptions_CMP0105_UNSET --config Release) - run_cmake_target(genex_DEVICE_LINK CMP0105_OLD LinkOptions_CMP0105_OLD --config Release) - run_cmake_target(genex_DEVICE_LINK CMP0105_NEW LinkOptions_CMP0105_NEW --config Release) - run_cmake_target(genex_DEVICE_LINK device LinkOptions_device --config Release) + # Separable compilation is only supported on NVCC. + if(NOT CMake_TEST_CUDA STREQUAL "Clang") + run_cmake_target(genex_DEVICE_LINK CMP0105_UNSET LinkOptions_CMP0105_UNSET --config Release) + run_cmake_target(genex_DEVICE_LINK CMP0105_OLD LinkOptions_CMP0105_OLD --config Release) + run_cmake_target(genex_DEVICE_LINK CMP0105_NEW LinkOptions_CMP0105_NEW --config Release) + run_cmake_target(genex_DEVICE_LINK device LinkOptions_device --config Release) + endif() + run_cmake_target(genex_DEVICE_LINK no_device LinkOptions_no_device --config Release) endif() @@ -416,7 +416,6 @@ CMAKE_CXX_SOURCES="\ cmProcessOutput \ cmProjectCommand \ cmPropertyDefinition \ - cmPropertyDefinitionMap \ cmPropertyMap \ cmReturnCommand \ cmRulePlaceholderExpander \ |