diff options
36 files changed, 219 insertions, 147 deletions
diff --git a/.gitlab/ci/configure_windows_clang_common.cmake b/.gitlab/ci/configure_windows_clang_common.cmake index 55dce1d..3d93aae 100644 --- a/.gitlab/ci/configure_windows_clang_common.cmake +++ b/.gitlab/ci/configure_windows_clang_common.cmake @@ -1,3 +1,7 @@ +set(CMake_TEST_FindOpenMP "ON" CACHE BOOL "") +set(CMake_TEST_FindOpenMP_C "ON" CACHE BOOL "") +set(CMake_TEST_FindOpenMP_CXX "ON" CACHE BOOL "") +set(CMake_TEST_FindOpenMP_Fortran "OFF" CACHE BOOL "") set(CMake_TEST_Java OFF CACHE BOOL "") set(configure_no_sccache 1) diff --git a/.gitlab/os-macos.yml b/.gitlab/os-macos.yml index 2bd3e94..81e9ce2 100644 --- a/.gitlab/os-macos.yml +++ b/.gitlab/os-macos.yml @@ -7,7 +7,7 @@ GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci ext/$CI_CONCURRENT_ID" # TODO: Factor this out so that each job selects the Xcode version to # use so that different versions can be tested in a single pipeline. - DEVELOPER_DIR: "/Applications/Xcode-15.1.app/Contents/Developer" + DEVELOPER_DIR: "/Applications/Xcode-15.2.app/Contents/Developer" # Avoid conflicting with other projects running on the same machine. SCCACHE_SERVER_PORT: 4227 @@ -135,7 +135,7 @@ - cmake # Since this is a bare runner, pin to a project. - macos-x86_64 - shell - - xcode-15.1 + - xcode-15.2 - nonconcurrent .macos_x86_64_tags_ext: @@ -143,7 +143,7 @@ - cmake # Since this is a bare runner, pin to a project. - macos-x86_64 - shell - - xcode-15.1 + - xcode-15.2 - concurrent .macos_arm64_tags: @@ -151,7 +151,7 @@ - cmake # Since this is a bare runner, pin to a project. - macos-arm64 - shell - - xcode-15.1 + - xcode-15.2 - nonconcurrent .macos_arm64_tags_ext: @@ -159,7 +159,7 @@ - cmake # Since this is a bare runner, pin to a project. - macos-arm64 - shell - - xcode-15.1 + - xcode-15.2 - concurrent .macos_arm64_tags_package: @@ -167,7 +167,7 @@ - cmake # Since this is a bare runner, pin to a project. - macos-arm64 - shell - - xcode-15.1 + - xcode-15.2 - nonconcurrent - finder diff --git a/Help/command/qt_wrap_cpp.rst b/Help/command/qt_wrap_cpp.rst index ce11c2d..02f7232 100644 --- a/Help/command/qt_wrap_cpp.rst +++ b/Help/command/qt_wrap_cpp.rst @@ -8,7 +8,7 @@ qt_wrap_cpp :module:`FindQt4` module provides the ``qt4_wrap_cpp()`` macro, which should be used instead for Qt 4 projects. For projects using Qt 5 or later, use the equivalent macro provided by Qt itself (e.g. Qt 5 provides - ``qt5_wrap_cpp()``). + `qt5_wrap_cpp() <https://doc.qt.io/qt-5/qtcore-cmake-qt5-wrap-cpp.html>`_). Manually create Qt Wrappers. diff --git a/Help/manual/cmake-qt.7.rst b/Help/manual/cmake-qt.7.rst index e5a39f5..27230c8 100644 --- a/Help/manual/cmake-qt.7.rst +++ b/Help/manual/cmake-qt.7.rst @@ -10,34 +10,39 @@ cmake-qt(7) Introduction ============ -CMake can find and use Qt 4 and Qt 5 libraries. The Qt 4 libraries are found -by the :module:`FindQt4` find-module shipped with CMake, whereas the -Qt 5 libraries are found using "Config-file Packages" shipped with Qt 5. See -:manual:`cmake-packages(7)` for more information about CMake packages, and -see `the Qt cmake manual <https://doc.qt.io/qt-5/cmake-manual.html>`_ -for your Qt version. - -Qt 4 and Qt 5 may be used together in the same +CMake can find and use Qt 4, Qt 5 and Qt 6 libraries. The Qt 4 libraries are +found by the :module:`FindQt4` find-module shipped with CMake, whereas the +Qt 5 and Qt 6 libraries are found using "Config-file Packages" shipped with +Qt 5 and Qt 6. See :manual:`cmake-packages(7)` for more information about CMake +packages, and see `the Qt cmake manual`_ for your Qt version. + +.. _`the Qt cmake manual`: https://doc.qt.io/qt-6/cmake-manual.html + +Qt 4, Qt 5 and Qt 6 may be used together in the same :manual:`CMake buildsystem <cmake-buildsystem(7)>`: .. code-block:: cmake - cmake_minimum_required(VERSION 3.8.0 FATAL_ERROR) + cmake_minimum_required(VERSION 3.16 FATAL_ERROR) - project(Qt4And5) + project(Qt4_5_6) set(CMAKE_AUTOMOC ON) - find_package(Qt5 COMPONENTS Widgets DBus REQUIRED) + find_package(Qt6 COMPONENTS Widgets DBus REQUIRED) add_executable(publisher publisher.cpp) - target_link_libraries(publisher Qt5::Widgets Qt5::DBus) + target_link_libraries(publisher Qt6::Widgets Qt6::DBus) + + find_package(Qt5 COMPONENTS Gui DBus REQUIRED) + add_executable(subscriber1 subscriber1.cpp) + target_link_libraries(subscriber1 Qt5::Gui Qt5::DBus) find_package(Qt4 REQUIRED) - add_executable(subscriber subscriber.cpp) - target_link_libraries(subscriber Qt4::QtGui Qt4::QtDBus) + add_executable(subscriber2 subscriber2.cpp) + target_link_libraries(subscriber2 Qt4::QtGui Qt4::QtDBus) -A CMake target may not link to both Qt 4 and Qt 5. A diagnostic is issued if -this is attempted or results from transitive target dependency evaluation. +A CMake target may not link to more than one Qt version. A diagnostic is issued +if this is attempted or results from transitive target dependency evaluation. Qt Build Tools ============== @@ -46,7 +51,7 @@ Qt relies on some bundled tools for code generation, such as ``moc`` for meta-object code generation, ``uic`` for widget layout and population, and ``rcc`` for virtual file system content generation. These tools may be automatically invoked by :manual:`cmake(1)` if the appropriate conditions -are met. The automatic tool invocation may be used with both Qt 4 and Qt 5. +are met. The automatic tool invocation may be used with Qt version 4 to 6. .. _`Qt AUTOMOC`: @@ -158,7 +163,7 @@ should be used when running ``uic``: .. code-block:: cmake add_library(KI18n klocalizedstring.cpp) - target_link_libraries(KI18n Qt5::Core) + target_link_libraries(KI18n Qt6::Core) # KI18n uses the tr2i18n() function instead of tr(). That function is # declared in the klocalizedstring.h header. @@ -213,25 +218,44 @@ overrides options from the :prop_tgt:`AUTORCC_OPTIONS` target property. Source files can be excluded from :prop_tgt:`AUTORCC` processing by enabling :prop_sf:`SKIP_AUTORCC` or the broader :prop_sf:`SKIP_AUTOGEN`. +.. _`<ORIGIN>_autogen`: + The ``<ORIGIN>_autogen`` target =============================== The ``moc`` and ``uic`` tools are executed as part of a synthesized -``<ORIGIN>_autogen`` :command:`custom target <add_custom_target>` generated by -CMake. By default that ``<ORIGIN>_autogen`` target inherits the dependencies +:ref:`<ORIGIN>_autogen` :command:`custom target <add_custom_target>` generated by +CMake. By default that :ref:`<ORIGIN>_autogen` target inherits the dependencies of the ``<ORIGIN>`` target (see :prop_tgt:`AUTOGEN_ORIGIN_DEPENDS`). -Target dependencies may be added to the ``<ORIGIN>_autogen`` target by adding +Target dependencies may be added to the :ref:`<ORIGIN>_autogen` target by adding them to the :prop_tgt:`AUTOGEN_TARGET_DEPENDS` target property. +.. note:: + If Qt 5.15 or later is used and the generator is either :generator:`Ninja` or + :ref:`Makefile Generators`, see :ref:`<ORIGIN>_autogen_timestamp_deps`. + +.. _`<ORIGIN>_autogen_timestamp_deps`: + +The ``<ORIGIN>_autogen_timestamp_deps`` target +============================================== + +If Qt 5.15 or later is used and the generator is either :generator:`Ninja` or +:ref:`Makefile Generators`, the ``<ORIGIN>_autogen_timestamp_deps`` target is +also created in addition to the :ref:`<ORIGIN>_autogen` target. This target +does not have any sources or commands to execute, but it has dependencies that +were previously inherited by the pre-Qt 5.15 :ref:`<ORIGIN>_autogen` target. +These dependencies will serve as a list of order-only dependencies for the +custom command, without forcing the custom command to re-execute. + Visual Studio Generators ======================== When using the :manual:`Visual Studio generators <cmake-generators(7)>`, CMake generates a ``PRE_BUILD`` :command:`custom command <add_custom_command>` -instead of the ``<ORIGIN>_autogen`` :command:`custom target <add_custom_target>` -(for :prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC`). -This isn't always possible though and -an ``<ORIGIN>_autogen`` :command:`custom target <add_custom_target>` is used, +instead of the :ref:`<ORIGIN>_autogen` +:command:`custom target <add_custom_target>` (for :prop_tgt:`AUTOMOC` and +:prop_tgt:`AUTOUIC`). This isn't always possible though and an +:ref:`<ORIGIN>_autogen` :command:`custom target <add_custom_target>` is used, when either - the ``<ORIGIN>`` target depends on :prop_sf:`GENERATED` files which aren't diff --git a/Help/prop_tgt/AUTOGEN_ORIGIN_DEPENDS.rst b/Help/prop_tgt/AUTOGEN_ORIGIN_DEPENDS.rst index 9350a4f..33db8a7 100644 --- a/Help/prop_tgt/AUTOGEN_ORIGIN_DEPENDS.rst +++ b/Help/prop_tgt/AUTOGEN_ORIGIN_DEPENDS.rst @@ -4,20 +4,29 @@ AUTOGEN_ORIGIN_DEPENDS .. versionadded:: 3.14 Switch for forwarding origin target dependencies to the corresponding -``_autogen`` target. +:ref:`<ORIGIN>_autogen` target. + + .. note:: + + If Qt 5.15 or later is used and the generator is either :generator:`Ninja` + or :ref:`Makefile Generators`, origin target dependencies are forwarded to + the :ref:`<ORIGIN>_autogen_timestamp_deps` target instead of + :ref:`<ORIGIN>_autogen` + Targets which have their :prop_tgt:`AUTOMOC` or :prop_tgt:`AUTOUIC` property -``ON`` have a corresponding ``_autogen`` target which generates -``moc`` and ``uic`` files. As this ``_autogen`` target is created at +``ON`` have a corresponding :ref:`<ORIGIN>_autogen` target which generates +``moc`` and ``uic`` files. As this :ref:`<ORIGIN>_autogen` target is created at generate-time, it is not possible to define dependencies of it using -e.g. :command:`add_dependencies`. Instead the -``AUTOGEN_ORIGIN_DEPENDS`` target property decides whether the origin -target dependencies should be forwarded to the ``_autogen`` target or not. +e.g. :command:`add_dependencies`. Instead the ``AUTOGEN_ORIGIN_DEPENDS`` +target property decides whether the origin target dependencies should be +forwarded to the :ref:`<ORIGIN>_autogen` target or not. By default ``AUTOGEN_ORIGIN_DEPENDS`` is initialized from :variable:`CMAKE_AUTOGEN_ORIGIN_DEPENDS` which is ``ON`` by default. -In total the dependencies of the ``_autogen`` target are composed from +In total the dependencies of the :ref:`<ORIGIN>_autogen` target are composed +from - forwarded origin target dependencies (enabled by default via ``AUTOGEN_ORIGIN_DEPENDS``) @@ -26,15 +35,14 @@ In total the dependencies of the ``_autogen`` target are composed from See the :manual:`cmake-qt(7)` manual for more information on using CMake with Qt. -Note -^^^^ +.. note:: -Disabling ``AUTOGEN_ORIGIN_DEPENDS`` is useful to avoid building of -origin target dependencies when building the ``_autogen`` target only. -This is especially interesting when a -:variable:`global autogen target <CMAKE_GLOBAL_AUTOGEN_TARGET>` is enabled. + Disabling ``AUTOGEN_ORIGIN_DEPENDS`` is useful to avoid building of + origin target dependencies when building the :ref:`<ORIGIN>_autogen` target + only. This is especially interesting when a + :variable:`global autogen target <CMAKE_GLOBAL_AUTOGEN_TARGET>` is enabled. -When the ``_autogen`` target doesn't require all the origin target's -dependencies, and ``AUTOGEN_ORIGIN_DEPENDS`` is disabled, it might be -necessary to extend :prop_tgt:`AUTOGEN_TARGET_DEPENDS` to add missing -dependencies. + When the :ref:`<ORIGIN>_autogen` target doesn't require all the origin target's + dependencies, and ``AUTOGEN_ORIGIN_DEPENDS`` is disabled, it might be + necessary to extend :prop_tgt:`AUTOGEN_TARGET_DEPENDS` to add missing + dependencies. diff --git a/Help/prop_tgt/AUTOGEN_PARALLEL.rst b/Help/prop_tgt/AUTOGEN_PARALLEL.rst index 663b54e..9d34355 100644 --- a/Help/prop_tgt/AUTOGEN_PARALLEL.rst +++ b/Help/prop_tgt/AUTOGEN_PARALLEL.rst @@ -6,9 +6,9 @@ AUTOGEN_PARALLEL Number of parallel ``moc`` or ``uic`` processes to start when using :prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC`. -The custom ``<origin>_autogen`` target starts a number of threads of which +The custom :ref:`<ORIGIN>_autogen` target starts a number of threads of which each one parses a source file and on demand starts a ``moc`` or ``uic`` -process. ``AUTOGEN_PARALLEL`` controls how many parallel threads +process. ``AUTOGEN_PARALLEL`` controls how many parallel threads (and therefore ``moc`` or ``uic`` processes) are started. - An empty (or unset) value or the string ``AUTO`` sets the number of diff --git a/Help/prop_tgt/AUTOGEN_TARGET_DEPENDS.rst b/Help/prop_tgt/AUTOGEN_TARGET_DEPENDS.rst index 5286d2d..13e2ef7 100644 --- a/Help/prop_tgt/AUTOGEN_TARGET_DEPENDS.rst +++ b/Help/prop_tgt/AUTOGEN_TARGET_DEPENDS.rst @@ -1,18 +1,28 @@ AUTOGEN_TARGET_DEPENDS ---------------------- -Additional target dependencies of the corresponding ``_autogen`` target. +Additional target dependencies of the corresponding :ref:`<ORIGIN>_autogen` +target. + + .. note:: + + If Qt 5.15 or later is used and the generator is either :generator:`Ninja` + or :ref:`Makefile Generators`, additional target dependencies are added to + the :ref:`<ORIGIN>_autogen_timestamp_deps` target instead of the + :ref:`<ORIGIN>_autogen` target. + Targets which have their :prop_tgt:`AUTOMOC` or :prop_tgt:`AUTOUIC` property -``ON`` have a corresponding ``_autogen`` target which generates -``moc`` and ``uic`` files. As this ``_autogen`` target is created at -generate-time, it is not possible to define dependencies of it using -e.g. :command:`add_dependencies`. Instead the -``AUTOGEN_TARGET_DEPENDS`` target property can be set to a -:ref:`;-list <CMake Language Lists>` of additional dependencies for the -``_autogen`` target. Dependencies can be target names or file names. - -In total the dependencies of the ``_autogen`` target are composed from +``ON`` have a corresponding :ref:`<ORIGIN>_autogen` target which generates +``moc`` and ``uic`` files. As this :ref:`<ORIGIN>_autogen` target is created +at generate-time, it is not possible to define dependencies of it using e.g. +:command:`add_dependencies`. Instead the ``AUTOGEN_TARGET_DEPENDS`` target +property can be set to a :ref:`;-list <CMake Language Lists>` of additional +dependencies for the :ref:`<ORIGIN>_autogen` target. Dependencies can be target +names or file names. + +In total the dependencies of the :ref:`<ORIGIN>_autogen` target are composed +from - forwarded origin target dependencies (enabled by default via :prop_tgt:`AUTOGEN_ORIGIN_DEPENDS`) diff --git a/Help/prop_tgt/AUTOMOC.rst b/Help/prop_tgt/AUTOMOC.rst index 6f58afb..d4f2b25 100644 --- a/Help/prop_tgt/AUTOMOC.rst +++ b/Help/prop_tgt/AUTOMOC.rst @@ -3,11 +3,13 @@ AUTOMOC Should the target be processed with auto-moc (for Qt projects). -``AUTOMOC`` is a boolean specifying whether CMake will handle the Qt -``moc`` preprocessor automatically, i.e. without having to use commands like -:module:`QT4_WRAP_CPP() <FindQt4>`, ``QT5_WRAP_CPP()``, etc. +``AUTOMOC`` is a boolean specifying whether CMake will handle the Qt ``moc`` +preprocessor automatically, i.e. without having to use commands like +:module:`QT4_WRAP_CPP() <FindQt4>`, `qt5_wrap_cpp()`_, etc. Currently, Qt versions 4 to 6 are supported. +.. _qt5_wrap_cpp(): https://doc.qt.io/qt-5/qtcore-cmake-qt5-wrap-cpp.html + This property is initialized by the value of the :variable:`CMAKE_AUTOMOC` variable if it is set when a target is created. @@ -240,7 +242,7 @@ e.g. in MSVS. :variable:`CMAKE_GLOBAL_AUTOGEN_TARGET`: A global ``autogen`` target, that depends on all ``AUTOMOC`` or -:prop_tgt:`AUTOUIC` generated ``<ORIGIN>_autogen`` targets in the project, +:prop_tgt:`AUTOUIC` generated :ref:`<ORIGIN>_autogen` targets in the project, will be generated when this variable is ``ON``. :prop_tgt:`AUTOGEN_PARALLEL`: diff --git a/Help/prop_tgt/AUTOMOC_DEPEND_FILTERS.rst b/Help/prop_tgt/AUTOMOC_DEPEND_FILTERS.rst index c4277d7..d571f53 100644 --- a/Help/prop_tgt/AUTOMOC_DEPEND_FILTERS.rst +++ b/Help/prop_tgt/AUTOMOC_DEPEND_FILTERS.rst @@ -22,14 +22,14 @@ file gets rebuilt even when the source file itself doesn't change. If any of the extracted files is :prop_sf:`GENERATED` or if it is not in the target's sources, then it might be necessary to add it to the -``_autogen`` target dependencies. +:ref:`<ORIGIN>_autogen` target dependencies. See :prop_tgt:`AUTOGEN_TARGET_DEPENDS` for reference. By default ``AUTOMOC_DEPEND_FILTERS`` is initialized from :variable:`CMAKE_AUTOMOC_DEPEND_FILTERS`, which is empty by default. -From Qt 5.15.0 on this variable is ignored as moc is able to output the correct -dependencies. +From Qt 5.15.0 on this variable is ignored as ``moc`` is able to output the +correct dependencies. See the :manual:`cmake-qt(7)` manual for more information on using CMake with Qt. diff --git a/Help/prop_tgt/AUTORCC.rst b/Help/prop_tgt/AUTORCC.rst index 33de352..fea906c 100644 --- a/Help/prop_tgt/AUTORCC.rst +++ b/Help/prop_tgt/AUTORCC.rst @@ -5,9 +5,11 @@ Should the target be processed with auto-rcc (for Qt projects). ``AUTORCC`` is a boolean specifying whether CMake will handle the Qt ``rcc`` code generator automatically, i.e. without having to use -commands like :module:`QT4_ADD_RESOURCES() <FindQt4>`, ``QT5_ADD_RESOURCES()``, +commands like :module:`QT4_ADD_RESOURCES() <FindQt4>`, `qt5_add_resources()`_, etc. Currently, Qt versions 4 to 6 are supported. +.. _`qt5_add_resources()`: https://doc.qt.io/qt-5/qtcore-cmake-qt5-add-resources.html + When this property is ``ON``, CMake will handle ``.qrc`` files added as target sources at build time and invoke ``rcc`` accordingly. This property is initialized by the value of the :variable:`CMAKE_AUTORCC` diff --git a/Help/prop_tgt/AUTOUIC.rst b/Help/prop_tgt/AUTOUIC.rst index 95366ee..5010220 100644 --- a/Help/prop_tgt/AUTOUIC.rst +++ b/Help/prop_tgt/AUTOUIC.rst @@ -5,9 +5,11 @@ Should the target be processed with auto-uic (for Qt projects). ``AUTOUIC`` is a boolean specifying whether CMake will handle the Qt ``uic`` code generator automatically, i.e. without having to use -commands like :module:`QT4_WRAP_UI() <FindQt4>`, ``QT5_WRAP_UI()``, etc. +commands like :module:`QT4_WRAP_UI() <FindQt4>`, `qt5_wrap_ui()`_, etc. Currently, Qt versions 4 to 6 are supported. +.. _`qt5_wrap_ui()`: https://doc.qt.io/qt-5/qtwidgets-cmake-qt5-wrap-ui.html + This property is initialized by the value of the :variable:`CMAKE_AUTOUIC` variable if it is set when a target is created. @@ -74,7 +76,7 @@ e.g. in MSVS. :variable:`CMAKE_GLOBAL_AUTOGEN_TARGET`: A global ``autogen`` target, that depends on all :prop_tgt:`AUTOMOC` or -``AUTOUIC`` generated ``<ORIGIN>_autogen`` targets in the project, +``AUTOUIC`` generated :ref:`<ORIGIN>_autogen` targets in the project, will be generated when this variable is ``ON``. :prop_tgt:`AUTOGEN_PARALLEL`: diff --git a/Help/release/3.14.rst b/Help/release/3.14.rst index 5fedf7d..ab59ee2 100644 --- a/Help/release/3.14.rst +++ b/Help/release/3.14.rst @@ -302,7 +302,7 @@ Autogen * A new :variable:`CMAKE_AUTOGEN_ORIGIN_DEPENDS` variable and :prop_tgt:`AUTOGEN_ORIGIN_DEPENDS` target property may be set to enable or disable forwarding of the origin target dependencies to the corresponding - ``_autogen`` target. + :ref:`<ORIGIN>_autogen` target. CTest ----- diff --git a/Help/variable/CMAKE_AUTOGEN_ORIGIN_DEPENDS.rst b/Help/variable/CMAKE_AUTOGEN_ORIGIN_DEPENDS.rst index f490974..52aa891 100644 --- a/Help/variable/CMAKE_AUTOGEN_ORIGIN_DEPENDS.rst +++ b/Help/variable/CMAKE_AUTOGEN_ORIGIN_DEPENDS.rst @@ -4,7 +4,14 @@ CMAKE_AUTOGEN_ORIGIN_DEPENDS .. versionadded:: 3.14 Switch for forwarding origin target dependencies to the corresponding -``_autogen`` targets. +:ref:`<ORIGIN>_autogen` targets. + + .. note:: + + If Qt 5.15 or later is used and the generator is either :generator:`Ninja` + or :ref:`Makefile Generators`, additional target dependencies are added to + the :ref:`<ORIGIN>_autogen_timestamp_deps` target instead of the + :ref:`<ORIGIN>_autogen` target. This variable is used to initialize the :prop_tgt:`AUTOGEN_ORIGIN_DEPENDS` property on all the targets. See that target property for additional diff --git a/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET.rst b/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET.rst index 7d3f9c3..2bf5f05 100644 --- a/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET.rst +++ b/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET.rst @@ -7,7 +7,7 @@ Switch to enable generation of a global ``autogen`` target. When ``CMAKE_GLOBAL_AUTOGEN_TARGET`` is enabled, a custom target ``autogen`` is generated. This target depends on all :prop_tgt:`AUTOMOC` and -:prop_tgt:`AUTOUIC` generated ``<ORIGIN>_autogen`` targets in the project. +:prop_tgt:`AUTOUIC` generated :ref:`<ORIGIN>_autogen` targets in the project. By building the global ``autogen`` target, all :prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC` files in the project will be generated. @@ -19,10 +19,9 @@ By default ``CMAKE_GLOBAL_AUTOGEN_TARGET`` is unset. See the :manual:`cmake-qt(7)` manual for more information on using CMake with Qt. -Note -^^^^ +.. note:: -``<ORIGIN>_autogen`` targets by default inherit their origin target's -dependencies. This might result in unintended dependency target -builds when only ``<ORIGIN>_autogen`` targets are built. A solution is to -disable :prop_tgt:`AUTOGEN_ORIGIN_DEPENDS` on the respective origin targets. + :ref:`<ORIGIN>_autogen` targets by default inherit their origin target's + dependencies. This might result in unintended dependency target builds when + only :ref:`<ORIGIN>_autogen` targets are built. A solution is to disable + :prop_tgt:`AUTOGEN_ORIGIN_DEPENDS` on the respective origin targets. diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake index b380aa5..25aacca 100644 --- a/Modules/CMakeDetermineCompilerId.cmake +++ b/Modules/CMakeDetermineCompilerId.cmake @@ -1182,7 +1182,7 @@ function(CMAKE_DETERMINE_MSVC_SHOWINCLUDES_PREFIX lang userflags) ENCODING AUTO # cl prints in console output code page ) string(REPLACE "\n" "\n " msg " ${out}") - if(res EQUAL 0 AND "${out}" MATCHES "(^|\n)([^:\n][^:\n]+:[^:\n]*[^: \n][^: \n]:?[ \t]+)([A-Za-z]:\\\\|\\./|/)") + if(res EQUAL 0 AND "${out}" MATCHES "(^|\n)([^:\n][^:\n]+:[^:\n]*[^: \n][^: \n]:?[ \t]+)([A-Za-z]:\\\\|\\./|\\.\\\\|/)") set(CMAKE_${lang}_CL_SHOWINCLUDES_PREFIX "${CMAKE_MATCH_2}" PARENT_SCOPE) string(APPEND msg "\nFound prefix \"${CMAKE_MATCH_2}\"") else() diff --git a/Modules/FindCUDAToolkit.cmake b/Modules/FindCUDAToolkit.cmake index ac72c17..1eaf36b 100644 --- a/Modules/FindCUDAToolkit.cmake +++ b/Modules/FindCUDAToolkit.cmake @@ -1139,18 +1139,12 @@ if(CUDAToolkit_FOUND) _CUDAToolkit_find_and_add_import_lib(cuda_driver ALT cuda) - _CUDAToolkit_find_and_add_import_lib(cudart) - _CUDAToolkit_find_and_add_import_lib(cudart_static) - # setup dependencies that are required for cudart_static when building + # setup dependencies that are required for cudart/cudart_static when building # on linux. These are generally only required when using the CUDA toolkit # when CUDA language is disabled - if(NOT TARGET CUDA::cudart_static_deps - AND TARGET CUDA::cudart_static) - + if(NOT TARGET CUDA::cudart_static_deps) add_library(CUDA::cudart_static_deps IMPORTED INTERFACE) - target_link_libraries(CUDA::cudart_static INTERFACE CUDA::cudart_static_deps) - if(UNIX AND (CMAKE_C_COMPILER OR CMAKE_CXX_COMPILER)) find_package(Threads REQUIRED) target_link_libraries(CUDA::cudart_static_deps INTERFACE Threads::Threads ${CMAKE_DL_LIBS}) @@ -1168,6 +1162,9 @@ if(CUDAToolkit_FOUND) endif() endif() + _CUDAToolkit_find_and_add_import_lib(cudart DEPS cudart_static_deps) + _CUDAToolkit_find_and_add_import_lib(cudart_static DEPS cudart_static_deps) + if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL 12.0.0) _CUDAToolkit_find_and_add_import_lib(nvJitLink) _CUDAToolkit_find_and_add_import_lib(nvJitLink_static DEPS cudart_static_deps) diff --git a/Modules/FindMatlab.cmake b/Modules/FindMatlab.cmake index 608b2ed..6c80506 100644 --- a/Modules/FindMatlab.cmake +++ b/Modules/FindMatlab.cmake @@ -485,18 +485,7 @@ function(matlab_extract_all_installed_versions_from_registry win64 matlab_versio foreach(_match IN LISTS _versions_regex) if(_match MATCHES "([0-9]+(\\.[0-9]+)+)") - cmake_host_system_information(RESULT _reg - QUERY WINDOWS_REGISTRY "HKLM/SOFTWARE/Mathworks/${_installation_type}/${CMAKE_MATCH_1}" - VALUE "MATLABROOT" - VIEW ${_view} - ) - - _Matlab_VersionInfoXML("${_reg}" _matlab_version_tmp) - if("${_matlab_version_tmp}" STREQUAL "unknown") - list(APPEND matlabs_from_registry ${_match}) - else() - list(APPEND matlabs_from_registry ${_matlab_version_tmp}) - endif() + list(APPEND matlabs_from_registry ${_match}) endif() endforeach() diff --git a/Modules/FindOpenMP.cmake b/Modules/FindOpenMP.cmake index 69099f7..f26b864 100644 --- a/Modules/FindOpenMP.cmake +++ b/Modules/FindOpenMP.cmake @@ -224,7 +224,8 @@ function(_OPENMP_GET_FLAGS LANG FLAG_MODE OPENMP_FLAG_VAR OPENMP_LIB_NAMES_VAR) OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT ) - if(OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG}) + if(OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG} AND + NOT "x${CMAKE_${LANG}_SIMULATE_ID}" STREQUAL "xMSVC") set("${OPENMP_FLAG_VAR}" "${OPENMP_FLAG}" PARENT_SCOPE) if(CMAKE_${LANG}_VERBOSE_FLAG) diff --git a/Modules/FindPackageHandleStandardArgs.cmake b/Modules/FindPackageHandleStandardArgs.cmake index 56ba1e6..63b2bf2 100644 --- a/Modules/FindPackageHandleStandardArgs.cmake +++ b/Modules/FindPackageHandleStandardArgs.cmake @@ -342,7 +342,7 @@ function(FIND_PACKAGE_CHECK_VERSION version result) set(version_msg "Found unsuitable version \"${version}\", but required is exact version \"${${package}_FIND_VERSION}\"") else () set(version_ok TRUE) - set(version_msg "(found suitable exact version \"${_FOUND_VERSION}\")") + set(version_msg "(found suitable exact version \"${version}\")") endif () else () if (NOT ${package}_FIND_VERSION VERSION_EQUAL version) diff --git a/Modules/FindVulkan.cmake b/Modules/FindVulkan.cmake index 581763d..0f45b63 100644 --- a/Modules/FindVulkan.cmake +++ b/Modules/FindVulkan.cmake @@ -537,13 +537,7 @@ _Vulkan_set_library_component_found(glslang-oglcompiler NO_WARNING) _Vulkan_set_library_component_found(glslang-osdependent NO_WARNING) _Vulkan_set_library_component_found(glslang-machineindependent NO_WARNING) _Vulkan_set_library_component_found(glslang-genericcodegen NO_WARNING) -_Vulkan_set_library_component_found(glslang - DEPENDENT_COMPONENTS - glslang-spirv - glslang-oglcompiler - glslang-osdependent - glslang-machineindependent - glslang-genericcodegen) +_Vulkan_set_library_component_found(glslang DEPENDENT_COMPONENTS glslang-spirv) _Vulkan_set_library_component_found(shaderc_combined) _Vulkan_set_library_component_found(SPIRV-Tools) _Vulkan_set_library_component_found(volk) @@ -747,10 +741,6 @@ if(Vulkan_FOUND) if((Vulkan_glslang_LIBRARY OR Vulkan_glslang_DEBUG_LIBRARY) AND TARGET Vulkan::glslang-spirv - AND TARGET Vulkan::glslang-oglcompiler - AND TARGET Vulkan::glslang-osdependent - AND TARGET Vulkan::glslang-machineindependent - AND TARGET Vulkan::glslang-genericcodegen AND NOT TARGET Vulkan::glslang) add_library(Vulkan::glslang STATIC IMPORTED) set_property(TARGET Vulkan::glslang @@ -775,10 +765,13 @@ if(Vulkan_FOUND) target_link_libraries(Vulkan::glslang INTERFACE Vulkan::glslang-spirv - Vulkan::glslang-oglcompiler - Vulkan::glslang-osdependent - Vulkan::glslang-machineindependent - Vulkan::glslang-genericcodegen + # OGLCompiler library has been fully removed since version 14.0.0 + # OSDependent, MachineIndependent, and GenericCodeGen may also be removed in the future. + # See https://github.com/KhronosGroup/glslang/issues/3462 + $<TARGET_NAME_IF_EXISTS:Vulkan::glslang-oglcompiler> + $<TARGET_NAME_IF_EXISTS:Vulkan::glslang-osdependent> + $<TARGET_NAME_IF_EXISTS:Vulkan::glslang-machineindependent> + $<TARGET_NAME_IF_EXISTS:Vulkan::glslang-genericcodegen> ) endif() diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index b8a9459..2f2f0ea 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,7 +1,7 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 29) -set(CMake_VERSION_PATCH 20240207) +set(CMake_VERSION_PATCH 20240209) #set(CMake_VERSION_RC 0) set(CMake_VERSION_IS_DIRTY 0) diff --git a/Source/cmQtAutoGenGlobalInitializer.cxx b/Source/cmQtAutoGenGlobalInitializer.cxx index 5e2f99f..591c53e 100644 --- a/Source/cmQtAutoGenGlobalInitializer.cxx +++ b/Source/cmQtAutoGenGlobalInitializer.cxx @@ -49,7 +49,7 @@ cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer( bool globalAutoGenTarget = false; bool globalAutoRccTarget = false; { - cmMakefile* makefile = localGen->GetMakefile(); + cmMakefile const* makefile = localGen->GetMakefile(); // Detect global autogen target name if (makefile->IsOn("CMAKE_GLOBAL_AUTOGEN_TARGET")) { std::string targetName = @@ -118,7 +118,7 @@ cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer( target->GetSafeProperty(this->kw().AUTORCC_EXECUTABLE); // We support Qt4, Qt5 and Qt6 - auto qtVersion = + auto const qtVersion = cmQtAutoGenInitializer::GetQtVersion(target.get(), mocExec); bool const validQt = (qtVersion.first.Major == 4) || (qtVersion.first.Major == 5) || (qtVersion.first.Major == 6); @@ -167,7 +167,7 @@ void cmQtAutoGenGlobalInitializer::GetOrCreateGlobalTarget( { // Test if the target already exists if (localGen->FindGeneratorTargetToUse(name) == nullptr) { - cmMakefile* makefile = localGen->GetMakefile(); + cmMakefile const* makefile = localGen->GetMakefile(); // Create utility target auto cc = cm::make_unique<cmCustomCommand>(); @@ -192,9 +192,10 @@ void cmQtAutoGenGlobalInitializer::GetOrCreateGlobalTarget( void cmQtAutoGenGlobalInitializer::AddToGlobalAutoGen( cmLocalGenerator* localGen, std::string const& targetName) { - auto it = this->GlobalAutoGenTargets_.find(localGen); + auto const it = this->GlobalAutoGenTargets_.find(localGen); if (it != this->GlobalAutoGenTargets_.end()) { - cmGeneratorTarget* target = localGen->FindGeneratorTargetToUse(it->second); + cmGeneratorTarget const* target = + localGen->FindGeneratorTargetToUse(it->second); if (target != nullptr) { target->Target->AddUtility(targetName, false, localGen->GetMakefile()); } @@ -204,9 +205,10 @@ void cmQtAutoGenGlobalInitializer::AddToGlobalAutoGen( void cmQtAutoGenGlobalInitializer::AddToGlobalAutoRcc( cmLocalGenerator* localGen, std::string const& targetName) { - auto it = this->GlobalAutoRccTargets_.find(localGen); + auto const it = this->GlobalAutoRccTargets_.find(localGen); if (it != this->GlobalAutoRccTargets_.end()) { - cmGeneratorTarget* target = localGen->FindGeneratorTargetToUse(it->second); + cmGeneratorTarget const* target = + localGen->FindGeneratorTargetToUse(it->second); if (target != nullptr) { target->Target->AddUtility(targetName, false, localGen->GetMakefile()); } @@ -216,7 +218,7 @@ void cmQtAutoGenGlobalInitializer::AddToGlobalAutoRcc( cmQtAutoGen::ConfigStrings<cmQtAutoGen::CompilerFeaturesHandle> cmQtAutoGenGlobalInitializer::GetCompilerFeatures( std::string const& generator, cmQtAutoGen::ConfigString const& executable, - std::string& error, bool const isMultiConfig, bool UseBetterGraph) + std::string& error, bool const isMultiConfig, bool const UseBetterGraph) { cmQtAutoGen::ConfigStrings<cmQtAutoGen::CompilerFeaturesHandle> res; if (isMultiConfig && UseBetterGraph) { @@ -275,7 +277,7 @@ cmQtAutoGenGlobalInitializer::GetCompilerFeatures( // Check if we have cached features { - auto it = this->CompilerFeatures_.Default.find(executable.Default); + auto const it = this->CompilerFeatures_.Default.find(executable.Default); if (it != this->CompilerFeatures_.Default.end()) { res.Default = it->second; return res; diff --git a/Source/cmUVProcessChain.cxx b/Source/cmUVProcessChain.cxx index 0412f45..b787f19 100644 --- a/Source/cmUVProcessChain.cxx +++ b/Source/cmUVProcessChain.cxx @@ -337,6 +337,11 @@ void cmUVProcessChain::InternalData::SpawnProcess( arguments.push_back(nullptr); options.args = const_cast<char**>(arguments.data()); options.flags = UV_PROCESS_WINDOWS_HIDE; +#if UV_VERSION_MAJOR > 1 || \ + (UV_VERSION_MAJOR == 1 && UV_VERSION_MINOR >= 48) || \ + !defined(CMAKE_USE_SYSTEM_LIBUV) + options.flags |= UV_PROCESS_WINDOWS_FILE_PATH_EXACT_NAME; +#endif if (!this->Builder->WorkingDirectory.empty()) { options.cwd = this->Builder->WorkingDirectory.c_str(); } diff --git a/Tests/FindVulkan/CMakeLists.txt b/Tests/FindVulkan/CMakeLists.txt index 46ce1c6..d7c99ce 100644 --- a/Tests/FindVulkan/CMakeLists.txt +++ b/Tests/FindVulkan/CMakeLists.txt @@ -5,6 +5,7 @@ add_test(NAME FindVulkan.Test COMMAND "${CMake_BINARY_DIR}/Tests/FindVulkan/Test" ${build_generator_args} --build-project TestFindVulkan - --build-options ${build_options} + # Use --fresh to make testing multiple SDK versions on the same computer easier + --build-options ${build_options} --fresh --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION> ) diff --git a/Tests/FindVulkan/Test/Run-glslangValidator.cmake b/Tests/FindVulkan/Test/Run-glslangValidator.cmake index 27fd950..fd7867f 100644 --- a/Tests/FindVulkan/Test/Run-glslangValidator.cmake +++ b/Tests/FindVulkan/Test/Run-glslangValidator.cmake @@ -11,8 +11,10 @@ function(run_glslangValidator exe exe_display) message(SEND_ERROR "Result of ${exe_display} --help is ${result}, should be 1") endif() - if(NOT output MATCHES "^Usage: glslangValidator") - message(SEND_ERROR "Output of ${exe_display} --help is \"${output}\", should begin with \"Usage: glslangValidator\"") + # NOTE: Newer version prefer just "glslang" since it's no longer really just a validator. + # This approach is still compatible with older version that output glslangValidator + if(NOT output MATCHES "^Usage: glslang") + message(SEND_ERROR "Output of ${exe_display} --help is \"${output}\", should begin with \"Usage: glslang\"") endif() endfunction() diff --git a/Tests/RunCMake/Ninja/RunCMakeTest.cmake b/Tests/RunCMake/Ninja/RunCMakeTest.cmake index f020f0d..8b24c16 100644 --- a/Tests/RunCMake/Ninja/RunCMakeTest.cmake +++ b/Tests/RunCMake/Ninja/RunCMakeTest.cmake @@ -46,7 +46,8 @@ if(WIN32) if(RunCMake_MAKE_PROGRAM) set(maybe_MAKE_PROGRAM "-DRunCMake_MAKE_PROGRAM=${RunCMake_MAKE_PROGRAM}") endif() - run_cmake_script(ShowIncludes-437-ClangCl -DshowIncludes=${showIncludes} ${maybe_MAKE_PROGRAM}) + run_cmake_script(ShowIncludes-437-ClangCl-17 -DshowIncludes=${showIncludes} ${maybe_MAKE_PROGRAM}) + run_cmake_script(ShowIncludes-437-ClangCl-18 -DshowIncludes=${showIncludes} ${maybe_MAKE_PROGRAM}) run_cmake_script(ShowIncludes-437-English -DshowIncludes=${showIncludes} ${maybe_MAKE_PROGRAM}) run_cmake_script(ShowIncludes-437-French -DshowIncludes=${showIncludes} ${maybe_MAKE_PROGRAM}) run_cmake_script(ShowIncludes-437-German -DshowIncludes=${showIncludes} ${maybe_MAKE_PROGRAM}) diff --git a/Tests/RunCMake/Ninja/ShowIncludes-437-ClangCl-check.cmake b/Tests/RunCMake/Ninja/ShowIncludes-437-ClangCl-17-check.cmake index 6136463..3ebdb4f 100644 --- a/Tests/RunCMake/Ninja/ShowIncludes-437-ClangCl-check.cmake +++ b/Tests/RunCMake/Ninja/ShowIncludes-437-ClangCl-17-check.cmake @@ -1,3 +1,3 @@ -# 'clang-cl /showIncludes' prefix. +# 'clang-cl /showIncludes' prefix for clang-cl <= 17. set(expect "Note: including file: ") include(${CMAKE_CURRENT_LIST_DIR}/ShowIncludes-check.cmake) diff --git a/Tests/RunCMake/Ninja/ShowIncludes-437-ClangCl-stdout.txt b/Tests/RunCMake/Ninja/ShowIncludes-437-ClangCl-17-stdout.txt index bda7eab..bda7eab 100644 --- a/Tests/RunCMake/Ninja/ShowIncludes-437-ClangCl-stdout.txt +++ b/Tests/RunCMake/Ninja/ShowIncludes-437-ClangCl-17-stdout.txt diff --git a/Tests/RunCMake/Ninja/ShowIncludes-437-ClangCl.cmake b/Tests/RunCMake/Ninja/ShowIncludes-437-ClangCl-17.cmake index 7eca3d3..9642f06 100644 --- a/Tests/RunCMake/Ninja/ShowIncludes-437-ClangCl.cmake +++ b/Tests/RunCMake/Ninja/ShowIncludes-437-ClangCl-17.cmake @@ -1,3 +1,3 @@ set(CODEPAGE 437) -set(VSLANG "clang-cl") # Special case for test, not a real VS value. +set(VSLANG "clang-cl-17") # Special case for test, not a real VS value. include(${CMAKE_CURRENT_LIST_DIR}/ShowIncludes.cmake) diff --git a/Tests/RunCMake/Ninja/ShowIncludes-437-ClangCl-18-check.cmake b/Tests/RunCMake/Ninja/ShowIncludes-437-ClangCl-18-check.cmake new file mode 100644 index 0000000..a42af86 --- /dev/null +++ b/Tests/RunCMake/Ninja/ShowIncludes-437-ClangCl-18-check.cmake @@ -0,0 +1,3 @@ +# 'clang-cl /showIncludes' prefix for clang-cl >= 18. +set(expect "Note: including file: ") +include(${CMAKE_CURRENT_LIST_DIR}/ShowIncludes-check.cmake) diff --git a/Tests/RunCMake/Ninja/ShowIncludes-437-ClangCl-18-stdout.txt b/Tests/RunCMake/Ninja/ShowIncludes-437-ClangCl-18-stdout.txt new file mode 100644 index 0000000..bda7eab --- /dev/null +++ b/Tests/RunCMake/Ninja/ShowIncludes-437-ClangCl-18-stdout.txt @@ -0,0 +1 @@ +-- showIncludes='Note: including file: ' diff --git a/Tests/RunCMake/Ninja/ShowIncludes-437-ClangCl-18.cmake b/Tests/RunCMake/Ninja/ShowIncludes-437-ClangCl-18.cmake new file mode 100644 index 0000000..997ffb9 --- /dev/null +++ b/Tests/RunCMake/Ninja/ShowIncludes-437-ClangCl-18.cmake @@ -0,0 +1,3 @@ +set(CODEPAGE 437) +set(VSLANG "clang-cl-18") # Special case for test, not a real VS value. +include(${CMAKE_CURRENT_LIST_DIR}/ShowIncludes.cmake) diff --git a/Tests/RunCMake/showIncludes.c b/Tests/RunCMake/showIncludes.c index 5114965..3859049 100644 --- a/Tests/RunCMake/showIncludes.c +++ b/Tests/RunCMake/showIncludes.c @@ -28,14 +28,22 @@ int main(void) printf("OEM code page: %u\n", GetOEMCP()); printf("VSLANG: %s\n", vslang); - // clang-cl (special case for test, not a real VS value). - if (strcmp(vslang, "clang-cl") == 0) { + // clang-cl <= 17 (special case for test, not a real VS value). + if (strcmp(vslang, "clang-cl-17") == 0) { if (cp == 437 || cp == 65001) { printf("Note: including file: ./foo.h\n"); return 0; } } + // clang-cl >= 18 (special case for test, not a real VS value). + if (strcmp(vslang, "clang-cl-18") == 0) { + if (cp == 437 || cp == 65001) { + printf("Note: including file: .\\\\foo.h\n"); + return 0; + } + } + // msvc-wine (special case for test, not a real VS value). if (strcmp(vslang, "msvc-wine") == 0) { if (cp == 437 || cp == 65001) { diff --git a/Utilities/cmlibuv/include/uv.h b/Utilities/cmlibuv/include/uv.h index ffe34ec..42e3446 100644 --- a/Utilities/cmlibuv/include/uv.h +++ b/Utilities/cmlibuv/include/uv.h @@ -1080,7 +1080,14 @@ enum uv_process_flags { * option is only meaningful on Windows systems. On Unix it is silently * ignored. */ - UV_PROCESS_WINDOWS_HIDE_GUI = (1 << 6) + UV_PROCESS_WINDOWS_HIDE_GUI = (1 << 6), + /* + * On Windows, if the path to the program to execute, specified in + * uv_process_options_t's file field, has a directory component, + * search for the exact file name before trying variants with + * extensions like '.exe' or '.cmd'. + */ + UV_PROCESS_WINDOWS_FILE_PATH_EXACT_NAME = (1 << 7) }; /* diff --git a/Utilities/cmlibuv/src/unix/process.c b/Utilities/cmlibuv/src/unix/process.c index 30872cf..39ec451 100644 --- a/Utilities/cmlibuv/src/unix/process.c +++ b/Utilities/cmlibuv/src/unix/process.c @@ -1008,6 +1008,7 @@ int uv_spawn(uv_loop_t* loop, assert(!(options->flags & ~(UV_PROCESS_DETACHED | UV_PROCESS_SETGID | UV_PROCESS_SETUID | + UV_PROCESS_WINDOWS_FILE_PATH_EXACT_NAME | UV_PROCESS_WINDOWS_HIDE | UV_PROCESS_WINDOWS_HIDE_CONSOLE | UV_PROCESS_WINDOWS_HIDE_GUI | diff --git a/Utilities/cmlibuv/src/win/process.c b/Utilities/cmlibuv/src/win/process.c index 7df3540..11cf5b2 100644 --- a/Utilities/cmlibuv/src/win/process.c +++ b/Utilities/cmlibuv/src/win/process.c @@ -329,10 +329,9 @@ static WCHAR* path_search_walk_ext(const WCHAR *dir, * - If there's really only a filename, check the current directory for file, * then search all path directories. * - * - If a full path is specified, search for the exact filename first. - * - * - If filename specified has *any* extension, search for the file with the - * specified extension first. + * - If filename specified has *any* extension, or already contains a path + * and the UV_PROCESS_WINDOWS_FILE_PATH_EXACT_NAME flag is specified, + * search for the file with the exact specified filename first. * * - If the literal filename is not found in a directory, try *appending* * (not replacing) .com first and then .exe. @@ -358,7 +357,8 @@ static WCHAR* path_search_walk_ext(const WCHAR *dir, */ static WCHAR* search_path(const WCHAR *file, WCHAR *cwd, - const WCHAR *path) { + const WCHAR *path, + unsigned int flags) { int file_has_dir; WCHAR* result = NULL; WCHAR *file_name_start; @@ -394,14 +394,12 @@ static WCHAR* search_path(const WCHAR *file, name_has_ext = (dot != NULL && dot[1] != L'\0'); if (file_has_dir) { - /* The file has a path inside, don't use path - * Try the exact filename first, and then try standard extensions - */ + /* The file has a path inside, don't use path */ result = path_search_walk_ext( file, file_name_start - file, file_name_start, file_len - (file_name_start - file), cwd, cwd_len, - 1); + name_has_ext || (flags & UV_PROCESS_WINDOWS_FILE_PATH_EXACT_NAME)); } else { dir_end = path; @@ -991,6 +989,7 @@ int uv_spawn(uv_loop_t* loop, assert(!(options->flags & ~(UV_PROCESS_DETACHED | UV_PROCESS_SETGID | UV_PROCESS_SETUID | + UV_PROCESS_WINDOWS_FILE_PATH_EXACT_NAME | UV_PROCESS_WINDOWS_HIDE | UV_PROCESS_WINDOWS_HIDE_CONSOLE | UV_PROCESS_WINDOWS_HIDE_GUI | @@ -1070,7 +1069,8 @@ int uv_spawn(uv_loop_t* loop, application_path = search_path(application, cwd, - path); + path, + options->flags); if (application_path == NULL) { /* Not found. */ err = ERROR_FILE_NOT_FOUND; |