diff options
229 files changed, 3454 insertions, 798 deletions
diff --git a/Auxiliary/vim/syntax/cmake.vim b/Auxiliary/vim/syntax/cmake.vim index 4517603..d7542b5 100644 --- a/Auxiliary/vim/syntax/cmake.vim +++ b/Auxiliary/vim/syntax/cmake.vim @@ -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/Help/command/configure_file.rst b/Help/command/configure_file.rst index 4304f09..e08c573 100644 --- a/Help/command/configure_file.rst +++ b/Help/command/configure_file.rst @@ -30,9 +30,23 @@ a false constant by the :command:`if` command. The "..." content on the line after the variable name, if any, is processed as above. Input file lines of the form ``#cmakedefine01 VAR`` will be replaced with either ``#define VAR 1`` or ``#define VAR 0`` similarly. +The result lines (with the exception of the ``#undef`` comments) can be +indented using spaces and/or tabs between the ``#`` character +and the ``cmakedefine`` or ``cmakedefine01`` words. This whitespace +indentation will be preserved in the output lines:: + + # cmakedefine VAR + # cmakedefine01 VAR + +will be replaced, if ``VAR`` is defined, with:: + + # define VAR + # define VAR 1 If the input file is modified the build system will re-run CMake to re-configure the file and generate the build system again. +The generated file is modified and its timestamp updated on subsequent +cmake runs only if its content is changed. The arguments are: diff --git a/Help/command/file.rst b/Help/command/file.rst index 7afb715..97466ff 100644 --- a/Help/command/file.rst +++ b/Help/command/file.rst @@ -306,8 +306,8 @@ from the input content to produce the output content. The options are: Exactly one ``CONTENT`` or ``INPUT`` option must be given. A specific ``OUTPUT`` file may be named by at most one invocation of ``file(GENERATE)``. -Generated files are modified on subsequent cmake runs only if their content -is changed. +Generated files are modified and their timestamp updated on subsequent cmake +runs only if their content is changed. Note also that ``file(GENERATE)`` does not create the output file until the generation phase. The output file will not yet have been written when the 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 c448445..889e4e3 100644 --- a/Help/dev/maint.rst +++ b/Help/dev/maint.rst @@ -29,6 +29,8 @@ command to integrate a merge request. Please check at least the following: * 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 diff --git a/Help/generator/Visual Studio 15 2017.rst b/Help/generator/Visual Studio 15 2017.rst index a88f8bc..2ac0449 100644 --- a/Help/generator/Visual Studio 15 2017.rst +++ b/Help/generator/Visual Studio 15 2017.rst @@ -15,6 +15,18 @@ a target platform name optionally at the end of this generator name: ``Visual Studio 15 2017 ARM`` Specify target platform ``ARM``. +Instance Selection +^^^^^^^^^^^^^^^^^^ + +VS 2017 supports multiple installations on the same machine. +CMake queries the Visual Studio Installer to locate VS instances. +If more than one instance is installed we do not define which one +is chosen by default. If the ``VS150COMNTOOLS`` environment variable +is set and points to the ``Common7/Tools`` directory within one of +the instances, that instance will be used. The environment variable +must remain consistently set whenever CMake is re-run within a given +build tree. + Toolset Selection ^^^^^^^^^^^^^^^^^ 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-server.7.rst b/Help/manual/cmake-server.7.rst index 211ebe4..f6d3032 100644 --- a/Help/manual/cmake-server.7.rst +++ b/Help/manual/cmake-server.7.rst @@ -254,6 +254,11 @@ versions supported by the cmake server. These are JSON objects with "major" and as experimental. These will contain the "isExperimental" key set to true. Enabling these requires a special command line argument when starting the cmake server mode. +Within a "major" version all "minor" versions are fully backwards compatible. +New "minor" versions may introduce functionality in such a way that existing +clients of the same "major" version will continue to work, provided they +ignore keys in the output that they do not know about. + Example:: [== "CMake Server" ==[ @@ -268,6 +273,9 @@ The first request that the client may send to the server is of type "handshake". This request needs to pass one of the "supportedProtocolVersions" of the "hello" type response received earlier back to the server in the "protocolVersion" field. +Giving the "major" version of the requested protocol version will make the server +use the latest minor version of that protocol. Use this if you do not explicitly +need to depend on a specific minor version. Each protocol version may request additional attributes to be present. diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 1a2726d..cc16b23 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 @@ -386,6 +387,7 @@ Variables for Languages /variable/CMAKE_LANG_ARCHIVE_FINISH /variable/CMAKE_LANG_COMPILER /variable/CMAKE_LANG_COMPILER_ABI + /variable/CMAKE_LANG_COMPILER_ARCHITECTURE_ID /variable/CMAKE_LANG_COMPILER_EXTERNAL_TOOLCHAIN /variable/CMAKE_LANG_COMPILER_ID /variable/CMAKE_LANG_COMPILER_LOADED diff --git a/Help/prop_dir/VS_GLOBAL_SECTION_POST_section.rst b/Help/prop_dir/VS_GLOBAL_SECTION_POST_section.rst index dcd2a4e..a316abe 100644 --- a/Help/prop_dir/VS_GLOBAL_SECTION_POST_section.rst +++ b/Help/prop_dir/VS_GLOBAL_SECTION_POST_section.rst @@ -26,4 +26,6 @@ and ExtensibilityAddIns by default. If you set the corresponding property, it will override the default section. For example, setting VS_GLOBAL_SECTION_POST_ExtensibilityGlobals will override the default contents of the ExtensibilityGlobals section, while keeping -ExtensibilityAddIns on its default. +ExtensibilityAddIns on its default. However, CMake will always +add a ``SolutionGuid`` to the ``ExtensibilityGlobals`` section +if it is not specified explicitly. diff --git a/Help/release/3.9.rst b/Help/release/3.9.rst index cd9476d..c31f533 100644 --- a/Help/release/3.9.rst +++ b/Help/release/3.9.rst @@ -16,6 +16,8 @@ Languages * ``CUDA`` is now supported by the :ref:`Visual Studio Generators` for VS 2010 and above. This complements the existing support by the :ref:`Makefile Generators` and the :generator:`Ninja` generator. + CUDA 8.0.61 or higher is recommended due to known bugs in the VS + integration by earlier versions. * CMake is now aware of the :prop_tgt:`C++ standards <CXX_STANDARD>` and :prop_tgt:`C standards <C_STANDARD>` and their associated meta-features for 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/iar.rst b/Help/release/dev/iar.rst new file mode 100644 index 0000000..c6678eb --- /dev/null +++ b/Help/release/dev/iar.rst @@ -0,0 +1,4 @@ +iar +--- + +* Support for the IAR ARM Compiler was improved. 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/dev/indented_cmakedefine.rst b/Help/release/dev/indented_cmakedefine.rst new file mode 100644 index 0000000..fd28b25 --- /dev/null +++ b/Help/release/dev/indented_cmakedefine.rst @@ -0,0 +1,7 @@ +indented_cmakedefine +-------------------- + +* The :command:`configure_file` command learned to support indented + ``# cmakedefine`` and ``# cmakedefine01``. Spaces and/or tabs between + the ``#`` character and the ``cmakedefine``/``cmakedefine01`` words + are now understood and preserved in the output. diff --git a/Help/variable/CMAKE_LANG_COMPILER_ARCHITECTURE_ID.rst b/Help/variable/CMAKE_LANG_COMPILER_ARCHITECTURE_ID.rst new file mode 100644 index 0000000..054c648 --- /dev/null +++ b/Help/variable/CMAKE_LANG_COMPILER_ARCHITECTURE_ID.rst @@ -0,0 +1,8 @@ +CMAKE_<LANG>_COMPILER_ARCHITECTURE_ID +------------------------------------- + +An internal variable subject to change. + +This is used to identify the variant of a compiler based on its target +architecture. For some compilers this is needed to determine the correct +usage. diff --git a/Help/variable/CMAKE_LANG_COMPILER_ID.rst b/Help/variable/CMAKE_LANG_COMPILER_ID.rst index 0fab10c..5204044 100644 --- a/Help/variable/CMAKE_LANG_COMPILER_ID.rst +++ b/Help/variable/CMAKE_LANG_COMPILER_ID.rst @@ -20,6 +20,7 @@ include: G95 = G95 Fortran (g95.org) GNU = GNU Compiler Collection (gcc.gnu.org) HP = Hewlett-Packard Compiler (hp.com) + IAR = IAR Systems (iar.com) Intel = Intel Compiler (intel.com) MIPSpro = SGI MIPSpro (sgi.com) MSVC = Microsoft Visual Studio (microsoft.com) 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/CMakeASMCompiler.cmake.in b/Modules/CMakeASMCompiler.cmake.in index 7b94d0f..a6465f6 100644 --- a/Modules/CMakeASMCompiler.cmake.in +++ b/Modules/CMakeASMCompiler.cmake.in @@ -7,8 +7,11 @@ set(CMAKE_ASM@ASM_DIALECT@_COMPILER_RANLIB "@_CMAKE_ASM_COMPILER_RANLIB@") set(CMAKE_LINKER "@CMAKE_LINKER@") set(CMAKE_ASM@ASM_DIALECT@_COMPILER_LOADED 1) set(CMAKE_ASM@ASM_DIALECT@_COMPILER_ID "@_CMAKE_ASM_COMPILER_ID@") +set(CMAKE_ASM@ASM_DIALECT@_COMPILER_VERSION "@_CMAKE_ASM_COMPILER_VERSION@") set(CMAKE_ASM@ASM_DIALECT@_COMPILER_ENV_VAR "@_CMAKE_ASM_COMPILER_ENV_VAR@") +@_SET_CMAKE_ASM_COMPILER_ARCHITECTURE_ID@ set(CMAKE_ASM@ASM_DIALECT@_IGNORE_EXTENSIONS h;H;o;O;obj;OBJ;def;DEF;rc;RC) set(CMAKE_ASM@ASM_DIALECT@_LINKER_PREFERENCE 0) +@CMAKE_ASM_COMPILER_CUSTOM_CODE@ diff --git a/Modules/CMakeCCompiler.cmake.in b/Modules/CMakeCCompiler.cmake.in index 974a579..92259dd 100644 --- a/Modules/CMakeCCompiler.cmake.in +++ b/Modules/CMakeCCompiler.cmake.in @@ -12,6 +12,7 @@ set(CMAKE_C11_COMPILE_FEATURES "@CMAKE_C11_COMPILE_FEATURES@") set(CMAKE_C_PLATFORM_ID "@CMAKE_C_PLATFORM_ID@") set(CMAKE_C_SIMULATE_ID "@CMAKE_C_SIMULATE_ID@") set(CMAKE_C_SIMULATE_VERSION "@CMAKE_C_SIMULATE_VERSION@") +@_SET_CMAKE_C_COMPILER_ARCHITECTURE_ID@ @SET_MSVC_C_ARCHITECTURE_ID@ @SET_CMAKE_XCODE_CURRENT_ARCH@ set(CMAKE_AR "@CMAKE_AR@") diff --git a/Modules/CMakeCXXCompiler.cmake.in b/Modules/CMakeCXXCompiler.cmake.in index fda7950..47fc624 100644 --- a/Modules/CMakeCXXCompiler.cmake.in +++ b/Modules/CMakeCXXCompiler.cmake.in @@ -13,6 +13,7 @@ set(CMAKE_CXX17_COMPILE_FEATURES "@CMAKE_CXX17_COMPILE_FEATURES@") set(CMAKE_CXX_PLATFORM_ID "@CMAKE_CXX_PLATFORM_ID@") set(CMAKE_CXX_SIMULATE_ID "@CMAKE_CXX_SIMULATE_ID@") set(CMAKE_CXX_SIMULATE_VERSION "@CMAKE_CXX_SIMULATE_VERSION@") +@_SET_CMAKE_CXX_COMPILER_ARCHITECTURE_ID@ @SET_MSVC_CXX_ARCHITECTURE_ID@ @SET_CMAKE_XCODE_CURRENT_ARCH@ set(CMAKE_AR "@CMAKE_AR@") diff --git a/Modules/CMakeDetermineASMCompiler.cmake b/Modules/CMakeDetermineASMCompiler.cmake index 87c6b28..d031421 100644 --- a/Modules/CMakeDetermineASMCompiler.cmake +++ b/Modules/CMakeDetermineASMCompiler.cmake @@ -84,7 +84,7 @@ if(NOT CMAKE_ASM${ASM_DIALECT}_COMPILER_ID) set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_FLAGS_TI "-h") set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_REGEX_TI "Texas Instruments") - list(APPEND CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDORS GNU IAR) + list(APPEND CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDORS IAR) set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_FLAGS_IAR ) set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_REGEX_IAR "IAR Assembler") @@ -103,10 +103,31 @@ if(NOT CMAKE_ASM${ASM_DIALECT}_COMPILER_ID) include(CMakeDetermineCompilerId) set(userflags) CMAKE_DETERMINE_COMPILER_ID_VENDOR(ASM${ASM_DIALECT} "${userflags}") + if("${CMAKE_ASM${ASM_DIALECT}_COMPILER_ID}" STREQUAL "IAR") + # primary necessary to detect architecture, so the right archiver and linker can be picked + # eg. IAR Assembler V8.10.1.12857/W32 for ARM + # Cut out identification first, newline handling is a pain + string(REGEX MATCH "IAR Assembler[^\r\n]*" _compileid "${CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_OUTPUT}") + if("${_compileid}" MATCHES "V([0-9]+\\.[0-9]+\\.[0-9]+)") + set(CMAKE_ASM${ASM_DIALECT}_COMPILER_VERSION ${CMAKE_MATCH_1}) + endif() + if("${_compileid}" MATCHES "for[ ]+([A-Za-z0-9]+)") + set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ARCHITECTURE_ID ${CMAKE_MATCH_1}) + endif() + endif() + unset(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_OUTPUT) + unset(_compileid) endif() + if(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID) - message(STATUS "The ASM${ASM_DIALECT} compiler identification is ${CMAKE_ASM${ASM_DIALECT}_COMPILER_ID}") + if(CMAKE_ASM${ASM_DIALECT}_COMPILER_VERSION) + set(_version " ${CMAKE_ASM${ASM_DIALECT}_COMPILER_VERSION}") + else() + set(_version "") + endif() + message(STATUS "The ASM${ASM_DIALECT} compiler identification is ${CMAKE_ASM${ASM_DIALECT}_COMPILER_ID}${_version}") + unset(_version) else() message(STATUS "The ASM${ASM_DIALECT} compiler identification is unknown") endif() @@ -143,6 +164,9 @@ endif () include(CMakeFindBinUtils) +set(_CMAKE_PROCESSING_LANGUAGE "ASM") +include(Compiler/${CMAKE_ASM${ASM_DIALECT}_COMPILER_ID}-FindBinUtils OPTIONAL) +unset(_CMAKE_PROCESSING_LANGUAGE) set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ENV_VAR "ASM${ASM_DIALECT}") @@ -152,20 +176,37 @@ else() message(STATUS "Didn't find assembler") endif() - -set(_CMAKE_ASM_COMPILER "${CMAKE_ASM${ASM_DIALECT}_COMPILER}") -set(_CMAKE_ASM_COMPILER_ID "${CMAKE_ASM${ASM_DIALECT}_COMPILER_ID}") -set(_CMAKE_ASM_COMPILER_ARG1 "${CMAKE_ASM${ASM_DIALECT}_COMPILER_ARG1}") -set(_CMAKE_ASM_COMPILER_ENV_VAR "${CMAKE_ASM${ASM_DIALECT}_COMPILER_ENV_VAR}") -set(_CMAKE_ASM_COMPILER_AR "${CMAKE_ASM${ASM_DIALECT}_COMPILER_AR}") -set(_CMAKE_ASM_COMPILER_RANLIB "${CMAKE_ASM${ASM_DIALECT}_COMPILER_RANLIB}") +foreach(_var + COMPILER + COMPILER_ID + COMPILER_ARG1 + COMPILER_ENV_VAR + COMPILER_AR + COMPILER_RANLIB + COMPILER_VERSION + ) + set(_CMAKE_ASM_${_var} "${CMAKE_ASM${ASM_DIALECT}_${_var}}") +endforeach() + +if(CMAKE_ASM${ASM_DIALECT}_COMPILER_ARCHITECTURE_ID) + set(_SET_CMAKE_ASM_COMPILER_ARCHITECTURE_ID + "set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ARCHITECTURE_ID ${CMAKE_ASM${ASM_DIALECT}_COMPILER_ARCHITECTURE_ID})") +else() + set(_SET_CMAKE_ASM_COMPILER_ARCHITECTURE_ID "") +endif() # configure variables set in this file for fast reload later on configure_file(${CMAKE_ROOT}/Modules/CMakeASMCompiler.cmake.in ${CMAKE_PLATFORM_INFO_DIR}/CMakeASM${ASM_DIALECT}Compiler.cmake @ONLY) -set(_CMAKE_ASM_COMPILER) -set(_CMAKE_ASM_COMPILER_ARG1) -set(_CMAKE_ASM_COMPILER_ENV_VAR) -set(_CMAKE_ASM_COMPILER_AR) -set(_CMAKE_ASM_COMPILER_RANLIB) +foreach(_var + COMPILER + COMPILER_ID + COMPILER_ARG1 + COMPILER_ENV_VAR + COMPILER_AR + COMPILER_RANLIB + COMPILER_VERSION + ) + unset(_CMAKE_ASM_${_var}) +endforeach() diff --git a/Modules/CMakeDetermineCCompiler.cmake b/Modules/CMakeDetermineCCompiler.cmake index 3caccde..fcbda20 100644 --- a/Modules/CMakeDetermineCCompiler.cmake +++ b/Modules/CMakeDetermineCCompiler.cmake @@ -170,6 +170,13 @@ set(_CMAKE_PROCESSING_LANGUAGE "C") include(Compiler/${CMAKE_C_COMPILER_ID}-FindBinUtils OPTIONAL) unset(_CMAKE_PROCESSING_LANGUAGE) +if(CMAKE_C_COMPILER_ARCHITECTURE_ID) + set(_SET_CMAKE_C_COMPILER_ARCHITECTURE_ID + "set(CMAKE_C_COMPILER_ARCHITECTURE_ID ${CMAKE_C_COMPILER_ARCHITECTURE_ID})") +else() + set(_SET_CMAKE_C_COMPILER_ARCHITECTURE_ID "") +endif() + if(MSVC_C_ARCHITECTURE_ID) set(SET_MSVC_C_ARCHITECTURE_ID "set(MSVC_C_ARCHITECTURE_ID ${MSVC_C_ARCHITECTURE_ID})") diff --git a/Modules/CMakeDetermineCXXCompiler.cmake b/Modules/CMakeDetermineCXXCompiler.cmake index 9150962..8c33eb6 100644 --- a/Modules/CMakeDetermineCXXCompiler.cmake +++ b/Modules/CMakeDetermineCXXCompiler.cmake @@ -73,6 +73,9 @@ else() set(CMAKE_CXX_COMPILER_ID_TEST_FLAGS # Try compiling to an object file only. "-c" + # IAR does not detect language automatically + "--c++" + "--ec++" ) endif() @@ -165,6 +168,13 @@ set(_CMAKE_PROCESSING_LANGUAGE "CXX") include(Compiler/${CMAKE_CXX_COMPILER_ID}-FindBinUtils OPTIONAL) unset(_CMAKE_PROCESSING_LANGUAGE) +if(CMAKE_CXX_COMPILER_ARCHITECTURE_ID) + set(_SET_CMAKE_CXX_COMPILER_ARCHITECTURE_ID + "set(CMAKE_CXX_COMPILER_ARCHITECTURE_ID ${CMAKE_CXX_COMPILER_ARCHITECTURE_ID})") +else() + set(_SET_CMAKE_CXX_COMPILER_ARCHITECTURE_ID "") +endif() + if(MSVC_CXX_ARCHITECTURE_ID) set(SET_MSVC_CXX_ARCHITECTURE_ID "set(MSVC_CXX_ARCHITECTURE_ID ${MSVC_CXX_ARCHITECTURE_ID})") diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake index eeb806f..8d4e6aa 100644 --- a/Modules/CMakeDetermineCompilerId.cmake +++ b/Modules/CMakeDetermineCompilerId.cmake @@ -102,6 +102,7 @@ function(CMAKE_DETERMINE_COMPILER_ID lang flagvar src) set(CMAKE_${lang}_COMPILER_ID "${CMAKE_${lang}_COMPILER_ID}" PARENT_SCOPE) set(CMAKE_${lang}_PLATFORM_ID "${CMAKE_${lang}_PLATFORM_ID}" PARENT_SCOPE) + set(CMAKE_${lang}_COMPILER_ARCHITECTURE_ID "${CMAKE_${lang}_COMPILER_ARCHITECTURE_ID}" PARENT_SCOPE) set(MSVC_${lang}_ARCHITECTURE_ID "${MSVC_${lang}_ARCHITECTURE_ID}" PARENT_SCOPE) set(CMAKE_${lang}_XCODE_CURRENT_ARCH "${CMAKE_${lang}_XCODE_CURRENT_ARCH}" PARENT_SCOPE) @@ -576,6 +577,7 @@ function(CMAKE_DETERMINE_COMPILER_ID_CHECK lang file) if(COMPILER_ID AND NOT COMPILER_ID_TWICE) set(CMAKE_${lang}_COMPILER_ID "${COMPILER_ID}") set(CMAKE_${lang}_PLATFORM_ID "${PLATFORM_ID}") + set(CMAKE_${lang}_COMPILER_ARCHITECTURE_ID "${ARCHITECTURE_ID}") set(MSVC_${lang}_ARCHITECTURE_ID "${ARCHITECTURE_ID}") set(CMAKE_${lang}_COMPILER_VERSION "${COMPILER_VERSION}") set(CMAKE_${lang}_SIMULATE_ID "${SIMULATE_ID}") @@ -625,6 +627,7 @@ function(CMAKE_DETERMINE_COMPILER_ID_CHECK lang file) # Return the information extracted. set(CMAKE_${lang}_COMPILER_ID "${CMAKE_${lang}_COMPILER_ID}" PARENT_SCOPE) set(CMAKE_${lang}_PLATFORM_ID "${CMAKE_${lang}_PLATFORM_ID}" PARENT_SCOPE) + set(CMAKE_${lang}_COMPILER_ARCHITECTURE_ID "${CMAKE_${lang}_COMPILER_ARCHITECTURE_ID}" PARENT_SCOPE) set(MSVC_${lang}_ARCHITECTURE_ID "${MSVC_${lang}_ARCHITECTURE_ID}" PARENT_SCOPE) set(CMAKE_${lang}_COMPILER_VERSION "${CMAKE_${lang}_COMPILER_VERSION}" PARENT_SCOPE) @@ -675,6 +678,7 @@ function(CMAKE_DETERMINE_COMPILER_ID_VENDOR lang userflags) "Checking whether the ${lang} compiler is ${vendor} using \"${flags}\" " "matched \"${regex}\":\n${output}") set(CMAKE_${lang}_COMPILER_ID "${vendor}" PARENT_SCOPE) + set(CMAKE_${lang}_COMPILER_ID_OUTPUT "${output}" PARENT_SCOPE) break() else() if("${result}" MATCHES "timeout") diff --git a/Modules/CMakeDetermineFortranCompiler.cmake b/Modules/CMakeDetermineFortranCompiler.cmake index d5220b4..5559640 100644 --- a/Modules/CMakeDetermineFortranCompiler.cmake +++ b/Modules/CMakeDetermineFortranCompiler.cmake @@ -261,6 +261,13 @@ set(_CMAKE_PROCESSING_LANGUAGE "Fortran") include(Compiler/${CMAKE_Fortran_COMPILER_ID}-FindBinUtils OPTIONAL) unset(_CMAKE_PROCESSING_LANGUAGE) +if(CMAKE_Fortran_COMPILER_ARCHITECTURE_ID) + set(_SET_CMAKE_Fortran_COMPILER_ARCHITECTURE_ID + "set(CMAKE_Fortran_COMPILER_ARCHITECTURE_ID ${CMAKE_Fortran_COMPILER_ARCHITECTURE_ID})") +else() + set(_SET_CMAKE_Fortran_COMPILER_ARCHITECTURE_ID "") +endif() + if(MSVC_Fortran_ARCHITECTURE_ID) set(SET_MSVC_Fortran_ARCHITECTURE_ID "set(MSVC_Fortran_ARCHITECTURE_ID ${MSVC_Fortran_ARCHITECTURE_ID})") diff --git a/Modules/CMakeFortranCompiler.cmake.in b/Modules/CMakeFortranCompiler.cmake.in index d521190..2e34cbb 100644 --- a/Modules/CMakeFortranCompiler.cmake.in +++ b/Modules/CMakeFortranCompiler.cmake.in @@ -6,6 +6,7 @@ set(CMAKE_Fortran_COMPILER_WRAPPER "@CMAKE_Fortran_COMPILER_WRAPPER@") set(CMAKE_Fortran_PLATFORM_ID "@CMAKE_Fortran_PLATFORM_ID@") set(CMAKE_Fortran_SIMULATE_ID "@CMAKE_Fortran_SIMULATE_ID@") set(CMAKE_Fortran_SIMULATE_VERSION "@CMAKE_Fortran_SIMULATE_VERSION@") +@_SET_CMAKE_Fortran_COMPILER_ARCHITECTURE_ID@ @SET_MSVC_Fortran_ARCHITECTURE_ID@ set(CMAKE_AR "@CMAKE_AR@") set(CMAKE_Fortran_COMPILER_AR "@CMAKE_Fortran_COMPILER_AR@") diff --git a/Modules/CMakePlatformId.h.in b/Modules/CMakePlatformId.h.in index 47eb00a..c7065b2 100644 --- a/Modules/CMakePlatformId.h.in +++ b/Modules/CMakePlatformId.h.in @@ -144,6 +144,16 @@ # define ARCHITECTURE_ID "" # endif +#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC) +# if defined(__ICCARM__) +# define ARCHITECTURE_ID "ARM" + +# elif defined(__ICCAVR__) +# define ARCHITECTURE_ID "AVR" + +# else /* unknown architecture */ +# define ARCHITECTURE_ID "" +# endif #else # define ARCHITECTURE_ID #endif 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/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/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/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/Compiler/Clang-FindBinUtils.cmake b/Modules/Compiler/Clang-FindBinUtils.cmake index c81e77a..e2822a1 100644 --- a/Modules/Compiler/Clang-FindBinUtils.cmake +++ b/Modules/Compiler/Clang-FindBinUtils.cmake @@ -16,6 +16,7 @@ find_program(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_AR NAMES HINTS ${__clang_hints} DOC "LLVM archiver" ) +mark_as_advanced(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_AR) # http://manpages.ubuntu.com/manpages/precise/en/man1/llvm-ranlib.1.html find_program(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_RANLIB NAMES @@ -23,3 +24,4 @@ find_program(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_RANLIB NAMES HINTS ${__clang_hints} DOC "Generate index for LLVM archive" ) +mark_as_advanced(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_RANLIB) diff --git a/Modules/Compiler/GNU-FindBinUtils.cmake b/Modules/Compiler/GNU-FindBinUtils.cmake index 142636c..16b7bbd 100644 --- a/Modules/Compiler/GNU-FindBinUtils.cmake +++ b/Modules/Compiler/GNU-FindBinUtils.cmake @@ -22,6 +22,7 @@ find_program(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_AR NAMES HINTS ${__gcc_hints} DOC "A wrapper around 'ar' adding the appropriate '--plugin' option for the GCC compiler" ) +mark_as_advanced(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_AR) # http://manpages.ubuntu.com/manpages/wily/en/man1/gcc-ranlib.1.html find_program(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_RANLIB NAMES @@ -31,3 +32,4 @@ find_program(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_RANLIB NAMES HINTS ${__gcc_hints} DOC "A wrapper around 'ranlib' adding the appropriate '--plugin' option for the GCC compiler" ) +mark_as_advanced(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_RANLIB) diff --git a/Modules/Compiler/IAR-ASM.cmake b/Modules/Compiler/IAR-ASM.cmake index 844c30e..651bc3a 100644 --- a/Modules/Compiler/IAR-ASM.cmake +++ b/Modules/Compiler/IAR-ASM.cmake @@ -2,13 +2,20 @@ include(Compiler/IAR) -set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> <SOURCE> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT>") - -if("${IAR_TARGET_ARCHITECTURE}" STREQUAL "ARM") +if("${CMAKE_ASM${ASM_DIALECT}_COMPILER_ARCHITECTURE_ID}" STREQUAL "ARM") +set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> -S <SOURCE> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT>") + __compiler_iar_ARM(ASM) set(CMAKE_ASM_SOURCE_FILE_EXTENSIONS s;asm;msa) -endif() + string(APPEND CMAKE_ASM_FLAGS_INIT " ") + string(APPEND CMAKE_ASM_FLAGS_DEBUG_INIT " -r") + string(APPEND CMAKE_ASM_FLAGS_MINSIZEREL_INIT " -DNDEBUG") + string(APPEND CMAKE_ASM_FLAGS_RELEASE_INIT " -DNDEBUG") + string(APPEND CMAKE_ASM_FLAGS_RELWITHDEBINFO_INIT " -r -DNDEBUG") -if("${IAR_TARGET_ARCHITECTURE}" STREQUAL "AVR") +elseif("${CMAKE_ASM${ASM_DIALECT}_COMPILER_ARCHITECTURE_ID}" STREQUAL "AVR") + set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> -S <SOURCE> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT>") + __compiler_iar_AVR(ASM) set(CMAKE_ASM_SOURCE_FILE_EXTENSIONS s90;asm;msa) + endif() diff --git a/Modules/Compiler/IAR-C.cmake b/Modules/Compiler/IAR-C.cmake index f65b0c7..48a9a16 100644 --- a/Modules/Compiler/IAR-C.cmake +++ b/Modules/Compiler/IAR-C.cmake @@ -1,25 +1,29 @@ # This file is processed when the IAR compiler is used for a C file - include(Compiler/IAR) - -set(CMAKE_C_COMPILE_OBJECT "<CMAKE_C_COMPILER> <SOURCE> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT>") -set(CMAKE_C_CREATE_PREPROCESSED_SOURCE "<CMAKE_C_COMPILER> <SOURCE> <DEFINES> <INCLUDES> <FLAGS> --preprocess=cnl <PREPROCESSED_SOURCE>") -set(CMAKE_C_CREATE_ASSEMBLY_SOURCE "<CMAKE_C_COMPILER> <SOURCE> <DEFINES> <INCLUDES> <FLAGS> -lAH <ASSEMBLY_SOURCE> -o <OBJECT>.dummy") - -set(CMAKE_C_RESPONSE_FILE_LINK_FLAG "-f ") -set(CMAKE_DEPFILE_FLAGS_C "--dependencies=ns <DEPFILE>") +include(Compiler/CMakeCommonCompilerMacros) # The toolchains for ARM and AVR are quite different: -if("${IAR_TARGET_ARCHITECTURE}" STREQUAL "ARM") - - set(CMAKE_C_LINK_EXECUTABLE "<CMAKE_LINKER> <OBJECTS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES> -o <TARGET>") - set(CMAKE_C_CREATE_STATIC_LIBRARY "<CMAKE_AR> <TARGET> --create <LINK_FLAGS> <OBJECTS> ") - -endif() +if("${CMAKE_C_COMPILER_ARCHITECTURE_ID}" STREQUAL "ARM") + set(CMAKE_C90_STANDARD_COMPILE_OPTION "") + set(CMAKE_C90_EXTENSION_COMPILE_OPTION -e) + + if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 6.10) + set(CMAKE_C90_STANDARD_COMPILE_OPTION --c89) + set(CMAKE_C90_EXTENSION_COMPILE_OPTION --c89 -e) + set(CMAKE_C99_STANDARD_COMPILE_OPTION "") + set(CMAKE_C99_EXTENSION_COMPILE_OPTION -e) + endif() + if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 8.10) + set(CMAKE_C11_STANDARD_COMPILE_OPTION "") + set(CMAKE_C11_EXTENSION_COMPILE_OPTION -e) + endif() + __compiler_iar_ARM(C) + __compiler_check_default_language_standard(C 1.10 90 6.10 99 8.10 11) -if("${IAR_TARGET_ARCHITECTURE}" STREQUAL "AVR") +elseif("${CMAKE_C_COMPILER_ARCHITECTURE_ID}" STREQUAL "AVR") + __compiler_iar_AVR(C) set(CMAKE_C_OUTPUT_EXTENSION ".r90") if(NOT CMAKE_C_LINK_FLAGS) @@ -29,9 +33,8 @@ if("${IAR_TARGET_ARCHITECTURE}" STREQUAL "AVR") set(CMAKE_C_LINK_EXECUTABLE "<CMAKE_LINKER> <OBJECTS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES> -o <TARGET>") set(CMAKE_C_CREATE_STATIC_LIBRARY "<CMAKE_AR> -o <TARGET> <OBJECTS> ") + # add the target specific include directory: + get_filename_component(_compilerDir "${CMAKE_C_COMPILER}" PATH) + get_filename_component(_compilerDir "${_compilerDir}" PATH) + include_directories("${_compilerDir}/inc" ) endif() - -# add the target specific include directory: -get_filename_component(_compilerDir "${CMAKE_C_COMPILER}" PATH) -get_filename_component(_compilerDir "${_compilerDir}" PATH) -include_directories("${_compilerDir}/inc" ) diff --git a/Modules/Compiler/IAR-CXX.cmake b/Modules/Compiler/IAR-CXX.cmake index f49968e..7a6ba2b 100644 --- a/Modules/Compiler/IAR-CXX.cmake +++ b/Modules/Compiler/IAR-CXX.cmake @@ -1,24 +1,39 @@ # This file is processed when the IAR compiler is used for a C++ file include(Compiler/IAR) +include(Compiler/CMakeCommonCompilerMacros) + +if("${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}" STREQUAL "ARM") + # "(extended) embedded C++" Mode + # old version: --ec++ or --eec++ + # since 8.10: --c++ --no_exceptions --no_rtti + # + # --c++ is full C++ and supported since 6.10 + if(NOT CMAKE_IAR_CXX_FLAG) + if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.10) + set(CMAKE_IAR_CXX_FLAG --c++) + else() + set(CMAKE_IAR_CXX_FLAG --eec++) + endif() + endif() -set(CMAKE_CXX_COMPILE_OBJECT "<CMAKE_CXX_COMPILER> <SOURCE> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT>") - -set(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE "<CMAKE_CXX_COMPILER> <SOURCE> <DEFINES> <INCLUDES> <FLAGS> --preprocess=cnl <PREPROCESSED_SOURCE>") -set(CMAKE_CXX_CREATE_ASSEMBLY_SOURCE "<CMAKE_CXX_COMPILER> <SOURCE> <DEFINES> <INCLUDES> <FLAGS> -lAH <ASSEMBLY_SOURCE> -o <OBJECT>.dummy") - -set(CMAKE_CXX_RESPONSE_FILE_LINK_FLAG "-f ") -set(CMAKE_DEPFILE_FLAGS_CXX "--dependencies=ns <DEPFILE>") - -if("${IAR_TARGET_ARCHITECTURE}" STREQUAL "ARM") + set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "") + set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION -e) - set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_LINKER> <OBJECTS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES> -o <TARGET>") - set(CMAKE_CXX_CREATE_STATIC_LIBRARY "<CMAKE_AR> <TARGET> --create <LINK_FLAGS> <OBJECTS> ") - -endif() + if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8.10) + set(CMAKE_CXX03_STANDARD_COMPILE_OPTION "") + set(CMAKE_CXX03_EXTENSION_COMPILE_OPTION -e) + set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "") + set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION -e) + set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "") + set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION -e) + endif() + __compiler_iar_ARM(CXX) + __compiler_check_default_language_standard(CXX 6.10 98 8.10 14) -if("${IAR_TARGET_ARCHITECTURE}" STREQUAL "AVR") +elseif("${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}" STREQUAL "AVR") + __compiler_iar_AVR(CXX) set(CMAKE_CXX_OUTPUT_EXTENSION ".r90") if(NOT CMAKE_CXX_LINK_FLAGS) set(CMAKE_CXX_LINK_FLAGS "-Fmotorola") @@ -27,9 +42,8 @@ if("${IAR_TARGET_ARCHITECTURE}" STREQUAL "AVR") set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_LINKER> <OBJECTS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES> -o <TARGET>") set(CMAKE_CXX_CREATE_STATIC_LIBRARY "<CMAKE_AR> -o <TARGET> <OBJECTS> ") + # add the target specific include directory: + get_filename_component(_compilerDir "${CMAKE_C_COMPILER}" PATH) + get_filename_component(_compilerDir "${_compilerDir}" PATH) + include_directories("${_compilerDir}/inc") endif() - -# add the target specific include directory: -get_filename_component(_compilerDir "${CMAKE_C_COMPILER}" PATH) -get_filename_component(_compilerDir "${_compilerDir}" PATH) -include_directories("${_compilerDir}/inc") diff --git a/Modules/Compiler/IAR-DetermineCompiler.cmake b/Modules/Compiler/IAR-DetermineCompiler.cmake index c39810a..4ef587b 100644 --- a/Modules/Compiler/IAR-DetermineCompiler.cmake +++ b/Modules/Compiler/IAR-DetermineCompiler.cmake @@ -1,4 +1,18 @@ - # IAR Systems compiler for embedded systems. # http://www.iar.com -set(_compiler_id_pp_test "defined(__IAR_SYSTEMS_ICC__ ) || defined(__IAR_SYSTEMS_ICC)") +# http://supp.iar.com/FilesPublic/UPDINFO/004916/arm/doc/EWARM_DevelopmentGuide.ENU.pdf +# +# __IAR_SYSTEMS_ICC__ An integer that identifies the IAR compiler platform. The current value is 8. Note that +# the number could be higher in a future version of the product +# __ICCARM__ An integer that is set to 1 when the code is compiled with the IAR C/C++ Compiler for ARM +# __VER__ An integer that identifies the version number of the IAR compiler in use. For example, +# version 5.11.3 is returned as 5011003. + +set(_compiler_id_pp_test "defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC)") + +set(_compiler_id_version_compute " +# if defined(__VER__) +# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@((__VER__) / 1000000) +# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(((__VER__) / 1000) % 1000) +# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@((__VER__) % 1000) +# endif") diff --git a/Modules/Compiler/IAR-FindBinUtils.cmake b/Modules/Compiler/IAR-FindBinUtils.cmake new file mode 100644 index 0000000..2b04795 --- /dev/null +++ b/Modules/Compiler/IAR-FindBinUtils.cmake @@ -0,0 +1,54 @@ +if(NOT DEFINED _CMAKE_PROCESSING_LANGUAGE OR _CMAKE_PROCESSING_LANGUAGE STREQUAL "") + message(FATAL_ERROR "Internal error: _CMAKE_PROCESSING_LANGUAGE is not set") +endif() + +# Try to find tools in the same directory as Clang itself +get_filename_component(__iar_hint_1 "${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER}" REALPATH) +get_filename_component(__iar_hint_1 "${__iar_hint_1}" DIRECTORY) + +get_filename_component(__iar_hint_2 "${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER}" DIRECTORY) + +set(__iar_hints "${__iar_hint_1}" "${__iar_hint_2}") + +if("${CMAKE_C_COMPILER_ARCHITECTURE_ID}" STREQUAL "ARM") + # could allow using normal binutils ar, since objects are normal ELF files? + find_program(CMAKE_IAR_LINKARM ilinkarm.exe HINTS ${__iar_hints} + DOC "The IAR ARM linker") + find_program(CMAKE_IAR_ARCHIVE iarchive.exe HINTS ${__iar_hints} + DOC "The IAR archiver") + + # find auxillary tools + find_program(CMAKE_IAR_ELFTOOL ielftool.exe HINTS ${__iar_hints} + DOC "The IAR ELF Tool") + find_program(CMAKE_IAR_ELFDUMP ielfdumparm.exe HINTS ${__iar_hints} + DOC "The IAR ELF Dumper") + find_program(CMAKE_IAR_OBJMANIP iobjmanip.exe HINTS ${__iar_hints} + DOC "The IAR ELF Object Tool") + find_program(CMAKE_IAR_SYMEXPORT isymexport.exe HINTS ${__iar_hints} + DOC "The IAR Absolute Symbol Exporter") + mark_as_advanced(CMAKE_IAR_LINKARM CMAKE_IAR_ARCHIVE CMAKE_IAR_ELFTOOL CMAKE_IAR_ELFDUMP CMAKE_IAR_OBJMANIP CMAKE_IAR_SYMEXPORT) + + set(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_CUSTOM_CODE +"set(CMAKE_IAR_LINKARM \"${CMAKE_IAR_LINKARM}\") +set(CMAKE_IAR_ARCHIVE \"${CMAKE_IAR_ARCHIVE}\") +set(CMAKE_IAR_ELFTOOL \"${CMAKE_IAR_ELFTOOL}\") +set(CMAKE_IAR_ELFDUMP \"${CMAKE_IAR_ELFDUMP}\") +set(CMAKE_IAR_OBJMANIP \"${CMAKE_IAR_OBJMANIP}\") +set(CMAKE_IAR_LINKARM \"${CMAKE_IAR_LINKARM}\") +") + + +elseif("${CMAKE_C_COMPILER_ARCHITECTURE_ID}" STREQUAL "AVR") + + # For AVR and AVR32, IAR uses the "xlink" linker and the "xar" archiver: + find_program(CMAKE_IAR_LINKER xlink.exe HINTS ${__iar_hints} + DOC "The IAR AVR linker") + find_program(CMAKE_IAR_AR xar.exe HINTS ${__iar_hints} + DOC "The IAR archiver") + mark_as_advanced(CMAKE_IAR_LINKER CMAKE_IAR_AR) + + set(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_CUSTOM_CODE +"set(CMAKE_IAR_LINKER \"${CMAKE_IAR_LINKER}\") +set(CMAKE_IAR_AR \"${CMAKE_IAR_AR}\") +") +endif() diff --git a/Modules/Compiler/IAR.cmake b/Modules/Compiler/IAR.cmake index 8c45276..52ebaf2 100644 --- a/Modules/Compiler/IAR.cmake +++ b/Modules/Compiler/IAR.cmake @@ -2,46 +2,75 @@ # Documentation can be downloaded here: http://www.iar.com/website1/1.0.1.0/675/1/ # The initial feature request is here: https://gitlab.kitware.com/cmake/cmake/issues/10176 # It also contains additional links and information. +# See USER GUIDES -> C/C++ Development Guide and ReleaseNotes for: +# version 6.30.8: http://supp.iar.com/FilesPublic/UPDINFO/006607/arm/doc/infocenter/index.ENU.html +# version 7.60.1: http://supp.iar.com/FilesPublic/UPDINFO/011006/arm/doc/infocenter/index.ENU.html +# version 8.10.1: http://netstorage.iar.com/SuppDB/Public/UPDINFO/011854/arm/doc/infocenter/index.ENU.html -if(_IAR_CMAKE_LOADED) +# C/C++ Standard versions +# +# IAR typically only supports one C and C++ Standard version, +# the exception is C89 which is always supported and can be selected +# if its not the default +# +# C++ is trickier, there were historically 3 switches, +# and some IAR versions support multiple of those. +# they are --eec++, --ec++ and --c++ and where used to +# enable various language features like exceptions +# +# recent versions only have --c++ for full support +# but can choose to disable features with further arguments +# +# C/C++ Standard compliance +# +# IAR has 3 modes: default, strict and extended +# the extended mode is needed for popular libraries like CMSIS +# +# "Silent" Operation +# +# this really is different to most programs I know. +# nothing meaningfull from the operation is lost, just some redundant +# code and data size printouts (that can be inspected with common tools). + +# This module is shared by multiple languages; use include blocker. +if(_IARARM_CMAKE_LOADED) return() endif() -set(_IAR_CMAKE_LOADED TRUE) +set(_IARARM_CMAKE_LOADED 1) +macro(__compiler_iar_ARM lang) + set(CMAKE_EXECUTABLE_SUFFIX ".elf") + if (${lang} STREQUAL "C" OR ${lang} STREQUAL "CXX") -get_filename_component(_CMAKE_C_TOOLCHAIN_LOCATION "${CMAKE_C_COMPILER}" PATH) -get_filename_component(_CMAKE_CXX_TOOLCHAIN_LOCATION "${CMAKE_CXX_COMPILER}" PATH) -get_filename_component(_CMAKE_ASM_TOOLCHAIN_LOCATION "${CMAKE_ASM_COMPILER}" PATH) + set(CMAKE_${lang}_COMPILE_OBJECT "<CMAKE_${lang}_COMPILER> ${CMAKE_IAR_${lang}_FLAG} --silent <SOURCE> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT>") + set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE "<CMAKE_${lang}_COMPILER> ${CMAKE_IAR_${lang}_FLAG} --silent <SOURCE> <DEFINES> <INCLUDES> <FLAGS> --preprocess=cnl <PREPROCESSED_SOURCE>") + set(CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE "<CMAKE_${lang}_COMPILER> ${CMAKE_IAR_${lang}_FLAG} --silent <SOURCE> <DEFINES> <INCLUDES> <FLAGS> -lAH <ASSEMBLY_SOURCE> -o <OBJECT>.dummy") + set(CMAKE_${lang}_RESPONSE_FILE_LINK_FLAG "-f ") + set(CMAKE_DEPFILE_FLAGS_${lang} "--dependencies=ns <DEPFILE>") -if("${CMAKE_C_COMPILER}" MATCHES "arm" OR "${CMAKE_CXX_COMPILER}" MATCHES "arm" OR "${CMAKE_ASM_COMPILER}" MATCHES "arm") - set(CMAKE_EXECUTABLE_SUFFIX ".elf") + string(APPEND CMAKE_${lang}_FLAGS_INIT " ") + string(APPEND CMAKE_${lang}_FLAGS_DEBUG_INIT " -r") + string(APPEND CMAKE_${lang}_FLAGS_MINSIZEREL_INIT " -Ohz -DNDEBUG") + string(APPEND CMAKE_${lang}_FLAGS_RELEASE_INIT " -Oh -DNDEBUG") + string(APPEND CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT " -Oh -r -DNDEBUG") + endif() - # For arm, IAR uses the "ilinkarm" linker and "iarchive" archiver: - find_program(CMAKE_IAR_LINKER ilinkarm HINTS "${_CMAKE_C_TOOLCHAIN_LOCATION}" "${_CMAKE_CXX_TOOLCHAIN_LOCATION}" "${_CMAKE_ASM_TOOLCHAIN_LOCATION}") - find_program(CMAKE_IAR_AR iarchive HINTS "${_CMAKE_C_TOOLCHAIN_LOCATION}" "${_CMAKE_CXX_TOOLCHAIN_LOCATION}" "${_CMAKE_ASM_TOOLCHAIN_LOCATION}" ) + set(CMAKE_${lang}_LINK_EXECUTABLE "\"${CMAKE_IAR_LINKARM}\" --silent <OBJECTS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES> -o <TARGET>") + set(CMAKE_${lang}_CREATE_STATIC_LIBRARY "\"${CMAKE_IAR_ARCHIVE}\" <TARGET> --create <LINK_FLAGS> <OBJECTS>") + set(CMAKE_${lang}_ARCHIVE_CREATE "\"${CMAKE_IAR_ARCHIVE}\" <TARGET> --create <LINK_FLAGS> <OBJECTS>") + set(CMAKE_${lang}_ARCHIVE_APPEND "\"${CMAKE_IAR_ARCHIVE}\" <TARGET> --replace <LINK_FLAGS> <OBJECTS>") + set(CMAKE_${lang}_ARCHIVE_FINISH "") - set(IAR_TARGET_ARCHITECTURE "ARM" CACHE STRING "IAR compiler target architecture") -endif() + set(CMAKE_LINKER "${CMAKE_IAR_LINKARM}" CACHE FILEPATH "The IAR linker" FORCE) + set(CMAKE_AR "${CMAKE_IAR_ARCHIVE}" CACHE FILEPATH "The IAR archiver" FORCE) +endmacro() -if("${CMAKE_C_COMPILER}" MATCHES "avr" OR "${CMAKE_CXX_COMPILER}" MATCHES "avr" OR "${CMAKE_ASM_COMPILER}" MATCHES "avr") +macro(__compiler_iar_AVR lang) set(CMAKE_EXECUTABLE_SUFFIX ".bin") - # For AVR and AVR32, IAR uses the "xlink" linker and the "xar" archiver: - find_program(CMAKE_IAR_LINKER xlink HINTS "${_CMAKE_C_TOOLCHAIN_LOCATION}" "${_CMAKE_CXX_TOOLCHAIN_LOCATION}" "${_CMAKE_ASM_TOOLCHAIN_LOCATION}" ) - find_program(CMAKE_IAR_AR xar HINTS "${_CMAKE_C_TOOLCHAIN_LOCATION}" "${_CMAKE_CXX_TOOLCHAIN_LOCATION}" "${_CMAKE_ASM_TOOLCHAIN_LOCATION}" ) - - set(IAR_TARGET_ARCHITECTURE "AVR" CACHE STRING "IAR compiler target architecture") - set(CMAKE_LIBRARY_PATH_FLAG "-I") -endif() - -if(NOT IAR_TARGET_ARCHITECTURE) - message(FATAL_ERROR "The IAR compiler for this architecture is not yet supported " - "by CMake. Please go to https://gitlab.kitware.com/cmake/cmake/issues " - "and enter a feature request there.") -endif() - -set(CMAKE_LINKER "${CMAKE_IAR_LINKER}" CACHE FILEPATH "The IAR linker" FORCE) -set(CMAKE_AR "${CMAKE_IAR_AR}" CACHE FILEPATH "The IAR archiver" FORCE) + set(CMAKE_LINKER "${CMAKE_IAR_LINKER}" CACHE FILEPATH "The IAR linker" FORCE) + set(CMAKE_AR "${CMAKE_IAR_AR}" CACHE FILEPATH "The IAR archiver" FORCE) +endmacro() 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/FindDoxygen.cmake b/Modules/FindDoxygen.cmake index 0d9e161..46bf340 100644 --- a/Modules/FindDoxygen.cmake +++ b/Modules/FindDoxygen.cmake @@ -179,7 +179,8 @@ Functions will be converted to an absolute path relative to the current binary directory. This is necessary because doxygen will normally be run from a directory within the source tree so that relative source paths work as - expected. + expected. If this directory does not exist, it will be recursively created + prior to executing the doxygen commands. To change any of these defaults or override any other Doxygen config option, set relevant variables before calling ``doxygen_add_docs()``. For example: @@ -389,10 +390,10 @@ macro(_Doxygen_find_doxygen) COMMAND "${DOXYGEN_EXECUTABLE}" --version OUTPUT_VARIABLE DOXYGEN_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE - RESULT_VARIABLE result + RESULT_VARIABLE _Doxygen_version_result ) - if(result) - message(WARNING "Unable to determine doxygen version: ${result}") + if(_Doxygen_version_result) + message(WARNING "Unable to determine doxygen version: ${_Doxygen_version_result}") endif() # Create an imported target for Doxygen @@ -619,15 +620,15 @@ 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 - RESULT_VARIABLE result + RESULT_VARIABLE _Doxygen_tpl_result ) - if(result) + if(_Doxygen_tpl_result) message(FATAL_ERROR - "Unable to generate Doxyfile template: ${result}") + "Unable to generate Doxyfile template: ${_Doxygen_tpl_result}") elseif(NOT EXISTS "${_Doxygen_tpl}") message(FATAL_ERROR "Doxygen has failed to generate a Doxyfile template") @@ -646,8 +647,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 +897,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? @@ -1020,18 +1021,25 @@ doxygen_add_docs() for target ${targetName}") WARN_LOGFILE XML_OUTPUT ) + + # Store the unmodified value of DOXYGEN_OUTPUT_DIRECTORY prior to invoking + # doxygen_quote_value() below. This will mutate the string specifically for + # consumption by Doxygen's config file, which we do not want when we use it + # later in the custom target's commands. + set( _original_doxygen_output_dir ${DOXYGEN_OUTPUT_DIRECTORY} ) + foreach(_item IN LISTS _doxygen_quoted_options) doxygen_quote_value(DOXYGEN_${_item}) 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}") # Add the target - add_custom_target( - ${targetName} + add_custom_target( ${targetName} VERBATIM + COMMAND ${CMAKE_COMMAND} -E make_directory ${_original_doxygen_output_dir} COMMAND "${DOXYGEN_EXECUTABLE}" "${_target_doxyfile}" WORKING_DIRECTORY "${_args_WORKING_DIRECTORY}" DEPENDS "${_target_doxyfile}" diff --git a/Modules/FindHDF5.cmake b/Modules/FindHDF5.cmake index 2d9d2a2..48d5de4 100644 --- a/Modules/FindHDF5.cmake +++ b/Modules/FindHDF5.cmake @@ -23,7 +23,7 @@ # Fortran_HL. If the COMPONENTS argument is not given, the module will # attempt to find only the C bindings. # -# On UNIX systems, this module will read the variable +# This module will read the variable # HDF5_USE_STATIC_LIBRARIES to determine whether or not to prefer a # static link to a dynamic link for HDF5 and all of it's dependencies. # To use this feature, make sure that the HDF5_USE_STATIC_LIBRARIES @@ -551,8 +551,12 @@ if(NOT HDF5_FOUND) if("x${L}" MATCHES "hdf5") # hdf5 library set(_HDF5_SEARCH_OPTS_LOCAL ${_HDF5_SEARCH_OPTS}) - if(UNIX AND HDF5_USE_STATIC_LIBRARIES) - set(_HDF5_SEARCH_NAMES_LOCAL lib${L}.a) + if(HDF5_USE_STATIC_LIBRARIES) + if(WIN32) + set(_HDF5_SEARCH_NAMES_LOCAL lib${L}) + else() + set(_HDF5_SEARCH_NAMES_LOCAL lib${L}.a) + endif() endif() else() # external library @@ -579,8 +583,12 @@ if(NOT HDF5_FOUND) if("x${L}" MATCHES "hdf5") # hdf5 library set(_HDF5_SEARCH_OPTS_LOCAL ${_HDF5_SEARCH_OPTS}) - if(UNIX AND HDF5_USE_STATIC_LIBRARIES) - set(_HDF5_SEARCH_NAMES_LOCAL lib${L}.a) + if(HDF5_USE_STATIC_LIBRARIES) + if(WIN32) + set(_HDF5_SEARCH_NAMES_LOCAL lib${L}) + else() + set(_HDF5_SEARCH_NAMES_LOCAL lib${L}.a) + endif() endif() else() # external library @@ -712,19 +720,22 @@ if( NOT HDF5_FOUND ) # find the HDF5 libraries foreach(LIB IN LISTS HDF5_${__lang}_LIBRARY_NAMES) - if(UNIX AND HDF5_USE_STATIC_LIBRARIES) + if(HDF5_USE_STATIC_LIBRARIES) # According to bug 1643 on the CMake bug tracker, this is the # preferred method for searching for a static library. # See https://gitlab.kitware.com/cmake/cmake/issues/1643. We search # first for the full static library name, but fall back to a # generic search on the name if the static search fails. set( THIS_LIBRARY_SEARCH_DEBUG - lib${LIB}d.a lib${LIB}_debug.a ${LIB}d ${LIB}_debug - lib${LIB}d-static.a lib${LIB}_debug-static.a ${LIB}d-static ${LIB}_debug-static ) - set( THIS_LIBRARY_SEARCH_RELEASE lib${LIB}.a ${LIB} lib${LIB}-static.a ${LIB}-static) + lib${LIB}d.a lib${LIB}_debug.a lib${LIB}d lib${LIB}_D lib${LIB}_debug + lib${LIB}d-static.a lib${LIB}_debug-static.a ${LIB}d-static ${LIB}_D-static ${LIB}_debug-static ) + set( THIS_LIBRARY_SEARCH_RELEASE lib${LIB}.a lib${LIB} lib${LIB}-static.a ${LIB}-static) else() - set( THIS_LIBRARY_SEARCH_DEBUG ${LIB}d ${LIB}_debug ${LIB}d-shared ${LIB}_debug-shared) + set( THIS_LIBRARY_SEARCH_DEBUG ${LIB}d ${LIB}_D ${LIB}_debug ${LIB}d-shared ${LIB}_D-shared ${LIB}_debug-shared) set( THIS_LIBRARY_SEARCH_RELEASE ${LIB} ${LIB}-shared) + if(WIN32) + list(APPEND HDF5_DEFINITIONS "-DH5_BUILT_AS_DYNAMIC_LIB") + endif() endif() find_library(HDF5_${LIB}_LIBRARY_DEBUG NAMES ${THIS_LIBRARY_SEARCH_DEBUG} @@ -749,18 +760,18 @@ if( NOT HDF5_FOUND ) if(FIND_HL) foreach(LIB IN LISTS HDF5_${__lang}_HL_LIBRARY_NAMES) - if(UNIX AND HDF5_USE_STATIC_LIBRARIES) + if(HDF5_USE_STATIC_LIBRARIES) # According to bug 1643 on the CMake bug tracker, this is the # preferred method for searching for a static library. # See https://gitlab.kitware.com/cmake/cmake/issues/1643. We search # first for the full static library name, but fall back to a # generic search on the name if the static search fails. set( THIS_LIBRARY_SEARCH_DEBUG - lib${LIB}d.a lib${LIB}_debug.a ${LIB}d ${LIB}_debug - lib${LIB}d-static.a lib${LIB}_debug-static.a ${LIB}d-static ${LIB}_debug-static ) - set( THIS_LIBRARY_SEARCH_RELEASE lib${LIB}.a ${LIB} lib${LIB}-static.a ${LIB}-static) + lib${LIB}d.a lib${LIB}_debug.a lib${LIB}d lib${LIB}_D lib${LIB}_debug + lib${LIB}d-static.a lib${LIB}_debug-static.a lib${LIB}d-static lib${LIB}_D-static lib${LIB}_debug-static ) + set( THIS_LIBRARY_SEARCH_RELEASE lib${LIB}.a ${LIB} lib${LIB}-static.a lib${LIB}-static) else() - set( THIS_LIBRARY_SEARCH_DEBUG ${LIB}d ${LIB}_debug ${LIB}d-shared ${LIB}_debug-shared) + set( THIS_LIBRARY_SEARCH_DEBUG ${LIB}d ${LIB}_D ${LIB}_debug ${LIB}d-shared ${LIB}_D-shared ${LIB}_debug-shared) set( THIS_LIBRARY_SEARCH_RELEASE ${LIB} ${LIB}-shared) endif() find_library(HDF5_${LIB}_LIBRARY_DEBUG @@ -786,6 +797,7 @@ if( NOT HDF5_FOUND ) set(HDF5_HL_FOUND True) endif() + _HDF5_remove_duplicates_from_beginning(HDF5_DEFINITIONS) _HDF5_remove_duplicates_from_beginning(HDF5_INCLUDE_DIRS) _HDF5_remove_duplicates_from_beginning(HDF5_LIBRARIES) _HDF5_remove_duplicates_from_beginning(HDF5_HL_LIBRARIES) diff --git a/Modules/FindMFC.cmake b/Modules/FindMFC.cmake index 5c2dbbf..3baaf32 100644 --- a/Modules/FindMFC.cmake +++ b/Modules/FindMFC.cmake @@ -31,6 +31,7 @@ if(MFC_ATTEMPT_TRY_COMPILE) configure_file(${CMAKE_ROOT}/Modules/CheckIncludeFile.cxx.in ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.cxx) message(STATUS "Looking for MFC") + # Try both shared and static as the root project may have set the /MT flag try_compile(MFC_HAVE_MFC ${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.cxx @@ -38,6 +39,16 @@ if(MFC_ATTEMPT_TRY_COMPILE) -DCMAKE_MFC_FLAG:STRING=2 -DCOMPILE_DEFINITIONS:STRING=-D_AFXDLL OUTPUT_VARIABLE OUTPUT) + if(NOT MFC_HAVE_MFC) + configure_file(${CMAKE_ROOT}/Modules/CheckIncludeFile.cxx.in + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.cxx) + try_compile(MFC_HAVE_MFC + ${CMAKE_BINARY_DIR} + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.cxx + CMAKE_FLAGS + -DCMAKE_MFC_FLAG:STRING=1 + OUTPUT_VARIABLE OUTPUT) + endif() if(MFC_HAVE_MFC) message(STATUS "Looking for MFC - found") set(MFC_HAVE_MFC 1 CACHE INTERNAL "Have MFC?") diff --git a/Modules/FindPkgConfig.cmake b/Modules/FindPkgConfig.cmake index a5357fa..8ac1691 100644 --- a/Modules/FindPkgConfig.cmake +++ b/Modules/FindPkgConfig.cmake @@ -584,7 +584,9 @@ endmacro() macro(pkg_check_modules _prefix _module0) _pkgconfig_parse_options(_pkg_modules _pkg_is_required _pkg_is_silent _no_cmake_path _no_cmake_environment_path _imp_target "${_module0}" ${ARGN}) # check cached value - if (NOT DEFINED __pkg_config_checked_${_prefix} OR __pkg_config_checked_${_prefix} LESS ${PKG_CONFIG_VERSION} OR NOT ${_prefix}_FOUND OR NOT "${__pkg_config_arguments_${_prefix}}" STREQUAL "${_module0};${ARGN}") + if (NOT DEFINED __pkg_config_checked_${_prefix} OR __pkg_config_checked_${_prefix} LESS ${PKG_CONFIG_VERSION} OR NOT ${_prefix}_FOUND OR + (NOT "${ARGN}" STREQUAL "" AND NOT "${__pkg_config_arguments_${_prefix}}" STREQUAL "${_module0};${ARGN}") OR + ( "${ARGN}" STREQUAL "" AND NOT "${__pkg_config_arguments_${_prefix}}" STREQUAL "${_module0}")) _pkg_check_modules_internal("${_pkg_is_required}" "${_pkg_is_silent}" ${_no_cmake_path} ${_no_cmake_environment_path} ${_imp_target} "${_prefix}" ${_pkg_modules}) _pkgconfig_set(__pkg_config_checked_${_prefix} ${PKG_CONFIG_VERSION}) 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/GetPrerequisites.cmake b/Modules/GetPrerequisites.cmake index 0090cdc..4e52cb3 100644 --- a/Modules/GetPrerequisites.cmake +++ b/Modules/GetPrerequisites.cmake @@ -609,7 +609,7 @@ function(gp_resolved_file_type original_file file exepath dirs type_var) if(NOT is_embedded) if(NOT IS_ABSOLUTE "${resolved_file}") - if(lower MATCHES "^msvc[^/]+dll" AND is_system) + if(lower MATCHES "^(msvc|api-ms-win-)[^/]+dll" AND is_system) message(STATUS "info: non-absolute msvc file '${file}' returning type '${type}'") else() message(STATUS "warning: gp_resolved_file_type non-absolute file '${file}' returning type '${type}' -- possibly incorrect") diff --git a/Modules/Platform/Android-Common.cmake b/Modules/Platform/Android-Common.cmake index ac72676..6360376 100644 --- a/Modules/Platform/Android-Common.cmake +++ b/Modules/Platform/Android-Common.cmake @@ -160,9 +160,13 @@ macro(__android_compiler_common lang) # Do not do this for a standalone toolchain because it is already # tied to a specific API version. if(CMAKE_ANDROID_NDK) - list(APPEND CMAKE_${lang}_STANDARD_INCLUDE_DIRECTORIES "${CMAKE_SYSROOT}/usr/include") if(NOT CMAKE_ANDROID_NDK_DEPRECATED_HEADERS) - list(APPEND CMAKE_${lang}_STANDARD_INCLUDE_DIRECTORIES "${CMAKE_SYSROOT}/usr/include/${CMAKE_ANDROID_ARCH_HEADER_TRIPLE}") + list(APPEND CMAKE_${lang}_STANDARD_INCLUDE_DIRECTORIES + "${CMAKE_SYSROOT_COMPILE}/usr/include" + "${CMAKE_SYSROOT_COMPILE}/usr/include/${CMAKE_ANDROID_ARCH_HEADER_TRIPLE}" + ) + else() + list(APPEND CMAKE_${lang}_STANDARD_INCLUDE_DIRECTORIES "${CMAKE_SYSROOT}/usr/include") endif() list(REMOVE_ITEM CMAKE_${lang}_IMPLICIT_INCLUDE_DIRECTORIES "/usr/include") endif() diff --git a/Modules/Platform/Android/ndk-stl-c++_shared.cmake b/Modules/Platform/Android/ndk-stl-c++_shared.cmake index f585adb..3389408 100644 --- a/Modules/Platform/Android/ndk-stl-c++_shared.cmake +++ b/Modules/Platform/Android/ndk-stl-c++_shared.cmake @@ -1,4 +1,5 @@ include(Platform/Android/ndk-stl-c++) macro(__android_stl lang) __android_stl_cxx(${lang} libc++_shared.so) + __android_stl_lib(${lang} "${CMAKE_ANDROID_NDK}/sources/cxx-stl/llvm-libc++/libs/${CMAKE_ANDROID_ARCH_ABI}/libandroid_support.a" 0) endmacro() diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 1878b8a..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} @@ -900,7 +903,6 @@ 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 ) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 684dfa5..6a45aec 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 20170620) +set(CMake_VERSION_PATCH 20170713) #set(CMake_VERSION_RC 1) 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/cmCPackGeneratorFactory.cxx b/Source/CPack/cmCPackGeneratorFactory.cxx index f135059..834913d 100644 --- a/Source/CPack/cmCPackGeneratorFactory.cxx +++ b/Source/CPack/cmCPackGeneratorFactory.cxx @@ -12,6 +12,7 @@ #ifdef HAVE_FREEBSD_PKG #include "cmCPackFreeBSDGenerator.h" #endif +#include "cmCPackDebGenerator.h" #include "cmCPackGenerator.h" #include "cmCPackLog.h" #include "cmCPackNSISGenerator.h" @@ -37,7 +38,6 @@ #if !defined(_WIN32) && !defined(__QNXNTO__) && !defined(__BEOS__) && \ !defined(__HAIKU__) -#include "cmCPackDebGenerator.h" #include "cmCPackRPMGenerator.h" #endif @@ -102,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", @@ -126,10 +130,6 @@ 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); diff --git a/Source/bindexplib.cxx b/Source/bindexplib.cxx index cd1fb8a..e96226a 100644 --- a/Source/bindexplib.cxx +++ b/Source/bindexplib.cxx @@ -242,24 +242,26 @@ public: // Check whether it is "Scalar deleting destructor" and "Vector // deleting destructor" - // if scalarPrefix and vectorPrefix are not found then print the - // symbol + // if scalarPrefix and vectorPrefix are not found then print + // the symbol const char* scalarPrefix = "??_G"; const char* vectorPrefix = "??_E"; + // The original code had a check for + // symbol.find("real@") == std::string::npos) + // but this disallows member functions with the name "real". if (symbol.compare(0, 4, scalarPrefix) && symbol.compare(0, 4, vectorPrefix)) { SectChar = this->SectionHeaders[pSymbolTable->SectionNumber - 1] .Characteristics; - // skip symbols containing a dot if (symbol.find('.') == std::string::npos) { - if (SectChar & IMAGE_SCN_MEM_EXECUTE) { - this->Symbols.insert(symbol); - } else if (SectChar & IMAGE_SCN_MEM_READ) { - // skip __real@ and __xmm@ - if (symbol.find("_real") == std::string::npos && - symbol.find("_xmm") == std::string::npos) { - this->DataSymbols.insert(symbol); + if (!pSymbolTable->Type && (SectChar & IMAGE_SCN_MEM_WRITE)) { + // Read only (i.e. constants) must be excluded + this->DataSymbols.insert(symbol); + } else { + if (pSymbolTable->Type || !(SectChar & IMAGE_SCN_MEM_READ) || + (SectChar & IMAGE_SCN_MEM_EXECUTE)) { + this->Symbols.insert(symbol); } } } diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index e260556..6078256 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -190,7 +190,8 @@ int cmCTest::HTTPRequest(std::string url, HTTPMethod method, ::curl_easy_setopt(curl, CURLOPT_PUT, 1); file = cmsys::SystemTools::Fopen(putFile, "rb"); ::curl_easy_setopt(curl, CURLOPT_INFILE, file); - // fall through to append GET fields + // fall through to append GET fields + CM_FALLTHROUGH; case cmCTest::HTTP_GET: if (!fields.empty()) { url += "?" + fields; 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/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/cmFileLockResult.cxx b/Source/cmFileLockResult.cxx index a040705..9ca5d8a 100644 --- a/Source/cmFileLockResult.cxx +++ b/Source/cmFileLockResult.cxx @@ -5,6 +5,7 @@ #include <errno.h> #include <string.h> +#define WINMSG_BUF_LEN (1024) cmFileLockResult cmFileLockResult::MakeOk() { return cmFileLockResult(OK, 0); @@ -53,18 +54,12 @@ std::string cmFileLockResult::GetOutputMessage() const case SYSTEM: #if defined(_WIN32) { - char* errorText = NULL; - - // http://stackoverflow.com/a/455533/2288008 - DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS; - ::FormatMessageA(flags, NULL, this->ErrorValue, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPSTR)&errorText, 0, NULL); - - if (errorText != NULL) { - const std::string message = errorText; - ::LocalFree(errorText); + char winmsg[WINMSG_BUF_LEN]; + DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS; + if (FormatMessageA(flags, NULL, this->ErrorValue, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPSTR)winmsg, WINMSG_BUF_LEN, NULL)) { + const std::string message = winmsg; return message; } else { return "Internal error (FormatMessageA failed)"; diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx index 581c401..e378208 100644 --- a/Source/cmFindBase.cxx +++ b/Source/cmFindBase.cxx @@ -216,6 +216,8 @@ void cmFindBase::FillPackageRootPath() paths.AddCMakePrefixPath(varName); paths.AddEnvPrefixPath(varName); } + + paths.AddSuffixes(this->SearchPathSuffixes); } void cmFindBase::FillCMakeVariablePath() diff --git a/Source/cmFindCommon.cxx b/Source/cmFindCommon.cxx index 103e692..fd0e317 100644 --- a/Source/cmFindCommon.cxx +++ b/Source/cmFindCommon.cxx @@ -11,7 +11,7 @@ cmFindCommon::PathGroup cmFindCommon::PathGroup::All("ALL"); cmFindCommon::PathLabel cmFindCommon::PathLabel::PackageRoot( - "PacakgeName_ROOT"); + "PackageName_ROOT"); cmFindCommon::PathLabel cmFindCommon::PathLabel::CMake("CMAKE"); cmFindCommon::PathLabel cmFindCommon::PathLabel::CMakeEnvironment( "CMAKE_ENVIRONMENT"); @@ -231,18 +231,6 @@ void cmFindCommon::RerootPaths(std::vector<std::string>& paths) } } -void cmFindCommon::FilterPaths(const std::vector<std::string>& inPaths, - const std::set<std::string>& ignore, - std::vector<std::string>& outPaths) -{ - for (std::vector<std::string>::const_iterator i = inPaths.begin(); - i != inPaths.end(); ++i) { - if (ignore.count(*i) == 0) { - outPaths.push_back(*i); - } - } -} - void cmFindCommon::GetIgnoredPaths(std::vector<std::string>& ignore) { // null-terminated list of paths. diff --git a/Source/cmFindCommon.h b/Source/cmFindCommon.h index 2eed47b..7954267 100644 --- a/Source/cmFindCommon.h +++ b/Source/cmFindCommon.h @@ -81,11 +81,6 @@ protected: void GetIgnoredPaths(std::vector<std::string>& ignore); void GetIgnoredPaths(std::set<std::string>& ignore); - /** Remove paths in the ignore set from the supplied vector. */ - void FilterPaths(const std::vector<std::string>& inPaths, - const std::set<std::string>& ignore, - std::vector<std::string>& outPaths); - /** Compute final search path list (reroot + trailing slash). */ void ComputeFinalPaths(); diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index 65670e5..f291f9d 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -739,7 +739,8 @@ bool cmFindPackageCommand::HandlePackageMode() if (result && !found) { // warn if package required or neither quiet nor in config mode if (this->Required || - !(this->Quiet || (this->UseConfigFiles && !this->UseFindModules))) { + !(this->Quiet || (this->UseConfigFiles && !this->UseFindModules && + this->ConsideredConfigs.empty()))) { // The variable is not set. std::ostringstream e; std::ostringstream aw; 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/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx index f067d8f..b155f5b 100644 --- a/Source/cmGlobalVisualStudio7Generator.cxx +++ b/Source/cmGlobalVisualStudio7Generator.cxx @@ -520,6 +520,7 @@ std::string cmGlobalVisualStudio7Generator::ConvertToSolutionPath( void cmGlobalVisualStudio7Generator::WriteSLNGlobalSections( std::ostream& fout, cmLocalGenerator* root) { + std::string const guid = this->GetGUID(root->GetProjectName() + ".sln"); bool extensibilityGlobalsOverridden = false; bool extensibilityAddInsOverridden = false; const std::vector<std::string> propKeys = @@ -538,11 +539,14 @@ void cmGlobalVisualStudio7Generator::WriteSLNGlobalSections( } else continue; if (!name.empty()) { - if (name == "ExtensibilityGlobals" && sectionType == "postSolution") + bool addGuid = false; + if (name == "ExtensibilityGlobals" && sectionType == "postSolution") { + addGuid = true; extensibilityGlobalsOverridden = true; - else if (name == "ExtensibilityAddIns" && - sectionType == "postSolution") + } else if (name == "ExtensibilityAddIns" && + sectionType == "postSolution") { extensibilityAddInsOverridden = true; + } fout << "\tGlobalSection(" << name << ") = " << sectionType << "\n"; std::vector<std::string> keyValuePairs; cmSystemTools::ExpandListArgument( @@ -557,15 +561,23 @@ void cmGlobalVisualStudio7Generator::WriteSLNGlobalSections( const std::string value = cmSystemTools::TrimWhitespace(itPair->substr(posEqual + 1)); fout << "\t\t" << key << " = " << value << "\n"; + if (key == "SolutionGuid") { + addGuid = false; + } } } + if (addGuid) { + fout << "\t\tSolutionGuid = {" << guid << "}\n"; + } fout << "\tEndGlobalSection\n"; } } } - if (!extensibilityGlobalsOverridden) + if (!extensibilityGlobalsOverridden) { fout << "\tGlobalSection(ExtensibilityGlobals) = postSolution\n" + << "\t\tSolutionGuid = {" << guid << "}\n" << "\tEndGlobalSection\n"; + } if (!extensibilityAddInsOverridden) fout << "\tGlobalSection(ExtensibilityAddIns) = postSolution\n" << "\tEndGlobalSection\n"; diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 45c1764..4be3c80 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -147,7 +147,7 @@ cmGlobalXCodeGenerator::cmGlobalXCodeGenerator( this->XcodeBuildCommandInitialized = false; this->ObjectDirArchDefault = "$(CURRENT_ARCH)"; - this->ComputeObjectDirArch(); + this->ObjectDirArch = this->ObjectDirArchDefault; cm->GetState()->SetIsGeneratorMultiConfig(true); } @@ -3087,12 +3087,12 @@ void cmGlobalXCodeGenerator::ComputeArchitectures(cmMakefile* mf) } } - this->ComputeObjectDirArch(); + this->ComputeObjectDirArch(mf); } -void cmGlobalXCodeGenerator::ComputeObjectDirArch() +void cmGlobalXCodeGenerator::ComputeObjectDirArch(cmMakefile* mf) { - if (this->Architectures.size() > 1) { + if (this->Architectures.size() > 1 || this->UseEffectivePlatformName(mf)) { this->ObjectDirArch = "$(CURRENT_ARCH)"; } else if (!this->Architectures.empty()) { this->ObjectDirArch = this->Architectures[0]; @@ -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/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h index f38fa3c..e69793b 100644 --- a/Source/cmGlobalXCodeGenerator.h +++ b/Source/cmGlobalXCodeGenerator.h @@ -247,7 +247,7 @@ private: const cmGeneratorTarget* t) const; void ComputeArchitectures(cmMakefile* mf); - void ComputeObjectDirArch(); + void ComputeObjectDirArch(cmMakefile* mf); void addObject(cmXCodeObject* obj); std::string PostBuildMakeTarget(std::string const& tName, 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..b63683f 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(); @@ -1488,20 +1501,30 @@ void cmLocalGenerator::AddCompilerRequirementFlag( // This compiler has no notion of language standard levels. return; } - std::string stdProp = lang + "_STANDARD"; - const char* standardProp = target->GetProperty(stdProp); - if (!standardProp) { - return; - } std::string extProp = lang + "_EXTENSIONS"; - std::string type = "EXTENSION"; bool ext = true; if (const char* extPropValue = target->GetProperty(extProp)) { if (cmSystemTools::IsOff(extPropValue)) { ext = false; - type = "STANDARD"; } } + std::string stdProp = lang + "_STANDARD"; + const char* standardProp = target->GetProperty(stdProp); + if (!standardProp) { + if (ext) { + // No language standard is specified and extensions are not disabled. + // Check if this compiler needs a flag to enable extensions. + std::string const option_flag = + "CMAKE_" + lang + "_EXTENSION_COMPILE_OPTION"; + if (const char* opt = + target->Target->GetMakefile()->GetDefinition(option_flag)) { + this->AppendFlagEscape(flags, opt); + } + } + return; + } + + std::string const type = ext ? "EXTENSION" : "STANDARD"; if (target->GetPropertyAsBool(lang + "_STANDARD_REQUIRED")) { std::string option_flag = diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 2a93966..fb956bc 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -66,8 +66,8 @@ cmMakefile::cmMakefile(cmGlobalGenerator* globalGenerator, this->DefineFlags = " "; - this->cmDefineRegex.compile("#cmakedefine[ \t]+([A-Za-z_0-9]*)"); - this->cmDefine01Regex.compile("#cmakedefine01[ \t]+([A-Za-z_0-9]*)"); + this->cmDefineRegex.compile("#([ \t]*)cmakedefine[ \t]+([A-Za-z_0-9]*)"); + this->cmDefine01Regex.compile("#([ \t]*)cmakedefine01[ \t]+([A-Za-z_0-9]*)"); this->cmAtVarRegex.compile("(@[A-Za-z_0-9/.+-]+@)"); this->cmNamedCurly.compile("^[A-Za-z0-9/_.+-]+{"); @@ -87,12 +87,10 @@ cmMakefile::cmMakefile(cmGlobalGenerator* globalGenerator, #if defined(CMAKE_BUILD_WITH_CMAKE) this->AddSourceGroup("", "^.*$"); - this->AddSourceGroup("Source Files", - "\\.(C|M|c|c\\+\\+|cc|cpp|cxx|f|f90|for|fpp" - "|ftn|m|mm|rc|def|r|odl|idl|hpj|bat)$"); + this->AddSourceGroup("Source Files", CM_SOURCE_REGEX); this->AddSourceGroup("Header Files", CM_HEADER_REGEX); this->AddSourceGroup("CMake Rules", "\\.rule$"); - this->AddSourceGroup("Resources", "\\.plist$"); + this->AddSourceGroup("Resources", CM_RESOURCE_REGEX); this->AddSourceGroup("Object Files", "\\.(lo|o|obj)$"); this->ObjectLibrariesSourceGroupIndex = this->SourceGroups.size(); @@ -3433,18 +3431,22 @@ void cmMakefile::ConfigureString(const std::string& input, std::string& output, // Replace #cmakedefine instances. if (this->cmDefineRegex.find(line)) { - const char* def = this->GetDefinition(this->cmDefineRegex.match(1)); + const char* def = this->GetDefinition(this->cmDefineRegex.match(2)); if (!cmSystemTools::IsOff(def)) { - cmSystemTools::ReplaceString(line, "#cmakedefine", "#define"); + const std::string indentation = this->cmDefineRegex.match(1); + cmSystemTools::ReplaceString(line, "#" + indentation + "cmakedefine", + "#" + indentation + "define"); output += line; } else { output += "/* #undef "; - output += this->cmDefineRegex.match(1); + output += this->cmDefineRegex.match(2); output += " */"; } } else if (this->cmDefine01Regex.find(line)) { - const char* def = this->GetDefinition(this->cmDefine01Regex.match(1)); - cmSystemTools::ReplaceString(line, "#cmakedefine01", "#define"); + const std::string indentation = this->cmDefine01Regex.match(1); + const char* def = this->GetDefinition(this->cmDefine01Regex.match(2)); + cmSystemTools::ReplaceString(line, "#" + indentation + "cmakedefine01", + "#" + indentation + "define"); output += line; if (!cmSystemTools::IsOff(def)) { output += " 1"; @@ -4191,6 +4193,23 @@ bool cmMakefile::CompileFeatureKnown(cmTarget const* target, const char* cmMakefile::CompileFeaturesAvailable(const std::string& lang, std::string* error) const { + if (!this->GlobalGenerator->GetLanguageEnabled(lang)) { + std::ostringstream e; + if (error) { + e << "cannot"; + } else { + e << "Cannot"; + } + e << " use features from non-enabled language " << lang; + if (error) { + *error = e.str(); + } else { + this->GetCMakeInstance()->IssueMessage(cmake::FATAL_ERROR, e.str(), + this->Backtrace); + } + return CM_NULLPTR; + } + const char* featuresKnown = this->GetDefinition("CMAKE_" + lang + "_COMPILE_FEATURES"); @@ -4202,9 +4221,9 @@ const char* cmMakefile::CompileFeaturesAvailable(const std::string& lang, e << "No"; } e << " known features for " << lang << " compiler\n\"" - << this->GetDefinition("CMAKE_" + lang + "_COMPILER_ID") + << this->GetSafeDefinition("CMAKE_" + lang + "_COMPILER_ID") << "\"\nversion " - << this->GetDefinition("CMAKE_" + lang + "_COMPILER_VERSION") << "."; + << this->GetSafeDefinition("CMAKE_" + lang + "_COMPILER_VERSION") << "."; if (error) { *error = e.str(); } else { 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/cmQtAutoGeneratorInitializer.cxx b/Source/cmQtAutoGeneratorInitializer.cxx index 6924ba2..cecf165 100644 --- a/Source/cmQtAutoGeneratorInitializer.cxx +++ b/Source/cmQtAutoGeneratorInitializer.cxx @@ -303,6 +303,13 @@ static void AcquireScanFiles(cmGeneratorTarget const* target, !(fileType == cmSystemTools::HEADER_FILE_FORMAT)) { continue; } + if (PropertyEnabled(sf, "GENERATED") && + !target->GetPropertyAsBool("__UNDOCUMENTED_AUTOGEN_GENERATED_FILES")) { + // FIXME: Add a policy whose NEW behavior allows generated files. + // The implementation already works. We disable it here to avoid + // changing behavior for existing projects that do not expect it. + continue; + } const std::string absFile = cmsys::SystemTools::GetRealPath(sf->GetFullPath()); // Skip flags diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx index 27e4928..feec735 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( @@ -971,17 +973,19 @@ bool cmQtAutoGenerators::MocParseSourceContent( const std::string headerToMoc = this->MocFindHeader(scannedFileAbsPath, incSubDir + incRealBasename); if (!headerToMoc.empty()) { - // Register moc job - mocsIncluded[headerToMoc] = incString; - this->MocFindDepends(headerToMoc, contentText, mocDepends); - // Store meta information for relaxed mode - if (relaxed && (incRealBasename == scannedFileBasename)) { - ownMocUnderscoreInclude = incString; - ownMocUnderscoreHeader = headerToMoc; + if (!this->MocSkip(headerToMoc)) { + // Register moc job + mocsIncluded[headerToMoc] = incString; + this->MocFindDepends(headerToMoc, contentText, mocDepends); + // Store meta information for relaxed mode + if (relaxed && (incRealBasename == scannedFileBasename)) { + ownMocUnderscoreInclude = incString; + ownMocUnderscoreHeader = headerToMoc; + } } } else { std::ostringstream ost; - ost << "AutoMoc: Error: " << absFilename << "\n" + ost << "AutoMoc: Error: " << Quoted(absFilename) << "\n" << "The file includes the moc file " << Quoted(incString) << ", but could not find header " << Quoted(incRealBasename + "{" + @@ -1004,35 +1008,38 @@ bool cmQtAutoGenerators::MocParseSourceContent( const std::string headerToMoc = this->MocFindHeader(scannedFileAbsPath, incSubDir + incBasename); if (!headerToMoc.empty()) { - // This is for KDE4 compatibility: - fileToMoc = headerToMoc; - if (!requiresMoc && (incBasename == scannedFileBasename)) { - std::ostringstream ost; - ost << "AutoMoc: Warning: " << Quoted(absFilename) << "\n" + if (!this->MocSkip(headerToMoc)) { + // This is for KDE4 compatibility: + fileToMoc = headerToMoc; + if (!requiresMoc && (incBasename == scannedFileBasename)) { + std::ostringstream ost; + ost + << "AutoMoc: Warning: " << Quoted(absFilename) << "\n" << "The file includes the moc file " << Quoted(incString) << ", but does not contain a Q_OBJECT or Q_GADGET macro.\n" << "Running moc on " << Quoted(headerToMoc) << "!\n" << "Include " << Quoted("moc_" + incBasename + ".cpp") << " for a compatibility with strict mode (see " "CMAKE_AUTOMOC_RELAXED_MODE).\n"; - this->LogWarning(ost.str()); - } else { - std::ostringstream ost; - ost << "AutoMoc: Warning: " << Quoted(absFilename) << "\n" - << "The file includes the moc file " << Quoted(incString) - << " instead of " << Quoted("moc_" + incBasename + ".cpp") - << ".\n" - << "Running moc on " << Quoted(headerToMoc) << "!\n" - << "Include " << Quoted("moc_" + incBasename + ".cpp") - << " for compatibility with strict mode (see " - "CMAKE_AUTOMOC_RELAXED_MODE).\n"; - this->LogWarning(ost.str()); + this->LogWarning(ost.str()); + } else { + std::ostringstream ost; + ost << "AutoMoc: Warning: " << Quoted(absFilename) << "\n" + << "The file includes the moc file " << Quoted(incString) + << " instead of " + << Quoted("moc_" + incBasename + ".cpp") << ".\n" + << "Running moc on " << Quoted(headerToMoc) << "!\n" + << "Include " << Quoted("moc_" + incBasename + ".cpp") + << " for compatibility with strict mode (see " + "CMAKE_AUTOMOC_RELAXED_MODE).\n"; + this->LogWarning(ost.str()); + } } } else { std::ostringstream ost; ost << "AutoMoc: Error: " << Quoted(absFilename) << "\n" << "The file includes the moc file " << Quoted(incString) - << ". which seems to be the moc file from a different " + << ", which seems to be the moc file from a different " "source file. CMake also could not find a matching " "header."; this->LogError(ost.str()); @@ -1048,7 +1055,7 @@ bool cmQtAutoGenerators::MocParseSourceContent( // Accept but issue a warning if moc isn't required if (!requiresMoc) { std::ostringstream ost; - ost << "AutoMoc: Error: " << Quoted(absFilename) << "\n" + ost << "AutoMoc: Warning: " << Quoted(absFilename) << "\n" << "The file includes the moc file " << Quoted(incString) << ", but does not contain a Q_OBJECT or Q_GADGET " "macro."; @@ -1160,7 +1167,6 @@ void cmQtAutoGenerators::SearchHeadersForSourceFile( if (!this->UicSkip(absFilename) && !this->UicSkip(headerName)) { uicHeaderFiles.insert(headerName); } - break; } } } diff --git a/Source/cmSourceFile.h b/Source/cmSourceFile.h index 0be659c..e739d18 100644 --- a/Source/cmSourceFile.h +++ b/Source/cmSourceFile.h @@ -120,4 +120,10 @@ private: // TODO: Factor out into platform information modules. #define CM_HEADER_REGEX "\\.(h|hh|h\\+\\+|hm|hpp|hxx|in|txx|inl)$" +#define CM_SOURCE_REGEX \ + "\\.(C|M|c|c\\+\\+|cc|cpp|cxx|f|f90|for|fpp|ftn|m|mm|rc|def|r|odl|idl|hpj" \ + "|bat)$" + +#define CM_RESOURCE_REGEX "\\.(pdf|plist|png|jpeg|jpg|storyboard|xcassets)$" + #endif diff --git a/Source/cmVS10CLFlagTable.h b/Source/cmVS10CLFlagTable.h index dbd760e..df4d58c 100644 --- a/Source/cmVS10CLFlagTable.h +++ b/Source/cmVS10CLFlagTable.h @@ -70,7 +70,8 @@ static cmVS7FlagTable cmVS10CLFlagTable[] = { cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue }, { "PrecompiledHeader", "Yu", "Use", "Use", cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue }, - { "PrecompiledHeader", "", "Not Using Precompiled Headers", "NotUsing", 0 }, + { "PrecompiledHeader", "Y-", "Not Using Precompiled Headers", "NotUsing", + 0 }, { "AssemblerOutput", "", "No Listing", "NoListing", 0 }, { "AssemblerOutput", "FA", "Assembly-Only Listing", "AssemblyCode", 0 }, diff --git a/Source/cmVS10RCFlagTable.h b/Source/cmVS10RCFlagTable.h index 32f35e5..6e2b834 100644 --- a/Source/cmVS10RCFlagTable.h +++ b/Source/cmVS10RCFlagTable.h @@ -1,6 +1,7 @@ static cmVS7FlagTable cmVS10RCFlagTable[] = { // Bool Properties { "NullTerminateStrings", "n", "", "true", 0 }, + { "SuppressStartupBanner", "nologo", "", "true", 0 }, { 0, 0, 0, 0, 0 } }; diff --git a/Source/cmVS11CLFlagTable.h b/Source/cmVS11CLFlagTable.h index 7531709..d156938 100644 --- a/Source/cmVS11CLFlagTable.h +++ b/Source/cmVS11CLFlagTable.h @@ -74,7 +74,8 @@ static cmVS7FlagTable cmVS11CLFlagTable[] = { cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue }, { "PrecompiledHeader", "Yu", "Use", "Use", cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue }, - { "PrecompiledHeader", "", "Not Using Precompiled Headers", "NotUsing", 0 }, + { "PrecompiledHeader", "Y-", "Not Using Precompiled Headers", "NotUsing", + 0 }, { "AssemblerOutput", "", "No Listing", "NoListing", 0 }, { "AssemblerOutput", "FA", "Assembly-Only Listing", "AssemblyCode", 0 }, diff --git a/Source/cmVS11RCFlagTable.h b/Source/cmVS11RCFlagTable.h index 666e434..4997fe1 100644 --- a/Source/cmVS11RCFlagTable.h +++ b/Source/cmVS11RCFlagTable.h @@ -1,6 +1,7 @@ static cmVS7FlagTable cmVS11RCFlagTable[] = { // Bool Properties { "NullTerminateStrings", "n", "", "true", 0 }, + { "SuppressStartupBanner", "nologo", "", "true", 0 }, { 0, 0, 0, 0, 0 } }; diff --git a/Source/cmVS12CLFlagTable.h b/Source/cmVS12CLFlagTable.h index 9515c91..a4f2518 100644 --- a/Source/cmVS12CLFlagTable.h +++ b/Source/cmVS12CLFlagTable.h @@ -78,7 +78,8 @@ static cmVS7FlagTable cmVS12CLFlagTable[] = { cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue }, { "PrecompiledHeader", "Yu", "Use", "Use", cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue }, - { "PrecompiledHeader", "", "Not Using Precompiled Headers", "NotUsing", 0 }, + { "PrecompiledHeader", "Y-", "Not Using Precompiled Headers", "NotUsing", + 0 }, { "AssemblerOutput", "", "No Listing", "NoListing", 0 }, { "AssemblerOutput", "FA", "Assembly-Only Listing", "AssemblyCode", 0 }, diff --git a/Source/cmVS12RCFlagTable.h b/Source/cmVS12RCFlagTable.h index d047f824..a650f85 100644 --- a/Source/cmVS12RCFlagTable.h +++ b/Source/cmVS12RCFlagTable.h @@ -1,6 +1,7 @@ static cmVS7FlagTable cmVS12RCFlagTable[] = { // Bool Properties { "NullTerminateStrings", "n", "", "true", 0 }, + { "SuppressStartupBanner", "nologo", "", "true", 0 }, { 0, 0, 0, 0, 0 } }; diff --git a/Source/cmVS140CLFlagTable.h b/Source/cmVS140CLFlagTable.h index 60b4379..2b89042 100644 --- a/Source/cmVS140CLFlagTable.h +++ b/Source/cmVS140CLFlagTable.h @@ -80,7 +80,8 @@ static cmVS7FlagTable cmVS140CLFlagTable[] = { cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue }, { "PrecompiledHeader", "Yu", "Use", "Use", cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue }, - { "PrecompiledHeader", "", "Not Using Precompiled Headers", "NotUsing", 0 }, + { "PrecompiledHeader", "Y-", "Not Using Precompiled Headers", "NotUsing", + 0 }, { "AssemblerOutput", "", "No Listing", "NoListing", 0 }, { "AssemblerOutput", "FA", "Assembly-Only Listing", "AssemblyCode", 0 }, diff --git a/Source/cmVS14LinkFlagTable.h b/Source/cmVS140LinkFlagTable.h index 596f880..b9a4dc3 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 }, @@ -129,9 +134,6 @@ static cmVS7FlagTable cmVS14LinkFlagTable[] = { { "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 }, diff --git a/Source/cmVS141CLFlagTable.h b/Source/cmVS141CLFlagTable.h index f751fc8..e8b8f5c 100644 --- a/Source/cmVS141CLFlagTable.h +++ b/Source/cmVS141CLFlagTable.h @@ -87,7 +87,8 @@ static cmVS7FlagTable cmVS141CLFlagTable[] = { cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue }, { "PrecompiledHeader", "Yu", "Use", "Use", cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue }, - { "PrecompiledHeader", "", "Not Using Precompiled Headers", "NotUsing", 0 }, + { "PrecompiledHeader", "Y-", "Not Using Precompiled Headers", "NotUsing", + 0 }, { "AssemblerOutput", "", "No Listing", "NoListing", 0 }, { "AssemblerOutput", "FA", "Assembly-Only Listing", "AssemblyCode", 0 }, diff --git a/Source/cmVS141LinkFlagTable.h b/Source/cmVS141LinkFlagTable.h new file mode 100644 index 0000000..8f0f1f4 --- /dev/null +++ b/Source/cmVS141LinkFlagTable.h @@ -0,0 +1,283 @@ +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 }, + + // 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/cmVS14RCFlagTable.h b/Source/cmVS14RCFlagTable.h index 11e00d5..5dc8d5a 100644 --- a/Source/cmVS14RCFlagTable.h +++ b/Source/cmVS14RCFlagTable.h @@ -1,6 +1,7 @@ static cmVS7FlagTable cmVS14RCFlagTable[] = { // Bool Properties { "NullTerminateStrings", "n", "", "true", 0 }, + { "SuppressStartupBanner", "nologo", "", "true", 0 }, { 0, 0, 0, 0, 0 } }; diff --git a/Source/cmVSSetupHelper.cxx b/Source/cmVSSetupHelper.cxx index c2ff664..7168f26 100644 --- a/Source/cmVSSetupHelper.cxx +++ b/Source/cmVSSetupHelper.cxx @@ -1,6 +1,7 @@ /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmVSSetupHelper.h" +#include "cmSystemTools.h" #ifndef VSSetupConstants #define VSSetupConstants @@ -240,6 +241,22 @@ bool cmVSSetupAPIHelper::EnumerateAndChooseVSInstance() setupHelper == NULL) return false; + std::string envVSCommonToolsDir; + + // FIXME: When we support VS versions beyond 2017, the version + // to choose will be passed in by the caller. We need to map that + // to a per-version name of this environment variable. + if (cmSystemTools::GetEnv("VS150COMNTOOLS", envVSCommonToolsDir)) { + cmSystemTools::ConvertToUnixSlashes(envVSCommonToolsDir); + } + // FIXME: If the environment variable value changes between runs + // of CMake within a given build tree the results are not defined. + // Instead we should save a CMAKE_GENERATOR_INSTANCE value in the cache + // (similar to CMAKE_GENERATOR_TOOLSET) to hold it persistently. + // Unfortunately doing so will require refactoring elsewhere in + // order to make sure the value is available in time to create + // the generator. + std::vector<VSInstanceInfo> vecVSInstances; SmartCOMPtr<IEnumSetupInstances> enumInstances = NULL; if (FAILED( @@ -263,6 +280,17 @@ bool cmVSSetupAPIHelper::EnumerateAndChooseVSInstance() instance = instance2 = NULL; if (isInstalled) { + if (!envVSCommonToolsDir.empty()) { + std::string currentVSLocation(instanceInfo.VSInstallLocation.begin(), + instanceInfo.VSInstallLocation.end()); + cmSystemTools::ConvertToUnixSlashes(currentVSLocation); + currentVSLocation += "/Common7/Tools"; + if (cmSystemTools::ComparePath(currentVSLocation, + envVSCommonToolsDir)) { + chosenInstanceInfo = instanceInfo; + return true; + } + } vecVSInstances.push_back(instanceInfo); } } diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index d689dcf..e4a4d6f 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmVisualStudio10TargetGenerator.h" +#include "cmAlgorithms.h" #include "cmComputeLinkInformation.h" #include "cmCustomCommandGenerator.h" #include "cmGeneratedFileStream.h" @@ -16,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, "&", "&"); @@ -26,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 @@ -145,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"; @@ -293,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); @@ -310,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); @@ -464,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); @@ -567,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) { @@ -577,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 @@ -706,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 @@ -719,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"; @@ -829,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(); @@ -948,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")) { @@ -1150,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 = @@ -1171,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); + } } } } @@ -1208,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) { @@ -1217,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( @@ -1274,7 +1359,7 @@ void cmVisualStudio10TargetGenerator::ConvertToWindowsSlash(std::string& s) } void cmVisualStudio10TargetGenerator::WriteGroups() { - if (csproj == this->ProjectType) { + if (this->ProjectType == csproj) { return; } @@ -1516,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 @@ -2038,19 +2123,15 @@ 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; - } + std::string link; + this->GetCSharpSourceLink(source, link); + if (!link.empty()) { + sourceFileTags["Link"] = link; } this->GetCSharpSourceProperties(&sf, sourceFileTags); // write source file specific tags @@ -2084,7 +2165,7 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions() if (ttype > cmStateEnums::GLOBAL_TARGET) { return; } - if (csproj == this->ProjectType) { + if (this->ProjectType == csproj) { return; } @@ -2161,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 @@ -2241,10 +2322,27 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions( this->Name.c_str()); return false; } - if (linkLanguage == "C" || linkLanguage == "CXX" || - linkLanguage == "Fortran" || linkLanguage == "CSharp") { + + // Choose a language whose flags to use for ClCompile. + static const char* clLangs[] = { "CXX", "C", "Fortran", "CSharp" }; + std::string langForClCompile; + if (std::find(cmArrayBegin(clLangs), cmArrayEnd(clLangs), linkLanguage) != + cmArrayEnd(clLangs)) { + langForClCompile = linkLanguage; + } else { + std::set<std::string> languages; + this->GeneratorTarget->GetLanguages(languages, configName); + for (const char* const* l = cmArrayBegin(clLangs); + l != cmArrayEnd(clLangs); ++l) { + if (languages.find(*l) != languages.end()) { + langForClCompile = *l; + break; + } + } + } + if (!langForClCompile.empty()) { std::string baseFlagVar = "CMAKE_"; - baseFlagVar += linkLanguage; + baseFlagVar += langForClCompile; baseFlagVar += "_FLAGS"; flags = this->GeneratorTarget->Target->GetMakefile()->GetRequiredDefinition( @@ -2255,6 +2353,8 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions( flags += this->GeneratorTarget->Target->GetMakefile()->GetRequiredDefinition( flagVar.c_str()); + this->LocalGenerator->AddCompileOptions(flags, this->GeneratorTarget, + langForClCompile, configName); } // set the correct language if (linkLanguage == "C") { @@ -2263,10 +2363,6 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions( if (linkLanguage == "CXX") { clOptions.AddFlag("CompileAs", "CompileAsCpp"); } - if (linkLanguage != "CUDA") { - this->LocalGenerator->AddCompileOptions(flags, this->GeneratorTarget, - linkLanguage, configName.c_str()); - } // Check IPO related warning/error. this->GeneratorTarget->IsIPOEnabled(linkLanguage, configName); @@ -2275,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 + "/"; @@ -2332,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") { @@ -2340,7 +2436,7 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions( clOptions.AddFlag("CallingConvention", ""); } } - if (csproj == this->ProjectType) { + if (this->ProjectType == csproj) { // /nowin32manifest overrides /win32manifest: parameter if (clOptions.HasFlag("NoWin32Manifest")) { clOptions.RemoveFlag("ApplicationManifest"); @@ -2500,6 +2596,8 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaOptions( std::string(this->Makefile->GetSafeDefinition("CMAKE_CUDA_FLAGS")) + std::string(" ") + std::string(this->Makefile->GetSafeDefinition(configFlagsVar)); + this->LocalGenerator->AddCompileOptions(flags, this->GeneratorTarget, "CUDA", + configName); // Get preprocessor definitions for this directory. std::string defineFlags = @@ -2525,9 +2623,16 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaOptions( cudaOptions.AddTable(gg->GetCudaHostFlagTable()); cudaOptions.Reparse("AdditionalCompilerOptions"); - // `CUDA 8.0.targets` places these before nvcc! Just drop whatever - // did not parse and hope it works. - cudaOptions.RemoveFlag("AdditionalCompilerOptions"); + // `CUDA 8.0.targets` places AdditionalCompilerOptions before nvcc! + // Pass them through -Xcompiler in AdditionalOptions instead. + if (const char* acoPtr = cudaOptions.GetFlag("AdditionalCompilerOptions")) { + std::string aco = acoPtr; + cudaOptions.RemoveFlag("AdditionalCompilerOptions"); + if (!aco.empty()) { + aco = this->LocalGenerator->EscapeForShell(aco, false); + cudaOptions.AppendFlagString("AdditionalOptions", "-Xcompiler=" + aco); + } + } cudaOptions.FixCudaCodeGeneration(); @@ -2614,8 +2719,8 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaLinkOptions( // Suppress deprecation warnings for default GPU targets during device link. if (cmSystemTools::VersionCompareGreaterEq( this->GlobalGenerator->GetPlatformToolsetCudaString(), "8.0")) { - cudaLinkOptions.AppendFlag("AdditionalOptions", - "-Wno-deprecated-gpu-targets"); + cudaLinkOptions.AppendFlagString("AdditionalOptions", + "-Wno-deprecated-gpu-targets"); } this->CudaLinkOptions[configName] = pOptions.release(); @@ -3125,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 += "/"; @@ -3177,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"); } } } @@ -3255,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]); @@ -3325,7 +3413,7 @@ void cmVisualStudio10TargetGenerator::WriteMidlOptions( if (!this->MSTools) { return; } - if (csproj == this->ProjectType) { + if (this->ProjectType == csproj) { return; } @@ -3367,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) { @@ -3391,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> @@ -3457,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); @@ -3467,7 +3558,7 @@ void cmVisualStudio10TargetGenerator::WriteEvent( } } (*this->BuildFileStream) << script; - if (csproj != this->ProjectType) { + if (this->ProjectType != csproj) { (*this->BuildFileStream) << "</Command>"; } (*this->BuildFileStream) << "\n"; @@ -3495,10 +3586,6 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences() ->TargetIsFortranOnly(dt)) { continue; } - if (csproj == this->ProjectType && - !this->GlobalGenerator->TargetIsCSharpOnly(dt)) { - continue; - } this->WriteString("<ProjectReference Include=\"", 2); cmLocalGenerator* lg = dt->GetLocalGenerator(); std::string name = dt->GetName(); @@ -4311,7 +4398,7 @@ bool cmVisualStudio10TargetGenerator::ForceOld(const std::string& source) const void cmVisualStudio10TargetGenerator::GetCSharpSourceProperties( cmSourceFile const* sf, std::map<std::string, std::string>& tags) { - if (csproj == this->ProjectType) { + if (this->ProjectType == csproj) { const cmPropertyMap& props = sf->GetProperties(); for (cmPropertyMap::const_iterator p = props.begin(); p != props.end(); ++p) { @@ -4344,6 +4431,23 @@ void cmVisualStudio10TargetGenerator::WriteCSharpSourceProperties( } } +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 0852459..2d98994 100644 --- a/Source/cmVisualStudio10TargetGenerator.h +++ b/Source/cmVisualStudio10TargetGenerator.h @@ -127,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(); @@ -158,6 +168,7 @@ private: 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; @@ -193,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/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index d138f58..34418c5 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -331,6 +331,7 @@ if(BUILD_TESTING) if(${CMAKE_GENERATOR} MATCHES "Visual Studio ([^89]|[89][0-9])") ADD_TEST_MACRO(CSharpOnly CSharpOnly) + ADD_TEST_MACRO(CSharpLinkToCxx CSharpLinkToCxx) endif() ADD_TEST_MACRO(COnly COnly) @@ -2081,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/CSharpLinkToCxx/CMakeLists.txt b/Tests/CSharpLinkToCxx/CMakeLists.txt new file mode 100644 index 0000000..c4269e0 --- /dev/null +++ b/Tests/CSharpLinkToCxx/CMakeLists.txt @@ -0,0 +1,17 @@ +# test if CSharp application correctly links +# to managed C++ binary +cmake_minimum_required(VERSION 3.9) +project (CSharpLinkToCxx CXX CSharp) + +# we have to change the default flags for the +# managed C++ project to build +string(REPLACE "/EHsc" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) +string(REPLACE "/RTC1" "" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG}) + +add_library(CLIApp SHARED cli.hpp cli.cpp) + +target_compile_options(CLIApp PRIVATE "/clr") + +add_executable(CSharpLinkToCxx csharp.cs) + +target_link_libraries(CSharpLinkToCxx CLIApp) diff --git a/Tests/CSharpLinkToCxx/cli.cpp b/Tests/CSharpLinkToCxx/cli.cpp new file mode 100644 index 0000000..97ac724 --- /dev/null +++ b/Tests/CSharpLinkToCxx/cli.cpp @@ -0,0 +1,10 @@ +#include "cli.hpp" + +using namespace System; + +namespace CLIApp { +void MyCli::testMyCli() +{ + Console::WriteLine("#message from CLIApp"); +} +} diff --git a/Tests/CSharpLinkToCxx/cli.hpp b/Tests/CSharpLinkToCxx/cli.hpp new file mode 100644 index 0000000..a8c116d --- /dev/null +++ b/Tests/CSharpLinkToCxx/cli.hpp @@ -0,0 +1,10 @@ +#pragma once + +namespace CLIApp { +public +ref class MyCli +{ +public: + void testMyCli(); +}; +} diff --git a/Tests/CSharpLinkToCxx/csharp.cs b/Tests/CSharpLinkToCxx/csharp.cs new file mode 100644 index 0000000..35c5cc3 --- /dev/null +++ b/Tests/CSharpLinkToCxx/csharp.cs @@ -0,0 +1,16 @@ +using System; +using CLIApp; + +namespace CSharpLinkToCxx +{ + internal class CSharpLinkToCxx + { + public static void Main(string[] args) + { + Console.WriteLine("#message from CSharpLinkToCxx"); + + var app = new MyCli(); + app.testMyCli(); + } + } +} diff --git a/Tests/Complex/CMakeLists.txt b/Tests/Complex/CMakeLists.txt index 075faa7..8537cd9 100644 --- a/Tests/Complex/CMakeLists.txt +++ b/Tests/Complex/CMakeLists.txt @@ -356,6 +356,8 @@ endwhile() set(SHOULD_BE_ZERO ) set(SHOULD_BE_ONE 1) +set(SHOULD_BE_ZERO_AND_INDENTED ) +set(SHOULD_BE_ONE_AND_INDENTED 1) # test elseif functionality, the mess below tries to catch problem # of clauses being executed early or late etc diff --git a/Tests/Complex/Executable/complex.cxx b/Tests/Complex/Executable/complex.cxx index 3b09229..ca39870 100644 --- a/Tests/Complex/Executable/complex.cxx +++ b/Tests/Complex/Executable/complex.cxx @@ -261,6 +261,12 @@ int main() cmPassed("ONE_VAR is defined."); #endif +#ifndef ONE_VAR_AND_INDENTED + cmFailed("cmakedefine is broken, ONE_VAR_AND_INDENTED is not defined."); +#else + cmPassed("ONE_VAR_AND_INDENTED is defined."); +#endif + #ifndef ONE_VAR_IS_DEFINED cmFailed("cmakedefine, SET or VARIABLE_REQUIRES is broken, " "ONE_VAR_IS_DEFINED is not defined."); @@ -274,6 +280,12 @@ int main() cmPassed("ZERO_VAR is not defined."); #endif +#ifdef ZERO_VAR_AND_INDENTED + cmFailed("cmakedefine is broken, ZERO_VAR_AND_INDENTED is defined."); +#else + cmPassed("ZERO_VAR_AND_INDENTED is not defined."); +#endif + #ifndef STRING_VAR cmFailed("the CONFIGURE_FILE command is broken, STRING_VAR is not defined."); #else @@ -1030,6 +1042,16 @@ int main() } else { cmFailed("cmakedefine01 is not working for 1"); } + if (SHOULD_BE_ZERO_AND_INDENTED == 0) { + cmPassed("cmakedefine01 is working for 0 and indented"); + } else { + cmFailed("cmakedefine01 is not working for 0 and indented"); + } + if (SHOULD_BE_ONE_AND_INDENTED == 1) { + cmPassed("cmakedefine01 is working for 1 and indented"); + } else { + cmFailed("cmakedefine01 is not working for 1 and indented"); + } #ifdef FORCE_TEST cmFailed("CMake SET CACHE FORCE"); #else diff --git a/Tests/Complex/VarTests.cmake b/Tests/Complex/VarTests.cmake index 8be59be..9761986 100644 --- a/Tests/Complex/VarTests.cmake +++ b/Tests/Complex/VarTests.cmake @@ -2,6 +2,7 @@ # Test SET # set (ZERO_VAR 0) +set (ZERO_VAR_AND_INDENTED 0) set (ZERO_VAR2 0) if(ZERO_VAR) @@ -11,6 +12,7 @@ else() endif() set(ONE_VAR 1) +set(ONE_VAR_AND_INDENTED 1) set(ONE_VAR2 1) set(STRING_VAR "CMake is great" CACHE STRING "test a cache variable") diff --git a/Tests/Complex/cmTestConfigure.h.in b/Tests/Complex/cmTestConfigure.h.in index d7424b1..72317bc 100644 --- a/Tests/Complex/cmTestConfigure.h.in +++ b/Tests/Complex/cmTestConfigure.h.in @@ -1,8 +1,10 @@ // Test SET, VARIABLE_REQUIRES #cmakedefine ONE_VAR +# cmakedefine ONE_VAR_AND_INDENTED #cmakedefine ONE_VAR_IS_DEFINED #cmakedefine ZERO_VAR +# cmakedefine ZERO_VAR_AND_INDENTED #define STRING_VAR "${STRING_VAR}" @@ -32,6 +34,8 @@ #cmakedefine01 SHOULD_BE_ZERO #cmakedefine01 SHOULD_BE_ONE +# cmakedefine01 SHOULD_BE_ZERO_AND_INDENTED +# cmakedefine01 SHOULD_BE_ONE_AND_INDENTED // Needed to check for files #define BINARY_DIR "${Complex_BINARY_DIR}" diff --git a/Tests/ComplexOneConfig/CMakeLists.txt b/Tests/ComplexOneConfig/CMakeLists.txt index 1b833b2..4cd0bae 100644 --- a/Tests/ComplexOneConfig/CMakeLists.txt +++ b/Tests/ComplexOneConfig/CMakeLists.txt @@ -313,6 +313,8 @@ endwhile() set(SHOULD_BE_ZERO ) set(SHOULD_BE_ONE 1) +set(SHOULD_BE_ZERO_AND_INDENTED ) +set(SHOULD_BE_ONE_AND_INDENTED 1) # test elseif functionality, the mess below tries to catch problem # of clauses being executed early or late etc diff --git a/Tests/ComplexOneConfig/Executable/complex.cxx b/Tests/ComplexOneConfig/Executable/complex.cxx index 9e4eaad..9b94962 100644 --- a/Tests/ComplexOneConfig/Executable/complex.cxx +++ b/Tests/ComplexOneConfig/Executable/complex.cxx @@ -261,6 +261,12 @@ int main() cmPassed("ONE_VAR is defined."); #endif +#ifndef ONE_VAR_AND_INDENTED + cmFailed("cmakedefine is broken, ONE_VAR_AND_INDENTED is not defined."); +#else + cmPassed("ONE_VAR_AND_INDENTED is defined."); +#endif + #ifndef ONE_VAR_IS_DEFINED cmFailed("cmakedefine, SET or VARIABLE_REQUIRES is broken, " "ONE_VAR_IS_DEFINED is not defined."); @@ -274,6 +280,12 @@ int main() cmPassed("ZERO_VAR is not defined."); #endif +#ifdef ZERO_VAR_AND_INDENTED + cmFailed("cmakedefine is broken, ZERO_VAR_AND_INDENTED is defined."); +#else + cmPassed("ZERO_VAR_AND_INDENTED is not defined."); +#endif + #ifndef STRING_VAR cmFailed("the CONFIGURE_FILE command is broken, STRING_VAR is not defined."); #else @@ -1030,6 +1042,16 @@ int main() } else { cmFailed("cmakedefine01 is not working for 1"); } + if (SHOULD_BE_ZERO_AND_INDENTED == 0) { + cmPassed("cmakedefine01 is working for 0 and indented"); + } else { + cmFailed("cmakedefine01 is not working for 0 and indented"); + } + if (SHOULD_BE_ONE_AND_INDENTED == 1) { + cmPassed("cmakedefine01 is working for 1 and indented"); + } else { + cmFailed("cmakedefine01 is not working for 1 and indented"); + } #ifdef FORCE_TEST cmFailed("CMake SET CACHE FORCE"); #else diff --git a/Tests/ComplexOneConfig/VarTests.cmake b/Tests/ComplexOneConfig/VarTests.cmake index 7dd8519..42afd19 100644 --- a/Tests/ComplexOneConfig/VarTests.cmake +++ b/Tests/ComplexOneConfig/VarTests.cmake @@ -2,6 +2,7 @@ # Test SET # set (ZERO_VAR 0) +set (ZERO_VAR_AND_INDENTED 0) set (ZERO_VAR2 0) if(ZERO_VAR) @@ -11,6 +12,7 @@ else() endif() set(ONE_VAR 1) +set(ONE_VAR_AND_INDENTED 1) set(ONE_VAR2 1) set(STRING_VAR "CMake is great" CACHE STRING "test a cache variable") diff --git a/Tests/ComplexOneConfig/cmTestConfigure.h.in b/Tests/ComplexOneConfig/cmTestConfigure.h.in index d7424b1..72317bc 100644 --- a/Tests/ComplexOneConfig/cmTestConfigure.h.in +++ b/Tests/ComplexOneConfig/cmTestConfigure.h.in @@ -1,8 +1,10 @@ // Test SET, VARIABLE_REQUIRES #cmakedefine ONE_VAR +# cmakedefine ONE_VAR_AND_INDENTED #cmakedefine ONE_VAR_IS_DEFINED #cmakedefine ZERO_VAR +# cmakedefine ZERO_VAR_AND_INDENTED #define STRING_VAR "${STRING_VAR}" @@ -32,6 +34,8 @@ #cmakedefine01 SHOULD_BE_ZERO #cmakedefine01 SHOULD_BE_ONE +# cmakedefine01 SHOULD_BE_ZERO_AND_INDENTED +# cmakedefine01 SHOULD_BE_ONE_AND_INDENTED // Needed to check for files #define BINARY_DIR "${Complex_BINARY_DIR}" 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 0a2542a..7ef626f 100644 --- a/Tests/CudaOnly/SeparateCompilation/CMakeLists.txt +++ b/Tests/CudaOnly/SeparateCompilation/CMakeLists.txt @@ -15,6 +15,15 @@ set(CMAKE_CUDA_STANDARD 11) add_library(CUDASeparateLibA STATIC file1.cu file2.cu file3.cu) +if(CMAKE_CUDA_SIMULATE_ID STREQUAL "MSVC") + # Test adding a flag that is not in our CUDA flag table for VS. + if(NOT CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 8) + string(APPEND CMAKE_CUDA_FLAGS " --ftemplate-depth 50") + endif() + # Test adding a flag that nvcc should pass to the host compiler. + target_compile_options(CUDASeparateLibA PRIVATE -Xcompiler=-bigobj) +endif() + #Having file4/file5 in a shared library causes serious problems #with the nvcc linker and it will generate bad entries that will #cause a segv when trying to run the executable @@ -39,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 38f2a44..0bc4e5c 100644 --- a/Tests/CudaOnly/WithDefs/CMakeLists.txt +++ b/Tests/CudaOnly/WithDefs/CMakeLists.txt @@ -28,6 +28,7 @@ add_executable(CudaOnlyWithDefs ${main}) target_compile_options(CudaOnlyWithDefs PRIVATE + -Xcompiler=-DHOST_DEFINE $<$<CONFIG:DEBUG>:$<BUILD_INTERFACE:${debug_compile_flags}>> ) @@ -36,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/CudaOnly/WithDefs/main.notcu b/Tests/CudaOnly/WithDefs/main.notcu index 80ed3a5..d2eff3f 100644 --- a/Tests/CudaOnly/WithDefs/main.notcu +++ b/Tests/CudaOnly/WithDefs/main.notcu @@ -2,6 +2,10 @@ #include <cuda_runtime.h> #include <iostream> +#ifndef HOST_DEFINE +#error "HOST_DEFINE not defined!" +#endif + #ifndef PACKED_DEFINE #error "PACKED_DEFINE not defined!" #endif diff --git a/Tests/MFC/CMakeLists.txt.in b/Tests/MFC/CMakeLists.txt.in index e6bfabd..bf98e91 100644 --- a/Tests/MFC/CMakeLists.txt.in +++ b/Tests/MFC/CMakeLists.txt.in @@ -45,6 +45,11 @@ set(files set(CMAKE_MFC_FLAG "@CMAKE_MFC_FLAG_VALUE@") +FIND_PACKAGE(MFC) +IF (NOT MFC_FOUND) + MESSAGE(FATAL_ERROR "MFC Could not be found during the MFC test") +ENDIF() + if("${CMAKE_MFC_FLAG}" STREQUAL "1") msvc_link_to_static_crt() else() diff --git a/Tests/QtAutogen/CMakeLists.txt b/Tests/QtAutogen/CMakeLists.txt index 3c6b2b3..89d2b80 100644 --- a/Tests/QtAutogen/CMakeLists.txt +++ b/Tests/QtAutogen/CMakeLists.txt @@ -61,6 +61,21 @@ if(NON_ASCII_BDIR AND WIN32) 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) set_property(TARGET rccOnly PROPERTY AUTORCC ON) @@ -73,15 +88,6 @@ set_property(TARGET rccEmpty PROPERTY AUTORCC ON) target_link_libraries(rccEmpty ${QT_QTCORE_TARGET}) # -- 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 # 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 diff --git a/Tests/QtAutogen/mocDepends/CMakeLists.txt b/Tests/QtAutogen/mocDepends/CMakeLists.txt index 8bd72eb..a67dcfe 100644 --- a/Tests/QtAutogen/mocDepends/CMakeLists.txt +++ b/Tests/QtAutogen/mocDepends/CMakeLists.txt @@ -28,6 +28,7 @@ add_executable(mocDepends1 test1.cpp ) target_link_libraries(mocDepends1 ${QT_CORE_TARGET}) set_target_properties(mocDepends1 PROPERTIES AUTOMOC TRUE) +set_property(TARGET mocDepends1 PROPERTY __UNDOCUMENTED_AUTOGEN_GENERATED_FILES 1) # -- Test 2 using generated library # This tests the dependency of AUTOMOC of mocDepends2 to the @@ -43,3 +44,4 @@ add_library(SimpleLib STATIC simpleLib.hpp simpleLib.cpp) add_executable(mocDepends2 test2.cpp ) target_link_libraries(mocDepends2 SimpleLib ${QT_CORE_TARGET}) set_target_properties(mocDepends2 PROPERTIES AUTOMOC TRUE) +set_property(TARGET mocDepends2 PROPERTY __UNDOCUMENTED_AUTOGEN_GENERATED_FILES 1) 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/QtAutogen/mocRerun/CMakeLists.txt b/Tests/QtAutogen/mocRerun/CMakeLists.txt index 69ea8d7..14b077b 100644 --- a/Tests/QtAutogen/mocRerun/CMakeLists.txt +++ b/Tests/QtAutogen/mocRerun/CMakeLists.txt @@ -27,6 +27,7 @@ add_executable(mocRerun ${CMAKE_CURRENT_BINARY_DIR}/main.cpp res1.qrc ) +set_property(TARGET mocRerun PROPERTY __UNDOCUMENTED_AUTOGEN_GENERATED_FILES 1) target_include_directories(mocRerun PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) target_link_libraries(mocRerun ${QT_CORE_TARGET}) # Write target name to text file diff --git a/Tests/RunCMake/AutoExportDll/foo.c b/Tests/RunCMake/AutoExportDll/foo.c index e70fbb5..4b1318b 100644 --- a/Tests/RunCMake/AutoExportDll/foo.c +++ b/Tests/RunCMake/AutoExportDll/foo.c @@ -13,5 +13,3 @@ int bar() { return 5; } - -const char testconst[] = "testconst"; diff --git a/Tests/RunCMake/AutoExportDll/say.cxx b/Tests/RunCMake/AutoExportDll/say.cxx index eb9c0ff..51060e8 100644 --- a/Tests/RunCMake/AutoExportDll/say.cxx +++ b/Tests/RunCMake/AutoExportDll/say.cxx @@ -13,14 +13,6 @@ int WINAPI foo(); int bar(); int objlib(); void justnop(); - -// test const export -#ifdef _WIN32 -// data symbols must be explicitly imported -__declspec(dllimport) extern const char testconst[]; -#else -extern const char testconst[]; -#endif } // test c++ functions @@ -51,8 +43,6 @@ int main() bar(); objlib(); printf("\n"); - printf("%s", testconst); - printf("\n"); #ifdef HAS_JUSTNOP justnop(); #endif diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 0369fa4..246138b 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -215,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}) @@ -376,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/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/VSSolution/MorePost-check.cmake b/Tests/RunCMake/VSSolution/MorePost-check.cmake index 0f7e370..d239b28 100644 --- a/Tests/RunCMake/VSSolution/MorePost-check.cmake +++ b/Tests/RunCMake/VSSolution/MorePost-check.cmake @@ -1,5 +1,5 @@ parseGlobalSections(pre post MorePost) testGlobalSection(post TestSec2 Key1=Value1 "Key2=Value with spaces") testGlobalSection(post TestSec4 Key6=Value1 "Key7=Value with spaces" Key8=ValueWithoutSpaces) -testGlobalSection(post ExtensibilityGlobals) +testGlobalSection(post ExtensibilityGlobals "SolutionGuid={00000000-0000-0000-0000-000000000000}") testGlobalSection(post ExtensibilityAddIns) diff --git a/Tests/RunCMake/VSSolution/MorePre-check.cmake b/Tests/RunCMake/VSSolution/MorePre-check.cmake index 45e7419..89b3c7e 100644 --- a/Tests/RunCMake/VSSolution/MorePre-check.cmake +++ b/Tests/RunCMake/VSSolution/MorePre-check.cmake @@ -1,5 +1,5 @@ parseGlobalSections(pre post MorePre) testGlobalSection(pre TestSec1 Key1=Value1 "Key2=Value with spaces") testGlobalSection(pre TestSec3 Key3=Value1 "Key4=Value with spaces" Key5=ValueWithoutSpaces) -testGlobalSection(post ExtensibilityGlobals) +testGlobalSection(post ExtensibilityGlobals "SolutionGuid={00000000-0000-0000-0000-000000000000}") testGlobalSection(post ExtensibilityAddIns) diff --git a/Tests/RunCMake/VSSolution/OnePost-check.cmake b/Tests/RunCMake/VSSolution/OnePost-check.cmake index 6af5156..f7d3712 100644 --- a/Tests/RunCMake/VSSolution/OnePost-check.cmake +++ b/Tests/RunCMake/VSSolution/OnePost-check.cmake @@ -1,4 +1,4 @@ parseGlobalSections(pre post OnePost) testGlobalSection(post TestSec2 Key1=Value1 "Key2=Value with spaces") -testGlobalSection(post ExtensibilityGlobals) +testGlobalSection(post ExtensibilityGlobals "SolutionGuid={00000000-0000-0000-0000-000000000000}") testGlobalSection(post ExtensibilityAddIns) diff --git a/Tests/RunCMake/VSSolution/OnePre-check.cmake b/Tests/RunCMake/VSSolution/OnePre-check.cmake index 70b18b2..c5db139 100644 --- a/Tests/RunCMake/VSSolution/OnePre-check.cmake +++ b/Tests/RunCMake/VSSolution/OnePre-check.cmake @@ -1,4 +1,4 @@ parseGlobalSections(pre post OnePre) testGlobalSection(pre TestSec1 Key1=Value1 "Key2=Value with spaces") -testGlobalSection(post ExtensibilityGlobals) +testGlobalSection(post ExtensibilityGlobals "SolutionGuid={00000000-0000-0000-0000-000000000000}") testGlobalSection(post ExtensibilityAddIns) diff --git a/Tests/RunCMake/VSSolution/Override1-check.cmake b/Tests/RunCMake/VSSolution/Override1-check.cmake index a19e2e1..5905204 100644 --- a/Tests/RunCMake/VSSolution/Override1-check.cmake +++ b/Tests/RunCMake/VSSolution/Override1-check.cmake @@ -1,4 +1,4 @@ parseGlobalSections(pre post Override1) testGlobalSection(post TestSec Key2=Value2 Key3=Value3) -testGlobalSection(post ExtensibilityGlobals Key1=Value1) +testGlobalSection(post ExtensibilityGlobals Key1=Value1 "SolutionGuid={00000000-0000-0000-0000-000000000000}") testGlobalSection(post ExtensibilityAddIns) diff --git a/Tests/RunCMake/VSSolution/Override2-check.cmake b/Tests/RunCMake/VSSolution/Override2-check.cmake index d9656e1..c981ec0 100644 --- a/Tests/RunCMake/VSSolution/Override2-check.cmake +++ b/Tests/RunCMake/VSSolution/Override2-check.cmake @@ -1,4 +1,4 @@ parseGlobalSections(pre post Override2) testGlobalSection(pre TestSec Key2=Value2 Key3=Value3) -testGlobalSection(post ExtensibilityGlobals) +testGlobalSection(post ExtensibilityGlobals "SolutionGuid={00000000-0000-0000-0000-000000000000}") testGlobalSection(post ExtensibilityAddIns Key1=Value1) diff --git a/Tests/RunCMake/VSSolution/Override3-check.cmake b/Tests/RunCMake/VSSolution/Override3-check.cmake new file mode 100644 index 0000000..baee9ed --- /dev/null +++ b/Tests/RunCMake/VSSolution/Override3-check.cmake @@ -0,0 +1,3 @@ +parseGlobalSections(pre post Override3) +testGlobalSection(post ExtensibilityGlobals Key1=Value1 "SolutionGuid={custom-guid}") +testGlobalSection(post ExtensibilityAddIns) diff --git a/Tests/RunCMake/VSSolution/Override3.cmake b/Tests/RunCMake/VSSolution/Override3.cmake new file mode 100644 index 0000000..a59ce19 --- /dev/null +++ b/Tests/RunCMake/VSSolution/Override3.cmake @@ -0,0 +1,4 @@ +set_property(DIRECTORY PROPERTY VS_GLOBAL_SECTION_POST_ExtensibilityGlobals + Key1=Value1 + SolutionGuid={custom-guid} + ) diff --git a/Tests/RunCMake/VSSolution/PrePost-check.cmake b/Tests/RunCMake/VSSolution/PrePost-check.cmake index 322a689..957c964 100644 --- a/Tests/RunCMake/VSSolution/PrePost-check.cmake +++ b/Tests/RunCMake/VSSolution/PrePost-check.cmake @@ -2,5 +2,5 @@ parseGlobalSections(pre post PrePost) testGlobalSection(post Postsec Key1=Value2) testGlobalSection(pre Presec Key1=Value1 "Key2=Value with some spaces") testGlobalSection(post Emptysec) -testGlobalSection(post ExtensibilityGlobals) +testGlobalSection(post ExtensibilityGlobals "SolutionGuid={00000000-0000-0000-0000-000000000000}") testGlobalSection(post ExtensibilityAddIns) diff --git a/Tests/RunCMake/VSSolution/RunCMakeTest.cmake b/Tests/RunCMake/VSSolution/RunCMakeTest.cmake index 3a04db4..c25833d 100644 --- a/Tests/RunCMake/VSSolution/RunCMakeTest.cmake +++ b/Tests/RunCMake/VSSolution/RunCMakeTest.cmake @@ -8,6 +8,7 @@ run_cmake(MorePost) run_cmake(PrePost) run_cmake(Override1) run_cmake(Override2) +run_cmake(Override3) run_cmake(StartupProject) run_cmake(StartupProjectMissing) run_cmake(AddPackageToDefault) diff --git a/Tests/RunCMake/VSSolution/solution_parsing.cmake b/Tests/RunCMake/VSSolution/solution_parsing.cmake index 4e5bb59..4b27550 100644 --- a/Tests/RunCMake/VSSolution/solution_parsing.cmake +++ b/Tests/RunCMake/VSSolution/solution_parsing.cmake @@ -44,6 +44,9 @@ macro(parseGlobalSections arg_out_pre arg_out_post testName) endif() string(STRIP "${CMAKE_MATCH_1}" key) string(STRIP "${CMAKE_MATCH_2}" value) + if(key STREQUAL "SolutionGuid" AND value MATCHES "^{[0-9A-F-]+}$") + set(value "{00000000-0000-0000-0000-000000000000}") + endif() list(APPEND ${out_${sectionType}}_${sectionName} "${key}=${value}") endif() endforeach() diff --git a/Tests/RunCMake/find_package/PackageRoot-stderr.txt b/Tests/RunCMake/find_package/PackageRoot-stderr.txt index 07b27bd..409fa89 100644 --- a/Tests/RunCMake/find_package/PackageRoot-stderr.txt +++ b/Tests/RunCMake/find_package/PackageRoot-stderr.txt @@ -1,7 +1,9 @@ Foo_ROOT : ENV{Foo_ROOT} : FOO_TEST_FILE_FOO :FOO_TEST_FILE_FOO-NOTFOUND +FOO_TEST_FILE_ZOT :FOO_TEST_FILE_ZOT-NOTFOUND FOO_TEST_PATH_FOO :FOO_TEST_PATH_FOO-NOTFOUND +FOO_TEST_PATH_ZOT :FOO_TEST_PATH_ZOT-NOTFOUND FOO_TEST_PROG_FOO :FOO_TEST_PROG_FOO-NOTFOUND Foo_ROOT : @@ -13,15 +15,19 @@ FOO_TEST_PATH_FOO :FOO_TEST_PATH_FOO-NOTFOUND FOO_TEST_PROG_FOO :FOO_TEST_PROG_FOO-NOTFOUND BAR_TEST_FILE_FOO :BAR_TEST_FILE_FOO-NOTFOUND BAR_TEST_FILE_BAR :BAR_TEST_FILE_BAR-NOTFOUND +BAR_TEST_FILE_ZOT :BAR_TEST_FILE_ZOT-NOTFOUND BAR_TEST_PATH_FOO :BAR_TEST_PATH_FOO-NOTFOUND BAR_TEST_PATH_BAR :BAR_TEST_PATH_BAR-NOTFOUND +BAR_TEST_PATH_ZOT :BAR_TEST_PATH_ZOT-NOTFOUND BAR_TEST_PROG_FOO :BAR_TEST_PROG_FOO-NOTFOUND BAR_TEST_PROG_BAR :BAR_TEST_PROG_BAR-NOTFOUND Foo_ROOT :.*/PackageRoot/foo/cmake_root ENV{Foo_ROOT} : FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h +FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include +FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe Foo_ROOT :.*/PackageRoot/foo/cmake_root @@ -33,15 +39,19 @@ FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe BAR_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h BAR_TEST_FILE_BAR :.*/PackageRoot/foo/cmake_root/include/bar.h +BAR_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h BAR_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include BAR_TEST_PATH_BAR :.*/PackageRoot/foo/cmake_root/include +BAR_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot BAR_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe BAR_TEST_PROG_BAR :.*/PackageRoot/foo/cmake_root/bin/bar.exe Foo_ROOT : ENV{Foo_ROOT} :.*/PackageRoot/foo/env_root FOO_TEST_FILE_FOO :.*/PackageRoot/foo/env_root/include/foo.h +FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h FOO_TEST_PATH_FOO :.*/PackageRoot/foo/env_root/include +FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot FOO_TEST_PROG_FOO :.*/PackageRoot/foo/env_root/bin/foo.exe Foo_ROOT : @@ -53,15 +63,19 @@ FOO_TEST_PATH_FOO :.*/PackageRoot/foo/env_root/include FOO_TEST_PROG_FOO :.*/PackageRoot/foo/env_root/bin/foo.exe BAR_TEST_FILE_FOO :.*/PackageRoot/foo/env_root/include/foo.h BAR_TEST_FILE_BAR :.*/PackageRoot/foo/env_root/include/bar.h +BAR_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h BAR_TEST_PATH_FOO :.*/PackageRoot/foo/env_root/include BAR_TEST_PATH_BAR :.*/PackageRoot/foo/env_root/include +BAR_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot BAR_TEST_PROG_FOO :.*/PackageRoot/foo/env_root/bin/foo.exe BAR_TEST_PROG_BAR :.*/PackageRoot/foo/env_root/bin/bar.exe Foo_ROOT :.*/PackageRoot/foo/cmake_root ENV{Foo_ROOT} :.*/PackageRoot/foo/env_root FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h +FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include +FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe Foo_ROOT :.*/PackageRoot/foo/cmake_root @@ -73,15 +87,19 @@ FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe BAR_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h BAR_TEST_FILE_BAR :.*/PackageRoot/foo/cmake_root/include/bar.h +BAR_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h BAR_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include BAR_TEST_PATH_BAR :.*/PackageRoot/foo/cmake_root/include +BAR_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot BAR_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe BAR_TEST_PROG_BAR :.*/PackageRoot/foo/cmake_root/bin/bar.exe Foo_ROOT : ENV{Foo_ROOT} : FOO_TEST_FILE_FOO :FOO_TEST_FILE_FOO-NOTFOUND +FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h FOO_TEST_PATH_FOO :FOO_TEST_PATH_FOO-NOTFOUND +FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot FOO_TEST_PROG_FOO :FOO_TEST_PROG_FOO-NOTFOUND Foo_ROOT : @@ -93,15 +111,19 @@ FOO_TEST_PATH_FOO :FOO_TEST_PATH_FOO-NOTFOUND FOO_TEST_PROG_FOO :FOO_TEST_PROG_FOO-NOTFOUND BAR_TEST_FILE_FOO :BAR_TEST_FILE_FOO-NOTFOUND BAR_TEST_FILE_BAR :.*/PackageRoot/bar/cmake_root/include/bar.h +BAR_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h BAR_TEST_PATH_FOO :BAR_TEST_PATH_FOO-NOTFOUND BAR_TEST_PATH_BAR :.*/PackageRoot/bar/cmake_root/include +BAR_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot BAR_TEST_PROG_FOO :BAR_TEST_PROG_FOO-NOTFOUND BAR_TEST_PROG_BAR :.*/PackageRoot/bar/cmake_root/bin/bar.exe Foo_ROOT : ENV{Foo_ROOT} : FOO_TEST_FILE_FOO :FOO_TEST_FILE_FOO-NOTFOUND +FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h FOO_TEST_PATH_FOO :FOO_TEST_PATH_FOO-NOTFOUND +FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot FOO_TEST_PROG_FOO :FOO_TEST_PROG_FOO-NOTFOUND Foo_ROOT : @@ -113,15 +135,19 @@ FOO_TEST_PATH_FOO :FOO_TEST_PATH_FOO-NOTFOUND FOO_TEST_PROG_FOO :FOO_TEST_PROG_FOO-NOTFOUND BAR_TEST_FILE_FOO :BAR_TEST_FILE_FOO-NOTFOUND BAR_TEST_FILE_BAR :.*/PackageRoot/bar/env_root/include/bar.h +BAR_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h BAR_TEST_PATH_FOO :BAR_TEST_PATH_FOO-NOTFOUND BAR_TEST_PATH_BAR :.*/PackageRoot/bar/env_root/include +BAR_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot BAR_TEST_PROG_FOO :BAR_TEST_PROG_FOO-NOTFOUND BAR_TEST_PROG_BAR :.*/PackageRoot/bar/env_root/bin/bar.exe Foo_ROOT : ENV{Foo_ROOT} : FOO_TEST_FILE_FOO :FOO_TEST_FILE_FOO-NOTFOUND +FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h FOO_TEST_PATH_FOO :FOO_TEST_PATH_FOO-NOTFOUND +FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot FOO_TEST_PROG_FOO :FOO_TEST_PROG_FOO-NOTFOUND Foo_ROOT : @@ -133,15 +159,19 @@ FOO_TEST_PATH_FOO :FOO_TEST_PATH_FOO-NOTFOUND FOO_TEST_PROG_FOO :FOO_TEST_PROG_FOO-NOTFOUND BAR_TEST_FILE_FOO :BAR_TEST_FILE_FOO-NOTFOUND BAR_TEST_FILE_BAR :.*/PackageRoot/bar/cmake_root/include/bar.h +BAR_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h BAR_TEST_PATH_FOO :BAR_TEST_PATH_FOO-NOTFOUND BAR_TEST_PATH_BAR :.*/PackageRoot/bar/cmake_root/include +BAR_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot BAR_TEST_PROG_FOO :BAR_TEST_PROG_FOO-NOTFOUND BAR_TEST_PROG_BAR :.*/PackageRoot/bar/cmake_root/bin/bar.exe Foo_ROOT :.*/PackageRoot/foo/cmake_root ENV{Foo_ROOT} : FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h +FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include +FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe Foo_ROOT :.*/PackageRoot/foo/cmake_root @@ -153,15 +183,19 @@ FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe BAR_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h BAR_TEST_FILE_BAR :.*/PackageRoot/bar/cmake_root/include/bar.h +BAR_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h BAR_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include BAR_TEST_PATH_BAR :.*/PackageRoot/bar/cmake_root/include +BAR_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot BAR_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe BAR_TEST_PROG_BAR :.*/PackageRoot/bar/cmake_root/bin/bar.exe Foo_ROOT : ENV{Foo_ROOT} :.*/PackageRoot/foo/env_root FOO_TEST_FILE_FOO :.*/PackageRoot/foo/env_root/include/foo.h +FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h FOO_TEST_PATH_FOO :.*/PackageRoot/foo/env_root/include +FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot FOO_TEST_PROG_FOO :.*/PackageRoot/foo/env_root/bin/foo.exe Foo_ROOT : @@ -173,15 +207,19 @@ FOO_TEST_PATH_FOO :.*/PackageRoot/foo/env_root/include FOO_TEST_PROG_FOO :.*/PackageRoot/foo/env_root/bin/foo.exe BAR_TEST_FILE_FOO :.*/PackageRoot/foo/env_root/include/foo.h BAR_TEST_FILE_BAR :.*/PackageRoot/bar/cmake_root/include/bar.h +BAR_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h BAR_TEST_PATH_FOO :.*/PackageRoot/foo/env_root/include BAR_TEST_PATH_BAR :.*/PackageRoot/bar/cmake_root/include +BAR_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot BAR_TEST_PROG_FOO :.*/PackageRoot/foo/env_root/bin/foo.exe BAR_TEST_PROG_BAR :.*/PackageRoot/bar/cmake_root/bin/bar.exe Foo_ROOT :.*/PackageRoot/foo/cmake_root ENV{Foo_ROOT} :.*/PackageRoot/foo/env_root FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h +FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include +FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe Foo_ROOT :.*/PackageRoot/foo/cmake_root @@ -193,15 +231,19 @@ FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe BAR_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h BAR_TEST_FILE_BAR :.*/PackageRoot/bar/cmake_root/include/bar.h +BAR_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h BAR_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include BAR_TEST_PATH_BAR :.*/PackageRoot/bar/cmake_root/include +BAR_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot BAR_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe BAR_TEST_PROG_BAR :.*/PackageRoot/bar/cmake_root/bin/bar.exe Foo_ROOT :.*/PackageRoot/foo/cmake_root ENV{Foo_ROOT} : FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h +FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include +FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe Foo_ROOT :.*/PackageRoot/foo/cmake_root @@ -213,15 +255,19 @@ FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe BAR_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h BAR_TEST_FILE_BAR :.*/PackageRoot/bar/env_root/include/bar.h +BAR_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h BAR_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include BAR_TEST_PATH_BAR :.*/PackageRoot/bar/env_root/include +BAR_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot BAR_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe BAR_TEST_PROG_BAR :.*/PackageRoot/bar/env_root/bin/bar.exe Foo_ROOT : ENV{Foo_ROOT} :.*/PackageRoot/foo/env_root FOO_TEST_FILE_FOO :.*/PackageRoot/foo/env_root/include/foo.h +FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h FOO_TEST_PATH_FOO :.*/PackageRoot/foo/env_root/include +FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot FOO_TEST_PROG_FOO :.*/PackageRoot/foo/env_root/bin/foo.exe Foo_ROOT : @@ -233,15 +279,19 @@ FOO_TEST_PATH_FOO :.*/PackageRoot/foo/env_root/include FOO_TEST_PROG_FOO :.*/PackageRoot/foo/env_root/bin/foo.exe BAR_TEST_FILE_FOO :.*/PackageRoot/foo/env_root/include/foo.h BAR_TEST_FILE_BAR :.*/PackageRoot/bar/env_root/include/bar.h +BAR_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h BAR_TEST_PATH_FOO :.*/PackageRoot/foo/env_root/include BAR_TEST_PATH_BAR :.*/PackageRoot/bar/env_root/include +BAR_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot BAR_TEST_PROG_FOO :.*/PackageRoot/foo/env_root/bin/foo.exe BAR_TEST_PROG_BAR :.*/PackageRoot/bar/env_root/bin/bar.exe Foo_ROOT :.*/PackageRoot/foo/cmake_root ENV{Foo_ROOT} :.*/PackageRoot/foo/env_root FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h +FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include +FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe Foo_ROOT :.*/PackageRoot/foo/cmake_root @@ -253,15 +303,19 @@ FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe BAR_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h BAR_TEST_FILE_BAR :.*/PackageRoot/bar/env_root/include/bar.h +BAR_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h BAR_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include BAR_TEST_PATH_BAR :.*/PackageRoot/bar/env_root/include +BAR_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot BAR_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe BAR_TEST_PROG_BAR :.*/PackageRoot/bar/env_root/bin/bar.exe Foo_ROOT :.*/PackageRoot/foo/cmake_root ENV{Foo_ROOT} : FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h +FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include +FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe Foo_ROOT :.*/PackageRoot/foo/cmake_root @@ -273,15 +327,19 @@ FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe BAR_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h BAR_TEST_FILE_BAR :.*/PackageRoot/bar/cmake_root/include/bar.h +BAR_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h BAR_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include BAR_TEST_PATH_BAR :.*/PackageRoot/bar/cmake_root/include +BAR_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot BAR_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe BAR_TEST_PROG_BAR :.*/PackageRoot/bar/cmake_root/bin/bar.exe Foo_ROOT : ENV{Foo_ROOT} :.*/PackageRoot/foo/env_root FOO_TEST_FILE_FOO :.*/PackageRoot/foo/env_root/include/foo.h +FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h FOO_TEST_PATH_FOO :.*/PackageRoot/foo/env_root/include +FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot FOO_TEST_PROG_FOO :.*/PackageRoot/foo/env_root/bin/foo.exe Foo_ROOT : @@ -293,15 +351,19 @@ FOO_TEST_PATH_FOO :.*/PackageRoot/foo/env_root/include FOO_TEST_PROG_FOO :.*/PackageRoot/foo/env_root/bin/foo.exe BAR_TEST_FILE_FOO :.*/PackageRoot/foo/env_root/include/foo.h BAR_TEST_FILE_BAR :.*/PackageRoot/bar/cmake_root/include/bar.h +BAR_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h BAR_TEST_PATH_FOO :.*/PackageRoot/foo/env_root/include BAR_TEST_PATH_BAR :.*/PackageRoot/bar/cmake_root/include +BAR_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot BAR_TEST_PROG_FOO :.*/PackageRoot/foo/env_root/bin/foo.exe BAR_TEST_PROG_BAR :.*/PackageRoot/bar/cmake_root/bin/bar.exe Foo_ROOT :.*/PackageRoot/foo/cmake_root ENV{Foo_ROOT} :.*/PackageRoot/foo/env_root FOO_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h +FOO_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include +FOO_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe Foo_ROOT :.*/PackageRoot/foo/cmake_root @@ -313,7 +375,9 @@ FOO_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include FOO_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe BAR_TEST_FILE_FOO :.*/PackageRoot/foo/cmake_root/include/foo.h BAR_TEST_FILE_BAR :.*/PackageRoot/bar/cmake_root/include/bar.h +BAR_TEST_FILE_ZOT :.*/PackageRoot/foo/cmake_root/include/zot/zot.h BAR_TEST_PATH_FOO :.*/PackageRoot/foo/cmake_root/include BAR_TEST_PATH_BAR :.*/PackageRoot/bar/cmake_root/include +BAR_TEST_PATH_ZOT :.*/PackageRoot/foo/cmake_root/include/zot BAR_TEST_PROG_FOO :.*/PackageRoot/foo/cmake_root/bin/foo.exe BAR_TEST_PROG_BAR :.*/PackageRoot/bar/cmake_root/bin/bar.exe diff --git a/Tests/RunCMake/find_package/PackageRoot.cmake b/Tests/RunCMake/find_package/PackageRoot.cmake index d9f41f8..421c243 100644 --- a/Tests/RunCMake/find_package/PackageRoot.cmake +++ b/Tests/RunCMake/find_package/PackageRoot.cmake @@ -37,7 +37,9 @@ macro(RunPackageRootTest) message("Foo_ROOT :${Foo_ROOT}") message("ENV{Foo_ROOT} :$ENV{Foo_ROOT}") message("FOO_TEST_FILE_FOO :${FOO_TEST_FILE_FOO}") + message("FOO_TEST_FILE_ZOT :${FOO_TEST_FILE_ZOT}") message("FOO_TEST_PATH_FOO :${FOO_TEST_PATH_FOO}") + message("FOO_TEST_PATH_ZOT :${FOO_TEST_PATH_ZOT}") message("FOO_TEST_PROG_FOO :${FOO_TEST_PROG_FOO}") CleanUpPackageRootTest() message("") @@ -57,8 +59,10 @@ macro(RunPackageRootTest) message("FOO_TEST_PROG_FOO :${FOO_TEST_PROG_FOO}") message("BAR_TEST_FILE_FOO :${BAR_TEST_FILE_FOO}") message("BAR_TEST_FILE_BAR :${BAR_TEST_FILE_BAR}") + message("BAR_TEST_FILE_ZOT :${BAR_TEST_FILE_ZOT}") message("BAR_TEST_PATH_FOO :${BAR_TEST_PATH_FOO}") message("BAR_TEST_PATH_BAR :${BAR_TEST_PATH_BAR}") + message("BAR_TEST_PATH_ZOT :${BAR_TEST_PATH_ZOT}") message("BAR_TEST_PROG_FOO :${BAR_TEST_PROG_FOO}") message("BAR_TEST_PROG_BAR :${BAR_TEST_PROG_BAR}") CleanUpPackageRootTest() diff --git a/Tests/RunCMake/find_package/PackageRoot/FindBar.cmake b/Tests/RunCMake/find_package/PackageRoot/FindBar.cmake index eefa49c..72774a7 100644 --- a/Tests/RunCMake/find_package/PackageRoot/FindBar.cmake +++ b/Tests/RunCMake/find_package/PackageRoot/FindBar.cmake @@ -1,6 +1,8 @@ find_file(BAR_TEST_FILE_FOO foo.h) find_file(BAR_TEST_FILE_BAR bar.h) +find_file(BAR_TEST_FILE_ZOT zot.h PATH_SUFFIXES zot) find_path(BAR_TEST_PATH_FOO foo.h) find_path(BAR_TEST_PATH_BAR bar.h) +find_path(BAR_TEST_PATH_ZOT zot.h PATH_SUFFIXES zot) find_program(BAR_TEST_PROG_FOO foo.exe) find_program(BAR_TEST_PROG_BAR bar.exe) diff --git a/Tests/RunCMake/find_package/PackageRoot/FindFoo.cmake b/Tests/RunCMake/find_package/PackageRoot/FindFoo.cmake index cb62390..e160a1d 100644 --- a/Tests/RunCMake/find_package/PackageRoot/FindFoo.cmake +++ b/Tests/RunCMake/find_package/PackageRoot/FindFoo.cmake @@ -1,5 +1,7 @@ find_file(FOO_TEST_FILE_FOO foo.h) +find_file(FOO_TEST_FILE_ZOT zot.h PATH_SUFFIXES zot) find_path(FOO_TEST_PATH_FOO foo.h) +find_path(FOO_TEST_PATH_ZOT zot.h PATH_SUFFIXES zot) find_program(FOO_TEST_PROG_FOO foo.exe) if ("Bar" IN_LIST Foo_FIND_COMPONENTS) diff --git a/Tests/RunCMake/find_package/PackageRoot/bar/cmake_root/include/zot/zot.h b/Tests/RunCMake/find_package/PackageRoot/bar/cmake_root/include/zot/zot.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tests/RunCMake/find_package/PackageRoot/bar/cmake_root/include/zot/zot.h diff --git a/Tests/RunCMake/find_package/PackageRoot/bar/env_root/include/zot/zot.h b/Tests/RunCMake/find_package/PackageRoot/bar/env_root/include/zot/zot.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tests/RunCMake/find_package/PackageRoot/bar/env_root/include/zot/zot.h diff --git a/Tests/RunCMake/find_package/PackageRoot/foo/cmake_root/include/zot/zot.h b/Tests/RunCMake/find_package/PackageRoot/foo/cmake_root/include/zot/zot.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tests/RunCMake/find_package/PackageRoot/foo/cmake_root/include/zot/zot.h diff --git a/Tests/RunCMake/find_package/PackageRoot/foo/env_root/include/zot/zot.h b/Tests/RunCMake/find_package/PackageRoot/foo/env_root/include/zot/zot.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tests/RunCMake/find_package/PackageRoot/foo/env_root/include/zot/zot.h diff --git a/Tests/RunCMake/find_package/RunCMakeTest.cmake b/Tests/RunCMake/find_package/RunCMakeTest.cmake index 72f9c4d..7875db6 100644 --- a/Tests/RunCMake/find_package/RunCMakeTest.cmake +++ b/Tests/RunCMake/find_package/RunCMakeTest.cmake @@ -17,3 +17,5 @@ run_cmake(PackageRoot) run_cmake(PolicyPush) run_cmake(PolicyPop) run_cmake(SetFoundFALSE) +run_cmake(WrongVersion) +run_cmake(WrongVersionConfig) diff --git a/Tests/RunCMake/find_package/SetFoundFALSE-stderr.txt b/Tests/RunCMake/find_package/SetFoundFALSE-stderr.txt new file mode 100644 index 0000000..695f645 --- /dev/null +++ b/Tests/RunCMake/find_package/SetFoundFALSE-stderr.txt @@ -0,0 +1,9 @@ +CMake Warning at SetFoundFALSE.cmake:2 \(find_package\): + Found package configuration file: + + .*/Tests/RunCMake/find_package/SetFoundFALSEConfig.cmake + + but it set SetFoundFALSE_FOUND to FALSE so package "SetFoundFALSE" is + considered to be NOT FOUND. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/find_package/SetFoundFALSE-stdout.txt b/Tests/RunCMake/find_package/SetFoundFALSE-stdout.txt deleted file mode 100644 index 37e6e7e..0000000 --- a/Tests/RunCMake/find_package/SetFoundFALSE-stdout.txt +++ /dev/null @@ -1 +0,0 @@ --- Could NOT find SetFoundFALSE \(missing: SetFoundFALSE_DIR\) diff --git a/Tests/RunCMake/find_package/VersionedA-1/VersionedAConfig.cmake b/Tests/RunCMake/find_package/VersionedA-1/VersionedAConfig.cmake new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tests/RunCMake/find_package/VersionedA-1/VersionedAConfig.cmake diff --git a/Tests/RunCMake/find_package/VersionedA-1/VersionedAConfigVersion.cmake b/Tests/RunCMake/find_package/VersionedA-1/VersionedAConfigVersion.cmake new file mode 100644 index 0000000..2dbcfb2 --- /dev/null +++ b/Tests/RunCMake/find_package/VersionedA-1/VersionedAConfigVersion.cmake @@ -0,0 +1,4 @@ +set(PACKAGE_VERSION 1) +if("${PACKAGE_FIND_VERSION_MAJOR}" EQUAL 1) + set(PACKAGE_VERSION_COMPATIBLE 1) +endif() diff --git a/Tests/RunCMake/find_package/VersionedA-2/VersionedAConfig.cmake b/Tests/RunCMake/find_package/VersionedA-2/VersionedAConfig.cmake new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tests/RunCMake/find_package/VersionedA-2/VersionedAConfig.cmake diff --git a/Tests/RunCMake/find_package/VersionedA-2/VersionedAConfigVersion.cmake b/Tests/RunCMake/find_package/VersionedA-2/VersionedAConfigVersion.cmake new file mode 100644 index 0000000..7eb8332 --- /dev/null +++ b/Tests/RunCMake/find_package/VersionedA-2/VersionedAConfigVersion.cmake @@ -0,0 +1,4 @@ +set(PACKAGE_VERSION 2) +if("${PACKAGE_FIND_VERSION_MAJOR}" EQUAL 2) + set(PACKAGE_VERSION_COMPATIBLE 1) +endif() diff --git a/Tests/RunCMake/find_package/WrongVersion-stderr.txt b/Tests/RunCMake/find_package/WrongVersion-stderr.txt new file mode 100644 index 0000000..ae9fc4a --- /dev/null +++ b/Tests/RunCMake/find_package/WrongVersion-stderr.txt @@ -0,0 +1,11 @@ +^CMake Warning at WrongVersion.cmake:[0-9]+ \(find_package\): + Could not find a configuration file for package "VersionedA" that is + compatible with requested version "3". + + The following configuration files were considered but not accepted: + + .*/Tests/RunCMake/find_package/VersionedA-[12]/VersionedAConfig.cmake, version: [12] + .*/Tests/RunCMake/find_package/VersionedA-[12]/VersionedAConfig.cmake, version: [12] + +Call Stack \(most recent call first\): + CMakeLists.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/find_package/WrongVersion.cmake b/Tests/RunCMake/find_package/WrongVersion.cmake new file mode 100644 index 0000000..5bc711f --- /dev/null +++ b/Tests/RunCMake/find_package/WrongVersion.cmake @@ -0,0 +1,2 @@ +set(CMAKE_PREFIX_PATH ${CMAKE_CURRENT_SOURCE_DIR}) +find_package(VersionedA 3) diff --git a/Tests/RunCMake/find_package/WrongVersionConfig-stderr.txt b/Tests/RunCMake/find_package/WrongVersionConfig-stderr.txt new file mode 100644 index 0000000..1b84233 --- /dev/null +++ b/Tests/RunCMake/find_package/WrongVersionConfig-stderr.txt @@ -0,0 +1,11 @@ +^CMake Warning at WrongVersionConfig.cmake:[0-9]+ \(find_package\): + Could not find a configuration file for package "VersionedA" that is + compatible with requested version "3". + + The following configuration files were considered but not accepted: + + .*/Tests/RunCMake/find_package/VersionedA-[12]/VersionedAConfig.cmake, version: [12] + .*/Tests/RunCMake/find_package/VersionedA-[12]/VersionedAConfig.cmake, version: [12] + +Call Stack \(most recent call first\): + CMakeLists.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/find_package/WrongVersionConfig.cmake b/Tests/RunCMake/find_package/WrongVersionConfig.cmake new file mode 100644 index 0000000..5bc711f --- /dev/null +++ b/Tests/RunCMake/find_package/WrongVersionConfig.cmake @@ -0,0 +1,2 @@ +set(CMAKE_PREFIX_PATH ${CMAKE_CURRENT_SOURCE_DIR}) +find_package(VersionedA 3) 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/RunCMake/target_compile_features/CMakeLists.txt b/Tests/RunCMake/target_compile_features/CMakeLists.txt index 3482e6b..2897109 100644 --- a/Tests/RunCMake/target_compile_features/CMakeLists.txt +++ b/Tests/RunCMake/target_compile_features/CMakeLists.txt @@ -1,3 +1,3 @@ cmake_minimum_required(VERSION 3.0) -project(${RunCMake_TEST} CXX) +project(${RunCMake_TEST} NONE) include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/target_compile_features/RunCMakeTest.cmake b/Tests/RunCMake/target_compile_features/RunCMakeTest.cmake index 33faf2b..1f67f11 100644 --- a/Tests/RunCMake/target_compile_features/RunCMakeTest.cmake +++ b/Tests/RunCMake/target_compile_features/RunCMakeTest.cmake @@ -11,3 +11,4 @@ run_cmake(not_a_cxx_feature) run_cmake(no_matching_cxx_feature) run_cmake(not_a_c_feature) run_cmake(no_matching_c_feature) +run_cmake(cxx_not_enabled) diff --git a/Tests/RunCMake/target_compile_features/alias_target-stderr.txt b/Tests/RunCMake/target_compile_features/alias_target-stderr.txt index 417bf62..5ebe170 100644 --- a/Tests/RunCMake/target_compile_features/alias_target-stderr.txt +++ b/Tests/RunCMake/target_compile_features/alias_target-stderr.txt @@ -1,4 +1,4 @@ -CMake Error at alias_target.cmake:4 \(target_compile_features\): +CMake Error at alias_target.cmake:[0-9]+ \(target_compile_features\): target_compile_features can not be used on an ALIAS target. Call Stack \(most recent call first\): CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/target_compile_features/alias_target.cmake b/Tests/RunCMake/target_compile_features/alias_target.cmake index d35ddba..6fcdada 100644 --- a/Tests/RunCMake/target_compile_features/alias_target.cmake +++ b/Tests/RunCMake/target_compile_features/alias_target.cmake @@ -1,3 +1,4 @@ +enable_language(CXX) add_executable(main empty.cpp) add_executable(Alias::Main ALIAS main) diff --git a/Tests/RunCMake/target_compile_features/cxx_not_enabled-result.txt b/Tests/RunCMake/target_compile_features/cxx_not_enabled-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/target_compile_features/cxx_not_enabled-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/target_compile_features/cxx_not_enabled-stderr.txt b/Tests/RunCMake/target_compile_features/cxx_not_enabled-stderr.txt new file mode 100644 index 0000000..4f707c7 --- /dev/null +++ b/Tests/RunCMake/target_compile_features/cxx_not_enabled-stderr.txt @@ -0,0 +1,4 @@ +^CMake Error at cxx_not_enabled.cmake:[0-9]+ \(target_compile_features\): + target_compile_features cannot use features from non-enabled language CXX +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\)$ diff --git a/Tests/RunCMake/target_compile_features/cxx_not_enabled.cmake b/Tests/RunCMake/target_compile_features/cxx_not_enabled.cmake new file mode 100644 index 0000000..b7e9119 --- /dev/null +++ b/Tests/RunCMake/target_compile_features/cxx_not_enabled.cmake @@ -0,0 +1,2 @@ +add_executable(main empty.c) +target_compile_features(main PRIVATE cxx_decltype) diff --git a/Tests/RunCMake/target_compile_features/imported_target-stderr.txt b/Tests/RunCMake/target_compile_features/imported_target-stderr.txt index c6ff5ec..7a07427 100644 --- a/Tests/RunCMake/target_compile_features/imported_target-stderr.txt +++ b/Tests/RunCMake/target_compile_features/imported_target-stderr.txt @@ -1,4 +1,4 @@ -CMake Error at imported_target.cmake:3 \(target_compile_features\): +CMake Error at imported_target.cmake:[0-9]+ \(target_compile_features\): Cannot specify compile features for imported target "main". Call Stack \(most recent call first\): CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/target_compile_features/imported_target.cmake b/Tests/RunCMake/target_compile_features/imported_target.cmake index e248c2f..e886ce9 100644 --- a/Tests/RunCMake/target_compile_features/imported_target.cmake +++ b/Tests/RunCMake/target_compile_features/imported_target.cmake @@ -1,3 +1,4 @@ +enable_language(CXX) add_library(main INTERFACE IMPORTED) target_compile_features(main INTERFACE cxx_delegating_constructors) diff --git a/Tests/RunCMake/target_compile_features/invalid_args-stderr.txt b/Tests/RunCMake/target_compile_features/invalid_args-stderr.txt index bd5b7b9..9917be7 100644 --- a/Tests/RunCMake/target_compile_features/invalid_args-stderr.txt +++ b/Tests/RunCMake/target_compile_features/invalid_args-stderr.txt @@ -1,4 +1,4 @@ -CMake Error at invalid_args.cmake:3 \(target_compile_features\): +CMake Error at invalid_args.cmake:[0-9]+ \(target_compile_features\): target_compile_features called with invalid arguments Call Stack \(most recent call first\): CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/target_compile_features/invalid_args.cmake b/Tests/RunCMake/target_compile_features/invalid_args.cmake index 1a7fb37..cc051a4 100644 --- a/Tests/RunCMake/target_compile_features/invalid_args.cmake +++ b/Tests/RunCMake/target_compile_features/invalid_args.cmake @@ -1,3 +1,4 @@ +enable_language(CXX) add_executable(main empty.cpp) target_compile_features(main INVALID cxx_delegating_constructors) diff --git a/Tests/RunCMake/target_compile_features/invalid_args_on_interface-stderr.txt b/Tests/RunCMake/target_compile_features/invalid_args_on_interface-stderr.txt index c30209a..3708998 100644 --- a/Tests/RunCMake/target_compile_features/invalid_args_on_interface-stderr.txt +++ b/Tests/RunCMake/target_compile_features/invalid_args_on_interface-stderr.txt @@ -1,4 +1,4 @@ -CMake Error at invalid_args_on_interface.cmake:3 \(target_compile_features\): +CMake Error at invalid_args_on_interface.cmake:[0-9]+ \(target_compile_features\): target_compile_features may only be set INTERFACE properties on INTERFACE targets Call Stack \(most recent call first\): diff --git a/Tests/RunCMake/target_compile_features/invalid_args_on_interface.cmake b/Tests/RunCMake/target_compile_features/invalid_args_on_interface.cmake index 324d0f3..49d2d82 100644 --- a/Tests/RunCMake/target_compile_features/invalid_args_on_interface.cmake +++ b/Tests/RunCMake/target_compile_features/invalid_args_on_interface.cmake @@ -1,3 +1,4 @@ +enable_language(CXX) add_library(main INTERFACE) target_compile_features(main PRIVATE cxx_delegating_constructors) diff --git a/Tests/RunCMake/target_compile_features/no_matching_c_feature-stderr.txt b/Tests/RunCMake/target_compile_features/no_matching_c_feature-stderr.txt index 96b959c..1875d12 100644 --- a/Tests/RunCMake/target_compile_features/no_matching_c_feature-stderr.txt +++ b/Tests/RunCMake/target_compile_features/no_matching_c_feature-stderr.txt @@ -1,4 +1,4 @@ -CMake Error at no_matching_c_feature.cmake:[0-9][0-9]? \((target_compile_features|message)\): +CMake Error at no_matching_c_feature.cmake:[0-9]+ \((target_compile_features|message)\): The compiler feature "gnu_c_dummy" is not known to C compiler "GNU" diff --git a/Tests/RunCMake/target_compile_features/no_matching_c_feature.cmake b/Tests/RunCMake/target_compile_features/no_matching_c_feature.cmake index a44caf2..0e93b41 100644 --- a/Tests/RunCMake/target_compile_features/no_matching_c_feature.cmake +++ b/Tests/RunCMake/target_compile_features/no_matching_c_feature.cmake @@ -1,3 +1,4 @@ +enable_language(CXX) if (NOT ";${CMAKE_C_COMPILE_FEATURES};" MATCHES ";gnu_c_typeof;") # Simulate passing the test. diff --git a/Tests/RunCMake/target_compile_features/no_matching_cxx_feature-stderr.txt b/Tests/RunCMake/target_compile_features/no_matching_cxx_feature-stderr.txt index f976dfe..90d41c9 100644 --- a/Tests/RunCMake/target_compile_features/no_matching_cxx_feature-stderr.txt +++ b/Tests/RunCMake/target_compile_features/no_matching_cxx_feature-stderr.txt @@ -1,4 +1,4 @@ -CMake Error at no_matching_cxx_feature.cmake:[0-9][0-9]? \((target_compile_features|message)\): +CMake Error at no_matching_cxx_feature.cmake:[0-9]+ \((target_compile_features|message)\): The compiler feature "[^"]+" is not known to CXX compiler "[^"]*" diff --git a/Tests/RunCMake/target_compile_features/no_matching_cxx_feature.cmake b/Tests/RunCMake/target_compile_features/no_matching_cxx_feature.cmake index ab1fd76..4ee3445 100644 --- a/Tests/RunCMake/target_compile_features/no_matching_cxx_feature.cmake +++ b/Tests/RunCMake/target_compile_features/no_matching_cxx_feature.cmake @@ -1,3 +1,4 @@ +enable_language(CXX) if (NOT ";${CMAKE_CXX_COMPILE_FEATURES};" MATCHES ";gnu_cxx_typeof;" AND NOT ";${CMAKE_CXX_COMPILE_FEATURES};" MATCHES ";msvc_cxx_sealed;" ) diff --git a/Tests/RunCMake/target_compile_features/no_target-stderr.txt b/Tests/RunCMake/target_compile_features/no_target-stderr.txt index 323ba7a..65974b4 100644 --- a/Tests/RunCMake/target_compile_features/no_target-stderr.txt +++ b/Tests/RunCMake/target_compile_features/no_target-stderr.txt @@ -1,4 +1,4 @@ -CMake Error at no_target.cmake:2 \(target_compile_features\): +CMake Error at no_target.cmake:[0-9]+ \(target_compile_features\): Cannot specify compile features for target "main" which is not built by this project. Call Stack \(most recent call first\): diff --git a/Tests/RunCMake/target_compile_features/no_target.cmake b/Tests/RunCMake/target_compile_features/no_target.cmake index 3f0afe2..a514de8 100644 --- a/Tests/RunCMake/target_compile_features/no_target.cmake +++ b/Tests/RunCMake/target_compile_features/no_target.cmake @@ -1,2 +1,3 @@ +enable_language(CXX) target_compile_features(main INTERFACE cxx_delegating_constructors) diff --git a/Tests/RunCMake/target_compile_features/not_a_c_feature-stderr.txt b/Tests/RunCMake/target_compile_features/not_a_c_feature-stderr.txt index 6dd00f3..493c582 100644 --- a/Tests/RunCMake/target_compile_features/not_a_c_feature-stderr.txt +++ b/Tests/RunCMake/target_compile_features/not_a_c_feature-stderr.txt @@ -1,4 +1,4 @@ -CMake Error at not_a_c_feature.cmake:3 \(target_compile_features\): +CMake Error at not_a_c_feature.cmake:[0-9]+ \(target_compile_features\): target_compile_features specified unknown feature "c_not_a_feature" for target "main". Call Stack \(most recent call first\): diff --git a/Tests/RunCMake/target_compile_features/not_a_c_feature.cmake b/Tests/RunCMake/target_compile_features/not_a_c_feature.cmake index 0420698..f5d70d0 100644 --- a/Tests/RunCMake/target_compile_features/not_a_c_feature.cmake +++ b/Tests/RunCMake/target_compile_features/not_a_c_feature.cmake @@ -1,3 +1,4 @@ +enable_language(C) add_executable(main empty.c) target_compile_features(main diff --git a/Tests/RunCMake/target_compile_features/not_a_cxx_feature-stderr.txt b/Tests/RunCMake/target_compile_features/not_a_cxx_feature-stderr.txt index efa2bad..3dbf0e6 100644 --- a/Tests/RunCMake/target_compile_features/not_a_cxx_feature-stderr.txt +++ b/Tests/RunCMake/target_compile_features/not_a_cxx_feature-stderr.txt @@ -1,4 +1,4 @@ -CMake Error at not_a_cxx_feature.cmake:3 \(target_compile_features\): +CMake Error at not_a_cxx_feature.cmake:[0-9]+ \(target_compile_features\): target_compile_features specified unknown feature "cxx_not_a_feature" for target "main". Call Stack \(most recent call first\): diff --git a/Tests/RunCMake/target_compile_features/not_a_cxx_feature.cmake b/Tests/RunCMake/target_compile_features/not_a_cxx_feature.cmake index 0207b72..bc3a8c4 100644 --- a/Tests/RunCMake/target_compile_features/not_a_cxx_feature.cmake +++ b/Tests/RunCMake/target_compile_features/not_a_cxx_feature.cmake @@ -1,3 +1,4 @@ +enable_language(CXX) add_executable(main empty.cpp) target_compile_features(main diff --git a/Tests/RunCMake/target_compile_features/not_enough_args-stderr.txt b/Tests/RunCMake/target_compile_features/not_enough_args-stderr.txt index 2f8d812..c0c2efa 100644 --- a/Tests/RunCMake/target_compile_features/not_enough_args-stderr.txt +++ b/Tests/RunCMake/target_compile_features/not_enough_args-stderr.txt @@ -1,4 +1,4 @@ -CMake Error at not_enough_args.cmake:3 \(target_compile_features\): +CMake Error at not_enough_args.cmake:[0-9]+ \(target_compile_features\): target_compile_features called with incorrect number of arguments Call Stack \(most recent call first\): CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/target_compile_features/not_enough_args.cmake b/Tests/RunCMake/target_compile_features/not_enough_args.cmake index 9561230..f5b7198 100644 --- a/Tests/RunCMake/target_compile_features/not_enough_args.cmake +++ b/Tests/RunCMake/target_compile_features/not_enough_args.cmake @@ -1,3 +1,4 @@ +enable_language(CXX) add_executable(main empty.cpp) target_compile_features(main) diff --git a/Tests/RunCMake/target_compile_features/utility_target-stderr.txt b/Tests/RunCMake/target_compile_features/utility_target-stderr.txt index d239059..ff03310 100644 --- a/Tests/RunCMake/target_compile_features/utility_target-stderr.txt +++ b/Tests/RunCMake/target_compile_features/utility_target-stderr.txt @@ -1,4 +1,4 @@ -CMake Error at utility_target.cmake:4 \(target_compile_features\): +CMake Error at utility_target.cmake:[0-9]+ \(target_compile_features\): target_compile_features called with non-compilable target type Call Stack \(most recent call first\): CMakeLists.txt:3 \(include\) diff --git a/Tests/VSResource/CMakeLists.txt b/Tests/VSResource/CMakeLists.txt index ee660ed..718e624 100644 --- a/Tests/VSResource/CMakeLists.txt +++ b/Tests/VSResource/CMakeLists.txt @@ -50,5 +50,9 @@ add_library(ResourceLib STATIC lib.cpp lib.rc) add_executable(VSResource main.cpp test.rc) target_link_libraries(VSResource ResourceLib) +if(MSVC AND NOT MSVC_VERSION VERSION_LESS 1600) + set_property(SOURCE test.rc PROPERTY COMPILE_FLAGS /nologo) +endif() + set_property(TARGET VSResource PROPERTY VS_GLOBAL_CMakeTestVsGlobalVariable "test val") 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/Scripts/clang-format.bash b/Utilities/Scripts/clang-format.bash index edcda77..428a9e4 100755 --- a/Utilities/Scripts/clang-format.bash +++ b/Utilities/Scripts/clang-format.bash @@ -92,7 +92,7 @@ fi # Verify that we have a tool. if ! type -p "$clang_format" >/dev/null; then - echo "Unable to locate '$clang_format'" + echo "Unable to locate a 'clang-format' tool." exit 1 fi diff --git a/Utilities/Scripts/update-expat.bash b/Utilities/Scripts/update-expat.bash index 8a2a5fe..4cc8646 100755 --- a/Utilities/Scripts/update-expat.bash +++ b/Utilities/Scripts/update-expat.bash @@ -7,8 +7,8 @@ shopt -s dotglob readonly name="expat" readonly ownership="Expat Upstream <kwrobot@kitware.com>" readonly subtree="Utilities/cmexpat" -readonly repo="http://git.code.sf.net/p/expat/code_git" -readonly tag="master" +readonly repo="https://github.com/libexpat/libexpat.git" +readonly tag="R_2_2_1" readonly shortlog=false readonly paths=" expat/lib/asciitab.h @@ -22,6 +22,7 @@ readonly paths=" expat/lib/utf8tab.h expat/lib/nametab.h expat/lib/ascii.h + expat/lib/siphash.h expat/lib/xmltok_impl.h expat/lib/xmltok_ns.c expat/lib/winconfig.h 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) diff --git a/Utilities/cmexpat/COPYING b/Utilities/cmexpat/COPYING index dcb4506..8d288f0 100644 --- a/Utilities/cmexpat/COPYING +++ b/Utilities/cmexpat/COPYING @@ -1,6 +1,5 @@ -Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd - and Clark Cooper -Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Expat maintainers. +Copyright (c) 1998-2000 Thai Open Source Software Center Ltd and Clark Cooper +Copyright (c) 2001-2017 Expat maintainers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/Utilities/cmexpat/README b/Utilities/cmexpat/README index 9ec8d0c..cd11a22 100644 --- a/Utilities/cmexpat/README +++ b/Utilities/cmexpat/README @@ -1,5 +1,5 @@ - Expat, Release 2.1.1 + Expat, Release 2.2.1 This is Expat, a C library for parsing XML, written by James Clark. Expat is a stream-oriented XML parser. This means that you register @@ -114,7 +114,7 @@ Note for Solaris users: The "ar" command is usually located in "/usr/ccs/bin", which is not in the default PATH. You will need to add this to your path for the "make" command, and probably also switch to GNU make (the "make" found in /usr/ccs/bin does not seem to work -properly -- appearantly it does not understand .PHONY directives). If +properly -- apparently it does not understand .PHONY directives). If you're using ksh or bash, use this command to build: PATH=/usr/ccs/bin:$PATH make diff --git a/Utilities/cmexpat/lib/expat.h b/Utilities/cmexpat/lib/expat.h index 5abcefd..28b0f95 100644 --- a/Utilities/cmexpat/lib/expat.h +++ b/Utilities/cmexpat/lib/expat.h @@ -95,7 +95,9 @@ enum XML_Error { /* Added in 2.0. */ XML_ERROR_RESERVED_PREFIX_XML, XML_ERROR_RESERVED_PREFIX_XMLNS, - XML_ERROR_RESERVED_NAMESPACE_URI + XML_ERROR_RESERVED_NAMESPACE_URI, + /* Added in 2.2.1. */ + XML_ERROR_INVALID_ARGUMENT }; enum XML_Content_Type { @@ -342,7 +344,7 @@ XML_SetEntityDeclHandler(XML_Parser parser, XML_EntityDeclHandler handler); /* OBSOLETE -- OBSOLETE -- OBSOLETE - This handler has been superceded by the EntityDeclHandler above. + This handler has been superseded by the EntityDeclHandler above. It is provided here for backward compatibility. This is called for a declaration of an unparsed (NDATA) entity. @@ -706,6 +708,7 @@ XML_UseParserAsHandlerArg(XML_Parser parser); be called, despite an external subset being parsed. Note: If XML_DTD is not defined when Expat is compiled, returns XML_ERROR_FEATURE_REQUIRES_XML_DTD. + Note: If parser == NULL, returns XML_ERROR_INVALID_ARGUMENT. */ XMLPARSEAPI(enum XML_Error) XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD); @@ -729,15 +732,16 @@ XML_GetBase(XML_Parser parser); to the XML_StartElementHandler that were specified in the start-tag rather than defaulted. Each attribute/value pair counts as 2; thus this correspondds to an index into the atts array passed to the - XML_StartElementHandler. + XML_StartElementHandler. Returns -1 if parser == NULL. */ XMLPARSEAPI(int) XML_GetSpecifiedAttributeCount(XML_Parser parser); /* Returns the index of the ID attribute passed in the last call to - XML_StartElementHandler, or -1 if there is no ID attribute. Each - attribute/value pair counts as 2; thus this correspondds to an - index into the atts array passed to the XML_StartElementHandler. + XML_StartElementHandler, or -1 if there is no ID attribute or + parser == NULL. Each attribute/value pair counts as 2; thus this + correspondds to an index into the atts array passed to the + XML_StartElementHandler. */ XMLPARSEAPI(int) XML_GetIdAttributeIndex(XML_Parser parser); @@ -901,6 +905,7 @@ enum XML_ParamEntityParsing { entities is requested; otherwise it will return non-zero. Note: If XML_SetParamEntityParsing is called after XML_Parse or XML_ParseBuffer, then it has no effect and will always return 0. + Note: If parser == NULL, the function will do nothing and return 0. */ XMLPARSEAPI(int) XML_SetParamEntityParsing(XML_Parser parser, @@ -910,6 +915,7 @@ XML_SetParamEntityParsing(XML_Parser parser, Helps in preventing DoS attacks based on predicting hash function behavior. This must be called before parsing is started. Returns 1 if successful, 0 when called after parsing has started. + Note: If parser == NULL, the function will do nothing and return 0. */ XMLPARSEAPI(int) XML_SetHashSalt(XML_Parser parser, @@ -936,6 +942,10 @@ XML_GetErrorCode(XML_Parser parser); the location is the location of the character at which the error was detected; otherwise the location is the location of the last parse event, as described above. + + Note: XML_GetCurrentLineNumber and XML_GetCurrentColumnNumber + return 0 to indicate an error. + Note: XML_GetCurrentByteIndex returns -1 to indicate an error. */ XMLPARSEAPI(XML_Size) XML_GetCurrentLineNumber(XML_Parser parser); XMLPARSEAPI(XML_Size) XML_GetCurrentColumnNumber(XML_Parser parser); @@ -1034,13 +1044,11 @@ XMLPARSEAPI(const XML_Feature *) XML_GetFeatureList(void); -/* Expat follows the GNU/Linux convention of odd number minor version for - beta/development releases and even number minor version for stable - releases. Micro is bumped with each release, and set to 0 with each - change to major or minor version. +/* Expat follows the semantic versioning convention. + See http://semver.org. */ #define XML_MAJOR_VERSION 2 -#define XML_MINOR_VERSION 1 +#define XML_MINOR_VERSION 2 #define XML_MICRO_VERSION 1 #ifdef __cplusplus diff --git a/Utilities/cmexpat/lib/expat_external.h b/Utilities/cmexpat/lib/expat_external.h index 07a3c5c..d60eecc 100644 --- a/Utilities/cmexpat/lib/expat_external.h +++ b/Utilities/cmexpat/lib/expat_external.h @@ -95,7 +95,10 @@ extern "C" { #endif #ifdef XML_UNICODE_WCHAR_T -#define XML_UNICODE +# define XML_UNICODE +# if defined(__SIZEOF_WCHAR_T__) && (__SIZEOF_WCHAR_T__ != 2) +# error "sizeof(wchar_t) != 2; Need -fshort-wchar for both Expat and libc" +# endif #endif #ifdef XML_UNICODE /* Information is UTF-16 encoded. */ diff --git a/Utilities/cmexpat/lib/siphash.h b/Utilities/cmexpat/lib/siphash.h new file mode 100644 index 0000000..db17458 --- /dev/null +++ b/Utilities/cmexpat/lib/siphash.h @@ -0,0 +1,354 @@ +/* ========================================================================== + * siphash.h - SipHash-2-4 in a single header file + * -------------------------------------------------------------------------- + * Derived by William Ahern from the reference implementation[1] published[2] + * by Jean-Philippe Aumasson and Daniel J. Berstein. Licensed in kind. + * by Jean-Philippe Aumasson and Daniel J. Berstein. + * Minimal changes by Sebastian Pipping on top, details below. + * Licensed under the CC0 Public Domain Dedication license. + * + * 1. https://www.131002.net/siphash/siphash24.c + * 2. https://www.131002.net/siphash/ + * -------------------------------------------------------------------------- + * HISTORY: + * + * 2017-06-10 (Sebastian Pipping) + * - Clarify license note in the header + * - Address C89 issues: + * - Stop using inline keyword (and let compiler decide) + * - Turn integer suffix ULL to UL + * - Replace _Bool by int + * - Turn macro siphash24 into a function + * - Address invalid conversion (void pointer) by explicit cast + * - Always expose sip24_valid (for self-tests) + * + * 2012-11-04 - Born. (William Ahern) + * -------------------------------------------------------------------------- + * USAGE: + * + * SipHash-2-4 takes as input two 64-bit words as the key, some number of + * message bytes, and outputs a 64-bit word as the message digest. This + * implementation employs two data structures: a struct sipkey for + * representing the key, and a struct siphash for representing the hash + * state. + * + * For converting a 16-byte unsigned char array to a key, use either the + * macro sip_keyof or the routine sip_tokey. The former instantiates a + * compound literal key, while the latter requires a key object as a + * parameter. + * + * unsigned char secret[16]; + * arc4random_buf(secret, sizeof secret); + * struct sipkey *key = sip_keyof(secret); + * + * For hashing a message, use either the convenience macro siphash24 or the + * routines sip24_init, sip24_update, and sip24_final. + * + * struct siphash state; + * void *msg; + * size_t len; + * uint64_t hash; + * + * sip24_init(&state, key); + * sip24_update(&state, msg, len); + * hash = sip24_final(&state); + * + * or + * + * hash = siphash24(msg, len, key); + * + * To convert the 64-bit hash value to a canonical 8-byte little-endian + * binary representation, use either the macro sip_binof or the routine + * sip_tobin. The former instantiates and returns a compound literal array, + * while the latter requires an array object as a parameter. + * -------------------------------------------------------------------------- + * NOTES: + * + * o Neither sip_keyof, sip_binof, nor siphash24 will work with compilers + * lacking compound literal support. Instead, you must use the lower-level + * interfaces which take as parameters the temporary state objects. + * + * o Uppercase macros may evaluate parameters more than once. Lowercase + * macros should not exhibit any such side effects. + * ========================================================================== + */ +#ifndef SIPHASH_H +#define SIPHASH_H + +#include <stddef.h> /* size_t */ + +#include <cm_kwiml.h> + +#ifndef KWIML_INT_HAVE_UINT64_T +# define uint64_t KWIML_INT_uint64_t +#endif +#ifndef KWIML_INT_HAVE_UINT32_T +# define uint32_t KWIML_INT_uint32_t +#endif +#ifndef KWIML_INT_HAVE_UINT8_T +# define uint8_t KWIML_INT_uint8_t +#endif + +#define SIP_ROTL(x, b) (uint64_t)(((x) << (b)) | ( (x) >> (64 - (b)))) + +#define SIP_U32TO8_LE(p, v) \ + (p)[0] = (uint8_t)((v) >> 0); (p)[1] = (uint8_t)((v) >> 8); \ + (p)[2] = (uint8_t)((v) >> 16); (p)[3] = (uint8_t)((v) >> 24); + +#define SIP_U64TO8_LE(p, v) \ + SIP_U32TO8_LE((p) + 0, (uint32_t)((v) >> 0)); \ + SIP_U32TO8_LE((p) + 4, (uint32_t)((v) >> 32)); + +#define SIP_U8TO64_LE(p) \ + (((uint64_t)((p)[0]) << 0) | \ + ((uint64_t)((p)[1]) << 8) | \ + ((uint64_t)((p)[2]) << 16) | \ + ((uint64_t)((p)[3]) << 24) | \ + ((uint64_t)((p)[4]) << 32) | \ + ((uint64_t)((p)[5]) << 40) | \ + ((uint64_t)((p)[6]) << 48) | \ + ((uint64_t)((p)[7]) << 56)) + + +#define SIPHASH_INITIALIZER { 0, 0, 0, 0, { 0 }, 0, 0 } + +struct siphash { + uint64_t v0, v1, v2, v3; + + unsigned char buf[8], *p; + uint64_t c; +}; /* struct siphash */ + + +#define SIP_KEYLEN 16 + +struct sipkey { + uint64_t k[2]; +}; /* struct sipkey */ + +#define sip_keyof(k) sip_tokey(&(struct sipkey){ { 0 } }, (k)) + +static struct sipkey *sip_tokey(struct sipkey *key, const void *src) { + key->k[0] = SIP_U8TO64_LE((const unsigned char *)src); + key->k[1] = SIP_U8TO64_LE((const unsigned char *)src + 8); + return key; +} /* sip_tokey() */ + + +#define sip_binof(v) sip_tobin((unsigned char[8]){ 0 }, (v)) + +static void *sip_tobin(void *dst, uint64_t u64) { + SIP_U64TO8_LE((unsigned char *)dst, u64); + return dst; +} /* sip_tobin() */ + + +static void sip_round(struct siphash *H, const int rounds) { + int i; + + for (i = 0; i < rounds; i++) { + H->v0 += H->v1; + H->v1 = SIP_ROTL(H->v1, 13); + H->v1 ^= H->v0; + H->v0 = SIP_ROTL(H->v0, 32); + + H->v2 += H->v3; + H->v3 = SIP_ROTL(H->v3, 16); + H->v3 ^= H->v2; + + H->v0 += H->v3; + H->v3 = SIP_ROTL(H->v3, 21); + H->v3 ^= H->v0; + + H->v2 += H->v1; + H->v1 = SIP_ROTL(H->v1, 17); + H->v1 ^= H->v2; + H->v2 = SIP_ROTL(H->v2, 32); + } +} /* sip_round() */ + + +static struct siphash *sip24_init(struct siphash *H, const struct sipkey *key) { + H->v0 = 0x736f6d6570736575UL ^ key->k[0]; + H->v1 = 0x646f72616e646f6dUL ^ key->k[1]; + H->v2 = 0x6c7967656e657261UL ^ key->k[0]; + H->v3 = 0x7465646279746573UL ^ key->k[1]; + + H->p = H->buf; + H->c = 0; + + return H; +} /* sip24_init() */ + + +#define sip_endof(a) (&(a)[sizeof (a) / sizeof *(a)]) + +static struct siphash *sip24_update(struct siphash *H, const void *src, size_t len) { + const unsigned char *p = (const unsigned char *)src, *pe = p + len; + uint64_t m; + + do { + while (p < pe && H->p < sip_endof(H->buf)) + *H->p++ = *p++; + + if (H->p < sip_endof(H->buf)) + break; + + m = SIP_U8TO64_LE(H->buf); + H->v3 ^= m; + sip_round(H, 2); + H->v0 ^= m; + + H->p = H->buf; + H->c += 8; + } while (p < pe); + + return H; +} /* sip24_update() */ + + +static uint64_t sip24_final(struct siphash *H) { + char left = H->p - H->buf; + uint64_t b = (H->c + left) << 56; + + switch (left) { + case 7: b |= (uint64_t)H->buf[6] << 48; + case 6: b |= (uint64_t)H->buf[5] << 40; + case 5: b |= (uint64_t)H->buf[4] << 32; + case 4: b |= (uint64_t)H->buf[3] << 24; + case 3: b |= (uint64_t)H->buf[2] << 16; + case 2: b |= (uint64_t)H->buf[1] << 8; + case 1: b |= (uint64_t)H->buf[0] << 0; + case 0: break; + } + + H->v3 ^= b; + sip_round(H, 2); + H->v0 ^= b; + H->v2 ^= 0xff; + sip_round(H, 4); + + return H->v0 ^ H->v1 ^ H->v2 ^ H->v3; +} /* sip24_final() */ + + +static uint64_t siphash24(const void *src, size_t len, const struct sipkey *key) { + struct siphash state = SIPHASH_INITIALIZER; + return sip24_final(sip24_update(sip24_init(&state, key), src, len)); +} /* siphash24() */ + + +/* + * SipHash-2-4 output with + * k = 00 01 02 ... + * and + * in = (empty string) + * in = 00 (1 byte) + * in = 00 01 (2 bytes) + * in = 00 01 02 (3 bytes) + * ... + * in = 00 01 02 ... 3e (63 bytes) + */ +static int sip24_valid(void) { + static const unsigned char vectors[64][8] = { + { 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, }, + { 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, }, + { 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, }, + { 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85, }, + { 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf, }, + { 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18, }, + { 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb, }, + { 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab, }, + { 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93, }, + { 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e, }, + { 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a, }, + { 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4, }, + { 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75, }, + { 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14, }, + { 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7, }, + { 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1, }, + { 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f, }, + { 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69, }, + { 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b, }, + { 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb, }, + { 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe, }, + { 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0, }, + { 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93, }, + { 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8, }, + { 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8, }, + { 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc, }, + { 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17, }, + { 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f, }, + { 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde, }, + { 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6, }, + { 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad, }, + { 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32, }, + { 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71, }, + { 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7, }, + { 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12, }, + { 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15, }, + { 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31, }, + { 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02, }, + { 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca, }, + { 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a, }, + { 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e, }, + { 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad, }, + { 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18, }, + { 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4, }, + { 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9, }, + { 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9, }, + { 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb, }, + { 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0, }, + { 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6, }, + { 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7, }, + { 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee, }, + { 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1, }, + { 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a, }, + { 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81, }, + { 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f, }, + { 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24, }, + { 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7, }, + { 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea, }, + { 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60, }, + { 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66, }, + { 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c, }, + { 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f, }, + { 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5, }, + { 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, } + }; + unsigned char in[64]; + struct sipkey k; + size_t i; + + sip_tokey(&k, "\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017"); + + for (i = 0; i < sizeof in; ++i) { + in[i] = i; + + if (siphash24(in, i, &k) != SIP_U8TO64_LE(vectors[i])) + return 0; + } + + return 1; +} /* sip24_valid() */ + + +#if SIPHASH_MAIN + +#include <stdio.h> + +int main(void) { + int ok = sip24_valid(); + + if (ok) + puts("OK"); + else + puts("FAIL"); + + return !ok; +} /* main() */ + +#endif /* SIPHASH_MAIN */ + + +#endif /* SIPHASH_H */ diff --git a/Utilities/cmexpat/lib/winconfig.h b/Utilities/cmexpat/lib/winconfig.h index d7dad38..c9dbfea 100644 --- a/Utilities/cmexpat/lib/winconfig.h +++ b/Utilities/cmexpat/lib/winconfig.h @@ -17,7 +17,24 @@ #include <memory.h> #include <string.h> -#include "expat_config.h" + +#if defined(HAVE_EXPAT_CONFIG_H) /* e.g. MinGW */ +# include <expat_config.h> +#else /* !defined(HAVE_EXPAT_CONFIG_H) */ + + +#define XML_NS 1 +#define XML_DTD 1 +#define XML_CONTEXT_BYTES 1024 + +/* we will assume all Windows platforms are little endian */ +#define BYTEORDER 1234 + +/* Windows has memmove() available. */ +#define HAVE_MEMMOVE + + +#endif /* !defined(HAVE_EXPAT_CONFIG_H) */ #if defined(_MSC_VER) # pragma warning(push,1) diff --git a/Utilities/cmexpat/lib/xmlparse.c b/Utilities/cmexpat/lib/xmlparse.c index b56b66a..76f078e 100644 --- a/Utilities/cmexpat/lib/xmlparse.c +++ b/Utilities/cmexpat/lib/xmlparse.c @@ -1,13 +1,19 @@ /* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd See the file COPYING for copying permission. + + 77fea421d361dca90041d0040ecf1dca651167fadf2af79e990e35168d70d933 (2.2.1+) */ +#define _GNU_SOURCE /* syscall prototype */ + #include <stddef.h> #include <string.h> /* memset(), memcpy() */ #include <assert.h> #include <limits.h> /* UINT_MAX */ +#include <stdio.h> /* fprintf */ +#include <stdlib.h> /* getenv */ -#ifdef COMPILING_FOR_WINDOWS +#ifdef _WIN32 #define getpid GetCurrentProcessId #else #include <sys/time.h> /* gettimeofday() */ @@ -17,20 +23,15 @@ #define XML_BUILDING_EXPAT 1 -#ifdef COMPILING_FOR_WINDOWS +#ifdef _WIN32 #include "winconfig.h" -#elif defined(MACOS_CLASSIC) -#include "macconfig.h" -#elif defined(__amigaos__) -#include "amigaconfig.h" -#elif defined(__WATCOMC__) -#include "watcomconfig.h" #elif defined(HAVE_EXPAT_CONFIG_H) #include <expat_config.h> -#endif /* ndef COMPILING_FOR_WINDOWS */ +#endif /* ndef _WIN32 */ #include "ascii.h" #include "expat.h" +#include "siphash.h" #ifdef XML_UNICODE #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX @@ -109,17 +110,11 @@ typedef struct { const XML_Memory_Handling_Suite *mem; } HASH_TABLE; -/* Basic character hash algorithm, taken from Python's string hash: - h = h * 1000003 ^ character, the constant being a prime number. +static size_t +keylen(KEY s); -*/ -#ifdef XML_UNICODE -#define CHAR_HASH(h, c) \ - (((h) * 0xF4243) ^ (unsigned short)(c)) -#else -#define CHAR_HASH(h, c) \ - (((h) * 0xF4243) ^ (unsigned char)(c)) -#endif +static void +copy_salt_to_sipkey(XML_Parser parser, struct sipkey * key); /* For probing (after a collision) we need a step size relative prime to the hash table size, which is a power of 2. We use double-hashing, @@ -355,6 +350,8 @@ doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr, const char *end, const char **nextPtr, XML_Bool haveMore); #endif /* XML_DTD */ +static void +freeBindings(XML_Parser parser, BINDING *bindings); static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *, const char *s, TAG_NAME *tagNamePtr, BINDING **bindingsPtr); @@ -697,10 +694,84 @@ static const XML_Char implicitContext[] = { ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\0' }; + +#if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) +# include <errno.h> + +# if defined(HAVE_GETRANDOM) +# include <sys/random.h> /* getrandom */ +# else +# include <unistd.h> /* syscall */ +# include <sys/syscall.h> /* SYS_getrandom */ +# endif + +/* Obtain entropy on Linux 3.17+ */ +static int +writeRandomBytes_getrandom(void * target, size_t count) { + int success = 0; /* full count bytes written? */ + size_t bytesWrittenTotal = 0; + const unsigned int getrandomFlags = 0; + + do { + void * const currentTarget = (void*)((char*)target + bytesWrittenTotal); + const size_t bytesToWrite = count - bytesWrittenTotal; + + const int bytesWrittenMore = +#if defined(HAVE_GETRANDOM) + getrandom(currentTarget, bytesToWrite, getrandomFlags); +#else + syscall(SYS_getrandom, currentTarget, bytesToWrite, getrandomFlags); +#endif + + if (bytesWrittenMore > 0) { + bytesWrittenTotal += bytesWrittenMore; + if (bytesWrittenTotal >= count) + success = 1; + } + } while (! success && (errno == EINTR || errno == EAGAIN)); + + return success; +} + +#endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */ + + +#ifdef _WIN32 + +typedef BOOLEAN (APIENTRY *RTLGENRANDOM_FUNC)(PVOID, ULONG); + +/* Obtain entropy on Windows XP / Windows Server 2003 and later. + * Hint on RtlGenRandom and the following article from libsodioum. + * + * Michael Howard: Cryptographically Secure Random number on Windows without using CryptoAPI + * https://blogs.msdn.microsoft.com/michael_howard/2005/01/14/cryptographically-secure-random-number-on-windows-without-using-cryptoapi/ + */ +static int +writeRandomBytes_RtlGenRandom(void * target, size_t count) { + int success = 0; /* full count bytes written? */ + const HMODULE advapi32 = LoadLibrary("ADVAPI32.DLL"); + + if (advapi32) { + const RTLGENRANDOM_FUNC RtlGenRandom + = (RTLGENRANDOM_FUNC)GetProcAddress(advapi32, "SystemFunction036"); + if (RtlGenRandom) { + if (RtlGenRandom((PVOID)target, (ULONG)count) == TRUE) { + success = 1; + } + } + FreeLibrary(advapi32); + } + + return success; +} + +#endif /* _WIN32 */ + + static unsigned long gather_time_entropy(void) { -#ifdef COMPILING_FOR_WINDOWS +#ifdef _WIN32 FILETIME ft; GetSystemTimeAsFileTime(&ft); /* never fails */ return ft.dwHighDateTime ^ ft.dwLowDateTime; @@ -716,20 +787,62 @@ gather_time_entropy(void) #endif } +#if defined(HAVE_ARC4RANDOM_BUF) && defined(HAVE_LIBBSD) +# include <bsd/stdlib.h> +#endif + +static unsigned long +ENTROPY_DEBUG(const char * label, unsigned long entropy) { + const char * const EXPAT_ENTROPY_DEBUG = getenv("EXPAT_ENTROPY_DEBUG"); + if (EXPAT_ENTROPY_DEBUG && ! strcmp(EXPAT_ENTROPY_DEBUG, "1")) { + fprintf(stderr, "Entropy: %s --> 0x%0*lx (%lu bytes)\n", + label, + (int)sizeof(entropy) * 2, entropy, + (unsigned long)sizeof(entropy)); + } + return entropy; +} + static unsigned long generate_hash_secret_salt(XML_Parser parser) { - /* Process ID is 0 bits entropy if attacker has local access - * XML_Parser address is few bits of entropy if attacker has local access */ - const unsigned long entropy = - gather_time_entropy() ^ getpid() ^ (unsigned long)parser; + unsigned long entropy; + (void)parser; +#if defined(HAVE_ARC4RANDOM_BUF) || defined(__CloudABI__) + (void)gather_time_entropy; + arc4random_buf(&entropy, sizeof(entropy)); + return ENTROPY_DEBUG("arc4random_buf", entropy); +#else + /* Try high quality providers first .. */ +#ifdef _WIN32 + if (writeRandomBytes_RtlGenRandom((void *)&entropy, sizeof(entropy))) { + return ENTROPY_DEBUG("RtlGenRandom", entropy); + } +#elif defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) + if (writeRandomBytes_getrandom((void *)&entropy, sizeof(entropy))) { + return ENTROPY_DEBUG("getrandom", entropy); + } +#endif + /* .. and self-made low quality for backup: */ + + /* Process ID is 0 bits entropy if attacker has local access */ + entropy = gather_time_entropy() ^ getpid(); /* Factors are 2^31-1 and 2^61-1 (Mersenne primes M31 and M61) */ if (sizeof(unsigned long) == 4) { - return entropy * 2147483647; + return ENTROPY_DEBUG("fallback(4)", entropy * 2147483647); } else { - return entropy * 2305843009213693951; + return ENTROPY_DEBUG("fallback(8)", + entropy * (unsigned long)2305843009213693951); } +#endif +} + +static unsigned long +get_hash_secret_salt(XML_Parser parser) { + if (parser->m_parentParser != NULL) + return get_hash_secret_salt(parser->m_parentParser); + return parser->m_hash_secret_salt; } static XML_Bool /* only valid for root parser */ @@ -960,6 +1073,10 @@ XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) { TAG *tStk; OPEN_INTERNAL_ENTITY *openEntityList; + + if (parser == NULL) + return XML_FALSE; + if (parentParser) return XML_FALSE; /* move tagStack to freeTagList */ @@ -994,6 +1111,8 @@ XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) enum XML_Status XMLCALL XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName) { + if (parser == NULL) + return XML_STATUS_ERROR; /* Block after XML_Parse()/XML_ParseBuffer() has been called. XXX There's no way for the caller to determine which of the XXX possible error cases caused the XML_STATUS_ERROR return. @@ -1017,52 +1136,88 @@ XML_ExternalEntityParserCreate(XML_Parser oldParser, { XML_Parser parser = oldParser; DTD *newDtd = NULL; - DTD *oldDtd = _dtd; - XML_StartElementHandler oldStartElementHandler = startElementHandler; - XML_EndElementHandler oldEndElementHandler = endElementHandler; - XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler; - XML_ProcessingInstructionHandler oldProcessingInstructionHandler - = processingInstructionHandler; - XML_CommentHandler oldCommentHandler = commentHandler; - XML_StartCdataSectionHandler oldStartCdataSectionHandler - = startCdataSectionHandler; - XML_EndCdataSectionHandler oldEndCdataSectionHandler - = endCdataSectionHandler; - XML_DefaultHandler oldDefaultHandler = defaultHandler; - XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler - = unparsedEntityDeclHandler; - XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler; - XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler - = startNamespaceDeclHandler; - XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler - = endNamespaceDeclHandler; - XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler; - XML_ExternalEntityRefHandler oldExternalEntityRefHandler - = externalEntityRefHandler; - XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler; - XML_UnknownEncodingHandler oldUnknownEncodingHandler - = unknownEncodingHandler; - XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler; - XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler; - XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler; - XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler; - ELEMENT_TYPE * oldDeclElementType = declElementType; - - void *oldUserData = userData; - void *oldHandlerArg = handlerArg; - XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities; - XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg; + DTD *oldDtd; + XML_StartElementHandler oldStartElementHandler; + XML_EndElementHandler oldEndElementHandler; + XML_CharacterDataHandler oldCharacterDataHandler; + XML_ProcessingInstructionHandler oldProcessingInstructionHandler; + XML_CommentHandler oldCommentHandler; + XML_StartCdataSectionHandler oldStartCdataSectionHandler; + XML_EndCdataSectionHandler oldEndCdataSectionHandler; + XML_DefaultHandler oldDefaultHandler; + XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler; + XML_NotationDeclHandler oldNotationDeclHandler; + XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler; + XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler; + XML_NotStandaloneHandler oldNotStandaloneHandler; + XML_ExternalEntityRefHandler oldExternalEntityRefHandler; + XML_SkippedEntityHandler oldSkippedEntityHandler; + XML_UnknownEncodingHandler oldUnknownEncodingHandler; + XML_ElementDeclHandler oldElementDeclHandler; + XML_AttlistDeclHandler oldAttlistDeclHandler; + XML_EntityDeclHandler oldEntityDeclHandler; + XML_XmlDeclHandler oldXmlDeclHandler; + ELEMENT_TYPE * oldDeclElementType; + + void *oldUserData; + void *oldHandlerArg; + XML_Bool oldDefaultExpandInternalEntities; + XML_Parser oldExternalEntityRefHandlerArg; #ifdef XML_DTD - enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing; - int oldInEntityValue = prologState.inEntityValue; + enum XML_ParamEntityParsing oldParamEntityParsing; + int oldInEntityValue; #endif - XML_Bool oldns_triplets = ns_triplets; + XML_Bool oldns_triplets; /* Note that the new parser shares the same hash secret as the old parser, so that dtdCopy and copyEntityTable can lookup values from hash tables associated with either parser without us having to worry which hash secrets each table has. */ - unsigned long oldhash_secret_salt = hash_secret_salt; + unsigned long oldhash_secret_salt; + + /* Validate the oldParser parameter before we pull everything out of it */ + if (oldParser == NULL) + return NULL; + + /* Stash the original parser contents on the stack */ + oldDtd = _dtd; + oldStartElementHandler = startElementHandler; + oldEndElementHandler = endElementHandler; + oldCharacterDataHandler = characterDataHandler; + oldProcessingInstructionHandler = processingInstructionHandler; + oldCommentHandler = commentHandler; + oldStartCdataSectionHandler = startCdataSectionHandler; + oldEndCdataSectionHandler = endCdataSectionHandler; + oldDefaultHandler = defaultHandler; + oldUnparsedEntityDeclHandler = unparsedEntityDeclHandler; + oldNotationDeclHandler = notationDeclHandler; + oldStartNamespaceDeclHandler = startNamespaceDeclHandler; + oldEndNamespaceDeclHandler = endNamespaceDeclHandler; + oldNotStandaloneHandler = notStandaloneHandler; + oldExternalEntityRefHandler = externalEntityRefHandler; + oldSkippedEntityHandler = skippedEntityHandler; + oldUnknownEncodingHandler = unknownEncodingHandler; + oldElementDeclHandler = elementDeclHandler; + oldAttlistDeclHandler = attlistDeclHandler; + oldEntityDeclHandler = entityDeclHandler; + oldXmlDeclHandler = xmlDeclHandler; + oldDeclElementType = declElementType; + + oldUserData = userData; + oldHandlerArg = handlerArg; + oldDefaultExpandInternalEntities = defaultExpandInternalEntities; + oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg; +#ifdef XML_DTD + oldParamEntityParsing = paramEntityParsing; + oldInEntityValue = prologState.inEntityValue; +#endif + oldns_triplets = ns_triplets; + /* Note that the new parser shares the same hash secret as the old + parser, so that dtdCopy and copyEntityTable can lookup values + from hash tables associated with either parser without us having + to worry which hash secrets each table has. + */ + oldhash_secret_salt = hash_secret_salt; #ifdef XML_DTD if (!context) @@ -1228,12 +1383,15 @@ XML_ParserFree(XML_Parser parser) void XMLCALL XML_UseParserAsHandlerArg(XML_Parser parser) { - handlerArg = parser; + if (parser != NULL) + handlerArg = parser; } enum XML_Error XMLCALL XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD) { + if (parser == NULL) + return XML_ERROR_INVALID_ARGUMENT; #ifdef XML_DTD /* block after XML_Parse()/XML_ParseBuffer() has been called */ if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED) @@ -1248,6 +1406,8 @@ XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD) void XMLCALL XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) { + if (parser == NULL) + return; /* block after XML_Parse()/XML_ParseBuffer() has been called */ if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED) return; @@ -1257,6 +1417,8 @@ XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) void XMLCALL XML_SetUserData(XML_Parser parser, void *p) { + if (parser == NULL) + return; if (handlerArg == userData) handlerArg = userData = p; else @@ -1266,6 +1428,8 @@ XML_SetUserData(XML_Parser parser, void *p) enum XML_Status XMLCALL XML_SetBase(XML_Parser parser, const XML_Char *p) { + if (parser == NULL) + return XML_STATUS_ERROR; if (p) { p = poolCopyString(&_dtd->pool, p); if (!p) @@ -1280,18 +1444,24 @@ XML_SetBase(XML_Parser parser, const XML_Char *p) const XML_Char * XMLCALL XML_GetBase(XML_Parser parser) { + if (parser == NULL) + return NULL; return curBase; } int XMLCALL XML_GetSpecifiedAttributeCount(XML_Parser parser) { + if (parser == NULL) + return -1; return nSpecifiedAtts; } int XMLCALL XML_GetIdAttributeIndex(XML_Parser parser) { + if (parser == NULL) + return -1; return idAttIndex; } @@ -1299,6 +1469,8 @@ XML_GetIdAttributeIndex(XML_Parser parser) const XML_AttrInfo * XMLCALL XML_GetAttributeInfo(XML_Parser parser) { + if (parser == NULL) + return NULL; return attInfo; } #endif @@ -1308,6 +1480,8 @@ XML_SetElementHandler(XML_Parser parser, XML_StartElementHandler start, XML_EndElementHandler end) { + if (parser == NULL) + return; startElementHandler = start; endElementHandler = end; } @@ -1315,34 +1489,39 @@ XML_SetElementHandler(XML_Parser parser, void XMLCALL XML_SetStartElementHandler(XML_Parser parser, XML_StartElementHandler start) { - startElementHandler = start; + if (parser != NULL) + startElementHandler = start; } void XMLCALL XML_SetEndElementHandler(XML_Parser parser, XML_EndElementHandler end) { - endElementHandler = end; + if (parser != NULL) + endElementHandler = end; } void XMLCALL XML_SetCharacterDataHandler(XML_Parser parser, XML_CharacterDataHandler handler) { - characterDataHandler = handler; + if (parser != NULL) + characterDataHandler = handler; } void XMLCALL XML_SetProcessingInstructionHandler(XML_Parser parser, XML_ProcessingInstructionHandler handler) { - processingInstructionHandler = handler; + if (parser != NULL) + processingInstructionHandler = handler; } void XMLCALL XML_SetCommentHandler(XML_Parser parser, XML_CommentHandler handler) { - commentHandler = handler; + if (parser != NULL) + commentHandler = handler; } void XMLCALL @@ -1350,6 +1529,8 @@ XML_SetCdataSectionHandler(XML_Parser parser, XML_StartCdataSectionHandler start, XML_EndCdataSectionHandler end) { + if (parser == NULL) + return; startCdataSectionHandler = start; endCdataSectionHandler = end; } @@ -1357,19 +1538,23 @@ XML_SetCdataSectionHandler(XML_Parser parser, void XMLCALL XML_SetStartCdataSectionHandler(XML_Parser parser, XML_StartCdataSectionHandler start) { - startCdataSectionHandler = start; + if (parser != NULL) + startCdataSectionHandler = start; } void XMLCALL XML_SetEndCdataSectionHandler(XML_Parser parser, XML_EndCdataSectionHandler end) { - endCdataSectionHandler = end; + if (parser != NULL) + endCdataSectionHandler = end; } void XMLCALL XML_SetDefaultHandler(XML_Parser parser, XML_DefaultHandler handler) { + if (parser == NULL) + return; defaultHandler = handler; defaultExpandInternalEntities = XML_FALSE; } @@ -1378,6 +1563,8 @@ void XMLCALL XML_SetDefaultHandlerExpand(XML_Parser parser, XML_DefaultHandler handler) { + if (parser == NULL) + return; defaultHandler = handler; defaultExpandInternalEntities = XML_TRUE; } @@ -1387,6 +1574,8 @@ XML_SetDoctypeDeclHandler(XML_Parser parser, XML_StartDoctypeDeclHandler start, XML_EndDoctypeDeclHandler end) { + if (parser == NULL) + return; startDoctypeDeclHandler = start; endDoctypeDeclHandler = end; } @@ -1394,27 +1583,31 @@ XML_SetDoctypeDeclHandler(XML_Parser parser, void XMLCALL XML_SetStartDoctypeDeclHandler(XML_Parser parser, XML_StartDoctypeDeclHandler start) { - startDoctypeDeclHandler = start; + if (parser != NULL) + startDoctypeDeclHandler = start; } void XMLCALL XML_SetEndDoctypeDeclHandler(XML_Parser parser, XML_EndDoctypeDeclHandler end) { - endDoctypeDeclHandler = end; + if (parser != NULL) + endDoctypeDeclHandler = end; } void XMLCALL XML_SetUnparsedEntityDeclHandler(XML_Parser parser, XML_UnparsedEntityDeclHandler handler) { - unparsedEntityDeclHandler = handler; + if (parser != NULL) + unparsedEntityDeclHandler = handler; } void XMLCALL XML_SetNotationDeclHandler(XML_Parser parser, XML_NotationDeclHandler handler) { - notationDeclHandler = handler; + if (parser != NULL) + notationDeclHandler = handler; } void XMLCALL @@ -1422,6 +1615,8 @@ XML_SetNamespaceDeclHandler(XML_Parser parser, XML_StartNamespaceDeclHandler start, XML_EndNamespaceDeclHandler end) { + if (parser == NULL) + return; startNamespaceDeclHandler = start; endNamespaceDeclHandler = end; } @@ -1429,32 +1624,38 @@ XML_SetNamespaceDeclHandler(XML_Parser parser, void XMLCALL XML_SetStartNamespaceDeclHandler(XML_Parser parser, XML_StartNamespaceDeclHandler start) { - startNamespaceDeclHandler = start; + if (parser != NULL) + startNamespaceDeclHandler = start; } void XMLCALL XML_SetEndNamespaceDeclHandler(XML_Parser parser, XML_EndNamespaceDeclHandler end) { - endNamespaceDeclHandler = end; + if (parser != NULL) + endNamespaceDeclHandler = end; } void XMLCALL XML_SetNotStandaloneHandler(XML_Parser parser, XML_NotStandaloneHandler handler) { - notStandaloneHandler = handler; + if (parser != NULL) + notStandaloneHandler = handler; } void XMLCALL XML_SetExternalEntityRefHandler(XML_Parser parser, XML_ExternalEntityRefHandler handler) { - externalEntityRefHandler = handler; + if (parser != NULL) + externalEntityRefHandler = handler; } void XMLCALL XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg) { + if (parser == NULL) + return; if (arg) externalEntityRefHandlerArg = (XML_Parser)arg; else @@ -1465,7 +1666,8 @@ void XMLCALL XML_SetSkippedEntityHandler(XML_Parser parser, XML_SkippedEntityHandler handler) { - skippedEntityHandler = handler; + if (parser != NULL) + skippedEntityHandler = handler; } void XMLCALL @@ -1473,6 +1675,8 @@ XML_SetUnknownEncodingHandler(XML_Parser parser, XML_UnknownEncodingHandler handler, void *data) { + if (parser == NULL) + return; unknownEncodingHandler = handler; unknownEncodingHandlerData = data; } @@ -1481,33 +1685,39 @@ void XMLCALL XML_SetElementDeclHandler(XML_Parser parser, XML_ElementDeclHandler eldecl) { - elementDeclHandler = eldecl; + if (parser != NULL) + elementDeclHandler = eldecl; } void XMLCALL XML_SetAttlistDeclHandler(XML_Parser parser, XML_AttlistDeclHandler attdecl) { - attlistDeclHandler = attdecl; + if (parser != NULL) + attlistDeclHandler = attdecl; } void XMLCALL XML_SetEntityDeclHandler(XML_Parser parser, XML_EntityDeclHandler handler) { - entityDeclHandler = handler; + if (parser != NULL) + entityDeclHandler = handler; } void XMLCALL XML_SetXmlDeclHandler(XML_Parser parser, XML_XmlDeclHandler handler) { - xmlDeclHandler = handler; + if (parser != NULL) + xmlDeclHandler = handler; } int XMLCALL XML_SetParamEntityParsing(XML_Parser parser, enum XML_ParamEntityParsing peParsing) { + if (parser == NULL) + return 0; /* block after XML_Parse()/XML_ParseBuffer() has been called */ if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED) return 0; @@ -1523,6 +1733,10 @@ int XMLCALL XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt) { + if (parser == NULL) + return 0; + if (parser->m_parentParser) + return XML_SetHashSalt(parser->m_parentParser, hash_salt); /* block after XML_Parse()/XML_ParseBuffer() has been called */ if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED) return 0; @@ -1533,6 +1747,10 @@ XML_SetHashSalt(XML_Parser parser, enum XML_Status XMLCALL XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) { + if ((parser == NULL) || (len < 0) || ((s == NULL) && (len != 0))) { + errorCode = XML_ERROR_INVALID_ARGUMENT; + return XML_STATUS_ERROR; + } switch (ps_parsing) { case XML_SUSPENDED: errorCode = XML_ERROR_SUSPENDED; @@ -1585,6 +1803,13 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) const char *end; int nLeftOver; enum XML_Status result; + /* Detect overflow (a+b > MAX <==> b > MAX-a) */ + if (len > ((XML_Size)-1) / 2 - parseEndByteIndex) { + errorCode = XML_ERROR_NO_MEMORY; + eventPtr = eventEndPtr = NULL; + processor = errorProcessor; + return XML_STATUS_ERROR; + } parseEndByteIndex += len; positionPtr = s; ps_finalBuffer = (XML_Bool)isFinal; @@ -1617,11 +1842,14 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) nLeftOver = s + len - end; if (nLeftOver) { if (buffer == NULL || nLeftOver > bufferLim - buffer) { - /* FIXME avoid integer overflow */ - char *temp; - temp = (buffer == NULL - ? (char *)MALLOC(len * 2) - : (char *)REALLOC(buffer, len * 2)); + /* avoid _signed_ integer overflow */ + char *temp = NULL; + const int bytesToAllocate = (int)((unsigned)len * 2U); + if (bytesToAllocate > 0) { + temp = (buffer == NULL + ? (char *)MALLOC(bytesToAllocate) + : (char *)REALLOC(buffer, bytesToAllocate)); + } if (temp == NULL) { errorCode = XML_ERROR_NO_MEMORY; eventPtr = eventEndPtr = NULL; @@ -1629,7 +1857,7 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) return XML_STATUS_ERROR; } buffer = temp; - bufferLim = buffer + len * 2; + bufferLim = buffer + bytesToAllocate; } memcpy(buffer, end, nLeftOver); } @@ -1659,6 +1887,8 @@ XML_ParseBuffer(XML_Parser parser, int len, int isFinal) const char *start; enum XML_Status result = XML_STATUS_OK; + if (parser == NULL) + return XML_STATUS_ERROR; switch (ps_parsing) { case XML_SUSPENDED: errorCode = XML_ERROR_SUSPENDED; @@ -1712,6 +1942,8 @@ XML_ParseBuffer(XML_Parser parser, int len, int isFinal) void * XMLCALL XML_GetBuffer(XML_Parser parser, int len) { + if (parser == NULL) + return NULL; if (len < 0) { errorCode = XML_ERROR_NO_MEMORY; return NULL; @@ -1808,6 +2040,8 @@ XML_GetBuffer(XML_Parser parser, int len) enum XML_Status XMLCALL XML_StopParser(XML_Parser parser, XML_Bool resumable) { + if (parser == NULL) + return XML_STATUS_ERROR; switch (ps_parsing) { case XML_SUSPENDED: if (resumable) { @@ -1840,6 +2074,8 @@ XML_ResumeParser(XML_Parser parser) { enum XML_Status result = XML_STATUS_OK; + if (parser == NULL) + return XML_STATUS_ERROR; if (ps_parsing != XML_SUSPENDED) { errorCode = XML_ERROR_NOT_SUSPENDED; return XML_STATUS_ERROR; @@ -1876,6 +2112,8 @@ XML_ResumeParser(XML_Parser parser) void XMLCALL XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status) { + if (parser == NULL) + return; assert(status != NULL); *status = parser->m_parsingStatus; } @@ -1883,20 +2121,26 @@ XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status) enum XML_Error XMLCALL XML_GetErrorCode(XML_Parser parser) { + if (parser == NULL) + return XML_ERROR_INVALID_ARGUMENT; return errorCode; } XML_Index XMLCALL XML_GetCurrentByteIndex(XML_Parser parser) { + if (parser == NULL) + return -1; if (eventPtr) - return parseEndByteIndex - (parseEndPtr - eventPtr); + return (XML_Index)(parseEndByteIndex - (parseEndPtr - eventPtr)); return -1; } int XMLCALL XML_GetCurrentByteCount(XML_Parser parser) { + if (parser == NULL) + return 0; if (eventEndPtr && eventPtr) return (int)(eventEndPtr - eventPtr); return 0; @@ -1906,11 +2150,19 @@ const char * XMLCALL XML_GetInputContext(XML_Parser parser, int *offset, int *size) { #ifdef XML_CONTEXT_BYTES + if (parser == NULL) + return NULL; if (eventPtr && buffer) { - *offset = (int)(eventPtr - buffer); - *size = (int)(bufferEnd - buffer); + if (offset != NULL) + *offset = (int)(eventPtr - buffer); + if (size != NULL) + *size = (int)(bufferEnd - buffer); return buffer; } +#else + (void)parser; + (void)offset; + (void)size; #endif /* defined XML_CONTEXT_BYTES */ return (char *) 0; } @@ -1918,6 +2170,8 @@ XML_GetInputContext(XML_Parser parser, int *offset, int *size) XML_Size XMLCALL XML_GetCurrentLineNumber(XML_Parser parser) { + if (parser == NULL) + return 0; if (eventPtr && eventPtr >= positionPtr) { XmlUpdatePosition(encoding, positionPtr, eventPtr, &position); positionPtr = eventPtr; @@ -1928,6 +2182,8 @@ XML_GetCurrentLineNumber(XML_Parser parser) XML_Size XMLCALL XML_GetCurrentColumnNumber(XML_Parser parser) { + if (parser == NULL) + return 0; if (eventPtr && eventPtr >= positionPtr) { XmlUpdatePosition(encoding, positionPtr, eventPtr, &position); positionPtr = eventPtr; @@ -1938,30 +2194,38 @@ XML_GetCurrentColumnNumber(XML_Parser parser) void XMLCALL XML_FreeContentModel(XML_Parser parser, XML_Content *model) { - FREE(model); + if (parser != NULL) + FREE(model); } void * XMLCALL XML_MemMalloc(XML_Parser parser, size_t size) { + if (parser == NULL) + return NULL; return MALLOC(size); } void * XMLCALL XML_MemRealloc(XML_Parser parser, void *ptr, size_t size) { + if (parser == NULL) + return NULL; return REALLOC(ptr, size); } void XMLCALL XML_MemFree(XML_Parser parser, void *ptr) { - FREE(ptr); + if (parser != NULL) + FREE(ptr); } void XMLCALL XML_DefaultCurrent(XML_Parser parser) { + if (parser == NULL) + return; if (defaultHandler) { if (openInternalEntities) reportDefault(parser, @@ -2468,7 +2732,7 @@ doContent(XML_Parser parser, &fromPtr, rawNameEnd, (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1); convLen = (int)(toPtr - (XML_Char *)tag->buf); - if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) { + if ((fromPtr >= rawNameEnd) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) { tag->name.strLen = convLen; break; } @@ -2511,8 +2775,10 @@ doContent(XML_Parser parser, return XML_ERROR_NO_MEMORY; poolFinish(&tempPool); result = storeAtts(parser, enc, s, &name, &bindings); - if (result) + if (result != XML_ERROR_NONE) { + freeBindings(parser, bindings); return result; + } poolFinish(&tempPool); if (startElementHandler) { startElementHandler(handlerArg, name.str, (const XML_Char **)atts); @@ -2527,15 +2793,7 @@ doContent(XML_Parser parser, if (noElmHandlers && defaultHandler) reportDefault(parser, enc, s, next); poolClear(&tempPool); - while (bindings) { - BINDING *b = bindings; - if (endNamespaceDeclHandler) - endNamespaceDeclHandler(handlerArg, b->prefix->name); - bindings = bindings->nextTagBinding; - b->nextTagBinding = freeBindingList; - freeBindingList = b; - b->prefix->binding = b->prevPrefixBinding; - } + freeBindings(parser, bindings); } if (tagLevel == 0) return epilogProcessor(parser, next, end, nextPtr); @@ -2733,6 +2991,29 @@ doContent(XML_Parser parser, /* not reached */ } +/* This function does not call free() on the allocated memory, merely + * moving it to the parser's freeBindingList where it can be freed or + * reused as appropriate. + */ +static void +freeBindings(XML_Parser parser, BINDING *bindings) +{ + while (bindings) { + BINDING *b = bindings; + + /* startNamespaceDeclHandler will have been called for this + * binding in addBindings(), so call the end handler now. + */ + if (endNamespaceDeclHandler) + endNamespaceDeclHandler(handlerArg, b->prefix->name); + + bindings = bindings->nextTagBinding; + b->nextTagBinding = freeBindingList; + freeBindingList = b; + b->prefix->binding = b->prevPrefixBinding; + } +} + /* Precondition: all arguments must be non-NULL; Purpose: - normalize attributes @@ -2957,7 +3238,13 @@ storeAtts(XML_Parser parser, const ENCODING *enc, if (s[-1] == 2) { /* prefixed */ ATTRIBUTE_ID *id; const BINDING *b; - unsigned long uriHash = hash_secret_salt; + unsigned long uriHash; + struct siphash sip_state; + struct sipkey sip_key; + + copy_salt_to_sipkey(parser, &sip_key); + sip24_init(&sip_state, &sip_key); + ((XML_Char *)s)[-1] = 0; /* clear flag */ id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0); if (!id || !id->prefix) @@ -2966,22 +3253,26 @@ storeAtts(XML_Parser parser, const ENCODING *enc, if (!b) return XML_ERROR_UNBOUND_PREFIX; - /* as we expand the name we also calculate its hash value */ for (j = 0; j < b->uriLen; j++) { const XML_Char c = b->uri[j]; if (!poolAppendChar(&tempPool, c)) return XML_ERROR_NO_MEMORY; - uriHash = CHAR_HASH(uriHash, c); } + + sip24_update(&sip_state, b->uri, b->uriLen * sizeof(XML_Char)); + while (*s++ != XML_T(ASCII_COLON)) ; + + sip24_update(&sip_state, s, keylen(s) * sizeof(XML_Char)); + do { /* copies null terminator */ - const XML_Char c = *s; if (!poolAppendChar(&tempPool, *s)) return XML_ERROR_NO_MEMORY; - uriHash = CHAR_HASH(uriHash, c); } while (*s++); + uriHash = (unsigned long)sip24_final(&sip_state); + { /* Check hash table for duplicate of expanded name (uriName). Derived from code in lookup(parser, HASH_TABLE *table, ...). */ @@ -3695,6 +3986,14 @@ entityValueInitProcessor(XML_Parser parser, *nextPtr = next; return XML_ERROR_NONE; } + /* If we get this token, we have the start of what might be a + normal tag, but not a declaration (i.e. it doesn't begin with + "<!"). In a DTD context, that isn't legal. + */ + else if (tok == XML_TOK_INSTANCE_START) { + *nextPtr = next; + return XML_ERROR_SYNTAX; + } start = next; eventPtr = start; } @@ -4871,6 +5170,8 @@ processInternalEntity(XML_Parser parser, ENTITY *entity, openEntity->internalEventEndPtr = NULL; textStart = (char *)entity->textPtr; textEnd = (char *)(entity->textPtr + entity->textLen); + /* Set a safe default value in case 'next' does not get set */ + next = textStart; #ifdef XML_DTD if (entity->is_param) { @@ -4916,6 +5217,8 @@ internalEntityProcessor(XML_Parser parser, entity = openEntity->entity; textStart = ((char *)entity->textPtr) + entity->processed; textEnd = (char *)(entity->textPtr + entity->textLen); + /* Set a safe default value in case 'next' does not get set */ + next = textStart; #ifdef XML_DTD if (entity->is_param) { @@ -5876,7 +6179,6 @@ dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, const XML_Memory_H newE->defaultAtts = (DEFAULT_ATTRIBUTE *) ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE)); if (!newE->defaultAtts) { - ms->free_fcn(newE); return 0; } } @@ -6011,13 +6313,32 @@ keyeq(KEY s1, KEY s2) return XML_FALSE; } +static size_t +keylen(KEY s) +{ + size_t len = 0; + for (; *s; s++, len++); + return len; +} + +static void +copy_salt_to_sipkey(XML_Parser parser, struct sipkey * key) +{ + key->k[0] = 0; + key->k[1] = get_hash_secret_salt(parser); +} + static unsigned long FASTCALL hash(XML_Parser parser, KEY s) { - unsigned long h = hash_secret_salt; - while (*s) - h = CHAR_HASH(h, *s++); - return h; + struct siphash state; + struct sipkey key; + (void)sip_tobin; + (void)sip24_valid; + copy_salt_to_sipkey(parser, &key); + sip24_init(&state, &key); + sip24_update(&state, s, keylen(s) * sizeof(XML_Char)); + return (unsigned long)sip24_final(&state); } static NAMED * @@ -6260,6 +6581,35 @@ poolStoreString(STRING_POOL *pool, const ENCODING *enc, return pool->start; } +static size_t +poolBytesToAllocateFor(int blockSize) +{ + /* Unprotected math would be: + ** return offsetof(BLOCK, s) + blockSize * sizeof(XML_Char); + ** + ** Detect overflow, avoiding _signed_ overflow undefined behavior + ** For a + b * c we check b * c in isolation first, so that addition of a + ** on top has no chance of making us accept a small non-negative number + */ + const size_t stretch = sizeof(XML_Char); /* can be 4 bytes */ + + if (blockSize <= 0) + return 0; + + if (blockSize > (int)(INT_MAX / stretch)) + return 0; + + { + const int stretchedBlockSize = blockSize * (int)stretch; + const int bytesToAllocate = (int)( + offsetof(BLOCK, s) + (unsigned)stretchedBlockSize); + if (bytesToAllocate < 0) + return 0; + + return (size_t)bytesToAllocate; + } +} + static XML_Bool FASTCALL poolGrow(STRING_POOL *pool) { @@ -6289,14 +6639,17 @@ poolGrow(STRING_POOL *pool) if (pool->blocks && pool->start == pool->blocks->s) { BLOCK *temp; int blockSize = (int)((unsigned)(pool->end - pool->start)*2U); + size_t bytesToAllocate; if (blockSize < 0) return XML_FALSE; + bytesToAllocate = poolBytesToAllocateFor(blockSize); + if (bytesToAllocate == 0) + return XML_FALSE; + temp = (BLOCK *) - pool->mem->realloc_fcn(pool->blocks, - (offsetof(BLOCK, s) - + blockSize * sizeof(XML_Char))); + pool->mem->realloc_fcn(pool->blocks, (unsigned)bytesToAllocate); if (temp == NULL) return XML_FALSE; pool->blocks = temp; @@ -6308,16 +6661,26 @@ poolGrow(STRING_POOL *pool) else { BLOCK *tem; int blockSize = (int)(pool->end - pool->start); + size_t bytesToAllocate; if (blockSize < 0) return XML_FALSE; if (blockSize < INIT_BLOCK_SIZE) blockSize = INIT_BLOCK_SIZE; - else + else { + /* Detect overflow, avoiding _signed_ overflow undefined behavior */ + if ((int)((unsigned)blockSize * 2U) < 0) { + return XML_FALSE; + } blockSize *= 2; - tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s) - + blockSize * sizeof(XML_Char)); + } + + bytesToAllocate = poolBytesToAllocateFor(blockSize); + if (bytesToAllocate == 0) + return XML_FALSE; + + tem = (BLOCK *)pool->mem->malloc_fcn(bytesToAllocate); if (!tem) return XML_FALSE; tem->size = blockSize; diff --git a/Utilities/cmexpat/lib/xmlrole.c b/Utilities/cmexpat/lib/xmlrole.c index 4e79ffd..a7c5630 100644 --- a/Utilities/cmexpat/lib/xmlrole.c +++ b/Utilities/cmexpat/lib/xmlrole.c @@ -4,19 +4,13 @@ #include <stddef.h> -#ifdef COMPILING_FOR_WINDOWS +#ifdef _WIN32 #include "winconfig.h" -#elif defined(MACOS_CLASSIC) -#include "macconfig.h" -#elif defined(__amigaos__) -#include "amigaconfig.h" -#elif defined(__WATCOMC__) -#include "watcomconfig.h" #else #ifdef HAVE_EXPAT_CONFIG_H #include <expat_config.h> #endif -#endif /* ndef COMPILING_FOR_WINDOWS */ +#endif /* ndef _WIN32 */ #include "expat_external.h" #include "internal.h" diff --git a/Utilities/cmexpat/lib/xmltok.c b/Utilities/cmexpat/lib/xmltok.c index 4195279..cdf0720 100644 --- a/Utilities/cmexpat/lib/xmltok.c +++ b/Utilities/cmexpat/lib/xmltok.c @@ -4,19 +4,13 @@ #include <stddef.h> -#ifdef COMPILING_FOR_WINDOWS +#ifdef _WIN32 #include "winconfig.h" -#elif defined(MACOS_CLASSIC) -#include "macconfig.h" -#elif defined(__amigaos__) -#include "amigaconfig.h" -#elif defined(__WATCOMC__) -#include "watcomconfig.h" #else #ifdef HAVE_EXPAT_CONFIG_H #include <expat_config.h> #endif -#endif /* ndef COMPILING_FOR_WINDOWS */ +#endif /* ndef _WIN32 */ #include "expat_external.h" #include "internal.h" @@ -369,24 +363,24 @@ utf8_toUtf8(const ENCODING *UNUSED_P(enc), const char **fromP, const char *fromLim, char **toP, const char *toLim) { - enum XML_Convert_Result res = XML_CONVERT_COMPLETED; char *to; const char *from; - if (fromLim - *fromP > toLim - *toP) { - /* Avoid copying partial characters. */ - res = XML_CONVERT_OUTPUT_EXHAUSTED; - fromLim = *fromP + (toLim - *toP); - align_limit_to_full_utf8_characters(*fromP, &fromLim); - } + const char *fromLimInitial = fromLim; + + /* Avoid copying partial characters. */ + align_limit_to_full_utf8_characters(*fromP, &fromLim); + for (to = *toP, from = *fromP; (from < fromLim) && (to < toLim); from++, to++) *to = *from; *fromP = from; *toP = to; - if ((to == toLim) && (from < fromLim)) + if (fromLim < fromLimInitial) + return XML_CONVERT_INPUT_INCOMPLETE; + else if ((to == toLim) && (from < fromLim)) return XML_CONVERT_OUTPUT_EXHAUSTED; else - return res; + return XML_CONVERT_COMPLETED; } static enum XML_Convert_Result PTRCALL @@ -402,7 +396,7 @@ utf8_toUtf16(const ENCODING *enc, case BT_LEAD2: if (fromLim - from < 2) { res = XML_CONVERT_INPUT_INCOMPLETE; - break; + goto after; } *to++ = (unsigned short)(((from[0] & 0x1f) << 6) | (from[1] & 0x3f)); from += 2; @@ -410,7 +404,7 @@ utf8_toUtf16(const ENCODING *enc, case BT_LEAD3: if (fromLim - from < 3) { res = XML_CONVERT_INPUT_INCOMPLETE; - break; + goto after; } *to++ = (unsigned short)(((from[0] & 0xf) << 12) | ((from[1] & 0x3f) << 6) | (from[2] & 0x3f)); @@ -441,6 +435,8 @@ utf8_toUtf16(const ENCODING *enc, break; } } + if (from < fromLim) + res = XML_CONVERT_OUTPUT_EXHAUSTED; after: *fromP = from; *toP = to; diff --git a/Utilities/cmexpat/lib/xmltok_impl.c b/Utilities/cmexpat/lib/xmltok_impl.c index fd0ee22..5f779c0 100644 --- a/Utilities/cmexpat/lib/xmltok_impl.c +++ b/Utilities/cmexpat/lib/xmltok_impl.c @@ -1198,6 +1198,8 @@ PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, const char *start; if (ptr >= end) return XML_TOK_NONE; + else if (! HAS_CHAR(enc, ptr, end)) + return XML_TOK_PARTIAL; start = ptr; while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { @@ -1256,6 +1258,8 @@ PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, const char *start; if (ptr >= end) return XML_TOK_NONE; + else if (! HAS_CHAR(enc, ptr, end)) + return XML_TOK_PARTIAL; start = ptr; while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { @@ -330,6 +330,7 @@ CMAKE_CXX_SOURCES="\ cmHexFileConverter \ cmIfCommand \ cmIncludeCommand \ + cmIncludeGuardCommand \ cmIncludeDirectoryCommand \ cmIncludeRegularExpressionCommand \ cmInstallCommand \ |