diff options
197 files changed, 3598 insertions, 727 deletions
diff --git a/Auxiliary/vim/syntax/cmake.vim b/Auxiliary/vim/syntax/cmake.vim index a191c18..d7542b5 100644 --- a/Auxiliary/vim/syntax/cmake.vim +++ b/Auxiliary/vim/syntax/cmake.vim @@ -78,7 +78,7 @@ syn keyword cmakeKWbuild_name contained \ CMAKE_CXX_COMPILER syn keyword cmakeKWcmake_host_system_information contained - \ AVAILABLE_PHYSICAL_MEMORY AVAILABLE_VIRTUAL_MEMORY FQDN HOSTNAME NUMBER_OF_LOGICAL_CORES NUMBER_OF_PHYSICAL_CORES QUERY RESULT TOTAL_PHYSICAL_MEMORY TOTAL_VIRTUAL_MEMORY + \ AVAILABLE_PHYSICAL_MEMORY AVAILABLE_VIRTUAL_MEMORY FQDN HOSTNAME NUMBER_OF_LOGICAL_CORES NUMBER_OF_PHYSICAL_CORES QUERY RESULT TOTAL_PHYSICAL_MEMORY TOTAL_VIRTUAL_MEMORY IS_64BIT HAS_FPU HAS_MMX HAS_MMX_PLUS HAS_SSE HAS_SSE2 HAS_SSE_FP HAS_SSE_MMX HAS_AMD_3DNOW HAS_AMD_3DNOW_PLUS HAS_IA64 HAS_SERIAL_NUMBER PROCESSOR_SERIAL_NUMBER PROCESSOR_NAME OS_NAME OS_RELEASE OS_VERSION OS_PLATFORM syn keyword cmakeKWcmake_minimum_required contained \ FATAL_ERROR VERSION @@ -203,6 +203,9 @@ syn keyword cmakeKWinclude_directories contained syn keyword cmakeKWinclude_external_msproject contained \ GUID MAP_IMPORTED_CONFIG_ PLATFORM TYPE WIX +syn keyword cmakeKWinclude_guard contained + \ DIRECTORY GLOBAL + syn keyword cmakeKWinstall contained \ ARCHIVE BUNDLE CODE COMPONENT CONFIGURATIONS CVS DESTDIR DESTINATION DIRECTORY DIRECTORY_PERMISSIONS DLL EXCLUDE_FROM_ALL EXPORT EXPORT_ANDROID_MK EXPORT_LINK_INTERFACE_LIBRARIES FILES FILES_MATCHING FILE_PERMISSIONS FRAMEWORK GROUP_EXECUTE GROUP_READ GROUP_WRITE IMPORTED_ INCLUDES INSTALL_PREFIX INTERFACE_INCLUDE_DIRECTORIES LIBRARY MACOSX_BUNDLE MESSAGE_NEVER NAMELINK_ONLY NAMELINK_SKIP NAMESPACE NDK OBJECTS OPTIONAL OWNER_EXECUTE OWNER_READ OWNER_WRITE PATTERN PERMISSIONS POST_INSTALL_SCRIPT PRE_INSTALL_SCRIPT PRIVATE_HEADER PROGRAMS PUBLIC_HEADER REGEX RENAME RESOURCE RUNTIME SCRIPT SETGID SETUID SOVERSION TARGETS TRUE USE_SOURCE_PERMISSIONS VERSION WORLD_EXECUTE WORLD_READ WORLD_WRITE @@ -327,7 +330,7 @@ syn keyword cmakeGeneratorExpressions contained syn case ignore syn keyword cmakeCommand - \ add_compile_options add_custom_command add_custom_target add_definitions add_dependencies add_executable add_library add_subdirectory add_test aux_source_directory break build_command cmake_host_system_information cmake_minimum_required cmake_parse_arguments cmake_policy configure_file continue create_test_sourcelist ctest_build ctest_configure ctest_coverage ctest_empty_binary_directory ctest_memcheck ctest_read_custom_files ctest_run_script ctest_sleep ctest_start ctest_submit ctest_test ctest_update ctest_upload define_property enable_language enable_testing endfunction endmacro execute_process export file find_file find_library find_package find_path find_program fltk_wrap_ui function get_cmake_property get_directory_property get_filename_component get_property get_source_file_property get_target_property get_test_property include include_directories include_external_msproject include_regular_expression install link_directories list load_cache load_command macro mark_as_advanced math message option project qt_wrap_cpp qt_wrap_ui remove_definitions return separate_arguments set set_directory_properties set_property set_source_files_properties set_target_properties set_tests_properties site_name source_group string target_compile_definitions target_compile_features target_compile_options target_include_directories target_link_libraries target_sources try_compile try_run unset variable_watch + \ add_compile_options add_custom_command add_custom_target add_definitions add_dependencies add_executable add_library add_subdirectory add_test aux_source_directory break build_command cmake_host_system_information cmake_minimum_required cmake_parse_arguments cmake_policy configure_file continue create_test_sourcelist ctest_build ctest_configure ctest_coverage ctest_empty_binary_directory ctest_memcheck ctest_read_custom_files ctest_run_script ctest_sleep ctest_start ctest_submit ctest_test ctest_update ctest_upload define_property enable_language enable_testing endfunction endmacro execute_process export file find_file find_library find_package find_path find_program fltk_wrap_ui function get_cmake_property get_directory_property get_filename_component get_property get_source_file_property get_target_property get_test_property include include_directories include_external_msproject include_guard include_regular_expression install link_directories list load_cache load_command macro mark_as_advanced math message option project qt_wrap_cpp qt_wrap_ui remove_definitions return separate_arguments set set_directory_properties set_property set_source_files_properties set_target_properties set_tests_properties site_name source_group string target_compile_definitions target_compile_features target_compile_options target_include_directories target_link_libraries target_sources try_compile try_run unset variable_watch \ nextgroup=cmakeArguments syn keyword cmakeCommandConditional @@ -420,6 +423,7 @@ hi def link cmakeKWif ModeMsg hi def link cmakeKWinclude ModeMsg hi def link cmakeKWinclude_directories ModeMsg hi def link cmakeKWinclude_external_msproject ModeMsg +hi def link cmakeKWinclude_guard ModeMsg hi def link cmakeKWinstall ModeMsg hi def link cmakeKWinstall_files ModeMsg hi def link cmakeKWinstall_programs ModeMsg diff --git a/CTestCustom.cmake.in b/CTestCustom.cmake.in index fa2fbe3..6a37275 100644 --- a/CTestCustom.cmake.in +++ b/CTestCustom.cmake.in @@ -44,6 +44,7 @@ list(APPEND CTEST_CUSTOM_WARNING_EXCEPTION "Warning: LINN32: Last line.*is less.*" "Warning: Olimit was exceeded on function.*" "Warning: To override Olimit for all functions in file.*" + "WarningMessagesDialog\\.cxx" "warning.*directory name.*CMake-Xcode.*/bin/.*does not exist.*" "stl_deque.h:1051" "(Lexer|Parser).*warning.*conversion.*may (alter its value|change the sign)" diff --git a/Copyright.txt b/Copyright.txt index daaa1d1..b7af4c5 100644 --- a/Copyright.txt +++ b/Copyright.txt @@ -34,6 +34,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The following individuals and institutions are among the Contributors: * Aaron C. Meadows <cmake@shadowguarddev.com> +* Adriaan de Groot <groot@kde.org> * Aleksey Avdeev <solo@altlinux.ru> * Alexander Neundorf <neundorf@kde.org> * Alexander Smorkalov <alexander.smorkalov@itseez.com> diff --git a/Help/command/cmake_host_system_information.rst b/Help/command/cmake_host_system_information.rst index 9402d57..7199874 100644 --- a/Help/command/cmake_host_system_information.rst +++ b/Help/command/cmake_host_system_information.rst @@ -13,13 +13,34 @@ queried. The list of queried values is stored in ``<variable>``. ``<key>`` can be one of the following values: -:: - - NUMBER_OF_LOGICAL_CORES = Number of logical cores. - NUMBER_OF_PHYSICAL_CORES = Number of physical cores. - HOSTNAME = Hostname. - FQDN = Fully qualified domain name. - TOTAL_VIRTUAL_MEMORY = Total virtual memory in megabytes. - AVAILABLE_VIRTUAL_MEMORY = Available virtual memory in megabytes. - TOTAL_PHYSICAL_MEMORY = Total physical memory in megabytes. - AVAILABLE_PHYSICAL_MEMORY = Available physical memory in megabytes. +============================= ================================================ +Key Description +============================= ================================================ +``NUMBER_OF_LOGICAL_CORES`` Number of logical cores +``NUMBER_OF_PHYSICAL_CORES`` Number of physical cores +``HOSTNAME`` Hostname +``FQDN`` Fully qualified domain name +``TOTAL_VIRTUAL_MEMORY`` Total virtual memory in megabytes +``AVAILABLE_VIRTUAL_MEMORY`` Available virtual memory in megabytes +``TOTAL_PHYSICAL_MEMORY`` Total physical memory in megabytes +``AVAILABLE_PHYSICAL_MEMORY`` Available physical memory in megabytes +``IS_64BIT`` One if processor is 64Bit +``HAS_FPU`` One if processor has floating point unit +``HAS_MMX`` One if processor supports MMX instructions +``HAS_MMX_PLUS`` One if porcessor supports Ext. MMX instructions +``HAS_SSE`` One if porcessor supports SSE instructions +``HAS_SSE2`` One if porcessor supports SSE2 instructions +``HAS_SSE_FP`` One if porcessor supports SSE FP instructions +``HAS_SSE_MMX`` One if porcessor supports SSE MMX instructions +``HAS_AMD_3DNOW`` One if porcessor supports 3DNow instructions +``HAS_AMD_3DNOW_PLUS`` One if porcessor supports 3DNow+ instructions +``HAS_IA64`` One if IA64 processor emulating x86 +``HAS_SERIAL_NUMBER`` One if processor has serial number +``PROCESSOR_SERIAL_NUMBER`` Processor serial number +``PROCESSOR_NAME`` Human readable processor name +``PROCESSOR_DESCRIPTION`` Human readable full processor description +``OS_NAME`` See :variable:`CMAKE_HOST_SYSTEM_NAME` +``OS_RELEASE`` The OS sub-type e.g. on Windows ``Professional`` +``OS_VERSION`` The OS build ID +``OS_PLATFORM`` See :variable:`CMAKE_HOST_SYSTEM_PROCESSOR` +============================= ================================================ diff --git a/Help/command/execute_process.rst b/Help/command/execute_process.rst index d617243..799493f 100644 --- a/Help/command/execute_process.rst +++ b/Help/command/execute_process.rst @@ -10,6 +10,7 @@ Execute one or more child processes. [WORKING_DIRECTORY <directory>] [TIMEOUT <seconds>] [RESULT_VARIABLE <variable>] + [RESULTS_VARIABLE <variable>] [OUTPUT_VARIABLE <variable>] [ERROR_VARIABLE <variable>] [INPUT_FILE <file>] @@ -49,10 +50,16 @@ Options: specified number of seconds (fractions are allowed). ``RESULT_VARIABLE`` - The variable will be set to contain the result of running the processes. + The variable will be set to contain the result of last child process. This will be an integer return code from the last child or a string describing an error condition. +``RESULTS_VARIABLE <variable>`` + The variable will be set to contain the result of all processes as a + :ref:`;-list <CMake Language Lists>`, in order of the given ``COMMAND`` + arguments. Each entry will be an integer return code from the + corresponding child or a string describing an error condition. + ``OUTPUT_VARIABLE``, ``ERROR_VARIABLE`` The variable named will be set with the contents of the standard output and standard error pipes, respectively. If the same variable is named diff --git a/Help/command/file.rst b/Help/command/file.rst index b2e4eea..7afb715 100644 --- a/Help/command/file.rst +++ b/Help/command/file.rst @@ -291,6 +291,8 @@ from the input content to produce the output content. The options are: ``INPUT <input-file>`` Use the content from a given file as input. + A relative path is treated with respect to the value of + :variable:`CMAKE_CURRENT_SOURCE_DIR`. See policy :policy:`CMP0070`. ``OUTPUT <output-file>`` Specify the output file name to generate. Use generator expressions @@ -298,6 +300,9 @@ from the input content to produce the output content. The options are: name. Multiple configurations may generate the same output file only if the generated content is identical. Otherwise, the ``<output-file>`` must evaluate to an unique name for each configuration. + A relative path (after evaluating generator expressions) is treated + with respect to the value of :variable:`CMAKE_CURRENT_BINARY_DIR`. + See policy :policy:`CMP0070`. Exactly one ``CONTENT`` or ``INPUT`` option must be given. A specific ``OUTPUT`` file may be named by at most one invocation of ``file(GENERATE)``. diff --git a/Help/command/include_guard.rst b/Help/command/include_guard.rst new file mode 100644 index 0000000..62cce22 --- /dev/null +++ b/Help/command/include_guard.rst @@ -0,0 +1,46 @@ +include_guard +------------- + +Provides an include guard for the file currently being processed by CMake. + +:: + + include_guard([DIRECTORY|GLOBAL]) + +Sets up an include guard for the current CMake file (see the +:variable:`CMAKE_CURRENT_LIST_FILE` variable documentation). + +CMake will end its processing of the current file at the location of the +:command:`include_guard` command if the current file has already been +processed for the applicable scope (see below). This provides functionality +similar to the include guards commonly used in source headers or to the +``#pragma once`` directive. If the current file has been processed previously +for the applicable scope, the effect is as though :command:`return` had been +called. Do not call this command from inside a function being defined within +the current file. + +An optional argument specifying the scope of the guard may be provided. +Possible values for the option are: + +``DIRECTORY`` + The include guard applies within the current directory and below. The file + will only be included once within this directory scope, but may be included + again by other files outside of this directory (i.e. a parent directory or + another directory not pulled in by :command:`add_subdirectory` or + :command:`include` from the current file or its children). + +``GLOBAL`` + The include guard applies globally to the whole build. The current file + will only be included once regardless of the scope. + +If no arguments given, ``include_guard`` has the same scope as a variable, +meaning that the include guard effect is isolated by the most recent +function scope or current directory if no inner function scopes exist. +In this case the command behavior is the same as: + +.. code-block:: cmake + + if(__CURRENT_FILE_VAR__) + return() + endif() + set(__CURRENT_FILE_VAR__ TRUE) diff --git a/Help/dev/maint.rst b/Help/dev/maint.rst index 78c06df..889e4e3 100644 --- a/Help/dev/maint.rst +++ b/Help/dev/maint.rst @@ -8,6 +8,38 @@ See documentation on `CMake Development`_ for more information. .. contents:: Maintainer Processes: +Review a Merge Request +====================== + +The `CMake Review Process`_ requires a maintainer to issue the ``Do: merge`` +command to integrate a merge request. Please check at least the following: + +* If the MR source branch is not named well for the change it makes + (e.g. it is just ``master`` or the patch changed during review), + add a ``Topic-rename: <topic>`` trailing line to the MR description + to provide a better topic name. + +* If the MR introduces a new feature or a user-facing behavior change, + such as a policy, ensure that a ``Help/release/dev/$topic.rst`` file + is added with a release note. + +* If a commit changes a specific area, such as a module, its commit + message should have an ``area:`` prefix on its first line. + +* If a commit fixes a tracked issue, its commit message should have + a trailing line such as ``Fixes: #00000``. + +* Ensure that the MR adds sufficient documentation and test cases. + +* Ensure that the MR has been tested sufficiently. Typically it should + be staged for nightly testing with ``Do: stage``. Then manually + review the `CMake CDash Page`_ to verify that no regressions were + introduced. (Learn to tolerate spurious failures due to idiosyncrasies + of various nightly builders.) + +.. _`CMake Review Process`: review.rst +.. _`CMake CDash Page`: https://open.cdash.org/index.php?project=CMake + Branch a New Release ==================== diff --git a/Help/dev/source.rst b/Help/dev/source.rst index 7e44995..16a9252 100644 --- a/Help/dev/source.rst +++ b/Help/dev/source.rst @@ -58,3 +58,50 @@ need to be handled with care: When assigning the result of ``.size()`` on a container for example, the result should be assigned to ``size_t`` not to ``std::size_t``, ``unsigned int`` or similar types. + +Source Tree Layout +================== + +The CMake source tree is organized as follows. + +* ``Auxiliary/``: + Shell and editor integration files. + +* ``Help/``: + Documentation. + + * ``Help/dev/``: + Developer documentation. + + * ``Help/release/dev/``: + Release note snippets for development since last release. + +* ``Licenses/``: + License files for third-party libraries in binary distributions. + +* ``Modules/``: + CMake language modules installed with CMake. + +* ``Packaging/``: + Files used for packaging CMake itself for distribution. + +* ``Source/``: + Source code of CMake itself. + +* ``Templates/``: + Files distributed with CMake as implementation details for generators, + packagers, etc. + +* ``Tests/``: + The test suite. See `Tests/README.rst`_. + +* ``Utilities/``: + Scripts, third-party source code. + + * ``Utilities/Sphinx/``: + Sphinx configuration to build CMake user documentation. + + * ``Utilities/Release/``: + Scripts used to package CMake itself for distribution on ``cmake.org``. + +.. _`Tests/README.rst`: ../../Tests/README.rst diff --git a/Help/manual/cmake-commands.7.rst b/Help/manual/cmake-commands.7.rst index 611c989..f8bfb32 100644 --- a/Help/manual/cmake-commands.7.rst +++ b/Help/manual/cmake-commands.7.rst @@ -44,6 +44,7 @@ These commands are always available. /command/get_property /command/if /command/include + /command/include_guard /command/list /command/macro /command/mark_as_advanced diff --git a/Help/manual/cmake-modules.7.rst b/Help/manual/cmake-modules.7.rst index 4a03b7a..fa6144c 100644 --- a/Help/manual/cmake-modules.7.rst +++ b/Help/manual/cmake-modules.7.rst @@ -60,6 +60,7 @@ All Modules /module/CPackCygwin /module/CPackDeb /module/CPackDMG + /module/CPackFreeBSD /module/CPackIFW /module/CPackIFWConfigureFile /module/CPackNSIS diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst index 7b85817..eb9af27 100644 --- a/Help/manual/cmake-policies.7.rst +++ b/Help/manual/cmake-policies.7.rst @@ -51,6 +51,14 @@ The :variable:`CMAKE_MINIMUM_REQUIRED_VERSION` variable may also be used to determine whether to report an error on use of deprecated macros or functions. +Policies Introduced by CMake 3.10 +================================= + +.. toctree:: + :maxdepth: 1 + + CMP0070: Define file(GENERATE) behavior for relative paths. </policy/CMP0070> + Policies Introduced by CMake 3.9 ================================ diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index ec25596..94ab70c 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -291,6 +291,7 @@ Properties on Targets /prop_tgt/VS_DEBUGGER_WORKING_DIRECTORY /prop_tgt/VS_DESKTOP_EXTENSIONS_VERSION /prop_tgt/VS_DOTNET_REFERENCE_refname + /prop_tgt/VS_DOTNET_REFERENCEPROP_refname_TAG_tagname /prop_tgt/VS_DOTNET_REFERENCES /prop_tgt/VS_DOTNET_REFERENCES_COPY_LOCAL /prop_tgt/VS_DOTNET_TARGET_FRAMEWORK_VERSION diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 1a2726d..ec8fedf 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -319,6 +319,7 @@ Variables that Control the Build /variable/CMAKE_MODULE_LINKER_FLAGS_CONFIG /variable/CMAKE_MODULE_LINKER_FLAGS_CONFIG_INIT /variable/CMAKE_MODULE_LINKER_FLAGS_INIT + /variable/CMAKE_MSVCIDE_RUN_PATH /variable/CMAKE_NINJA_OUTPUT_PATH_PREFIX /variable/CMAKE_NO_BUILTIN_CHRPATH /variable/CMAKE_NO_SYSTEM_FROM_IMPORTED diff --git a/Help/module/CPackFreeBSD.rst b/Help/module/CPackFreeBSD.rst new file mode 100644 index 0000000..083f0cb --- /dev/null +++ b/Help/module/CPackFreeBSD.rst @@ -0,0 +1 @@ +.. cmake-module:: ../../Modules/CPackFreeBSD.cmake diff --git a/Help/policy/CMP0070.rst b/Help/policy/CMP0070.rst new file mode 100644 index 0000000..0fb3617 --- /dev/null +++ b/Help/policy/CMP0070.rst @@ -0,0 +1,25 @@ +CMP0070 +------- + +Define :command:`file(GENERATE)` behavior for relative paths. + +CMake 3.10 and newer define that relative paths given to ``INPUT`` and +``OUTPUT`` arguments of ``file(GENERATE)`` are interpreted relative to the +current source and binary directories, respectively. CMake 3.9 and lower did +not define any behavior for relative paths but did not diagnose them either +and accidentally treated them relative to the process working directory. +Policy ``CMP0070`` provides compatibility with projects that used the old +undefined behavior. + +This policy affects behavior of relative paths given to ``file(GENERATE)``. +The ``OLD`` behavior for this policy is to treat the paths relative to the +working directory of CMake. The ``NEW`` behavior for this policy is to +interpret relative paths with respect to the current source or binary +directory of the caller. + +This policy was introduced in CMake version 3.10. CMake version +|release| warns when the policy is not set and uses ``OLD`` behavior. +Use the :command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` +explicitly. + +.. include:: DEPRECATED.txt diff --git a/Help/prop_tgt/LANG_COMPILER_LAUNCHER.rst b/Help/prop_tgt/LANG_COMPILER_LAUNCHER.rst index 0fe0b31..28925fc 100644 --- a/Help/prop_tgt/LANG_COMPILER_LAUNCHER.rst +++ b/Help/prop_tgt/LANG_COMPILER_LAUNCHER.rst @@ -1,7 +1,8 @@ <LANG>_COMPILER_LAUNCHER ------------------------ -This property is implemented only when ``<LANG>`` is ``C`` or ``CXX``. +This property is implemented only when ``<LANG>`` is ``C``, ``CXX``, +or ``CUDA``. Specify a :ref:`;-list <CMake Language Lists>` containing a command line for a compiler launching tool. The :ref:`Makefile Generators` and the diff --git a/Help/prop_tgt/VS_DOTNET_REFERENCEPROP_refname_TAG_tagname.rst b/Help/prop_tgt/VS_DOTNET_REFERENCEPROP_refname_TAG_tagname.rst new file mode 100644 index 0000000..ab311ea --- /dev/null +++ b/Help/prop_tgt/VS_DOTNET_REFERENCEPROP_refname_TAG_tagname.rst @@ -0,0 +1,14 @@ +VS_DOTNET_REFERENCEPROP_<refname>_TAG_<tagname> +----------------------------------------------- + +Defines an XML property ``<tagname>`` for a .NET reference +``<refname>``. + +Reference properties can be set for .NET references which are +defined by the target properties :prop_tgt:`VS_DOTNET_REFERENCES`, +:prop_tgt:`VS_DOTNET_REFERENCE_<refname>` +and also for project references to other C# targets which are +established by :command:`target_link_libraries()`. + +This property is only applicable to C# targets and Visual Studio +generators 2010 and later. diff --git a/Help/release/dev/0-sample-topic.rst b/Help/release/dev/0-sample-topic.rst new file mode 100644 index 0000000..e4cc01e --- /dev/null +++ b/Help/release/dev/0-sample-topic.rst @@ -0,0 +1,7 @@ +0-sample-topic +-------------- + +* This is a sample release note for the change in a topic. + Developers should add similar notes for each topic branch + making a noteworthy change. Each document should be named + and titled to match the topic name to avoid merge conflicts. diff --git a/Help/release/dev/VS_DOTNET_REFERENCEPROP_refname_TAG_tagname.rst b/Help/release/dev/VS_DOTNET_REFERENCEPROP_refname_TAG_tagname.rst new file mode 100644 index 0000000..0e258fd --- /dev/null +++ b/Help/release/dev/VS_DOTNET_REFERENCEPROP_refname_TAG_tagname.rst @@ -0,0 +1,6 @@ +vs-dotnet-custom-reference-tags +------------------------------- + +* The :prop_tgt:`VS_DOTNET_REFERENCEPROP_<refname>_TAG_<tagname>` + target property was added to support custom XML tags for reference + assemblies in C# targets. diff --git a/Help/release/dev/cmake_host_system_information-extend.rst b/Help/release/dev/cmake_host_system_information-extend.rst new file mode 100644 index 0000000..d1c882d --- /dev/null +++ b/Help/release/dev/cmake_host_system_information-extend.rst @@ -0,0 +1,6 @@ +cmake_host_system_information-extend +------------------------------------ + +* The :command:`cmake_host_system_information` command learned more keys + to get information about the processor capabilities and the host OS + version. diff --git a/Help/release/dev/cpack-freebsd-pkg.rst b/Help/release/dev/cpack-freebsd-pkg.rst new file mode 100644 index 0000000..1732581 --- /dev/null +++ b/Help/release/dev/cpack-freebsd-pkg.rst @@ -0,0 +1,5 @@ +cpack-freebsd-pkg +----------------- + +* CPack gained a ``FREEBSD`` generator for FreeBSD ``pkg(8)``, configured + by the :module:`CPackFreeBSD` module. diff --git a/Help/release/dev/cuda-compiler-launcher.rst b/Help/release/dev/cuda-compiler-launcher.rst new file mode 100644 index 0000000..f217780 --- /dev/null +++ b/Help/release/dev/cuda-compiler-launcher.rst @@ -0,0 +1,8 @@ +cuda-compiler-launcher +---------------------- + +* The :ref:`Makefile Generators` and the :generator:`Ninja` generator learned + to add compiler launcher tools like ccache along with the compiler for the + ``CUDA`` language (``C`` and ``CXX`` were supported previously). See the + :variable:`CMAKE_<LANG>_COMPILER_LAUNCHER` variable and + :prop_tgt:`<LANG>_COMPILER_LAUNCHER` target property for details. diff --git a/Help/release/dev/deb-on-windows.rst b/Help/release/dev/deb-on-windows.rst new file mode 100644 index 0000000..b307720 --- /dev/null +++ b/Help/release/dev/deb-on-windows.rst @@ -0,0 +1,7 @@ +deb-on-windows +-------------- + +* The CPack ``DEB`` generator, configured by the :module:`CPackDeb` module, + was enabled on Windows. While not fully featured (due to the lack of + external UNIX tools) this will allow building basic cross-platform Debian + packages. diff --git a/Help/release/dev/execute_process-pipeline-results.rst b/Help/release/dev/execute_process-pipeline-results.rst new file mode 100644 index 0000000..9755ef5 --- /dev/null +++ b/Help/release/dev/execute_process-pipeline-results.rst @@ -0,0 +1,6 @@ +execute_process-pipeline-results +-------------------------------- + +* The :command:`execute_process` command gained a ``RESULTS_VARIABLE`` + option to collect a list of results from all children in a pipeline + of processes when multiple ``COMMAND`` arguments are given. diff --git a/Help/release/dev/file-generate-relative-paths.rst b/Help/release/dev/file-generate-relative-paths.rst new file mode 100644 index 0000000..fdeb9e0e --- /dev/null +++ b/Help/release/dev/file-generate-relative-paths.rst @@ -0,0 +1,7 @@ +file-generate-relative-paths +---------------------------- + +* The :command:`file(GENERATE)` command now interprets relative paths + given to its ``OUTPUT`` and ``INPUT`` arguments with respect to the + caller's current binary and source directories, respectively. + See policy :policy:`CMP0070`. diff --git a/Help/release/dev/include-guard.rst b/Help/release/dev/include-guard.rst new file mode 100644 index 0000000..9b0c64c --- /dev/null +++ b/Help/release/dev/include-guard.rst @@ -0,0 +1,8 @@ +include_guard +------------- + +* The :command:`include_guard` command was introduced to allow guarding + CMake scripts from being included more than once. The command supports + ``DIRECTORY`` and ``GLOBAL`` options to adjust the corresponding include guard + scope. If no options given, include guard is similar to basic variable-based + check. diff --git a/Help/release/index.rst b/Help/release/index.rst index 8222d0c..7f481a3 100644 --- a/Help/release/index.rst +++ b/Help/release/index.rst @@ -5,6 +5,8 @@ CMake Release Notes This file should include the adjacent "dev.txt" file in development versions but not in release versions. +.. include:: dev.txt + Releases ======== diff --git a/Help/variable/CMAKE_LANG_COMPILER_LAUNCHER.rst b/Help/variable/CMAKE_LANG_COMPILER_LAUNCHER.rst index 7961f60..f4e2ba5 100644 --- a/Help/variable/CMAKE_LANG_COMPILER_LAUNCHER.rst +++ b/Help/variable/CMAKE_LANG_COMPILER_LAUNCHER.rst @@ -3,4 +3,4 @@ CMAKE_<LANG>_COMPILER_LAUNCHER Default value for :prop_tgt:`<LANG>_COMPILER_LAUNCHER` target property. This variable is used to initialize the property on each target as it is -created. This is done only when ``<LANG>`` is ``C`` or ``CXX``. +created. This is done only when ``<LANG>`` is ``C``, ``CXX``, or ``CUDA``. diff --git a/Help/variable/CMAKE_MSVCIDE_RUN_PATH.rst b/Help/variable/CMAKE_MSVCIDE_RUN_PATH.rst new file mode 100644 index 0000000..22e727f --- /dev/null +++ b/Help/variable/CMAKE_MSVCIDE_RUN_PATH.rst @@ -0,0 +1,10 @@ +CMAKE_MSVCIDE_RUN_PATH +---------------------- + +Extra PATH locations that should be used when executing +:command:`add_custom_command` or :command:`add_custom_target` when using the +:generator:`Visual Studio 9 2008` (or above) generator. This allows +for running commands and using dll's that the IDE environment is not aware of. + +If not set explicitly the value is initialized by the ``CMAKE_MSVCIDE_RUN_PATH`` +environment variable, if set, and otherwise left empty. diff --git a/Modules/CMakeCSharpInformation.cmake b/Modules/CMakeCSharpInformation.cmake index cd86016..d474c29 100644 --- a/Modules/CMakeCSharpInformation.cmake +++ b/Modules/CMakeCSharpInformation.cmake @@ -10,7 +10,7 @@ get_filename_component(CMAKE_BASE_NAME "${CMAKE_CSharp_COMPILER}" NAME_WE) set(CMAKE_BUILD_TYPE_INIT Debug) -set(CMAKE_CSharp_FLAGS_INIT "/define:TRACE /langversion:3 /nowin32manifest") +set(CMAKE_CSharp_FLAGS_INIT "/define:TRACE /langversion:3") set(CMAKE_CSharp_FLAGS_DEBUG_INIT "/debug:full /optimize- /warn:3 /errorreport:prompt /define:DEBUG") set(CMAKE_CSharp_FLAGS_RELEASE_INIT "/debug:none /optimize /warn:1 /errorreport:queue") set(CMAKE_CSharp_FLAGS_RELWITHDEBINFO_INIT "/debug:full /optimize-") diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake index a63fc83..3915943 100644 --- a/Modules/CPack.cmake +++ b/Modules/CPack.cmake @@ -471,6 +471,7 @@ if(NOT CPACK_GENERATOR) option(CPACK_BINARY_TZ "Enable to build TZ packages" ON) endif() option(CPACK_BINARY_DEB "Enable to build Debian packages" OFF) + option(CPACK_BINARY_FREEBSD "Enable to build FreeBSD packages" OFF) option(CPACK_BINARY_NSIS "Enable to build NSIS packages" OFF) option(CPACK_BINARY_RPM "Enable to build RPM packages" OFF) option(CPACK_BINARY_STGZ "Enable to build STGZ packages" ON) @@ -491,6 +492,7 @@ if(NOT CPACK_GENERATOR) cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_CYGWIN CygwinBinary) cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_DEB DEB) cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_DRAGNDROP DragNDrop) + cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_FREEBSD FREEBSD) cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_IFW IFW) cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_NSIS NSIS) cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_OSXX11 OSXX11) @@ -542,6 +544,7 @@ mark_as_advanced( CPACK_BINARY_CYGWIN CPACK_BINARY_DEB CPACK_BINARY_DRAGNDROP + CPACK_BINARY_FREEBSD CPACK_BINARY_IFW CPACK_BINARY_NSIS CPACK_BINARY_OSXX11 diff --git a/Modules/CPackDeb.cmake b/Modules/CPackDeb.cmake index ddf8b23..daba7d5 100644 --- a/Modules/CPackDeb.cmake +++ b/Modules/CPackDeb.cmake @@ -497,6 +497,16 @@ # # This value is not interpreted. It is possible to pass an optional # revision number of the referenced source package as well. +# +# Building Debian packages on Windows +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +# +# To communicate UNIX file permissions from the install stage +# to the CPack DEB generator the "cmake_mode_t" NTFS +# alternate data stream (ADT) is used. +# +# When a filesystem without ADT support is used only owner read/write +# permissions can be preserved. # CPack script for creating Debian package # Author: Mathieu Malaterre @@ -507,10 +517,6 @@ if(CMAKE_BINARY_DIR) message(FATAL_ERROR "CPackDeb.cmake may only be used by CPack internally.") endif() -if(NOT UNIX) - message(FATAL_ERROR "CPackDeb.cmake may only be used under UNIX.") -endif() - function(cpack_deb_variable_fallback OUTPUT_VAR_NAME) set(FALLBACK_VAR_NAMES ${ARGN}) diff --git a/Modules/CPackFreeBSD.cmake b/Modules/CPackFreeBSD.cmake new file mode 100644 index 0000000..7fec78a --- /dev/null +++ b/Modules/CPackFreeBSD.cmake @@ -0,0 +1,246 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +CPackFreeBSD +------------ + +The built in (binary) CPack FreeBSD (pkg) generator (Unix only) + +Variables specific to CPack FreeBSD (pkg) generator +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +CPackFreeBSD may be used to create pkg(8) packages -- these may be used +on FreeBSD, DragonflyBSD, NetBSD, OpenBSD, but also on Linux or OSX, +depending on the installed package-management tools -- using :module:`CPack`. + +CPackFreeBSD is a :module:`CPack` generator and uses the ``CPACK_XXX`` +variables used by :module:`CPack`. It tries to re-use packaging information +that may already be specified for Debian packages for the :module:`CPackDeb` +generator. it also tries to re-use RPM packaging information when Debian +does not specify. + +CPackFreeBSD generator should work on any host with libpkg installed. The +packages it produces are specific to the host architecture and ABI. + +CPackFreeBSD sets package-metadata through :code:`CPACK_FREEBSD_XXX` variables. +CPackFreeBSD, unlike CPackDeb, does not specially support componentized +packages; a single package is created from all the software artifacts +created through CMake. + +All of the variables can be set specifically for FreeBSD packaging in +the CPackConfig file or in CMakeLists.txt, but most of them have defaults +that use general settings (e.g. CMAKE_PROJECT_NAME) or Debian-specific +variables when those make sense (e.g. the homepage of an upstream project +is usually unchanged by the flavor of packaging). When there is no Debian +information to fall back on, but the RPM packaging has it, fall back to +the RPM information (e.g. package license). + +.. variable:: CPACK_FREEBSD_PACKAGE_NAME + + Sets the package name (in the package manifest, but also affects the + output filename). + + * Mandatory: YES + * Default: + + - :variable:`CPACK_PACKAGE_NAME` (this is always set by CPack itself, + based on CMAKE_PROJECT_NAME). + +.. variable:: CPACK_FREEBSD_PACKAGE_COMMENT + + Sets the package comment. This is the short description displayed by + pkg(8) in standard "pkg info" output. + + * Mandatory: YES + * Default: + + - :variable:`CPACK_PACKAGE_DESCRIPTION_SUMMARY` (this is always set + by CPack itself, if nothing else sets it explicitly). + - :variable:`PROJECT_DESCRIPTION` (this can be set with the DESCRIPTION + parameter for :command:`project`). + +.. variable:: CPACK_FREEBSD_PACKAGE_DESCRIPTION + + Sets the package description. This is the long description of the package, + given by "pkg info" with a specific package as argument. + + * Mandatory: YES + * Default: + + - :variable:`CPACK_DEBIAN_PACKAGE_DESCRIPTION` (this may be set already + for Debian packaging, so we may as well re-use it). + +.. variable:: CPACK_FREEBSD_PACKAGE_WWW + + The URL of the web site for this package, preferably (when applicable) the + site from which the original source can be obtained and any additional + upstream documentation or information may be found. + + * Mandatory: YES + * Default: + + - :variable:`CPACK_DEBIAN_PACKAGE_HOMEPAGE` (this may be set already + for Debian packaging, so we may as well re-use it). + +.. variable:: CPACK_FREEBSD_PACKAGE_LICENSE + + The license, or licenses, which apply to this software package. This must + be one or more license-identifiers that pkg recognizes as acceptable license + identifiers (e.g. "GPLv2"). + + * Mandatory: YES + * Default: + + - :variable:`CPACK_RPM_PACKAGE_LICENSE` + +.. variable:: CPACK_FREEBSD_PACKAGE_LICENSE_LOGIC + + This variable is only of importance if there is more than one license. + The default is "single", which is only applicable to a single license. + Other acceptable values are determined by pkg -- those are "dual" or "multi" -- + meaning choice (OR) or simultaneous (AND) application of the licenses. + + * Mandatory: NO + * Default: single + +.. variable:: CPACK_FREEBSD_PACKAGE_MAINTAINER + + The FreeBSD maintainer (e.g. kde@freebsd.org) of this package. + + * Mandatory: YES + * Default: none + +.. variable:: CPACK_FREEBSD_PACKAGE_ORIGIN + + The origin (ports label) of this package; for packages built by CPack + outside of the ports system this is of less importance. The default + puts the package somewhere under misc/, as a stopgap. + + * Mandatory: YES + * Default: misc/<package name> + +.. variable:: CPACK_FREEBSD_PACKAGE_CATEGORIES + + The ports categories where this package lives (if it were to be built + from ports). If none is set a single category is determined based on + the package origin. + + * Mandatory: YES + * Default: derived from ORIGIN + +.. variable:: CPACK_FREEBSD_PACKAGE_DEPS + + A list of package origins that should be added as package dependencies. + These are in the form <category>/<packagename>, e.g. x11/libkonq. + No version information needs to be provided (this is not included + in the manifest). + + * Mandatory: NO + * Default: empty +#]=======================================================================] + + + +if(CMAKE_BINARY_DIR) + message(FATAL_ERROR "CPackFreeBSD.cmake may only be used by CPack internally.") +endif() + +if(NOT UNIX) + message(FATAL_ERROR "CPackFreeBSD.cmake may only be used under UNIX.") +endif() + + +### +# +# These bits are copied from the Debian packaging file; slightly modified. +# They are used for filling in FreeBSD-packaging variables that can take +# on values from elsewhere -- e.g. the package description may as well be +# copied from Debian. +# +function(_cpack_freebsd_fallback_var OUTPUT_VAR_NAME) + set(FALLBACK_VAR_NAMES ${ARGN}) + + set(VALUE "${${OUTPUT_VAR_NAME}}") + if(VALUE) + return() + endif() + + foreach(variable_name IN LISTS FALLBACK_VAR_NAMES) + if(${variable_name}) + set(${OUTPUT_VAR_NAME} "${${variable_name}}" PARENT_SCOPE) + set(VALUE "${${variable_name}}") + break() + endif() + endforeach() + if(NOT VALUE) + message(WARNING "Variable ${OUTPUT_VAR_NAME} could not be given a fallback value from any variable ${FALLBACK_VAR_NAMES}.") + endif() +endfunction() + +function(check_required_var VAR_NAME) + if(NOT ${VAR_NAME}) + message(FATAL_ERROR "Variable ${VAR_NAME} is not set.") + endif() +endfunction() + +set(_cpack_freebsd_fallback_origin "misc/bogus") + +_cpack_freebsd_fallback_var("CPACK_FREEBSD_PACKAGE_NAME" + "CPACK_PACKAGE_NAME" + "CMAKE_PROJECT_NAME" + ) + +set(_cpack_freebsd_fallback_www "http://example.com/?pkg=${CPACK_FREEBSD_PACKAGE_NAME}") + +_cpack_freebsd_fallback_var("CPACK_FREEBSD_PACKAGE_COMMENT" + "CPACK_PACKAGE_DESCRIPTION_SUMMARY" + ) + +# TODO: maybe read the PACKAGE_DESCRIPTION file for the longer +# FreeBSD pkg-descr? +_cpack_freebsd_fallback_var("CPACK_FREEBSD_PACKAGE_DESCRIPTION" + "CPACK_DEBIAN_PACKAGE_DESCRIPTION" + "CPACK_PACKAGE_DESCRIPTION_SUMMARY" + "PACKAGE_DESCRIPTION" + ) + +# There's really only one homepage for a project, so +# re-use the Debian setting if it's there. +_cpack_freebsd_fallback_var("CPACK_FREEBSD_PACKAGE_WWW" + "CPACK_DEBIAN_PACKAGE_HOMEPAGE" + "_cpack_freebsd_fallback_www" + ) + +_cpack_freebsd_fallback_var("CPACK_FREEBSD_PACKAGE_VERSION" + "CMAKE_PROJECT_VERSION" + "${CMAKE_PROJECT_NAME}_VERSION" + "PROJECT_VERSION" + "CPACK_PACKAGE_VERSION" + "CPACK_PACKAGE_VERSION" + ) + +_cpack_freebsd_fallback_var("CPACK_FREEBSD_PACKAGE_MAINTAINER" + "CPACK_PACKAGE_CONTACT" + ) + +_cpack_freebsd_fallback_var("CPACK_FREEBSD_PACKAGE_LICENSE" + "CPACK_RPM_PACKAGE_LICENSE" + ) + +_cpack_freebsd_fallback_var("CPACK_FREEBSD_PACKAGE_ORIGIN" + "_cpack_freebsd_fallback_origin" + ) + +if(NOT CPACK_FREEBSD_PACKAGE_CATEGORIES) + string(REGEX REPLACE "/.*" "" CPACK_FREEBSD_PACKAGE_CATEGORIES ${CPACK_FREEBSD_PACKAGE_ORIGIN}) +endif() + +check_required_var("CPACK_FREEBSD_PACKAGE_NAME") +check_required_var("CPACK_FREEBSD_PACKAGE_ORIGIN") +check_required_var("CPACK_FREEBSD_PACKAGE_VERSION") +check_required_var("CPACK_FREEBSD_PACKAGE_MAINTAINER") +check_required_var("CPACK_FREEBSD_PACKAGE_COMMENT") +check_required_var("CPACK_FREEBSD_PACKAGE_DESCRIPTION") +check_required_var("CPACK_FREEBSD_PACKAGE_WWW") +check_required_var("CPACK_FREEBSD_PACKAGE_LICENSE") diff --git a/Modules/CheckCCompilerFlag.cmake b/Modules/CheckCCompilerFlag.cmake index 1ba67fc..5a7298b 100644 --- a/Modules/CheckCCompilerFlag.cmake +++ b/Modules/CheckCCompilerFlag.cmake @@ -1,26 +1,36 @@ # Distributed under the OSI-approved BSD 3-Clause License. See accompanying # file Copyright.txt or https://cmake.org/licensing for details. -#.rst: -# CheckCCompilerFlag -# ------------------ -# -# Check whether the C compiler supports a given flag. -# -# CHECK_C_COMPILER_FLAG(<flag> <var>) -# -# :: -# -# <flag> - the compiler flag -# <var> - variable to store the result -# Will be created as an internal cache variable. -# -# This internally calls the check_c_source_compiles macro and sets -# CMAKE_REQUIRED_DEFINITIONS to <flag>. See help for -# CheckCSourceCompiles for a listing of variables that can otherwise -# modify the build. The result only tells that the compiler does not -# give an error message when it encounters the flag. If the flag has -# any effect or even a specific one is beyond the scope of this module. +#[=======================================================================[.rst: +CheckCCompilerFlag +------------------ + +Check whether the C compiler supports a given flag. + +.. command:: check_c_compiler_flag + + :: + + check_c_compiler_flag(<flag> <var>) + + Check that the ``<flag>`` is accepted by the compiler without + a diagnostic. Stores the result in an internal cache entry + named ``<var>``. + +This command temporarily sets the ``CMAKE_REQUIRED_DEFINITIONS`` variable +and calls the ``check_c_source_compiles`` macro from the +:module:`CheckCSourceCompiles` module. See documentation of that +module for a listing of variables that can otherwise modify the build. + +A positive result from this check indicates only that the compiler did not +issue a diagnostic message when given the flag. Whether the flag has any +effect or even a specific one is beyond the scope of this module. + +.. note:: + Since the :command:`try_compile` command forwards flags from variables + like :variable:`CMAKE_C_FLAGS <CMAKE_<LANG>_FLAGS>`, unknown flags + in such variables may cause a false negative for this check. +#]=======================================================================] include(CheckCSourceCompiles) include(CMakeCheckCompilerFlagCommonPatterns) diff --git a/Modules/CheckCSourceCompiles.cmake b/Modules/CheckCSourceCompiles.cmake index ac2c6c5..56e68d5 100644 --- a/Modules/CheckCSourceCompiles.cmake +++ b/Modules/CheckCSourceCompiles.cmake @@ -1,31 +1,65 @@ # Distributed under the OSI-approved BSD 3-Clause License. See accompanying # file Copyright.txt or https://cmake.org/licensing for details. -#.rst: -# CheckCSourceCompiles -# -------------------- -# -# Check if given C source compiles and links into an executable -# -# CHECK_C_SOURCE_COMPILES(<code> <var> [FAIL_REGEX <fail-regex>]) -# -# :: -# -# <code> - source code to try to compile, must define 'main' -# <var> - variable to store whether the source code compiled -# Will be created as an internal cache variable. -# <fail-regex> - fail if test output matches this regex -# -# The following variables may be set before calling this macro to modify -# the way the check is run: -# -# :: -# -# CMAKE_REQUIRED_FLAGS = string of compile command line flags -# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar) -# CMAKE_REQUIRED_INCLUDES = list of include directories -# CMAKE_REQUIRED_LIBRARIES = list of libraries to link -# CMAKE_REQUIRED_QUIET = execute quietly without messages +#[=======================================================================[.rst: +CheckCSourceCompiles +-------------------- + +Check if given C source compiles and links into an executable. + +.. command:: check_c_source_compiles + + :: + + check_c_source_compiles(code resultVar [FAIL_REGEX regex1 [regex2...]]) + + Check that the source supplied in ``code`` can be compiled as a C source + file and linked as an executable (so it must contain at least a ``main()`` + function). The result will be stored in the internal cache variable specified + by ``resultVar``, with a boolean true value for success and boolean false for + failure. If ``FAIL_REGEX`` is provided, then failure is determined by + checking if anything in the output matches any of the specified regular + expressions. + + The underlying check is performed by the :command:`try_compile` command. The + compile and link commands can be influenced by setting any of the following + variables prior to calling ``check_c_source_compiles()``: + + ``CMAKE_REQUIRED_FLAGS`` + Additional flags to pass to the compiler. Note that the contents of + :variable:`CMAKE_C_FLAGS <CMAKE_<LANG>_FLAGS>` and its associated + configuration-specific variable are automatically added to the compiler + command before the contents of ``CMAKE_REQUIRED_FLAGS``. + + ``CMAKE_REQUIRED_DEFINITIONS`` + A :ref:`;-list <CMake Language Lists>` of compiler definitions of the form + ``-DFOO`` or ``-DFOO=bar``. A definition for the name specified by + ``resultVar`` will also be added automatically. + + ``CMAKE_REQUIRED_INCLUDES`` + A :ref:`;-list <CMake Language Lists>` of header search paths to pass to + the compiler. These will be the only header search paths used by + ``try_compile()``, i.e. the contents of the :prop_dir:`INCLUDE_DIRECTORIES` + directory property will be ignored. + + ``CMAKE_REQUIRED_LIBRARIES`` + A :ref:`;-list <CMake Language Lists>` of libraries to add to the link + command. These can be the name of system libraries or they can be + :ref:`Imported Targets <Imported Targets>` (see :command:`try_compile` for + further details). + + ``CMAKE_REQUIRED_QUIET`` + If this variable evaluates to a boolean true value, all status messages + associated with the check will be suppressed. + + The check is only performed once, with the result cached in the variable + named by ``resultVar``. Every subsequent CMake run will re-use this cached + value rather than performing the check again, even if the ``code`` changes. + In order to force the check to be re-evaluated, the variable named by + ``resultVar`` must be manually removed from the cache. + +#]=======================================================================] + macro(CHECK_C_SOURCE_COMPILES SOURCE VAR) if(NOT DEFINED "${VAR}") diff --git a/Modules/CheckCSourceRuns.cmake b/Modules/CheckCSourceRuns.cmake index 70aa9fd..8da9f1e 100644 --- a/Modules/CheckCSourceRuns.cmake +++ b/Modules/CheckCSourceRuns.cmake @@ -1,31 +1,64 @@ # Distributed under the OSI-approved BSD 3-Clause License. See accompanying # file Copyright.txt or https://cmake.org/licensing for details. -#.rst: -# CheckCSourceRuns -# ---------------- -# -# Check if the given C source code compiles and runs. -# -# CHECK_C_SOURCE_RUNS(<code> <var>) -# -# :: -# -# <code> - source code to try to compile -# <var> - variable to store the result -# (1 for success, empty for failure) -# Will be created as an internal cache variable. -# -# The following variables may be set before calling this macro to modify -# the way the check is run: -# -# :: -# -# CMAKE_REQUIRED_FLAGS = string of compile command line flags -# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar) -# CMAKE_REQUIRED_INCLUDES = list of include directories -# CMAKE_REQUIRED_LIBRARIES = list of libraries to link -# CMAKE_REQUIRED_QUIET = execute quietly without messages +#[=======================================================================[.rst: +CheckCSourceRuns +---------------- + +Check if given C source compiles and links into an executable and can +subsequently be run. + +.. command:: check_c_source_runs + + :: + + check_c_source_runs(code resultVar) + + Check that the source supplied in ``code`` can be compiled as a C source + file, linked as an executable and then run. The ``code`` must contain at + least a ``main()`` function. If the code could be built and run successfully, + the internal cache variable specified by ``resultVar`` will be set to 1, + otherwise it will be set to an value that evaluates to boolean false (e.g. + an empty string or an error message). + + The underlying check is performed by the :command:`try_run` command. The + compile and link commands can be influenced by setting any of the following + variables prior to calling ``check_c_source_runs()``: + + ``CMAKE_REQUIRED_FLAGS`` + Additional flags to pass to the compiler. Note that the contents of + :variable:`CMAKE_C_FLAGS <CMAKE_<LANG>_FLAGS>` and its associated + configuration-specific variable are automatically added to the compiler + command before the contents of ``CMAKE_REQUIRED_FLAGS``. + + ``CMAKE_REQUIRED_DEFINITIONS`` + A :ref:`;-list <CMake Language Lists>` of compiler definitions of the form + ``-DFOO`` or ``-DFOO=bar``. A definition for the name specified by + ``resultVar`` will also be added automatically. + + ``CMAKE_REQUIRED_INCLUDES`` + A :ref:`;-list <CMake Language Lists>` of header search paths to pass to + the compiler. These will be the only header search paths used by + ``try_run()``, i.e. the contents of the :prop_dir:`INCLUDE_DIRECTORIES` + directory property will be ignored. + + ``CMAKE_REQUIRED_LIBRARIES`` + A :ref:`;-list <CMake Language Lists>` of libraries to add to the link + command. These can be the name of system libraries or they can be + :ref:`Imported Targets <Imported Targets>` (see :command:`try_run` for + further details). + + ``CMAKE_REQUIRED_QUIET`` + If this variable evaluates to a boolean true value, all status messages + associated with the check will be suppressed. + + The check is only performed once, with the result cached in the variable + named by ``resultVar``. Every subsequent CMake run will re-use this cached + value rather than performing the check again, even if the ``code`` changes. + In order to force the check to be re-evaluated, the variable named by + ``resultVar`` must be manually removed from the cache. + +#]=======================================================================] macro(CHECK_C_SOURCE_RUNS SOURCE VAR) if(NOT DEFINED "${VAR}") diff --git a/Modules/CheckCXXCompilerFlag.cmake b/Modules/CheckCXXCompilerFlag.cmake index afbb231..f731b70 100644 --- a/Modules/CheckCXXCompilerFlag.cmake +++ b/Modules/CheckCXXCompilerFlag.cmake @@ -1,25 +1,36 @@ # Distributed under the OSI-approved BSD 3-Clause License. See accompanying # file Copyright.txt or https://cmake.org/licensing for details. -#.rst: -# CheckCXXCompilerFlag -# -------------------- -# -# Check whether the CXX compiler supports a given flag. -# -# CHECK_CXX_COMPILER_FLAG(<flag> <var>) -# -# :: -# -# <flag> - the compiler flag -# <var> - variable to store the result -# -# This internally calls the check_cxx_source_compiles macro and sets -# CMAKE_REQUIRED_DEFINITIONS to <flag>. See help for -# CheckCXXSourceCompiles for a listing of variables that can otherwise -# modify the build. The result only tells that the compiler does not -# give an error message when it encounters the flag. If the flag has -# any effect or even a specific one is beyond the scope of this module. +#[=======================================================================[.rst: +CheckCXXCompilerFlag +------------------------ + +Check whether the CXX compiler supports a given flag. + +.. command:: check_cxx_compiler_flag + + :: + + check_cxx_compiler_flag(<flag> <var>) + + Check that the ``<flag>`` is accepted by the compiler without + a diagnostic. Stores the result in an internal cache entry + named ``<var>``. + +This command temporarily sets the ``CMAKE_REQUIRED_DEFINITIONS`` variable +and calls the ``check_cxx_source_compiles`` macro from the +:module:`CheckCXXSourceCompiles` module. See documentation of that +module for a listing of variables that can otherwise modify the build. + +A positive result from this check indicates only that the compiler did not +issue a diagnostic message when given the flag. Whether the flag has any +effect or even a specific one is beyond the scope of this module. + +.. note:: + Since the :command:`try_compile` command forwards flags from variables + like :variable:`CMAKE_CXX_FLAGS <CMAKE_<LANG>_FLAGS>`, unknown flags + in such variables may cause a false negative for this check. +#]=======================================================================] include(CheckCXXSourceCompiles) include(CMakeCheckCompilerFlagCommonPatterns) diff --git a/Modules/CheckCXXSourceCompiles.cmake b/Modules/CheckCXXSourceCompiles.cmake index e54d09e..4634a7b 100644 --- a/Modules/CheckCXXSourceCompiles.cmake +++ b/Modules/CheckCXXSourceCompiles.cmake @@ -1,31 +1,64 @@ # Distributed under the OSI-approved BSD 3-Clause License. See accompanying # file Copyright.txt or https://cmake.org/licensing for details. -#.rst: -# CheckCXXSourceCompiles -# ---------------------- -# -# Check if given C++ source compiles and links into an executable -# -# CHECK_CXX_SOURCE_COMPILES(<code> <var> [FAIL_REGEX <fail-regex>]) -# -# :: -# -# <code> - source code to try to compile, must define 'main' -# <var> - variable to store whether the source code compiled -# Will be created as an internal cache variable. -# <fail-regex> - fail if test output matches this regex -# -# The following variables may be set before calling this macro to modify -# the way the check is run: -# -# :: -# -# CMAKE_REQUIRED_FLAGS = string of compile command line flags -# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar) -# CMAKE_REQUIRED_INCLUDES = list of include directories -# CMAKE_REQUIRED_LIBRARIES = list of libraries to link -# CMAKE_REQUIRED_QUIET = execute quietly without messages +#[=======================================================================[.rst: +CheckCXXSourceCompiles +---------------------- + +Check if given C++ source compiles and links into an executable. + +.. command:: check_cxx_source_compiles + + :: + + check_cxx_source_compiles(code resultVar [FAIL_REGEX regex1 [regex2...]]) + + Check that the source supplied in ``code`` can be compiled as a C++ source + file and linked as an executable (so it must contain at least a ``main()`` + function). The result will be stored in the internal cache variable specified + by ``resultVar``, with a boolean true value for success and boolean false for + failure. If ``FAIL_REGEX`` is provided, then failure is determined by + checking if anything in the output matches any of the specified regular + expressions. + + The underlying check is performed by the :command:`try_compile` command. The + compile and link commands can be influenced by setting any of the following + variables prior to calling ``check_cxx_source_compiles()``: + + ``CMAKE_REQUIRED_FLAGS`` + Additional flags to pass to the compiler. Note that the contents of + :variable:`CMAKE_CXX_FLAGS <CMAKE_<LANG>_FLAGS>` and its associated + configuration-specific variable are automatically added to the compiler + command before the contents of ``CMAKE_REQUIRED_FLAGS``. + + ``CMAKE_REQUIRED_DEFINITIONS`` + A :ref:`;-list <CMake Language Lists>` of compiler definitions of the form + ``-DFOO`` or ``-DFOO=bar``. A definition for the name specified by + ``resultVar`` will also be added automatically. + + ``CMAKE_REQUIRED_INCLUDES`` + A :ref:`;-list <CMake Language Lists>` of header search paths to pass to + the compiler. These will be the only header search paths used by + ``try_compile()``, i.e. the contents of the :prop_dir:`INCLUDE_DIRECTORIES` + directory property will be ignored. + + ``CMAKE_REQUIRED_LIBRARIES`` + A :ref:`;-list <CMake Language Lists>` of libraries to add to the link + command. These can be the name of system libraries or they can be + :ref:`Imported Targets <Imported Targets>` (see :command:`try_compile` for + further details). + + ``CMAKE_REQUIRED_QUIET`` + If this variable evaluates to a boolean true value, all status messages + associated with the check will be suppressed. + + The check is only performed once, with the result cached in the variable + named by ``resultVar``. Every subsequent CMake run will re-use this cached + value rather than performing the check again, even if the ``code`` changes. + In order to force the check to be re-evaluated, the variable named by + ``resultVar`` must be manually removed from the cache. + +#]=======================================================================] macro(CHECK_CXX_SOURCE_COMPILES SOURCE VAR) if(NOT DEFINED "${VAR}") diff --git a/Modules/CheckCXXSourceRuns.cmake b/Modules/CheckCXXSourceRuns.cmake index e083659..558708c 100644 --- a/Modules/CheckCXXSourceRuns.cmake +++ b/Modules/CheckCXXSourceRuns.cmake @@ -1,31 +1,64 @@ # Distributed under the OSI-approved BSD 3-Clause License. See accompanying # file Copyright.txt or https://cmake.org/licensing for details. -#.rst: -# CheckCXXSourceRuns -# ------------------ -# -# Check if the given C++ source code compiles and runs. -# -# CHECK_CXX_SOURCE_RUNS(<code> <var>) -# -# :: -# -# <code> - source code to try to compile -# <var> - variable to store the result -# (1 for success, empty for failure) -# Will be created as an internal cache variable. -# -# The following variables may be set before calling this macro to modify -# the way the check is run: -# -# :: -# -# CMAKE_REQUIRED_FLAGS = string of compile command line flags -# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar) -# CMAKE_REQUIRED_INCLUDES = list of include directories -# CMAKE_REQUIRED_LIBRARIES = list of libraries to link -# CMAKE_REQUIRED_QUIET = execute quietly without messages +#[=======================================================================[.rst: +CheckCXXSourceRuns +------------------ + +Check if given C++ source compiles and links into an executable and can +subsequently be run. + +.. command:: check_cxx_source_runs + + :: + + check_cxx_source_runs(code resultVar) + + Check that the source supplied in ``code`` can be compiled as a C++ source + file, linked as an executable and then run. The ``code`` must contain at + least a ``main()`` function. If the code could be built and run successfully, + the internal cache variable specified by ``resultVar`` will be set to 1, + otherwise it will be set to an value that evaluates to boolean false (e.g. + an empty string or an error message). + + The underlying check is performed by the :command:`try_run` command. The + compile and link commands can be influenced by setting any of the following + variables prior to calling ``check_cxx_source_runs()``: + + ``CMAKE_REQUIRED_FLAGS`` + Additional flags to pass to the compiler. Note that the contents of + :variable:`CMAKE_CXX_FLAGS <CMAKE_<LANG>_FLAGS>` and its associated + configuration-specific variable are automatically added to the compiler + command before the contents of ``CMAKE_REQUIRED_FLAGS``. + + ``CMAKE_REQUIRED_DEFINITIONS`` + A :ref:`;-list <CMake Language Lists>` of compiler definitions of the form + ``-DFOO`` or ``-DFOO=bar``. A definition for the name specified by + ``resultVar`` will also be added automatically. + + ``CMAKE_REQUIRED_INCLUDES`` + A :ref:`;-list <CMake Language Lists>` of header search paths to pass to + the compiler. These will be the only header search paths used by + ``try_run()``, i.e. the contents of the :prop_dir:`INCLUDE_DIRECTORIES` + directory property will be ignored. + + ``CMAKE_REQUIRED_LIBRARIES`` + A :ref:`;-list <CMake Language Lists>` of libraries to add to the link + command. These can be the name of system libraries or they can be + :ref:`Imported Targets <Imported Targets>` (see :command:`try_run` for + further details). + + ``CMAKE_REQUIRED_QUIET`` + If this variable evaluates to a boolean true value, all status messages + associated with the check will be suppressed. + + The check is only performed once, with the result cached in the variable + named by ``resultVar``. Every subsequent CMake run will re-use this cached + value rather than performing the check again, even if the ``code`` changes. + In order to force the check to be re-evaluated, the variable named by + ``resultVar`` must be manually removed from the cache. + +#]=======================================================================] macro(CHECK_CXX_SOURCE_RUNS SOURCE VAR) if(NOT DEFINED "${VAR}") diff --git a/Modules/CheckFortranCompilerFlag.cmake b/Modules/CheckFortranCompilerFlag.cmake index 8519fcc..8a1a8b9 100644 --- a/Modules/CheckFortranCompilerFlag.cmake +++ b/Modules/CheckFortranCompilerFlag.cmake @@ -1,27 +1,36 @@ # Distributed under the OSI-approved BSD 3-Clause License. See accompanying # file Copyright.txt or https://cmake.org/licensing for details. -#.rst: -# CheckFortranCompilerFlag -# ------------------------ -# -# Check whether the Fortran compiler supports a given flag. -# -# CHECK_Fortran_COMPILER_FLAG(<flag> <var>) -# -# :: -# -# <flag> - the compiler flag -# <var> - variable to store the result -# Will be created as an internal cache variable. -# -# This internally calls the check_fortran_source_compiles macro and -# sets CMAKE_REQUIRED_DEFINITIONS to <flag>. See help for -# CheckFortranSourceCompiles for a listing of variables that can -# otherwise modify the build. The result only tells that the compiler -# does not give an error message when it encounters the flag. If the -# flag has any effect or even a specific one is beyond the scope of -# this module. +#[=======================================================================[.rst: +CheckFortranCompilerFlag +------------------------ + +Check whether the Fortran compiler supports a given flag. + +.. command:: check_fortran_compiler_flag + + :: + + check_fortran_compiler_flag(<flag> <var>) + + Check that the ``<flag>`` is accepted by the compiler without + a diagnostic. Stores the result in an internal cache entry + named ``<var>``. + +This command temporarily sets the ``CMAKE_REQUIRED_DEFINITIONS`` variable +and calls the ``check_fortran_source_compiles`` macro from the +:module:`CheckFortranSourceCompiles` module. See documentation of that +module for a listing of variables that can otherwise modify the build. + +A positive result from this check indicates only that the compiler did not +issue a diagnostic message when given the flag. Whether the flag has any +effect or even a specific one is beyond the scope of this module. + +.. note:: + Since the :command:`try_compile` command forwards flags from variables + like :variable:`CMAKE_Fortran_FLAGS <CMAKE_<LANG>_FLAGS>`, unknown flags + in such variables may cause a false negative for this check. +#]=======================================================================] include(CheckFortranSourceCompiles) include(CMakeCheckCompilerFlagCommonPatterns) diff --git a/Modules/CheckFortranSourceCompiles.cmake b/Modules/CheckFortranSourceCompiles.cmake index c42254c..4df17e3 100644 --- a/Modules/CheckFortranSourceCompiles.cmake +++ b/Modules/CheckFortranSourceCompiles.cmake @@ -1,35 +1,71 @@ # Distributed under the OSI-approved BSD 3-Clause License. See accompanying # file Copyright.txt or https://cmake.org/licensing for details. -#.rst: -# CheckFortranSourceCompiles -# -------------------------- -# -# Check if given Fortran source compiles and links into an executable:: -# -# CHECK_Fortran_SOURCE_COMPILES(<code> <var> [FAIL_REGEX <fail-regex>] -# [SRC_EXT <ext>]) -# -# The arguments are: -# -# ``<code>`` -# Source code to try to compile. It must define a PROGRAM entry point. -# ``<var>`` -# Variable to store whether the source code compiled. -# Will be created as an internal cache variable. -# ``FAIL_REGEX <fail-regex>`` -# Fail if test output matches this regex. -# ``SRC_EXT <ext>`` -# Use source extension ``.<ext>`` instead of the default ``.F``. -# -# The following variables may be set before calling this macro to modify -# the way the check is run:: -# -# CMAKE_REQUIRED_FLAGS = string of compile command line flags -# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar) -# CMAKE_REQUIRED_INCLUDES = list of include directories -# CMAKE_REQUIRED_LIBRARIES = list of libraries to link -# CMAKE_REQUIRED_QUIET = execute quietly without messages +#[=======================================================================[.rst: +CheckFortranSourceCompiles +-------------------------- + +Check if given Fortran source compiles and links into an executable. + +.. command:: check_fortran_source_compiles + + :: + + check_fortran_source_compiles(code resultVar + [FAIL_REGEX regex1 [regex2...]] + [SRC_EXT ext] + ) + + Check that the source supplied in ``code`` can be compiled as a Fortran + source file and linked as an executable (so it must contain at least a + ``PROGRAM`` entry point). The result will be stored in the internal cache + variable specified by ``resultVar``, with a boolean true value for success + and boolean false for failure. If ``FAIL_REGEX`` is provided, then failure is + determined by checking if anything in the output matches any of the specified + regular expressions. + + By default, the test source file will be given a ``.F`` file extension. The + ``SRC_EXT`` option can be used to override this with ``.ext`` instead. + + The underlying check is performed by the :command:`try_compile` command. The + compile and link commands can be influenced by setting any of the following + variables prior to calling ``check_fortran_source_compiles()``: + + ``CMAKE_REQUIRED_FLAGS`` + Additional flags to pass to the compiler. Note that the contents of + :variable:`CMAKE_Fortran_FLAGS <CMAKE_<LANG>_FLAGS>` and its associated + configuration-specific variable are automatically added to the compiler + command before the contents of ``CMAKE_REQUIRED_FLAGS``. + + ``CMAKE_REQUIRED_DEFINITIONS`` + A :ref:`;-list <CMake Language Lists>` of compiler definitions of the form + ``-DFOO`` or ``-DFOO=bar``. A definition for the name specified by + ``resultVar`` will also be added automatically. + + ``CMAKE_REQUIRED_INCLUDES`` + A :ref:`;-list <CMake Language Lists>` of header search paths to pass to + the compiler. These will be the only header search paths used by + ``try_compile()``, i.e. the contents of the :prop_dir:`INCLUDE_DIRECTORIES` + directory property will be ignored. + + ``CMAKE_REQUIRED_LIBRARIES`` + A :ref:`;-list <CMake Language Lists>` of libraries to add to the link + command. These can be the name of system libraries or they can be + :ref:`Imported Targets <Imported Targets>` (see :command:`try_compile` for + further details). + + ``CMAKE_REQUIRED_QUIET`` + If this variable evaluates to a boolean true value, all status messages + associated with the check will be suppressed. + + The check is only performed once, with the result cached in the variable + named by ``resultVar``. Every subsequent CMake run will re-use this cached + value rather than performing the check again, even if the ``code`` changes. + In order to force the check to be re-evaluated, the variable named by + ``resultVar`` must be manually removed from the cache. + +#]=======================================================================] + macro(CHECK_Fortran_SOURCE_COMPILES SOURCE VAR) if(NOT DEFINED "${VAR}") diff --git a/Modules/CheckTypeSize.c.in b/Modules/CheckTypeSize.c.in index b6c3688..2303c4e 100644 --- a/Modules/CheckTypeSize.c.in +++ b/Modules/CheckTypeSize.c.in @@ -9,6 +9,12 @@ # define KEY '_','_','p','p','c','_','_' #elif defined(__ppc64__) # define KEY '_','_','p','p','c','6','4','_','_' +#elif defined(__aarch64__) +# define KEY '_','_','a','a','r','c','h','6','4','_','_' +#elif defined(__ARM_ARCH_7A__) +# define KEY '_','_','A','R','M','_','A','R','C','H','_','7','A','_','_' +#elif defined(__ARM_ARCH_7S__) +# define KEY '_','_','A','R','M','_','A','R','C','H','_','7','S','_','_' #endif #define SIZE (sizeof(@type@)) diff --git a/Modules/Compiler/Clang-C.cmake b/Modules/Compiler/Clang-C.cmake index b881e2b..a5f9d84 100644 --- a/Modules/Compiler/Clang-C.cmake +++ b/Modules/Compiler/Clang-C.cmake @@ -7,14 +7,30 @@ if(WIN32 OR (APPLE AND NOT appleClangPolicy STREQUAL NEW)) endif() if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.4) - set(CMAKE_C90_STANDARD_COMPILE_OPTION "-std=c90") - set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-std=gnu90") + if(NOT "x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC") + set(CMAKE_C90_STANDARD_COMPILE_OPTION "-std=c90") + set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-std=gnu90") - set(CMAKE_C99_STANDARD_COMPILE_OPTION "-std=c99") - set(CMAKE_C99_EXTENSION_COMPILE_OPTION "-std=gnu99") + set(CMAKE_C99_STANDARD_COMPILE_OPTION "-std=c99") + set(CMAKE_C99_EXTENSION_COMPILE_OPTION "-std=gnu99") - set(CMAKE_C11_STANDARD_COMPILE_OPTION "-std=c11") - set(CMAKE_C11_EXTENSION_COMPILE_OPTION "-std=gnu11") + set(CMAKE_C11_STANDARD_COMPILE_OPTION "-std=c11") + set(CMAKE_C11_EXTENSION_COMPILE_OPTION "-std=gnu11") + else() + # clang-cl doesn't have any of these + set(CMAKE_C90_STANDARD_COMPILE_OPTION "") + set(CMAKE_C90_EXTENSION_COMPILE_OPTION "") + + set(CMAKE_C99_STANDARD_COMPILE_OPTION "") + set(CMAKE_C99_EXTENSION_COMPILE_OPTION "") + + set(CMAKE_C11_STANDARD_COMPILE_OPTION "") + set(CMAKE_C11_EXTENSION_COMPILE_OPTION "") + endif() endif() -__compiler_check_default_language_standard(C 3.4 99 3.6 11) +if(NOT "x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC") + __compiler_check_default_language_standard(C 3.4 99 3.6 11) +else() + set(CMAKE_C_STANDARD_DEFAULT "") +endif() diff --git a/Modules/Compiler/Clang-CXX.cmake b/Modules/Compiler/Clang-CXX.cmake index d3707ee..efc68b3 100644 --- a/Modules/Compiler/Clang-CXX.cmake +++ b/Modules/Compiler/Clang-CXX.cmake @@ -10,30 +10,46 @@ if(APPLE AND NOT appleClangPolicy STREQUAL NEW) return() endif() -if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 2.1) - set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "-std=c++98") - set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "-std=gnu++98") -endif() +if(NOT "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC") + if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 2.1) + set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "-std=c++98") + set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "-std=gnu++98") + endif() -if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.1) - set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "-std=c++11") - set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-std=gnu++11") -elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 2.1) - set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "-std=c++0x") - set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-std=gnu++0x") -endif() + if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.1) + set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "-std=c++11") + set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-std=gnu++11") + elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 2.1) + set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "-std=c++0x") + set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-std=gnu++0x") + endif() -if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.5) - set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "-std=c++14") - set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-std=gnu++14") -elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.4) - set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "-std=c++1y") - set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-std=gnu++1y") -endif() + if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.5) + set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "-std=c++14") + set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-std=gnu++14") + elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.4) + set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "-std=c++1y") + set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-std=gnu++1y") + endif() -if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.5) - set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-std=c++1z") - set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std=gnu++1z") + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.5) + set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-std=c++1z") + set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std=gnu++1z") + endif() +else() + # clang-cl does not know these options because it behaves like cl.exe + set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "") + set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "") + set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "") + set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "") + set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "") + set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "") + set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "") + set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "") endif() -__compiler_check_default_language_standard(CXX 2.1 98) +if(NOT "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC") + __compiler_check_default_language_standard(CXX 2.1 98) +else() + set(CMAKE_CXX_STANDARD_DEFAULT "") +endif() diff --git a/Modules/FindCUDA.cmake b/Modules/FindCUDA.cmake index a4dca54..5dc55d4 100644 --- a/Modules/FindCUDA.cmake +++ b/Modules/FindCUDA.cmake @@ -679,7 +679,11 @@ if(CMAKE_CROSSCOMPILING) # add known CUDA targetr root path to the set of directories we search for programs, libraries and headers set( CMAKE_FIND_ROOT_PATH "${CUDA_TOOLKIT_TARGET_DIR};${CMAKE_FIND_ROOT_PATH}") macro( cuda_find_host_program ) - find_host_program( ${ARGN} ) + if (COMMAND find_host_program) + find_host_program( ${ARGN} ) + else() + find_program( ${ARGN} ) + endif() endmacro() else() # for non-cross-compile, find_host_program == find_program and CUDA_TOOLKIT_TARGET_DIR == CUDA_TOOLKIT_ROOT_DIR @@ -1698,6 +1702,7 @@ function(CUDA_LINK_SEPARABLE_COMPILATION_OBJECTS output_file cuda_target options COMMAND ${CUDA_NVCC_EXECUTABLE} ${nvcc_flags} -dlink ${object_files} -o ${output_file} ${flags} COMMENT "Building NVCC intermediate link file ${output_file_relative_path}" + COMMAND_EXPAND_LISTS ${_verbatim} ) else() @@ -1708,6 +1713,7 @@ function(CUDA_LINK_SEPARABLE_COMPILATION_OBJECTS output_file cuda_target options COMMAND ${CMAKE_COMMAND} -E echo "Building NVCC intermediate link file ${output_file_relative_path}" COMMAND ${CMAKE_COMMAND} -E make_directory "${output_file_dir}" COMMAND ${CUDA_NVCC_EXECUTABLE} ${nvcc_flags} ${flags} -dlink ${object_files} -o "${output_file}" + COMMAND_EXPAND_LISTS ${_verbatim} ) endif() diff --git a/Modules/FindCurses.cmake b/Modules/FindCurses.cmake index 4365e99..8d58d03 100644 --- a/Modules/FindCurses.cmake +++ b/Modules/FindCurses.cmake @@ -199,4 +199,5 @@ mark_as_advanced( CURSES_CURSES_LIBRARY CURSES_NCURSES_LIBRARY CURSES_EXTRA_LIBRARY + CURSES_FORM_LIBRARY ) diff --git a/Modules/FindDoxygen.cmake b/Modules/FindDoxygen.cmake index 26d44b9..fb16f20 100644 --- a/Modules/FindDoxygen.cmake +++ b/Modules/FindDoxygen.cmake @@ -619,7 +619,7 @@ if(TARGET Doxygen::doxygen) # If doxygen was found, use it to generate a minimal default Doxyfile. # We will delete this file after we have finished using it below to # generate the other files that doxygen_add_docs() will use. - set(_Doxygen_tpl "${PROJECT_BINARY_DIR}/CMakeDoxyfile.tpl") + set(_Doxygen_tpl "${CMAKE_BINARY_DIR}/CMakeDoxyfile.tpl") execute_process( COMMAND "${DOXYGEN_EXECUTABLE}" -s -g "${_Doxygen_tpl}" OUTPUT_QUIET @@ -646,8 +646,8 @@ if(TARGET Doxygen::doxygen) # content is only dependent on the version of Doxygen being used. Therefore # we always put them at the top of the build tree so that they are in a # predictable location. - set(_doxyfile_in "${PROJECT_BINARY_DIR}/CMakeDoxyfile.in") - set(_doxyfile_defaults "${PROJECT_BINARY_DIR}/CMakeDoxygenDefaults.cmake") + set(_doxyfile_in "${CMAKE_BINARY_DIR}/CMakeDoxyfile.in") + set(_doxyfile_defaults "${CMAKE_BINARY_DIR}/CMakeDoxygenDefaults.cmake") file(WRITE "${_doxyfile_in}" ${_Doxygen_dne_header}) file(WRITE "${_doxyfile_defaults}" ${_Doxygen_dne_header}) @@ -896,7 +896,7 @@ doxygen_add_docs() for target ${targetName}") # Now bring in Doxgen's defaults for those things the project has not # already set and we have not provided above - include("${PROJECT_BINARY_DIR}/CMakeDoxygenDefaults.cmake" OPTIONAL) + include("${CMAKE_BINARY_DIR}/CMakeDoxygenDefaults.cmake" OPTIONAL) # Cleanup built HTMLs on "make clean" # TODO Any other dirs? @@ -1025,7 +1025,7 @@ doxygen_add_docs() for target ${targetName}") endforeach() # Prepare doxygen configuration file - set(_doxyfile_template "${PROJECT_BINARY_DIR}/CMakeDoxyfile.in") + set(_doxyfile_template "${CMAKE_BINARY_DIR}/CMakeDoxyfile.in") set(_target_doxyfile "${CMAKE_CURRENT_BINARY_DIR}/Doxyfile.${targetName}") configure_file("${_doxyfile_template}" "${_target_doxyfile}") diff --git a/Modules/FindHDF5.cmake b/Modules/FindHDF5.cmake index 5962c5b..2d9d2a2 100644 --- a/Modules/FindHDF5.cmake +++ b/Modules/FindHDF5.cmake @@ -187,8 +187,16 @@ function(_HDF5_test_regular_compiler_C success version is_parallel) file(WRITE ${test_file} "#include <hdf5.h>\n" "#include <hdf5_hl.h>\n" - "int main(void) {\n" - " char const* info_ver = \"INFO\" \":\" H5_VERSION;\n" + "const char* info_ver = \"INFO\" \":\" H5_VERSION;\n" + "#ifdef H5_HAVE_PARALLEL\n" + "const char* info_parallel = \"INFO\" \":\" \"PARALLEL\";\n" + "#endif\n" + "int main(int argc, char **argv) {\n" + " int require = 0;\n" + " require += info_ver[argc];\n" + "#ifdef H5_HAVE_PARALLEL\n" + " require += info_parallel[argc];\n" + "#endif\n" " hid_t fid;\n" " fid = H5Fcreate(\"foo.h5\",H5F_ACC_TRUNC,H5P_DEFAULT,H5P_DEFAULT);\n" " return 0;\n" @@ -198,11 +206,11 @@ function(_HDF5_test_regular_compiler_C success version is_parallel) ) endif() if(${success}) - file(STRINGS ${scratch_directory}/compiler_has_h5_c INFO_VER - REGEX "^INFO:([0-9]+\\.[0-9]+\\.[0-9]+)(-patch([0-9]+))?" + file(STRINGS ${scratch_directory}/compiler_has_h5_c INFO_STRINGS + REGEX "^INFO:" ) string(REGEX MATCH "^INFO:([0-9]+\\.[0-9]+\\.[0-9]+)(-patch([0-9]+))?" - INFO_VER "${INFO_VER}" + INFO_VER "${INFO_STRINGS}" ) set(${version} ${CMAKE_MATCH_1}) if(CMAKE_MATCH_3) @@ -210,12 +218,7 @@ function(_HDF5_test_regular_compiler_C success version is_parallel) endif() set(${version} ${${version}} PARENT_SCOPE) - execute_process(COMMAND ${CMAKE_C_COMPILER} -showconfig - OUTPUT_VARIABLE config_output - ERROR_VARIABLE config_error - RESULT_VARIABLE config_result - ) - if(config_output MATCHES "Parallel HDF5: yes") + if(INFO_STRINGS MATCHES "INFO:PARALLEL") set(${is_parallel} TRUE PARENT_SCOPE) else() set(${is_parallel} FALSE PARENT_SCOPE) @@ -233,8 +236,16 @@ function(_HDF5_test_regular_compiler_CXX success version is_parallel) "#ifndef H5_NO_NAMESPACE\n" "using namespace H5;\n" "#endif\n" + "const char* info_ver = \"INFO\" \":\" H5_VERSION;\n" + "#ifdef H5_HAVE_PARALLEL\n" + "const char* info_parallel = \"INFO\" \":\" \"PARALLEL\";\n" + "#endif\n" "int main(int argc, char **argv) {\n" - " char const* info_ver = \"INFO\" \":\" H5_VERSION;\n" + " int require = 0;\n" + " require += info_ver[argc];\n" + "#ifdef H5_HAVE_PARALLEL\n" + " require += info_parallel[argc];\n" + "#endif\n" " H5File file(\"foo.h5\", H5F_ACC_TRUNC);\n" " return 0;\n" "}") @@ -243,11 +254,11 @@ function(_HDF5_test_regular_compiler_CXX success version is_parallel) ) endif() if(${success}) - file(STRINGS ${scratch_directory}/compiler_has_h5_cxx INFO_VER - REGEX "^INFO:([0-9]+\\.[0-9]+\\.[0-9]+)(-patch([0-9]+))?" + file(STRINGS ${scratch_directory}/compiler_has_h5_cxx INFO_STRINGS + REGEX "^INFO:" ) string(REGEX MATCH "^INFO:([0-9]+\\.[0-9]+\\.[0-9]+)(-patch([0-9]+))?" - INFO_VER "${INFO_VER}" + INFO_VER "${INFO_STRINGS}" ) set(${version} ${CMAKE_MATCH_1}) if(CMAKE_MATCH_3) @@ -255,12 +266,7 @@ function(_HDF5_test_regular_compiler_CXX success version is_parallel) endif() set(${version} ${${version}} PARENT_SCOPE) - execute_process(COMMAND ${CMAKE_CXX_COMPILER} -showconfig - OUTPUT_VARIABLE config_output - ERROR_VARIABLE config_error - RESULT_VARIABLE config_result - ) - if(config_output MATCHES "Parallel HDF5: yes") + if(INFO_STRINGS MATCHES "INFO:PARALLEL") set(${is_parallel} TRUE PARENT_SCOPE) else() set(${is_parallel} FALSE PARENT_SCOPE) diff --git a/Modules/FindHTMLHelp.cmake b/Modules/FindHTMLHelp.cmake index 84e2458..6aab8a7 100644 --- a/Modules/FindHTMLHelp.cmake +++ b/Modules/FindHTMLHelp.cmake @@ -18,28 +18,28 @@ if(WIN32) find_program(HTML_HELP_COMPILER - hhc - "[HKEY_CURRENT_USER\\Software\\Microsoft\\HTML Help Workshop;InstallDir]" - "$ENV{ProgramFiles}/HTML Help Workshop" - "C:/Program Files/HTML Help Workshop" + NAMES hhc + PATHS + "[HKEY_CURRENT_USER\\Software\\Microsoft\\HTML Help Workshop;InstallDir]" + PATH_SUFFIXES "HTML Help Workshop" ) get_filename_component(HTML_HELP_COMPILER_PATH "${HTML_HELP_COMPILER}" PATH) find_path(HTML_HELP_INCLUDE_PATH - htmlhelp.h - "${HTML_HELP_COMPILER_PATH}/include" - "[HKEY_CURRENT_USER\\Software\\Microsoft\\HTML Help Workshop;InstallDir]/include" - "$ENV{ProgramFiles}/HTML Help Workshop/include" - "C:/Program Files/HTML Help Workshop/include" + NAMES htmlhelp.h + PATHS + "${HTML_HELP_COMPILER_PATH}/include" + "[HKEY_CURRENT_USER\\Software\\Microsoft\\HTML Help Workshop;InstallDir]/include" + PATH_SUFFIXES "HTML Help Workshop/include" ) find_library(HTML_HELP_LIBRARY - htmlhelp - "${HTML_HELP_COMPILER_PATH}/lib" - "[HKEY_CURRENT_USER\\Software\\Microsoft\\HTML Help Workshop;InstallDir]/lib" - "$ENV{ProgramFiles}/HTML Help Workshop/lib" - "C:/Program Files/HTML Help Workshop/lib" + NAMES htmlhelp + PATHS + "${HTML_HELP_COMPILER_PATH}/lib" + "[HKEY_CURRENT_USER\\Software\\Microsoft\\HTML Help Workshop;InstallDir]/lib" + PATH_SUFFIXES "HTML Help Workshop/lib" ) mark_as_advanced( diff --git a/Modules/FindICU.cmake b/Modules/FindICU.cmake index 5210f08..d9705d9 100644 --- a/Modules/FindICU.cmake +++ b/Modules/FindICU.cmake @@ -55,6 +55,11 @@ # ICU_<C>_FOUND - ON if component was found # ICU_<C>_LIBRARIES - libraries for component # +# ICU datafiles are reported in:: +# +# ICU_MAKEFILE_INC - Makefile.inc +# ICU_PKGDATA_INC - pkgdata.inc +# # Note that ``<C>`` is the uppercased name of the component. # # This module reads hints about search results from:: @@ -100,6 +105,10 @@ set(icu_programs icupkg gencmn) +set(icu_data + Makefile.inc + pkgdata.inc) + # The ICU checks are contained in a function due to the large number # of temporary variables needed. function(_ICU_FIND) @@ -116,6 +125,28 @@ function(_ICU_FIND) endif() endif() + # Find include directory + list(APPEND icu_include_suffixes "include") + find_path(ICU_INCLUDE_DIR + NAMES "unicode/utypes.h" + HINTS ${icu_roots} + PATH_SUFFIXES ${icu_include_suffixes} + DOC "ICU include directory") + set(ICU_INCLUDE_DIR "${ICU_INCLUDE_DIR}" PARENT_SCOPE) + + # Get version + if(ICU_INCLUDE_DIR AND EXISTS "${ICU_INCLUDE_DIR}/unicode/uvernum.h") + file(STRINGS "${ICU_INCLUDE_DIR}/unicode/uvernum.h" icu_header_str + REGEX "^#define[\t ]+U_ICU_VERSION[\t ]+\".*\".*") + + string(REGEX REPLACE "^#define[\t ]+U_ICU_VERSION[\t ]+\"([^ \\n]*)\".*" + "\\1" icu_version_string "${icu_header_str}") + set(ICU_VERSION "${icu_version_string}") + set(ICU_VERSION "${icu_version_string}" PARENT_SCOPE) + unset(icu_header_str) + unset(icu_version_string) + endif() + if(CMAKE_SIZEOF_VOID_P EQUAL 8) # 64-bit binary directory set(_bin64 "bin64") @@ -123,12 +154,9 @@ function(_ICU_FIND) set(_lib64 "lib64") endif() - # Generic 64-bit and 32-bit directories - list(APPEND icu_binary_suffixes "${_bin64}" "bin") - list(APPEND icu_library_suffixes "${_lib64}" "lib") - list(APPEND icu_include_suffixes "include") # Find all ICU programs + list(APPEND icu_binary_suffixes "${_bin64}" "bin") foreach(program ${icu_programs}) string(TOUPPER "${program}" program_upcase) set(cache_var "ICU_${program_upcase}_EXECUTABLE") @@ -141,27 +169,8 @@ function(_ICU_FIND) set("${program_var}" "${${cache_var}}" PARENT_SCOPE) endforeach() - # Find include directory - find_path(ICU_INCLUDE_DIR - NAMES "unicode/utypes.h" - HINTS ${icu_roots} - PATH_SUFFIXES ${icu_include_suffixes} - DOC "ICU include directory") - set(ICU_INCLUDE_DIR "${ICU_INCLUDE_DIR}" PARENT_SCOPE) - - # Get version - if(ICU_INCLUDE_DIR AND EXISTS "${ICU_INCLUDE_DIR}/unicode/uvernum.h") - file(STRINGS "${ICU_INCLUDE_DIR}/unicode/uvernum.h" icu_header_str - REGEX "^#define[\t ]+U_ICU_VERSION[\t ]+\".*\".*") - - string(REGEX REPLACE "^#define[\t ]+U_ICU_VERSION[\t ]+\"([^ \\n]*)\".*" - "\\1" icu_version_string "${icu_header_str}") - set(ICU_VERSION "${icu_version_string}" PARENT_SCOPE) - unset(icu_header_str) - unset(icu_version_string) - endif() - # Find all ICU libraries + list(APPEND icu_library_suffixes "${_lib64}" "lib") set(ICU_REQUIRED_LIBS_FOUND ON) foreach(component ${ICU_FIND_COMPONENTS}) string(TOUPPER "${component}" component_upcase) @@ -233,6 +242,32 @@ function(_ICU_FIND) set(_ICU_REQUIRED_LIBS_FOUND "${ICU_REQUIRED_LIBS_FOUND}" PARENT_SCOPE) set(ICU_LIBRARY "${ICU_LIBRARY}" PARENT_SCOPE) + # Find all ICU data files + if(CMAKE_LIBRARY_ARCHITECTURE) + list(APPEND icu_data_suffixes + "${_lib64}/${CMAKE_LIBRARY_ARCHITECTURE}/icu/${ICU_VERSION}" + "lib/${CMAKE_LIBRARY_ARCHITECTURE}/icu/${ICU_VERSION}" + "${_lib64}/${CMAKE_LIBRARY_ARCHITECTURE}/icu" + "lib/${CMAKE_LIBRARY_ARCHITECTURE}/icu") + endif() + list(APPEND icu_data_suffixes + "${_lib64}/icu/${ICU_VERSION}" + "lib/icu/${ICU_VERSION}" + "${_lib64}/icu" + "lib/icu") + foreach(data ${icu_data}) + string(TOUPPER "${data}" data_upcase) + string(REPLACE "." "_" data_upcase "${data_upcase}") + set(cache_var "ICU_${data_upcase}") + set(data_var "ICU_${data_upcase}") + find_file("${cache_var}" "${data}" + HINTS ${icu_roots} + PATH_SUFFIXES ${icu_data_suffixes} + DOC "ICU ${data} data file") + mark_as_advanced(cache_var) + set("${data_var}" "${${cache_var}}" PARENT_SCOPE) + endforeach() + if(NOT ICU_FIND_QUIETLY) if(ICU_LIBS_FOUND) message(STATUS "Found the following ICU libraries:") @@ -334,6 +369,15 @@ if(ICU_DEBUG) unset(program_lib) endforeach() + foreach(data IN LISTS icu_data) + string(TOUPPER "${data}" data_upcase) + string(REPLACE "." "_" data_upcase "${data_upcase}") + set(data_lib "ICU_${data_upcase}") + message(STATUS "${data} data: ${${data_lib}}") + unset(data_upcase) + unset(data_lib) + endforeach() + foreach(component IN LISTS ICU_FIND_COMPONENTS) string(TOUPPER "${component}" component_upcase) set(component_lib "ICU_${component_upcase}_LIBRARIES") diff --git a/Modules/FindXCTest.cmake b/Modules/FindXCTest.cmake index ffdf677..8497336 100644 --- a/Modules/FindXCTest.cmake +++ b/Modules/FindXCTest.cmake @@ -136,7 +136,7 @@ function(xctest_add_bundle target testee) XCODE_ATTRIBUTE_TEST_HOST "$<TARGET_FILE:${testee}>") if(NOT XCODE_VERSION VERSION_LESS 7.3) set_target_properties(${target} PROPERTIES - LIBRARY_OUTPUT_DIRECTORY "$<TARGET_FILE_DIR:${testee}>/../PlugIns") + LIBRARY_OUTPUT_DIRECTORY "$<TARGET_BUNDLE_CONTENT_DIR:${testee}>/PlugIns") endif() else(XCODE) target_link_libraries(${target} @@ -183,7 +183,7 @@ function(xctest_add_test name bundle) add_test( NAME ${name} - COMMAND ${XCTest_EXECUTABLE} $<TARGET_LINKER_FILE_DIR:${bundle}>/../..) + COMMAND ${XCTest_EXECUTABLE} $<TARGET_BUNDLE_DIR:${bundle}>) # point loader to testee in case rpath is disabled diff --git a/Modules/FindwxWidgets.cmake b/Modules/FindwxWidgets.cmake index af4daf0..63f2c60 100644 --- a/Modules/FindwxWidgets.cmake +++ b/Modules/FindwxWidgets.cmake @@ -778,28 +778,24 @@ else() ) if(RET EQUAL 0) string(STRIP "${wxWidgets_CXX_FLAGS}" wxWidgets_CXX_FLAGS) - separate_arguments(wxWidgets_CXX_FLAGS) + separate_arguments(wxWidgets_CXX_FLAGS_LIST NATIVE_COMMAND "${wxWidgets_CXX_FLAGS}") DBG_MSG_V("wxWidgets_CXX_FLAGS=${wxWidgets_CXX_FLAGS}") - # parse definitions from cxxflags; - # drop -D* from CXXFLAGS and the -D prefix - string(REGEX MATCHALL "-D[^;]+" - wxWidgets_DEFINITIONS "${wxWidgets_CXX_FLAGS}") - string(REGEX REPLACE "-D[^;]+(;|$)" "" - wxWidgets_CXX_FLAGS "${wxWidgets_CXX_FLAGS}") - string(REGEX REPLACE ";$" "" - wxWidgets_CXX_FLAGS "${wxWidgets_CXX_FLAGS}") - string(REPLACE "-D" "" - wxWidgets_DEFINITIONS "${wxWidgets_DEFINITIONS}") - - # parse include dirs from cxxflags; drop -I prefix - string(REGEX MATCHALL "-I[^;]+" - wxWidgets_INCLUDE_DIRS "${wxWidgets_CXX_FLAGS}") - string(REGEX REPLACE "-I[^;]+;" "" - wxWidgets_CXX_FLAGS "${wxWidgets_CXX_FLAGS}") - string(REPLACE "-I" "" - wxWidgets_INCLUDE_DIRS "${wxWidgets_INCLUDE_DIRS}") + # parse definitions and include dirs from cxxflags + # drop the -D and -I prefixes + set(wxWidgets_CXX_FLAGS) + foreach(arg IN LISTS wxWidgets_CXX_FLAGS_LIST) + if("${arg}" MATCHES "^-I(.*)$") + # include directory + list(APPEND wxWidgets_INCLUDE_DIRS "${CMAKE_MATCH_1}") + elseif("${arg}" MATCHES "^-D(.*)$") + # compile definition + list(APPEND wxWidgets_DEFINITIONS "${CMAKE_MATCH_1}") + else() + list(APPEND wxWidgets_CXX_FLAGS "${arg}") + endif() + endforeach() DBG_MSG_V("wxWidgets_DEFINITIONS=${wxWidgets_DEFINITIONS}") DBG_MSG_V("wxWidgets_INCLUDE_DIRS=${wxWidgets_INCLUDE_DIRS}") diff --git a/Modules/Platform/Generic-SDCC-C.cmake b/Modules/Platform/Generic-SDCC-C.cmake index bbefe19..4b3912a 100644 --- a/Modules/Platform/Generic-SDCC-C.cmake +++ b/Modules/Platform/Generic-SDCC-C.cmake @@ -41,7 +41,7 @@ endif() set(CMAKE_C_COMPILE_OBJECT "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>") # link object files to an executable -set(CMAKE_C_LINK_EXECUTABLE "<CMAKE_C_COMPILER> <FLAGS> <OBJECTS> --out-fmt-ihx -o <TARGET> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>") +set(CMAKE_C_LINK_EXECUTABLE "<CMAKE_C_COMPILER> <FLAGS> <OBJECTS> -o <TARGET> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>") # needs sdcc 2.7.0 + sddclib from cvs set(CMAKE_C_CREATE_STATIC_LIBRARY diff --git a/Modules/UseSWIG.cmake b/Modules/UseSWIG.cmake index bfe1a6f..456a6bd 100644 --- a/Modules/UseSWIG.cmake +++ b/Modules/UseSWIG.cmake @@ -82,10 +82,6 @@ macro(SWIG_MODULE_INITIALIZE name language) set(SWIG_MODULE_${name}_REAL_NAME "_${name}") elseif("x${SWIG_MODULE_${name}_LANGUAGE}" STREQUAL "xPERL") set(SWIG_MODULE_${name}_EXTRA_FLAGS "-shadow") - elseif("x${SWIG_MODULE_${name}_LANGUAGE}" STREQUAL "xCSHARP") - # This makes sure that the name used in the generated DllImport - # matches the library name created by CMake - set(SWIG_MODULE_${name}_EXTRA_FLAGS "-dllimport;${name}") endif() endmacro() @@ -192,6 +188,13 @@ macro(SWIG_ADD_SOURCE_TO_MODULE name outfiles infile) if(swig_source_file_cplusplus) set(swig_special_flags ${swig_special_flags} "-c++") endif() + if("x${SWIG_MODULE_${name}_LANGUAGE}" STREQUAL "xCSHARP") + if(NOT ";${swig_source_file_flags};${CMAKE_SWIG_FLAGS};" MATCHES ";-dllimport;") + # This makes sure that the name used in the generated DllImport + # matches the library name created by CMake + set(SWIG_MODULE_${name}_EXTRA_FLAGS "-dllimport;${name}") + endif() + endif() set(swig_extra_flags) if(SWIG_MODULE_${name}_EXTRA_FLAGS) set(swig_extra_flags ${swig_extra_flags} ${SWIG_MODULE_${name}_EXTRA_FLAGS}) diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 40403ca..e556ca6 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -469,6 +469,8 @@ set(SRCS cmIncludeDirectoryCommand.h cmIncludeExternalMSProjectCommand.cxx cmIncludeExternalMSProjectCommand.h + cmIncludeGuardCommand.cxx + cmIncludeGuardCommand.h cmIncludeRegularExpressionCommand.cxx cmIncludeRegularExpressionCommand.h cmInstallCommand.cxx @@ -874,6 +876,7 @@ set(CPACK_SRCS CPack/cmCPackTarCompressGenerator.cxx CPack/cmCPackZIPGenerator.cxx CPack/cmCPack7zGenerator.cxx + CPack/cmCPackDebGenerator.cxx ) # CPack IFW generator set(CPACK_SRCS ${CPACK_SRCS} @@ -896,11 +899,39 @@ if(CYGWIN) ) endif() +option(CPACK_ENABLE_FREEBSD_PKG "Add FreeBSD pkg(8) generator to CPack." OFF) + if(UNIX) set(CPACK_SRCS ${CPACK_SRCS} - CPack/cmCPackDebGenerator.cxx CPack/cmCPackRPMGenerator.cxx ) + + # Optionally, try to use pkg(8) + if(CPACK_ENABLE_FREEBSD_PKG) + # On UNIX, you may find FreeBSD's pkg(8) and attendant + # library -- it can be used on FreeBSD, Dragonfly, NetBSD, + # OpenBSD and also Linux and OSX. Look for the header and + # the library; it's a warning on FreeBSD if they're not + # found, and informational on other platforms. + find_path(FREEBSD_PKG_INCLUDE_DIRS "pkg.h" PATHS /usr/local) + if(FREEBSD_PKG_INCLUDE_DIRS) + find_library(FREEBSD_PKG_LIBRARIES + pkg + DOC "FreeBSD pkg(8) library") + if(FREEBSD_PKG_LIBRARIES) + set(CPACK_SRCS ${CPACK_SRCS} + CPack/cmCPackFreeBSDGenerator.cxx + ) + endif() + endif() + + if (NOT FREEBSD_PKG_INCLUDE_DIRS OR NOT FREEBSD_PKG_LIBRARIES) + message(FATAL_ERROR "CPack needs libpkg(3) to produce FreeBSD packages natively.") + endif() + else() + set(FREEBSD_PKG_INCLUDE_DIRS NOTFOUND) + set(FREEBSD_PKG_LIBRARIES NOTFOUND) + endif() endif() if(WIN32) @@ -958,6 +989,11 @@ if(APPLE) "See CMakeFiles/CMakeError.log for details of the failure.") endif() endif() +if(CPACK_ENABLE_FREEBSD_PKG AND FREEBSD_PKG_INCLUDE_DIRS AND FREEBSD_PKG_LIBRARIES) + target_link_libraries(CPackLib ${FREEBSD_PKG_LIBRARIES}) + include_directories(${FREEBSD_PKG_INCLUDE_DIRS}) + add_definitions(-DHAVE_FREEBSD_PKG) +endif() if(APPLE) add_executable(cmakexbuild cmakexbuild.cxx) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 70b72ec..182bc31 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,5 +1,5 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 9) -set(CMake_VERSION_PATCH 0) -set(CMake_VERSION_RC 5) +set(CMake_VERSION_PATCH 20170630) +#set(CMake_VERSION_RC 1) diff --git a/Source/CPack/cmCPackBundleGenerator.h b/Source/CPack/cmCPackBundleGenerator.h index 861fe4b..a127e7b 100644 --- a/Source/CPack/cmCPackBundleGenerator.h +++ b/Source/CPack/cmCPackBundleGenerator.h @@ -21,7 +21,7 @@ public: cmCPackTypeMacro(cmCPackBundleGenerator, cmCPackDragNDropGenerator); cmCPackBundleGenerator(); - virtual ~cmCPackBundleGenerator(); + ~cmCPackBundleGenerator() CM_OVERRIDE; protected: int InitializeInternal() CM_OVERRIDE; diff --git a/Source/CPack/cmCPackCygwinBinaryGenerator.h b/Source/CPack/cmCPackCygwinBinaryGenerator.h index 58e80bd..b5a0531 100644 --- a/Source/CPack/cmCPackCygwinBinaryGenerator.h +++ b/Source/CPack/cmCPackCygwinBinaryGenerator.h @@ -17,7 +17,7 @@ public: * Construct generator */ cmCPackCygwinBinaryGenerator(); - virtual ~cmCPackCygwinBinaryGenerator(); + ~cmCPackCygwinBinaryGenerator() CM_OVERRIDE; protected: virtual int InitializeInternal(); diff --git a/Source/CPack/cmCPackCygwinSourceGenerator.h b/Source/CPack/cmCPackCygwinSourceGenerator.h index 896de1d..d19f87c 100644 --- a/Source/CPack/cmCPackCygwinSourceGenerator.h +++ b/Source/CPack/cmCPackCygwinSourceGenerator.h @@ -17,7 +17,7 @@ public: * Construct generator */ cmCPackCygwinSourceGenerator(); - virtual ~cmCPackCygwinSourceGenerator(); + ~cmCPackCygwinSourceGenerator() CM_OVERRIDE; protected: const char* GetPackagingInstallPrefix(); diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx index af54fce..00d017e 100644 --- a/Source/CPack/cmCPackDebGenerator.cxx +++ b/Source/CPack/cmCPackDebGenerator.cxx @@ -479,6 +479,25 @@ int cmCPackDebGenerator::createDeb() cmCPackLogger(cmCPackLog::LOG_DEBUG, "RELATIVEDIR: \"" << relativeDir << "\"" << std::endl); +#ifdef WIN32 + std::string mode_t_adt_filename = *fileIt + ":cmake_mode_t"; + cmsys::ifstream permissionStream(mode_t_adt_filename.c_str()); + + mode_t permissions = 0; + + if (permissionStream) { + permissionStream >> std::oct >> permissions; + } + + if (permissions != 0) { + data_tar.SetPermissions(permissions); + } else if (cmSystemTools::FileIsDirectory(*fileIt)) { + data_tar.SetPermissions(0755); + } else { + data_tar.ClearPermissions(); + } +#endif + // do not recurse because the loop will do it if (!data_tar.Add(*fileIt, topLevelLength, ".", false)) { cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem adding file to tar:" @@ -553,8 +572,8 @@ int cmCPackDebGenerator::createDeb() and https://lintian.debian.org/tags/control-file-has-bad-permissions.html */ - const mode_t permission644 = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; - const mode_t permissionExecute = S_IXUSR | S_IXGRP | S_IXOTH; + const mode_t permission644 = 0644; + const mode_t permissionExecute = 0111; const mode_t permission755 = permission644 | permissionExecute; // for md5sum and control (that we have generated here), we use 644 @@ -831,7 +850,7 @@ static int copy_ar(CF* cfp, off_t size) ? static_cast<size_t>(sz) : sizeof(buf), from)) > 0) { - sz -= nr; + sz -= static_cast<off_t>(nr); for (size_t off = 0; off < nr; nr -= off, off += nw) { if ((nw = fwrite(buf + off, 1, nr, to)) < nr) { return -1; @@ -854,7 +873,6 @@ static int copy_ar(CF* cfp, off_t size) static int put_arobj(CF* cfp, struct stat* sb) { int result = 0; - struct ar_hdr* hdr; /* If passed an sb structure, reading a file from disk. Get stat(2) * information, build a name and construct a header. (Files are named @@ -873,7 +891,7 @@ static int put_arobj(CF* cfp, struct stat* sb) if (gid > USHRT_MAX) { gid = USHRT_MAX; } - if (lname > sizeof(hdr->ar_name) || strchr(name, ' ')) { + if (lname > sizeof(ar_hdr().ar_name) || strchr(name, ' ')) { (void)sprintf(ar_hb, HDR1, AR_EFMT1, (int)lname, (long int)sb->st_mtime, (unsigned)uid, (unsigned)gid, (unsigned)sb->st_mode, (long long)sb->st_size + lname, ARFMAG); diff --git a/Source/CPack/cmCPackDragNDropGenerator.h b/Source/CPack/cmCPackDragNDropGenerator.h index ae2cc17..ffa9015 100644 --- a/Source/CPack/cmCPackDragNDropGenerator.h +++ b/Source/CPack/cmCPackDragNDropGenerator.h @@ -23,7 +23,7 @@ public: cmCPackTypeMacro(cmCPackDragNDropGenerator, cmCPackGenerator); cmCPackDragNDropGenerator(); - virtual ~cmCPackDragNDropGenerator(); + ~cmCPackDragNDropGenerator() CM_OVERRIDE; protected: int InitializeInternal() CM_OVERRIDE; @@ -40,8 +40,6 @@ protected: int CreateDMG(const std::string& src_dir, const std::string& output_file); - std::string InstallPrefix; - private: std::string slaDirectory; bool singleLicense; diff --git a/Source/CPack/cmCPackFreeBSDGenerator.cxx b/Source/CPack/cmCPackFreeBSDGenerator.cxx new file mode 100644 index 0000000..ae17b79 --- /dev/null +++ b/Source/CPack/cmCPackFreeBSDGenerator.cxx @@ -0,0 +1,359 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmCPackFreeBSDGenerator.h" + +#include "cmArchiveWrite.h" +#include "cmCPackArchiveGenerator.h" +#include "cmCPackLog.h" +#include "cmGeneratedFileStream.h" +#include "cmSystemTools.h" + +// Needed for ::open() and ::stat() +#include <fcntl.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <unistd.h> + +#include <pkg.h> + +#include <algorithm> + +cmCPackFreeBSDGenerator::cmCPackFreeBSDGenerator() + : cmCPackArchiveGenerator(cmArchiveWrite::CompressXZ, "paxr") +{ +} + +int cmCPackFreeBSDGenerator::InitializeInternal() +{ + this->SetOptionIfNotSet("CPACK_PACKAGING_INSTALL_PREFIX", "/usr/local"); + this->SetOption("CPACK_INCLUDE_TOPLEVEL_DIRECTORY", "0"); + return this->Superclass::InitializeInternal(); +} + +cmCPackFreeBSDGenerator::~cmCPackFreeBSDGenerator() +{ +} + +// This is a wrapper, for use only in stream-based output, +// that will output a string in UCL escaped fashion (in particular, +// quotes and backslashes are escaped). The list of characters +// to escape is taken from https://github.com/vstakhov/libucl +// (which is the reference implementation pkg(8) refers to). +class EscapeQuotes +{ +public: + const std::string& value; + + EscapeQuotes(const std::string& s) + : value(s) + { + } +}; + +// Output a string as "string" with escaping applied. +cmGeneratedFileStream& operator<<(cmGeneratedFileStream& s, + const EscapeQuotes& v) +{ + s << '"'; + for (std::string::size_type i = 0; i < v.value.length(); ++i) { + char c = v.value[i]; + switch (c) { + case '\n': + s << "\\n"; + break; + case '\r': + s << "\\r"; + break; + case '\b': + s << "\\b"; + break; + case '\t': + s << "\\t"; + break; + case '\f': + s << "\\f"; + break; + case '\\': + s << "\\\\"; + break; + case '"': + s << "\\\""; + break; + default: + s << c; + break; + } + } + s << '"'; + return s; +} + +// The following classes are all helpers for writing out the UCL +// manifest file (it also looks like JSON). ManifestKey just has +// a (string-valued) key; subclasses add a specific kind of +// value-type to the key, and implement write_value() to output +// the corresponding UCL. +class ManifestKey +{ +public: + std::string key; + + ManifestKey(const std::string& k) + : key(k) + { + } + + virtual ~ManifestKey() {} + + // Output the value associated with this key to the stream @p s. + // Format is to be decided by subclasses. + virtual void write_value(cmGeneratedFileStream& s) const = 0; +}; + +// Basic string-value (e.g. "name": "cmake") +class ManifestKeyValue : public ManifestKey +{ +public: + std::string value; + + ManifestKeyValue(const std::string& k, const std::string& v) + : ManifestKey(k) + , value(v) + { + } + + void write_value(cmGeneratedFileStream& s) const CM_OVERRIDE + { + s << EscapeQuotes(value); + } +}; + +// List-of-strings values (e.g. "licenses": ["GPLv2", "LGPLv2"]) +class ManifestKeyListValue : public ManifestKey +{ +public: + typedef std::vector<std::string> VList; + VList value; + + ManifestKeyListValue(const std::string& k) + : ManifestKey(k) + { + } + + ManifestKeyListValue& operator<<(const std::string& v) + { + value.push_back(v); + return *this; + } + + ManifestKeyListValue& operator<<(const std::vector<std::string>& v) + { + for (VList::const_iterator it = v.begin(); it != v.end(); ++it) { + (*this) << (*it); + } + return *this; + } + + void write_value(cmGeneratedFileStream& s) const CM_OVERRIDE + { + bool with_comma = false; + + s << '['; + for (VList::const_iterator it = value.begin(); it != value.end(); ++it) { + s << (with_comma ? ',' : ' '); + s << EscapeQuotes(*it); + with_comma = true; + } + s << " ]"; + } +}; + +// Deps: actually a dictionary, but we'll treat it as a +// list so we only name the deps, and produce dictionary- +// like output via write_value() +class ManifestKeyDepsValue : public ManifestKeyListValue +{ +public: + ManifestKeyDepsValue(const std::string& k) + : ManifestKeyListValue(k) + { + } + + void write_value(cmGeneratedFileStream& s) const CM_OVERRIDE + { + s << "{\n"; + for (VList::const_iterator it = value.begin(); it != value.end(); ++it) { + s << " \"" << *it << "\": {\"origin\": \"" << *it << "\"},\n"; + } + s << '}'; + } +}; + +// Write one of the key-value classes (above) to the stream @p s +cmGeneratedFileStream& operator<<(cmGeneratedFileStream& s, + const ManifestKey& v) +{ + s << '"' << v.key << "\": "; + v.write_value(s); + s << ",\n"; + return s; +} + +// Look up variable; if no value is set, returns an empty string; +// basically a wrapper that handles the NULL-ptr return from GetOption(). +std::string cmCPackFreeBSDGenerator::var_lookup(const char* var_name) +{ + const char* pv = this->GetOption(var_name); + if (!pv) { + return std::string(); + } else { + return pv; + } +} + +// Produce UCL in the given @p manifest file for the common +// manifest fields (common to the compact and regular formats), +// by reading the CPACK_FREEBSD_* variables. +void cmCPackFreeBSDGenerator::write_manifest_fields( + cmGeneratedFileStream& manifest) +{ + manifest << ManifestKeyValue("name", + var_lookup("CPACK_FREEBSD_PACKAGE_NAME")); + manifest << ManifestKeyValue("origin", + var_lookup("CPACK_FREEBSD_PACKAGE_ORIGIN")); + manifest << ManifestKeyValue("version", + var_lookup("CPACK_FREEBSD_PACKAGE_VERSION")); + manifest << ManifestKeyValue("maintainer", + var_lookup("CPACK_FREEBSD_PACKAGE_MAINTAINER")); + manifest << ManifestKeyValue("comment", + var_lookup("CPACK_FREEBSD_PACKAGE_COMMENT")); + manifest << ManifestKeyValue( + "desc", var_lookup("CPACK_FREEBSD_PACKAGE_DESCRIPTION")); + manifest << ManifestKeyValue("www", var_lookup("CPACK_FREEBSD_PACKAGE_WWW")); + std::vector<std::string> licenses; + cmSystemTools::ExpandListArgument( + var_lookup("CPACK_FREEBSD_PACKAGE_LICENSE"), licenses); + std::string licenselogic("single"); + if (licenses.size() < 1) { + cmSystemTools::SetFatalErrorOccured(); + } else if (licenses.size() > 1) { + licenselogic = var_lookup("CPACK_FREEBSD_PACKAGE_LICENSE_LOGIC"); + } + manifest << ManifestKeyValue("licenselogic", licenselogic); + manifest << (ManifestKeyListValue("licenses") << licenses); + std::vector<std::string> categories; + cmSystemTools::ExpandListArgument( + var_lookup("CPACK_FREEBSD_PACKAGE_CATEGORIES"), categories); + manifest << (ManifestKeyListValue("categories") << categories); + manifest << ManifestKeyValue("prefix", var_lookup("CMAKE_INSTALL_PREFIX")); + std::vector<std::string> deps; + cmSystemTools::ExpandListArgument(var_lookup("CPACK_FREEBSD_PACKAGE_DEPS"), + deps); + if (deps.size() > 0) { + manifest << (ManifestKeyDepsValue("deps") << deps); + } +} + +// Package only actual files; others are ignored (in particular, +// intermediate subdirectories are ignored). +static bool ignore_file(const std::string& filename) +{ + struct stat statbuf; + + if (!((stat(filename.c_str(), &statbuf) >= 0) && + ((statbuf.st_mode & S_IFMT) == S_IFREG))) { + return true; + } + // May be other reasons to return false + return false; +} + +// Write the given list of @p files to the manifest stream @p s, +// as the UCL field "files" (which is dictionary-valued, to +// associate filenames with hashes). All the files are transformed +// to paths relative to @p toplevel, with a leading / (since the paths +// in FreeBSD package files are supposed to be absolute). +void write_manifest_files(cmGeneratedFileStream& s, + const std::string& toplevel, + const std::vector<std::string>& files) +{ + const char* c_toplevel = toplevel.c_str(); + std::vector<std::string>::const_iterator it; + + s << "\"files\": {\n"; + for (it = files.begin(); it != files.end(); ++it) { + s << " \"/" << cmSystemTools::RelativePath(c_toplevel, it->c_str()) + << "\": \"" + << "<sha256>" + << "\",\n"; + } + s << " },\n"; +} + +static bool has_suffix(const std::string& str, const std::string& suffix) +{ + return str.size() >= suffix.size() && + str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0; +} + +int cmCPackFreeBSDGenerator::PackageFiles() +{ + if (!this->ReadListFile("CPackFreeBSD.cmake")) { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Error while execution CPackFreeBSD.cmake" << std::endl); + return 0; + } + + std::vector<std::string>::const_iterator fileIt; + std::string dir = cmSystemTools::GetCurrentWorkingDirectory(); + cmSystemTools::ChangeDirectory(toplevel); + + files.erase(std::remove_if(files.begin(), files.end(), ignore_file), + files.end()); + + std::string manifestname = toplevel + "/+MANIFEST"; + { + cmGeneratedFileStream manifest(manifestname.c_str()); + manifest << "{\n"; + write_manifest_fields(manifest); + write_manifest_files(manifest, toplevel, files); + manifest << "}\n"; + } + + cmCPackLogger(cmCPackLog::LOG_DEBUG, "Toplevel: " << toplevel << std::endl); + + if (WantsComponentInstallation()) { + // CASE 1 : COMPONENT ALL-IN-ONE package + // If ALL COMPONENTS in ONE package has been requested + // then the package file is unique and should be open here. + if (componentPackageMethod == ONE_PACKAGE) { + return PackageComponentsAllInOne(); + } + // CASE 2 : COMPONENT CLASSICAL package(s) (i.e. not all-in-one) + // There will be 1 package for each component group + // however one may require to ignore component group and + // in this case you'll get 1 package for each component. + return PackageComponents(componentPackageMethod == + ONE_PACKAGE_PER_COMPONENT); + } + + std::string output_dir = + cmSystemTools::CollapseCombinedPath(toplevel, "../"); + pkg_create_from_manifest(output_dir.c_str(), ::TXZ, toplevel.c_str(), + manifestname.c_str(), NULL); + + std::string broken_suffix = std::string("-") + + var_lookup("CPACK_TOPLEVEL_TAG") + std::string(GetOutputExtension()); + for (std::vector<std::string>::iterator it = packageFileNames.begin(); + it != packageFileNames.end(); ++it) { + cmCPackLogger(cmCPackLog::LOG_DEBUG, "Packagefile " << *it << std::endl); + if (has_suffix(*it, broken_suffix)) { + it->replace(it->size() - broken_suffix.size(), std::string::npos, + GetOutputExtension()); + break; + } + } + + cmSystemTools::ChangeDirectory(dir); + return 1; +} diff --git a/Source/CPack/cmCPackFreeBSDGenerator.h b/Source/CPack/cmCPackFreeBSDGenerator.h new file mode 100644 index 0000000..230f728 --- /dev/null +++ b/Source/CPack/cmCPackFreeBSDGenerator.h @@ -0,0 +1,37 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#ifndef cmCPackFreeBSDGenerator_h +#define cmCPackFreeBSDGenerator_h + +#include <cmConfigure.h> + +#include "cmCPackArchiveGenerator.h" +#include "cmCPackGenerator.h" + +class cmGeneratedFileStream; + +/** \class cmCPackFreeBSDGenerator + * \brief A generator for FreeBSD package files (TXZ with a manifest) + * + */ +class cmCPackFreeBSDGenerator : public cmCPackArchiveGenerator +{ +public: + cmCPackTypeMacro(cmCPackFreeBSDGenerator, cmCPackArchiveGenerator); + /** + * Construct generator + */ + cmCPackFreeBSDGenerator(); + ~cmCPackFreeBSDGenerator() CM_OVERRIDE; + + int InitializeInternal() CM_OVERRIDE; + int PackageFiles() CM_OVERRIDE; + +protected: + const char* GetOutputExtension() CM_OVERRIDE { return ".txz"; } + + std::string var_lookup(const char* var_name); + void write_manifest_fields(cmGeneratedFileStream&); +}; + +#endif diff --git a/Source/CPack/cmCPackGeneratorFactory.cxx b/Source/CPack/cmCPackGeneratorFactory.cxx index 31f48c7..834913d 100644 --- a/Source/CPack/cmCPackGeneratorFactory.cxx +++ b/Source/CPack/cmCPackGeneratorFactory.cxx @@ -9,6 +9,10 @@ #include "IFW/cmCPackIFWGenerator.h" #include "cmAlgorithms.h" #include "cmCPack7zGenerator.h" +#ifdef HAVE_FREEBSD_PKG +#include "cmCPackFreeBSDGenerator.h" +#endif +#include "cmCPackDebGenerator.h" #include "cmCPackGenerator.h" #include "cmCPackLog.h" #include "cmCPackNSISGenerator.h" @@ -34,7 +38,6 @@ #if !defined(_WIN32) && !defined(__QNXNTO__) && !defined(__BEOS__) && \ !defined(__HAIKU__) -#include "cmCPackDebGenerator.h" #include "cmCPackRPMGenerator.h" #endif @@ -99,6 +102,10 @@ cmCPackGeneratorFactory::cmCPackGeneratorFactory() this->RegisterGenerator("TZ", "Tar Compress compression", cmCPackTarCompressGenerator::CreateGenerator); } + if (cmCPackDebGenerator::CanGenerate()) { + this->RegisterGenerator("DEB", "Debian packages", + cmCPackDebGenerator::CreateGenerator); + } #ifdef __APPLE__ if (cmCPackDragNDropGenerator::CanGenerate()) { this->RegisterGenerator("DragNDrop", "Mac OSX Drag And Drop", @@ -123,15 +130,17 @@ cmCPackGeneratorFactory::cmCPackGeneratorFactory() #endif #if !defined(_WIN32) && !defined(__QNXNTO__) && !defined(__BEOS__) && \ !defined(__HAIKU__) - if (cmCPackDebGenerator::CanGenerate()) { - this->RegisterGenerator("DEB", "Debian packages", - cmCPackDebGenerator::CreateGenerator); - } if (cmCPackRPMGenerator::CanGenerate()) { this->RegisterGenerator("RPM", "RPM packages", cmCPackRPMGenerator::CreateGenerator); } #endif +#ifdef HAVE_FREEBSD_PKG + if (cmCPackFreeBSDGenerator::CanGenerate()) { + this->RegisterGenerator("FREEBSD", "FreeBSD pkg(8) packages", + cmCPackFreeBSDGenerator::CreateGenerator); + } +#endif } cmCPackGeneratorFactory::~cmCPackGeneratorFactory() diff --git a/Source/CPack/cmCPackOSXX11Generator.h b/Source/CPack/cmCPackOSXX11Generator.h index 0eebc6d..0a1770c 100644 --- a/Source/CPack/cmCPackOSXX11Generator.h +++ b/Source/CPack/cmCPackOSXX11Generator.h @@ -23,7 +23,7 @@ public: * Construct generator */ cmCPackOSXX11Generator(); - virtual ~cmCPackOSXX11Generator(); + ~cmCPackOSXX11Generator() CM_OVERRIDE; protected: virtual int InitializeInternal() CM_OVERRIDE; diff --git a/Source/CPack/cmCPackPKGGenerator.h b/Source/CPack/cmCPackPKGGenerator.h index f873c59..d9461ee 100644 --- a/Source/CPack/cmCPackPKGGenerator.h +++ b/Source/CPack/cmCPackPKGGenerator.h @@ -27,7 +27,7 @@ public: * Construct generator */ cmCPackPKGGenerator(); - virtual ~cmCPackPKGGenerator(); + ~cmCPackPKGGenerator() CM_OVERRIDE; bool SupportsComponentInstallation() const CM_OVERRIDE; diff --git a/Source/CPack/cmCPackPackageMakerGenerator.h b/Source/CPack/cmCPackPackageMakerGenerator.h index 6274515..770f434 100644 --- a/Source/CPack/cmCPackPackageMakerGenerator.h +++ b/Source/CPack/cmCPackPackageMakerGenerator.h @@ -25,7 +25,7 @@ public: * Construct generator */ cmCPackPackageMakerGenerator(); - virtual ~cmCPackPackageMakerGenerator(); + ~cmCPackPackageMakerGenerator() CM_OVERRIDE; bool SupportsComponentInstallation() const CM_OVERRIDE; protected: diff --git a/Source/CPack/cmCPackProductBuildGenerator.h b/Source/CPack/cmCPackProductBuildGenerator.h index 12093a0..3435641 100644 --- a/Source/CPack/cmCPackProductBuildGenerator.h +++ b/Source/CPack/cmCPackProductBuildGenerator.h @@ -25,7 +25,7 @@ public: * Construct generator */ cmCPackProductBuildGenerator(); - virtual ~cmCPackProductBuildGenerator(); + ~cmCPackProductBuildGenerator() CM_OVERRIDE; protected: int InitializeInternal() CM_OVERRIDE; diff --git a/Source/QtDialog/CMakeSetupDialog.cxx b/Source/QtDialog/CMakeSetupDialog.cxx index 57f8e10..5290afe 100644 --- a/Source/QtDialog/CMakeSetupDialog.cxx +++ b/Source/QtDialog/CMakeSetupDialog.cxx @@ -1195,7 +1195,7 @@ void CMakeSetupDialog::setSearchFilter(const QString& str) this->CacheValues->setSearchFilter(str); } -void CMakeSetupDialog::doOutputContextMenu(const QPoint& pt) +void CMakeSetupDialog::doOutputContextMenu(QPoint pt) { QMenu* menu = this->Output->createStandardContextMenu(); diff --git a/Source/QtDialog/CMakeSetupDialog.h b/Source/QtDialog/CMakeSetupDialog.h index 1abdb46..0da28d8 100644 --- a/Source/QtDialog/CMakeSetupDialog.h +++ b/Source/QtDialog/CMakeSetupDialog.h @@ -70,7 +70,7 @@ protected slots: bool doConfigureInternal(); bool doGenerateInternal(); void exitLoop(int); - void doOutputContextMenu(const QPoint&); + void doOutputContextMenu(QPoint pt); void doOutputFindDialog(); void doOutputFindNext(bool directionForward = true); void doOutputFindPrev(); diff --git a/Source/QtDialog/FirstConfigure.cxx b/Source/QtDialog/FirstConfigure.cxx index b193a27..88ce7cb 100644 --- a/Source/QtDialog/FirstConfigure.cxx +++ b/Source/QtDialog/FirstConfigure.cxx @@ -301,7 +301,7 @@ QString CrossCompilerSetup::getFindRoot() const void CrossCompilerSetup::setFindRoot(const QString& t) { - return this->crossFindRoot->setText(t); + this->crossFindRoot->setText(t); } int CrossCompilerSetup::getProgramMode() const diff --git a/Source/cmCMakeHostSystemInformationCommand.cxx b/Source/cmCMakeHostSystemInformationCommand.cxx index 4475c5a..5106f52 100644 --- a/Source/cmCMakeHostSystemInformationCommand.cxx +++ b/Source/cmCMakeHostSystemInformationCommand.cxx @@ -76,6 +76,55 @@ bool cmCMakeHostSystemInformationCommand::GetValue( value = this->ValueToString(info.GetTotalPhysicalMemory()); } else if (key == "AVAILABLE_PHYSICAL_MEMORY") { value = this->ValueToString(info.GetAvailablePhysicalMemory()); + } else if (key == "IS_64BIT") { + value = this->ValueToString(info.Is64Bits()); + } else if (key == "HAS_FPU") { + value = this->ValueToString( + info.DoesCPUSupportFeature(cmsys::SystemInformation::CPU_FEATURE_FPU)); + } else if (key == "HAS_MMX") { + value = this->ValueToString( + info.DoesCPUSupportFeature(cmsys::SystemInformation::CPU_FEATURE_MMX)); + } else if (key == "HAS_MMX_PLUS") { + value = this->ValueToString(info.DoesCPUSupportFeature( + cmsys::SystemInformation::CPU_FEATURE_MMX_PLUS)); + } else if (key == "HAS_SSE") { + value = this->ValueToString( + info.DoesCPUSupportFeature(cmsys::SystemInformation::CPU_FEATURE_SSE)); + } else if (key == "HAS_SSE2") { + value = this->ValueToString( + info.DoesCPUSupportFeature(cmsys::SystemInformation::CPU_FEATURE_SSE2)); + } else if (key == "HAS_SSE_FP") { + value = this->ValueToString(info.DoesCPUSupportFeature( + cmsys::SystemInformation::CPU_FEATURE_SSE_FP)); + } else if (key == "HAS_SSE_MMX") { + value = this->ValueToString(info.DoesCPUSupportFeature( + cmsys::SystemInformation::CPU_FEATURE_SSE_MMX)); + } else if (key == "HAS_AMD_3DNOW") { + value = this->ValueToString(info.DoesCPUSupportFeature( + cmsys::SystemInformation::CPU_FEATURE_AMD_3DNOW)); + } else if (key == "HAS_AMD_3DNOW_PLUS") { + value = this->ValueToString(info.DoesCPUSupportFeature( + cmsys::SystemInformation::CPU_FEATURE_AMD_3DNOW_PLUS)); + } else if (key == "HAS_IA64") { + value = this->ValueToString( + info.DoesCPUSupportFeature(cmsys::SystemInformation::CPU_FEATURE_IA64)); + } else if (key == "HAS_SERIAL_NUMBER") { + value = this->ValueToString(info.DoesCPUSupportFeature( + cmsys::SystemInformation::CPU_FEATURE_SERIALNUMBER)); + } else if (key == "PROCESSOR_NAME") { + value = this->ValueToString(info.GetExtendedProcessorName()); + } else if (key == "PROCESSOR_DESCRIPTION") { + value = info.GetCPUDescription(); + } else if (key == "PROCESSOR_SERIAL_NUMBER") { + value = this->ValueToString(info.GetProcessorSerialNumber()); + } else if (key == "OS_NAME") { + value = this->ValueToString(info.GetOSName()); + } else if (key == "OS_RELEASE") { + value = this->ValueToString(info.GetOSRelease()); + } else if (key == "OS_VERSION") { + value = this->ValueToString(info.GetOSVersion()); + } else if (key == "OS_PLATFORM") { + value = this->ValueToString(info.GetOSPlatform()); #ifdef HAVE_VS_SETUP_HELPER } else if (key == "VS_15_DIR") { cmVSSetupAPIHelper vsSetupAPIHelper; diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx index e1d8ef1..485dd50 100644 --- a/Source/cmCommands.cxx +++ b/Source/cmCommands.cxx @@ -42,6 +42,7 @@ #include "cmIfCommand.h" #include "cmIncludeCommand.h" #include "cmIncludeDirectoryCommand.h" +#include "cmIncludeGuardCommand.h" #include "cmIncludeRegularExpressionCommand.h" #include "cmInstallCommand.h" #include "cmInstallFilesCommand.h" @@ -132,6 +133,7 @@ void GetScriptingCommands(cmState* state) state->AddBuiltinCommand("get_property", new cmGetPropertyCommand); state->AddBuiltinCommand("if", new cmIfCommand); state->AddBuiltinCommand("include", new cmIncludeCommand); + state->AddBuiltinCommand("include_guard", new cmIncludeGuardCommand); state->AddBuiltinCommand("list", new cmListCommand); state->AddBuiltinCommand("macro", new cmMacroCommand); state->AddBuiltinCommand("make_directory", new cmMakeDirectoryCommand); diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx index 391d65c..6a007c8 100644 --- a/Source/cmCommonTargetGenerator.cxx +++ b/Source/cmCommonTargetGenerator.cxx @@ -22,10 +22,11 @@ cmCommonTargetGenerator::cmCommonTargetGenerator(cmGeneratorTarget* gt) : GeneratorTarget(gt) , Makefile(gt->Makefile) - , LocalGenerator(static_cast<cmLocalCommonGenerator*>(gt->LocalGenerator)) - , GlobalGenerator(static_cast<cmGlobalCommonGenerator*>( + , LocalCommonGenerator( + static_cast<cmLocalCommonGenerator*>(gt->LocalGenerator)) + , GlobalCommonGenerator(static_cast<cmGlobalCommonGenerator*>( gt->LocalGenerator->GetGlobalGenerator())) - , ConfigName(LocalGenerator->GetConfigName()) + , ConfigName(LocalCommonGenerator->GetConfigName()) { } @@ -62,10 +63,10 @@ void cmCommonTargetGenerator::AddModuleDefinitionFlag( // Append the flag and value. Use ConvertToLinkReference to help // vs6's "cl -link" pass it to the linker. std::string flag = defFileFlag; - flag += this->LocalGenerator->ConvertToOutputFormat( + flag += this->LocalCommonGenerator->ConvertToOutputFormat( linkLineComputer->ConvertToLinkReference(mdi->DefFile), cmOutputConverter::SHELL); - this->LocalGenerator->AppendFlags(flags, flag); + this->LocalCommonGenerator->AppendFlags(flags, flag); } void cmCommonTargetGenerator::AppendFortranFormatFlags( @@ -90,8 +91,8 @@ void cmCommonTargetGenerator::AppendFortranFormatFlags( break; } if (var) { - this->LocalGenerator->AppendFlags(flags, - this->Makefile->GetDefinition(var)); + this->LocalCommonGenerator->AppendFlags( + flags, this->Makefile->GetDefinition(var)); } } @@ -101,8 +102,8 @@ std::string cmCommonTargetGenerator::GetFlags(const std::string& l) if (i == this->FlagsByLanguage.end()) { std::string flags; - this->LocalGenerator->GetTargetCompileFlags(this->GeneratorTarget, - this->ConfigName, l, flags); + this->LocalCommonGenerator->GetTargetCompileFlags( + this->GeneratorTarget, this->ConfigName, l, flags); ByLanguageMap::value_type entry(l, flags); i = this->FlagsByLanguage.insert(entry).first; @@ -115,11 +116,11 @@ std::string cmCommonTargetGenerator::GetDefines(const std::string& l) ByLanguageMap::iterator i = this->DefinesByLanguage.find(l); if (i == this->DefinesByLanguage.end()) { std::set<std::string> defines; - this->LocalGenerator->GetTargetDefines(this->GeneratorTarget, - this->ConfigName, l, defines); + this->LocalCommonGenerator->GetTargetDefines(this->GeneratorTarget, + this->ConfigName, l, defines); std::string definesString; - this->LocalGenerator->JoinDefines(defines, definesString, l); + this->LocalCommonGenerator->JoinDefines(defines, definesString, l); ByLanguageMap::value_type entry(l, definesString); i = this->DefinesByLanguage.insert(entry).first; @@ -198,9 +199,10 @@ std::string cmCommonTargetGenerator::GetManifests() std::vector<std::string> manifests; for (std::vector<cmSourceFile const*>::iterator mi = manifest_srcs.begin(); mi != manifest_srcs.end(); ++mi) { - manifests.push_back(this->LocalGenerator->ConvertToOutputFormat( - this->LocalGenerator->ConvertToRelativePath( - this->LocalGenerator->GetWorkingDirectory(), (*mi)->GetFullPath()), + manifests.push_back(this->LocalCommonGenerator->ConvertToOutputFormat( + this->LocalCommonGenerator->ConvertToRelativePath( + this->LocalCommonGenerator->GetWorkingDirectory(), + (*mi)->GetFullPath()), cmOutputConverter::SHELL)); } @@ -233,6 +235,6 @@ void cmCommonTargetGenerator::AppendOSXVerFlag(std::string& flags, // Append the flag since a non-zero version is specified. std::ostringstream vflag; vflag << flag << major << "." << minor << "." << patch; - this->LocalGenerator->AppendFlags(flags, vflag.str()); + this->LocalCommonGenerator->AppendFlags(flags, vflag.str()); } } diff --git a/Source/cmCommonTargetGenerator.h b/Source/cmCommonTargetGenerator.h index c36145f..6b0f74e 100644 --- a/Source/cmCommonTargetGenerator.h +++ b/Source/cmCommonTargetGenerator.h @@ -37,8 +37,8 @@ protected: cmGeneratorTarget* GeneratorTarget; cmMakefile* Makefile; - cmLocalCommonGenerator* LocalGenerator; - cmGlobalCommonGenerator* GlobalGenerator; + cmLocalCommonGenerator* LocalCommonGenerator; + cmGlobalCommonGenerator* GlobalCommonGenerator; std::string ConfigName; void AppendFortranFormatFlags(std::string& flags, diff --git a/Source/cmExecuteProcessCommand.cxx b/Source/cmExecuteProcessCommand.cxx index 8c10dbe..435adca 100644 --- a/Source/cmExecuteProcessCommand.cxx +++ b/Source/cmExecuteProcessCommand.cxx @@ -7,6 +7,7 @@ #include <sstream> #include <stdio.h> +#include "cmAlgorithms.h" #include "cmMakefile.h" #include "cmProcessOutput.h" #include "cmSystemTools.h" @@ -46,6 +47,7 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args, std::string output_variable; std::string error_variable; std::string result_variable; + std::string results_variable; std::string working_directory; cmProcessOutput::Encoding encoding = cmProcessOutput::None; for (size_t i = 0; i < args.size(); ++i) { @@ -77,6 +79,14 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args, this->SetError(" called with no value for RESULT_VARIABLE."); return false; } + } else if (args[i] == "RESULTS_VARIABLE") { + doing_command = false; + if (++i < args.size()) { + results_variable = args[i]; + } else { + this->SetError(" called with no value for RESULTS_VARIABLE."); + return false; + } } else if (args[i] == "WORKING_DIRECTORY") { doing_command = false; if (++i < args.size()) { @@ -287,7 +297,7 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args, switch (cmsysProcess_GetState(cp)) { case cmsysProcess_State_Exited: { int v = cmsysProcess_GetExitValue(cp); - char buf[100]; + char buf[16]; sprintf(buf, "%d", v); this->Makefile->AddDefinition(result_variable, buf); } break; @@ -305,6 +315,47 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args, break; } } + // Store the result of running the processes. + if (!results_variable.empty()) { + switch (cmsysProcess_GetState(cp)) { + case cmsysProcess_State_Exited: { + std::vector<std::string> res; + for (size_t i = 0; i < cmds.size(); ++i) { + switch (cmsysProcess_GetStateByIndex(cp, static_cast<int>(i))) { + case kwsysProcess_StateByIndex_Exited: { + int exitCode = + cmsysProcess_GetExitValueByIndex(cp, static_cast<int>(i)); + char buf[16]; + sprintf(buf, "%d", exitCode); + res.push_back(buf); + } break; + case kwsysProcess_StateByIndex_Exception: + res.push_back(cmsysProcess_GetExceptionStringByIndex( + cp, static_cast<int>(i))); + break; + case kwsysProcess_StateByIndex_Error: + default: + res.push_back("Error getting the child return code"); + break; + } + } + this->Makefile->AddDefinition(results_variable, + cmJoin(res, ";").c_str()); + } break; + case cmsysProcess_State_Exception: + this->Makefile->AddDefinition(results_variable, + cmsysProcess_GetExceptionString(cp)); + break; + case cmsysProcess_State_Error: + this->Makefile->AddDefinition(results_variable, + cmsysProcess_GetErrorString(cp)); + break; + case cmsysProcess_State_Expired: + this->Makefile->AddDefinition(results_variable, + "Process terminated due to timeout"); + break; + } + } // Delete the process instance. cmsysProcess_Delete(cp); diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index 5777fb2..b769a56 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -55,14 +55,14 @@ class cmSystemToolsFileTime; static mode_t mode_owner_read = S_IREAD; static mode_t mode_owner_write = S_IWRITE; static mode_t mode_owner_execute = S_IEXEC; -static mode_t mode_group_read = 0; -static mode_t mode_group_write = 0; -static mode_t mode_group_execute = 0; -static mode_t mode_world_read = 0; -static mode_t mode_world_write = 0; -static mode_t mode_world_execute = 0; -static mode_t mode_setuid = 0; -static mode_t mode_setgid = 0; +static mode_t mode_group_read = 040; +static mode_t mode_group_write = 020; +static mode_t mode_group_execute = 010; +static mode_t mode_world_read = 04; +static mode_t mode_world_write = 02; +static mode_t mode_world_execute = 01; +static mode_t mode_setuid = 04000; +static mode_t mode_setgid = 02000; #else static mode_t mode_owner_read = S_IRUSR; static mode_t mode_owner_write = S_IWUSR; @@ -1076,11 +1076,26 @@ protected: bool SetPermissions(const char* toFile, mode_t permissions) { - if (permissions && !cmSystemTools::SetPermissions(toFile, permissions)) { - std::ostringstream e; - e << this->Name << " cannot set permissions on \"" << toFile << "\""; - this->FileCommand->SetError(e.str()); - return false; + if (permissions) { +#ifdef WIN32 + if (Makefile->IsOn("CMAKE_CROSSCOMPILING")) { + std::string mode_t_adt_filename = + std::string(toFile) + ":cmake_mode_t"; + + cmsys::ofstream permissionStream(mode_t_adt_filename.c_str()); + + if (permissionStream) { + permissionStream << std::oct << permissions << std::endl; + } + } +#endif + + if (!cmSystemTools::SetPermissions(toFile, permissions)) { + std::ostringstream e; + e << this->Name << " cannot set permissions on \"" << toFile << "\""; + this->FileCommand->SetError(e.str()); + return false; + } } return true; } diff --git a/Source/cmGeneratorExpressionEvaluationFile.cxx b/Source/cmGeneratorExpressionEvaluationFile.cxx index 1526454..5003e8d 100644 --- a/Source/cmGeneratorExpressionEvaluationFile.cxx +++ b/Source/cmGeneratorExpressionEvaluationFile.cxx @@ -20,11 +20,13 @@ cmGeneratorExpressionEvaluationFile::cmGeneratorExpressionEvaluationFile( const std::string& input, CM_AUTO_PTR<cmCompiledGeneratorExpression> outputFileExpr, - CM_AUTO_PTR<cmCompiledGeneratorExpression> condition, bool inputIsContent) + CM_AUTO_PTR<cmCompiledGeneratorExpression> condition, bool inputIsContent, + cmPolicies::PolicyStatus policyStatusCMP0070) : Input(input) , OutputFileExpr(outputFileExpr) , Condition(condition) , InputIsContent(inputIsContent) + , PolicyStatusCMP0070(policyStatusCMP0070) { } @@ -51,11 +53,17 @@ void cmGeneratorExpressionEvaluationFile::Generate( } } - const std::string outputFileName = this->OutputFileExpr->Evaluate( + std::string outputFileName = this->OutputFileExpr->Evaluate( lg, config, false, CM_NULLPTR, CM_NULLPTR, CM_NULLPTR, lang); const std::string outputContent = inputExpression->Evaluate( lg, config, false, CM_NULLPTR, CM_NULLPTR, CM_NULLPTR, lang); + if (cmSystemTools::FileIsFullPath(outputFileName)) { + outputFileName = cmSystemTools::CollapseFullPath(outputFileName); + } else { + outputFileName = this->FixRelativePath(outputFileName, PathForOutput, lg); + } + std::map<std::string, std::string>::iterator it = outputFiles.find(outputFileName); @@ -111,12 +119,18 @@ void cmGeneratorExpressionEvaluationFile::Generate(cmLocalGenerator* lg) if (this->InputIsContent) { inputContent = this->Input; } else { - lg->GetMakefile()->AddCMakeDependFile(this->Input); - cmSystemTools::GetPermissions(this->Input.c_str(), perm); - cmsys::ifstream fin(this->Input.c_str()); + std::string inputFileName = this->Input; + if (cmSystemTools::FileIsFullPath(inputFileName)) { + inputFileName = cmSystemTools::CollapseFullPath(inputFileName); + } else { + inputFileName = this->FixRelativePath(inputFileName, PathForInput, lg); + } + lg->GetMakefile()->AddCMakeDependFile(inputFileName); + cmSystemTools::GetPermissions(inputFileName.c_str(), perm); + cmsys::ifstream fin(inputFileName.c_str()); if (!fin) { std::ostringstream e; - e << "Evaluation file \"" << this->Input << "\" cannot be read."; + e << "Evaluation file \"" << inputFileName << "\" cannot be read."; lg->IssueMessage(cmake::FATAL_ERROR, e.str()); return; } @@ -159,3 +173,57 @@ void cmGeneratorExpressionEvaluationFile::Generate(cmLocalGenerator* lg) } } } + +std::string cmGeneratorExpressionEvaluationFile::FixRelativePath( + std::string const& relativePath, PathRole role, cmLocalGenerator* lg) +{ + std::string resultPath; + switch (this->PolicyStatusCMP0070) { + case cmPolicies::WARN: { + std::string arg; + switch (role) { + case PathForInput: + arg = "INPUT"; + break; + case PathForOutput: + arg = "OUTPUT"; + break; + } + std::ostringstream w; + /* clang-format off */ + w << + cmPolicies::GetPolicyWarning(cmPolicies::CMP0070) << "\n" + "file(GENERATE) given relative " << arg << " path:\n" + " " << relativePath << "\n" + "This is not defined behavior unless CMP0070 is set to NEW. " + "For compatibility with older versions of CMake, the previous " + "undefined behavior will be used." + ; + /* clang-format on */ + lg->IssueMessage(cmake::AUTHOR_WARNING, w.str()); + } + CM_FALLTHROUGH; + case cmPolicies::OLD: + // OLD behavior is to use the relative path unchanged, + // which ends up being used relative to the working dir. + resultPath = relativePath; + break; + case cmPolicies::REQUIRED_IF_USED: + case cmPolicies::REQUIRED_ALWAYS: + case cmPolicies::NEW: + // NEW behavior is to interpret the relative path with respect + // to the current source or binary directory. + switch (role) { + case PathForInput: + resultPath = cmSystemTools::CollapseFullPath( + relativePath, lg->GetCurrentSourceDirectory()); + break; + case PathForOutput: + resultPath = cmSystemTools::CollapseFullPath( + relativePath, lg->GetCurrentBinaryDirectory()); + break; + } + break; + } + return resultPath; +} diff --git a/Source/cmGeneratorExpressionEvaluationFile.h b/Source/cmGeneratorExpressionEvaluationFile.h index 9872746..ecf919d 100644 --- a/Source/cmGeneratorExpressionEvaluationFile.h +++ b/Source/cmGeneratorExpressionEvaluationFile.h @@ -10,6 +10,7 @@ #include <vector> #include "cmGeneratorExpression.h" +#include "cmPolicies.h" #include "cm_auto_ptr.hxx" #include "cm_sys_stat.h" @@ -21,7 +22,8 @@ public: cmGeneratorExpressionEvaluationFile( const std::string& input, CM_AUTO_PTR<cmCompiledGeneratorExpression> outputFileExpr, - CM_AUTO_PTR<cmCompiledGeneratorExpression> condition, bool inputIsContent); + CM_AUTO_PTR<cmCompiledGeneratorExpression> condition, bool inputIsContent, + cmPolicies::PolicyStatus policyStatusCMP0070); void Generate(cmLocalGenerator* lg); @@ -35,12 +37,21 @@ private: cmCompiledGeneratorExpression* inputExpression, std::map<std::string, std::string>& outputFiles, mode_t perm); + enum PathRole + { + PathForInput, + PathForOutput + }; + std::string FixRelativePath(std::string const& filePath, PathRole role, + cmLocalGenerator* lg); + private: const std::string Input; const CM_AUTO_PTR<cmCompiledGeneratorExpression> OutputFileExpr; const CM_AUTO_PTR<cmCompiledGeneratorExpression> Condition; std::vector<std::string> Files; const bool InputIsContent; + cmPolicies::PolicyStatus PolicyStatusCMP0070; }; #endif diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 099f705..37a2759 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -90,7 +90,7 @@ cmGlobalGenerator::cmGlobalGenerator(cmake* cm) this->TryCompileTimeout = 0; this->ExtraGenerator = CM_NULLPTR; - this->CurrentMakefile = CM_NULLPTR; + this->CurrentConfigureMakefile = CM_NULLPTR; this->TryCompileOuterMakefile = CM_NULLPTR; this->ConfigureDoneCMP0026AndCMP0024 = false; @@ -490,7 +490,6 @@ void cmGlobalGenerator::EnableLanguage( windowsVersionString << osviex.dwMajorVersion << "." << osviex.dwMinorVersion << "." << osviex.dwBuildNumber; - windowsVersionString.str(); mf->AddDefinition("CMAKE_HOST_SYSTEM_VERSION", windowsVersionString.str().c_str()); #endif @@ -1075,7 +1074,7 @@ bool cmGlobalGenerator::GetLanguageEnabled(const std::string& l) const void cmGlobalGenerator::ClearEnabledLanguages() { - return this->CMakeInstance->GetState()->ClearEnabledLanguages(); + this->CMakeInstance->GetState()->ClearEnabledLanguages(); } void cmGlobalGenerator::CreateLocalGenerators() diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 871178b..23c6218 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -187,9 +187,15 @@ public: return this->LocalGenerators; } - cmMakefile* GetCurrentMakefile() const { return this->CurrentMakefile; } + cmMakefile* GetCurrentMakefile() const + { + return this->CurrentConfigureMakefile; + } - void SetCurrentMakefile(cmMakefile* mf) { this->CurrentMakefile = mf; } + void SetCurrentMakefile(cmMakefile* mf) + { + this->CurrentConfigureMakefile = mf; + } void AddMakefile(cmMakefile* mf); @@ -460,7 +466,7 @@ protected: cmake* CMakeInstance; std::vector<cmMakefile*> Makefiles; std::vector<cmLocalGenerator*> LocalGenerators; - cmMakefile* CurrentMakefile; + cmMakefile* CurrentConfigureMakefile; // map from project name to vector of local generators in that project std::map<std::string, std::vector<cmLocalGenerator*> > ProjectMap; diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx index 0e02b0a..e3835ff 100644 --- a/Source/cmGlobalVisualStudio10Generator.cxx +++ b/Source/cmGlobalVisualStudio10Generator.cxx @@ -130,6 +130,7 @@ cmGlobalVisualStudio10Generator::cmGlobalVisualStudio10Generator( this->DefaultNasmFlagTable = cmVS10NASMFlagTable; this->DefaultRcFlagTable = cmVS10RCFlagTable; this->Version = VS10; + this->PlatformToolsetNeedsDebugEnum = false; } bool cmGlobalVisualStudio10Generator::MatchesGeneratorName( @@ -195,6 +196,24 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset( return false; } + if (cmHasLiteralPrefix(this->GetPlatformToolsetString(), "v140")) { + // The GenerateDebugInformation link setting for the v140 toolset + // in VS 2015 was originally an enum with "No" and "Debug" values, + // differing from the "false" and "true" values used in older toolsets. + // A VS 2015 update changed it back. Parse the "link.xml" file to + // discover which one we need. + std::string const link_xml = this->VCTargetsPath + "/1033/link.xml"; + cmsys::ifstream fin(link_xml.c_str()); + std::string line; + while (fin && cmSystemTools::GetLineFromStream(fin, line)) { + if (line.find(" Switch=\"DEBUG\" ") != std::string::npos) { + this->PlatformToolsetNeedsDebugEnum = + line.find(" Name=\"Debug\" ") != std::string::npos; + break; + } + } + } + if (this->GeneratorToolsetCuda.empty()) { // Find the highest available version of the CUDA tools. std::vector<std::string> cudaTools; diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h index 20f992a..4a5c245 100644 --- a/Source/cmGlobalVisualStudio10Generator.h +++ b/Source/cmGlobalVisualStudio10Generator.h @@ -59,6 +59,13 @@ public: const char* GetPlatformToolsetCuda() const; std::string const& GetPlatformToolsetCudaString() const; + /** Return whether we need to use No/Debug instead of false/true + for GenerateDebugInformation. */ + bool GetPlatformToolsetNeedsDebugEnum() const + { + return this->PlatformToolsetNeedsDebugEnum; + } + /** Return the CMAKE_SYSTEM_NAME. */ std::string const& GetSystemName() const { return this->SystemName; } @@ -169,6 +176,8 @@ private: virtual std::string FindDevEnvCommand(); virtual std::string GetVSMakeProgram() { return this->GetMSBuildCommand(); } + bool PlatformToolsetNeedsDebugEnum; + bool ParseGeneratorToolset(std::string const& ts, cmMakefile* mf); std::string VCTargetsPath; diff --git a/Source/cmGlobalVisualStudio14Generator.cxx b/Source/cmGlobalVisualStudio14Generator.cxx index df086d3..c8cf02c 100644 --- a/Source/cmGlobalVisualStudio14Generator.cxx +++ b/Source/cmGlobalVisualStudio14Generator.cxx @@ -8,8 +8,8 @@ #include "cmMakefile.h" #include "cmVS140CLFlagTable.h" #include "cmVS140CSharpFlagTable.h" +#include "cmVS140LinkFlagTable.h" #include "cmVS14LibFlagTable.h" -#include "cmVS14LinkFlagTable.h" #include "cmVS14MASMFlagTable.h" #include "cmVS14RCFlagTable.h" @@ -93,7 +93,7 @@ cmGlobalVisualStudio14Generator::cmGlobalVisualStudio14Generator( this->DefaultClFlagTable = cmVS140CLFlagTable; this->DefaultCSharpFlagTable = cmVS140CSharpFlagTable; this->DefaultLibFlagTable = cmVS14LibFlagTable; - this->DefaultLinkFlagTable = cmVS14LinkFlagTable; + this->DefaultLinkFlagTable = cmVS140LinkFlagTable; this->DefaultMasmFlagTable = cmVS14MASMFlagTable; this->DefaultRcFlagTable = cmVS14RCFlagTable; this->Version = VS14; diff --git a/Source/cmGlobalVisualStudio15Generator.cxx b/Source/cmGlobalVisualStudio15Generator.cxx index da2bf8c..ce1ba00 100644 --- a/Source/cmGlobalVisualStudio15Generator.cxx +++ b/Source/cmGlobalVisualStudio15Generator.cxx @@ -8,6 +8,7 @@ #include "cmMakefile.h" #include "cmVS141CLFlagTable.h" #include "cmVS141CSharpFlagTable.h" +#include "cmVS141LinkFlagTable.h" #include "cmVSSetupHelper.h" static const char vs15generatorName[] = "Visual Studio 15 2017"; @@ -85,6 +86,7 @@ cmGlobalVisualStudio15Generator::cmGlobalVisualStudio15Generator( this->DefaultPlatformToolset = "v141"; this->DefaultClFlagTable = cmVS141CLFlagTable; this->DefaultCSharpFlagTable = cmVS141CSharpFlagTable; + this->DefaultLinkFlagTable = cmVS141LinkFlagTable; this->Version = VS15; } diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 9037961..4be3c80 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -3298,6 +3298,31 @@ void cmGlobalXCodeGenerator::OutputXCodeProject( void cmGlobalXCodeGenerator::OutputXCodeSharedSchemes( const std::string& xcProjDir) { + // collect all tests for the targets + std::map<std::string, cmXCodeScheme::TestObjects> testables; + + for (std::vector<cmXCodeObject*>::const_iterator i = + this->XCodeObjects.begin(); + i != this->XCodeObjects.end(); ++i) { + cmXCodeObject* obj = *i; + if (obj->GetType() != cmXCodeObject::OBJECT || + obj->GetIsA() != cmXCodeObject::PBXNativeTarget) { + continue; + } + + if (!obj->GetTarget()->IsXCTestOnApple()) { + continue; + } + + const char* testee = obj->GetTarget()->GetProperty("XCTEST_TESTEE"); + if (!testee) { + continue; + } + + testables[testee].push_back(obj); + } + + // generate scheme for (std::vector<cmXCodeObject*>::const_iterator i = this->XCodeObjects.begin(); i != this->XCodeObjects.end(); ++i) { @@ -3305,8 +3330,9 @@ void cmGlobalXCodeGenerator::OutputXCodeSharedSchemes( if (obj->GetType() == cmXCodeObject::OBJECT && (obj->GetIsA() == cmXCodeObject::PBXNativeTarget || obj->GetIsA() == cmXCodeObject::PBXAggregateTarget)) { - cmXCodeScheme schm(obj, this->CurrentConfigurationTypes, - this->XcodeVersion); + const std::string& targetName = obj->GetTarget()->GetName(); + cmXCodeScheme schm(obj, testables[targetName], + this->CurrentConfigurationTypes, this->XcodeVersion); schm.WriteXCodeSharedScheme(xcProjDir, this->RelativeToSource(xcProjDir.c_str())); } diff --git a/Source/cmIncludeGuardCommand.cxx b/Source/cmIncludeGuardCommand.cxx new file mode 100644 index 0000000..505b07c --- /dev/null +++ b/Source/cmIncludeGuardCommand.cxx @@ -0,0 +1,108 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmIncludeGuardCommand.h" + +#include "cmExecutionStatus.h" +#include "cmMakefile.h" +#include "cmStateDirectory.h" +#include "cmStateSnapshot.h" +#include "cmSystemTools.h" +#include "cmake.h" + +namespace { + +enum IncludeGuardScope +{ + VARIABLE, + DIRECTORY, + GLOBAL +}; + +std::string GetIncludeGuardVariableName(std::string const& filePath) +{ + std::string result = "__INCGUARD_"; +#ifdef CMAKE_BUILD_WITH_CMAKE + result += cmSystemTools::ComputeStringMD5(filePath); +#else + result += cmSystemTools::MakeCidentifier(filePath); +#endif + result += "__"; + return result; +} + +bool CheckIncludeGuardIsSet(cmMakefile* mf, std::string const& includeGuardVar) +{ + if (mf->GetProperty(includeGuardVar)) { + return true; + } + cmStateSnapshot dirSnapshot = + mf->GetStateSnapshot().GetBuildsystemDirectoryParent(); + while (dirSnapshot.GetState()) { + cmStateDirectory stateDir = dirSnapshot.GetDirectory(); + if (stateDir.GetProperty(includeGuardVar)) { + return true; + } + dirSnapshot = dirSnapshot.GetBuildsystemDirectoryParent(); + } + return false; +} + +} // anonymous namespace + +// cmIncludeGuardCommand +bool cmIncludeGuardCommand::InitialPass(std::vector<std::string> const& args, + cmExecutionStatus& status) +{ + if (args.size() > 1) { + this->SetError( + "given an invalid number of arguments. The command takes at " + "most 1 argument."); + return false; + } + + IncludeGuardScope scope = VARIABLE; + + if (!args.empty()) { + std::string const& arg = args[0]; + if (arg == "DIRECTORY") { + scope = DIRECTORY; + } else if (arg == "GLOBAL") { + scope = GLOBAL; + } else { + this->SetError("given an invalid scope: " + arg); + return false; + } + } + + std::string includeGuardVar = GetIncludeGuardVariableName( + this->Makefile->GetDefinition("CMAKE_CURRENT_LIST_FILE")); + + cmMakefile* const mf = this->Makefile; + + switch (scope) { + case VARIABLE: + if (mf->IsDefinitionSet(includeGuardVar)) { + status.SetReturnInvoked(); + return true; + } + mf->AddDefinition(includeGuardVar, true); + break; + case DIRECTORY: + if (CheckIncludeGuardIsSet(mf, includeGuardVar)) { + status.SetReturnInvoked(); + return true; + } + mf->SetProperty(includeGuardVar, "TRUE"); + break; + case GLOBAL: + cmake* const cm = mf->GetCMakeInstance(); + if (cm->GetProperty(includeGuardVar)) { + status.SetReturnInvoked(); + return true; + } + cm->SetProperty(includeGuardVar, "TRUE"); + break; + } + + return true; +} diff --git a/Source/cmIncludeGuardCommand.h b/Source/cmIncludeGuardCommand.h new file mode 100644 index 0000000..140c04f --- /dev/null +++ b/Source/cmIncludeGuardCommand.h @@ -0,0 +1,37 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#ifndef cmIncludeGuardCommand_h +#define cmIncludeGuardCommand_h + +#include "cmConfigure.h" + +#include <string> +#include <vector> + +#include "cmCommand.h" + +class cmExecutionStatus; + +/** \class cmIncludeGuardCommand + * \brief cmIncludeGuardCommand identical to C++ #pragma_once command + * Can work in 3 modes: GLOBAL (works on global properties), + * DIRECTORY(use directory property), VARIABLE(unnamed overload without + * arguments) define an ordinary variable to be used as include guard checker + */ +class cmIncludeGuardCommand : public cmCommand +{ +public: + /** + * This is a virtual constructor for the command. + */ + cmCommand* Clone() CM_OVERRIDE { return new cmIncludeGuardCommand; } + + /** + * This is called when the command is first encountered in + * the CMakeLists.txt file. + */ + bool InitialPass(std::vector<std::string> const& args, + cmExecutionStatus& status) CM_OVERRIDE; +}; + +#endif diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 8e00303..9049a42 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -451,6 +451,19 @@ void cmLocalGenerator::GenerateInstallRules() /* clang-format on */ } + // Copy cmake cross compile state to install code. + if (const char* crosscompiling = + this->Makefile->GetDefinition("CMAKE_CROSSCOMPILING")) { + /* clang-format off */ + fout << + "# Is this installation the result of a crosscompile?\n" + "if(NOT DEFINED CMAKE_CROSSCOMPILING)\n" + " set(CMAKE_CROSSCOMPILING \"" << crosscompiling << "\")\n" + "endif()\n" + "\n"; + /* clang-format on */ + } + // Ask each install generator to write its code. std::vector<cmInstallGenerator*> const& installers = this->Makefile->GetInstallGenerators(); diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 608b18a..4a0cab3 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -592,7 +592,8 @@ void cmMakefile::AddEvaluationFile( CM_AUTO_PTR<cmCompiledGeneratorExpression> condition, bool inputIsContent) { this->EvaluationFiles.push_back(new cmGeneratorExpressionEvaluationFile( - inputFile, outputName, condition, inputIsContent)); + inputFile, outputName, condition, inputIsContent, + this->GetPolicyStatus(cmPolicies::CMP0070))); } std::vector<cmGeneratorExpressionEvaluationFile*> diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index a4511b6..7938683 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -657,7 +657,8 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile( } // Maybe insert a compiler launcher like ccache or distcc - if (!compileCommands.empty() && (lang == "C" || lang == "CXX")) { + if (!compileCommands.empty() && + (lang == "C" || lang == "CXX" || lang == "CUDA")) { std::string const clauncher_prop = lang + "_COMPILER_LAUNCHER"; const char* clauncher = this->GeneratorTarget->GetProperty(clauncher_prop); diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 14a4ef8..1e0bf8d 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -409,10 +409,14 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile) this->GetLocalGenerator()->ConvertToOutputFormat( cmSystemTools::GetCMakeCommand(), cmOutputConverter::SHELL); if (targetType == cmStateEnums::EXECUTABLE) { + std::vector<std::string> commandLines; + commandLines.push_back(cmakeCommand + + " -E cmake_symlink_executable $in $out"); + commandLines.push_back("$POST_BUILD"); + this->GetGlobalGenerator()->AddRule( "CMAKE_SYMLINK_EXECUTABLE", - cmakeCommand + " -E cmake_symlink_executable" - " $in $out && $POST_BUILD", + this->GetLocalGenerator()->BuildCommandLine(commandLines), "Creating executable symlink $out", "Rule for creating " "executable symlink.", /*depfile*/ "", @@ -422,10 +426,14 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile) /*restat*/ "", /*generator*/ false); } else { + std::vector<std::string> commandLines; + commandLines.push_back(cmakeCommand + + " -E cmake_symlink_library $in $SONAME $out"); + commandLines.push_back("$POST_BUILD"); + this->GetGlobalGenerator()->AddRule( "CMAKE_SYMLINK_LIBRARY", - cmakeCommand + " -E cmake_symlink_library" - " $in $SONAME $out && $POST_BUILD", + this->GetLocalGenerator()->BuildCommandLine(commandLines), "Creating library symlink $out", "Rule for creating " "library symlink.", /*depfile*/ "", diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 2f4cccb..7c57ef0 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -648,7 +648,8 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang) } // Maybe insert a compiler launcher like ccache or distcc - if (!compileCmds.empty() && (lang == "C" || lang == "CXX")) { + if (!compileCmds.empty() && + (lang == "C" || lang == "CXX" || lang == "CUDA")) { std::string const clauncher_prop = lang + "_COMPILER_LAUNCHER"; const char* clauncher = this->GeneratorTarget->GetProperty(clauncher_prop); if (clauncher && *clauncher) { diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index 69cbc18..0a0178c 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -206,6 +206,9 @@ class cmMakefile; cmPolicies::WARN) \ SELECT(POLICY, CMP0069, \ "INTERPROCEDURAL_OPTIMIZATION is enforced when enabled.", 3, 9, 0, \ + cmPolicies::WARN) \ + SELECT(POLICY, CMP0070, \ + "Define file(GENERATE) behavior for relative paths.", 3, 10, 0, \ cmPolicies::WARN) #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1) diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx index 27e4928..7f0bd86 100644 --- a/Source/cmQtAutoGenerators.cxx +++ b/Source/cmQtAutoGenerators.cxx @@ -281,9 +281,11 @@ cmQtAutoGenerators::cmQtAutoGenerators() // Moc macro filters this->MocMacroFilters[0].first = "Q_OBJECT"; - this->MocMacroFilters[0].second.compile("[\n][ \t]*Q_OBJECT[^a-zA-Z0-9_]"); + this->MocMacroFilters[0].second.compile( + "[\n][ \t]*{?[ \t]*Q_OBJECT[^a-zA-Z0-9_]"); this->MocMacroFilters[1].first = "Q_GADGET"; - this->MocMacroFilters[1].second.compile("[\n][ \t]*Q_GADGET[^a-zA-Z0-9_]"); + this->MocMacroFilters[1].second.compile( + "[\n][ \t]*{?[ \t]*Q_GADGET[^a-zA-Z0-9_]"); // Precompile regular expressions this->MocRegExpInclude.compile( diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index c95a3ca..c1b6f97 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -276,6 +276,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, this->SetPropertyDefault("CUDA_STANDARD", CM_NULLPTR); this->SetPropertyDefault("CUDA_STANDARD_REQUIRED", CM_NULLPTR); this->SetPropertyDefault("CUDA_EXTENSIONS", CM_NULLPTR); + this->SetPropertyDefault("CUDA_COMPILER_LAUNCHER", CM_NULLPTR); this->SetPropertyDefault("LINK_SEARCH_START_STATIC", CM_NULLPTR); this->SetPropertyDefault("LINK_SEARCH_END_STATIC", CM_NULLPTR); } diff --git a/Source/cmVS10CSharpFlagTable.h b/Source/cmVS10CSharpFlagTable.h index 493ec2b..18d587c 100644 --- a/Source/cmVS10CSharpFlagTable.h +++ b/Source/cmVS10CSharpFlagTable.h @@ -25,7 +25,8 @@ static cmVS7FlagTable cmVS10CSharpFlagTable[] = { { "ApplicationIcon", "win32icon", "", "", cmIDEFlagTable::UserValueRequired }, - { "Win32Manifest", "win32manifest:", "", "true", 0 }, + { "ApplicationManifest", "win32manifest:", "", "", + cmIDEFlagTable::UserValueRequired }, { "NoWin32Manifest", "nowin32manifest", "", "true", 0 }, diff --git a/Source/cmVS11CSharpFlagTable.h b/Source/cmVS11CSharpFlagTable.h index 71870b6..e3ba83c 100644 --- a/Source/cmVS11CSharpFlagTable.h +++ b/Source/cmVS11CSharpFlagTable.h @@ -25,7 +25,8 @@ static cmVS7FlagTable cmVS11CSharpFlagTable[] = { { "ApplicationIcon", "win32icon", "", "", cmIDEFlagTable::UserValueRequired }, - { "Win32Manifest", "win32manifest:", "", "true", 0 }, + { "ApplicationManifest", "win32manifest:", "", "", + cmIDEFlagTable::UserValueRequired }, { "NoWin32Manifest", "nowin32manifest", "", "true", 0 }, diff --git a/Source/cmVS12CSharpFlagTable.h b/Source/cmVS12CSharpFlagTable.h index f98b184..f8db636 100644 --- a/Source/cmVS12CSharpFlagTable.h +++ b/Source/cmVS12CSharpFlagTable.h @@ -25,7 +25,8 @@ static cmVS7FlagTable cmVS12CSharpFlagTable[] = { { "ApplicationIcon", "win32icon", "", "", cmIDEFlagTable::UserValueRequired }, - { "Win32Manifest", "win32manifest:", "", "true", 0 }, + { "ApplicationManifest", "win32manifest:", "", "", + cmIDEFlagTable::UserValueRequired }, { "NoWin32Manifest", "nowin32manifest", "", "true", 0 }, diff --git a/Source/cmVS140CSharpFlagTable.h b/Source/cmVS140CSharpFlagTable.h index 256c35f..055d5cb 100644 --- a/Source/cmVS140CSharpFlagTable.h +++ b/Source/cmVS140CSharpFlagTable.h @@ -25,7 +25,8 @@ static cmVS7FlagTable cmVS140CSharpFlagTable[] = { { "ApplicationIcon", "win32icon", "", "", cmIDEFlagTable::UserValueRequired }, - { "Win32Manifest", "win32manifest:", "", "true", 0 }, + { "ApplicationManifest", "win32manifest:", "", "", + cmIDEFlagTable::UserValueRequired }, { "NoWin32Manifest", "nowin32manifest", "", "true", 0 }, diff --git a/Source/cmVS14LinkFlagTable.h b/Source/cmVS140LinkFlagTable.h index 596f880..ceb1d78 100644 --- a/Source/cmVS14LinkFlagTable.h +++ b/Source/cmVS140LinkFlagTable.h @@ -1,4 +1,4 @@ -static cmVS7FlagTable cmVS14LinkFlagTable[] = { +static cmVS7FlagTable cmVS140LinkFlagTable[] = { // Enum Properties { "ShowProgress", "", "Not Set", "NotSet", 0 }, @@ -38,7 +38,12 @@ static cmVS7FlagTable cmVS14LinkFlagTable[] = { { "GenerateDebugInformation", "DEBUG:FASTLINK", "Optimize for faster linking", "DebugFastLink", cmVS7FlagTable::CaseInsensitive }, - { "GenerateDebugInformation", "DEBUG", "Optimize for debugging", "Debug", + { "GenerateDebugInformation", "DEBUG:FULL", "Optimize for debugging", "true", + cmVS7FlagTable::CaseInsensitive }, + { "GenerateDebugInformation", "DEBUG:NONE", + "Produces no debugging information", "false", + cmVS7FlagTable::CaseInsensitive }, + { "GenerateDebugInformation", "DEBUG", "Optimize for debugging", "true", cmVS7FlagTable::CaseInsensitive }, { "SubSystem", "", "Not Set", "NotSet", 0 }, diff --git a/Source/cmVS141CSharpFlagTable.h b/Source/cmVS141CSharpFlagTable.h index 8508581..5de9bf3 100644 --- a/Source/cmVS141CSharpFlagTable.h +++ b/Source/cmVS141CSharpFlagTable.h @@ -25,7 +25,8 @@ static cmVS7FlagTable cmVS141CSharpFlagTable[] = { { "ApplicationIcon", "win32icon", "", "", cmIDEFlagTable::UserValueRequired }, - { "Win32Manifest", "win32manifest:", "", "true", 0 }, + { "ApplicationManifest", "win32manifest:", "", "", + cmIDEFlagTable::UserValueRequired }, { "NoWin32Manifest", "nowin32manifest", "", "true", 0 }, diff --git a/Source/cmVS141LinkFlagTable.h b/Source/cmVS141LinkFlagTable.h new file mode 100644 index 0000000..d7faf81 --- /dev/null +++ b/Source/cmVS141LinkFlagTable.h @@ -0,0 +1,286 @@ +static cmVS7FlagTable cmVS141LinkFlagTable[] = { + + // Enum Properties + { "ShowProgress", "", "Not Set", "NotSet", 0 }, + { "ShowProgress", "VERBOSE", "Display all progress messages", "LinkVerbose", + 0 }, + { "ShowProgress", "VERBOSE:Lib", "For Libraries Searched", "LinkVerboseLib", + 0 }, + { "ShowProgress", "VERBOSE:ICF", + "About COMDAT folding during optimized linking", "LinkVerboseICF", 0 }, + { "ShowProgress", "VERBOSE:REF", + "About data removed during optimized linking", "LinkVerboseREF", 0 }, + { "ShowProgress", "VERBOSE:SAFESEH", "About Modules incompatible with SEH", + "LinkVerboseSAFESEH", 0 }, + { "ShowProgress", "VERBOSE:CLR", + "About linker activity related to managed code", "LinkVerboseCLR", 0 }, + + { "ForceFileOutput", "FORCE", "Enabled", "Enabled", 0 }, + { "ForceFileOutput", "FORCE:MULTIPLE", "Multiply Defined Symbol Only", + "MultiplyDefinedSymbolOnly", 0 }, + { "ForceFileOutput", "FORCE:UNRESOLVED", "Undefined Symbol Only", + "UndefinedSymbolOnly", 0 }, + + { "CreateHotPatchableImage", "FUNCTIONPADMIN", "Enabled", "Enabled", 0 }, + { "CreateHotPatchableImage", "FUNCTIONPADMIN:5", "X86 Image Only", + "X86Image", 0 }, + { "CreateHotPatchableImage", "FUNCTIONPADMIN:6", "X64 Image Only", + "X64Image", 0 }, + { "CreateHotPatchableImage", "FUNCTIONPADMIN:16", "Itanium Image Only", + "ItaniumImage", 0 }, + + { "UACExecutionLevel", "level='asInvoker'", "asInvoker", "AsInvoker", 0 }, + { "UACExecutionLevel", "level='highestAvailable'", "highestAvailable", + "HighestAvailable", 0 }, + { "UACExecutionLevel", "level='requireAdministrator'", + "requireAdministrator", "RequireAdministrator", 0 }, + + { "GenerateDebugInformation", "DEBUG:FASTLINK", + "Generate Debug Information optimized for faster links", "DebugFastLink", + cmVS7FlagTable::CaseInsensitive }, + { "GenerateDebugInformation", "DEBUG:FULL", + "Generate Debug Information optimized for sharing and publishing", + "DebugFull", cmVS7FlagTable::CaseInsensitive }, + { "GenerateDebugInformation", "DEBUG:NONE", + "Produces no debugging information", "false", + cmVS7FlagTable::CaseInsensitive }, + { "GenerateDebugInformation", "DEBUG", "Generate Debug Information", "true", + cmVS7FlagTable::CaseInsensitive }, + + { "SubSystem", "", "Not Set", "NotSet", 0 }, + { "SubSystem", "SUBSYSTEM:CONSOLE", "Console", "Console", 0 }, + { "SubSystem", "SUBSYSTEM:WINDOWS", "Windows", "Windows", 0 }, + { "SubSystem", "SUBSYSTEM:NATIVE", "Native", "Native", 0 }, + { "SubSystem", "SUBSYSTEM:EFI_APPLICATION", "EFI Application", + "EFI Application", 0 }, + { "SubSystem", "SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER", + "EFI Boot Service Driver", "EFI Boot Service Driver", 0 }, + { "SubSystem", "SUBSYSTEM:EFI_ROM", "EFI ROM", "EFI ROM", 0 }, + { "SubSystem", "SUBSYSTEM:EFI_RUNTIME_DRIVER", "EFI Runtime", "EFI Runtime", + 0 }, + { "SubSystem", "SUBSYSTEM:POSIX", "POSIX", "POSIX", 0 }, + + { "Driver", "", "Not Set", "NotSet", 0 }, + { "Driver", "Driver", "Driver", "Driver", 0 }, + { "Driver", "DRIVER:UPONLY", "UP Only", "UpOnly", 0 }, + { "Driver", "DRIVER:WDM", "WDM", "WDM", 0 }, + + { "LinkTimeCodeGeneration", "", "Default", "Default", 0 }, + { "LinkTimeCodeGeneration", "LTCG:incremental", + "Use Fast Link Time Code Generation", "UseFastLinkTimeCodeGeneration", 0 }, + { "LinkTimeCodeGeneration", "LTCG", "Use Link Time Code Generation", + "UseLinkTimeCodeGeneration", 0 }, + { "LinkTimeCodeGeneration", "LTCG:PGInstrument", + "Profile Guided Optimization - Instrument", "PGInstrument", 0 }, + { "LinkTimeCodeGeneration", "LTCG:PGOptimize", + "Profile Guided Optimization - Optimization", "PGOptimization", 0 }, + { "LinkTimeCodeGeneration", "LTCG:PGUpdate", + "Profile Guided Optimization - Update", "PGUpdate", 0 }, + + { "GenerateWindowsMetadata", "WINMD", "Yes", "true", 0 }, + { "GenerateWindowsMetadata", "WINMD:NO", "No", "false", 0 }, + + { "WindowsMetadataSignHash", "WINMDSIGNHASH:SHA1", "SHA1", "SHA1", 0 }, + { "WindowsMetadataSignHash", "WINMDSIGNHASH:SHA256", "SHA256", "SHA256", 0 }, + { "WindowsMetadataSignHash", "WINMDSIGNHASH:SHA384", "SHA384", "SHA384", 0 }, + { "WindowsMetadataSignHash", "WINMDSIGNHASH:SHA512", "SHA512", "SHA512", 0 }, + + { "TargetMachine", "", "Not Set", "NotSet", 0 }, + { "TargetMachine", "MACHINE:ARM", "MachineARM", "MachineARM", 0 }, + { "TargetMachine", "MACHINE:EBC", "MachineEBC", "MachineEBC", 0 }, + { "TargetMachine", "MACHINE:IA64", "MachineIA64", "MachineIA64", 0 }, + { "TargetMachine", "MACHINE:MIPS", "MachineMIPS", "MachineMIPS", 0 }, + { "TargetMachine", "MACHINE:MIPS16", "MachineMIPS16", "MachineMIPS16", 0 }, + { "TargetMachine", "MACHINE:MIPSFPU", "MachineMIPSFPU", "MachineMIPSFPU", + 0 }, + { "TargetMachine", "MACHINE:MIPSFPU16", "MachineMIPSFPU16", + "MachineMIPSFPU16", 0 }, + { "TargetMachine", "MACHINE:SH4", "MachineSH4", "MachineSH4", 0 }, + { "TargetMachine", "MACHINE:THUMB", "MachineTHUMB", "MachineTHUMB", 0 }, + { "TargetMachine", "MACHINE:X64", "MachineX64", "MachineX64", 0 }, + { "TargetMachine", "MACHINE:X86", "MachineX86", "MachineX86", 0 }, + + { "CLRThreadAttribute", "CLRTHREADATTRIBUTE:MTA", "MTA threading attribute", + "MTAThreadingAttribute", 0 }, + { "CLRThreadAttribute", "CLRTHREADATTRIBUTE:STA", "STA threading attribute", + "STAThreadingAttribute", 0 }, + { "CLRThreadAttribute", "CLRTHREADATTRIBUTE:NONE", + "Default threading attribute", "DefaultThreadingAttribute", 0 }, + + { "CLRImageType", "CLRIMAGETYPE:IJW", "Force IJW image", "ForceIJWImage", + 0 }, + { "CLRImageType", "CLRIMAGETYPE:PURE", "Force Pure IL Image", + "ForcePureILImage", 0 }, + { "CLRImageType", "CLRIMAGETYPE:SAFE", "Force Safe IL Image", + "ForceSafeILImage", 0 }, + { "CLRImageType", "", "Default image type", "Default", 0 }, + + { "SignHash", "CLRSIGNHASH:SHA1", "SHA1", "SHA1", 0 }, + { "SignHash", "CLRSIGNHASH:SHA256", "SHA256", "SHA256", 0 }, + { "SignHash", "CLRSIGNHASH:SHA384", "SHA384", "SHA384", 0 }, + { "SignHash", "CLRSIGNHASH:SHA512", "SHA512", "SHA512", 0 }, + + { "LinkErrorReporting", "ERRORREPORT:PROMPT", "PromptImmediately", + "PromptImmediately", 0 }, + { "LinkErrorReporting", "ERRORREPORT:QUEUE", "Queue For Next Login", + "QueueForNextLogin", 0 }, + { "LinkErrorReporting", "ERRORREPORT:SEND", "Send Error Report", + "SendErrorReport", 0 }, + { "LinkErrorReporting", "ERRORREPORT:NONE", "No Error Report", + "NoErrorReport", 0 }, + + { "CLRSupportLastError", "CLRSupportLastError", "Enabled", "Enabled", 0 }, + { "CLRSupportLastError", "CLRSupportLastError:NO", "Disabled", "Disabled", + 0 }, + { "CLRSupportLastError", "CLRSupportLastError:SYSTEMDLL", "System Dlls Only", + "SystemDlls", 0 }, + + { "LinkControlFlowGuard", "guard:cf", "Enable Security Check with Guard", + "Guard", 0 }, + + // Bool Properties + { "LinkIncremental", "INCREMENTAL:NO", "", "false", 0 }, + { "LinkIncremental", "INCREMENTAL", "", "true", 0 }, + { "SuppressStartupBanner", "NOLOGO", "", "true", 0 }, + { "LinkStatus", "LTCG:NOSTATUS", "", "false", 0 }, + { "LinkStatus", "LTCG:STATUS", "", "true", 0 }, + { "PreventDllBinding", "ALLOWBIND:NO", "", "false", 0 }, + { "PreventDllBinding", "ALLOWBIND", "", "true", 0 }, + { "TreatLinkerWarningAsErrors", "WX:NO", "", "false", 0 }, + { "TreatLinkerWarningAsErrors", "WX", "", "true", 0 }, + { "IgnoreAllDefaultLibraries", "NODEFAULTLIB", "", "true", 0 }, + { "GenerateManifest", "MANIFEST:NO", "", "false", 0 }, + { "GenerateManifest", "MANIFEST", "", "true", 0 }, + { "AllowIsolation", "ALLOWISOLATION:NO", "", "false", 0 }, + { "UACUIAccess", "uiAccess='false'", "", "false", 0 }, + { "UACUIAccess", "uiAccess='true'", "", "true", 0 }, + { "ManifestEmbed", "manifest:embed", "", "true", 0 }, + { "MapExports", "MAPINFO:EXPORTS", "", "true", 0 }, + { "AssemblyDebug", "ASSEMBLYDEBUG:DISABLE", "", "false", 0 }, + { "AssemblyDebug", "ASSEMBLYDEBUG", "", "true", 0 }, + { "LargeAddressAware", "LARGEADDRESSAWARE:NO", "", "false", 0 }, + { "LargeAddressAware", "LARGEADDRESSAWARE", "", "true", 0 }, + { "TerminalServerAware", "TSAWARE:NO", "", "false", 0 }, + { "TerminalServerAware", "TSAWARE", "", "true", 0 }, + { "SwapRunFromCD", "SWAPRUN:CD", "", "true", 0 }, + { "SwapRunFromNET", "SWAPRUN:NET", "", "true", 0 }, + { "OptimizeReferences", "OPT:NOREF", "", "false", 0 }, + { "OptimizeReferences", "OPT:REF", "", "true", 0 }, + { "EnableCOMDATFolding", "OPT:NOICF", "", "false", 0 }, + { "EnableCOMDATFolding", "OPT:ICF", "", "true", 0 }, + { "IgnoreEmbeddedIDL", "IGNOREIDL", "", "true", 0 }, + { "AppContainer", "APPCONTAINER", "", "true", 0 }, + { "WindowsMetadataLinkDelaySign", "WINMDDELAYSIGN:NO", "", "false", 0 }, + { "WindowsMetadataLinkDelaySign", "WINMDDELAYSIGN", "", "true", 0 }, + { "NoEntryPoint", "NOENTRY", "", "true", 0 }, + { "SetChecksum", "RELEASE", "", "true", 0 }, + { "RandomizedBaseAddress", "DYNAMICBASE:NO", "", "false", 0 }, + { "RandomizedBaseAddress", "DYNAMICBASE", "", "true", 0 }, + { "FixedBaseAddress", "FIXED:NO", "", "false", 0 }, + { "FixedBaseAddress", "FIXED", "", "true", 0 }, + { "DataExecutionPrevention", "NXCOMPAT:NO", "", "false", 0 }, + { "DataExecutionPrevention", "NXCOMPAT", "", "true", 0 }, + { "TurnOffAssemblyGeneration", "NOASSEMBLY", "", "true", 0 }, + { "SupportUnloadOfDelayLoadedDLL", "DELAY:UNLOAD", "", "true", 0 }, + { "SupportNobindOfDelayLoadedDLL", "DELAY:NOBIND", "", "true", 0 }, + { "Profile", "PROFILE", "", "true", 0 }, + { "LinkDelaySign", "DELAYSIGN:NO", "", "false", 0 }, + { "LinkDelaySign", "DELAYSIGN", "", "true", 0 }, + { "CLRUnmanagedCodeCheck", "CLRUNMANAGEDCODECHECK:NO", "", "false", 0 }, + { "CLRUnmanagedCodeCheck", "CLRUNMANAGEDCODECHECK", "", "true", 0 }, + { "DetectOneDefinitionRule", "ODR", "", "true", 0 }, + { "ImageHasSafeExceptionHandlers", "SAFESEH:NO", "", "false", 0 }, + { "ImageHasSafeExceptionHandlers", "SAFESEH", "", "true", 0 }, + { "LinkDLL", "DLL", "", "true", 0 }, + + // Bool Properties With Argument + { "EnableUAC", "MANIFESTUAC:NO", "", "false", 0 }, + { "EnableUAC", "MANIFESTUAC:", "", "true", + cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue }, + { "UACUIAccess", "MANIFESTUAC:", "Enable User Account Control (UAC)", "", + cmVS7FlagTable::UserValueRequired }, + { "GenerateMapFile", "MAP", "", "true", + cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue }, + { "MapFileName", "MAP:", "Generate Map File", "", + cmVS7FlagTable::UserValueRequired }, + + // String List Properties + { "AdditionalLibraryDirectories", "LIBPATH:", + "Additional Library Directories", "", + cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable }, + { "Natvis", "NATVIS:", "Natvis files", "", + cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable }, + // Skip [AdditionalDependencies] - no command line Switch. + { "IgnoreSpecificDefaultLibraries", "NODEFAULTLIB:", + "Ignore Specific Default Libraries", "", + cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable }, + { "AddModuleNamesToAssembly", "ASSEMBLYMODULE:", "Add Module to Assembly", + "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable }, + { "EmbedManagedResourceFile", "ASSEMBLYRESOURCE:", + "Embed Managed Resource File", "", + cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable }, + { "ForceSymbolReferences", "INCLUDE:", "Force Symbol References", "", + cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable }, + { "DelayLoadDLLs", "DELAYLOAD:", "Delay Loaded Dlls", "", + cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable }, + { "AssemblyLinkResource", "ASSEMBLYLINKRESOURCE:", "Assembly Link Resource", + "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable }, + { "AdditionalManifestDependencies", "MANIFESTDEPENDENCY:", + "Additional Manifest Dependencies", "", + cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable }, + { "ManifestInput", "manifestinput:", "Manifest Input", "", + cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable }, + + // String Properties + { "OutputFile", "OUT:", "Output File", "", cmVS7FlagTable::UserValue }, + { "Version", "VERSION:", "Version", "", cmVS7FlagTable::UserValue }, + { "SpecifySectionAttributes", "SECTION:", "Specify Section Attributes", "", + cmVS7FlagTable::UserValue }, + { "MSDOSStubFileName", "STUB:", "MS-DOS Stub File Name", "", + cmVS7FlagTable::UserValue }, + // Skip [TrackerLogDirectory] - no command line Switch. + { "ModuleDefinitionFile", "DEF:", "Module Definition File", "", + cmVS7FlagTable::UserValue }, + { "ManifestFile", "ManifestFile:", "Manifest File", "", + cmVS7FlagTable::UserValue }, + { "ProgramDatabaseFile", "PDB:", "Generate Program Database File", "", + cmVS7FlagTable::UserValue }, + { "StripPrivateSymbols", "PDBSTRIPPED:", "Strip Private Symbols", "", + cmVS7FlagTable::UserValue }, + // Skip [MapFileName] - no command line Switch. + // Skip [MinimumRequiredVersion] - no command line Switch. + { "HeapReserveSize", "HEAP:", "Heap Reserve Size", "", + cmVS7FlagTable::UserValue }, + // Skip [HeapCommitSize] - no command line Switch. + { "StackReserveSize", "STACK:", "Stack Reserve Size", "", + cmVS7FlagTable::UserValue }, + // Skip [StackCommitSize] - no command line Switch. + { "FunctionOrder", "ORDER:@", "Function Order", "", + cmVS7FlagTable::UserValue }, + { "ProfileGuidedDatabase", "PGD:", "Profile Guided Database", "", + cmVS7FlagTable::UserValue }, + { "MidlCommandFile", "MIDL:@", "MIDL Commands", "", + cmVS7FlagTable::UserValue }, + { "MergedIDLBaseFileName", "IDLOUT:", "Merged IDL Base File Name", "", + cmVS7FlagTable::UserValue }, + { "TypeLibraryFile", "TLBOUT:", "Type Library", "", + cmVS7FlagTable::UserValue }, + { "WindowsMetadataFile", "WINMDFILE:", "Windows Metadata File", "", + cmVS7FlagTable::UserValue }, + { "WindowsMetadataLinkKeyFile", "WINMDKEYFILE:", "Windows Metadata Key File", + "", cmVS7FlagTable::UserValue }, + { "WindowsMetadataKeyContainer", "WINMDKEYCONTAINER:", + "Windows Metadata Key Container", "", cmVS7FlagTable::UserValue }, + { "EntryPointSymbol", "ENTRY:", "Entry Point", "", + cmVS7FlagTable::UserValue }, + { "BaseAddress", "BASE:", "Base Address", "", cmVS7FlagTable::UserValue }, + { "ImportLibrary", "IMPLIB:", "Import Library", "", + cmVS7FlagTable::UserValue }, + { "MergeSections", "MERGE:", "Merge Sections", "", + cmVS7FlagTable::UserValue }, + { "LinkKeyFile", "KEYFILE:", "Key File", "", cmVS7FlagTable::UserValue }, + { "KeyContainer", "KEYCONTAINER:", "Key Container", "", + cmVS7FlagTable::UserValue }, + // Skip [AdditionalOptions] - no command line Switch. + { 0, 0, 0, 0, 0 } +}; diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index de1f5b0..e4a4d6f 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -17,8 +17,6 @@ #include "cm_auto_ptr.hxx" -static std::string const kWINDOWS_7_1_SDK = "Windows7.1SDK"; - static std::string cmVS10EscapeXML(std::string arg) { cmSystemTools::ReplaceString(arg, "&", "&"); @@ -27,6 +25,12 @@ static std::string cmVS10EscapeXML(std::string arg) return arg; } +static std::string cmVS10EscapeQuotes(std::string arg) +{ + cmSystemTools::ReplaceString(arg, "\"", """); + return arg; +} + static std::string cmVS10EscapeComment(std::string comment) { // MSBuild takes the CDATA of a <Message></Message> element and just @@ -146,7 +150,7 @@ void cmVisualStudio10TargetGenerator::WritePlatformConfigTag( (*stream) << config << "|" << this->Platform; (*stream) << "'"; // handle special case for 32 bit C# targets - if (csproj == this->ProjectType && this->Platform == "Win32") { + if (this->ProjectType == csproj && this->Platform == "Win32") { (*stream) << " Or "; (*stream) << "'$(Configuration)|$(Platform)'=='"; (*stream) << config << "|x86"; @@ -294,7 +298,7 @@ void cmVisualStudio10TargetGenerator::Generate() this->WriteString("</PropertyGroup>\n", 1); } - if (csproj != this->ProjectType) { + if (this->ProjectType != csproj) { this->WriteProjectConfigurations(); } this->WriteString("<PropertyGroup Label=\"Globals\">\n", 1); @@ -311,7 +315,7 @@ void cmVisualStudio10TargetGenerator::Generate() this->GeneratorTarget->GetProperty("VS_GLOBAL_PROJECT_TYPES"); if (vsProjectTypes) { std::string tagName = "ProjectTypes"; - if (csproj == this->ProjectType) { + if (this->ProjectType == csproj) { tagName = "ProjectTypeGuids"; } this->WriteString("", 2); @@ -465,7 +469,7 @@ void cmVisualStudio10TargetGenerator::Generate() this->WriteProjectConfigurationValues(); - if (vcxproj == this->ProjectType) { + if (this->ProjectType == vcxproj) { this->WriteString("<Import Project=\"" VS10_CXX_PROPS "\" />\n", 1); } this->WriteString("<ImportGroup Label=\"ExtensionSettings\">\n", 1); @@ -568,7 +572,7 @@ void cmVisualStudio10TargetGenerator::Generate() this->WriteString(import.c_str(), 2); } this->WriteString("</ImportGroup>\n", 1); - if (csproj == this->ProjectType) { + if (this->ProjectType == csproj) { for (std::vector<std::string>::const_iterator i = this->Configurations.begin(); i != this->Configurations.end(); ++i) { @@ -578,6 +582,18 @@ void cmVisualStudio10TargetGenerator::Generate() this->WriteEvents(*i); this->WriteString("</PropertyGroup>\n", 1); } + // make sure custom commands are executed before build (if necessary) + this->WriteString("<PropertyGroup>\n", 1); + this->WriteString("<BuildDependsOn>\n", 2); + for (std::set<std::string>::const_iterator i = + this->CSharpCustomCommandNames.begin(); + i != this->CSharpCustomCommandNames.end(); ++i) { + this->WriteString(i->c_str(), 3); + (*this->BuildFileStream) << ";\n"; + } + this->WriteString("$(BuildDependsOn)\n", 3); + this->WriteString("</BuildDependsOn>\n", 2); + this->WriteString("</PropertyGroup>\n", 1); } this->WriteString("</Project>", 0); // The groups are stored in a separate file for VS 10 @@ -659,9 +675,39 @@ void cmVisualStudio10TargetGenerator::WriteDotNetReference( this->WriteString("<HintPath>", 3); (*this->BuildFileStream) << hint << "</HintPath>\n"; } + this->WriteDotNetReferenceCustomTags(ref); this->WriteString("</Reference>\n", 2); } +void cmVisualStudio10TargetGenerator::WriteDotNetReferenceCustomTags( + std::string const& ref) +{ + + static const std::string refpropPrefix = "VS_DOTNET_REFERENCEPROP_"; + static const std::string refpropInfix = "_TAG_"; + const std::string refPropFullPrefix = refpropPrefix + ref + refpropInfix; + typedef std::map<std::string, std::string> CustomTags; + CustomTags tags; + cmPropertyMap const& props = this->GeneratorTarget->Target->GetProperties(); + for (cmPropertyMap::const_iterator i = props.begin(); i != props.end(); + ++i) { + if (i->first.find(refPropFullPrefix) == 0) { + std::string refTag = i->first.substr(refPropFullPrefix.length()); + std::string refVal = i->second.GetValue(); + if (!refTag.empty() && !refVal.empty()) { + tags[refTag] = refVal; + } + } + } + for (CustomTags::const_iterator tag = tags.begin(); tag != tags.end(); + ++tag) { + this->WriteString("<", 3); + (*this->BuildFileStream) << tag->first << ">" + << cmVS10EscapeXML(tag->second) << "</" + << tag->first << ">\n"; + } +} + void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup() { std::vector<cmSourceFile const*> resxObjs; @@ -677,7 +723,7 @@ void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup() this->WriteString("<EmbeddedResource Include=\"", 2); this->ConvertToWindowsSlash(obj); bool useRelativePath = false; - if (csproj == this->ProjectType && this->InSourceBuild) { + if (this->ProjectType == csproj && this->InSourceBuild) { // If we do an in-source build and the resource file is in a // subdirectory // of the .csproj file, we have to use relative pathnames, otherwise @@ -690,7 +736,7 @@ void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup() } (*this->BuildFileStream) << obj << "\">\n"; - if (csproj != this->ProjectType) { + if (this->ProjectType != csproj) { this->WriteString("<DependentUpon>", 3); std::string hFileName = obj.substr(0, obj.find_last_of(".")) + ".h"; (*this->BuildFileStream) << hFileName << "</DependentUpon>\n"; @@ -800,7 +846,7 @@ void cmVisualStudio10TargetGenerator::WriteXamlFilesGroup() } this->WriteSource(xamlType, *oi, ">\n"); - if (csproj == this->ProjectType && !this->InSourceBuild) { + if (this->ProjectType == csproj && !this->InSourceBuild) { // add <Link> tag to written XAML source if necessary const std::string srcDir = this->Makefile->GetCurrentSourceDirectory(); const std::string binDir = this->Makefile->GetCurrentBinaryDirectory(); @@ -919,7 +965,7 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues() this->WritePlatformConfigTag("PropertyGroup", i->c_str(), 1, " Label=\"Configuration\"", "\n"); - if (csproj != this->ProjectType) { + if (this->ProjectType != csproj) { std::string configType = "<ConfigurationType>"; if (const char* vsConfigurationType = this->GeneratorTarget->GetProperty("VS_CONFIGURATION_TYPE")) { @@ -1121,6 +1167,7 @@ void cmVisualStudio10TargetGenerator::WriteNsightTegraConfigurationValues( void cmVisualStudio10TargetGenerator::WriteCustomCommands() { this->SourcesVisited.clear(); + this->CSharpCustomCommandNames.clear(); std::vector<cmSourceFile const*> customCommands; this->GeneratorTarget->GetCustomCommands(customCommands, ""); for (std::vector<cmSourceFile const*>::const_iterator si = @@ -1142,9 +1189,14 @@ void cmVisualStudio10TargetGenerator::WriteCustomCommand( } } if (cmCustomCommand const* command = sf->GetCustomCommand()) { - this->WriteString("<ItemGroup>\n", 1); + // C# projects write their <Target> within WriteCustomRule() + if (this->ProjectType != csproj) { + this->WriteString("<ItemGroup>\n", 1); + } this->WriteCustomRule(sf, *command); - this->WriteString("</ItemGroup>\n", 1); + if (this->ProjectType != csproj) { + this->WriteString("</ItemGroup>\n", 1); + } } } } @@ -1179,8 +1231,20 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule( } cmLocalVisualStudio7Generator* lg = this->LocalGenerator; - this->WriteSource("CustomBuild", source, ">\n"); - + if (this->ProjectType != csproj) { + this->WriteSource("CustomBuild", source, ">\n"); + } else { + this->WriteString("<ItemGroup>\n", 1); + std::string link; + this->GetCSharpSourceLink(source, link); + this->WriteSource("None", source, ">\n"); + if (!link.empty()) { + this->WriteString("<Link>", 3); + (*this->BuildFileStream) << link << "</Link>\n"; + } + this->WriteString("</None>\n", 2); + this->WriteString("</ItemGroup>\n", 1); + } for (std::vector<std::string>::const_iterator i = this->Configurations.begin(); i != this->Configurations.end(); ++i) { @@ -1188,41 +1252,91 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule( std::string comment = lg->ConstructComment(ccg); comment = cmVS10EscapeComment(comment); std::string script = cmVS10EscapeXML(lg->ConstructScript(ccg)); - this->WritePlatformConfigTag("Message", i->c_str(), 3); - (*this->BuildFileStream) << cmVS10EscapeXML(comment) << "</Message>\n"; - this->WritePlatformConfigTag("Command", i->c_str(), 3); - (*this->BuildFileStream) << script << "</Command>\n"; - this->WritePlatformConfigTag("AdditionalInputs", i->c_str(), 3); - - (*this->BuildFileStream) << cmVS10EscapeXML(source->GetFullPath()); + // input files for custom command + std::stringstream inputs; + inputs << cmVS10EscapeXML(source->GetFullPath()); for (std::vector<std::string>::const_iterator d = ccg.GetDepends().begin(); d != ccg.GetDepends().end(); ++d) { std::string dep; if (this->LocalGenerator->GetRealDependency(d->c_str(), i->c_str(), dep)) { this->ConvertToWindowsSlash(dep); - (*this->BuildFileStream) << ";" << cmVS10EscapeXML(dep); + inputs << ";" << cmVS10EscapeXML(dep); } } - (*this->BuildFileStream) << ";%(AdditionalInputs)</AdditionalInputs>\n"; - this->WritePlatformConfigTag("Outputs", i->c_str(), 3); + // output files for custom command + std::stringstream outputs; const char* sep = ""; for (std::vector<std::string>::const_iterator o = ccg.GetOutputs().begin(); o != ccg.GetOutputs().end(); ++o) { std::string out = *o; this->ConvertToWindowsSlash(out); - (*this->BuildFileStream) << sep << cmVS10EscapeXML(out); + outputs << sep << cmVS10EscapeXML(out); sep = ";"; } - (*this->BuildFileStream) << "</Outputs>\n"; - if (this->LocalGenerator->GetVersion() > - cmGlobalVisualStudioGenerator::VS10) { - // VS >= 11 let us turn off linking of custom command outputs. - this->WritePlatformConfigTag("LinkObjects", i->c_str(), 3); - (*this->BuildFileStream) << "false</LinkObjects>\n"; + if (this->ProjectType == csproj) { + std::string name = "CustomCommand_" + *i + "_" + + cmSystemTools::ComputeStringMD5(sourcePath); + std::string inputs_s = inputs.str(); + std::string outputs_s = outputs.str(); + comment = cmVS10EscapeQuotes(comment); + script = cmVS10EscapeQuotes(script); + inputs_s = cmVS10EscapeQuotes(inputs_s); + outputs_s = cmVS10EscapeQuotes(outputs_s); + this->WriteCustomRuleCSharp(*i, name, script, inputs_s, outputs_s, + comment); + } else { + this->WriteCustomRuleCpp(*i, script, inputs.str(), outputs.str(), + comment); } } - this->WriteString("</CustomBuild>\n", 2); + if (this->ProjectType != csproj) { + this->WriteString("</CustomBuild>\n", 2); + } +} + +void cmVisualStudio10TargetGenerator::WriteCustomRuleCpp( + std::string const& config, std::string const& script, + std::string const& inputs, std::string const& outputs, + std::string const& comment) +{ + this->WritePlatformConfigTag("Message", config, 3); + (*this->BuildFileStream) << cmVS10EscapeXML(comment) << "</Message>\n"; + this->WritePlatformConfigTag("Command", config, 3); + (*this->BuildFileStream) << script << "</Command>\n"; + this->WritePlatformConfigTag("AdditionalInputs", config, 3); + (*this->BuildFileStream) << inputs; + (*this->BuildFileStream) << ";%(AdditionalInputs)</AdditionalInputs>\n"; + this->WritePlatformConfigTag("Outputs", config, 3); + (*this->BuildFileStream) << outputs << "</Outputs>\n"; + if (this->LocalGenerator->GetVersion() > + cmGlobalVisualStudioGenerator::VS10) { + // VS >= 11 let us turn off linking of custom command outputs. + this->WritePlatformConfigTag("LinkObjects", config, 3); + (*this->BuildFileStream) << "false</LinkObjects>\n"; + } +} + +void cmVisualStudio10TargetGenerator::WriteCustomRuleCSharp( + std::string const& config, std::string const& name, + std::string const& script, std::string const& inputs, + std::string const& outputs, std::string const& comment) +{ + this->CSharpCustomCommandNames.insert(name); + std::stringstream attributes; + attributes << "\n Name=\"" << name << "\""; + attributes << "\n Inputs=\"" << inputs << "\""; + attributes << "\n Outputs=\"" << outputs << "\""; + this->WritePlatformConfigTag("Target", config, 1, attributes.str().c_str(), + "\n"); + if (!comment.empty()) { + this->WriteString("<Exec Command=\"", 2); + (*this->BuildFileStream) << "echo " << cmVS10EscapeXML(comment) + << "\" />\n"; + } + this->WriteString("<Exec Command=\"", 2); + (*this->BuildFileStream) << script << "\" />\n"; + this->WriteString("</Target>\n", 1); } std::string cmVisualStudio10TargetGenerator::ConvertPath( @@ -1245,7 +1359,7 @@ void cmVisualStudio10TargetGenerator::ConvertToWindowsSlash(std::string& s) } void cmVisualStudio10TargetGenerator::WriteGroups() { - if (csproj == this->ProjectType) { + if (this->ProjectType == csproj) { return; } @@ -1487,7 +1601,7 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(cmSourceFile const* sf) std::string copyToOutDir; std::string includeInVsix; std::string ext = cmSystemTools::LowerCase(sf->GetExtension()); - if (csproj == this->ProjectType) { + if (this->ProjectType == csproj) { // EVERY extra source file must have a <Link>, otherwise it might not // be visible in Visual Studio at all. The path relative to current // source- or binary-dir is used within the link, if the file is @@ -1566,6 +1680,10 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(cmSourceFile const* sf) toolHasSettings = true; } + // Collect VS_CSHARP_* property values (if some are set) + std::map<std::string, std::string> sourceFileTags; + this->GetCSharpSourceProperties(sf, sourceFileTags); + if (this->NsightTegra) { // Nsight Tegra needs specific file types to check up-to-dateness. std::string name = cmSystemTools::LowerCase(sf->GetLocation().GetName()); @@ -1682,7 +1800,8 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(cmSourceFile const* sf) (*this->BuildFileStream) << cmVS10EscapeXML(includeInVsix) << "</IncludeInVSIX>\n"; } - + // write source file specific tags + this->WriteCSharpSourceProperties(sourceFileTags); this->WriteString("</", 2); (*this->BuildFileStream) << tool << ">\n"; } else { @@ -2004,48 +2123,23 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags( std::string xamlFileName = fileName.substr(0, fileName.find_last_of(".")); (*this->BuildFileStream) << xamlFileName << "</DependentUpon>\n"; } - if (csproj == this->ProjectType) { + if (this->ProjectType == csproj) { std::string f = source->GetFullPath(); typedef std::map<std::string, std::string> CsPropMap; CsPropMap sourceFileTags; // set <Link> tag if necessary - if (!this->InSourceBuild) { - const std::string stripFromPath = - this->Makefile->GetCurrentSourceDirectory(); - if (f.find(stripFromPath) != std::string::npos) { - std::string link = f.substr(stripFromPath.length() + 1); - this->ConvertToWindowsSlash(link); - sourceFileTags["Link"] = link; - } - } - const cmPropertyMap& props = sf.GetProperties(); - for (cmPropertyMap::const_iterator p = props.begin(); p != props.end(); - ++p) { - static const std::string propNamePrefix = "VS_CSHARP_"; - if (p->first.find(propNamePrefix.c_str()) == 0) { - std::string tagName = p->first.substr(propNamePrefix.length()); - if (!tagName.empty()) { - const std::string val = props.GetPropertyValue(p->first); - if (!val.empty()) { - sourceFileTags[tagName] = val; - } else { - sourceFileTags.erase(tagName); - } - } - } + std::string link; + this->GetCSharpSourceLink(source, link); + if (!link.empty()) { + sourceFileTags["Link"] = link; } + this->GetCSharpSourceProperties(&sf, sourceFileTags); // write source file specific tags if (!sourceFileTags.empty()) { hasFlags = true; (*this->BuildFileStream) << firstString; firstString = ""; - for (CsPropMap::const_iterator i = sourceFileTags.begin(); - i != sourceFileTags.end(); ++i) { - this->WriteString("<", 3); - (*this->BuildFileStream) - << i->first << ">" << cmVS10EscapeXML(i->second) << "</" << i->first - << ">\n"; - } + this->WriteCSharpSourceProperties(sourceFileTags); } } @@ -2071,7 +2165,7 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions() if (ttype > cmStateEnums::GLOBAL_TARGET) { return; } - if (csproj == this->ProjectType) { + if (this->ProjectType == csproj) { return; } @@ -2148,7 +2242,7 @@ void cmVisualStudio10TargetGenerator::OutputLinkIncremental( if (!this->MSTools) { return; } - if (csproj == this->ProjectType) { + if (this->ProjectType == csproj) { return; } // static libraries and things greater than modules do not need @@ -2277,7 +2371,7 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions( std::string defineFlags = this->GeneratorTarget->Target->GetMakefile()->GetDefineFlags(); if (this->MSTools) { - if (vcxproj == this->ProjectType) { + if (this->ProjectType == vcxproj) { clOptions.FixExceptionHandlingDefault(); clOptions.AddFlag("PrecompiledHeader", "NotUsing"); std::string asmLocation = configName + "/"; @@ -2334,7 +2428,7 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions( } } - if (csproj != this->ProjectType && clOptions.IsManaged()) { + if (this->ProjectType != csproj && clOptions.IsManaged()) { this->Managed = true; std::string managedType = clOptions.GetFlag("CompileAsManaged"); if (managedType == "Safe") { @@ -2342,6 +2436,12 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions( clOptions.AddFlag("CallingConvention", ""); } } + if (this->ProjectType == csproj) { + // /nowin32manifest overrides /win32manifest: parameter + if (clOptions.HasFlag("NoWin32Manifest")) { + clOptions.RemoveFlag("ApplicationManifest"); + } + } this->ClOptions[configName] = pOptions.release(); return true; @@ -3130,12 +3230,7 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions( linkOptions.AddFlag("StackReserveSize", stackVal); } - if (this->LocalGenerator->GetVersion() >= - cmGlobalVisualStudioGenerator::VS14) { - linkOptions.AddFlag("GenerateDebugInformation", "No"); - } else { - linkOptions.AddFlag("GenerateDebugInformation", "false"); - } + linkOptions.AddFlag("GenerateDebugInformation", "false"); std::string pdb = this->GeneratorTarget->GetPDBDirectory(config.c_str()); pdb += "/"; @@ -3182,26 +3277,14 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions( "%(IgnoreSpecificDefaultLibraries)"); } - // Hack to fix flag version selection in a common use case. - // FIXME: Select flag table based on toolset instead of VS version. - if (this->LocalGenerator->GetVersion() >= - cmGlobalVisualStudioGenerator::VS14) { - const char* toolset = gg->GetPlatformToolset(); - if (toolset && - (toolset == kWINDOWS_7_1_SDK || /* clang-format please break here */ - cmHasLiteralPrefix(toolset, "v80") || - cmHasLiteralPrefix(toolset, "v90") || - cmHasLiteralPrefix(toolset, "v100") || - cmHasLiteralPrefix(toolset, "v110") || - cmHasLiteralPrefix(toolset, "v120"))) { - if (const char* debug = - linkOptions.GetFlag("GenerateDebugInformation")) { - // Convert value from enumeration back to boolean for older toolsets. - if (strcmp(debug, "No") == 0) { - linkOptions.AddFlag("GenerateDebugInformation", "false"); - } else if (strcmp(debug, "Debug") == 0) { - linkOptions.AddFlag("GenerateDebugInformation", "true"); - } + // VS 2015 without all updates has a v140 toolset whose + // GenerateDebugInformation expects No/Debug instead of false/true. + if (gg->GetPlatformToolsetNeedsDebugEnum()) { + if (const char* debug = linkOptions.GetFlag("GenerateDebugInformation")) { + if (strcmp(debug, "false") == 0) { + linkOptions.AddFlag("GenerateDebugInformation", "No"); + } else if (strcmp(debug, "true") == 0) { + linkOptions.AddFlag("GenerateDebugInformation", "Debug"); } } } @@ -3260,7 +3343,7 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions( this->GeneratorTarget->GetType() > cmStateEnums::MODULE_LIBRARY) { return; } - if (csproj == this->ProjectType) { + if (this->ProjectType == csproj) { return; } Options& linkOptions = *(this->LinkOptions[config]); @@ -3330,7 +3413,7 @@ void cmVisualStudio10TargetGenerator::WriteMidlOptions( if (!this->MSTools) { return; } - if (csproj == this->ProjectType) { + if (this->ProjectType == csproj) { return; } @@ -3372,6 +3455,9 @@ void cmVisualStudio10TargetGenerator::WriteMidlOptions( void cmVisualStudio10TargetGenerator::WriteItemDefinitionGroups() { + if (this->ProjectType == csproj) { + return; + } for (std::vector<std::string>::const_iterator i = this->Configurations.begin(); i != this->Configurations.end(); ++i) { @@ -3396,7 +3482,7 @@ void cmVisualStudio10TargetGenerator::WriteItemDefinitionGroups() // output midl flags <Midl></Midl> this->WriteMidlOptions(*i, includes); // write events - if (csproj != this->ProjectType) { + if (this->ProjectType != csproj) { this->WriteEvents(*i); } // output link flags <Link></Link> @@ -3462,7 +3548,7 @@ void cmVisualStudio10TargetGenerator::WriteEvent( script += cmVS10EscapeXML(lg->ConstructScript(ccg)); } comment = cmVS10EscapeComment(comment); - if (csproj != this->ProjectType) { + if (this->ProjectType != csproj) { this->WriteString("<Message>", 3); (*this->BuildFileStream) << cmVS10EscapeXML(comment) << "</Message>\n"; this->WriteString("<Command>", 3); @@ -3472,7 +3558,7 @@ void cmVisualStudio10TargetGenerator::WriteEvent( } } (*this->BuildFileStream) << script; - if (csproj != this->ProjectType) { + if (this->ProjectType != csproj) { (*this->BuildFileStream) << "</Command>"; } (*this->BuildFileStream) << "\n"; @@ -3521,6 +3607,7 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences() (*this->BuildFileStream) << "</Project>\n"; this->WriteString("<Name>", 3); (*this->BuildFileStream) << name << "</Name>\n"; + this->WriteDotNetReferenceCustomTags(name); this->WriteString("</ProjectReference>\n", 2); } this->WriteString("</ItemGroup>\n", 1); @@ -4308,6 +4395,59 @@ bool cmVisualStudio10TargetGenerator::ForceOld(const std::string& source) const return true; } +void cmVisualStudio10TargetGenerator::GetCSharpSourceProperties( + cmSourceFile const* sf, std::map<std::string, std::string>& tags) +{ + if (this->ProjectType == csproj) { + const cmPropertyMap& props = sf->GetProperties(); + for (cmPropertyMap::const_iterator p = props.begin(); p != props.end(); + ++p) { + static const std::string propNamePrefix = "VS_CSHARP_"; + if (p->first.find(propNamePrefix.c_str()) == 0) { + std::string tagName = p->first.substr(propNamePrefix.length()); + if (!tagName.empty()) { + const std::string val = props.GetPropertyValue(p->first); + if (!val.empty()) { + tags[tagName] = val; + } else { + tags.erase(tagName); + } + } + } + } + } +} + +void cmVisualStudio10TargetGenerator::WriteCSharpSourceProperties( + const std::map<std::string, std::string>& tags) +{ + if (!tags.empty()) { + for (std::map<std::string, std::string>::const_iterator i = tags.begin(); + i != tags.end(); ++i) { + this->WriteString("<", 3); + (*this->BuildFileStream) << i->first << ">" << cmVS10EscapeXML(i->second) + << "</" << i->first << ">\n"; + } + } +} + +void cmVisualStudio10TargetGenerator::GetCSharpSourceLink( + cmSourceFile const* sf, std::string& link) +{ + std::string f = sf->GetFullPath(); + if (!this->InSourceBuild) { + const std::string stripFromPath = + this->Makefile->GetCurrentSourceDirectory(); + if (f.find(stripFromPath) != std::string::npos) { + link = f.substr(stripFromPath.length() + 1); + if (const char* l = sf->GetProperty("VS_CSHARP_Link")) { + link = l; + } + this->ConvertToWindowsSlash(link); + } + } +} + std::string cmVisualStudio10TargetGenerator::GetCMakeFilePath( const char* relativeFilePath) const { diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h index 6106615..2d98994 100644 --- a/Source/cmVisualStudio10TargetGenerator.h +++ b/Source/cmVisualStudio10TargetGenerator.h @@ -66,6 +66,7 @@ private: void WriteAllSources(); void WriteDotNetReferences(); void WriteDotNetReference(std::string const& ref, std::string const& hint); + void WriteDotNetReferenceCustomTags(std::string const& ref); void WriteEmbeddedResourceGroup(); void WriteWinRTReferences(); void WriteWinRTPackageCertificateKeyFile(); @@ -126,6 +127,16 @@ private: void OutputLinkIncremental(std::string const& configName); void WriteCustomRule(cmSourceFile const* source, cmCustomCommand const& command); + void WriteCustomRuleCpp(std::string const& config, std::string const& script, + std::string const& inputs, + std::string const& outputs, + std::string const& comment); + void WriteCustomRuleCSharp(std::string const& config, + std::string const& commandName, + std::string const& script, + std::string const& inputs, + std::string const& outputs, + std::string const& comment); void WriteCustomCommands(); void WriteCustomCommand(cmSourceFile const* sf); void WriteGroups(); @@ -153,6 +164,12 @@ private: bool ForceOld(const std::string& source) const; + void GetCSharpSourceProperties(cmSourceFile const* sf, + std::map<std::string, std::string>& tags); + void WriteCSharpSourceProperties( + const std::map<std::string, std::string>& tags); + void GetCSharpSourceLink(cmSourceFile const* sf, std::string& link); + private: typedef cmVisualStudioGeneratorOptions Options; typedef std::map<std::string, Options*> OptionsMap; @@ -187,6 +204,7 @@ private: cmGeneratedFileStream* BuildFileStream; cmLocalVisualStudio7Generator* LocalGenerator; std::set<cmSourceFile const*> SourcesVisited; + std::set<std::string> CSharpCustomCommandNames; bool IsMissingFiles; std::vector<std::string> AddedFiles; std::string DefaultArtifactDir; diff --git a/Source/cmVisualStudio10ToolsetOptions.cxx b/Source/cmVisualStudio10ToolsetOptions.cxx index afca216..9a1d950 100644 --- a/Source/cmVisualStudio10ToolsetOptions.cxx +++ b/Source/cmVisualStudio10ToolsetOptions.cxx @@ -26,10 +26,11 @@ #include "cmVS12RCFlagTable.h" #include "cmVS140CLFlagTable.h" #include "cmVS140CSharpFlagTable.h" +#include "cmVS140LinkFlagTable.h" #include "cmVS141CLFlagTable.h" #include "cmVS141CSharpFlagTable.h" +#include "cmVS141LinkFlagTable.h" #include "cmVS14LibFlagTable.h" -#include "cmVS14LinkFlagTable.h" #include "cmVS14MASMFlagTable.h" #include "cmVS14RCFlagTable.h" @@ -114,8 +115,10 @@ cmIDEFlagTable const* cmVisualStudio10ToolsetOptions::GetLinkFlagTable( { std::string const useToolset = this->GetToolsetName(name, toolset); - if ((useToolset == "v140") || (useToolset == "v141")) { - return cmVS14LinkFlagTable; + if (useToolset == "v141") { + return cmVS141LinkFlagTable; + } else if (useToolset == "v140") { + return cmVS140LinkFlagTable; } else if (useToolset == "v120") { return cmVS12LinkFlagTable; } else if (useToolset == "v110") { diff --git a/Source/cmXCodeScheme.cxx b/Source/cmXCodeScheme.cxx index 5c22531..bca39af 100644 --- a/Source/cmXCodeScheme.cxx +++ b/Source/cmXCodeScheme.cxx @@ -10,13 +10,12 @@ #include "cmGeneratorTarget.h" #include "cmXMLSafe.h" -cmXCodeScheme::cmXCodeScheme(cmXCodeObject* xcObj, +cmXCodeScheme::cmXCodeScheme(cmXCodeObject* xcObj, const TestObjects& tests, const std::vector<std::string>& configList, unsigned int xcVersion) : Target(xcObj) + , Tests(tests) , TargetName(xcObj->GetTarget()->GetName()) - , BuildableName(xcObj->GetTarget()->GetFullName()) - , TargetId(xcObj->GetId()) , ConfigList(configList) , XcodeVersion(xcVersion) { @@ -58,7 +57,7 @@ void cmXCodeScheme::WriteXCodeXCScheme(std::ostream& fout, xout.Attribute("version", "1.3"); WriteBuildAction(xout, container); - WriteTestAction(xout, FindConfiguration("Debug")); + WriteTestAction(xout, FindConfiguration("Debug"), container); WriteLaunchAction(xout, FindConfiguration("Debug"), container); WriteProfileAction(xout, FindConfiguration("Release")); WriteAnalyzeAction(xout, FindConfiguration("Debug")); @@ -84,14 +83,7 @@ void cmXCodeScheme::WriteBuildAction(cmXMLWriter& xout, xout.Attribute("buildForArchiving", "YES"); xout.Attribute("buildForAnalyzing", "YES"); - xout.StartElement("BuildableReference"); - xout.BreakAttributes(); - xout.Attribute("BuildableIdentifier", "primary"); - xout.Attribute("BlueprintIdentifier", this->TargetId); - xout.Attribute("BuildableName", this->BuildableName); - xout.Attribute("BlueprintName", this->TargetName); - xout.Attribute("ReferencedContainer", "container:" + container); - xout.EndElement(); + WriteBuildableReference(xout, this->Target, container); xout.EndElement(); // BuildActionEntry xout.EndElement(); // BuildActionEntries @@ -99,7 +91,8 @@ void cmXCodeScheme::WriteBuildAction(cmXMLWriter& xout, } void cmXCodeScheme::WriteTestAction(cmXMLWriter& xout, - std::string configuration) + std::string configuration, + const std::string& container) { xout.StartElement("TestAction"); xout.BreakAttributes(); @@ -111,8 +104,22 @@ void cmXCodeScheme::WriteTestAction(cmXMLWriter& xout, xout.Attribute("shouldUseLaunchSchemeArgsEnv", "YES"); xout.StartElement("Testables"); + for (TestObjects::const_iterator it = this->Tests.begin(); + it != this->Tests.end(); ++it) { + xout.StartElement("TestableReference"); + xout.BreakAttributes(); + xout.Attribute("skipped", "NO"); + WriteBuildableReference(xout, *it, container); + xout.EndElement(); // TestableReference + } xout.EndElement(); + if (IsTestable()) { + xout.StartElement("MacroExpansion"); + WriteBuildableReference(xout, this->Target, container); + xout.EndElement(); // MacroExpansion + } + xout.StartElement("AdditionalOptions"); xout.EndElement(); @@ -146,14 +153,7 @@ void cmXCodeScheme::WriteLaunchAction(cmXMLWriter& xout, xout.StartElement("MacroExpansion"); } - xout.StartElement("BuildableReference"); - xout.BreakAttributes(); - xout.Attribute("BuildableIdentifier", "primary"); - xout.Attribute("BlueprintIdentifier", this->TargetId); - xout.Attribute("BuildableName", this->BuildableName); - xout.Attribute("BlueprintName", this->TargetName); - xout.Attribute("ReferencedContainer", "container:" + container); - xout.EndElement(); + WriteBuildableReference(xout, this->Target, container); xout.EndElement(); // MacroExpansion @@ -195,6 +195,20 @@ void cmXCodeScheme::WriteArchiveAction(cmXMLWriter& xout, xout.EndElement(); } +void cmXCodeScheme::WriteBuildableReference(cmXMLWriter& xout, + const cmXCodeObject* xcObj, + const std::string& container) +{ + xout.StartElement("BuildableReference"); + xout.BreakAttributes(); + xout.Attribute("BuildableIdentifier", "primary"); + xout.Attribute("BlueprintIdentifier", xcObj->GetId()); + xout.Attribute("BuildableName", xcObj->GetTarget()->GetFullName()); + xout.Attribute("BlueprintName", xcObj->GetTarget()->GetName()); + xout.Attribute("ReferencedContainer", "container:" + container); + xout.EndElement(); +} + std::string cmXCodeScheme::WriteVersionString() { std::ostringstream v; @@ -215,6 +229,11 @@ std::string cmXCodeScheme::FindConfiguration(const std::string& name) return name; } +bool cmXCodeScheme::IsTestable() const +{ + return !this->Tests.empty() || IsExecutable(this->Target); +} + bool cmXCodeScheme::IsExecutable(const cmXCodeObject* target) { cmGeneratorTarget* gt = target->GetTarget(); diff --git a/Source/cmXCodeScheme.h b/Source/cmXCodeScheme.h index 379afed..def75b1 100644 --- a/Source/cmXCodeScheme.h +++ b/Source/cmXCodeScheme.h @@ -5,6 +5,8 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include <vector> + #include "cmGlobalXCodeGenerator.h" #include "cmSystemTools.h" #include "cmXCodeObject.h" @@ -16,7 +18,9 @@ class cmXCodeScheme { public: - cmXCodeScheme(cmXCodeObject* xcObj, + typedef std::vector<const cmXCodeObject*> TestObjects; + + cmXCodeScheme(cmXCodeObject* xcObj, const TestObjects& tests, const std::vector<std::string>& configList, unsigned int xcVersion); @@ -25,25 +29,30 @@ public: private: const cmXCodeObject* const Target; + const TestObjects Tests; const std::string& TargetName; - const std::string BuildableName; - const std::string& TargetId; const std::vector<std::string>& ConfigList; const unsigned int XcodeVersion; void WriteXCodeXCScheme(std::ostream& fout, const std::string& container); void WriteBuildAction(cmXMLWriter& xout, const std::string& container); - void WriteTestAction(cmXMLWriter& xout, std::string configuration); + void WriteTestAction(cmXMLWriter& xout, std::string configuration, + const std::string& container); void WriteLaunchAction(cmXMLWriter& xout, std::string configuration, const std::string& container); void WriteProfileAction(cmXMLWriter& xout, std::string configuration); void WriteAnalyzeAction(cmXMLWriter& xout, std::string configuration); void WriteArchiveAction(cmXMLWriter& xout, std::string configuration); + void WriteBuildableReference(cmXMLWriter& xout, const cmXCodeObject* xcObj, + const std::string& container); + std::string WriteVersionString(); std::string FindConfiguration(const std::string& name); + bool IsTestable() const; + static bool IsExecutable(const cmXCodeObject* target); }; diff --git a/Source/cm_sys_stat.h b/Source/cm_sys_stat.h index 26e4baa..796f027 100644 --- a/Source/cm_sys_stat.h +++ b/Source/cm_sys_stat.h @@ -7,6 +7,11 @@ typedef unsigned short mode_t; #endif +#if defined(WIN32) +typedef unsigned short uid_t; +typedef unsigned short gid_t; +#endif + #include <sys/types.h> // include sys/stat.h after sys/types.h #include <sys/stat.h> diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx index 1c4fe33..c5bbd41 100644 --- a/Source/kwsys/SystemTools.cxx +++ b/Source/kwsys/SystemTools.cxx @@ -22,7 +22,6 @@ #include KWSYS_HEADER(FStream.hxx) #include KWSYS_HEADER(Encoding.hxx) -#include <algorithm> #include <fstream> #include <iostream> #include <set> @@ -3709,16 +3708,6 @@ std::string SystemTools::JoinPath( return result; } -void SystemTools::RemoveEmptyPathElements(std::vector<std::string>& path) -{ - if (path.empty()) { - return; - } - - path.erase(std::remove(path.begin() + 1, path.end(), std::string("")), - path.end()); -} - bool SystemTools::ComparePath(const std::string& c1, const std::string& c2) { #if defined(_WIN32) || defined(__APPLE__) diff --git a/Source/kwsys/SystemTools.hxx.in b/Source/kwsys/SystemTools.hxx.in index 5e091c2..1672e92 100644 --- a/Source/kwsys/SystemTools.hxx.in +++ b/Source/kwsys/SystemTools.hxx.in @@ -461,6 +461,10 @@ public: * produce the original path. Home directory references are * automatically expanded if expand_home_dir is true and this * platform supports them. + * + * This does *not* normalize the input path. All components are + * preserved, including empty ones. Typically callers should use + * this only on paths that have already been normalized. */ static void SplitPath(const std::string& p, std::vector<std::string>& components, @@ -469,15 +473,15 @@ public: /** * Join components of a path name into a single string. See * SplitPath for the format of the components. + * + * This does *not* normalize the input path. All components are + * preserved, including empty ones. Typically callers should use + * this only on paths that have already been normalized. */ static std::string JoinPath(const std::vector<std::string>& components); static std::string JoinPath(std::vector<std::string>::const_iterator first, std::vector<std::string>::const_iterator last); - /** Removes empty components from path. - */ - static void RemoveEmptyPathElements(std::vector<std::string>& path); - /** * Compare a path or components of a path. */ diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index d16df1c..34418c5 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -2082,7 +2082,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release set(reg_nasm "[HKEY_CURRENT_USER\\SOFTWARE\\nasm]") foreach(reg vs10 vs11 vs12 vs14 ws80 ws81 ws10_0 wp80 wp81 wince tegra nasm) get_filename_component(r "${reg_${reg}}" ABSOLUTE) - if(IS_DIRECTORY "${r}") + if(IS_DIRECTORY "${r}" AND NOT "${r}" STREQUAL "/registry") set(${reg} 1) else() set(${reg} 0) diff --git a/Tests/CMakeTests/CMakeHostSystemInformationTest.cmake.in b/Tests/CMakeTests/CMakeHostSystemInformationTest.cmake.in index 3294a2f..a3c2b05 100644 --- a/Tests/CMakeTests/CMakeHostSystemInformationTest.cmake.in +++ b/Tests/CMakeTests/CMakeHostSystemInformationTest.cmake.in @@ -22,6 +22,25 @@ try_and_print(TOTAL_VIRTUAL_MEMORY) try_and_print(AVAILABLE_VIRTUAL_MEMORY) try_and_print(TOTAL_PHYSICAL_MEMORY) try_and_print(AVAILABLE_PHYSICAL_MEMORY) +try_and_print(IS_64BIT) +try_and_print(HAS_FPU) +try_and_print(HAS_MMX) +try_and_print(HAS_MMX_PLUS) +try_and_print(HAS_SSE) +try_and_print(HAS_SSE2) +try_and_print(HAS_SSE_FP) +try_and_print(HAS_SSE_MMX) +try_and_print(HAS_AMD_3DNOW) +try_and_print(HAS_AMD_3DNOW_PLUS) +try_and_print(HAS_IA64) +try_and_print(HAS_SERIAL_NUMBER) +try_and_print(PROCESSOR_SERIAL_NUMBER) +try_and_print(PROCESSOR_NAME) +try_and_print(PROCESSOR_DESCRIPTION) +try_and_print(OS_NAME) +try_and_print(OS_RELEASE) +try_and_print(OS_VERSION) +try_and_print(OS_PLATFORM) include("@CMAKE_CURRENT_SOURCE_DIR@/CheckCMakeTest.cmake") diff --git a/Tests/Cuda/Complex/CMakeLists.txt b/Tests/Cuda/Complex/CMakeLists.txt index 450ef48..a7137e3 100644 --- a/Tests/Cuda/Complex/CMakeLists.txt +++ b/Tests/Cuda/Complex/CMakeLists.txt @@ -42,7 +42,6 @@ add_executable(CudaComplex main.cpp) target_link_libraries(CudaComplex PUBLIC CudaComplexMixedLib) if(APPLE) - # We need to add the default path to the driver (libcuda.dylib) as an rpath, so that - # the static cuda runtime can find it at runtime. - target_link_libraries(CudaComplex PRIVATE -Wl,-rpath,/usr/local/cuda/lib) + # Help the static cuda runtime find the driver (libcuda.dyllib) at runtime. + set_property(TARGET CudaComplex PROPERTY BUILD_RPATH ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES}) endif() diff --git a/Tests/Cuda/ObjectLibrary/CMakeLists.txt b/Tests/Cuda/ObjectLibrary/CMakeLists.txt index 1d93be7..276dc92 100644 --- a/Tests/Cuda/ObjectLibrary/CMakeLists.txt +++ b/Tests/Cuda/ObjectLibrary/CMakeLists.txt @@ -10,8 +10,8 @@ add_library(CudaMixedObjectLib OBJECT static.cu static.cpp) add_executable(CudaObjectLibrary main.cpp $<TARGET_OBJECTS:CudaMixedObjectLib>) + if(APPLE) - # We need to add the default path to the driver (libcuda.dylib) as an rpath, so that - # the static cuda runtime can find it at runtime. - target_link_libraries(CudaObjectLibrary PRIVATE -Wl,-rpath,/usr/local/cuda/lib) + # Help the static cuda runtime find the driver (libcuda.dyllib) at runtime. + set_property(TARGET CudaObjectLibrary PROPERTY BUILD_RPATH ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES}) endif() diff --git a/Tests/Cuda/WithC/CMakeLists.txt b/Tests/Cuda/WithC/CMakeLists.txt index 1f25ab4..831ce12 100644 --- a/Tests/Cuda/WithC/CMakeLists.txt +++ b/Tests/Cuda/WithC/CMakeLists.txt @@ -6,7 +6,6 @@ string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=compute_30") add_executable(CudaWithC main.c cuda.cu) if(APPLE) - # We need to add the default path to the driver (libcuda.dylib) as an rpath, so that - # the static cuda runtime can find it at runtime. - target_link_libraries(CudaWithC PRIVATE -Wl,-rpath,/usr/local/cuda/lib) + # Help the static cuda runtime find the driver (libcuda.dyllib) at runtime. + set_property(TARGET CudaWithC PROPERTY BUILD_RPATH ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES}) endif() diff --git a/Tests/CudaOnly/ExportPTX/CMakeLists.txt b/Tests/CudaOnly/ExportPTX/CMakeLists.txt index 10249c6..65d5243 100644 --- a/Tests/CudaOnly/ExportPTX/CMakeLists.txt +++ b/Tests/CudaOnly/ExportPTX/CMakeLists.txt @@ -67,9 +67,8 @@ target_compile_definitions(CudaOnlyExportPTX PRIVATE "CONFIG_TYPE=gen_$<LOWER_CASE:$<CONFIG>>") if(APPLE) - # We need to add the default path to the driver (libcuda.dylib) as an rpath, so that - # the static cuda runtime can find it at runtime. - target_link_libraries(CudaOnlyExportPTX PRIVATE -Wl,-rpath,/usr/local/cuda/lib) + # Help the static cuda runtime find the driver (libcuda.dyllib) at runtime. + set_property(TARGET CudaOnlyExportPTX PROPERTY BUILD_RPATH ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES}) endif() #Verify that we can install object targets properly diff --git a/Tests/CudaOnly/ResolveDeviceSymbols/CMakeLists.txt b/Tests/CudaOnly/ResolveDeviceSymbols/CMakeLists.txt index b96bb98..8d6551b 100644 --- a/Tests/CudaOnly/ResolveDeviceSymbols/CMakeLists.txt +++ b/Tests/CudaOnly/ResolveDeviceSymbols/CMakeLists.txt @@ -46,7 +46,6 @@ add_executable(CudaOnlyResolveDeviceSymbols main.cu) target_link_libraries(CudaOnlyResolveDeviceSymbols PRIVATE CUDAResolveDeviceLib) if(APPLE) - # We need to add the default path to the driver (libcuda.dylib) as an rpath, so that - # the static cuda runtime can find it at runtime. - target_link_libraries(CudaOnlyResolveDeviceSymbols PRIVATE -Wl,-rpath,/usr/local/cuda/lib) + # Help the static cuda runtime find the driver (libcuda.dyllib) at runtime. + set_property(TARGET CudaOnlyResolveDeviceSymbols PROPERTY BUILD_RPATH ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES}) endif() diff --git a/Tests/CudaOnly/SeparateCompilation/CMakeLists.txt b/Tests/CudaOnly/SeparateCompilation/CMakeLists.txt index 3d4a170..7ef626f 100644 --- a/Tests/CudaOnly/SeparateCompilation/CMakeLists.txt +++ b/Tests/CudaOnly/SeparateCompilation/CMakeLists.txt @@ -48,8 +48,7 @@ if (CMAKE_GENERATOR MATCHES "^Visual Studio") PROPERTIES CUDA_SEPARABLE_COMPILATION ON) endif() -if (APPLE) - # We need to add the default path to the driver (libcuda.dylib) as an rpath, so that - # the static cuda runtime can find it at runtime. - target_link_libraries(CudaOnlySeparateCompilation PRIVATE -Wl,-rpath,/usr/local/cuda/lib) +if(APPLE) + # Help the static cuda runtime find the driver (libcuda.dyllib) at runtime. + set_property(TARGET CudaOnlySeparateCompilation PROPERTY BUILD_RPATH ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES}) endif() diff --git a/Tests/CudaOnly/WithDefs/CMakeLists.txt b/Tests/CudaOnly/WithDefs/CMakeLists.txt index e25f141..0bc4e5c 100644 --- a/Tests/CudaOnly/WithDefs/CMakeLists.txt +++ b/Tests/CudaOnly/WithDefs/CMakeLists.txt @@ -37,8 +37,7 @@ target_compile_definitions(CudaOnlyWithDefs $<$<CONFIG:RELEASE>:$<BUILD_INTERFACE:${release_compile_defs}>> ) -#we need to add an rpath for the cuda library so that everything -#loads properly on the mac -if(CMAKE_SYSTEM_NAME MATCHES "Darwin") - set_target_properties(CudaOnlyWithDefs PROPERTIES LINK_FLAGS "-Wl,-rpath,${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES}") +if(APPLE) + # Help the static cuda runtime find the driver (libcuda.dyllib) at runtime. + set_property(TARGET CudaOnlyWithDefs PROPERTY BUILD_RPATH ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES}) endif() diff --git a/Tests/Qt4Targets/CMakeLists.txt b/Tests/Qt4Targets/CMakeLists.txt index ae0a02b..2ca11e4 100644 --- a/Tests/Qt4Targets/CMakeLists.txt +++ b/Tests/Qt4Targets/CMakeLists.txt @@ -20,6 +20,16 @@ if (WIN32) endif() endif() +# Qt4 moc does not support utf8 paths in _parameter files generated by +# qt4_wrap_cpp and qt4_generate_moc +# https://bugreports.qt.io/browse/QTBUG-35480 +# Do a simple check if there is are non ASCII character in the build path +string(REGEX MATCH "[^ -~]+" NON_ASCII_BDIR ${CMAKE_CURRENT_BINARY_DIR}) +if(NON_ASCII_BDIR) + message(WARNING "Build path contains non ASCII characters. Skipping Qt4 test.") + return() +endif() + qt4_generate_moc(main_gen_test.cpp "${CMAKE_CURRENT_BINARY_DIR}/main_gen_test.moc" TARGET Qt4GenerateMacroTest diff --git a/Tests/QtAutogen/CMakeLists.txt b/Tests/QtAutogen/CMakeLists.txt index 073c5fd..89d2b80 100644 --- a/Tests/QtAutogen/CMakeLists.txt +++ b/Tests/QtAutogen/CMakeLists.txt @@ -46,6 +46,35 @@ endif() get_property(QT_COMPILE_FEATURES TARGET ${QT_QTCORE_TARGET} PROPERTY INTERFACE_COMPILE_FEATURES) +# Qt4 moc does not support utf8 paths in _parameter files generated by +# qtx_wrap_cpp +# https://bugreports.qt.io/browse/QTBUG-35480 +# Do a simple check if there is are non ASCII character in the build path +string(REGEX MATCH "[^ -~]+" NON_ASCII_BDIR ${CMAKE_CURRENT_BINARY_DIR}) +if((NOT NON_ASCII_BDIR) OR (NOT QT_TEST_VERSION STREQUAL 4)) + set(ALLOW_WRAP_CPP TRUE) +endif() +# On windows qtx_wrap_cpp also fails in Qt5 when used on a path that +# contains non ASCII characters +if(NON_ASCII_BDIR AND WIN32) + set(ALLOW_WRAP_CPP FALSE) +endif() + +# -- Test +# MOC only +add_executable(mocOnly mocOnlySource/main.cpp mocOnlySource/StyleA.cpp mocOnlySource/StyleB.cpp) +set_property(TARGET mocOnly PROPERTY AUTOMOC ON) +target_link_libraries(mocOnly ${QT_LIBRARIES}) + +# -- Test +# UIC only +if(ALLOW_WRAP_CPP) + qtx_wrap_cpp(uicOnlyMoc uicOnlySource/uiconly.h) + add_executable(uicOnly uicOnlySource/uiconly.cpp ${uicOnlyMoc}) + set_property(TARGET uicOnly PROPERTY AUTOUIC ON) + target_link_libraries(uicOnly ${QT_LIBRARIES}) +endif() + # -- Test # RCC only add_executable(rccOnly rccOnly.cpp rccOnlyRes.qrc) @@ -59,13 +88,6 @@ set_property(TARGET rccEmpty PROPERTY AUTORCC ON) target_link_libraries(rccEmpty ${QT_QTCORE_TARGET}) # -- Test -# UIC only -qtx_wrap_cpp(uicOnlyMoc uicOnlySource/uiconly.h) -add_executable(uicOnly uicOnlySource/uiconly.cpp ${uicOnlyMoc}) -set_property(TARGET uicOnly PROPERTY AUTOUIC ON) -target_link_libraries(uicOnly ${QT_LIBRARIES}) - -# -- Test # Add not_generated_file.qrc to the source list to get the file-level # dependency, but don't generate a c++ file from it. Disable the AUTORCC # feature for this target. This tests that qrc files in the sources don't @@ -100,7 +122,7 @@ if (NOT RCC_DEPENDS) message(SEND_ERROR "Initial build of rccDepends failed. Output: ${output}") endif() # Get name and timestamp of the output binary -file(STRINGS "${RCC_DEPENDS_BIN}/target.txt" targetList) +file(STRINGS "${RCC_DEPENDS_BIN}/target.txt" targetList ENCODING UTF-8) list(GET targetList 0 rccDependsBin) file(TIMESTAMP "${rccDependsBin}" timeBegin "${timeformat}") # Sleep, touch regular qrc input file, rebuild and compare timestamp @@ -188,7 +210,7 @@ if (NOT MOC_RERUN) message(SEND_ERROR "Initial build of mocRerun failed. Output: ${output}") endif() # Get name and timestamp of the output binary -file(STRINGS "${CMAKE_CURRENT_BINARY_DIR}/mocRerun/target1.txt" target1List) +file(STRINGS "${CMAKE_CURRENT_BINARY_DIR}/mocRerun/target1.txt" target1List ENCODING UTF-8) list(GET target1List 0 binFile) file(TIMESTAMP "${binFile}" timeBegin "${timeformat}") # Change file content and rebuild @@ -209,25 +231,27 @@ endif() # -- Test # Test for SKIP_AUTOMOC and SKIP_AUTOGEN on an AUTOMOC enabled target -qtx_wrap_cpp(skipMocWrapMoc - skipSource/qItemA.hpp - skipSource/qItemB.hpp) -set(skipMocSources - skipMoc.cpp - skipSource/qItemA.cpp - skipSource/qItemB.cpp - skipSource/qItemC.cpp) -set_property(SOURCE skipSource/qItemA.cpp PROPERTY SKIP_AUTOMOC ON) -set_property(SOURCE skipSource/qItemB.cpp PROPERTY SKIP_AUTOGEN ON) -# AUTOMOC enabled only -add_executable(skipMocA ${skipMocSources} ${skipMocWrapMoc}) -set_property(TARGET skipMocA PROPERTY AUTOMOC ON) -target_link_libraries(skipMocA ${QT_LIBRARIES}) -# AUTOMOC and AUTOUIC enabled -add_executable(skipMocB ${skipMocSources} ${skipMocWrapMoc}) -set_property(TARGET skipMocB PROPERTY AUTOMOC ON) -set_property(TARGET skipMocB PROPERTY AUTOUIC ON) -target_link_libraries(skipMocB ${QT_LIBRARIES}) +if(ALLOW_WRAP_CPP) + qtx_wrap_cpp(skipMocWrapMoc + skipSource/qItemA.hpp + skipSource/qItemB.hpp) + set(skipMocSources + skipMoc.cpp + skipSource/qItemA.cpp + skipSource/qItemB.cpp + skipSource/qItemC.cpp) + set_property(SOURCE skipSource/qItemA.cpp PROPERTY SKIP_AUTOMOC ON) + set_property(SOURCE skipSource/qItemB.cpp PROPERTY SKIP_AUTOGEN ON) + # AUTOMOC enabled only + add_executable(skipMocA ${skipMocSources} ${skipMocWrapMoc}) + set_property(TARGET skipMocA PROPERTY AUTOMOC ON) + target_link_libraries(skipMocA ${QT_LIBRARIES}) + # AUTOMOC and AUTOUIC enabled + add_executable(skipMocB ${skipMocSources} ${skipMocWrapMoc}) + set_property(TARGET skipMocB PROPERTY AUTOMOC ON) + set_property(TARGET skipMocB PROPERTY AUTOUIC ON) + target_link_libraries(skipMocB ${QT_LIBRARIES}) +endif() # -- Test # Test for SKIP_AUTOUIC and SKIP_AUTOGEN on an AUTOUIC enabled target diff --git a/Tests/QtAutogen/mocOnlySource/StyleA.cpp b/Tests/QtAutogen/mocOnlySource/StyleA.cpp new file mode 100644 index 0000000..ced1dd1 --- /dev/null +++ b/Tests/QtAutogen/mocOnlySource/StyleA.cpp @@ -0,0 +1,5 @@ +#include "StyleA.hpp" + +StyleA::StyleA() +{ +} diff --git a/Tests/QtAutogen/mocOnlySource/StyleA.hpp b/Tests/QtAutogen/mocOnlySource/StyleA.hpp new file mode 100644 index 0000000..66735b6 --- /dev/null +++ b/Tests/QtAutogen/mocOnlySource/StyleA.hpp @@ -0,0 +1,15 @@ +#ifndef STYLEA_HPP +#define STYLEA_HPP + +#include <QObject> + +/// Q_OBJECT on a single new line +/// +class StyleA : public QObject +{ + Q_OBJECT +public: + StyleA(); +}; + +#endif diff --git a/Tests/QtAutogen/mocOnlySource/StyleB.cpp b/Tests/QtAutogen/mocOnlySource/StyleB.cpp new file mode 100644 index 0000000..bec6c1c --- /dev/null +++ b/Tests/QtAutogen/mocOnlySource/StyleB.cpp @@ -0,0 +1,5 @@ +#include "StyleB.hpp" + +StyleB::StyleB() +{ +} diff --git a/Tests/QtAutogen/mocOnlySource/StyleB.hpp b/Tests/QtAutogen/mocOnlySource/StyleB.hpp new file mode 100644 index 0000000..425daf8 --- /dev/null +++ b/Tests/QtAutogen/mocOnlySource/StyleB.hpp @@ -0,0 +1,16 @@ +#ifndef STYLEB_HPP +#define STYLEB_HPP + +#include <QObject> + +/* clang-format off */ +/// Q_OBJECT behind a brace +/// +class StyleB : public QObject +{ Q_OBJECT +public: + StyleB(); +}; +/* clang-format on */ + +#endif diff --git a/Tests/QtAutogen/mocOnlySource/main.cpp b/Tests/QtAutogen/mocOnlySource/main.cpp new file mode 100644 index 0000000..06f8d81 --- /dev/null +++ b/Tests/QtAutogen/mocOnlySource/main.cpp @@ -0,0 +1,9 @@ +#include "StyleA.hpp" +#include "StyleB.hpp" + +int main(int argv, char** args) +{ + StyleA styleA; + StyleB styleB; + return 0; +} diff --git a/Tests/README b/Tests/README deleted file mode 100644 index 8b2fda8..0000000 --- a/Tests/README +++ /dev/null @@ -1,39 +0,0 @@ -If you think about adding a new testcase then here is a small checklist you -can run through to find a proper place for it. Go through the list from the -beginning and stop once you find something that matches your tests needs, -i.e. if you will test a module and only need the configure mode use the -instructions from section 2, not 3. - -1. Your testcase can run in CMake script mode, i.e. "cmake -P something" - -Put your test in Tests/CMakeTests/ directory as a .cmake.in file. It will be -put into the test binary directory by configure_file(... @ONLY) and run from -there. Use the AddCMakeTest() macro in Tests/CMakeTests/CMakeLists.txt to add -your test to the test runs. - -2. Your test needs CMake to run in configure mode, but will not build anything - -This includes tests that will build something using try_compile() and friends, -but nothing that expects add_executable(), add_library(), or add_test() to run. - -If the test configures the project only once and it must succeed then put it -into the Tests/CMakeOnly/ directory. Create a subdirectory named like your -test and write the CMakeLists.txt you need into that subdirectory. Use the -add_CMakeOnly_test() macro from Tests/CMakeOnly/CMakeLists.txt to add your -test to the test runs. - -If the test configures the project with multiple variations and verifies -success or failure each time then put it into the Tests/RunCMake/ directory. -Read the instructions in Tests/RunCMake/CMakeLists.txt to add a test. - -3. If you are testing something from the Modules directory - -Put your test in the Tests/Modules/ directory. Create a subdirectory there -named after your test. Use the ADD_TEST_MACRO macro from Tests/CMakeLists.txt -to add your test to the test run. If you have put your stuff in -Tests/Modules/Foo then you call it using ADD_TEST_MACRO(Module.Foo Foo). - -4. You are doing other stuff. - -Find a good place ;) In doubt mail to cmake-developers@cmake.org and ask for -advise. diff --git a/Tests/README.rst b/Tests/README.rst new file mode 100644 index 0000000..3e98938 --- /dev/null +++ b/Tests/README.rst @@ -0,0 +1,31 @@ +CMake Tests Directory +********************* + +This directory contains the CMake test suite. +See also the `CMake Source Code Guide`_. + +.. _`CMake Source Code Guide`: ../Help/dev/source.rst + +Many tests exist as immediate subdirectories, but some tests +are organized as follows. + +* ``CMakeLib/``: + Source code, used for tests, that links to the ``CMakeLib`` library + defined over in ``Source/``. + +* ``CMakeOnly/``: + Deprecated. Tests that run CMake to generate a project but not build it. + Superseded by ``Tests/RunCMake/``. + +* ``Find*/``: + Tests for specific find modules that can only be run on machines with + the corresponding packages installed. They are enabled in + ``CMakeLists.txt`` by undocumented options used on CI builds. + +* ``Module/``: + Tests for specific CMake modules. + +* ``RunCMake/``: + Tests that run CMake and/or other tools while precisely checking + their return code and stdout/stderr content. Useful for testing + error cases and diagnostic output. diff --git a/Tests/RunCMake/BuildDepends/C-Exe-Manifest.cmake b/Tests/RunCMake/BuildDepends/C-Exe-Manifest.cmake index ef33012..87b0de0 100644 --- a/Tests/RunCMake/BuildDepends/C-Exe-Manifest.cmake +++ b/Tests/RunCMake/BuildDepends/C-Exe-Manifest.cmake @@ -11,7 +11,7 @@ endif() ]]) endif() -file(GENERATE OUTPUT check-$<LOWER_CASE:$<CONFIG>>.cmake CONTENT " +file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/check-$<LOWER_CASE:$<CONFIG>>.cmake CONTENT " set(check_pairs \"$<TARGET_FILE:main>|${CMAKE_CURRENT_BINARY_DIR}/test.manifest\" ) diff --git a/Tests/RunCMake/BuildDepends/C-Exe.cmake b/Tests/RunCMake/BuildDepends/C-Exe.cmake index 5057ca9..ad5cd4d 100644 --- a/Tests/RunCMake/BuildDepends/C-Exe.cmake +++ b/Tests/RunCMake/BuildDepends/C-Exe.cmake @@ -2,7 +2,7 @@ enable_language(C) add_executable(main ${CMAKE_CURRENT_BINARY_DIR}/main.c) -file(GENERATE OUTPUT check-$<LOWER_CASE:$<CONFIG>>.cmake CONTENT " +file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/check-$<LOWER_CASE:$<CONFIG>>.cmake CONTENT " set(check_pairs \"$<TARGET_FILE:main>|${CMAKE_CURRENT_BINARY_DIR}/main.c\" ) diff --git a/Tests/RunCMake/BuildDepends/Custom-Always.cmake b/Tests/RunCMake/BuildDepends/Custom-Always.cmake index d412708..c7e7fb0 100644 --- a/Tests/RunCMake/BuildDepends/Custom-Always.cmake +++ b/Tests/RunCMake/BuildDepends/Custom-Always.cmake @@ -16,7 +16,7 @@ add_custom_command( add_custom_target(drive ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/after-always) -file(GENERATE OUTPUT check-$<LOWER_CASE:$<CONFIG>>.cmake CONTENT " +file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/check-$<LOWER_CASE:$<CONFIG>>.cmake CONTENT " set(check_pairs \"${CMAKE_CURRENT_BINARY_DIR}/always-updated|${CMAKE_CURRENT_BINARY_DIR}/before-always\" \"${CMAKE_CURRENT_BINARY_DIR}/after-always|${CMAKE_CURRENT_BINARY_DIR}/always-updated\" diff --git a/Tests/RunCMake/BuildDepends/Custom-Symbolic-and-Byproduct.cmake b/Tests/RunCMake/BuildDepends/Custom-Symbolic-and-Byproduct.cmake index 687c827..1e1f22a 100644 --- a/Tests/RunCMake/BuildDepends/Custom-Symbolic-and-Byproduct.cmake +++ b/Tests/RunCMake/BuildDepends/Custom-Symbolic-and-Byproduct.cmake @@ -16,7 +16,7 @@ add_custom_command( add_custom_target(drive ALL DEPENDS use-byproduct) add_dependencies(drive produce) -file(GENERATE OUTPUT check-$<LOWER_CASE:$<CONFIG>>.cmake CONTENT " +file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/check-$<LOWER_CASE:$<CONFIG>>.cmake CONTENT " if (check_step EQUAL 1) set(check_pairs \"${CMAKE_CURRENT_BINARY_DIR}/use-byproduct|${CMAKE_CURRENT_BINARY_DIR}/gen-byproduct-stamp\" diff --git a/Tests/RunCMake/BuildDepends/MakeCustomIncludes.cmake b/Tests/RunCMake/BuildDepends/MakeCustomIncludes.cmake index 0f92e0e..8b2ae78 100644 --- a/Tests/RunCMake/BuildDepends/MakeCustomIncludes.cmake +++ b/Tests/RunCMake/BuildDepends/MakeCustomIncludes.cmake @@ -6,7 +6,7 @@ add_custom_command( add_custom_target(generate ALL DEPENDS output.cxx) set_property(TARGET generate PROPERTY INCLUDE_DIRECTORIES ${CMAKE_CURRENT_BINARY_DIR}) -file(GENERATE OUTPUT check-$<LOWER_CASE:$<CONFIG>>.cmake CONTENT " +file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/check-$<LOWER_CASE:$<CONFIG>>.cmake CONTENT " set(check_pairs \"${CMAKE_CURRENT_BINARY_DIR}/output.cxx|${CMAKE_CURRENT_BINARY_DIR}/MakeCustomIncludes.h\" ) diff --git a/Tests/RunCMake/BuildDepends/MakeInProjectOnly.cmake b/Tests/RunCMake/BuildDepends/MakeInProjectOnly.cmake index add9aeb..af6ad86 100644 --- a/Tests/RunCMake/BuildDepends/MakeInProjectOnly.cmake +++ b/Tests/RunCMake/BuildDepends/MakeInProjectOnly.cmake @@ -3,7 +3,7 @@ get_filename_component(include_dir "${CMAKE_BINARY_DIR}" PATH) include_directories("${include_dir}") add_executable(MakeInProjectOnly MakeInProjectOnly.c) set(CMAKE_DEPENDS_IN_PROJECT_ONLY 1) -file(GENERATE OUTPUT check-$<LOWER_CASE:$<CONFIG>>.cmake CONTENT " +file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/check-$<LOWER_CASE:$<CONFIG>>.cmake CONTENT " if (check_step EQUAL 1) set(check_pairs \"$<TARGET_FILE:MakeInProjectOnly>|${include_dir}/MakeInProjectOnly.h\" diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 79f487d..246138b 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -181,8 +181,10 @@ add_RunCMake_test(add_custom_target) add_RunCMake_test(add_dependencies) add_RunCMake_test(add_subdirectory) add_RunCMake_test(build_command) +add_executable(exit_code exit_code.c) +set(execute_process_ARGS -DEXIT_CODE_EXE=$<TARGET_FILE:exit_code>) if(NOT CMake_TEST_EXTERNAL_CMAKE) - set(execute_process_ARGS -DTEST_ENCODING_EXE=$<TARGET_FILE:testEncoding>) + list(APPEND execute_process_ARGS -DTEST_ENCODING_EXE=$<TARGET_FILE:testEncoding>) endif() add_RunCMake_test(execute_process) add_RunCMake_test(export) @@ -213,6 +215,7 @@ add_RunCMake_test(get_property) add_RunCMake_test(if) add_RunCMake_test(include) add_RunCMake_test(include_directories) +add_RunCMake_test(include_guard) add_RunCMake_test(list) add_RunCMake_test(message) add_RunCMake_test(project -DCMake_TEST_RESOURCES=${CMake_TEST_RESOURCES}) @@ -341,6 +344,9 @@ if("${CMAKE_GENERATOR}" MATCHES "Make|Ninja") add_RunCMake_test(ClangTidy -DPSEUDO_TIDY=$<TARGET_FILE:pseudo_tidy>) add_RunCMake_test(IncludeWhatYouUse -DPSEUDO_IWYU=$<TARGET_FILE:pseudo_iwyu>) add_RunCMake_test(Cpplint -DPSEUDO_CPPLINT=$<TARGET_FILE:pseudo_cpplint>) + if(DEFINED CMake_TEST_CUDA) + list(APPEND CompilerLauncher_ARGS -DCMake_TEST_CUDA=${CMake_TEST_CUDA}) + endif() add_RunCMake_test(CompilerLauncher) endif() @@ -371,3 +377,7 @@ if(CMake_TEST_ANDROID_NDK OR CMake_TEST_ANDROID_STANDALONE_TOOLCHAIN) endif() set_property(TEST RunCMake.Android PROPERTY TIMEOUT ${CMake_TEST_ANDROID_TIMEOUT}) endif() + +if(${CMAKE_GENERATOR} MATCHES "Visual Studio ([^89]|[89][0-9])") + add_RunCMake_test(CSharpCustomCommand) +endif() diff --git a/Tests/RunCMake/CPackInstallProperties/FilenameGenex.cmake b/Tests/RunCMake/CPackInstallProperties/FilenameGenex.cmake index 1a373b9..8fc1218 100644 --- a/Tests/RunCMake/CPackInstallProperties/FilenameGenex.cmake +++ b/Tests/RunCMake/CPackInstallProperties/FilenameGenex.cmake @@ -1,6 +1,6 @@ add_executable(mytest test.cpp) -file(GENERATE OUTPUT runtest_info.cmake CONTENT [[ +file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/runtest_info.cmake CONTENT [[ set(EXPECTED_MYTEST_NAME "$<TARGET_FILE_NAME:mytest>") ]]) diff --git a/Tests/RunCMake/CPackInstallProperties/PerConfigValue.cmake b/Tests/RunCMake/CPackInstallProperties/PerConfigValue.cmake index 77fe8ed..b23d3c7 100644 --- a/Tests/RunCMake/CPackInstallProperties/PerConfigValue.cmake +++ b/Tests/RunCMake/CPackInstallProperties/PerConfigValue.cmake @@ -6,7 +6,7 @@ foreach(CONFIG IN LISTS CMAKE_CONFIGURATION_TYPES) OUTPUT_NAME_${UPPER_CONFIG} bar_${CONFIG}) endforeach() -file(GENERATE OUTPUT runtest_info_$<CONFIG>.cmake CONTENT [[ +file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/runtest_info_$<CONFIG>.cmake CONTENT [[ set(CPACK_BUILD_CONFIG "$<CONFIG>") set(EXPECTED_MYTEST_NAME "$<TARGET_FILE_NAME:mytest>") ]]) diff --git a/Tests/RunCMake/CPackInstallProperties/ValueGenex.cmake b/Tests/RunCMake/CPackInstallProperties/ValueGenex.cmake index 2e1d465..2001d9f 100644 --- a/Tests/RunCMake/CPackInstallProperties/ValueGenex.cmake +++ b/Tests/RunCMake/CPackInstallProperties/ValueGenex.cmake @@ -1,6 +1,6 @@ add_executable(mytest test.cpp) -file(GENERATE OUTPUT runtest_info.cmake CONTENT [[ +file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/runtest_info.cmake CONTENT [[ set(EXPECTED_MYTEST_NAME "$<TARGET_FILE_NAME:mytest>") ]]) diff --git a/Tests/RunCMake/CSharpCustomCommand/CMakeLists.txt b/Tests/RunCMake/CSharpCustomCommand/CMakeLists.txt new file mode 100644 index 0000000..74b3ff8 --- /dev/null +++ b/Tests/RunCMake/CSharpCustomCommand/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.3) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/CSharpCustomCommand/CommandWithOutput-check.cmake b/Tests/RunCMake/CSharpCustomCommand/CommandWithOutput-check.cmake new file mode 100644 index 0000000..60d77eb --- /dev/null +++ b/Tests/RunCMake/CSharpCustomCommand/CommandWithOutput-check.cmake @@ -0,0 +1,21 @@ +if(checkLevel EQUAL 0) + message("checking generation (${srcName} does not exist)") + if(EXISTS "${generatedFileName}") + set(RunCMake_TEST_FAILED "file \"${generatedFileName}\" should not exist") + endif() +elseif(checkLevel EQUAL 1) + message("checking build 1 (generate ${srcName})") + if(NOT "${actual_stdout}" MATCHES "${commandComment}") + set(RunCMake_TEST_FAILED "command not executed") + endif() +elseif(checkLevel EQUAL 2) + message("checking build 2 (no change in ${srcName}.in)") + if("${actual_stdout}" MATCHES "${commandComment}") + set(RunCMake_TEST_FAILED "command executed") + endif() +elseif(checkLevel EQUAL 3) + message("checking build 3 (update ${srcName})") + if(NOT "${actual_stdout}" MATCHES "${commandComment}") + set(RunCMake_TEST_FAILED "command not executed") + endif() +endif() diff --git a/Tests/RunCMake/CSharpCustomCommand/CommandWithOutput.cmake b/Tests/RunCMake/CSharpCustomCommand/CommandWithOutput.cmake new file mode 100644 index 0000000..68341fa --- /dev/null +++ b/Tests/RunCMake/CSharpCustomCommand/CommandWithOutput.cmake @@ -0,0 +1,13 @@ +enable_language(CSharp) + +add_executable(CSharpCustomCommand dummy.cs) + +add_custom_command(OUTPUT ${generatedFileName} + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${inputFileName} ${generatedFileName} + MAIN_DEPENDENCY ${inputFileName} + COMMENT "${commandComment}") + +target_sources(CSharpCustomCommand PRIVATE + ${inputFileName} + ${generatedFileName}) diff --git a/Tests/RunCMake/CSharpCustomCommand/RunCMakeTest.cmake b/Tests/RunCMake/CSharpCustomCommand/RunCMakeTest.cmake new file mode 100644 index 0000000..fa5618a --- /dev/null +++ b/Tests/RunCMake/CSharpCustomCommand/RunCMakeTest.cmake @@ -0,0 +1,34 @@ +include(RunCMake) + +# Use a single build tree for a few tests without cleaning. +set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CommandWithOutput-build) +set(RunCMake_TEST_NO_CLEAN 1) +file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}") +file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}") +set(RunCMake-check-file CommandWithOutput-check.cmake) + +set(srcName "test.cs") +set(srcFileName "${CMAKE_CURRENT_LIST_DIR}/${srcName}.in") +set(inputFileName "${RunCMake_TEST_BINARY_DIR}/${srcName}.in") +set(generatedFileName "${RunCMake_TEST_BINARY_DIR}/${srcName}") +set(commandComment "Generating ${srcName}") + +# copy the input file to build dir to avoid changing files in cmake +# source tree. +file(COPY "${srcFileName}" DESTINATION "${RunCMake_TEST_BINARY_DIR}") + +set(RunCMake_TEST_OPTIONS ${RunCMake_TEST_OPTIONS} + "-DinputFileName=${inputFileName}" + "-DgeneratedFileName=${generatedFileName}" + "-DcommandComment=${commandComment}") + +set(checkLevel 0) +run_cmake(CommandWithOutput) +set(checkLevel 1) +run_cmake_command(CommandWithOutput-build1 ${CMAKE_COMMAND} --build . --config Debug) +set(checkLevel 2) +run_cmake_command(CommandWithOutput-build2 ${CMAKE_COMMAND} --build . --config Debug) +# change file content to trigger custom command with next build +file(APPEND ${inputFileName} "\n") +set(checkLevel 3) +run_cmake_command(CommandWithOutput-build3 ${CMAKE_COMMAND} --build . --config Debug) diff --git a/Tests/RunCMake/CSharpCustomCommand/dummy.cs b/Tests/RunCMake/CSharpCustomCommand/dummy.cs new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tests/RunCMake/CSharpCustomCommand/dummy.cs diff --git a/Tests/RunCMake/CSharpCustomCommand/test.cs.in b/Tests/RunCMake/CSharpCustomCommand/test.cs.in new file mode 100644 index 0000000..05a7531 --- /dev/null +++ b/Tests/RunCMake/CSharpCustomCommand/test.cs.in @@ -0,0 +1,8 @@ +class TestCs +{ + public static int Main(string[] args) + { + System.Console.WriteLine("Test C#"); + return 0; + } +} diff --git a/Tests/RunCMake/CompilerLauncher/CUDA-Build-stdout.txt b/Tests/RunCMake/CompilerLauncher/CUDA-Build-stdout.txt new file mode 100644 index 0000000..3313e31 --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/CUDA-Build-stdout.txt @@ -0,0 +1 @@ +.*-E env USED_LAUNCHER=1.* diff --git a/Tests/RunCMake/CompilerLauncher/CUDA-launch-Build-stdout.txt b/Tests/RunCMake/CompilerLauncher/CUDA-launch-Build-stdout.txt new file mode 100644 index 0000000..3313e31 --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/CUDA-launch-Build-stdout.txt @@ -0,0 +1 @@ +.*-E env USED_LAUNCHER=1.* diff --git a/Tests/RunCMake/CompilerLauncher/CUDA-launch.cmake b/Tests/RunCMake/CompilerLauncher/CUDA-launch.cmake new file mode 100644 index 0000000..6b4b816 --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/CUDA-launch.cmake @@ -0,0 +1,3 @@ +set(CTEST_USE_LAUNCHERS 1) +include(CTestUseLaunchers) +include(CUDA.cmake) diff --git a/Tests/RunCMake/CompilerLauncher/CUDA.cmake b/Tests/RunCMake/CompilerLauncher/CUDA.cmake new file mode 100644 index 0000000..fe5560b --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/CUDA.cmake @@ -0,0 +1,4 @@ +enable_language(CUDA) +set(CMAKE_CUDA_COMPILER_LAUNCHER "${CMAKE_COMMAND};-E;env;USED_LAUNCHER=1") +set(CMAKE_VERBOSE_MAKEFILE TRUE) +add_executable(main main.cu) diff --git a/Tests/RunCMake/CompilerLauncher/RunCMakeTest.cmake b/Tests/RunCMake/CompilerLauncher/RunCMakeTest.cmake index 5884d5c..ab26512 100644 --- a/Tests/RunCMake/CompilerLauncher/RunCMakeTest.cmake +++ b/Tests/RunCMake/CompilerLauncher/RunCMakeTest.cmake @@ -15,9 +15,14 @@ function(run_compiler_launcher lang) run_cmake_command(${lang}-Build ${CMAKE_COMMAND} --build . ${verbose_args}) endfunction() -run_compiler_launcher(C) -run_compiler_launcher(CXX) -if (NOT RunCMake_GENERATOR STREQUAL "Watcom WMake") - run_compiler_launcher(C-launch) - run_compiler_launcher(CXX-launch) +set(langs C CXX) +if(CMake_TEST_CUDA) + list(APPEND langs CUDA) endif() + +foreach(lang ${langs}) + run_compiler_launcher(${lang}) + if (NOT RunCMake_GENERATOR STREQUAL "Watcom WMake") + run_compiler_launcher(${lang}-launch) + endif() +endforeach() diff --git a/Tests/RunCMake/CompilerLauncher/main.cu b/Tests/RunCMake/CompilerLauncher/main.cu new file mode 100644 index 0000000..f8b643a --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/main.cu @@ -0,0 +1,4 @@ +int main() +{ + return 0; +} diff --git a/Tests/RunCMake/File_Generate/CMP0070-NEW-check.cmake b/Tests/RunCMake/File_Generate/CMP0070-NEW-check.cmake new file mode 100644 index 0000000..05ec26e --- /dev/null +++ b/Tests/RunCMake/File_Generate/CMP0070-NEW-check.cmake @@ -0,0 +1,13 @@ +foreach(f + "${RunCMake_TEST_SOURCE_DIR}/relative-input-NEW.txt" + "${RunCMake_TEST_BINARY_DIR}/relative-output-NEW.txt" + ) + if(EXISTS "${f}") + file(READ "${f}" content) + if(NOT content MATCHES "^relative-input-NEW[\r\n]*$") + string(APPEND RunCMake_TEST_FAILED "File\n ${f}\ndoes not have expected content.\n") + endif() + else() + string(APPEND RunCMake_TEST_FAILED "Missing\n ${f}\n") + endif() +endforeach() diff --git a/Tests/RunCMake/File_Generate/CMP0070-NEW.cmake b/Tests/RunCMake/File_Generate/CMP0070-NEW.cmake new file mode 100644 index 0000000..1a03822 --- /dev/null +++ b/Tests/RunCMake/File_Generate/CMP0070-NEW.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0070 NEW) +file(GENERATE OUTPUT relative-output-NEW.txt INPUT relative-input-NEW.txt) diff --git a/Tests/RunCMake/File_Generate/CMP0070-OLD-check.cmake b/Tests/RunCMake/File_Generate/CMP0070-OLD-check.cmake new file mode 100644 index 0000000..a71d822 --- /dev/null +++ b/Tests/RunCMake/File_Generate/CMP0070-OLD-check.cmake @@ -0,0 +1,13 @@ +foreach(f + "${RunCMake_TEST_BINARY_DIR}/relative-input-OLD.txt" + "${RunCMake_TEST_BINARY_DIR}/relative-output-OLD.txt" + ) + if(EXISTS "${f}") + file(READ "${f}" content) + if(NOT content MATCHES "^relative-input-OLD[\r\n]*$") + string(APPEND RunCMake_TEST_FAILED "File\n ${f}\ndoes not have expected content.\n") + endif() + else() + string(APPEND RunCMake_TEST_FAILED "Missing\n ${f}\n") + endif() +endforeach() diff --git a/Tests/RunCMake/File_Generate/CMP0070-OLD.cmake b/Tests/RunCMake/File_Generate/CMP0070-OLD.cmake new file mode 100644 index 0000000..0fb47cd --- /dev/null +++ b/Tests/RunCMake/File_Generate/CMP0070-OLD.cmake @@ -0,0 +1,3 @@ +cmake_policy(SET CMP0070 OLD) +file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/relative-input-OLD.txt "relative-input-OLD\n") +file(GENERATE OUTPUT relative-output-OLD.txt INPUT relative-input-OLD.txt) diff --git a/Tests/RunCMake/File_Generate/CMP0070-WARN-check.cmake b/Tests/RunCMake/File_Generate/CMP0070-WARN-check.cmake new file mode 100644 index 0000000..1488df0 --- /dev/null +++ b/Tests/RunCMake/File_Generate/CMP0070-WARN-check.cmake @@ -0,0 +1,13 @@ +foreach(f + "${RunCMake_TEST_BINARY_DIR}/relative-input-WARN.txt" + "${RunCMake_TEST_BINARY_DIR}/relative-output-WARN.txt" + ) + if(EXISTS "${f}") + file(READ "${f}" content) + if(NOT content MATCHES "^relative-input-WARN[\r\n]*$") + string(APPEND RunCMake_TEST_FAILED "File\n ${f}\ndoes not have expected content.\n") + endif() + else() + string(APPEND RunCMake_TEST_FAILED "Missing\n ${f}\n") + endif() +endforeach() diff --git a/Tests/RunCMake/File_Generate/CMP0070-WARN-stderr.txt b/Tests/RunCMake/File_Generate/CMP0070-WARN-stderr.txt new file mode 100644 index 0000000..dbabaa9 --- /dev/null +++ b/Tests/RunCMake/File_Generate/CMP0070-WARN-stderr.txt @@ -0,0 +1,27 @@ +^CMake Warning \(dev\) in CMakeLists.txt: + Policy CMP0070 is not set: Define file\(GENERATE\) behavior for relative + paths. Run "cmake --help-policy CMP0070" for policy details. Use the + cmake_policy command to set the policy and suppress this warning. + + file\(GENERATE\) given relative INPUT path: + + relative-input-WARN.txt + + This is not defined behavior unless CMP0070 is set to NEW. For + compatibility with older versions of CMake, the previous undefined behavior + will be used. +This warning is for project developers. Use -Wno-dev to suppress it.( ++ +CMake Warning \(dev\) in CMakeLists.txt: + Policy CMP0070 is not set: Define file\(GENERATE\) behavior for relative + paths. Run "cmake --help-policy CMP0070" for policy details. Use the + cmake_policy command to set the policy and suppress this warning. + + file\(GENERATE\) given relative OUTPUT path: + + relative-output-WARN.txt + + This is not defined behavior unless CMP0070 is set to NEW. For + compatibility with older versions of CMake, the previous undefined behavior + will be used. +This warning is for project developers. Use -Wno-dev to suppress it.)+$ diff --git a/Tests/RunCMake/File_Generate/CMP0070-WARN.cmake b/Tests/RunCMake/File_Generate/CMP0070-WARN.cmake new file mode 100644 index 0000000..ccb0452 --- /dev/null +++ b/Tests/RunCMake/File_Generate/CMP0070-WARN.cmake @@ -0,0 +1,2 @@ +file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/relative-input-WARN.txt "relative-input-WARN\n") +file(GENERATE OUTPUT relative-output-WARN.txt INPUT relative-input-WARN.txt) diff --git a/Tests/RunCMake/File_Generate/COMPILE_LANGUAGE-genex.cmake b/Tests/RunCMake/File_Generate/COMPILE_LANGUAGE-genex.cmake index e2b081d..59ccf19 100644 --- a/Tests/RunCMake/File_Generate/COMPILE_LANGUAGE-genex.cmake +++ b/Tests/RunCMake/File_Generate/COMPILE_LANGUAGE-genex.cmake @@ -7,6 +7,6 @@ target_compile_options(empty ) file(GENERATE - OUTPUT opts-$<COMPILE_LANGUAGE>.txt + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/opts-$<COMPILE_LANGUAGE>.txt CONTENT "$<TARGET_PROPERTY:empty,COMPILE_OPTIONS>\n" ) diff --git a/Tests/RunCMake/File_Generate/ReRunCMake.cmake b/Tests/RunCMake/File_Generate/ReRunCMake.cmake index 109d60e..541d86d 100644 --- a/Tests/RunCMake/File_Generate/ReRunCMake.cmake +++ b/Tests/RunCMake/File_Generate/ReRunCMake.cmake @@ -1,5 +1,5 @@ file(GENERATE - OUTPUT output_file.txt + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/output_file.txt" INPUT "${CMAKE_CURRENT_BINARY_DIR}/input_file.txt" ) diff --git a/Tests/RunCMake/File_Generate/RunCMakeTest.cmake b/Tests/RunCMake/File_Generate/RunCMakeTest.cmake index 82e903d..b660463 100644 --- a/Tests/RunCMake/File_Generate/RunCMakeTest.cmake +++ b/Tests/RunCMake/File_Generate/RunCMakeTest.cmake @@ -1,5 +1,9 @@ include(RunCMake) +run_cmake(CMP0070-NEW) +run_cmake(CMP0070-OLD) +run_cmake(CMP0070-WARN) + run_cmake(CommandConflict) if("${RunCMake_GENERATOR}" MATCHES "Visual Studio|Xcode") run_cmake(OutputConflict) diff --git a/Tests/RunCMake/File_Generate/WriteIfDifferent.cmake b/Tests/RunCMake/File_Generate/WriteIfDifferent.cmake index d1d832a..bb36a4c 100644 --- a/Tests/RunCMake/File_Generate/WriteIfDifferent.cmake +++ b/Tests/RunCMake/File_Generate/WriteIfDifferent.cmake @@ -1,5 +1,5 @@ file(GENERATE - OUTPUT output_file.txt + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/output_file.txt CONTENT "123" ) diff --git a/Tests/RunCMake/File_Generate/relative-input-NEW.txt b/Tests/RunCMake/File_Generate/relative-input-NEW.txt new file mode 100644 index 0000000..7293e90 --- /dev/null +++ b/Tests/RunCMake/File_Generate/relative-input-NEW.txt @@ -0,0 +1 @@ +relative-input-NEW diff --git a/Tests/RunCMake/Framework/FrameworkLayout.cmake b/Tests/RunCMake/Framework/FrameworkLayout.cmake index 3d62a8a..4f42459 100644 --- a/Tests/RunCMake/Framework/FrameworkLayout.cmake +++ b/Tests/RunCMake/Framework/FrameworkLayout.cmake @@ -22,4 +22,4 @@ set_source_files_properties(some.txt PROPERTIES MACOSX_PACKAGE_LOCATION somedir) add_custom_command(TARGET Framework POST_BUILD COMMAND /usr/bin/file $<TARGET_FILE:Framework>) -file(GENERATE OUTPUT FrameworkName.cmake CONTENT "set(framework-dir \"$<TARGET_BUNDLE_DIR:Framework>\")\n") +file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/FrameworkName.cmake CONTENT "set(framework-dir \"$<TARGET_BUNDLE_DIR:Framework>\")\n") diff --git a/Tests/RunCMake/TargetObjects/NoTarget.cmake b/Tests/RunCMake/TargetObjects/NoTarget.cmake index 5d7e33e..268577d 100644 --- a/Tests/RunCMake/TargetObjects/NoTarget.cmake +++ b/Tests/RunCMake/TargetObjects/NoTarget.cmake @@ -1,7 +1,7 @@ add_library(iface INTERFACE) target_sources(iface INTERFACE $<TARGET_OBJECTS:NoTarget>) -file(GENERATE OUTPUT test_output CONTENT $<TARGET_OBJECTS:NoTarget>) -file(GENERATE OUTPUT test_output2 CONTENT $<TARGET_PROPERTY:iface,INTERFACE_SOURCES>) +file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/test_output CONTENT $<TARGET_OBJECTS:NoTarget>) +file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/test_output2 CONTENT $<TARGET_PROPERTY:iface,INTERFACE_SOURCES>) install(FILES $<TARGET_OBJECTS:NoTarget> DESTINATION objects) diff --git a/Tests/RunCMake/TargetObjects/NotObjlibTarget.cmake b/Tests/RunCMake/TargetObjects/NotObjlibTarget.cmake index 8e5fdd0..3bb3e37 100644 --- a/Tests/RunCMake/TargetObjects/NotObjlibTarget.cmake +++ b/Tests/RunCMake/TargetObjects/NotObjlibTarget.cmake @@ -1,3 +1,3 @@ add_library(StaticLib empty.cpp) -file(GENERATE OUTPUT test_output CONTENT $<TARGET_OBJECTS:StaticLib>) +file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/test_output CONTENT $<TARGET_OBJECTS:StaticLib>) diff --git a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake index 3af877f..6e7c2f3 100644 --- a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake +++ b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake @@ -4,3 +4,4 @@ run_cmake(VsTargetsFileReferences) run_cmake(VsCustomProps) run_cmake(VsDebuggerWorkingDir) run_cmake(VsCSharpCustomTags) +run_cmake(VsCSharpReferenceProps) diff --git a/Tests/RunCMake/VS10Project/VsCSharpCustomTags-check.cmake b/Tests/RunCMake/VS10Project/VsCSharpCustomTags-check.cmake index 70ea193..9eb4619 100644 --- a/Tests/RunCMake/VS10Project/VsCSharpCustomTags-check.cmake +++ b/Tests/RunCMake/VS10Project/VsCSharpCustomTags-check.cmake @@ -4,20 +4,31 @@ if(NOT EXISTS "${csProjectFile}") return() endif() -set(tagFound FALSE) +# test VS_CSHARP_* for the following extensions +set(fileExtensions + "cs" + "png" + "jpg" + "xml" + "settings") +# set(tagName "MyCustomTag") set(tagValue "MyCustomValue") file(STRINGS "${csProjectFile}" lines) -foreach(line IN LISTS lines) - if(line MATCHES "^ *<${tagName}>${tagValue}</${tagName}>") - message(STATUS "foo.csproj has tag ${tagName} with value ${tagValue} defined") - set(tagFound TRUE) + +foreach(e ${fileExtensions}) + string(TOUPPER ${e} eUC) + set(tagFound FALSE) + foreach(line IN LISTS lines) + if(line MATCHES "^ *<${tagName}${eUC}>${tagValue}${eUC}</${tagName}${eUC}>") + message(STATUS "foo.csproj has tag ${tagName}${eUC} with value ${tagValue}${eUC} defined") + set(tagFound TRUE) + endif() + endforeach() + if(NOT tagFound) + set(RunCMake_TEST_FAILED "Source file tag ${tagName}${eUC} with value ${tagValue}${eUC} not found.") + return() endif() endforeach() - -if(NOT tagFound) - set(RunCMake_TEST_FAILED "Source file tag ${tagName} with value ${tagValue} not found.") - return() -endif() diff --git a/Tests/RunCMake/VS10Project/VsCSharpCustomTags.cmake b/Tests/RunCMake/VS10Project/VsCSharpCustomTags.cmake index c51e9c3..45766a0 100644 --- a/Tests/RunCMake/VS10Project/VsCSharpCustomTags.cmake +++ b/Tests/RunCMake/VS10Project/VsCSharpCustomTags.cmake @@ -1,11 +1,27 @@ enable_language(CSharp) -add_library(foo foo.cs) -set(props_file "${CMAKE_CURRENT_SOURCE_DIR}/my.props") +# test VS_CSHARP_* for the following extensions +set(fileExtensions + "cs" + "png" + "jpg" + "xml" + "settings") +# set(tagName "MyCustomTag") set(tagValue "MyCustomValue") -set_source_files_properties(foo.cs - PROPERTIES - VS_CSHARP_${tagName} "${tagValue}") +set(fileNames) +foreach(e ${fileExtensions}) + set(currentFile "${CMAKE_CURRENT_BINARY_DIR}/foo.${e}") + list(APPEND fileNames ${currentFile}) + execute_process(COMMAND ${CMAKE_COMMAND} -E touch + "${currentFile}") + string(TOUPPER ${e} eUC) + set_source_files_properties("${currentFile}" + PROPERTIES + VS_CSHARP_${tagName}${eUC} "${tagValue}${eUC}") +endforeach() + +add_library(foo ${fileNames}) diff --git a/Tests/RunCMake/VS10Project/VsCSharpReferenceProps-check.cmake b/Tests/RunCMake/VS10Project/VsCSharpReferenceProps-check.cmake new file mode 100644 index 0000000..8b9bb67 --- /dev/null +++ b/Tests/RunCMake/VS10Project/VsCSharpReferenceProps-check.cmake @@ -0,0 +1,49 @@ +set(csProjectFile "${RunCMake_TEST_BINARY_DIR}/foo.csproj") +if(NOT EXISTS "${csProjectFile}") + set(RunCMake_TEST_FAILED "Project file ${csProjectFile} does not exist.") + return() +endif() + +set(test1Reference "System") +set(test1Tag "Hello") +set(test1Value "World") + +set(test2Reference "foo2") +set(test2Tag "Hallo") +set(test2Value "Welt") + +set(tag1Found FALSE) +set(ref1Found FALSE) + +file(STRINGS "${csProjectFile}" lines) + +foreach(i 1 2) + set(testReference "${test${i}Reference}") + set(testTag "${test${i}Tag}") + set(testValue "${test${i}Value}") + foreach(line IN LISTS lines) + if(line MATCHES "^ *<(Project|)Reference .*>$") + set(validTag FALSE) + if(line MATCHES "^ *<(Project|)Reference .*\".*${testReference}.*\".*>$") + set(validTag TRUE) + message(STATUS "foo.csproj is using reference ${testReference}") + set(ref${i}Found TRUE) + endif() + endif() + if(line MATCHES "^ *<${testTag}>${testValue}</${testTag}>$") + if(validTag) + message(STATUS "foo.csproj reference ${testReference} has tag ${testTag}") + set(tag${i}Found TRUE) + else() + message(STATUS "tag ${testTag} found in wrong place!") + set(tag${i}Found FALSE) + endif() + endif() + endforeach() +endforeach() + +if(NOT tag1Found OR NOT ref1Found OR + NOT tag2Found OR NOT ref2Found) + set(RunCMake_TEST_FAILED "Custom reference XML tag not found.") + return() +endif() diff --git a/Tests/RunCMake/VS10Project/VsCSharpReferenceProps.cmake b/Tests/RunCMake/VS10Project/VsCSharpReferenceProps.cmake new file mode 100644 index 0000000..2af1756 --- /dev/null +++ b/Tests/RunCMake/VS10Project/VsCSharpReferenceProps.cmake @@ -0,0 +1,19 @@ +enable_language(CSharp) +add_library(foo foo.cs) +add_library(foo2 foo.cs) + +set(test1Reference "System") +set(test1Tag "Hello") +set(test1Value "World") + +set(test2Reference "foo2") +set(test2Tag "Hallo") +set(test2Value "Welt") + +target_link_libraries(foo foo2) + +set_target_properties(foo PROPERTIES + VS_DOTNET_REFERENCES "${test1Reference};Blubb" + VS_DOTNET_REFERENCEPROP_${test1Reference}_TAG_${test1Tag} ${test1Value} + VS_DOTNET_REFERENCEPROP_${test2Reference}_TAG_${test2Tag} ${test2Value} + ) diff --git a/Tests/RunCMake/execute_process/ExitValues-stdout.txt b/Tests/RunCMake/execute_process/ExitValues-stdout.txt new file mode 100644 index 0000000..3bcaf46 --- /dev/null +++ b/Tests/RunCMake/execute_process/ExitValues-stdout.txt @@ -0,0 +1,14 @@ +^-- 1 - 1 RESULT_VARIABLE: 0 +-- 1 - 2 RESULT_VARIABLE: [^0].* +-- 2 - 1 RESULT_VARIABLE: 0 +-- 2 - 1 RESULTS_VARIABLE: 0 +-- 2 - 2 RESULT_VARIABLE: [^0].* +-- 2 - 2 RESULTS_VARIABLE: [^0].* +-- 3 - 1 RESULTS_VARIABLE: 0 +-- 3 - 2 RESULTS_VARIABLE: [^0].* +-- 4 - 1 RESULT_VARIABLE: 0 +-- 4 - 1 RESULTS_VARIABLE: [^0].*;0;[^0].*;0;[^0].*;0 +-- 4 - 1 RESULTS_VARIABLE_LENGTH: 6 +-- 5 - 1 RESULT_VARIABLE: [^0].* +-- 5 - 1 RESULTS_VARIABLE: 0;0;[^0].* +-- 5 - 1 RESULTS_VARIABLE_LENGTH: 3$ diff --git a/Tests/RunCMake/execute_process/ExitValues.cmake b/Tests/RunCMake/execute_process/ExitValues.cmake new file mode 100644 index 0000000..d80a57b --- /dev/null +++ b/Tests/RunCMake/execute_process/ExitValues.cmake @@ -0,0 +1,120 @@ +#1st TEST RESULT_VARIABLE ONLY +execute_process(COMMAND ${EXIT_CODE_EXE} "zero_exit" + RESULT_VARIABLE r0 + ) +message(STATUS " 1 - 1 RESULT_VARIABLE: ${r0}") +if(NOT r0 EQUAL 0) + message(FATAL_ERROR "zero exit code expected") +endif() +execute_process(COMMAND ${EXIT_CODE_EXE} "non_zero_exit" + RESULT_VARIABLE r01 + ERROR_QUIET + ) +message(STATUS " 1 - 2 RESULT_VARIABLE: ${r01}") +if(r01 EQUAL 0) + message(FATAL_ERROR "non-zero exit code expected") +endif() +#2nd TEST RESULT_VARIABLE and RESULTS_VARIABLE +execute_process(COMMAND ${EXIT_CODE_EXE} "zero_exit" + RESULT_VARIABLE r1 + RESULTS_VARIABLE r1s + ) +message(STATUS " 2 - 1 RESULT_VARIABLE: ${r1}") +message(STATUS " 2 - 1 RESULTS_VARIABLE: ${r1s}") +if(NOT r1 EQUAL 0 OR NOT r1s EQUAL 0) + message(FATAL_ERROR "zero exit code expected") +endif() +execute_process(COMMAND ${EXIT_CODE_EXE} "non_zero_exit" + RESULT_VARIABLE r11 + RESULTS_VARIABLE r11s + ERROR_QUIET + ) +message(STATUS " 2 - 2 RESULT_VARIABLE: ${r11}") +message(STATUS " 2 - 2 RESULTS_VARIABLE: ${r11s}") +if(r11 EQUAL 0 OR r11s EQUAL 0) + message(FATAL_ERROR "non-zero exit code expected") +endif() +#3rd TEST RESULTS_VARIABLE +execute_process(COMMAND ${EXIT_CODE_EXE} "zero_exit" + RESULTS_VARIABLE r2s + ) +message(STATUS " 3 - 1 RESULTS_VARIABLE: ${r2s}") +if(NOT r2s EQUAL 0) + message(FATAL_ERROR "zero exit code expected") +endif() +execute_process(COMMAND ${EXIT_CODE_EXE} "non_zero_exit" + RESULTS_VARIABLE r21s + ERROR_QUIET + ) +message(STATUS " 3 - 2 RESULTS_VARIABLE: ${r21s}") +if(r21s EQUAL 0) + message(FATAL_ERROR "non-zero exit code expected") +endif() +#4th TEST RESULT_VARIABLE and RESULTS_VARIABLE WITH MULTICOMMAND +execute_process(COMMAND ${EXIT_CODE_EXE} "non_zero_exit" + COMMAND ${EXIT_CODE_EXE} "zero_exit" + COMMAND ${EXIT_CODE_EXE} "non_zero_exit" + COMMAND ${EXIT_CODE_EXE} "zero_exit" + COMMAND ${EXIT_CODE_EXE} "non_zero_exit" + COMMAND ${EXIT_CODE_EXE} "zero_exit" + RESULT_VARIABLE r31 + RESULTS_VARIABLE r31s + OUTPUT_QUIET + ERROR_QUIET + ) +message(STATUS " 4 - 1 RESULT_VARIABLE: ${r31}") +message(STATUS " 4 - 1 RESULTS_VARIABLE: ${r31s}") +if(NOT r31 EQUAL 0) + message(FATAL_ERROR "zero exit code expected for last command") +endif() +list(LENGTH r31s r31sLen) +message(STATUS " 4 - 1 RESULTS_VARIABLE_LENGTH: ${r31sLen}") +if(NOT r31sLen EQUAL 6) + message(FATAL_ERROR "length of RESULTS_VARIABLE is not as expected") +else() + foreach(loop_var RANGE 5) + list(GET r31s ${loop_var} rsLocal) + math(EXPR isOdd "${loop_var} % 2") + if(isOdd) + if(NOT rsLocal EQUAL 0) + message(FATAL_ERROR "zero exit code expected") + endif() + else() + if(rsLocal EQUAL 0) + message(FATAL_ERROR "non-zero exit code expected") + endif() + endif() + endforeach() +endif() +#5th TEST RESULT_VARIABLE and RESULTS_VARIABLE WITH MULTICOMMAND +execute_process(COMMAND ${EXIT_CODE_EXE} "zero_exit" + COMMAND ${EXIT_CODE_EXE} "zero_exit" + COMMAND ${EXIT_CODE_EXE} "non_zero_exit" + RESULT_VARIABLE r41 + RESULTS_VARIABLE r41s + OUTPUT_QUIET + ERROR_QUIET + ) +message(STATUS " 5 - 1 RESULT_VARIABLE: ${r41}") +message(STATUS " 5 - 1 RESULTS_VARIABLE: ${r41s}") +if(r41 EQUAL 0) + message(FATAL_ERROR "non-zero exit code expected for last command") +endif() +list(LENGTH r41s r41sLen) +message(STATUS " 5 - 1 RESULTS_VARIABLE_LENGTH: ${r41sLen}") +if(NOT r31sLen EQUAL 6) + message(FATAL_ERROR "length of RESULTS_VARIABLE is not as expected") +else() + list(GET r41s 0 rsLocal) + if(NOT rsLocal EQUAL 0) + message(FATAL_ERROR "zero exit code expected") + endif() + list(GET r41s 1 rsLocal) + if(NOT rsLocal EQUAL 0) + message(FATAL_ERROR "zero exit code expected") + endif() + list(GET r41s 2 rsLocal) + if(rsLocal EQUAL 0) + message(FATAL_ERROR "non-zero exit code expected") + endif() +endif() diff --git a/Tests/RunCMake/execute_process/RunCMakeTest.cmake b/Tests/RunCMake/execute_process/RunCMakeTest.cmake index 62e18c6..83589bb 100644 --- a/Tests/RunCMake/execute_process/RunCMakeTest.cmake +++ b/Tests/RunCMake/execute_process/RunCMakeTest.cmake @@ -11,3 +11,7 @@ run_cmake(EncodingMissing) if(TEST_ENCODING_EXE) run_cmake_command(EncodingUTF8 ${CMAKE_COMMAND} -DTEST_ENCODING=UTF8 -DTEST_ENCODING_EXE=${TEST_ENCODING_EXE} -P ${RunCMake_SOURCE_DIR}/Encoding.cmake) endif() + +if(EXIT_CODE_EXE) + run_cmake_command(ExitValues ${CMAKE_COMMAND} -DEXIT_CODE_EXE=${EXIT_CODE_EXE} -P ${RunCMake_SOURCE_DIR}/ExitValues.cmake) +endif() diff --git a/Tests/RunCMake/exit_code.c b/Tests/RunCMake/exit_code.c new file mode 100644 index 0000000..3eba019 --- /dev/null +++ b/Tests/RunCMake/exit_code.c @@ -0,0 +1,30 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +// Usage: +// +// /path/to/program arg1 [arg2 [...]] +// +// Return EXIT_SUCCESS if 'zero_exit' +// string was found in <arg1>. +// Return EXIT_FAILURE if 'non_zero_exit' +// string was found in <arg1>. + +int main(int argc, const char* argv[]) +{ + const char* substring_failure = "non_zero_exit"; + const char* substring_success = "zero_exit"; + const char* str = argv[1]; + if (argc < 2) { + return EXIT_FAILURE; + } + if (strcmp(str, substring_success) == 0) { + return EXIT_SUCCESS; + } else if (strcmp(str, substring_failure) == 0) { + return EXIT_FAILURE; + } + fprintf(stderr, "Failed to find string '%s' in '%s'\n", substring_success, + str); + return EXIT_FAILURE; +} diff --git a/Tests/RunCMake/include_guard/CMakeLists.txt b/Tests/RunCMake/include_guard/CMakeLists.txt new file mode 100644 index 0000000..d3137f6 --- /dev/null +++ b/Tests/RunCMake/include_guard/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.9) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/include_guard/DirectoryScope.cmake b/Tests/RunCMake/include_guard/DirectoryScope.cmake new file mode 100644 index 0000000..d6c5a3c --- /dev/null +++ b/Tests/RunCMake/include_guard/DirectoryScope.cmake @@ -0,0 +1,19 @@ +set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/Scripts") + +# Test include_guard with DIRECTORY scope + +# Add subdirectory which includes DirScript three times: +# 1. Include at inner function scope +# 2. At directory scope +# 3. At another subdirectory to check that the guard is checked +# against parent directories +add_subdirectory(sub_dir_script1) +# Add another directory which includes DirScript +add_subdirectory(sub_dir_script2) + +# check inclusions count +get_property(dir_count GLOBAL PROPERTY DIR_SCRIPT_COUNT) +if(NOT dir_count EQUAL 2) + message(FATAL_ERROR + "Wrong DIR_SCRIPT_COUNT value: ${dir_count}, expected: 2") +endif() diff --git a/Tests/RunCMake/include_guard/GlobalScope.cmake b/Tests/RunCMake/include_guard/GlobalScope.cmake new file mode 100644 index 0000000..02137fa --- /dev/null +++ b/Tests/RunCMake/include_guard/GlobalScope.cmake @@ -0,0 +1,11 @@ +set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/Scripts") + +# Test GLOBAL include guard +add_subdirectory(global_script_dir) +include(GlobScript) + +get_property(glob_count GLOBAL PROPERTY GLOB_SCRIPT_COUNT) +if(NOT glob_count EQUAL 1) + message(FATAL_ERROR + "Wrong GLOB_SCRIPT_COUNT value: ${glob_count}, expected: 1") +endif() diff --git a/Tests/RunCMake/include_guard/InvalidArgumentsNumber-result.txt b/Tests/RunCMake/include_guard/InvalidArgumentsNumber-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/include_guard/InvalidArgumentsNumber-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/include_guard/InvalidArgumentsNumber-stderr.txt b/Tests/RunCMake/include_guard/InvalidArgumentsNumber-stderr.txt new file mode 100644 index 0000000..cdd33ac --- /dev/null +++ b/Tests/RunCMake/include_guard/InvalidArgumentsNumber-stderr.txt @@ -0,0 +1,5 @@ +CMake Error at InvalidArgumentsNumber.cmake:1 \(include_guard\): + include_guard given an invalid number of arguments. The command takes at + most 1 argument. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/include_guard/InvalidArgumentsNumber.cmake b/Tests/RunCMake/include_guard/InvalidArgumentsNumber.cmake new file mode 100644 index 0000000..a63a395 --- /dev/null +++ b/Tests/RunCMake/include_guard/InvalidArgumentsNumber.cmake @@ -0,0 +1 @@ +include_guard(ARG1 ARG2) diff --git a/Tests/RunCMake/include_guard/InvalidScope-result.txt b/Tests/RunCMake/include_guard/InvalidScope-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/include_guard/InvalidScope-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/include_guard/InvalidScope-stderr.txt b/Tests/RunCMake/include_guard/InvalidScope-stderr.txt new file mode 100644 index 0000000..456709d --- /dev/null +++ b/Tests/RunCMake/include_guard/InvalidScope-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at InvalidScope.cmake:1 \(include_guard\): + include_guard given an invalid scope: INVALID +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/include_guard/InvalidScope.cmake b/Tests/RunCMake/include_guard/InvalidScope.cmake new file mode 100644 index 0000000..f69f9fd --- /dev/null +++ b/Tests/RunCMake/include_guard/InvalidScope.cmake @@ -0,0 +1 @@ +include_guard(INVALID) diff --git a/Tests/RunCMake/include_guard/RunCMakeTest.cmake b/Tests/RunCMake/include_guard/RunCMakeTest.cmake new file mode 100644 index 0000000..e87bddd --- /dev/null +++ b/Tests/RunCMake/include_guard/RunCMakeTest.cmake @@ -0,0 +1,7 @@ +include(RunCMake) + +run_cmake(VariableScope) +run_cmake(DirectoryScope) +run_cmake(GlobalScope) +run_cmake(InvalidScope) +run_cmake(InvalidArgumentsNumber) diff --git a/Tests/RunCMake/include_guard/Scripts/DirScript.cmake b/Tests/RunCMake/include_guard/Scripts/DirScript.cmake new file mode 100644 index 0000000..e61d180 --- /dev/null +++ b/Tests/RunCMake/include_guard/Scripts/DirScript.cmake @@ -0,0 +1,12 @@ +include_guard(DIRECTORY) + +set(prop_name DIR_SCRIPT_COUNT) +get_property(count_is_set GLOBAL PROPERTY ${prop_name} SET) + +if(NOT count_is_set) + set_property(GLOBAL PROPERTY ${prop_name} 1) +else() + get_property(count GLOBAL PROPERTY ${prop_name}) + math(EXPR count "${count} + 1") + set_property(GLOBAL PROPERTY ${prop_name} ${count}) +endif() diff --git a/Tests/RunCMake/include_guard/Scripts/GlobScript.cmake b/Tests/RunCMake/include_guard/Scripts/GlobScript.cmake new file mode 100644 index 0000000..c26bf40 --- /dev/null +++ b/Tests/RunCMake/include_guard/Scripts/GlobScript.cmake @@ -0,0 +1,12 @@ +include_guard(GLOBAL) + +set(prop_name GLOB_SCRIPT_COUNT) +get_property(count_is_set GLOBAL PROPERTY ${prop_name} SET) + +if(NOT count_is_set) + set_property(GLOBAL PROPERTY ${prop_name} 1) +else() + get_property(count GLOBAL PROPERTY ${prop_name}) + math(EXPR count "${count} + 1") + set_property(GLOBAL PROPERTY ${prop_name} ${count}) +endif() diff --git a/Tests/RunCMake/include_guard/Scripts/VarScript.cmake b/Tests/RunCMake/include_guard/Scripts/VarScript.cmake new file mode 100644 index 0000000..3080377 --- /dev/null +++ b/Tests/RunCMake/include_guard/Scripts/VarScript.cmake @@ -0,0 +1,12 @@ +include_guard() + +set(prop_name VAR_SCRIPT_COUNT) +get_property(count_is_set GLOBAL PROPERTY ${prop_name} SET) + +if(NOT count_is_set) + set_property(GLOBAL PROPERTY ${prop_name} 1) +else() + get_property(count GLOBAL PROPERTY ${prop_name}) + math(EXPR count "${count} + 1") + set_property(GLOBAL PROPERTY ${prop_name} ${count}) +endif() diff --git a/Tests/RunCMake/include_guard/VariableScope.cmake b/Tests/RunCMake/include_guard/VariableScope.cmake new file mode 100644 index 0000000..7f8477d --- /dev/null +++ b/Tests/RunCMake/include_guard/VariableScope.cmake @@ -0,0 +1,24 @@ +set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/Scripts") + +# Test include_guard with VARIABLE scope +function(var_include_func) + # Include twice in the same scope + include(VarScript) + include(VarScript) + get_property(var_count GLOBAL PROPERTY VAR_SCRIPT_COUNT) + if(NOT var_count EQUAL 1) + message(FATAL_ERROR + "Wrong VAR_SCRIPT_COUNT value: ${var_count}, expected: 1") + endif() +endfunction() + +var_include_func() + +# Check again that include_guard has been reset +include(VarScript) + +get_property(var_count GLOBAL PROPERTY VAR_SCRIPT_COUNT) +if(NOT var_count EQUAL 2) + message(FATAL_ERROR + "Wrong VAR_SCRIPT_COUNT value: ${var_count}, expected: 2") +endif() diff --git a/Tests/RunCMake/include_guard/global_script_dir/CMakeLists.txt b/Tests/RunCMake/include_guard/global_script_dir/CMakeLists.txt new file mode 100644 index 0000000..ee7ea2e --- /dev/null +++ b/Tests/RunCMake/include_guard/global_script_dir/CMakeLists.txt @@ -0,0 +1 @@ +include(GlobScript) diff --git a/Tests/RunCMake/include_guard/sub_dir_script1/CMakeLists.txt b/Tests/RunCMake/include_guard/sub_dir_script1/CMakeLists.txt new file mode 100644 index 0000000..d3626e5 --- /dev/null +++ b/Tests/RunCMake/include_guard/sub_dir_script1/CMakeLists.txt @@ -0,0 +1,9 @@ +function(dir_check) + include(DirScript) +endfunction() + +dir_check() + +include(DirScript) + +add_subdirectory(sub_dir_script3) diff --git a/Tests/RunCMake/include_guard/sub_dir_script1/sub_dir_script3/CMakeLists.txt b/Tests/RunCMake/include_guard/sub_dir_script1/sub_dir_script3/CMakeLists.txt new file mode 100644 index 0000000..1c3b1b2 --- /dev/null +++ b/Tests/RunCMake/include_guard/sub_dir_script1/sub_dir_script3/CMakeLists.txt @@ -0,0 +1 @@ +include(DirScript) diff --git a/Tests/RunCMake/include_guard/sub_dir_script2/CMakeLists.txt b/Tests/RunCMake/include_guard/sub_dir_script2/CMakeLists.txt new file mode 100644 index 0000000..1c3b1b2 --- /dev/null +++ b/Tests/RunCMake/include_guard/sub_dir_script2/CMakeLists.txt @@ -0,0 +1 @@ +include(DirScript) diff --git a/Tests/XCTest/CMakeLists.txt b/Tests/XCTest/CMakeLists.txt index d40c40e..d0b07ea 100644 --- a/Tests/XCTest/CMakeLists.txt +++ b/Tests/XCTest/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.1) -project(XCTest) +project(XCTest C) enable_testing() find_package(XCTest REQUIRED) diff --git a/Utilities/cmcurl/CMakeLists.txt b/Utilities/cmcurl/CMakeLists.txt index 45ae3de..d85f366 100644 --- a/Utilities/cmcurl/CMakeLists.txt +++ b/Utilities/cmcurl/CMakeLists.txt @@ -929,6 +929,8 @@ if(HAVE_LIBWS2_32) set(CMAKE_REQUIRED_LIBRARIES ws2_32) elseif(HAVE_LIBSOCKET) set(CMAKE_REQUIRED_LIBRARIES socket) +elseif(HAVE_LIBNETWORK) + set(CMAKE_REQUIRED_LIBRARIES network) endif() check_symbol_exists(basename "${CURL_INCLUDES}" HAVE_BASENAME) @@ -9,26 +9,22 @@ die() { # Compile flag extraction function. cmake_extract_standard_flags() { - cd "${cmake_source_dir}/Modules/Compiler/" - for file in ${1:-*}-${2}.cmake; do - cat "${file}" \ - | sed -n "s/ *set *( *CMAKE_${2}${3}_EXTENSION_COMPILE_OPTION *\"\{0,1\}\([^\")]*\).*/\1/p" \ - | tr ';' ' ' - done + sed -n "s/ *set *( *CMAKE_${2}${3}_EXTENSION_COMPILE_OPTION *\"\{0,1\}\([^\")]*\).*/\1/p" \ + "${cmake_source_dir}/Modules/Compiler/"${1:-*}-${2}.cmake 2>/dev/null | tr ';' ' ' } # Version number extraction function. cmake_version_component() { - cat "${cmake_source_dir}/Source/CMakeVersion.cmake" | sed -n " + sed -n " /^set(CMake_VERSION_${1}/ {s/set(CMake_VERSION_${1} *\([0-9]*\))/\1/;p;} -" +" "${cmake_source_dir}/Source/CMakeVersion.cmake" } # Install destination extraction function. cmake_install_dest_default() { - cat "${cmake_source_dir}/Source/CMakeInstallDestinations.cmake" | sed -n ' + sed -n ' /^ *set(CMAKE_'"${1}"'_DIR_DEFAULT.*) # '"${2}"'$/ { s/^ *set(CMAKE_'"${1}"'_DIR_DEFAULT *"\([^"]*\)").*$/\1/ s/${CMake_VERSION_MAJOR}/'"${cmake_version_major}"'/ @@ -37,12 +33,12 @@ cmake_install_dest_default() p q } -' +' "${cmake_source_dir}/Source/CMakeInstallDestinations.cmake" } cmake_toupper() { - echo "$1" | sed 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' + echo "$1" | tr '[:lower:]' '[:upper:]' } # Detect system and directory information. @@ -84,7 +80,7 @@ cmake_sphinx_build="" cmake_sphinx_flags="" # Determine whether this is a Cygwin environment. -if echo "${cmake_system}" | grep CYGWIN >/dev/null 2>&1; then +if echo "${cmake_system}" | grep -q CYGWIN; then cmake_system_cygwin=true cmake_doc_dir_keyword="CYGWIN" cmake_man_dir_keyword="CYGWIN" @@ -93,21 +89,21 @@ else fi # Determine whether this is a MinGW environment. -if echo "${cmake_system}" | grep 'MINGW\|MSYS' >/dev/null 2>&1; then +if echo "${cmake_system}" | grep -q 'MINGW\|MSYS'; then cmake_system_mingw=true else cmake_system_mingw=false fi # Determine whether this is OS X -if echo "${cmake_system}" | grep Darwin >/dev/null 2>&1; then +if echo "${cmake_system}" | grep -q Darwin; then cmake_system_darwin=true else cmake_system_darwin=false fi # Determine whether this is BeOS -if echo "${cmake_system}" | grep BeOS >/dev/null 2>&1; then +if echo "${cmake_system}" | grep -q BeOS; then cmake_system_beos=true cmake_doc_dir_keyword="HAIKU" cmake_man_dir_keyword="HAIKU" @@ -116,7 +112,7 @@ else fi # Determine whether this is Haiku -if echo "${cmake_system}" | grep Haiku >/dev/null 2>&1; then +if echo "${cmake_system}" | grep -q Haiku; then cmake_system_haiku=true cmake_doc_dir_keyword="HAIKU" cmake_man_dir_keyword="HAIKU" @@ -125,21 +121,21 @@ else fi # Determine whether this is OpenVMS -if echo "${cmake_system}" | grep OpenVMS >/dev/null 2>&1; then +if echo "${cmake_system}" | grep -q OpenVMS; then cmake_system_openvms=true else cmake_system_openvms=false fi # Determine whether this is HP-UX -if echo "${cmake_system}" | grep HP-UX >/dev/null 2>&1; then +if echo "${cmake_system}" | grep -q HP-UX; then cmake_system_hpux=true else cmake_system_hpux=false fi # Determine whether this is Linux -if echo "${cmake_system}" | grep Linux >/dev/null 2>&1; then +if echo "${cmake_system}" | grep -q Linux; then cmake_system_linux=true else cmake_system_linux=false @@ -150,11 +146,11 @@ else # may falsely detect parisc on HP-UX m68k cmake_machine_parisc=false if ${cmake_system_linux}; then - if uname -m | grep parisc >/dev/null 2>&1; then + if uname -m | grep -q parisc; then cmake_machine_parisc=true fi elif ${cmake_system_hpux}; then - if uname -m | grep ia64 >/dev/null 2>&1; then : ; else + if uname -m | grep -q ia64; then : ; else cmake_machine_parisc=true fi fi @@ -334,6 +330,7 @@ CMAKE_CXX_SOURCES="\ cmHexFileConverter \ cmIfCommand \ cmIncludeCommand \ + cmIncludeGuardCommand \ cmIncludeDirectoryCommand \ cmIncludeRegularExpressionCommand \ cmInstallCommand \ @@ -581,8 +578,7 @@ cmake_replace_string () SEARCHFOR="$3" REPLACEWITH="$4" if [ -f "${INFILE}" ] || ${cmake_system_openvms}; then - cat "${INFILE}" | - sed "s/\@${SEARCHFOR}\@/${REPLACEWITH}/g" > "${OUTFILE}${_tmp}" + sed "s/\@${SEARCHFOR}\@/${REPLACEWITH}/g" "${INFILE}" > "${OUTFILE}${_tmp}" if [ -f "${OUTFILE}${_tmp}" ]; then if "${_diff}" "${OUTFILE}" "${OUTFILE}${_tmp}" > /dev/null 2> /dev/null ; then #echo "Files are the same" @@ -604,15 +600,14 @@ cmake_kwsys_config_replace_string () APPEND="$*" if [ -f "${INFILE}" ] || ${cmake_system_openvms}; then echo "${APPEND}" > "${OUTFILE}${_tmp}" - cat "${INFILE}" | - sed "/./ {s/\@KWSYS_NAMESPACE\@/cmsys/g; - s/@KWSYS_BUILD_SHARED@/${KWSYS_BUILD_SHARED}/g; - s/@KWSYS_LFS_AVAILABLE@/${KWSYS_LFS_AVAILABLE}/g; - s/@KWSYS_LFS_REQUESTED@/${KWSYS_LFS_REQUESTED}/g; - s/@KWSYS_NAME_IS_KWSYS@/${KWSYS_NAME_IS_KWSYS}/g; - s/@KWSYS_STL_HAS_WSTRING@/${KWSYS_STL_HAS_WSTRING}/g; - s/@KWSYS_CXX_HAS_EXT_STDIO_FILEBUF_H@/${KWSYS_CXX_HAS_EXT_STDIO_FILEBUF_H}/g; - }" >> "${OUTFILE}${_tmp}" + sed "/./ {s/\@KWSYS_NAMESPACE\@/cmsys/g; + s/@KWSYS_BUILD_SHARED@/${KWSYS_BUILD_SHARED}/g; + s/@KWSYS_LFS_AVAILABLE@/${KWSYS_LFS_AVAILABLE}/g; + s/@KWSYS_LFS_REQUESTED@/${KWSYS_LFS_REQUESTED}/g; + s/@KWSYS_NAME_IS_KWSYS@/${KWSYS_NAME_IS_KWSYS}/g; + s/@KWSYS_STL_HAS_WSTRING@/${KWSYS_STL_HAS_WSTRING}/g; + s/@KWSYS_CXX_HAS_EXT_STDIO_FILEBUF_H@/${KWSYS_CXX_HAS_EXT_STDIO_FILEBUF_H}/g; + }" "${INFILE}" >> "${OUTFILE}${_tmp}" if [ -f "${OUTFILE}${_tmp}" ]; then if "${_diff}" "${OUTFILE}" "${OUTFILE}${_tmp}" > /dev/null 2> /dev/null ; then #echo "Files are the same" |