diff options
256 files changed, 2024 insertions, 832 deletions
diff --git a/Help/command/FIND_XXX.txt b/Help/command/FIND_XXX.txt index 38c231a..73dbd57 100644 --- a/Help/command/FIND_XXX.txt +++ b/Help/command/FIND_XXX.txt @@ -137,7 +137,7 @@ If ``NO_DEFAULT_PATH`` is not specified, the search process is as follows: .. |FIND_ARGS_XXX| replace:: <VAR> NAMES name -On OS X the :variable:`CMAKE_FIND_FRAMEWORK` and +On macOS the :variable:`CMAKE_FIND_FRAMEWORK` and :variable:`CMAKE_FIND_APPBUNDLE` variables determine the order of preference between Apple-style and unix-style package components. diff --git a/Help/command/add_library.rst b/Help/command/add_library.rst index b7ba724..c4c512c 100644 --- a/Help/command/add_library.rst +++ b/Help/command/add_library.rst @@ -35,7 +35,7 @@ variable :variable:`BUILD_SHARED_LIBS` is ``ON``. For ``SHARED`` and ``MODULE`` libraries the :prop_tgt:`POSITION_INDEPENDENT_CODE` target property is set to ``ON`` automatically. A ``SHARED`` or ``STATIC`` library may be marked with the :prop_tgt:`FRAMEWORK` -target property to create an OS X Framework. +target property to create an macOS Framework. If a library does not export any symbols, it must not be declared as a ``SHARED`` library. For example, a Windows resource DLL or a managed C++/CLI diff --git a/Help/command/cmake_host_system_information.rst b/Help/command/cmake_host_system_information.rst index 9893151..2dee93a 100644 --- a/Help/command/cmake_host_system_information.rst +++ b/Help/command/cmake_host_system_information.rst @@ -20,10 +20,10 @@ Key Description ``NUMBER_OF_PHYSICAL_CORES`` Number of physical cores ``HOSTNAME`` Hostname ``FQDN`` Fully qualified domain name -``TOTAL_VIRTUAL_MEMORY`` Total virtual memory in megabytes -``AVAILABLE_VIRTUAL_MEMORY`` Available virtual memory in megabytes -``TOTAL_PHYSICAL_MEMORY`` Total physical memory in megabytes -``AVAILABLE_PHYSICAL_MEMORY`` Available physical memory in megabytes +``TOTAL_VIRTUAL_MEMORY`` Total virtual memory in MiB [#mebibytes]_ +``AVAILABLE_VIRTUAL_MEMORY`` Available virtual memory in MiB [#mebibytes]_ +``TOTAL_PHYSICAL_MEMORY`` Total physical memory in MiB [#mebibytes]_ +``AVAILABLE_PHYSICAL_MEMORY`` Available physical memory in MiB [#mebibytes]_ ``IS_64BIT`` One if processor is 64Bit ``HAS_FPU`` One if processor has floating point unit ``HAS_MMX`` One if processor supports MMX instructions @@ -44,3 +44,7 @@ Key Description ``OS_VERSION`` The OS build ID ``OS_PLATFORM`` See :variable:`CMAKE_HOST_SYSTEM_PROCESSOR` ============================= ================================================ + +.. rubric:: Footnotes + +.. [#mebibytes] One MiB (mebibyte) is equal to 1024x1024 bytes. diff --git a/Help/command/find_package.rst b/Help/command/find_package.rst index bbe8c4d..b486b79 100644 --- a/Help/command/find_package.rst +++ b/Help/command/find_package.rst @@ -216,7 +216,7 @@ Each entry is meant for installation trees following Windows (W), UNIX <prefix>/<name>*/(lib/<arch>|lib*|share)/<name>*/ (W/U) <prefix>/<name>*/(lib/<arch>|lib*|share)/<name>*/(cmake|CMake)/ (W/U) -On systems supporting OS X Frameworks and Application Bundles the +On systems supporting macOS Frameworks and Application Bundles the following directories are searched for frameworks or bundles containing a configuration file:: diff --git a/Help/command/if.rst b/Help/command/if.rst index f04f233..5294ce8 100644 --- a/Help/command/if.rst +++ b/Help/command/if.rst @@ -148,23 +148,33 @@ Possible expressions are: ``if(<variable|string> VERSION_LESS <variable|string>)`` Component-wise integer version number comparison (version format is - ``major[.minor[.patch[.tweak]]]``). + ``major[.minor[.patch[.tweak]]]``, omitted components are treated as zero). + Any non-integer version component or non-integer trailing part of a version + component effectively truncates the string at that point. ``if(<variable|string> VERSION_GREATER <variable|string>)`` Component-wise integer version number comparison (version format is - ``major[.minor[.patch[.tweak]]]``). + ``major[.minor[.patch[.tweak]]]``, omitted components are treated as zero). + Any non-integer version component or non-integer trailing part of a version + component effectively truncates the string at that point. ``if(<variable|string> VERSION_EQUAL <variable|string>)`` Component-wise integer version number comparison (version format is - ``major[.minor[.patch[.tweak]]]``). + ``major[.minor[.patch[.tweak]]]``, omitted components are treated as zero). + Any non-integer version component or non-integer trailing part of a version + component effectively truncates the string at that point. ``if(<variable|string> VERSION_LESS_EQUAL <variable|string>)`` Component-wise integer version number comparison (version format is - ``major[.minor[.patch[.tweak]]]``). + ``major[.minor[.patch[.tweak]]]``, omitted components are treated as zero). + Any non-integer version component or non-integer trailing part of a version + component effectively truncates the string at that point. ``if(<variable|string> VERSION_GREATER_EQUAL <variable|string>)`` Component-wise integer version number comparison (version format is - ``major[.minor[.patch[.tweak]]]``). + ``major[.minor[.patch[.tweak]]]``, omitted components are treated as zero). + Any non-integer version component or non-integer trailing part of a version + component effectively truncates the string at that point. ``if(<variable|string> IN_LIST <variable>)`` True if the given element is contained in the named list variable. diff --git a/Help/command/install.rst b/Help/command/install.rst index 8b2a971..3a2b4da 100644 --- a/Help/command/install.rst +++ b/Help/command/install.rst @@ -115,19 +115,19 @@ project. There are several kinds of target files that may be installed: ``ARCHIVE`` Static libraries are treated as ``ARCHIVE`` targets, except those - marked with the ``FRAMEWORK`` property on OS X (see ``FRAMEWORK`` + marked with the ``FRAMEWORK`` property on macOS (see ``FRAMEWORK`` below.) For DLL platforms (all Windows-based systems including Cygwin), the DLL import library is treated as an ``ARCHIVE`` target. ``LIBRARY`` Module libraries are always treated as ``LIBRARY`` targets. For non- DLL platforms shared libraries are treated as ``LIBRARY`` targets, - except those marked with the ``FRAMEWORK`` property on OS X (see + except those marked with the ``FRAMEWORK`` property on macOS (see ``FRAMEWORK`` below.) ``RUNTIME`` Executables are treated as ``RUNTIME`` objects, except those marked - with the ``MACOSX_BUNDLE`` property on OS X (see ``BUNDLE`` below.) + with the ``MACOSX_BUNDLE`` property on macOS (see ``BUNDLE`` below.) For DLL platforms (all Windows-based systems including Cygwin), the DLL part of a shared library is treated as a ``RUNTIME`` target. @@ -137,11 +137,11 @@ project. There are several kinds of target files that may be installed: ``FRAMEWORK`` Both static and shared libraries marked with the ``FRAMEWORK`` - property are treated as ``FRAMEWORK`` targets on OS X. + property are treated as ``FRAMEWORK`` targets on macOS. ``BUNDLE`` Executables marked with the ``MACOSX_BUNDLE`` property are treated as - ``BUNDLE`` targets on OS X. + ``BUNDLE`` targets on macOS. ``PUBLIC_HEADER`` Any ``PUBLIC_HEADER`` files associated with a library are installed in diff --git a/Help/command/set_directory_properties.rst b/Help/command/set_directory_properties.rst index e485fce..42e7fd7 100644 --- a/Help/command/set_directory_properties.rst +++ b/Help/command/set_directory_properties.rst @@ -1,12 +1,11 @@ set_directory_properties ------------------------ -Set a property of the directory. +Set properties of the current directory and subdirectories in key-value pairs. :: set_directory_properties(PROPERTIES prop1 value1 prop2 value2) -Set a property for the current directory and subdirectories. See -:ref:`Directory Properties` for the list of properties known -to CMake. +See :ref:`Directory Properties` for the list of properties known to CMake +and their individual documentation for the behavior of each property. diff --git a/Help/command/target_link_libraries.rst b/Help/command/target_link_libraries.rst index 1f0d69e..e1c374e 100644 --- a/Help/command/target_link_libraries.rst +++ b/Help/command/target_link_libraries.rst @@ -18,10 +18,13 @@ All of them have the general form:: target_link_libraries(<target> ... <item>... ...) -The named ``<target>`` must have been created in the current directory by -a command such as :command:`add_executable` or :command:`add_library` and -must not be an :ref:`ALIAS target <Alias Targets>`. -Repeated calls for the same ``<target>`` append items in the order called. +The named ``<target>`` must have been created by a command such as +:command:`add_executable` or :command:`add_library` and must not be an +:ref:`ALIAS target <Alias Targets>`. If policy :policy:`CMP0079` is not +set to ``NEW`` then the target must have been created in the current +directory. Repeated calls for the same ``<target>`` append items in +the order called. + Each ``<item>`` may be: * **A library target name**: The generated link line will have the diff --git a/Help/cpack_gen/bundle.rst b/Help/cpack_gen/bundle.rst index 4628968..29727e2 100644 --- a/Help/cpack_gen/bundle.rst +++ b/Help/cpack_gen/bundle.rst @@ -1,14 +1,14 @@ CPack Bundle Generator ---------------------- -CPack Bundle generator (Mac OS X) specific options +CPack Bundle generator (macOS) specific options Variables specific to CPack Bundle generator ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Installers built on Mac OS X using the Bundle generator use the -aforementioned DragNDrop (CPACK_DMG_xxx) variables, plus the following -Bundle-specific parameters (CPACK_BUNDLE_xxx). +Installers built on macOS using the Bundle generator use the +aforementioned DragNDrop (``CPACK_DMG_xxx``) variables, plus the following +Bundle-specific parameters (``CPACK_BUNDLE_xxx``). .. variable:: CPACK_BUNDLE_NAME @@ -25,7 +25,7 @@ Bundle-specific parameters (CPACK_BUNDLE_xxx). Path to an OSX icon file that will be used as the icon for the generated bundle. This is the icon that appears in the OSX finder for the bundle, and - in the OSX dock when the bundle is opened. Required. + in the OSX dock when the bundle is opened. Required. .. variable:: CPACK_BUNDLE_STARTUP_COMMAND @@ -36,13 +36,13 @@ Bundle-specific parameters (CPACK_BUNDLE_xxx). .. variable:: CPACK_BUNDLE_APPLE_CERT_APP The name of your Apple supplied code signing certificate for the application. - The name usually takes the form "Developer ID Application: [Name]" or - "3rd Party Mac Developer Application: [Name]". If this variable is not set + The name usually takes the form ``Developer ID Application: [Name]`` or + ``3rd Party Mac Developer Application: [Name]``. If this variable is not set the application will not be signed. .. variable:: CPACK_BUNDLE_APPLE_ENTITLEMENTS - The name of the plist file that contains your apple entitlements for sandboxing + The name of the ``Plist`` file that contains your apple entitlements for sandboxing your application. This file is required for submission to the Mac App Store. .. variable:: CPACK_BUNDLE_APPLE_CODESIGN_FILES @@ -53,12 +53,12 @@ Bundle-specific parameters (CPACK_BUNDLE_xxx). .. variable:: CPACK_BUNDLE_APPLE_CODESIGN_PARAMETER - Additional parameter that will passed to codesign. - Default value: "--deep -f" + Additional parameter that will passed to ``codesign``. + Default value: ``--deep -f`` .. variable:: CPACK_COMMAND_CODESIGN - Path to the codesign(1) command used to sign applications with an + Path to the ``codesign(1)`` command used to sign applications with an Apple cert. This variable can be used to override the automatically detected command (or specify its location if the auto-detection fails - to find it.) + to find it). diff --git a/Help/cpack_gen/dmg.rst b/Help/cpack_gen/dmg.rst index e4482ef..b7b3a0a 100644 --- a/Help/cpack_gen/dmg.rst +++ b/Help/cpack_gen/dmg.rst @@ -1,13 +1,13 @@ CPack DMG Generator ------------------- -DragNDrop CPack generator (Mac OS X). +DragNDrop CPack generator (macOS). Variables specific to CPack DragNDrop generator ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The following variables are specific to the DragNDrop installers built -on Mac OS X: +on macOS: .. variable:: CPACK_DMG_VOLUME_NAME @@ -16,33 +16,33 @@ on Mac OS X: .. variable:: CPACK_DMG_FORMAT - The disk image format. Common values are UDRO (UDIF read-only), UDZO (UDIF - zlib-compressed) or UDBZ (UDIF bzip2-compressed). Refer to hdiutil(1) for - more information on other available formats. Defaults to UDZO. + The disk image format. Common values are ``UDRO`` (UDIF read-only), ``UDZO`` (UDIF + zlib-compressed) or ``UDBZ`` (UDIF bzip2-compressed). Refer to ``hdiutil(1)`` for + more information on other available formats. Defaults to ``UDZO``. .. variable:: CPACK_DMG_DS_STORE - Path to a custom DS_Store file. This .DS_Store file e.g. can be used to + Path to a custom ``.DS_Store`` file. This ``.DS_Store`` file can be used to specify the Finder window position/geometry and layout (such as hidden toolbars, placement of the icons etc.). This file has to be generated by the Finder (either manually or through AppleScript) using a normal folder - from which the .DS_Store file can then be extracted. + from which the ``.DS_Store`` file can then be extracted. .. variable:: CPACK_DMG_DS_STORE_SETUP_SCRIPT Path to a custom AppleScript file. This AppleScript is used to generate - a .DS_Store file which specifies the Finder window position/geometry and + a ``.DS_Store`` file which specifies the Finder window position/geometry and layout (such as hidden toolbars, placement of the icons etc.). By specifying a custom AppleScript there is no need to use - CPACK_DMG_DS_STORE, as the .DS_Store that is generated by the AppleScript + ``CPACK_DMG_DS_STORE``, as the ``.DS_Store`` that is generated by the AppleScript will be packaged. .. variable:: CPACK_DMG_BACKGROUND_IMAGE Path to an image file to be used as the background. This file will be - copied to .background/background.<ext>, where ext is the original image file + copied to ``.background``/``background.<ext>``, where ``<ext>`` is the original image file extension. The background image is installed into the image before - CPACK_DMG_DS_STORE_SETUP_SCRIPT is executed or CPACK_DMG_DS_STORE is + ``CPACK_DMG_DS_STORE_SETUP_SCRIPT`` is executed or ``CPACK_DMG_DS_STORE`` is installed. By default no background image is set. .. variable:: CPACK_DMG_DISABLE_APPLICATIONS_SYMLINK @@ -83,19 +83,19 @@ on Mac OS X: .. variable:: CPACK_COMMAND_HDIUTIL - Path to the hdiutil(1) command used to operate on disk image files on Mac - OS X. This variable can be used to override the automatically detected - command (or specify its location if the auto-detection fails to find it.) + Path to the ``hdiutil(1)`` command used to operate on disk image files on + macOS. This variable can be used to override the automatically detected + command (or specify its location if the auto-detection fails to find it). .. variable:: CPACK_COMMAND_SETFILE - Path to the SetFile(1) command used to set extended attributes on files and - directories on Mac OS X. This variable can be used to override the + Path to the ``SetFile(1)`` command used to set extended attributes on files and + directories on macOS. This variable can be used to override the automatically detected command (or specify its location if the - auto-detection fails to find it.) + auto-detection fails to find it). .. variable:: CPACK_COMMAND_REZ - Path to the Rez(1) command used to compile resources on Mac OS X. This + Path to the ``Rez(1)`` command used to compile resources on macOS. This variable can be used to override the automatically detected command (or - specify its location if the auto-detection fails to find it.) + specify its location if the auto-detection fails to find it). diff --git a/Help/cpack_gen/ifw.rst b/Help/cpack_gen/ifw.rst index 68776e1..e43b1d6 100644 --- a/Help/cpack_gen/ifw.rst +++ b/Help/cpack_gen/ifw.rst @@ -17,7 +17,7 @@ and meta information for QtIFW_ tools. The QtIFW_ provides a set of tools and utilities to create installers for the supported desktop Qt platforms: Linux, Microsoft Windows, -and Mac OS X. +and macOS. You should also install QtIFW_ to use CPack ``IFW`` generator. @@ -107,7 +107,7 @@ Package .. variable:: CPACK_IFW_PACKAGE_ICON - Filename for a custom installer icon. The actual file is '.icns' (Mac OS X), + Filename for a custom installer icon. The actual file is '.icns' (macOS), '.ico' (Windows). No functionality on Unix. .. variable:: CPACK_IFW_PACKAGE_WINDOW_ICON diff --git a/Help/cpack_gen/packagemaker.rst b/Help/cpack_gen/packagemaker.rst index f9abdd8..e9464b7 100644 --- a/Help/cpack_gen/packagemaker.rst +++ b/Help/cpack_gen/packagemaker.rst @@ -1,23 +1,23 @@ CPack PackageMaker Generator ---------------------------- -PackageMaker CPack generator (Mac OS X). +PackageMaker CPack generator (macOS). Variables specific to CPack PackageMaker generator ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The following variable is specific to installers built on Mac -OS X using PackageMaker: +macOS using PackageMaker: .. variable:: CPACK_OSX_PACKAGE_VERSION - The version of Mac OS X that the resulting PackageMaker archive should be - compatible with. Different versions of Mac OS X support different + The version of macOS that the resulting PackageMaker archive should be + compatible with. Different versions of macOS support different features. For example, CPack can only build component-based installers for - Mac OS X 10.4 or newer, and can only build installers that download - component son-the-fly for Mac OS X 10.5 or newer. If left blank, this value - will be set to the minimum version of Mac OS X that supports the requested + macOS 10.4 or newer, and can only build installers that download + component son-the-fly for macOS 10.5 or newer. If left blank, this value + will be set to the minimum version of macOS that supports the requested features. Set this variable to some value (e.g., 10.4) only if you want to - guarantee that your installer will work on that version of Mac OS X, and + guarantee that your installer will work on that version of macOS, and don't mind missing extra features available in the installer shipping with - later versions of Mac OS X. + later versions of macOS. diff --git a/Help/cpack_gen/productbuild.rst b/Help/cpack_gen/productbuild.rst index 1a6e0f8..d22fcd4 100644 --- a/Help/cpack_gen/productbuild.rst +++ b/Help/cpack_gen/productbuild.rst @@ -1,20 +1,20 @@ CPack productbuild Generator ---------------------------- -productbuild CPack generator (Mac OS X). +productbuild CPack generator (macOS). Variables specific to CPack productbuild generator ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The following variable is specific to installers built on Mac -OS X using ProductBuild: +macOS using ProductBuild: .. variable:: CPACK_COMMAND_PRODUCTBUILD - Path to the productbuild(1) command used to generate a product archive for - the OS X Installer or Mac App Store. This variable can be used to override + Path to the ``productbuild(1)`` command used to generate a product archive for + the macOS Installer or Mac App Store. This variable can be used to override the automatically detected command (or specify its location if the - auto-detection fails to find it.) + auto-detection fails to find it). .. variable:: CPACK_PRODUCTBUILD_IDENTITY_NAME @@ -28,9 +28,9 @@ OS X using ProductBuild: .. variable:: CPACK_COMMAND_PKGBUILD - Path to the pkgbuild(1) command used to generate an OS X component package - on OS X. This variable can be used to override the automatically detected - command (or specify its location if the auto-detection fails to find it.) + Path to the ``pkgbuild(1)`` command used to generate an macOS component package + on macOS. This variable can be used to override the automatically detected + command (or specify its location if the auto-detection fails to find it). .. variable:: CPACK_PKGBUILD_IDENTITY_NAME diff --git a/Help/envvar/CMAKE_OSX_ARCHITECTURES.rst b/Help/envvar/CMAKE_OSX_ARCHITECTURES.rst index 8bbf993..5fd6e52 100644 --- a/Help/envvar/CMAKE_OSX_ARCHITECTURES.rst +++ b/Help/envvar/CMAKE_OSX_ARCHITECTURES.rst @@ -1,7 +1,7 @@ CMAKE_OSX_ARCHITECTURES ----------------------- -Target specific architectures for OS X. +Target specific architectures for macOS. The ``CMAKE_OSX_ARCHITECTURES`` environment variable sets the default value for the :variable:`CMAKE_OSX_ARCHITECTURES` variable. See diff --git a/Help/envvar/MACOSX_DEPLOYMENT_TARGET.rst b/Help/envvar/MACOSX_DEPLOYMENT_TARGET.rst index e6051b4..9dafa32 100644 --- a/Help/envvar/MACOSX_DEPLOYMENT_TARGET.rst +++ b/Help/envvar/MACOSX_DEPLOYMENT_TARGET.rst @@ -1,7 +1,7 @@ MACOSX_DEPLOYMENT_TARGET ------------------------ -Specify the minimum version of OS X on which the target binaries are +Specify the minimum version of macOS on which the target binaries are to be deployed. The ``MACOSX_DEPLOYMENT_TARGET`` environment variable sets the default value for diff --git a/Help/manual/OPTIONS_BUILD.txt b/Help/manual/OPTIONS_BUILD.txt index 33d27af..baa73d5 100644 --- a/Help/manual/OPTIONS_BUILD.txt +++ b/Help/manual/OPTIONS_BUILD.txt @@ -1,3 +1,11 @@ +``-S <path-to-source>`` + Path to root directory of the CMake project to build. + +``-B <path-to-build>`` + Path to directory which CMake will use as the root of build directory. + + If the directory doesn't already exist CMake will make it. + ``-C <initial-cache>`` Pre-load a script to populate the cache. diff --git a/Help/manual/cmake-buildsystem.7.rst b/Help/manual/cmake-buildsystem.7.rst index dd7934a..4fc484b 100644 --- a/Help/manual/cmake-buildsystem.7.rst +++ b/Help/manual/cmake-buildsystem.7.rst @@ -95,7 +95,7 @@ Apple Frameworks """""""""""""""" A ``SHARED`` library may be marked with the :prop_tgt:`FRAMEWORK` -target property to create an OS X or iOS Framework Bundle. +target property to create an macOS or iOS Framework Bundle. The ``MACOSX_FRAMEWORK_IDENTIFIER`` sets ``CFBundleIdentifier`` key and it uniquely identifies the bundle. diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst index 8fd07d7..76fd3d9 100644 --- a/Help/manual/cmake-generator-expressions.7.rst +++ b/Help/manual/cmake-generator-expressions.7.rst @@ -51,7 +51,7 @@ Available logical expressions are: ``0`` if all ``?`` are ``0``, else ``1`` ``$<NOT:?>`` ``0`` if ``?`` is ``1``, else ``1`` -``$<IF:?,true-value...,false-value...>``` +``$<IF:?,true-value...,false-value...>`` ``true-value...`` if ``?`` is ``1``, ``false-value...`` if ``?`` is ``0`` ``$<STREQUAL:a,b>`` ``1`` if ``a`` is STREQUAL ``b``, else ``0`` @@ -68,10 +68,13 @@ Available logical expressions are: target. ``$<PLATFORM_ID:comp>`` ``1`` if the CMake-id of the platform matches ``comp``, otherwise ``0``. + See also the :variable:`CMAKE_SYSTEM_NAME` variable. ``$<C_COMPILER_ID:comp>`` ``1`` if the CMake-id of the C compiler matches ``comp``, otherwise ``0``. + See also the :variable:`CMAKE_<LANG>_COMPILER_ID` variable. ``$<CXX_COMPILER_ID:comp>`` ``1`` if the CMake-id of the CXX compiler matches ``comp``, otherwise ``0``. + See also the :variable:`CMAKE_<LANG>_COMPILER_ID` variable. ``$<VERSION_LESS:v1,v2>`` ``1`` if ``v1`` is a version less than ``v2``, else ``0``. ``$<VERSION_GREATER:v1,v2>`` @@ -84,8 +87,10 @@ Available logical expressions are: ``1`` if ``v1`` is a version greater than or equal to ``v2``, else ``0``. ``$<C_COMPILER_VERSION:ver>`` ``1`` if the version of the C compiler matches ``ver``, otherwise ``0``. + See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable. ``$<CXX_COMPILER_VERSION:ver>`` ``1`` if the version of the CXX compiler matches ``ver``, otherwise ``0``. + See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable. ``$<TARGET_POLICY:pol>`` ``1`` if the policy ``pol`` was NEW when the 'head' target was created, else ``0``. If the policy was not set, the warning message for the policy diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst index 32a0118..8ecca4d 100644 --- a/Help/manual/cmake-policies.7.rst +++ b/Help/manual/cmake-policies.7.rst @@ -57,6 +57,7 @@ Policies Introduced by CMake 3.13 .. toctree:: :maxdepth: 1 + CMP0079: target_link_libraries allows use with targets in other directories. </policy/CMP0079> CMP0078: UseSWIG generates standard target names. </policy/CMP0078> CMP0077: option() honors normal variables. </policy/CMP0077> CMP0076: target_sources() command converts relative paths to absolute. </policy/CMP0076> diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 3eea8a2..6071999 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -24,6 +24,7 @@ Variables that Provide Information /variable/CMAKE_CACHE_PATCH_VERSION /variable/CMAKE_CFG_INTDIR /variable/CMAKE_COMMAND + /variable/CMAKE_CPACK_COMMAND /variable/CMAKE_CROSSCOMPILING /variable/CMAKE_CROSSCOMPILING_EMULATOR /variable/CMAKE_CTEST_COMMAND @@ -77,6 +78,7 @@ Variables that Provide Information /variable/CMAKE_PROJECT_VERSION_TWEAK /variable/CMAKE_RANLIB /variable/CMAKE_ROOT + /variable/CMAKE_RULE_MESSAGES /variable/CMAKE_SCRIPT_MODE_FILE /variable/CMAKE_SHARED_LIBRARY_PREFIX /variable/CMAKE_SHARED_LIBRARY_SUFFIX diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst index 00d95ce..b11526c 100644 --- a/Help/manual/cmake.1.rst +++ b/Help/manual/cmake.1.rst @@ -9,6 +9,7 @@ Synopsis .. parsed-literal:: cmake [<options>] {<path-to-source> | <path-to-existing-build>} + cmake [<options>] -S <path-to-source> -B <path-to-build> cmake [{-D <var>=<value>}...] -P <cmake-script-file> cmake --build <dir> [<options>...] [-- <build-tool-options>...] cmake --open <dir> diff --git a/Help/policy/CMP0079.rst b/Help/policy/CMP0079.rst new file mode 100644 index 0000000..0244d6c --- /dev/null +++ b/Help/policy/CMP0079.rst @@ -0,0 +1,40 @@ +CMP0079 +------- + +:command:`target_link_libraries` allows use with targets in other directories. + +Prior to CMake 3.13 the :command:`target_link_libraries` command did not +accept targets not created in the calling directory as its first argument +for calls that update the :prop_tgt:`LINK_LIBRARIES` of the target itself. +It did accidentally accept targets from other directories on calls that +only update the :prop_tgt:`INTERFACE_LINK_LIBRARIES`, but would simply +add entries to the property as if the call were made in the original +directory. Thus link interface libraries specified this way were always +looked up by generators in the scope of the original target rather than +in the scope that called :command:`target_link_libraries`. + +CMake 3.13 now allows the :command:`target_link_libraries` command to +be called from any directory to add link dependencies and link interface +libraries to targets created in other directories. The entries are added +to :prop_tgt:`LINK_LIBRARIES` and :prop_tgt:`INTERFACE_LINK_LIBRARIES` +using a special (internal) suffix to tell the generators to look up the +names in the calling scope rather than the scope that created the target. + +This policy provides compatibility with projects that already use +:command:`target_link_libraries` with the ``INTERFACE`` keyword +on a target in another directory to add :prop_tgt:`INTERFACE_LINK_LIBRARIES` +entries to be looked up in the target's directory. Such projects should +be updated to be aware of the new scoping rules in that case. + +The ``OLD`` behavior of this policy is to disallow +:command:`target_link_libraries` calls naming targets from another directory +except in the previously accidentally allowed case of using the ``INTERFACE`` +keyword only. The ``NEW`` behavior of this policy is to allow all such +calls but use the new scoping rules. + +This policy was introduced in CMake version 3.13. CMake version +|release| warns when the policy is not set and uses ``OLD`` behavior. +Use the :command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` +explicitly. + +.. include:: DEPRECATED.txt diff --git a/Help/prop_dir/INCLUDE_DIRECTORIES.rst b/Help/prop_dir/INCLUDE_DIRECTORIES.rst index 6789a56..5d856b8 100644 --- a/Help/prop_dir/INCLUDE_DIRECTORIES.rst +++ b/Help/prop_dir/INCLUDE_DIRECTORIES.rst @@ -11,11 +11,17 @@ target property, which is used by the generators to set the include directories for the compiler. In addition to accepting values from that command, values may be set -directly on any directory using the :command:`set_property` command. A -directory gets its initial value from its parent directory if it has one. -The initial value of the :prop_tgt:`INCLUDE_DIRECTORIES` target property +directly on any directory using the :command:`set_property` command, and can be +set on the current directory using the :command:`set_directory_properties` +command. A directory gets its initial value from its parent directory if it has +one. The initial value of the :prop_tgt:`INCLUDE_DIRECTORIES` target property comes from the value of this property. Both directory and target property values are adjusted by calls to the :command:`include_directories` command. +Calls to :command:`set_property` or :command:`set_directory_properties`, +however, will update the directory property value without updating target +property values. Therefore direct property updates must be made before +calls to :command:`add_executable` or :command:`add_library` for targets +they are meant to affect. The target property values are used by the generators to set the include paths for the compiler. diff --git a/Help/prop_gbl/RULE_MESSAGES.rst b/Help/prop_gbl/RULE_MESSAGES.rst index 87a5ca6..a9734a7 100644 --- a/Help/prop_gbl/RULE_MESSAGES.rst +++ b/Help/prop_gbl/RULE_MESSAGES.rst @@ -8,6 +8,6 @@ progress message describing what each build rule does. If the property is not set the default is ON. Set the property to OFF to disable granular messages and report only as each target completes. This is intended to allow scripted builds to avoid the build time cost -of detailed reports. If a ``CMAKE_RULE_MESSAGES`` cache entry exists +of detailed reports. If a :variable:`CMAKE_RULE_MESSAGES` cache entry exists its value initializes the value of this property. Non-Makefile generators currently ignore this property. diff --git a/Help/prop_sf/MACOSX_PACKAGE_LOCATION.rst b/Help/prop_sf/MACOSX_PACKAGE_LOCATION.rst index a064afa..d185d91 100644 --- a/Help/prop_sf/MACOSX_PACKAGE_LOCATION.rst +++ b/Help/prop_sf/MACOSX_PACKAGE_LOCATION.rst @@ -3,19 +3,19 @@ MACOSX_PACKAGE_LOCATION Place a source file inside a Application Bundle (:prop_tgt:`MACOSX_BUNDLE`), Core Foundation Bundle (:prop_tgt:`BUNDLE`), -or Framework Bundle (:prop_tgt:`FRAMEWORK`). It is applicable for OS X +or Framework Bundle (:prop_tgt:`FRAMEWORK`). It is applicable for macOS and iOS. Executable targets with the :prop_tgt:`MACOSX_BUNDLE` property set are -built as OS X or iOS application bundles on Apple platforms. Shared +built as macOS or iOS application bundles on Apple platforms. Shared library targets with the :prop_tgt:`FRAMEWORK` property set are built as -OS X or iOS frameworks on Apple platforms. Module library targets with -the :prop_tgt:`BUNDLE` property set are built as OS X ``CFBundle`` bundles +macOS or iOS frameworks on Apple platforms. Module library targets with +the :prop_tgt:`BUNDLE` property set are built as macOS ``CFBundle`` bundles on Apple platforms. Source files listed in the target with this property set will be copied to a directory inside the bundle or framework content -folder specified by the property value. For OS X Application Bundles the -content folder is ``<name>.app/Contents``. For OS X Frameworks the -content folder is ``<name>.framework/Versions/<version>``. For OS X +folder specified by the property value. For macOS Application Bundles the +content folder is ``<name>.app/Contents``. For macOS Frameworks the +content folder is ``<name>.framework/Versions/<version>``. For macOS CFBundles the content folder is ``<name>.bundle/Contents`` (unless the extension is changed). See the :prop_tgt:`PUBLIC_HEADER`, :prop_tgt:`PRIVATE_HEADER`, and :prop_tgt:`RESOURCE` target properties for diff --git a/Help/prop_tgt/BUNDLE.rst b/Help/prop_tgt/BUNDLE.rst index 075f017..c556ac3 100644 --- a/Help/prop_tgt/BUNDLE.rst +++ b/Help/prop_tgt/BUNDLE.rst @@ -1,7 +1,7 @@ BUNDLE ------ -This target is a ``CFBundle`` on the OS X. +This target is a ``CFBundle`` on the macOS. If a module library target has this property set to true it will be built as a ``CFBundle`` when built on the mac. It will have the directory diff --git a/Help/prop_tgt/BUNDLE_EXTENSION.rst b/Help/prop_tgt/BUNDLE_EXTENSION.rst index 6b3d580..70de11c 100644 --- a/Help/prop_tgt/BUNDLE_EXTENSION.rst +++ b/Help/prop_tgt/BUNDLE_EXTENSION.rst @@ -2,7 +2,7 @@ BUNDLE_EXTENSION ---------------- The file extension used to name a :prop_tgt:`BUNDLE`, a :prop_tgt:`FRAMEWORK`, -or a :prop_tgt:`MACOSX_BUNDLE` target on the OS X and iOS. +or a :prop_tgt:`MACOSX_BUNDLE` target on the macOS and iOS. The default value is ``bundle``, ``framework``, or ``app`` for the respective target types. diff --git a/Help/prop_tgt/ENABLE_EXPORTS.rst b/Help/prop_tgt/ENABLE_EXPORTS.rst index 9e22309..581c2b9 100644 --- a/Help/prop_tgt/ENABLE_EXPORTS.rst +++ b/Help/prop_tgt/ENABLE_EXPORTS.rst @@ -12,7 +12,7 @@ dependency on the executable is created for targets that link to it. For DLL platforms an import library will be created for the exported symbols and then used for linking. All Windows-based systems including Cygwin are DLL platforms. For non-DLL platforms that -require all symbols to be resolved at link time, such as OS X, the +require all symbols to be resolved at link time, such as macOS, the module will "link" to the executable using a flag like ``-bundle_loader``. For other non-DLL platforms the link rule is simply ignored since the dynamic loader will automatically bind symbols when diff --git a/Help/prop_tgt/FRAMEWORK.rst b/Help/prop_tgt/FRAMEWORK.rst index 495d30e..9dad060 100644 --- a/Help/prop_tgt/FRAMEWORK.rst +++ b/Help/prop_tgt/FRAMEWORK.rst @@ -1,17 +1,17 @@ FRAMEWORK --------- -Build ``SHARED`` or ``STATIC`` library as Framework Bundle on the OS X and iOS. +Build ``SHARED`` or ``STATIC`` library as Framework Bundle on the macOS and iOS. If such a library target has this property set to ``TRUE`` it will be -built as a framework when built on the OS X and iOS. It will have the +built as a framework when built on the macOS and iOS. It will have the directory structure required for a framework and will be suitable to be used with the ``-framework`` option To customize ``Info.plist`` file in the framework, use :prop_tgt:`MACOSX_FRAMEWORK_INFO_PLIST` target property. -For OS X see also the :prop_tgt:`FRAMEWORK_VERSION` target property. +For macOS see also the :prop_tgt:`FRAMEWORK_VERSION` target property. Example of creation ``dynamicFramework``: diff --git a/Help/prop_tgt/FRAMEWORK_VERSION.rst b/Help/prop_tgt/FRAMEWORK_VERSION.rst index 6aa3026..c2ae7b9 100644 --- a/Help/prop_tgt/FRAMEWORK_VERSION.rst +++ b/Help/prop_tgt/FRAMEWORK_VERSION.rst @@ -4,5 +4,5 @@ FRAMEWORK_VERSION Version of a framework created using the :prop_tgt:`FRAMEWORK` target property (e.g. ``A``). -This property only affects OS X, as iOS doesn't have versioned +This property only affects macOS, as iOS doesn't have versioned directory structure. diff --git a/Help/prop_tgt/IMPORTED_LOCATION.rst b/Help/prop_tgt/IMPORTED_LOCATION.rst index 8cfef73..2d07aad 100644 --- a/Help/prop_tgt/IMPORTED_LOCATION.rst +++ b/Help/prop_tgt/IMPORTED_LOCATION.rst @@ -5,11 +5,11 @@ Full path to the main file on disk for an IMPORTED target. Set this to the location of an IMPORTED target file on disk. For executables this is the location of the executable file. For bundles -on OS X this is the location of the executable file inside +on macOS this is the location of the executable file inside Contents/MacOS under the application bundle folder. For static libraries and modules this is the location of the library or module. For shared libraries on non-DLL platforms this is the location of the -shared library. For frameworks on OS X this is the location of the +shared library. For frameworks on macOS this is the location of the library file symlink just inside the framework folder. For DLLs this is the location of the ".dll" part of the library. For UNKNOWN libraries this is the location of the file to be linked. Ignored for diff --git a/Help/prop_tgt/INTERFACE_LINK_LIBRARIES.rst b/Help/prop_tgt/INTERFACE_LINK_LIBRARIES.rst index 832d12b..bf7f72f 100644 --- a/Help/prop_tgt/INTERFACE_LINK_LIBRARIES.rst +++ b/Help/prop_tgt/INTERFACE_LINK_LIBRARIES.rst @@ -17,6 +17,8 @@ with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` manual for available expressions. See the :manual:`cmake-buildsystem(7)` manual for more on defining buildsystem properties. +.. include:: LINK_LIBRARIES_INDIRECTION.txt + Creating Relocatable Packages ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/Help/prop_tgt/LINK_LIBRARIES.rst b/Help/prop_tgt/LINK_LIBRARIES.rst index aa4b9f5..d88e798 100644 --- a/Help/prop_tgt/LINK_LIBRARIES.rst +++ b/Help/prop_tgt/LINK_LIBRARIES.rst @@ -15,3 +15,5 @@ Contents of ``LINK_LIBRARIES`` may use "generator expressions" with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` manual for available expressions. See the :manual:`cmake-buildsystem(7)` manual for more on defining buildsystem properties. + +.. include:: LINK_LIBRARIES_INDIRECTION.txt diff --git a/Help/prop_tgt/LINK_LIBRARIES_INDIRECTION.txt b/Help/prop_tgt/LINK_LIBRARIES_INDIRECTION.txt new file mode 100644 index 0000000..1fdb6ad --- /dev/null +++ b/Help/prop_tgt/LINK_LIBRARIES_INDIRECTION.txt @@ -0,0 +1,10 @@ +.. note:: + A call to :command:`target_link_libraries(<target> ...)` may update this + property on ``<target>``. If ``<target>`` was not created in the same + directory as the call then :command:`target_link_libraries` will add a + suffix of the form ``::@<directory-id>`` to each entry, where the + ``::@`` is a separator and the ``<directory-id>`` is unspecified. + This tells the generators that the named libraries must be looked up in + the scope of the caller rather than in the scope in which the + ``<target>`` was created. Valid directory ids are stripped on export + by the :command:`install(EXPORT)` and :command:`export` commands. diff --git a/Help/prop_tgt/MACOSX_BUNDLE.rst b/Help/prop_tgt/MACOSX_BUNDLE.rst index f9e11ee..92bce53 100644 --- a/Help/prop_tgt/MACOSX_BUNDLE.rst +++ b/Help/prop_tgt/MACOSX_BUNDLE.rst @@ -1,9 +1,9 @@ MACOSX_BUNDLE ------------- -Build an executable as an Application Bundle on OS X or iOS. +Build an executable as an Application Bundle on macOS or iOS. -When this property is set to ``TRUE`` the executable when built on OS X +When this property is set to ``TRUE`` the executable when built on macOS or iOS will be created as an application bundle. This makes it a GUI executable that can be launched from the Finder. See the :prop_tgt:`MACOSX_BUNDLE_INFO_PLIST` target property for information about diff --git a/Help/prop_tgt/MACOSX_BUNDLE_INFO_PLIST.rst b/Help/prop_tgt/MACOSX_BUNDLE_INFO_PLIST.rst index 8515acc..443a645 100644 --- a/Help/prop_tgt/MACOSX_BUNDLE_INFO_PLIST.rst +++ b/Help/prop_tgt/MACOSX_BUNDLE_INFO_PLIST.rst @@ -1,10 +1,10 @@ MACOSX_BUNDLE_INFO_PLIST ------------------------ -Specify a custom ``Info.plist`` template for a OS X and iOS Application Bundle. +Specify a custom ``Info.plist`` template for a macOS and iOS Application Bundle. An executable target with :prop_tgt:`MACOSX_BUNDLE` enabled will be built as an -application bundle on OS X. By default its ``Info.plist`` file is created +application bundle on macOS. By default its ``Info.plist`` file is created by configuring a template called ``MacOSXBundleInfo.plist.in`` located in the :variable:`CMAKE_MODULE_PATH`. This property specifies an alternative template file name which may be a full path. diff --git a/Help/prop_tgt/MACOSX_FRAMEWORK_INFO_PLIST.rst b/Help/prop_tgt/MACOSX_FRAMEWORK_INFO_PLIST.rst index 58f31d4..82fdcc0 100644 --- a/Help/prop_tgt/MACOSX_FRAMEWORK_INFO_PLIST.rst +++ b/Help/prop_tgt/MACOSX_FRAMEWORK_INFO_PLIST.rst @@ -1,10 +1,10 @@ MACOSX_FRAMEWORK_INFO_PLIST --------------------------- -Specify a custom ``Info.plist`` template for a OS X and iOS Framework. +Specify a custom ``Info.plist`` template for a macOS and iOS Framework. A library target with :prop_tgt:`FRAMEWORK` enabled will be built as a -framework on OS X. By default its ``Info.plist`` file is created by +framework on macOS. By default its ``Info.plist`` file is created by configuring a template called ``MacOSXFrameworkInfo.plist.in`` located in the :variable:`CMAKE_MODULE_PATH`. This property specifies an alternative template file name which may be a full path. diff --git a/Help/prop_tgt/MACOSX_RPATH.rst b/Help/prop_tgt/MACOSX_RPATH.rst index 1f9a036..acd5a7a 100644 --- a/Help/prop_tgt/MACOSX_RPATH.rst +++ b/Help/prop_tgt/MACOSX_RPATH.rst @@ -1,7 +1,7 @@ MACOSX_RPATH ------------ -Whether this target on OS X or iOS is located at runtime using rpaths. +Whether this target on macOS or iOS is located at runtime using rpaths. When this property is set to ``TRUE``, the directory portion of the ``install_name`` field of this shared library will be ``@rpath`` diff --git a/Help/prop_tgt/OSX_ARCHITECTURES.rst b/Help/prop_tgt/OSX_ARCHITECTURES.rst index cefe03f..996a4be 100644 --- a/Help/prop_tgt/OSX_ARCHITECTURES.rst +++ b/Help/prop_tgt/OSX_ARCHITECTURES.rst @@ -1,10 +1,10 @@ OSX_ARCHITECTURES ----------------- -Target specific architectures for OS X. +Target specific architectures for macOS. The ``OSX_ARCHITECTURES`` property sets the target binary architecture for -targets on OS X (``-arch``). This property is initialized by the value of the +targets on macOS (``-arch``). This property is initialized by the value of the variable :variable:`CMAKE_OSX_ARCHITECTURES` if it is set when a target is created. Use :prop_tgt:`OSX_ARCHITECTURES_<CONFIG>` to set the binary architectures on a per-configuration basis, where ``<CONFIG>`` is an diff --git a/Help/prop_tgt/OSX_ARCHITECTURES_CONFIG.rst b/Help/prop_tgt/OSX_ARCHITECTURES_CONFIG.rst index fb78177..06da4fb 100644 --- a/Help/prop_tgt/OSX_ARCHITECTURES_CONFIG.rst +++ b/Help/prop_tgt/OSX_ARCHITECTURES_CONFIG.rst @@ -1,7 +1,7 @@ OSX_ARCHITECTURES_<CONFIG> -------------------------- -Per-configuration OS X and iOS binary architectures for a target. +Per-configuration macOS and iOS binary architectures for a target. This property is the configuration-specific version of :prop_tgt:`OSX_ARCHITECTURES`. diff --git a/Help/prop_tgt/PRIVATE_HEADER.rst b/Help/prop_tgt/PRIVATE_HEADER.rst index c4412ed..2bd4079 100644 --- a/Help/prop_tgt/PRIVATE_HEADER.rst +++ b/Help/prop_tgt/PRIVATE_HEADER.rst @@ -4,7 +4,7 @@ PRIVATE_HEADER Specify private header files in a :prop_tgt:`FRAMEWORK` shared library target. Shared library targets marked with the :prop_tgt:`FRAMEWORK` property generate -frameworks on OS X, iOS and normal shared libraries on other platforms. +frameworks on macOS, iOS and normal shared libraries on other platforms. This property may be set to a list of header files to be placed in the PrivateHeaders directory inside the framework folder. On non-Apple platforms these headers may be installed using the ``PRIVATE_HEADER`` diff --git a/Help/prop_tgt/PUBLIC_HEADER.rst b/Help/prop_tgt/PUBLIC_HEADER.rst index d4a636c..549ac7c 100644 --- a/Help/prop_tgt/PUBLIC_HEADER.rst +++ b/Help/prop_tgt/PUBLIC_HEADER.rst @@ -4,7 +4,7 @@ PUBLIC_HEADER Specify public header files in a :prop_tgt:`FRAMEWORK` shared library target. Shared library targets marked with the :prop_tgt:`FRAMEWORK` property generate -frameworks on OS X, iOS and normal shared libraries on other platforms. +frameworks on macOS, iOS and normal shared libraries on other platforms. This property may be set to a list of header files to be placed in the ``Headers`` directory inside the framework folder. On non-Apple platforms these headers may be installed using the ``PUBLIC_HEADER`` option to the diff --git a/Help/prop_tgt/RESOURCE.rst b/Help/prop_tgt/RESOURCE.rst index d837f7b..55ae774 100644 --- a/Help/prop_tgt/RESOURCE.rst +++ b/Help/prop_tgt/RESOURCE.rst @@ -4,10 +4,10 @@ RESOURCE Specify resource files in a :prop_tgt:`FRAMEWORK` or :prop_tgt:`BUNDLE`. Target marked with the :prop_tgt:`FRAMEWORK` or :prop_tgt:`BUNDLE` property -generate framework or application bundle (both OS X and iOS is supported) +generate framework or application bundle (both macOS and iOS is supported) or normal shared libraries on other platforms. This property may be set to a list of files to be placed in the corresponding -directory (eg. ``Resources`` directory for OS X) inside the bundle. +directory (eg. ``Resources`` directory for macOS) inside the bundle. On non-Apple platforms these files may be installed using the ``RESOURCE`` option to the ``install(TARGETS)`` command. @@ -42,7 +42,7 @@ will produce flat structure for iOS systems:: Info.plist resourcefile.txt -For OS X systems it will produce following directory structure:: +For macOS systems it will produce following directory structure:: ExecutableTarget.app/ Contents diff --git a/Help/prop_tgt/SOVERSION.rst b/Help/prop_tgt/SOVERSION.rst index 82b6b97..b07c17c 100644 --- a/Help/prop_tgt/SOVERSION.rst +++ b/Help/prop_tgt/SOVERSION.rst @@ -20,7 +20,7 @@ These numbers are used as the image version of the binary. Mach-O Versions ^^^^^^^^^^^^^^^ -For shared libraries and executables on Mach-O systems (e.g. OS X, iOS), +For shared libraries and executables on Mach-O systems (e.g. macOS, iOS), the ``SOVERSION`` property corresponds to *compatibility version* and :prop_tgt:`VERSION` to *current version*. See the :prop_tgt:`FRAMEWORK` target property for an example. Versions of Mach-O binaries may be checked with the diff --git a/Help/prop_tgt/VERSION.rst b/Help/prop_tgt/VERSION.rst index 66e7bde..ff3b303 100644 --- a/Help/prop_tgt/VERSION.rst +++ b/Help/prop_tgt/VERSION.rst @@ -22,7 +22,7 @@ These numbers are used as the image version of the binary. Mach-O Versions ^^^^^^^^^^^^^^^ -For shared libraries and executables on Mach-O systems (e.g. OS X, iOS), +For shared libraries and executables on Mach-O systems (e.g. macOS, iOS), the :prop_tgt:`SOVERSION` property correspond to *compatibility version* and ``VERSION`` to *current version*. See the :prop_tgt:`FRAMEWORK` target property for an example. Versions of Mach-O binaries may be checked with the diff --git a/Help/release/dev/FindPython-lookup-strategy.rst b/Help/release/dev/FindPython-lookup-strategy.rst new file mode 100644 index 0000000..f6d6db5 --- /dev/null +++ b/Help/release/dev/FindPython-lookup-strategy.rst @@ -0,0 +1,6 @@ +FindPython-lookup-strategy +-------------------------- + +* Modules :module:`FindPython3`, :module:`FindPython2` and :module:`FindPython` + gain capability to control order of resource lookup on macOS (Framework) and + Windows (Registry). diff --git a/Help/release/dev/FindSubversion-wc-info-error.rst b/Help/release/dev/FindSubversion-wc-info-error.rst new file mode 100644 index 0000000..eaf6bfe --- /dev/null +++ b/Help/release/dev/FindSubversion-wc-info-error.rst @@ -0,0 +1,6 @@ +FindSubversion-wc-info-error +---------------------------- + +* The :module:`FindSubversion` module ``Subversion_WC_INFO`` command + gained an ``IGNORE_SVN_FAILURE`` option to suppress failures, + e.g. when the source tree is not under Subversion control. diff --git a/Help/release/dev/cmake-explicit-dirs.rst b/Help/release/dev/cmake-explicit-dirs.rst new file mode 100644 index 0000000..35f2d3a --- /dev/null +++ b/Help/release/dev/cmake-explicit-dirs.rst @@ -0,0 +1,10 @@ +cmake-explicit-dirs +------------------- + +* The :manual:`cmake <cmake(1)>` command gained the ``-S <source_dir>`` + command line option to specify the location of the source directory. + This option can be used independently of ``-B``. + +* The :manual:`cmake <cmake(1)>` command gained the ``-B <build_dir>`` + command line option to specify the location of the build directory. + This option can be used independently of ``-S``. diff --git a/Help/release/dev/out-of-dir-linking.rst b/Help/release/dev/out-of-dir-linking.rst new file mode 100644 index 0000000..6166be6 --- /dev/null +++ b/Help/release/dev/out-of-dir-linking.rst @@ -0,0 +1,6 @@ +out-of-dir-linking +------------------ + +* The :command:`target_link_libraries` command may now be called + to modify targets created outside the current directory. + See policy :policy:`CMP0079`. diff --git a/Help/release/dev/vs-ipo.rst b/Help/release/dev/vs-ipo.rst new file mode 100644 index 0000000..a31601f --- /dev/null +++ b/Help/release/dev/vs-ipo.rst @@ -0,0 +1,6 @@ +vs-ipo +------ + +* The :ref:`Visual Studio Generators` for VS 2010 and above learned to + support the :prop_tgt:`INTERPROCEDURAL_OPTIMIZATION` target property + and supporting :module:`CheckIPOSupported` module. diff --git a/Help/variable/CMAKE_APPBUNDLE_PATH.rst b/Help/variable/CMAKE_APPBUNDLE_PATH.rst index 2bc79ac..c1f0951 100644 --- a/Help/variable/CMAKE_APPBUNDLE_PATH.rst +++ b/Help/variable/CMAKE_APPBUNDLE_PATH.rst @@ -2,5 +2,5 @@ CMAKE_APPBUNDLE_PATH -------------------- :ref:`;-list <CMake Language Lists>` of directories specifying a search path -for OS X application bundles used by the :command:`find_program`, and +for macOS application bundles used by the :command:`find_program`, and :command:`find_package` commands. diff --git a/Help/variable/CMAKE_CPACK_COMMAND.rst b/Help/variable/CMAKE_CPACK_COMMAND.rst new file mode 100644 index 0000000..559108a --- /dev/null +++ b/Help/variable/CMAKE_CPACK_COMMAND.rst @@ -0,0 +1,8 @@ +CMAKE_CPACK_COMMAND +------------------- + +Full path to :manual:`cpack(1)` command installed with CMake. + +This is the full path to the CPack executable :manual:`cpack(1)` which is +useful from custom commands that want to use the :manual:`cmake(1)` ``-E`` +option for portable system commands. diff --git a/Help/variable/CMAKE_ENABLE_EXPORTS.rst b/Help/variable/CMAKE_ENABLE_EXPORTS.rst index 9a877e7..7ec4d63 100644 --- a/Help/variable/CMAKE_ENABLE_EXPORTS.rst +++ b/Help/variable/CMAKE_ENABLE_EXPORTS.rst @@ -12,7 +12,7 @@ dependency on the executable is created for targets that link to it. For DLL platforms an import library will be created for the exported symbols and then used for linking. All Windows-based systems including Cygwin are DLL platforms. For non-DLL platforms that -require all symbols to be resolved at link time, such as OS X, the +require all symbols to be resolved at link time, such as macOS, the module will ``link`` to the executable using a flag like ``-bundle_loader``. For other non-DLL platforms the link rule is simply ignored since the dynamic loader will automatically bind symbols when diff --git a/Help/variable/CMAKE_FIND_APPBUNDLE.rst b/Help/variable/CMAKE_FIND_APPBUNDLE.rst index e0727b5..7a05fac 100644 --- a/Help/variable/CMAKE_FIND_APPBUNDLE.rst +++ b/Help/variable/CMAKE_FIND_APPBUNDLE.rst @@ -2,9 +2,9 @@ CMAKE_FIND_APPBUNDLE -------------------- This variable affects how ``find_*`` commands choose between -OS X Application Bundles and unix-style package components. +macOS Application Bundles and unix-style package components. -On Darwin or systems supporting OS X Application Bundles, the +On Darwin or systems supporting macOS Application Bundles, the ``CMAKE_FIND_APPBUNDLE`` variable can be set to empty or one of the following: diff --git a/Help/variable/CMAKE_FIND_FRAMEWORK.rst b/Help/variable/CMAKE_FIND_FRAMEWORK.rst index 790694a..4d5078f 100644 --- a/Help/variable/CMAKE_FIND_FRAMEWORK.rst +++ b/Help/variable/CMAKE_FIND_FRAMEWORK.rst @@ -2,9 +2,9 @@ CMAKE_FIND_FRAMEWORK -------------------- This variable affects how ``find_*`` commands choose between -OS X Frameworks and unix-style package components. +macOS Frameworks and unix-style package components. -On Darwin or systems supporting OS X Frameworks, the +On Darwin or systems supporting macOS Frameworks, the ``CMAKE_FIND_FRAMEWORK`` variable can be set to empty or one of the following: diff --git a/Help/variable/CMAKE_FRAMEWORK_PATH.rst b/Help/variable/CMAKE_FRAMEWORK_PATH.rst index 5ff08e6..04751f8 100644 --- a/Help/variable/CMAKE_FRAMEWORK_PATH.rst +++ b/Help/variable/CMAKE_FRAMEWORK_PATH.rst @@ -2,6 +2,6 @@ CMAKE_FRAMEWORK_PATH -------------------- :ref:`;-list <CMake Language Lists>` of directories specifying a search path -for OS X frameworks used by the :command:`find_library`, +for macOS frameworks used by the :command:`find_library`, :command:`find_package`, :command:`find_path`, and :command:`find_file` commands. diff --git a/Help/variable/CMAKE_HOST_APPLE.rst b/Help/variable/CMAKE_HOST_APPLE.rst index ac7b030..9c205ec 100644 --- a/Help/variable/CMAKE_HOST_APPLE.rst +++ b/Help/variable/CMAKE_HOST_APPLE.rst @@ -1,6 +1,6 @@ CMAKE_HOST_APPLE ---------------- -``True`` for Apple OS X operating systems. +``True`` for Apple macOS operating systems. -Set to ``true`` when the host system is Apple OS X. +Set to ``true`` when the host system is Apple macOS. diff --git a/Help/variable/CMAKE_HOST_SYSTEM_NAME.rst b/Help/variable/CMAKE_HOST_SYSTEM_NAME.rst index c673592..e892677 100644 --- a/Help/variable/CMAKE_HOST_SYSTEM_NAME.rst +++ b/Help/variable/CMAKE_HOST_SYSTEM_NAME.rst @@ -4,5 +4,5 @@ CMAKE_HOST_SYSTEM_NAME Name of the OS CMake is running on. On systems that have the uname command, this variable is set to the -output of ``uname -s``. ``Linux``, ``Windows``, and ``Darwin`` for OS X +output of ``uname -s``. ``Linux``, ``Windows``, and ``Darwin`` for macOS are the values found on the big three operating systems. diff --git a/Help/variable/CMAKE_INSTALL_NAME_DIR.rst b/Help/variable/CMAKE_INSTALL_NAME_DIR.rst index 1f2d62b..5ba4c04 100644 --- a/Help/variable/CMAKE_INSTALL_NAME_DIR.rst +++ b/Help/variable/CMAKE_INSTALL_NAME_DIR.rst @@ -1,7 +1,7 @@ CMAKE_INSTALL_NAME_DIR ---------------------- -OS X directory name for installed targets. +macOS directory name for installed targets. ``CMAKE_INSTALL_NAME_DIR`` is used to initialize the :prop_tgt:`INSTALL_NAME_DIR` property on all targets. See that target diff --git a/Help/variable/CMAKE_MACOSX_RPATH.rst b/Help/variable/CMAKE_MACOSX_RPATH.rst index 042e807..2fc648d 100644 --- a/Help/variable/CMAKE_MACOSX_RPATH.rst +++ b/Help/variable/CMAKE_MACOSX_RPATH.rst @@ -1,7 +1,7 @@ CMAKE_MACOSX_RPATH ------------------- -Whether to use rpaths on OS X and iOS. +Whether to use rpaths on macOS and iOS. This variable is used to initialize the :prop_tgt:`MACOSX_RPATH` property on all targets. diff --git a/Help/variable/CMAKE_OSX_ARCHITECTURES.rst b/Help/variable/CMAKE_OSX_ARCHITECTURES.rst index 51b840d..fdaca28 100644 --- a/Help/variable/CMAKE_OSX_ARCHITECTURES.rst +++ b/Help/variable/CMAKE_OSX_ARCHITECTURES.rst @@ -1,7 +1,7 @@ CMAKE_OSX_ARCHITECTURES ----------------------- -Target specific architectures for OS X and iOS. +Target specific architectures for macOS and iOS. This variable is used to initialize the :prop_tgt:`OSX_ARCHITECTURES` property on each target as it is created. See that target property diff --git a/Help/variable/CMAKE_OSX_SYSROOT.rst b/Help/variable/CMAKE_OSX_SYSROOT.rst index f1d58c6..db9fccd 100644 --- a/Help/variable/CMAKE_OSX_SYSROOT.rst +++ b/Help/variable/CMAKE_OSX_SYSROOT.rst @@ -1,7 +1,7 @@ CMAKE_OSX_SYSROOT ----------------- -Specify the location or name of the OS X platform SDK to be used. +Specify the location or name of the macOS platform SDK to be used. CMake uses this value to compute the value of the ``-isysroot`` flag or equivalent and to help the ``find_*`` commands locate files in the SDK. diff --git a/Help/variable/CMAKE_RULE_MESSAGES.rst b/Help/variable/CMAKE_RULE_MESSAGES.rst new file mode 100644 index 0000000..7460a81 --- /dev/null +++ b/Help/variable/CMAKE_RULE_MESSAGES.rst @@ -0,0 +1,8 @@ +CMAKE_RULE_MESSAGES +------------------- + +Specify whether to report a message for each make rule. + +If set in the cache it is used to initialize the value of the :prop_gbl:`RULE_MESSAGES` property. +Users may disable the option in their local build tree to disable granular messages +and report only as each target completes in Makefile builds. diff --git a/Help/variable/CMAKE_SYSTEM_APPBUNDLE_PATH.rst b/Help/variable/CMAKE_SYSTEM_APPBUNDLE_PATH.rst index 3c6687c..666af46 100644 --- a/Help/variable/CMAKE_SYSTEM_APPBUNDLE_PATH.rst +++ b/Help/variable/CMAKE_SYSTEM_APPBUNDLE_PATH.rst @@ -1,7 +1,7 @@ CMAKE_SYSTEM_APPBUNDLE_PATH --------------------------- -Search path for OS X application bundles used by the :command:`find_program`, +Search path for macOS application bundles used by the :command:`find_program`, and :command:`find_package` commands. By default it contains the standard directories for the current system. It is *not* intended to be modified by the project, use :variable:`CMAKE_APPBUNDLE_PATH` for this. diff --git a/Help/variable/CMAKE_SYSTEM_FRAMEWORK_PATH.rst b/Help/variable/CMAKE_SYSTEM_FRAMEWORK_PATH.rst index 1e8b0d9..14ba18e 100644 --- a/Help/variable/CMAKE_SYSTEM_FRAMEWORK_PATH.rst +++ b/Help/variable/CMAKE_SYSTEM_FRAMEWORK_PATH.rst @@ -1,7 +1,7 @@ CMAKE_SYSTEM_FRAMEWORK_PATH --------------------------- -Search path for OS X frameworks used by the :command:`find_library`, +Search path for macOS frameworks used by the :command:`find_library`, :command:`find_package`, :command:`find_path`, and :command:`find_file` commands. By default it contains the standard directories for the current system. It is *not* intended to be modified by the project, diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake index dc4d9be..5e2df26a 100644 --- a/Modules/CMakeDetermineCompilerId.cmake +++ b/Modules/CMakeDetermineCompilerId.cmake @@ -525,6 +525,9 @@ function(CMAKE_DETERMINE_COMPILER_ID_CHECK lang file) ${CMAKE_${lang}_COMPILER_ID_STRINGS_PARAMETERS} REGEX "INFO:[A-Za-z0-9_]+\\[[^]]*\\]") set(COMPILER_ID_TWICE) + # With the IAR Compiler, some strings are found twice, first time as incomplete + # list like "?<Constant "INFO:compiler[IAR]">". Remove the incomplete copies. + list(FILTER CMAKE_${lang}_COMPILER_ID_STRINGS EXCLUDE REGEX "\\?<Constant \\\"") # In C# binaries, some strings are found more than once. list(REMOVE_DUPLICATES CMAKE_${lang}_COMPILER_ID_STRINGS) foreach(info ${CMAKE_${lang}_COMPILER_ID_STRINGS}) diff --git a/Modules/CMakeExtraGeneratorDetermineCompilerMacrosAndIncludeDirs.cmake b/Modules/CMakeExtraGeneratorDetermineCompilerMacrosAndIncludeDirs.cmake index 55e0373..11f4a29 100644 --- a/Modules/CMakeExtraGeneratorDetermineCompilerMacrosAndIncludeDirs.cmake +++ b/Modules/CMakeExtraGeneratorDetermineCompilerMacrosAndIncludeDirs.cmake @@ -27,6 +27,7 @@ macro(_DETERMINE_GCC_SYSTEM_INCLUDE_DIRS _lang _resultIncludeDirs _resultDefines set(_compilerExecutable "${CMAKE_C_COMPILER}") set(_arg1 "${CMAKE_C_COMPILER_ARG1}") endif () + separate_arguments(_arg1 NATIVE_COMMAND "${_arg1}") execute_process(COMMAND ${_compilerExecutable} ${_arg1} ${_stdver} ${_stdlib} -v -E -x ${_lang} -dD dummy WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/CMakeFiles ERROR_VARIABLE _gccOutput diff --git a/Modules/CMakeIOSInstallCombined.cmake b/Modules/CMakeIOSInstallCombined.cmake index fad2e8f..418bafd 100644 --- a/Modules/CMakeIOSInstallCombined.cmake +++ b/Modules/CMakeIOSInstallCombined.cmake @@ -1,6 +1,8 @@ # Distributed under the OSI-approved BSD 3-Clause License. See accompanying # file Copyright.txt or https://cmake.org/licensing for details. +cmake_policy(PUSH) +cmake_policy(SET CMP0057 NEW) # if IN_LIST # Function to print messages of this module function(_ios_install_combined_message) @@ -57,6 +59,7 @@ endfunction() # Get architectures of given SDK (iphonesimulator/iphoneos) function(_ios_install_combined_get_valid_archs sdk resultvar) + cmake_policy(PUSH) cmake_policy(SET CMP0007 NEW) if("${resultvar}" STREQUAL "") @@ -73,6 +76,8 @@ function(_ios_install_combined_get_valid_archs sdk resultvar) _ios_install_combined_message("Architectures (${sdk}): ${printable}") set("${resultvar}" "${valid_archs}" PARENT_SCOPE) + + cmake_policy(POP) endfunction() # Final target can contain more architectures that specified by SDK. This @@ -161,8 +166,6 @@ function(_ios_install_combined_keep_archs lib archs) endfunction() function(_ios_install_combined_detect_sdks this_sdk_var corr_sdk_var) - cmake_policy(SET CMP0057 NEW) - set(this_sdk "$ENV{PLATFORM_NAME}") if("${this_sdk}" STREQUAL "") message(FATAL_ERROR "Environment variable PLATFORM_NAME is empty") @@ -305,3 +308,5 @@ function(ios_install_combined target destination) _ios_install_combined_message("Install done: ${destination}") endfunction() + +cmake_policy(POP) diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake index cdc38a6..f3e3423 100644 --- a/Modules/CPack.cmake +++ b/Modules/CPack.cmake @@ -19,7 +19,7 @@ command (and the deprecated :command:`install_files`, :command:`install_programs` and :command:`install_targets` commands). For certain kinds of binary installers (including the graphical -installers on Mac OS X and Windows), CPack generates installers that +installers on macOS and Windows), CPack generates installers that allow users to select individual application components to install. See :module:`CPackComponent` module for further details. diff --git a/Modules/CPackComponent.cmake b/Modules/CPackComponent.cmake index 6c122e5..a0d9935 100644 --- a/Modules/CPackComponent.cmake +++ b/Modules/CPackComponent.cmake @@ -14,7 +14,7 @@ # part of CPack. See CPack module for general information about CPack. # # For certain kinds of binary installers (including the graphical -# installers on Mac OS X and Windows), CPack generates installers that +# installers on macOS and Windows), CPack generates installers that # allow users to select individual application components to install. # The contents of each of the components are identified by the COMPONENT # argument of CMake's INSTALL command. These components can be @@ -283,8 +283,8 @@ # # # -# On Mac OS X, installers that download components on-the-fly can only -# be built and installed on system using Mac OS X 10.5 or later. +# On macOS, installers that download components on-the-fly can only +# be built and installed on system using macOS 10.5 or later. # # The site argument is a URL where the archives for downloadable # components will reside, e.g., diff --git a/Modules/CSharpUtilities.cmake b/Modules/CSharpUtilities.cmake index e9e1510..6a4b5c7 100644 --- a/Modules/CSharpUtilities.cmake +++ b/Modules/CSharpUtilities.cmake @@ -184,6 +184,9 @@ Helper functions which are used by the above ones #]=======================================================================] +cmake_policy(PUSH) +cmake_policy(SET CMP0057 NEW) # if IN_LIST + function(csharp_get_filename_keys OUT) set(${OUT} "") foreach(f ${ARGN}) @@ -304,3 +307,5 @@ function(csharp_set_xaml_cs_properties) endif() endforeach() endfunction() + +cmake_policy(POP) diff --git a/Modules/CheckIPOSupported.cmake b/Modules/CheckIPOSupported.cmake index 3344834..ad8852c 100644 --- a/Modules/CheckIPOSupported.cmake +++ b/Modules/CheckIPOSupported.cmake @@ -226,7 +226,7 @@ function(check_ipo_supported) endif() endforeach() - if(CMAKE_GENERATOR MATCHES "^Visual Studio ") + if(CMAKE_GENERATOR MATCHES "^Visual Studio 9 ") _ipo_not_supported("CMake doesn't support IPO for current generator") return() endif() diff --git a/Modules/Compiler/IAR-ASM.cmake b/Modules/Compiler/IAR-ASM.cmake index 651bc3a..e12bfd1 100644 --- a/Modules/Compiler/IAR-ASM.cmake +++ b/Modules/Compiler/IAR-ASM.cmake @@ -18,4 +18,6 @@ elseif("${CMAKE_ASM${ASM_DIALECT}_COMPILER_ARCHITECTURE_ID}" STREQUAL "AVR") __compiler_iar_AVR(ASM) set(CMAKE_ASM_SOURCE_FILE_EXTENSIONS s90;asm;msa) +else() + message(FATAL_ERROR "CMAKE_ASM${ASM_DIALECT}_COMPILER_ARCHITECTURE_ID not detected as \"AVR\" or \"ARM\". This should be automatic.") endif() diff --git a/Modules/Compiler/IAR-C.cmake b/Modules/Compiler/IAR-C.cmake index 55e019e..2ed8818 100644 --- a/Modules/Compiler/IAR-C.cmake +++ b/Modules/Compiler/IAR-C.cmake @@ -5,6 +5,9 @@ include(Compiler/CMakeCommonCompilerMacros) # The toolchains for ARM and AVR are quite different: if("${CMAKE_C_COMPILER_ARCHITECTURE_ID}" STREQUAL "ARM") + if(NOT CMAKE_C_COMPILER_VERSION) + message(FATAL_ERROR "CMAKE_C_COMPILER_VERSION not detected. This should be automatic.") + endif() set(CMAKE_C_EXTENSION_COMPILE_OPTION -e) @@ -40,4 +43,7 @@ elseif("${CMAKE_C_COMPILER_ARCHITECTURE_ID}" STREQUAL "AVR") get_filename_component(_compilerDir "${CMAKE_C_COMPILER}" PATH) get_filename_component(_compilerDir "${_compilerDir}" PATH) include_directories("${_compilerDir}/inc" ) + +else() + message(FATAL_ERROR "CMAKE_C_COMPILER_ARCHITECTURE_ID not detected as \"AVR\" or \"ARM\". This should be automatic.") endif() diff --git a/Modules/Compiler/IAR-CXX.cmake b/Modules/Compiler/IAR-CXX.cmake index 8d86100..5b783b2 100644 --- a/Modules/Compiler/IAR-CXX.cmake +++ b/Modules/Compiler/IAR-CXX.cmake @@ -10,6 +10,9 @@ if("${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}" STREQUAL "ARM") # # --c++ is full C++ and supported since 6.10 if(NOT CMAKE_IAR_CXX_FLAG) + if(NOT CMAKE_CXX_COMPILER_VERSION) + message(FATAL_ERROR "CMAKE_CXX_COMPILER_VERSION not detected. This should be automatic.") + endif() if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.10) set(CMAKE_IAR_CXX_FLAG --c++) else() @@ -48,4 +51,7 @@ elseif("${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}" STREQUAL "AVR") get_filename_component(_compilerDir "${CMAKE_C_COMPILER}" PATH) get_filename_component(_compilerDir "${_compilerDir}" PATH) include_directories("${_compilerDir}/inc") + +else() + message(FATAL_ERROR "CMAKE_CXX_COMPILER_ARCHITECTURE_ID not detected as \"AVR\" or \"ARM\". This should be automatic." ) endif() diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake index f65a493..37539ba 100644 --- a/Modules/FindBoost.cmake +++ b/Modules/FindBoost.cmake @@ -493,11 +493,11 @@ function(_Boost_GUESS_COMPILER_PREFIX _ret) if(Boost_MINOR_VERSION) if(${Boost_MINOR_VERSION} GREATER 35) # In Boost 1.36.0 and newer, the mangled compiler name used - # on Mac OS X/Darwin is "xgcc". + # on macOS/Darwin is "xgcc". set(_boost_COMPILER "-xgcc${_boost_COMPILER_VERSION}") else() # In Boost <= 1.35.0, there is no mangled compiler name for - # the Mac OS X/Darwin version of GCC. + # the macOS/Darwin version of GCC. set(_boost_COMPILER "") endif() else() @@ -573,7 +573,7 @@ function(_Boost_COMPONENT_DEPENDENCIES component _ret) endif() set(_Boost_IMPORTED_TARGETS TRUE) - if(Boost_VERSION VERSION_LESS 103300) + if(Boost_VERSION AND Boost_VERSION VERSION_LESS 103300) message(WARNING "Imported targets and dependency information not available for Boost version ${Boost_VERSION} (all versions older than 1.33)") set(_Boost_IMPORTED_TARGETS FALSE) elseif(NOT Boost_VERSION VERSION_LESS 103300 AND Boost_VERSION VERSION_LESS 103500) diff --git a/Modules/FindCUDA.cmake b/Modules/FindCUDA.cmake index 1650e55..5547dee 100644 --- a/Modules/FindCUDA.cmake +++ b/Modules/FindCUDA.cmake @@ -43,7 +43,7 @@ # matches what is needed by the CUDA runtime version. # # The following variables affect the behavior of the macros in the -# script (in alphebetical order). Note that any of these flags can be +# script (in alphabetical order). Note that any of these flags can be # changed multiple times in the same directory before calling # ``CUDA_ADD_EXECUTABLE``, ``CUDA_ADD_LIBRARY``, ``CUDA_COMPILE``, # ``CUDA_COMPILE_PTX``, ``CUDA_COMPILE_FATBIN``, ``CUDA_COMPILE_CUBIN`` @@ -147,7 +147,7 @@ # VERBOSE=1 to see output), although setting CUDA_VERBOSE_BUILD to ON will # always print the output. # -# The script creates the following macros (in alphebetical order):: +# The script creates the following macros (in alphabetical order):: # # CUDA_ADD_CUFFT_TO_TARGET( cuda_target ) # -- Adds the cufft library to the target (can be any target). Handles whether diff --git a/Modules/FindDoxygen.cmake b/Modules/FindDoxygen.cmake index 945ee0e..2ed9449 100644 --- a/Modules/FindDoxygen.cmake +++ b/Modules/FindDoxygen.cmake @@ -370,6 +370,9 @@ Deprecated Hint Variables #]=======================================================================] +cmake_policy(PUSH) +cmake_policy(SET CMP0057 NEW) # if IN_LIST + # For backwards compatibility support if(Doxygen_FIND_QUIETLY) set(DOXYGEN_FIND_QUIETLY TRUE) @@ -1108,3 +1111,5 @@ doxygen_add_docs() for target ${targetName}") ) endfunction() + +cmake_policy(POP) diff --git a/Modules/FindMPI.cmake b/Modules/FindMPI.cmake index 75c4441..bfcd876 100644 --- a/Modules/FindMPI.cmake +++ b/Modules/FindMPI.cmake @@ -1680,7 +1680,7 @@ foreach(LANG IN ITEMS C CXX Fortran) set(MPI_${LANG}_INCLUDE_PATH "${MPI_${LANG}_INCLUDE_DIRS}") unset(MPI_${LANG}_COMPILE_FLAGS) if(MPI_${LANG}_COMPILE_OPTIONS) - set(MPI_${LANG}_COMPILE_FLAGS "${MPI_${LANG}_COMPILE_OPTIONS}") + list(JOIN MPI_${LANG}_COMPILE_FLAGS " " MPI_${LANG}_COMPILE_OPTIONS) endif() if(MPI_${LANG}_COMPILE_DEFINITIONS) foreach(_MPI_DEF IN LISTS MPI_${LANG}_COMPILE_DEFINITIONS) diff --git a/Modules/FindOpenThreads.cmake b/Modules/FindOpenThreads.cmake index a197e4d..91545e0 100644 --- a/Modules/FindOpenThreads.cmake +++ b/Modules/FindOpenThreads.cmake @@ -47,6 +47,8 @@ # standard install paths. # Explicit -DVAR=value arguments should still be able to override everything. +include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake) + find_path(OPENTHREADS_INCLUDE_DIR OpenThreads/Thread HINTS ENV OPENTHREADS_INCLUDE_DIR @@ -62,7 +64,7 @@ find_path(OPENTHREADS_INCLUDE_DIR OpenThreads/Thread ) -find_library(OPENTHREADS_LIBRARY +find_library(OPENTHREADS_LIBRARY_RELEASE NAMES OpenThreads OpenThreadsWin32 HINTS ENV OPENTHREADS_LIBRARY_DIR @@ -93,13 +95,7 @@ find_library(OPENTHREADS_LIBRARY_DEBUG PATH_SUFFIXES lib ) -if(OPENTHREADS_LIBRARY_DEBUG) - set(OPENTHREADS_LIBRARIES - optimized ${OPENTHREADS_LIBRARY} - debug ${OPENTHREADS_LIBRARY_DEBUG}) -else() - set(OPENTHREADS_LIBRARIES ${OPENTHREADS_LIBRARY}) -endif() +select_library_configurations(OPENTHREADS) include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenThreads DEFAULT_MSG diff --git a/Modules/FindPython.cmake b/Modules/FindPython.cmake index 8139e53..0bf0b4f 100644 --- a/Modules/FindPython.cmake +++ b/Modules/FindPython.cmake @@ -116,6 +116,25 @@ Hints * If set to TRUE, search **only** for static libraries. * If set to FALSE, search **only** for shared libraries. +``Python_FIND_REGISTRY`` + On Windows the ``Python_FIND_REGISTRY`` variable determine the order + of preference between registry and environment variables. + the ``Python_FIND_REGISTRY`` variable can be set to empty or one of the + following: + + * ``FIRST``: Try to use registry before environment variables. + This is the default. + * ``LAST``: Try to use registry after environment variables. + * ``NEVER``: Never try to use registry. + +``CMAKE_FIND_FRAMEWORK`` + On OS X the :variable:`CMAKE_FIND_FRAMEWORK` variable determine the order of + preference between Apple-style and unix-style package components. + + .. note:: + + Value ``ONLY`` is not supported so ``FIRST`` will be used instead. + Commands ^^^^^^^^ diff --git a/Modules/FindPython/Support.cmake b/Modules/FindPython/Support.cmake index fe3df91..1834591 100644 --- a/Modules/FindPython/Support.cmake +++ b/Modules/FindPython/Support.cmake @@ -44,9 +44,28 @@ macro (_PYTHON_DISPLAY_FAILURE _PYTHON_MSG) endmacro() +macro (_PYTHON_FIND_FRAMEWORKS) + set (${_PYTHON_PREFIX}_FRAMEWORKS) + if (APPLE) + set (_pff_frameworks ${CMAKE_FRAMEWORK_PATH} + $ENV{CMAKE_FRAMEWORK_PATH} + ~/Library/Frameworks + /usr/local/Frameworks + ${CMAKE_SYSTEM_FRAMEWORK_PATH}) + list (REMOVE_DUPLICATES _pff_frameworks) + foreach (_pff_framework IN LISTS _pff_frameworks) + if (EXISTS ${_pff_framework}/Python.framework) + list (APPEND ${_PYTHON_PREFIX}_FRAMEWORKS ${_pff_framework}/Python.framework) + endif() + endforeach() + unset (_pff_frameworks) + unset (_pff_framework) + endif() +endmacro() + function (_PYTHON_GET_FRAMEWORKS _PYTHON_PGF_FRAMEWORK_PATHS _PYTHON_VERSION) set (_PYTHON_FRAMEWORK_PATHS) - foreach (_PYTHON_FRAMEWORK IN LISTS Python_FRAMEWORKS) + foreach (_PYTHON_FRAMEWORK IN LISTS ${_PYTHON_PREFIX}_FRAMEWORKS) list (APPEND _PYTHON_FRAMEWORK_PATHS "${_PYTHON_FRAMEWORK}/Versions/${_PYTHON_VERSION}") endforeach() @@ -59,20 +78,43 @@ function (_PYTHON_VALIDATE_INTERPRETER) return() endif() - if (${_PYTHON_PREFIX}_EXECUTABLE MATCHES "python${CMAKE_EXECUTABLE_SUFFIX}$") - # executable found do not have version in name - # ensure major version is OK + if (ARGC EQUAL 1) + set (expected_version ${ARGV0}) + else() + unset (expected_version) + endif() + + get_filename_component (python_name "${${_PYTHON_PREFIX}_EXECUTABLE}" NAME) + + if (expected_version AND NOT python_name STREQUAL "python${expected_version}${CMAKE_EXECUTABLE_SUFFIX}") + # executable found must have a specific version execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys; sys.stdout.write(str(sys.version_info[0]))" + "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:2]]))" RESULT_VARIABLE result OUTPUT_VARIABLE version ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) - if (result OR NOT version EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) + if (result OR NOT version EQUAL expected_version) # interpreter not usable or has wrong major version set (${_PYTHON_PREFIX}_EXECUTABLE ${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND CACHE INTERNAL "" FORCE) return() endif() + else() + if (NOT python_name STREQUAL "python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}${CMAKE_EXECUTABLE_SUFFIX}") + # executable found do not have version in name + # ensure major version is OK + execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c + "import sys; sys.stdout.write(str(sys.version_info[0]))" + RESULT_VARIABLE result + OUTPUT_VARIABLE version + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + if (result OR NOT version EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) + # interpreter not usable or has wrong major version + set (${_PYTHON_PREFIX}_EXECUTABLE ${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND CACHE INTERNAL "" FORCE) + return() + endif() + endif() endif() if (CMAKE_SIZEOF_VOID_P AND "Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS @@ -93,6 +135,33 @@ function (_PYTHON_VALIDATE_INTERPRETER) endfunction() +function (_PYTHON_VALIDATE_COMPILER expected_version) + if (NOT ${_PYTHON_PREFIX}_COMPILER) + return() + endif() + + # retrieve python environment version from compiler + set (working_dir "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/PythonCompilerVersion.dir") + file (WRITE "${working_dir}/version.py" "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:2]]))\n") + execute_process (COMMAND "${${_PYTHON_PREFIX}_COMPILER}" /target:exe /embed "${working_dir}/version.py" + WORKING_DIRECTORY "${working_dir}" + OUTPUT_QUIET + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + execute_process (COMMAND "${working_dir}/version" + WORKING_DIRECTORY "${working_dir}" + RESULT_VARIABLE result + OUTPUT_VARIABLE version + ERROR_QUIET) + file (REMOVE_RECURSE "${_${_PYTHON_PREFIX}_VERSION_DIR}") + + if (result OR NOT version EQUAL expected_version) + # Compiler not usable or has wrong major version + set (${_PYTHON_PREFIX}_COMPILER ${_PYTHON_PREFIX}_COMPILER-NOTFOUND CACHE INTERNAL "" FORCE) + endif() +endfunction() + + function (_PYTHON_FIND_RUNTIME_LIBRARY _PYTHON_LIB) string (REPLACE "_RUNTIME" "" _PYTHON_LIB "${_PYTHON_LIB}") # look at runtime part on systems supporting it @@ -181,19 +250,47 @@ else() # architecture unknown, search for natural interpreter set (_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES ipy) endif() +set (_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES net45 net40) # Apple frameworks handling -include (${CMAKE_CURRENT_LIST_DIR}/../CMakeFindFrameworks.cmake) -cmake_find_frameworks (Python) +_python_find_frameworks () + +# Save CMAKE_FIND_APPBUNDLE +if (DEFINED CMAKE_FIND_APPBUNDLE) + set (_${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE ${CMAKE_FIND_APPBUNDLE}) +else() + unset (_${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE) +endif() +# To avoid app bundle lookup +set (CMAKE_FIND_APPBUNDLE "NEVER") # Save CMAKE_FIND_FRAMEWORK if (DEFINED CMAKE_FIND_FRAMEWORK) set (_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK ${CMAKE_FIND_FRAMEWORK}) + if (CMAKE_FIND_FRAMEWORK STREQUAL "ONLY") + message (AUTHOR_WARNING "Find${_PYTHON_PREFIX}: CMAKE_FIND_FRAMEWORK: 'ONLY' value is not supported. 'FIRST' will be used instead.") + set (_${_PYTHON_PREFIX}_FIND_FRAMEWORK "FIRST") + else() + set (_${_PYTHON_PREFIX}_FIND_FRAMEWORK ${CMAKE_FIND_FRAMEWORK}) + endif() else() unset (_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK) + set (_${_PYTHON_PREFIX}_FIND_FRAMEWORK "FIRST") +endif() +# To avoid framework lookup +set (CMAKE_FIND_FRAMEWORK "NEVER") + +# Windows Registry handling +if (DEFINED ${_PYTHON_PREFIX}_FIND_REGISTRY) + if (NOT ${_PYTHON_PREFIX}_FIND_REGISTRY MATCHES "^(FIRST|LAST|NEVER)$") + message (AUTHOR_WARNING "Find${_PYTHON_PREFIX}: ${${_PYTHON_PREFIX}_FIND_REGISTRY}: invalid value for '${_PYTHON_PREFIX}_FIND_REGISTRY'. 'FIRST', 'LAST' or 'NEVER' expected.") + set (_${_PYTHON_PREFIX}_FIND_REGISTRY "FIRST") + else() + set (_${_PYTHON_PREFIX}_FIND_REGISTRY ${${_PYTHON_PREFIX}_FIND_REGISTRY}) + endif() +else() + set (_${_PYTHON_PREFIX}_FIND_REGISTRY "FIRST") endif() -# To avoid picking up the system elements pre-maturely. -set (CMAKE_FIND_FRAMEWORK LAST) unset (_${_PYTHON_PREFIX}_REQUIRED_VARS) @@ -215,22 +312,83 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION}) + # Apple frameworks handling + if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") + find_program (${_PYTHON_PREFIX}_EXECUTABLE + NAMES python${_${_PYTHON_PREFIX}_VERSION} + python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} + NAMES_PER_DIR + PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} + PATH_SUFFIXES bin + NO_CMAKE_PATH + NO_CMAKE_ENVIRONMENT_PATH + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) + endif() + + # Windows registry + if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") + find_program (${_PYTHON_PREFIX}_EXECUTABLE + NAMES python${_${_PYTHON_PREFIX}_VERSION} + python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} + python + ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} + NAMES_PER_DIR + HINTS ${_${_PYTHON_PREFIX}_HINTS} + PATHS [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] + [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] + [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] + [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] + [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] + [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] + [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] + PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) + endif() + # try using HINTS find_program (${_PYTHON_PREFIX}_EXECUTABLE NAMES python${_${_PYTHON_PREFIX}_VERSION} + python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} + python + ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} NAMES_PER_DIR HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} PATH_SUFFIXES bin NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH) - # try using registry - if (WIN32) + # try using standard paths. + # NAMES_PER_DIR is not defined on purpose to have a chance to find + # expected version. + # For example, typical systems have 'python' for version 2.* and 'python3' + # for version 3.*. So looking for names per dir will find, potentially, + # systematically 'python' (i.e. version 2) even if version 3 is searched. + find_program (${_PYTHON_PREFIX}_EXECUTABLE + NAMES python${_${_PYTHON_PREFIX}_VERSION} + python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} + python + ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}) + + # Apple frameworks handling + if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST") find_program (${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_VERSION} python + NAMES python${_${_PYTHON_PREFIX}_VERSION} + python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} + NAMES_PER_DIR + PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} + PATH_SUFFIXES bin + NO_DEFAULT_PATH) + endif() + + # Windows registry + if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") + find_program (${_PYTHON_PREFIX}_EXECUTABLE + NAMES python${_${_PYTHON_PREFIX}_VERSION} + python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} + python ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} PATHS [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] @@ -238,27 +396,37 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - PATH_SUFFIXES bin - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) + PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} + NO_DEFAULT_PATH) endif() - # try in standard paths - find_program (${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_VERSION}) - _python_validate_interpreter () + _python_validate_interpreter (${_${_PYTHON_PREFIX}_VERSION}) if (${_PYTHON_PREFIX}_EXECUTABLE) break() endif() endforeach() - # try more generic names if (NOT ${_PYTHON_PREFIX}_EXECUTABLE) + # No specific version found. Retry with generic names + # try using HINTS find_program (${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} python + NAMES python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} + python ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin) + PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) + # try using standard paths. + # NAMES_PER_DIR is not defined on purpose to have a chance to find + # expected version. + # For example, typical systems have 'python' for version 2.* and 'python3' + # for version 3.*. So looking for names per dir will find, potentially, + # systematically 'python' (i.e. version 2) even if version 3 is searched. + find_program (${_PYTHON_PREFIX}_EXECUTABLE + NAMES python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} + python + ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}) _python_validate_interpreter () endif() @@ -359,19 +527,42 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) # try using root dir and registry foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) + if (_${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") + find_program (${_PYTHON_PREFIX}_COMPILER + NAMES ipyc + HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS} + PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] + PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) + endif() + find_program (${_PYTHON_PREFIX}_COMPILER NAMES ipyc HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS} - PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] + PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH) + + if (_${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") + find_program (${_PYTHON_PREFIX}_COMPILER + NAMES ipyc + PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] + PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} + NO_DEFAULT_PATH) + endif() + + _python_validate_compiler (${_${_PYTHON_PREFIX}_VERSION}) if (${_PYTHON_PREFIX}_COMPILER) break() endif() endforeach() - # try in standard paths + + # no specific version found, re-try in standard paths find_program (${_PYTHON_PREFIX}_COMPILER - NAMES ipyc) + NAMES ipyc + HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS} + PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}) if (${_PYTHON_PREFIX}_COMPILER) # retrieve python environment version from compiler @@ -483,6 +674,7 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS list (APPEND _${_PYTHON_PREFIX}_CONFIG_NAMES "python${_${_PYTHON_PREFIX}_VERSION}-config") find_program (_${_PYTHON_PREFIX}_CONFIG NAMES ${_${_PYTHON_PREFIX}_CONFIG_NAMES} + NAMES_PER_DIR HINTS ${_${_PYTHON_PREFIX}_HINTS} PATH_SUFFIXES bin) unset (_${_PYTHON_PREFIX}_CONFIG_NAMES) @@ -571,7 +763,54 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION}) - # search first in known locations + set (_${_PYTHON_PREFIX}_REGISTRY_PATHS + [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] + [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] + [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] + [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]) + + if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") + find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE + NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} + python${_${_PYTHON_PREFIX}_VERSION}mu + python${_${_PYTHON_PREFIX}_VERSION}m + python${_${_PYTHON_PREFIX}_VERSION}u + python${_${_PYTHON_PREFIX}_VERSION} + NAMES_PER_DIR + PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} + PATH_SUFFIXES lib/${CMAKE_LIBRARY_ARCHITECTURE} lib libs + lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}mu + lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}m + lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}u + lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION} + lib/python${_${_PYTHON_PREFIX}_VERSION}/config + NO_CMAKE_PATH + NO_CMAKE_ENVIRONMENT_PATH + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) + endif() + + if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") + find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE + NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} + python${_${_PYTHON_PREFIX}_VERSION}mu + python${_${_PYTHON_PREFIX}_VERSION}m + python${_${_PYTHON_PREFIX}_VERSION}u + python${_${_PYTHON_PREFIX}_VERSION} + NAMES_PER_DIR + HINTS ${_${_PYTHON_PREFIX}_HINTS} + PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} + PATH_SUFFIXES lib/${CMAKE_LIBRARY_ARCHITECTURE} lib libs + lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}mu + lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}m + lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}u + lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION} + lib/python${_${_PYTHON_PREFIX}_VERSION}/config + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) + endif() + + # search in HINTS locations find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} python${_${_PYTHON_PREFIX}_VERSION}mu @@ -580,11 +819,6 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS python${_${_PYTHON_PREFIX}_VERSION} NAMES_PER_DIR HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] PATH_SUFFIXES lib/${CMAKE_LIBRARY_ARCHITECTURE} lib libs lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}mu lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}m @@ -593,6 +827,19 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS lib/python${_${_PYTHON_PREFIX}_VERSION}/config NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH) + + if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST") + set (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}) + else() + unset (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS) + endif() + + if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") + set (__${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}) + else() + unset (__${_PYTHON_PREFIX}_REGISTRY_PATHS) + endif() + # search in all default paths find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} @@ -601,6 +848,8 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS python${_${_PYTHON_PREFIX}_VERSION}u python${_${_PYTHON_PREFIX}_VERSION} NAMES_PER_DIR + PATHS ${__${_PYTHON_PREFIX}_FRAMEWORK_PATHS} + ${__${_PYTHON_PREFIX}_REGISTRY_PATHS} PATH_SUFFIXES lib/${CMAKE_LIBRARY_ARCHITECTURE} lib libs lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}mu lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}m @@ -618,11 +867,6 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS python${_${_PYTHON_PREFIX}_VERSION} NAMES_PER_DIR HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] PATH_SUFFIXES bin) endif() @@ -632,27 +876,28 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS # use library location as a hint get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY) find_library (${_PYTHON_PREFIX}_LIBRARY_DEBUG - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d - NAMES_PER_DIR - HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS} - NO_DEFAULT_PATH) - else() - # search first in known locations - find_library (${_PYTHON_PREFIX}_LIBRARY_DEBUG NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - PATH_SUFFIXES lib libs - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) + HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS} + NO_DEFAULT_PATH) + else() + # search first in known locations + if (_${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") + find_library (${_PYTHON_PREFIX}_LIBRARY_DEBUG + NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d + NAMES_PER_DIR + HINTS ${_${_PYTHON_PREFIX}_HINTS} + PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} + PATH_SUFFIXES lib libs + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) + endif() # search in all default paths find_library (${_PYTHON_PREFIX}_LIBRARY_DEBUG NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d NAMES_PER_DIR + HINTS ${_${_PYTHON_PREFIX}_HINTS} + PATHS ${__${_PYTHON_PREFIX}_REGISTRY_PATHS} PATH_SUFFIXES lib libs) endif() if (${_PYTHON_PREFIX}_LIBRARY_DEBUG) @@ -661,10 +906,6 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d NAMES_PER_DIR HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS} - PATHS [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] PATH_SUFFIXES bin) endif() endif() @@ -672,6 +913,21 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS # Don't search for include dir until library location is known if (${_PYTHON_PREFIX}_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG) unset (_${_PYTHON_PREFIX}_INCLUDE_HINTS) + + if (${_PYTHON_PREFIX}_EXECUTABLE) + # pick up include directory from configuration + execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c + "import sys; import sysconfig; sys.stdout.write(sysconfig.get_path('include'))" + RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT + OUTPUT_VARIABLE _${_PYTHON_PREFIX}_PATH + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + if (NOT _${_PYTHON_PREFIX}_RESULT) + file (TO_CMAKE_PATH "${_${_PYTHON_PREFIX}_PATH}" _${_PYTHON_PREFIX}_PATH) + list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${_${_PYTHON_PREFIX}_PATH}") + endif() + endif() + foreach (_${_PYTHON_PREFIX}_LIB IN ITEMS ${_PYTHON_PREFIX}_LIBRARY_RELEASE ${_PYTHON_PREFIX}_LIBRARY_DEBUG) if (${_${_PYTHON_PREFIX}_LIB}) # Use the library's install prefix as a hint @@ -691,14 +947,41 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS endforeach() list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_INCLUDE_HINTS) + if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") + find_path (${_PYTHON_PREFIX}_INCLUDE_DIR + NAMES Python.h + HINTS ${_${_PYTHON_PREFIX}_HINTS} + PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} + PATH_SUFFIXES include/python${_${_PYTHON_PREFIX}_VERSION}mu + include/python${_${_PYTHON_PREFIX}_VERSION}m + include/python${_${_PYTHON_PREFIX}_VERSION}u + include/python${_${_PYTHON_PREFIX}_VERSION} + include + NO_CMAKE_PATH + NO_CMAKE_ENVIRONMENT_PATH + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) + endif() + + if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") + find_path (${_PYTHON_PREFIX}_INCLUDE_DIR + NAMES Python.h + HINTS ${_${_PYTHON_PREFIX}_INCLUDE_HINTS} ${_${_PYTHON_PREFIX}_HINTS} + PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} + PATH_SUFFIXES include/python${_${_PYTHON_PREFIX}_VERSION}mu + include/python${_${_PYTHON_PREFIX}_VERSION}m + include/python${_${_PYTHON_PREFIX}_VERSION}u + include/python${_${_PYTHON_PREFIX}_VERSION} + include + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) + endif() + find_path (${_PYTHON_PREFIX}_INCLUDE_DIR NAMES Python.h HINTS ${_${_PYTHON_PREFIX}_INCLUDE_HINTS} ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] + PATHS ${__${_PYTHON_PREFIX}_FRAMEWORK_PATHS} + ${__${_PYTHON_PREFIX}_REGISTRY_PATHS} PATH_SUFFIXES include/python${_${_PYTHON_PREFIX}_VERSION}mu include/python${_${_PYTHON_PREFIX}_VERSION}m include/python${_${_PYTHON_PREFIX}_VERSION}u @@ -914,6 +1197,13 @@ endif() # final clean-up +# Restore CMAKE_FIND_APPBUNDLE +if (DEFINED _${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE) + set (CMAKE_FIND_APPBUNDLE ${_${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE}) + unset (_${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE) +else() + unset (CMAKE_FIND_APPBUNDLE) +endif() # Restore CMAKE_FIND_FRAMEWORK if (DEFINED _${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK) set (CMAKE_FIND_FRAMEWORK ${_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK}) diff --git a/Modules/FindPython2.cmake b/Modules/FindPython2.cmake index 22e9a8f..2735a25 100644 --- a/Modules/FindPython2.cmake +++ b/Modules/FindPython2.cmake @@ -117,6 +117,25 @@ Hints * If set to TRUE, search **only** for static libraries. * If set to FALSE, search **only** for shared libraries. +``Python2_FIND_REGISTRY`` + On Windows the ``Python2_FIND_REGISTRY`` variable determine the order + of preference between registry and environment variables. + the ``Python2_FIND_REGISTRY`` variable can be set to empty or one of the + following: + + * ``FIRST``: Try to use registry before environment variables. + This is the default. + * ``LAST``: Try to use registry after environment variables. + * ``NEVER``: Never try to use registry. + +``CMAKE_FIND_FRAMEWORK`` + On macOS the :variable:`CMAKE_FIND_FRAMEWORK` variable determine the order of + preference between Apple-style and unix-style package components. + + .. note:: + + Value ``ONLY`` is not supported so ``FIRST`` will be used instead. + Commands ^^^^^^^^ diff --git a/Modules/FindPython3.cmake b/Modules/FindPython3.cmake index 99c159b..ed7e1a3 100644 --- a/Modules/FindPython3.cmake +++ b/Modules/FindPython3.cmake @@ -117,6 +117,25 @@ Hints * If set to TRUE, search **only** for static libraries. * If set to FALSE, search **only** for shared libraries. +``Python3_FIND_REGISTRY`` + On Windows the ``Python3_FIND_REGISTRY`` variable determine the order + of preference between registry and environment variables. + the ``Python3_FIND_REGISTRY`` variable can be set to empty or one of the + following: + + * ``FIRST``: Try to use registry before environment variables. + This is the default. + * ``LAST``: Try to use registry after environment variables. + * ``NEVER``: Never try to use registry. + +``CMAKE_FIND_FRAMEWORK`` + On OS X the :variable:`CMAKE_FIND_FRAMEWORK` variable determine the order of + preference between Apple-style and unix-style package components. + + .. note:: + + Value ``ONLY`` is not supported so ``FIRST`` will be used instead. + Commands ^^^^^^^^ diff --git a/Modules/FindSubversion.cmake b/Modules/FindSubversion.cmake index 537d3b2..e18ae88 100644 --- a/Modules/FindSubversion.cmake +++ b/Modules/FindSubversion.cmake @@ -19,17 +19,21 @@ # # # The minimum required version of Subversion can be specified using the -# standard syntax, e.g. find_package(Subversion 1.4) +# standard syntax, e.g. ``find_package(Subversion 1.4)``. # # If the command line client executable is found two macros are defined: # # :: # -# Subversion_WC_INFO(<dir> <var-prefix>) +# Subversion_WC_INFO(<dir> <var-prefix> [IGNORE_SVN_FAILURE]) # Subversion_WC_LOG(<dir> <var-prefix>) # -# Subversion_WC_INFO extracts information of a subversion working copy -# at a given location. This macro defines the following variables: +# ``Subversion_WC_INFO`` extracts information of a subversion working copy at a +# given location. This macro defines the following variables if running +# Subversion's ``info`` command on ``<dir>`` succeeds; otherwise a +# ``SEND_ERROR`` message is generated. The error can be ignored by providing the +# ``IGNORE_SVN_FAILURE`` option, which causes these variables to remain +# undefined. # # :: # @@ -41,9 +45,8 @@ # <var-prefix>_WC_LAST_CHANGED_REV - revision of last commit # <var-prefix>_WC_INFO - output of command `svn info <dir>' # -# Subversion_WC_LOG retrieves the log message of the base revision of a -# subversion working copy at a given location. This macro defines the -# variable: +# ``Subversion_WC_LOG`` retrieves the log message of the base revision of a +# subversion working copy at a given location. This macro defines the variable: # # :: # @@ -84,6 +87,14 @@ if(Subversion_SVN_EXECUTABLE) "\\2" Subversion_VERSION_SVN "${Subversion_VERSION_SVN}") macro(Subversion_WC_INFO dir prefix) + + cmake_parse_arguments( + "Subversion_WC_INFO" + "IGNORE_SVN_FAILURE" + "" "" + ${ARGN} + ) + # the subversion commands should be executed with the C locale, otherwise # the message (which are parsed) may be translated, Alex set(_Subversion_SAVED_LC_ALL "$ENV{LC_ALL}") @@ -95,10 +106,7 @@ if(Subversion_SVN_EXECUTABLE) RESULT_VARIABLE Subversion_svn_info_result OUTPUT_STRIP_TRAILING_WHITESPACE) - if(NOT ${Subversion_svn_info_result} EQUAL 0) - message(SEND_ERROR "Command \"${Subversion_SVN_EXECUTABLE} info ${dir}\" failed with output:\n${Subversion_svn_info_error}") - else() - + if(${Subversion_svn_info_result} EQUAL 0) string(REGEX REPLACE "^(.*\n)?URL: ([^\n]+).*" "\\2" ${prefix}_WC_URL "${${prefix}_WC_INFO}") string(REGEX REPLACE "^(.*\n)?Repository Root: ([^\n]+).*" @@ -111,7 +119,8 @@ if(Subversion_SVN_EXECUTABLE) "\\2" ${prefix}_WC_LAST_CHANGED_REV "${${prefix}_WC_INFO}") string(REGEX REPLACE "^(.*\n)?Last Changed Date: ([^\n]+).*" "\\2" ${prefix}_WC_LAST_CHANGED_DATE "${${prefix}_WC_INFO}") - + elseif(NOT Subversion_WC_INFO_IGNORE_SVN_FAILURE) + message(SEND_ERROR "Command \"${Subversion_SVN_EXECUTABLE} info ${dir}\" failed with output:\n${Subversion_svn_info_error}") endif() # restore the previous LC_ALL diff --git a/Modules/Findosg_functions.cmake b/Modules/Findosg_functions.cmake index 60de726..adaeb6b 100644 --- a/Modules/Findosg_functions.cmake +++ b/Modules/Findosg_functions.cmake @@ -13,6 +13,8 @@ # libraries and nodekits. Please see FindOpenSceneGraph.cmake for full # documentation. +include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake) + # # OSG_FIND_PATH # @@ -39,7 +41,7 @@ endfunction() function(OSG_FIND_LIBRARY module library) string(TOUPPER ${module} module_uc) - find_library(${module_uc}_LIBRARY + find_library(${module_uc}_LIBRARY_RELEASE NAMES ${library} HINTS ENV ${module_uc}_DIR @@ -63,18 +65,12 @@ function(OSG_FIND_LIBRARY module library) PATH_SUFFIXES lib ) - if(NOT ${module_uc}_LIBRARY_DEBUG) - # They don't have a debug library - set(${module_uc}_LIBRARY_DEBUG ${${module_uc}_LIBRARY} PARENT_SCOPE) - set(${module_uc}_LIBRARIES ${${module_uc}_LIBRARY} PARENT_SCOPE) - else() - # They really have a FOO_LIBRARY_DEBUG - set(${module_uc}_LIBRARIES - optimized ${${module_uc}_LIBRARY} - debug ${${module_uc}_LIBRARY_DEBUG} - PARENT_SCOPE - ) - endif() + select_library_configurations(${module_uc}) + + # the variables set by select_library_configurations go out of scope + # here, so we need to set them again + set(${module_uc}_LIBRARY ${${module_uc}_LIBRARY} PARENT_SCOPE) + set(${module_uc}_LIBRARIES ${${module_uc}_LIBRARIES} PARENT_SCOPE) endfunction() # diff --git a/Modules/GoogleTest.cmake b/Modules/GoogleTest.cmake index 2c9ee11..a5bb863 100644 --- a/Modules/GoogleTest.cmake +++ b/Modules/GoogleTest.cmake @@ -308,7 +308,7 @@ function(gtest_add_tests) set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${source}) endif() file(READ "${source}" contents) - string(REGEX MATCHALL "${gtest_test_type_regex} *\\(([A-Za-z_0-9 ,]+)\\)" found_tests ${contents}) + string(REGEX MATCHALL "${gtest_test_type_regex} *\\(([A-Za-z_0-9 ,]+)\\)" found_tests "${contents}") foreach(hit ${found_tests}) string(REGEX MATCH "${gtest_test_type_regex}" test_type ${hit}) diff --git a/Modules/Internal/CPack/CPackDeb.cmake b/Modules/Internal/CPack/CPackDeb.cmake index 4ef4539..ca3a004 100644 --- a/Modules/Internal/CPack/CPackDeb.cmake +++ b/Modules/Internal/CPack/CPackDeb.cmake @@ -10,6 +10,9 @@ if(CMAKE_BINARY_DIR) message(FATAL_ERROR "CPackDeb.cmake may only be used by CPack internally.") endif() +cmake_policy(PUSH) +cmake_policy(SET CMP0057 NEW) # if IN_LIST + function(cpack_deb_variable_fallback OUTPUT_VAR_NAME) set(FALLBACK_VAR_NAMES ${ARGN}) @@ -579,3 +582,5 @@ function(cpack_deb_prepare_package_vars) endfunction() cpack_deb_prepare_package_vars() + +cmake_policy(POP) diff --git a/Modules/Internal/CPack/CPackRPM.cmake b/Modules/Internal/CPack/CPackRPM.cmake index 06298d7..3bd5147 100644 --- a/Modules/Internal/CPack/CPackRPM.cmake +++ b/Modules/Internal/CPack/CPackRPM.cmake @@ -3,6 +3,9 @@ # Author: Eric Noulard with the help of Alexander Neundorf. +cmake_policy(PUSH) +cmake_policy(SET CMP0057 NEW) # if IN_LIST + function(get_file_permissions FILE RETURN_VAR) execute_process(COMMAND ls -l ${FILE} OUTPUT_VARIABLE permissions_ @@ -1865,3 +1868,5 @@ mv %_topdir/tmpBBroot $RPM_BUILD_ROOT endfunction() cpack_rpm_generate_package() + +cmake_policy(POP) diff --git a/Modules/Platform/Android-Determine.cmake b/Modules/Platform/Android-Determine.cmake index e623902..bb42eed 100644 --- a/Modules/Platform/Android-Determine.cmake +++ b/Modules/Platform/Android-Determine.cmake @@ -18,6 +18,9 @@ if(CMAKE_SYSTEM_VERSION EQUAL 1) return() endif() +cmake_policy(PUSH) +cmake_policy(SET CMP0057 NEW) # if IN_LIST + # If the user provided CMAKE_SYSROOT for us, extract information from it. set(_ANDROID_SYSROOT_NDK "") set(_ANDROID_SYSROOT_API "") @@ -371,3 +374,5 @@ endif() # Report the chosen architecture. message(STATUS "Android: Targeting API '${CMAKE_SYSTEM_VERSION}' with architecture '${CMAKE_ANDROID_ARCH}', ABI '${CMAKE_ANDROID_ARCH_ABI}', and processor '${CMAKE_SYSTEM_PROCESSOR}'") + +cmake_policy(POP) diff --git a/Modules/ProcessorCount.cmake b/Modules/ProcessorCount.cmake index 772a615..8a37884 100644 --- a/Modules/ProcessorCount.cmake +++ b/Modules/ProcessorCount.cmake @@ -12,7 +12,7 @@ # Sets the variable named ${var} to the number of physical cores # available on the machine if the information can be determined. # Otherwise it is set to 0. Currently this functionality is implemented -# for AIX, cygwin, FreeBSD, HPUX, IRIX, Linux, Mac OS X, QNX, Sun and +# for AIX, cygwin, FreeBSD, HPUX, IRIX, Linux, macOS, QNX, Sun and # Windows. # # This function is guaranteed to return a positive integer (>=1) if it diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 0457984..628cc6f 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -265,6 +265,7 @@ set(SRCS cmInstallDirectoryGenerator.h cmInstallDirectoryGenerator.cxx cmLinkedTree.h + cmLinkItem.cxx cmLinkItem.h cmLinkLineComputer.cxx cmLinkLineComputer.h diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index e46ab68..1a5fd15 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 12) -set(CMake_VERSION_PATCH 20180907) +set(CMake_VERSION_PATCH 20180919) #set(CMake_VERSION_RC 1) diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx index 6347eed..acd6650 100644 --- a/Source/CPack/cmCPackGenerator.cxx +++ b/Source/CPack/cmCPackGenerator.cxx @@ -360,8 +360,6 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories( return 0; } files = gl.GetFiles(); - std::vector<std::string>::iterator gfit; - std::vector<cmsys::RegularExpression>::iterator regIt; for (std::string const& gf : files) { bool skip = false; std::string inFile = gf; @@ -1499,7 +1497,6 @@ cmCPackComponent* cmCPackGenerator::GetComponent( if (installTypes && *installTypes) { std::vector<std::string> installTypesVector; cmSystemTools::ExpandListArgument(installTypes, installTypesVector); - std::vector<std::string>::iterator installTypesIt; for (std::string const& installType : installTypesVector) { component->InstallationTypes.push_back( this->GetInstallationType(projectName, installType)); @@ -1511,7 +1508,6 @@ cmCPackComponent* cmCPackGenerator::GetComponent( if (depends && *depends) { std::vector<std::string> dependsVector; cmSystemTools::ExpandListArgument(depends, dependsVector); - std::vector<std::string>::iterator dependIt; for (std::string const& depend : dependsVector) { cmCPackComponent* child = GetComponent(projectName, depend); component->Dependencies.push_back(child); diff --git a/Source/CTest/cmCTestHandlerCommand.cxx b/Source/CTest/cmCTestHandlerCommand.cxx index 8863dc8..667a8ba 100644 --- a/Source/CTest/cmCTestHandlerCommand.cxx +++ b/Source/CTest/cmCTestHandlerCommand.cxx @@ -151,9 +151,9 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args, cmSystemTools::CollapseFullPath(this->Values[ct_BUILD]).c_str(), this->Quiet); } else { - const char* bdir = + std::string const& bdir = this->Makefile->GetSafeDefinition("CTEST_BINARY_DIRECTORY"); - if (bdir) { + if (!bdir.empty()) { this->CTest->SetCTestConfiguration( "BuildDirectory", cmSystemTools::CollapseFullPath(bdir).c_str(), this->Quiet); diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx index 52db9d4..3e0c1ac 100644 --- a/Source/CTest/cmCTestMultiProcessHandler.cxx +++ b/Source/CTest/cmCTestMultiProcessHandler.cxx @@ -5,7 +5,6 @@ #include "cmAffinity.h" #include "cmCTest.h" #include "cmCTestRunTest.h" -#include "cmCTestScriptHandler.h" #include "cmCTestTestHandler.h" #include "cmSystemTools.h" #include "cmWorkingDirectory.h" @@ -52,11 +51,11 @@ cmCTestMultiProcessHandler::cmCTestMultiProcessHandler() { this->ParallelLevel = 1; this->TestLoad = 0; + this->FakeLoadForTesting = 0; this->Completed = 0; this->RunningCount = 0; this->ProcessorsAvailable = cmAffinity::GetProcessorsAvailable(); this->HaveAffinity = this->ProcessorsAvailable.size(); - this->StopTimePassed = false; this->HasCycles = false; this->SerialTestRunning = false; } @@ -96,6 +95,16 @@ void cmCTestMultiProcessHandler::SetParallelLevel(size_t level) void cmCTestMultiProcessHandler::SetTestLoad(unsigned long load) { this->TestLoad = load; + + std::string fake_load_value; + if (cmSystemTools::GetEnv("__CTEST_FAKE_LOAD_AVERAGE_FOR_TESTING", + fake_load_value)) { + if (!cmSystemTools::StringToULong(fake_load_value.c_str(), + &this->FakeLoadForTesting)) { + cmSystemTools::Error("Failed to parse fake load value: ", + fake_load_value.c_str()); + } + } } void cmCTestMultiProcessHandler::RunTests() @@ -120,17 +129,6 @@ void cmCTestMultiProcessHandler::RunTests() bool cmCTestMultiProcessHandler::StartTestProcess(int test) { - std::chrono::system_clock::time_point stop_time = this->CTest->GetStopTime(); - if (stop_time != std::chrono::system_clock::time_point() && - stop_time <= std::chrono::system_clock::now()) { - cmCTestLog(this->CTest, ERROR_MESSAGE, - "The stop time has been passed. " - "Stopping all tests." - << std::endl); - this->StopTimePassed = true; - return false; - } - if (this->HaveAffinity && this->Properties[test]->WantAffinity) { size_t needProcessors = this->GetProcessorsUsed(test); if (needProcessors > this->ProcessorsAvailable.size()) { @@ -189,6 +187,30 @@ bool cmCTestMultiProcessHandler::StartTestProcess(int test) return false; } +bool cmCTestMultiProcessHandler::CheckStopTimePassed() +{ + if (!this->StopTimePassed) { + std::chrono::system_clock::time_point stop_time = + this->CTest->GetStopTime(); + if (stop_time != std::chrono::system_clock::time_point() && + stop_time <= std::chrono::system_clock::now()) { + this->SetStopTimePassed(); + } + } + return this->StopTimePassed; +} + +void cmCTestMultiProcessHandler::SetStopTimePassed() +{ + if (!this->StopTimePassed) { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "The stop time has been passed. " + "Stopping all tests." + << std::endl); + this->StopTimePassed = true; + } +} + void cmCTestMultiProcessHandler::LockResources(int index) { this->LockedResources.insert( @@ -258,12 +280,23 @@ bool cmCTestMultiProcessHandler::StartTest(int test) void cmCTestMultiProcessHandler::StartNextTests() { - size_t numToStart = 0; + if (this->TestLoadRetryTimer.get() != nullptr) { + // This timer may be waiting to call StartNextTests again. + // Since we have been called it is no longer needed. + uv_timer_stop(this->TestLoadRetryTimer); + } if (this->Tests.empty()) { + this->TestLoadRetryTimer.reset(); return; } + if (this->CheckStopTimePassed()) { + return; + } + + size_t numToStart = 0; + if (this->RunningCount < this->ParallelLevel) { numToStart = this->ParallelLevel - this->RunningCount; } @@ -279,7 +312,6 @@ void cmCTestMultiProcessHandler::StartNextTests() } bool allTestsFailedTestLoadCheck = false; - bool usedFakeLoadForTesting = false; size_t minProcessorsRequired = this->ParallelLevel; std::string testWithMinProcessors; @@ -292,15 +324,11 @@ void cmCTestMultiProcessHandler::StartNextTests() allTestsFailedTestLoadCheck = true; // Check for a fake load average value used in testing. - std::string fake_load_value; - if (cmSystemTools::GetEnv("__CTEST_FAKE_LOAD_AVERAGE_FOR_TESTING", - fake_load_value)) { - usedFakeLoadForTesting = true; - if (!cmSystemTools::StringToULong(fake_load_value.c_str(), - &systemLoad)) { - cmSystemTools::Error("Failed to parse fake load value: ", - fake_load_value.c_str()); - } + if (this->FakeLoadForTesting > 0) { + systemLoad = this->FakeLoadForTesting; + // Drop the fake load for the next iteration to a value low enough + // that the next iteration will start tests. + this->FakeLoadForTesting = 1; } // If it's not set, look up the true load average. else { @@ -346,10 +374,6 @@ void cmCTestMultiProcessHandler::StartNextTests() } if (testLoadOk && processors <= numToStart && this->StartTest(test)) { - if (this->StopTimePassed) { - return; - } - numToStart -= processors; } else if (numToStart == 0) { break; @@ -384,18 +408,25 @@ void cmCTestMultiProcessHandler::StartNextTests() } cmCTestLog(this->CTest, HANDLER_OUTPUT, "*****" << std::endl); - if (usedFakeLoadForTesting) { - // Break out of the infinite loop of waiting for our fake load - // to come down. - this->StopTimePassed = true; - } else { - // Wait between 1 and 5 seconds before trying again. - cmCTestScriptHandler::SleepInSeconds(cmSystemTools::RandomSeed() % 5 + - 1); + // Wait between 1 and 5 seconds before trying again. + unsigned int milliseconds = (cmSystemTools::RandomSeed() % 5 + 1) * 1000; + if (this->FakeLoadForTesting) { + milliseconds = 10; } + if (this->TestLoadRetryTimer.get() == nullptr) { + this->TestLoadRetryTimer.init(this->Loop, this); + } + this->TestLoadRetryTimer.start( + &cmCTestMultiProcessHandler::OnTestLoadRetryCB, milliseconds, 0); } } +void cmCTestMultiProcessHandler::OnTestLoadRetryCB(uv_timer_t* timer) +{ + auto self = static_cast<cmCTestMultiProcessHandler*>(timer->data); + self->StartNextTests(); +} + void cmCTestMultiProcessHandler::FinishTestProcess(cmCTestRunTest* runner, bool started) { @@ -405,8 +436,11 @@ void cmCTestMultiProcessHandler::FinishTestProcess(cmCTestRunTest* runner, auto properties = runner->GetTestProperties(); bool testResult = runner->EndTest(this->Completed, this->Total, started); + if (runner->TimedOutForStopTime()) { + this->SetStopTimePassed(); + } if (started) { - if (runner->StartAgain()) { + if (!this->StopTimePassed && runner->StartAgain()) { this->Completed--; // remove the completed test because run again return; } diff --git a/Source/CTest/cmCTestMultiProcessHandler.h b/Source/CTest/cmCTestMultiProcessHandler.h index 203170e..3927a8a 100644 --- a/Source/CTest/cmCTestMultiProcessHandler.h +++ b/Source/CTest/cmCTestMultiProcessHandler.h @@ -12,6 +12,7 @@ #include <string> #include <vector> +#include "cmUVHandlePtr.h" #include "cm_uv.h" class cmCTest; @@ -101,6 +102,8 @@ protected: void EraseTest(int index); void FinishTestProcess(cmCTestRunTest* runner, bool started); + static void OnTestLoadRetryCB(uv_timer_t* timer); + void RemoveTest(int index); // Check if we need to resume an interrupted test set void CheckResume(); @@ -110,6 +113,9 @@ protected: inline size_t GetProcessorsUsed(int index); std::string GetName(int index); + bool CheckStopTimePassed(); + void SetStopTimePassed(); + void LockResources(int index); void UnlockResources(int index); // map from test number to set of depend tests @@ -122,7 +128,7 @@ protected: size_t RunningCount; std::set<size_t> ProcessorsAvailable; size_t HaveAffinity; - bool StopTimePassed; + bool StopTimePassed = false; // list of test properties (indices concurrent to the test map) PropertiesMap Properties; std::map<int, bool> TestRunningMap; @@ -135,7 +141,9 @@ protected: std::vector<cmCTestTestHandler::cmCTestTestResult>* TestResults; size_t ParallelLevel; // max number of process that can be run at once unsigned long TestLoad; + unsigned long FakeLoadForTesting; uv_loop_t Loop; + cm::uv_timer_ptr TestLoadRetryTimer; cmCTestTestHandler* TestHandler; cmCTest* CTest; bool HasCycles; diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx index ef0a49d..23d4616 100644 --- a/Source/CTest/cmCTestRunTest.cxx +++ b/Source/CTest/cmCTestRunTest.cxx @@ -140,6 +140,9 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started) bool passed = true; cmProcess::State res = started ? this->TestProcess->GetProcessStatus() : cmProcess::State::Error; + if (res != cmProcess::State::Expired) { + this->TimeoutIsForStopTime = false; + } int retVal = this->TestProcess->GetExitValue(); bool forceFail = false; bool skipped = false; @@ -537,6 +540,7 @@ bool cmCTestRunTest::StartTest(size_t total) auto timeout = this->TestProperties->Timeout; + this->TimeoutIsForStopTime = false; std::chrono::system_clock::time_point stop_time = this->CTest->GetStopTime(); if (stop_time != std::chrono::system_clock::time_point()) { std::chrono::duration<double> stop_timeout = @@ -547,6 +551,7 @@ bool cmCTestRunTest::StartTest(size_t total) } if (timeout == std::chrono::duration<double>::zero() || stop_timeout < timeout) { + this->TimeoutIsForStopTime = true; timeout = stop_timeout; } } diff --git a/Source/CTest/cmCTestRunTest.h b/Source/CTest/cmCTestRunTest.h index 3b1d674..7e80157 100644 --- a/Source/CTest/cmCTestRunTest.h +++ b/Source/CTest/cmCTestRunTest.h @@ -80,6 +80,8 @@ public: void FinalizeTest(); + bool TimedOutForStopTime() const { return this->TimeoutIsForStopTime; } + private: bool NeedsToRerun(); void DartProcessing(); @@ -92,6 +94,7 @@ private: void MemCheckPostProcess(); cmCTestTestHandler::cmCTestTestProperties* TestProperties; + bool TimeoutIsForStopTime = false; // Pointer back to the "parent"; the handler that invoked this test run cmCTestTestHandler* TestHandler; cmCTest* CTest; diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx index cbed40e..c7f3f39 100644 --- a/Source/CTest/cmCTestSubmitHandler.cxx +++ b/Source/CTest/cmCTestSubmitHandler.cxx @@ -425,6 +425,29 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const std::string& localprefix, ((url.find('?') == std::string::npos) ? '?' : '&') + "FileName=" + ofile; + cmCTestCurl ctest_curl(this->CTest); + upload_as += "&build="; + upload_as += + ctest_curl.Escape(this->CTest->GetCTestConfiguration("BuildName")); + upload_as += "&site="; + upload_as += + ctest_curl.Escape(this->CTest->GetCTestConfiguration("Site")); + upload_as += "&stamp="; + upload_as += ctest_curl.Escape(this->CTest->GetCurrentTag()); + upload_as += "-"; + upload_as += ctest_curl.Escape(this->CTest->GetTestModelString()); + cmCTestScriptHandler* ch = + static_cast<cmCTestScriptHandler*>(this->CTest->GetHandler("script")); + cmake* cm = ch->GetCMake(); + if (cm) { + const char* subproject = + cm->GetState()->GetGlobalProperty("SubProject"); + if (subproject) { + upload_as += "&subproject="; + upload_as += ctest_curl.Escape(subproject); + } + } + upload_as += "&MD5="; if (cmSystemTools::IsOn(this->GetOption("InternalTest"))) { diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx index 2646c9a..7b980a0 100644 --- a/Source/QtDialog/CMakeSetup.cxx +++ b/Source/QtDialog/CMakeSetup.cxx @@ -150,7 +150,7 @@ int main(int argc, char** argv) typedef cmsys::CommandLineArguments argT; arg.AddArgument("-B", argT::CONCAT_ARGUMENT, &binaryDirectory, "Binary Directory"); - arg.AddArgument("-H", argT::CONCAT_ARGUMENT, &sourceDirectory, + arg.AddArgument("-S", argT::CONCAT_ARGUMENT, &sourceDirectory, "Source Directory"); // do not complain about unknown options arg.StoreUnusedArguments(true); diff --git a/Source/QtDialog/CMakeSetupDialog.cxx b/Source/QtDialog/CMakeSetupDialog.cxx index 5d589cc..3761bd3 100644 --- a/Source/QtDialog/CMakeSetupDialog.cxx +++ b/Source/QtDialog/CMakeSetupDialog.cxx @@ -108,7 +108,7 @@ CMakeSetupDialog::CMakeSetupDialog() QMenu* ToolsMenu = this->menuBar()->addMenu(tr("&Tools")); this->ConfigureAction = ToolsMenu->addAction(tr("&Configure")); - // prevent merging with Preferences menu item on Mac OS X + // prevent merging with Preferences menu item on macOS this->ConfigureAction->setMenuRole(QAction::NoRole); QObject::connect(this->ConfigureAction, SIGNAL(triggered(bool)), this, SLOT(doConfigure())); diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx index 0e14a3f..0133b88 100644 --- a/Source/QtDialog/QCMake.cxx +++ b/Source/QtDialog/QCMake.cxx @@ -94,11 +94,11 @@ void QCMake::setBinaryDirectory(const QString& _dir) } const char* gen = state->GetCacheEntryValue("CMAKE_GENERATOR"); if (gen) { - const char* extraGen = + const std::string* extraGen = state->GetInitializedCacheValue("CMAKE_EXTRA_GENERATOR"); std::string curGen = cmExternalMakefileProjectGenerator::CreateFullGeneratorName( - gen, extraGen ? extraGen : ""); + gen, extraGen ? *extraGen : ""); this->setGenerator(QString::fromLocal8Bit(curGen.c_str())); } diff --git a/Source/QtDialog/QCMakeCacheView.cxx b/Source/QtDialog/QCMakeCacheView.cxx index 1b3fb15..7d3aa57 100644 --- a/Source/QtDialog/QCMakeCacheView.cxx +++ b/Source/QtDialog/QCMakeCacheView.cxx @@ -614,7 +614,7 @@ bool QCMakeCacheModelDelegate::editorEvent(QEvent* e, // Can remove this function and FileDialogFlag when minimum Qt version is 4.5 bool QCMakeCacheModelDelegate::eventFilter(QObject* object, QEvent* evt) { - // workaround for what looks like a bug in Qt on Mac OS X + // workaround for what looks like a bug in Qt on macOS // where it doesn't create a QWidget wrapper for the native file dialog // so the Qt library ends up assuming the focus was lost to something else diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index e847bae..6639787 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -476,11 +476,13 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command) tag.clear(); } std::string track; - if (cmSystemTools::GetLineFromStream(tfin, track)) { + if (cmSystemTools::GetLineFromStream(tfin, track) && + !this->Parts[PartStart] && !command) { this->SpecificTrack = track; } std::string model; - if (cmSystemTools::GetLineFromStream(tfin, model)) { + if (cmSystemTools::GetLineFromStream(tfin, model) && + !this->Parts[PartStart] && !command) { this->TestModel = GetTestModelFromString(model.c_str()); } tfin.close(); diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx index d2d419f..b391dc4 100644 --- a/Source/cmCacheManager.cxx +++ b/Source/cmCacheManager.cxx @@ -127,15 +127,15 @@ bool cmCacheManager::LoadCache(const std::string& path, bool internal, } this->CacheMajorVersion = 0; this->CacheMinorVersion = 0; - if (const char* cmajor = + if (const std::string* cmajor = this->GetInitializedCacheValue("CMAKE_CACHE_MAJOR_VERSION")) { unsigned int v = 0; - if (sscanf(cmajor, "%u", &v) == 1) { + if (sscanf(cmajor->c_str(), "%u", &v) == 1) { this->CacheMajorVersion = v; } - if (const char* cminor = + if (const std::string* cminor = this->GetInitializedCacheValue("CMAKE_CACHE_MINOR_VERSION")) { - if (sscanf(cminor, "%u", &v) == 1) { + if (sscanf(cminor->c_str(), "%u", &v) == 1) { this->CacheMinorVersion = v; } } @@ -153,18 +153,20 @@ bool cmCacheManager::LoadCache(const std::string& path, bool internal, } // check to make sure the cache directory has not // been moved - const char* oldDir = this->GetInitializedCacheValue("CMAKE_CACHEFILE_DIR"); + const std::string* oldDir = + this->GetInitializedCacheValue("CMAKE_CACHEFILE_DIR"); if (internal && oldDir) { std::string currentcwd = path; - std::string oldcwd = oldDir; + std::string oldcwd = *oldDir; cmSystemTools::ConvertToUnixSlashes(currentcwd); currentcwd += "/CMakeCache.txt"; oldcwd += "/CMakeCache.txt"; if (!cmSystemTools::SameFile(oldcwd, currentcwd)) { + const std::string* dir = + this->GetInitializedCacheValue("CMAKE_CACHEFILE_DIR"); std::ostringstream message; message << "The current CMakeCache.txt directory " << currentcwd - << " is different than the directory " - << this->GetInitializedCacheValue("CMAKE_CACHEFILE_DIR") + << " is different than the directory " << (dir ? *dir : "") << " where CMakeCache.txt was created. This may result " "in binaries being created in the wrong place. If you " "are not sure, reedit the CMakeCache.txt"; @@ -512,12 +514,12 @@ cmCacheManager::CacheIterator cmCacheManager::GetCacheIterator(const char* key) return CacheIterator(*this, key); } -const char* cmCacheManager::GetInitializedCacheValue( +const std::string* cmCacheManager::GetInitializedCacheValue( const std::string& key) const { CacheEntryMap::const_iterator i = this->Cache.find(key); if (i != this->Cache.end() && i->second.Initialized) { - return i->second.Value.c_str(); + return &i->second.Value; } return nullptr; } diff --git a/Source/cmCacheManager.h b/Source/cmCacheManager.h index 73923d1..a269271 100644 --- a/Source/cmCacheManager.h +++ b/Source/cmCacheManager.h @@ -126,7 +126,7 @@ public: int GetSize() { return static_cast<int>(this->Cache.size()); } ///! Get a value from the cache given a key - const char* GetInitializedCacheValue(const std::string& key) const; + const std::string* GetInitializedCacheValue(const std::string& key) const; const char* GetCacheEntryValue(const std::string& key) { diff --git a/Source/cmCommandArgumentParserHelper.cxx b/Source/cmCommandArgumentParserHelper.cxx index c7210b4..2b4ceaa 100644 --- a/Source/cmCommandArgumentParserHelper.cxx +++ b/Source/cmCommandArgumentParserHelper.cxx @@ -68,12 +68,12 @@ const char* cmCommandArgumentParserHelper::ExpandSpecialVariable( return ""; } if (strcmp(key, "CACHE") == 0) { - if (const char* c = + if (const std::string* c = this->Makefile->GetState()->GetInitializedCacheValue(var)) { if (this->EscapeQuotes) { - return this->AddString(cmSystemTools::EscapeQuotes(c)); + return this->AddString(cmSystemTools::EscapeQuotes(*c)); } - return this->AddString(c); + return this->AddString(*c); } return ""; } @@ -253,7 +253,6 @@ int cmCommandArgumentParserHelper::ParseString(const char* str, int verb) void cmCommandArgumentParserHelper::CleanupParser() { - std::vector<char*>::iterator sit; for (char* var : this->Variables) { delete[] var; } diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx index b1f3860..aa17de6 100644 --- a/Source/cmComputeLinkDepends.cxx +++ b/Source/cmComputeLinkDepends.cxx @@ -279,12 +279,12 @@ cmComputeLinkDepends::Compute() return this->FinalLinkEntries; } -std::map<std::string, int>::iterator cmComputeLinkDepends::AllocateLinkEntry( - std::string const& item) +std::map<cmLinkItem, int>::iterator cmComputeLinkDepends::AllocateLinkEntry( + cmLinkItem const& item) { - std::map<std::string, int>::value_type index_entry( + std::map<cmLinkItem, int>::value_type index_entry( item, static_cast<int>(this->EntryList.size())); - std::map<std::string, int>::iterator lei = + std::map<cmLinkItem, int>::iterator lei = this->LinkEntryIndex.insert(index_entry).first; this->EntryList.emplace_back(); this->InferredDependSets.push_back(nullptr); @@ -295,7 +295,7 @@ std::map<std::string, int>::iterator cmComputeLinkDepends::AllocateLinkEntry( int cmComputeLinkDepends::AddLinkEntry(cmLinkItem const& item) { // Check if the item entry has already been added. - std::map<std::string, int>::iterator lei = this->LinkEntryIndex.find(item); + std::map<cmLinkItem, int>::iterator lei = this->LinkEntryIndex.find(item); if (lei != this->LinkEntryIndex.end()) { // Yes. We do not need to follow the item's dependencies again. return lei->second; @@ -307,10 +307,11 @@ int cmComputeLinkDepends::AddLinkEntry(cmLinkItem const& item) // Initialize the item entry. int index = lei->second; LinkEntry& entry = this->EntryList[index]; - entry.Item = item; + entry.Item = item.AsStr(); entry.Target = item.Target; - entry.IsFlag = (!entry.Target && item[0] == '-' && item[1] != 'l' && - item.substr(0, 10) != "-framework"); + entry.IsFlag = + (!entry.Target && entry.Item[0] == '-' && entry.Item[1] != 'l' && + entry.Item.substr(0, 10) != "-framework"); // If the item has dependencies queue it to follow them. if (entry.Target) { @@ -395,7 +396,7 @@ void cmComputeLinkDepends::QueueSharedDependencies( void cmComputeLinkDepends::HandleSharedDependency(SharedDepEntry const& dep) { // Check if the target already has an entry. - std::map<std::string, int>::iterator lei = + std::map<cmLinkItem, int>::iterator lei = this->LinkEntryIndex.find(dep.Item); if (lei == this->LinkEntryIndex.end()) { // Allocate a spot for the item entry. @@ -403,7 +404,7 @@ void cmComputeLinkDepends::HandleSharedDependency(SharedDepEntry const& dep) // Initialize the item entry. LinkEntry& entry = this->EntryList[lei->second]; - entry.Item = dep.Item; + entry.Item = dep.Item.AsStr(); entry.Target = dep.Item.Target; // This item was added specifically because it is a dependent @@ -473,9 +474,9 @@ void cmComputeLinkDepends::AddVarLinkEntries(int depender_index, // If the library is meant for this link type then use it. if (llt == GENERAL_LibraryType || llt == this->LinkType) { - actual_libs.emplace_back(d, this->FindTargetToLink(depender_index, d)); + actual_libs.emplace_back(this->ResolveLinkItem(depender_index, d)); } else if (this->OldLinkDirMode) { - cmLinkItem item(d, this->FindTargetToLink(depender_index, d)); + cmLinkItem item = this->ResolveLinkItem(depender_index, d); this->CheckWrongConfigItem(item); } @@ -512,7 +513,7 @@ void cmComputeLinkDepends::AddLinkEntries(int depender_index, // Skip entries that will resolve to the target getting linked or // are empty. cmLinkItem const& item = l; - if (item == this->Target->GetName() || item.empty()) { + if (item.AsStr() == this->Target->GetName() || item.AsStr().empty()) { continue; } @@ -553,8 +554,8 @@ void cmComputeLinkDepends::AddLinkEntries(int depender_index, } } -cmGeneratorTarget const* cmComputeLinkDepends::FindTargetToLink( - int depender_index, const std::string& name) +cmLinkItem cmComputeLinkDepends::ResolveLinkItem(int depender_index, + const std::string& name) { // Look for a target in the scope of the depender. cmGeneratorTarget const* from = this->Target; @@ -564,7 +565,7 @@ cmGeneratorTarget const* cmComputeLinkDepends::FindTargetToLink( from = depender; } } - return from->FindTargetToLink(name); + return from->ResolveLinkItem(name); } void cmComputeLinkDepends::InferDependencies() diff --git a/Source/cmComputeLinkDepends.h b/Source/cmComputeLinkDepends.h index dd0e029..66fb1e6 100644 --- a/Source/cmComputeLinkDepends.h +++ b/Source/cmComputeLinkDepends.h @@ -72,19 +72,18 @@ private: std::string Config; EntryVector FinalLinkEntries; - std::map<std::string, int>::iterator AllocateLinkEntry( - std::string const& item); + std::map<cmLinkItem, int>::iterator AllocateLinkEntry( + cmLinkItem const& item); int AddLinkEntry(cmLinkItem const& item); void AddVarLinkEntries(int depender_index, const char* value); void AddDirectLinkEntries(); template <typename T> void AddLinkEntries(int depender_index, std::vector<T> const& libs); - cmGeneratorTarget const* FindTargetToLink(int depender_index, - const std::string& name); + cmLinkItem ResolveLinkItem(int depender_index, const std::string& name); // One entry for each unique item. std::vector<LinkEntry> EntryList; - std::map<std::string, int> LinkEntryIndex; + std::map<cmLinkItem, int> LinkEntryIndex; // BFS of initial dependencies. struct BFSEntry diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index 8d6efde..a3e135f 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -30,7 +30,7 @@ Notes about linking on various platforms: ------------------------------------------------------------------------------ -Linux, FreeBSD, Mac OS X, IRIX, Sun, Windows: +Linux, FreeBSD, macOS, IRIX, Sun, Windows: Linking to libraries using the full path works fine. @@ -1725,7 +1725,7 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs, } const char* stagePath = this->Makefile->GetDefinition("CMAKE_STAGING_PREFIX"); - const char* installPrefix = + std::string const& installPrefix = this->Makefile->GetSafeDefinition("CMAKE_INSTALL_PREFIX"); cmSystemTools::ConvertToUnixSlashes(rootPath); std::vector<std::string> const& rdirs = this->GetRuntimeSearchPath(); diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx index efdd3a5..268e749 100644 --- a/Source/cmComputeTargetDepends.cxx +++ b/Source/cmComputeTargetDepends.cxx @@ -195,7 +195,7 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index) // dependencies in all targets, because the generated build-systems can't // deal with config-specific dependencies. { - std::set<std::string> emitted; + std::set<cmLinkItem> emitted; std::vector<std::string> configs; depender->Makefile->GetConfigurations(configs); @@ -206,27 +206,31 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index) std::vector<cmSourceFile const*> objectFiles; depender->GetExternalObjects(objectFiles, it); for (cmSourceFile const* o : objectFiles) { - std::string objLib = o->GetObjectLibrary(); - if (!objLib.empty() && emitted.insert(objLib).second) { - if (depender->GetType() != cmStateEnums::EXECUTABLE && - depender->GetType() != cmStateEnums::STATIC_LIBRARY && - depender->GetType() != cmStateEnums::SHARED_LIBRARY && - depender->GetType() != cmStateEnums::MODULE_LIBRARY && - depender->GetType() != cmStateEnums::OBJECT_LIBRARY) { - this->GlobalGenerator->GetCMakeInstance()->IssueMessage( - cmake::FATAL_ERROR, - "Only executables and libraries may reference target objects.", - depender->GetBacktrace()); - return; + std::string const& objLib = o->GetObjectLibrary(); + if (!objLib.empty()) { + cmLinkItem const& objItem = depender->ResolveLinkItem(objLib); + if (emitted.insert(objItem).second) { + if (depender->GetType() != cmStateEnums::EXECUTABLE && + depender->GetType() != cmStateEnums::STATIC_LIBRARY && + depender->GetType() != cmStateEnums::SHARED_LIBRARY && + depender->GetType() != cmStateEnums::MODULE_LIBRARY && + depender->GetType() != cmStateEnums::OBJECT_LIBRARY) { + this->GlobalGenerator->GetCMakeInstance()->IssueMessage( + cmake::FATAL_ERROR, + "Only executables and libraries may reference target objects.", + depender->GetBacktrace()); + return; + } + const_cast<cmGeneratorTarget*>(depender)->Target->AddUtility( + objLib); } - const_cast<cmGeneratorTarget*>(depender)->Target->AddUtility(objLib); } } cmLinkImplementation const* impl = depender->GetLinkImplementation(it); // A target should not depend on itself. - emitted.insert(depender->GetName()); + emitted.insert(cmLinkItem(depender)); for (cmLinkImplItem const& lib : impl->Libraries) { // Don't emit the same library twice for this target. if (emitted.insert(lib).second) { @@ -240,9 +244,9 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index) // Loop over all utility dependencies. { std::set<cmLinkItem> const& tutils = depender->GetUtilityItems(); - std::set<std::string> emitted; + std::set<cmLinkItem> emitted; // A target should not depend on itself. - emitted.insert(depender->GetName()); + emitted.insert(cmLinkItem(depender)); for (cmLinkItem const& litem : tutils) { // Don't emit the same utility twice for this target. if (emitted.insert(litem).second) { @@ -254,7 +258,7 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index) void cmComputeTargetDepends::AddInterfaceDepends( int depender_index, const cmGeneratorTarget* dependee, - const std::string& config, std::set<std::string>& emitted) + const std::string& config, std::set<cmLinkItem>& emitted) { cmGeneratorTarget const* depender = this->Targets[depender_index]; if (cmLinkInterface const* iface = @@ -271,7 +275,7 @@ void cmComputeTargetDepends::AddInterfaceDepends( void cmComputeTargetDepends::AddInterfaceDepends( int depender_index, cmLinkItem const& dependee_name, - const std::string& config, std::set<std::string>& emitted) + const std::string& config, std::set<cmLinkItem>& emitted) { cmGeneratorTarget const* depender = this->Targets[depender_index]; cmGeneratorTarget const* dependee = dependee_name.Target; @@ -285,7 +289,7 @@ void cmComputeTargetDepends::AddInterfaceDepends( if (dependee) { // A target should not depend on itself. - emitted.insert(depender->GetName()); + emitted.insert(cmLinkItem(depender)); this->AddInterfaceDepends(depender_index, dependee, config, emitted); } } @@ -324,7 +328,7 @@ void cmComputeTargetDepends::AddTargetDepend(int depender_index, << depender->GetName() << "\" does not exist."; cmListFileBacktrace const* backtrace = - depender->GetUtilityBacktrace(dependee_name); + depender->GetUtilityBacktrace(dependee_name.AsStr()); if (backtrace) { cm->IssueMessage(messageType, e.str(), *backtrace); } else { diff --git a/Source/cmComputeTargetDepends.h b/Source/cmComputeTargetDepends.h index e93e376..3046e8a 100644 --- a/Source/cmComputeTargetDepends.h +++ b/Source/cmComputeTargetDepends.h @@ -51,11 +51,11 @@ private: bool ComputeFinalDepends(cmComputeComponentGraph const& ccg); void AddInterfaceDepends(int depender_index, cmLinkItem const& dependee_name, const std::string& config, - std::set<std::string>& emitted); + std::set<cmLinkItem>& emitted); void AddInterfaceDepends(int depender_index, cmGeneratorTarget const* dependee, const std::string& config, - std::set<std::string>& emitted); + std::set<cmLinkItem>& emitted); cmGlobalGenerator* GlobalGenerator; bool DebugMode; bool NoCycles; diff --git a/Source/cmDepends.cxx b/Source/cmDepends.cxx index 4716e14..6f1afd7 100644 --- a/Source/cmDepends.cxx +++ b/Source/cmDepends.cxx @@ -36,7 +36,7 @@ bool cmDepends::Write(std::ostream& makeDepends, std::ostream& internalDepends) std::string srcLang = "CMAKE_DEPENDS_CHECK_"; srcLang += this->Language; cmMakefile* mf = this->LocalGenerator->GetMakefile(); - const char* srcStr = mf->GetSafeDefinition(srcLang); + std::string const& srcStr = mf->GetSafeDefinition(srcLang); std::vector<std::string> pairs; cmSystemTools::ExpandListArgument(srcStr, pairs); diff --git a/Source/cmExportBuildAndroidMKGenerator.cxx b/Source/cmExportBuildAndroidMKGenerator.cxx index bb370c4..d12ad7f 100644 --- a/Source/cmExportBuildAndroidMKGenerator.cxx +++ b/Source/cmExportBuildAndroidMKGenerator.cxx @@ -8,11 +8,8 @@ #include <utility> #include "cmAlgorithms.h" -#include "cmGeneratorExpression.h" -#include "cmGeneratorExpressionDAGChecker.h" #include "cmGeneratorTarget.h" #include "cmLinkItem.h" -#include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmPolicies.h" #include "cmStateTypes.h" @@ -104,27 +101,14 @@ void cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties( os << "LOCAL_CPP_FEATURES += "; os << (property.second) << "\n"; } else if (property.first == "INTERFACE_LINK_LIBRARIES") { - // evaluate any generator expressions with the current - // build type of the makefile - cmGeneratorExpression ge; - cmGeneratorExpressionDAGChecker dagChecker( - target->GetName(), "INTERFACE_LINK_LIBRARIES", nullptr, nullptr); - std::unique_ptr<cmCompiledGeneratorExpression> cge = - ge.Parse(property.second); - std::string evaluated = cge->Evaluate( - target->GetLocalGenerator(), config, false, target, &dagChecker); - // need to look at list in pi->second and see if static or shared - // FindTargetToLink - // target->GetLocalGenerator()->FindGeneratorTargetToUse() - // then add to LOCAL_CPPFLAGS - std::vector<std::string> libraries; - cmSystemTools::ExpandListArgument(evaluated, libraries); std::string staticLibs; std::string sharedLibs; std::string ldlibs; - for (std::string const& lib : libraries) { - cmGeneratorTarget* gt = - target->GetLocalGenerator()->FindGeneratorTargetToUse(lib); + cmLinkInterfaceLibraries const* linkIFace = + target->GetLinkInterfaceLibraries(config, target, false); + for (cmLinkItem const& item : linkIFace->Libraries) { + cmGeneratorTarget const* gt = item.Target; + std::string const& lib = item.AsStr(); if (gt) { if (gt->GetType() == cmStateEnums::SHARED_LIBRARY || diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index 75d3374..d6573b8 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -195,7 +195,7 @@ static bool checkInterfaceDirs(const std::string& prepro, cmGeneratorTarget* target, const std::string& prop) { - const char* installDir = + std::string const& installDir = target->Makefile->GetSafeDefinition("CMAKE_INSTALL_PREFIX"); std::string const& topSourceDir = target->GetLocalGenerator()->GetSourceDirectory(); @@ -567,14 +567,17 @@ bool cmExportFileGenerator::AddTargetNamespace( std::string& input, cmGeneratorTarget* target, std::vector<std::string>& missingTargets) { - cmLocalGenerator* lg = target->GetLocalGenerator(); + cmGeneratorTarget::TargetOrString resolved = + target->ResolveTargetReference(input); - cmGeneratorTarget* tgt = lg->FindGeneratorTargetToUse(input); + cmGeneratorTarget* tgt = resolved.Target; if (!tgt) { + input = resolved.String; return false; } if (tgt->IsImported()) { + input = tgt->GetName(); return true; } if (this->ExportedTargets.find(tgt) != this->ExportedTargets.end()) { @@ -584,6 +587,8 @@ bool cmExportFileGenerator::AddTargetNamespace( this->HandleMissingTarget(namespacedTarget, missingTargets, target, tgt); if (!namespacedTarget.empty()) { input = namespacedTarget; + } else { + input = tgt->GetName(); } } return true; @@ -831,6 +836,16 @@ void cmExportFileGenerator::SetImportDetailProperties( } } +static std::string const& asString(std::string const& l) +{ + return l; +} + +static std::string const& asString(cmLinkItem const& l) +{ + return l.AsStr(); +} + template <typename T> void cmExportFileGenerator::SetImportLinkProperty( std::string const& suffix, cmGeneratorTarget* target, @@ -850,7 +865,7 @@ void cmExportFileGenerator::SetImportLinkProperty( link_entries += sep; sep = ";"; - std::string temp = l; + std::string temp = asString(l); this->AddTargetNamespace(temp, target, missingTargets); link_entries += temp; } diff --git a/Source/cmExportTryCompileFileGenerator.cxx b/Source/cmExportTryCompileFileGenerator.cxx index 87648cb..c169032 100644 --- a/Source/cmExportTryCompileFileGenerator.cxx +++ b/Source/cmExportTryCompileFileGenerator.cxx @@ -65,8 +65,7 @@ std::string cmExportTryCompileFileGenerator::FindTargets( cmGeneratorExpression ge; - cmGeneratorExpressionDAGChecker dagChecker(tgt->GetName(), propName, nullptr, - nullptr); + cmGeneratorExpressionDAGChecker dagChecker(tgt, propName, nullptr, nullptr); std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop); diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx index fbf6560..07a60de 100644 --- a/Source/cmExtraCodeBlocksGenerator.cxx +++ b/Source/cmExtraCodeBlocksGenerator.cxx @@ -666,7 +666,7 @@ std::string cmExtraCodeBlocksGenerator::GetCBCompilerId(const cmMakefile* mf) pureFortran = true; } - std::string compilerId = mf->GetSafeDefinition(compilerIdVar); + std::string const& compilerId = mf->GetSafeDefinition(compilerIdVar); std::string compiler = "gcc"; // default to gcc if (compilerId == "MSVC") { if (mf->IsDefinitionSet("MSVC10")) { diff --git a/Source/cmExtraCodeLiteGenerator.cxx b/Source/cmExtraCodeLiteGenerator.cxx index fe5c7bb..28106d1 100644 --- a/Source/cmExtraCodeLiteGenerator.cxx +++ b/Source/cmExtraCodeLiteGenerator.cxx @@ -599,7 +599,7 @@ std::string cmExtraCodeLiteGenerator::GetCodeLiteCompilerName( compilerIdVar = "CMAKE_C_COMPILER_ID"; } - std::string compilerId = mf->GetSafeDefinition(compilerIdVar); + std::string const& compilerId = mf->GetSafeDefinition(compilerIdVar); std::string compiler = "gnu g++"; // default to g++ // Since we need the compiler for parsing purposes only diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx index 313d46b..34f58ad 100644 --- a/Source/cmExtraEclipseCDT4Generator.cxx +++ b/Source/cmExtraEclipseCDT4Generator.cxx @@ -215,7 +215,7 @@ void cmExtraEclipseCDT4Generator::AddEnvVar(std::ostream& out, std::string cacheEntryName = "CMAKE_ECLIPSE_ENVVAR_"; cacheEntryName += envVar; - const char* cacheValue = + const std::string* cacheValue = lg->GetState()->GetInitializedCacheValue(cacheEntryName); // now we have both, decide which one to use @@ -232,14 +232,14 @@ void cmExtraEclipseCDT4Generator::AddEnvVar(std::ostream& out, mf->GetCMakeInstance()->SaveCache(lg->GetBinaryDirectory()); } else if (!envVarSet && cacheValue != nullptr) { // It is already in the cache, but not in the env, so use it from the cache - valueToUse = cacheValue; + valueToUse = *cacheValue; } else { // It is both in the cache and in the env. // Use the version from the env. except if the value from the env is // completely contained in the value from the cache (for the case that we // now have a PATH without MSVC dirs in the env. but had the full PATH with // all MSVC dirs during the cmake run which stored the var in the cache: - valueToUse = cacheValue; + valueToUse = *cacheValue; if (valueToUse.find(envVarValue) == std::string::npos) { valueToUse = envVarValue; mf->AddCacheDefinition(cacheEntryName, valueToUse.c_str(), diff --git a/Source/cmExtraSublimeTextGenerator.cxx b/Source/cmExtraSublimeTextGenerator.cxx index 14e7927..c4cca07 100644 --- a/Source/cmExtraSublimeTextGenerator.cxx +++ b/Source/cmExtraSublimeTextGenerator.cxx @@ -354,8 +354,8 @@ std::string cmExtraSublimeTextGenerator::ComputeFlagsForObject( lg->GetTargetCompileFlags(gtgt, config, language, flags); // Add source file specific flags. - cmGeneratorExpressionInterpreter genexInterpreter(lg, gtgt, config, - gtgt->GetName(), language); + cmGeneratorExpressionInterpreter genexInterpreter(lg, config, gtgt, + language); const std::string COMPILE_FLAGS("COMPILE_FLAGS"); if (const char* cflags = source->GetProperty(COMPILE_FLAGS)) { @@ -381,8 +381,8 @@ std::string cmExtraSublimeTextGenerator::ComputeDefines( cmMakefile* makefile = lg->GetMakefile(); const std::string& language = source->GetLanguage(); const std::string& config = makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"); - cmGeneratorExpressionInterpreter genexInterpreter( - lg, target, config, target->GetName(), language); + cmGeneratorExpressionInterpreter genexInterpreter(lg, config, target, + language); // Add the export symbol definition for shared library objects. if (const char* exportMacro = target->GetExportMacro()) { @@ -419,8 +419,8 @@ std::string cmExtraSublimeTextGenerator::ComputeIncludes( cmMakefile* makefile = lg->GetMakefile(); const std::string& language = source->GetLanguage(); const std::string& config = makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"); - cmGeneratorExpressionInterpreter genexInterpreter( - lg, target, config, target->GetName(), language); + cmGeneratorExpressionInterpreter genexInterpreter(lg, config, target, + language); // Add include directories for this source file const std::string INCLUDE_DIRECTORIES("INCLUDE_DIRECTORIES"); diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx index 6823cd5..658e9a7 100644 --- a/Source/cmGeneratorExpression.cxx +++ b/Source/cmGeneratorExpression.cxx @@ -389,14 +389,16 @@ void cmCompiledGeneratorExpression::GetMaxLanguageStandard( const std::string& cmGeneratorExpressionInterpreter::Evaluate( const char* expression, const std::string& property) { - if (this->Target.empty()) { - return this->EvaluateExpression(expression); - } + this->CompiledGeneratorExpression = + this->GeneratorExpression.Parse(expression); // Specify COMPILE_OPTIONS to DAGchecker, same semantic as COMPILE_FLAGS cmGeneratorExpressionDAGChecker dagChecker( - this->Target, property == "COMPILE_FLAGS" ? "COMPILE_OPTIONS" : property, - nullptr, nullptr); + this->HeadTarget, + property == "COMPILE_FLAGS" ? "COMPILE_OPTIONS" : property, nullptr, + nullptr); - return this->EvaluateExpression(expression, &dagChecker); + return this->CompiledGeneratorExpression->Evaluate( + this->LocalGenerator, this->Config, false, this->HeadTarget, &dagChecker, + this->Language); } diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h index 2b7df91..8176d5c 100644 --- a/Source/cmGeneratorExpression.h +++ b/Source/cmGeneratorExpression.h @@ -160,24 +160,15 @@ class cmGeneratorExpressionInterpreter public: cmGeneratorExpressionInterpreter(cmLocalGenerator* localGenerator, - cmGeneratorTarget* generatorTarget, - const std::string& config, - const std::string& target, - const std::string& lang) + std::string const& config, + cmGeneratorTarget const* headTarget, + std::string const& lang = std::string()) : LocalGenerator(localGenerator) - , GeneratorTarget(generatorTarget) , Config(config) - , Target(target) + , HeadTarget(headTarget) , Language(lang) { } - cmGeneratorExpressionInterpreter(cmLocalGenerator* localGenerator, - cmGeneratorTarget* generatorTarget, - const std::string& config) - : cmGeneratorExpressionInterpreter(localGenerator, generatorTarget, config, - std::string(), std::string()) - { - } const std::string& Evaluate(const char* expression, const std::string& property); @@ -188,47 +179,11 @@ public: } protected: - cmGeneratorExpression& GetGeneratorExpression() - { - return this->GeneratorExpression; - } - - cmCompiledGeneratorExpression& GetCompiledGeneratorExpression() - { - return *(this->CompiledGeneratorExpression); - } - - cmLocalGenerator* GetLocalGenerator() { return this->LocalGenerator; } - - cmGeneratorTarget* GetGeneratorTarget() { return this->GeneratorTarget; } - - const std::string& GetTargetName() const { return this->Target; } - const std::string& GetLanguage() const { return this->Language; } - - const std::string& EvaluateExpression( - const char* expression, - cmGeneratorExpressionDAGChecker* dagChecker = nullptr) - { - this->CompiledGeneratorExpression = - this->GeneratorExpression.Parse(expression); - - if (dagChecker == nullptr) { - return this->CompiledGeneratorExpression->Evaluate( - this->LocalGenerator, this->Config, false, this->GeneratorTarget); - } - - return this->CompiledGeneratorExpression->Evaluate( - this->LocalGenerator, this->Config, false, this->GeneratorTarget, - dagChecker, this->Language); - } - -private: cmGeneratorExpression GeneratorExpression; std::unique_ptr<cmCompiledGeneratorExpression> CompiledGeneratorExpression; cmLocalGenerator* LocalGenerator = nullptr; - cmGeneratorTarget* GeneratorTarget = nullptr; std::string Config; - std::string Target; + cmGeneratorTarget const* HeadTarget = nullptr; std::string Language; }; diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx index face282..8d57441 100644 --- a/Source/cmGeneratorExpressionDAGChecker.cxx +++ b/Source/cmGeneratorExpressionDAGChecker.cxx @@ -14,7 +14,7 @@ #include <utility> cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker( - const cmListFileBacktrace& backtrace, const std::string& target, + const cmListFileBacktrace& backtrace, cmGeneratorTarget const* target, const std::string& property, const GeneratorExpressionContent* content, cmGeneratorExpressionDAGChecker* parent) : Parent(parent) @@ -28,7 +28,7 @@ cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker( } cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker( - const std::string& target, const std::string& property, + cmGeneratorTarget const* target, const std::string& property, const GeneratorExpressionContent* content, cmGeneratorExpressionDAGChecker* parent) : Parent(parent) @@ -58,8 +58,8 @@ void cmGeneratorExpressionDAGChecker::Initialize() TEST_TRANSITIVE_PROPERTY_METHOD) false)) // NOLINT(clang-tidy) #undef TEST_TRANSITIVE_PROPERTY_METHOD { - std::map<std::string, std::set<std::string>>::const_iterator it = - top->Seen.find(this->Target); + std::map<cmGeneratorTarget const*, std::set<std::string>>::const_iterator + it = top->Seen.find(this->Target); if (it != top->Seen.end()) { const std::set<std::string>& propSet = it->second; if (propSet.find(this->Property) != propSet.end()) { @@ -166,7 +166,8 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingGenexExpression() return top->Property == "TARGET_GENEX_EVAL" || top->Property == "GENEX_EVAL"; } -bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries(const char* tgt) +bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries( + cmGeneratorTarget const* tgt) { const cmGeneratorExpressionDAGChecker* top = this; const cmGeneratorExpressionDAGChecker* parent = this->Parent; @@ -189,7 +190,7 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries(const char* tgt) strcmp(prop, "INTERFACE_LINK_LIBRARIES") == 0; } -std::string cmGeneratorExpressionDAGChecker::TopTarget() const +cmGeneratorTarget const* cmGeneratorExpressionDAGChecker::TopTarget() const { const cmGeneratorExpressionDAGChecker* top = this; const cmGeneratorExpressionDAGChecker* parent = this->Parent; diff --git a/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h index cd23904..8b1697b 100644 --- a/Source/cmGeneratorExpressionDAGChecker.h +++ b/Source/cmGeneratorExpressionDAGChecker.h @@ -13,6 +13,7 @@ struct GeneratorExpressionContent; struct cmGeneratorExpressionContext; +class cmGeneratorTarget; #define CM_SELECT_BOTH(F, A1, A2) F(A1, A2) #define CM_SELECT_FIRST(F, A1, A2) F(A1) @@ -41,11 +42,11 @@ struct cmGeneratorExpressionContext; struct cmGeneratorExpressionDAGChecker { cmGeneratorExpressionDAGChecker(const cmListFileBacktrace& backtrace, - const std::string& target, + cmGeneratorTarget const* target, const std::string& property, const GeneratorExpressionContent* content, cmGeneratorExpressionDAGChecker* parent); - cmGeneratorExpressionDAGChecker(const std::string& target, + cmGeneratorExpressionDAGChecker(cmGeneratorTarget const* target, const std::string& property, const GeneratorExpressionContent* content, cmGeneratorExpressionDAGChecker* parent); @@ -64,7 +65,7 @@ struct cmGeneratorExpressionDAGChecker const std::string& expr); bool EvaluatingGenexExpression(); - bool EvaluatingLinkLibraries(const char* tgt = nullptr); + bool EvaluatingLinkLibraries(cmGeneratorTarget const* tgt = nullptr); #define DECLARE_TRANSITIVE_PROPERTY_METHOD(METHOD) bool METHOD() const; @@ -75,7 +76,7 @@ struct cmGeneratorExpressionDAGChecker bool GetTransitivePropertiesOnly(); void SetTransitivePropertiesOnly() { this->TransitivePropertiesOnly = true; } - std::string TopTarget() const; + cmGeneratorTarget const* TopTarget() const; private: Result CheckGraph() const; @@ -83,9 +84,9 @@ private: private: const cmGeneratorExpressionDAGChecker* const Parent; - const std::string Target; + cmGeneratorTarget const* Target; const std::string Property; - std::map<std::string, std::set<std::string>> Seen; + std::map<cmGeneratorTarget const*, std::set<std::string>> Seen; const GeneratorExpressionContent* const Content; const cmListFileBacktrace Backtrace; Result CheckResult; diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx index 9aa5212..f901215 100644 --- a/Source/cmGeneratorExpressionNode.cxx +++ b/Source/cmGeneratorExpressionNode.cxx @@ -378,8 +378,8 @@ protected: { if (context->HeadTarget) { cmGeneratorExpressionDAGChecker dagChecker( - context->Backtrace, context->HeadTarget->GetName(), genexOperator, - content, dagCheckerParent); + context->Backtrace, context->HeadTarget, genexOperator, content, + dagCheckerParent); switch (dagChecker.Check()) { case cmGeneratorExpressionDAGChecker::SELF_REFERENCE: case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE: { @@ -580,10 +580,11 @@ struct CompilerIdNode : public cmGeneratorExpressionNode cmGeneratorExpressionDAGChecker* /*unused*/, const std::string& lang) const { - const char* compilerId = context->LG->GetMakefile()->GetSafeDefinition( - "CMAKE_" + lang + "_COMPILER_ID"); + std::string const& compilerId = + context->LG->GetMakefile()->GetSafeDefinition("CMAKE_" + lang + + "_COMPILER_ID"); if (parameters.empty()) { - return compilerId ? compilerId : ""; + return compilerId; } static cmsys::RegularExpression compilerIdValidator("^[A-Za-z0-9_]*$"); if (!compilerIdValidator.find(*parameters.begin())) { @@ -591,15 +592,16 @@ struct CompilerIdNode : public cmGeneratorExpressionNode "Expression syntax not recognized."); return std::string(); } - if (!compilerId) { + if (compilerId.empty()) { return parameters.front().empty() ? "1" : "0"; } - if (strcmp(parameters.begin()->c_str(), compilerId) == 0) { + if (strcmp(parameters.begin()->c_str(), compilerId.c_str()) == 0) { return "1"; } - if (cmsysString_strcasecmp(parameters.begin()->c_str(), compilerId) == 0) { + if (cmsysString_strcasecmp(parameters.begin()->c_str(), + compilerId.c_str()) == 0) { switch (context->LG->GetPolicyStatus(cmPolicies::CMP0044)) { case cmPolicies::WARN: { std::ostringstream e; @@ -676,11 +678,11 @@ struct CompilerVersionNode : public cmGeneratorExpressionNode cmGeneratorExpressionDAGChecker* /*unused*/, const std::string& lang) const { - const char* compilerVersion = + std::string const& compilerVersion = context->LG->GetMakefile()->GetSafeDefinition("CMAKE_" + lang + "_COMPILER_VERSION"); if (parameters.empty()) { - return compilerVersion ? compilerVersion : ""; + return compilerVersion; } static cmsys::RegularExpression compilerIdValidator("^[0-9\\.]*$"); @@ -689,13 +691,13 @@ struct CompilerVersionNode : public cmGeneratorExpressionNode "Expression syntax not recognized."); return std::string(); } - if (!compilerVersion) { + if (compilerVersion.empty()) { return parameters.front().empty() ? "1" : "0"; } return cmSystemTools::VersionCompare(cmSystemTools::OP_EQUAL, parameters.begin()->c_str(), - compilerVersion) + compilerVersion.c_str()) ? "1" : "0"; } @@ -757,17 +759,17 @@ struct PlatformIdNode : public cmGeneratorExpressionNode const GeneratorExpressionContent* /*content*/, cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override { - const char* platformId = + std::string const& platformId = context->LG->GetMakefile()->GetSafeDefinition("CMAKE_SYSTEM_NAME"); if (parameters.empty()) { - return platformId ? platformId : ""; + return platformId; } - if (!platformId) { + if (platformId.empty()) { return parameters.front().empty() ? "1" : "0"; } - if (strcmp(parameters.begin()->c_str(), platformId) == 0) { + if (*parameters.begin() == platformId) { return "1"; } return "0"; @@ -1054,7 +1056,9 @@ std::string getLinkedTargetsContent( // Don't follow such link interface entries so as not to create a // self-referencing loop. if (l.Target && l.Target != target) { - depString += sep + "$<TARGET_PROPERTY:" + l.Target->GetName() + "," + + std::string uniqueName = + target->GetGlobalGenerator()->IndexGeneratorTargetUniquely(l.Target); + depString += sep + "$<TARGET_PROPERTY:" + std::move(uniqueName) + "," + interfacePropertyName + ">"; sep = ";"; } @@ -1196,9 +1200,8 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode return target->GetLinkerLanguage(context->Config); } - cmGeneratorExpressionDAGChecker dagChecker(context->Backtrace, - target->GetName(), propertyName, - content, dagCheckerParent); + cmGeneratorExpressionDAGChecker dagChecker( + context->Backtrace, target, propertyName, content, dagCheckerParent); switch (dagChecker.Check()) { case cmGeneratorExpressionDAGChecker::SELF_REFERENCE: @@ -1911,9 +1914,9 @@ struct TargetFilesystemArtifact : public cmGeneratorExpressionNode return std::string(); } if (dagChecker && - (dagChecker->EvaluatingLinkLibraries(name.c_str()) || + (dagChecker->EvaluatingLinkLibraries(target) || (dagChecker->EvaluatingSources() && - name == dagChecker->TopTarget()))) { + target == dagChecker->TopTarget()))) { ::reportError(context, content->GetOriginalExpression(), "Expressions which require the linker language may not " "be used while evaluating link libraries"); diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 80a99d5..a58d3cb 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -138,8 +138,7 @@ cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg) this->SourceEntries, true); this->DLLPlatform = - strcmp(this->Makefile->GetSafeDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX"), - "") != 0; + !this->Makefile->GetSafeDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX").empty(); this->PolicyMap = t->PolicyMap; } @@ -671,9 +670,12 @@ std::set<cmLinkItem> const& cmGeneratorTarget::GetUtilityItems() const this->UtilityItemsDone = true; std::set<std::string> const& utilities = this->GetUtilities(); for (std::string const& i : utilities) { - cmGeneratorTarget* gt = - this->LocalGenerator->FindGeneratorTargetToUse(i); - this->UtilityItems.insert(cmLinkItem(i, gt)); + if (cmGeneratorTarget* gt = + this->LocalGenerator->FindGeneratorTargetToUse(i)) { + this->UtilityItems.insert(cmLinkItem(gt)); + } else { + this->UtilityItems.insert(cmLinkItem(i)); + } } } return this->UtilityItems; @@ -770,7 +772,7 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory( if (iter == this->SystemIncludesCache.end()) { cmGeneratorExpressionDAGChecker dagChecker( - this->GetName(), "SYSTEM_INCLUDE_DIRECTORIES", nullptr, nullptr); + this, "SYSTEM_INCLUDE_DIRECTORIES", nullptr, nullptr); bool excludeImported = this->GetPropertyAsBool("NO_SYSTEM_FROM_IMPORTED"); @@ -816,7 +818,11 @@ static void AddInterfaceEntries( thisTarget->GetLinkImplementationLibraries(config)) { for (cmLinkImplItem const& lib : impl->Libraries) { if (lib.Target) { - std::string genex = "$<TARGET_PROPERTY:" + lib + "," + prop + ">"; + std::string uniqueName = + thisTarget->GetGlobalGenerator()->IndexGeneratorTargetUniquely( + lib.Target); + std::string genex = + "$<TARGET_PROPERTY:" + std::move(uniqueName) + "," + prop + ">"; cmGeneratorExpression ge(lib.Backtrace); std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(genex); cge->SetEvaluateForBuildsystem(true); @@ -836,7 +842,10 @@ static void AddObjectEntries( for (cmLinkImplItem const& lib : impl->Libraries) { if (lib.Target && lib.Target->GetType() == cmStateEnums::OBJECT_LIBRARY) { - std::string genex = "$<TARGET_OBJECTS:" + lib + ">"; + std::string uniqueName = + thisTarget->GetGlobalGenerator()->IndexGeneratorTargetUniquely( + lib.Target); + std::string genex = "$<TARGET_OBJECTS:" + std::move(uniqueName) + ">"; cmGeneratorExpression ge(lib.Backtrace); std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(genex); cge->SetEvaluateForBuildsystem(true); @@ -860,7 +869,7 @@ static bool processSources( for (cmGeneratorTarget::TargetPropertyEntry* entry : entries) { cmLinkImplItem const& item = entry->LinkImplItem; - std::string const& targetName = item; + std::string const& targetName = item.AsStr(); std::vector<std::string> entrySources; cmSystemTools::ExpandListArgument( entry->ge->Evaluate(tgt->GetLocalGenerator(), config, false, tgt, tgt, @@ -960,8 +969,8 @@ void cmGeneratorTarget::GetSourceFiles(std::vector<std::string>& files, this->DebugSourcesDone = true; } - cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), "SOURCES", - nullptr, nullptr); + cmGeneratorExpressionDAGChecker dagChecker(this, "SOURCES", nullptr, + nullptr); std::unordered_set<std::string> uniqueSrcs; bool contextDependentDirectSources = @@ -1756,7 +1765,7 @@ public: void Visit(cmLinkItem const& item) { if (!item.Target) { - if (item.find("::") != std::string::npos) { + if (item.AsStr().find("::") != std::string::npos) { bool noMessage = false; cmake::MessageType messageType = cmake::FATAL_ERROR; std::ostringstream e; @@ -1777,7 +1786,7 @@ public: if (!noMessage) { e << "Target \"" << this->Target->GetName() - << "\" links to target \"" << item + << "\" links to target \"" << item.AsStr() << "\" but the target was not found. Perhaps a find_package() " "call is missing for an IMPORTED target, or an ALIAS target is " "missing?"; @@ -2074,8 +2083,8 @@ void cmGeneratorTarget::GetAutoUicOptions(std::vector<std::string>& result, } cmGeneratorExpression ge; - cmGeneratorExpressionDAGChecker dagChecker( - this->GetName(), "AUTOUIC_OPTIONS", nullptr, nullptr); + cmGeneratorExpressionDAGChecker dagChecker(this, "AUTOUIC_OPTIONS", nullptr, + nullptr); cmSystemTools::ExpandListArgument( ge.Parse(prop)->Evaluate(this->LocalGenerator, config, false, this, &dagChecker), @@ -2477,7 +2486,7 @@ static void processIncludeDirectories( { for (cmGeneratorTarget::TargetPropertyEntry* entry : entries) { cmLinkImplItem const& item = entry->LinkImplItem; - std::string const& targetName = item; + std::string const& targetName = item.AsStr(); bool const fromImported = item.Target && item.Target->IsImported(); bool const checkCMP0027 = item.FromGenex; std::vector<std::string> entryIncludes; @@ -2584,8 +2593,8 @@ std::vector<std::string> cmGeneratorTarget::GetIncludeDirectories( std::vector<std::string> includes; std::unordered_set<std::string> uniqueIncludes; - cmGeneratorExpressionDAGChecker dagChecker( - this->GetName(), "INCLUDE_DIRECTORIES", nullptr, nullptr); + cmGeneratorExpressionDAGChecker dagChecker(this, "INCLUDE_DIRECTORIES", + nullptr, nullptr); std::vector<std::string> debugProperties; const char* debugProp = @@ -2615,7 +2624,7 @@ std::vector<std::string> cmGeneratorTarget::GetIncludeDirectories( cmLinkImplementationLibraries const* impl = this->GetLinkImplementationLibraries(config); for (cmLinkImplItem const& lib : impl->Libraries) { - std::string libDir = cmSystemTools::CollapseFullPath(lib); + std::string libDir = cmSystemTools::CollapseFullPath(lib.AsStr()); static cmsys::RegularExpression frameworkCheck( "(.*\\.framework)(/Versions/[^/]+)?/[^/]+$"); @@ -2706,8 +2715,8 @@ void cmGeneratorTarget::GetCompileOptions(std::vector<std::string>& result, { std::unordered_set<std::string> uniqueOptions; - cmGeneratorExpressionDAGChecker dagChecker( - this->GetName(), "COMPILE_OPTIONS", nullptr, nullptr); + cmGeneratorExpressionDAGChecker dagChecker(this, "COMPILE_OPTIONS", nullptr, + nullptr); std::vector<std::string> debugProperties; const char* debugProp = @@ -2759,8 +2768,8 @@ void cmGeneratorTarget::GetCompileFeatures(std::vector<std::string>& result, { std::unordered_set<std::string> uniqueFeatures; - cmGeneratorExpressionDAGChecker dagChecker( - this->GetName(), "COMPILE_FEATURES", nullptr, nullptr); + cmGeneratorExpressionDAGChecker dagChecker(this, "COMPILE_FEATURES", nullptr, + nullptr); std::vector<std::string> debugProperties; const char* debugProp = @@ -2810,8 +2819,8 @@ void cmGeneratorTarget::GetCompileDefinitions( { std::unordered_set<std::string> uniqueOptions; - cmGeneratorExpressionDAGChecker dagChecker( - this->GetName(), "COMPILE_DEFINITIONS", nullptr, nullptr); + cmGeneratorExpressionDAGChecker dagChecker(this, "COMPILE_DEFINITIONS", + nullptr, nullptr); std::vector<std::string> debugProperties; const char* debugProp = @@ -2891,8 +2900,8 @@ void cmGeneratorTarget::GetLinkOptions(std::vector<std::string>& result, { std::unordered_set<std::string> uniqueOptions; - cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), "LINK_OPTIONS", - nullptr, nullptr); + cmGeneratorExpressionDAGChecker dagChecker(this, "LINK_OPTIONS", nullptr, + nullptr); std::vector<std::string> debugProperties; const char* debugProp = @@ -3039,8 +3048,8 @@ void cmGeneratorTarget::GetStaticLibraryLinkOptions( std::vector<cmGeneratorTarget::TargetPropertyEntry*> entries; std::unordered_set<std::string> uniqueOptions; - cmGeneratorExpressionDAGChecker dagChecker( - this->GetName(), "STATIC_LIBRARY_OPTIONS", nullptr, nullptr); + cmGeneratorExpressionDAGChecker dagChecker(this, "STATIC_LIBRARY_OPTIONS", + nullptr, nullptr); if (const char* linkOptions = this->GetProperty("STATIC_LIBRARY_OPTIONS")) { std::vector<std::string> options; @@ -3079,8 +3088,8 @@ void cmGeneratorTarget::GetLinkDepends(std::vector<std::string>& result, { std::vector<cmGeneratorTarget::TargetPropertyEntry*> linkDependsEntries; std::unordered_set<std::string> uniqueOptions; - cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), "LINK_DEPENDS", - nullptr, nullptr); + cmGeneratorExpressionDAGChecker dagChecker(this, "LINK_DEPENDS", nullptr, + nullptr); if (const char* linkDepends = this->GetProperty("LINK_DEPENDS")) { std::vector<std::string> depends; @@ -3486,11 +3495,11 @@ void cmGeneratorTarget::GetFullNameInternal( // if there is no prefix on the target use the cmake definition if (!targetPrefix && prefixVar) { - targetPrefix = this->Makefile->GetSafeDefinition(prefixVar); + targetPrefix = this->Makefile->GetSafeDefinition(prefixVar).c_str(); } // if there is no suffix on the target use the cmake definition if (!targetSuffix && suffixVar) { - targetSuffix = this->Makefile->GetSafeDefinition(suffixVar); + targetSuffix = this->Makefile->GetSafeDefinition(suffixVar).c_str(); } // frameworks have directory prefix but no suffix @@ -4495,7 +4504,7 @@ void cmGeneratorTarget::LookupLinkItems(std::vector<std::string> const& names, if (name == this->GetName() || name.empty()) { continue; } - items.emplace_back(name, this->FindTargetToLink(name)); + items.push_back(this->ResolveLinkItem(name)); } } @@ -4505,8 +4514,7 @@ void cmGeneratorTarget::ExpandLinkItems( std::vector<cmLinkItem>& items, bool& hadHeadSensitiveCondition) const { cmGeneratorExpression ge; - cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), prop, nullptr, - nullptr); + cmGeneratorExpressionDAGChecker dagChecker(this, prop, nullptr, nullptr); // The $<LINK_ONLY> expression may be in a link interface to specify private // link dependencies that are otherwise excluded from usage requirements. if (usage_requirements_only) { @@ -4571,7 +4579,7 @@ void cmGeneratorTarget::ComputeLinkInterface( this->GetType() == cmStateEnums::INTERFACE_LIBRARY) { // Shared libraries may have runtime implementation dependencies // on other shared libraries that are not in the interface. - std::unordered_set<std::string> emitted; + std::set<cmLinkItem> emitted; for (cmLinkItem const& lib : iface.Libraries) { emitted.insert(lib); } @@ -5557,8 +5565,8 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries( end = entryRange.end(); le != end; ++le, ++btIt) { std::vector<std::string> llibs; - cmGeneratorExpressionDAGChecker dagChecker( - this->GetName(), "LINK_LIBRARIES", nullptr, nullptr); + cmGeneratorExpressionDAGChecker dagChecker(this, "LINK_LIBRARIES", nullptr, + nullptr); cmGeneratorExpression ge(*btIt); std::unique_ptr<cmCompiledGeneratorExpression> const cge = ge.Parse(*le); std::string const& evaluated = @@ -5603,7 +5611,7 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries( } // The entry is meant for this configuration. - impl.Libraries.emplace_back(name, this->FindTargetToLink(name), *btIt, + impl.Libraries.emplace_back(this->ResolveLinkItem(name), *btIt, evaluated != *le); } @@ -5631,27 +5639,70 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries( continue; } // Support OLD behavior for CMP0003. - impl.WrongConfigLibraries.emplace_back(name, - this->FindTargetToLink(name)); + impl.WrongConfigLibraries.push_back(this->ResolveLinkItem(name)); } } } -cmGeneratorTarget* cmGeneratorTarget::FindTargetToLink( +cmGeneratorTarget::TargetOrString cmGeneratorTarget::ResolveTargetReference( std::string const& name) const { - cmGeneratorTarget* tgt = - this->LocalGenerator->FindGeneratorTargetToUse(name); + cmLocalGenerator const* lg = this->LocalGenerator; + std::string const* lookupName = &name; + + // When target_link_libraries() is called with a LHS target that is + // not created in the calling directory it adds a directory id suffix + // that we can use to look up the calling directory. It is that scope + // in which the item name is meaningful. This case is relatively rare + // so we allocate a separate string only when the directory id is present. + std::string::size_type pos = name.find(CMAKE_DIRECTORY_ID_SEP); + std::string plainName; + if (pos != std::string::npos) { + // We will look up the plain name without the directory id suffix. + plainName = name.substr(0, pos); + + // We will look up in the scope of the directory id. + // If we do not recognize the id then leave the original + // syntax in place to produce an indicative error later. + cmDirectoryId const dirId = + name.substr(pos + sizeof(CMAKE_DIRECTORY_ID_SEP) - 1); + if (cmLocalGenerator const* otherLG = + this->GlobalGenerator->FindLocalGenerator(dirId)) { + lg = otherLG; + lookupName = &plainName; + } + } + + TargetOrString resolved; + + if (cmGeneratorTarget* tgt = lg->FindGeneratorTargetToUse(*lookupName)) { + resolved.Target = tgt; + } else if (lookupName == &plainName) { + resolved.String = std::move(plainName); + } else { + resolved.String = name; + } + + return resolved; +} + +cmLinkItem cmGeneratorTarget::ResolveLinkItem(std::string const& name) const +{ + TargetOrString resolved = this->ResolveTargetReference(name); + + if (!resolved.Target) { + return cmLinkItem(resolved.String); + } // Skip targets that will not really be linked. This is probably a // name conflict between an external library and an executable // within the project. - if (tgt && tgt->GetType() == cmStateEnums::EXECUTABLE && - !tgt->IsExecutableWithExports()) { - tgt = nullptr; + if (resolved.Target->GetType() == cmStateEnums::EXECUTABLE && + !resolved.Target->IsExecutableWithExports()) { + return cmLinkItem(resolved.Target->GetName()); } - return tgt; + return cmLinkItem(resolved.Target); } std::string cmGeneratorTarget::GetPDBDirectory(const std::string& config) const diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index 1030d91..9d8c9f5 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -357,7 +357,14 @@ public: cmOptionalLinkImplementation& impl, const cmGeneratorTarget* head) const; - cmGeneratorTarget* FindTargetToLink(std::string const& name) const; + struct TargetOrString + { + std::string String; + cmGeneratorTarget* Target = nullptr; + }; + TargetOrString ResolveTargetReference(std::string const& name) const; + + cmLinkItem ResolveLinkItem(std::string const& name) const; // Compute the set of languages compiled by the target. This is // computed every time it is called because the languages can change diff --git a/Source/cmGetDirectoryPropertyCommand.cxx b/Source/cmGetDirectoryPropertyCommand.cxx index bf464d9..0d4d653 100644 --- a/Source/cmGetDirectoryPropertyCommand.cxx +++ b/Source/cmGetDirectoryPropertyCommand.cxx @@ -65,7 +65,7 @@ bool cmGetDirectoryPropertyCommand::InitialPass( "providing the name of the variable to get."); return false; } - std::string output = dir->GetSafeDefinition(*i); + std::string const& output = dir->GetSafeDefinition(*i); this->Makefile->AddDefinition(variable, output.c_str()); return true; } diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index b5212fc..71e844e 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -215,15 +215,15 @@ void cmGlobalGenerator::ResolveLanguageCompiler(const std::string& lang, if (!optional && (path.empty() || !cmSystemTools::FileExists(path))) { return; } - const char* cname = + const std::string* cname = this->GetCMakeInstance()->GetState()->GetInitializedCacheValue(langComp); std::string changeVars; if (cname && !optional) { std::string cnameString; - if (!cmSystemTools::FileIsFullPath(cname)) { - cnameString = cmSystemTools::FindProgram(cname); + if (!cmSystemTools::FileIsFullPath(*cname)) { + cnameString = cmSystemTools::FindProgram(*cname); } else { - cnameString = cname; + cnameString = *cname; } std::string pathString = path; // get rid of potentially multiple slashes: @@ -239,7 +239,7 @@ void cmGlobalGenerator::ResolveLanguageCompiler(const std::string& lang, } changeVars += langComp; changeVars += ";"; - changeVars += cname; + changeVars += *cname; this->GetCMakeInstance()->GetState()->SetGlobalProperty( "__CMAKE_DELETE_CACHE_CHANGE_VARS_", changeVars.c_str()); } @@ -828,10 +828,8 @@ void cmGlobalGenerator::EnableLanguage( std::string sharedLibFlagsVar = "CMAKE_SHARED_LIBRARY_"; sharedLibFlagsVar += lang; sharedLibFlagsVar += "_FLAGS"; - const char* sharedLibFlags = mf->GetSafeDefinition(sharedLibFlagsVar); - if (sharedLibFlags) { - this->LanguageToOriginalSharedLibFlags[lang] = sharedLibFlags; - } + this->LanguageToOriginalSharedLibFlags[lang] = + mf->GetSafeDefinition(sharedLibFlagsVar); // Translate compiler ids for compatibility. this->CheckCompilerIdCompatibility(mf, lang); @@ -1092,7 +1090,7 @@ void cmGlobalGenerator::FillExtensionToLanguageMap(const std::string& l, { std::string extensionsVar = std::string("CMAKE_") + std::string(l) + std::string("_SOURCE_FILE_EXTENSIONS"); - std::string exts = mf->GetSafeDefinition(extensionsVar); + const std::string& exts = mf->GetSafeDefinition(extensionsVar); std::vector<std::string> extensionList; cmSystemTools::ExpandListArgument(exts, extensionList); for (std::string const& i : extensionList) { @@ -1112,7 +1110,7 @@ bool cmGlobalGenerator::GlobalSettingIsOn(std::string const& name) const return this->Makefiles[0]->IsOn(name); } -const char* cmGlobalGenerator::GetSafeGlobalSetting( +std::string cmGlobalGenerator::GetSafeGlobalSetting( std::string const& name) const { assert(!this->Makefiles.empty()); @@ -1139,11 +1137,14 @@ void cmGlobalGenerator::ClearEnabledLanguages() void cmGlobalGenerator::CreateLocalGenerators() { + this->LocalGeneratorSearchIndex.clear(); cmDeleteAll(this->LocalGenerators); this->LocalGenerators.clear(); this->LocalGenerators.reserve(this->Makefiles.size()); for (cmMakefile* m : this->Makefiles) { - this->LocalGenerators.push_back(this->CreateLocalGenerator(m)); + cmLocalGenerator* lg = this->CreateLocalGenerator(m); + this->LocalGenerators.push_back(lg); + this->IndexLocalGenerator(lg); } } @@ -1593,7 +1594,7 @@ void cmGlobalGenerator::FinalizeTargetCompileInfo() for (std::string const& li : langs) { std::string const standardIncludesVar = "CMAKE_" + li + "_STANDARD_INCLUDE_DIRECTORIES"; - std::string const standardIncludesStr = + std::string const& standardIncludesStr = mf->GetSafeDefinition(standardIncludesVar); std::vector<std::string> standardIncludesVec; cmSystemTools::ExpandListArgument(standardIncludesStr, @@ -1661,6 +1662,7 @@ void cmGlobalGenerator::ClearGeneratorMembers() this->TargetSearchIndex.clear(); this->GeneratorTargetSearchIndex.clear(); this->MakefileSearchIndex.clear(); + this->LocalGeneratorSearchIndex.clear(); this->ProjectMap.clear(); this->RuleHashes.clear(); this->DirectoryContentMap.clear(); @@ -1970,7 +1972,7 @@ void cmGlobalGenerator::AddMakefile(cmMakefile* mf) // update progress // estimate how many lg there will be - const char* numGenC = + const std::string* numGenC = this->CMakeInstance->GetState()->GetInitializedCacheValue( "CMAKE_NUMBER_OF_MAKEFILES"); @@ -1988,7 +1990,7 @@ void cmGlobalGenerator::AddMakefile(cmMakefile* mf) return; } - int numGen = atoi(numGenC); + int numGen = atoi(numGenC->c_str()); float prog = 0.9f * static_cast<float>(this->Makefiles.size()) / static_cast<float>(numGen); if (prog > 0.9f) { @@ -2130,15 +2132,13 @@ cmMakefile* cmGlobalGenerator::FindMakefile(const std::string& start_dir) const return nullptr; } -///! Find a local generator by its startdirectory cmLocalGenerator* cmGlobalGenerator::FindLocalGenerator( - const std::string& start_dir) const + cmDirectoryId const& id) const { - for (cmLocalGenerator* lg : this->LocalGenerators) { - std::string sd = lg->GetCurrentSourceDirectory(); - if (sd == start_dir) { - return lg; - } + LocalGeneratorMap::const_iterator i = + this->LocalGeneratorSearchIndex.find(id.String); + if (i != this->LocalGeneratorSearchIndex.end()) { + return i->second; } return nullptr; } @@ -2168,6 +2168,24 @@ void cmGlobalGenerator::IndexGeneratorTarget(cmGeneratorTarget* gt) } } +std::string cmGlobalGenerator::IndexGeneratorTargetUniquely( + cmGeneratorTarget const* gt) +{ + // Use the pointer value to uniquely identify the target instance. + // Use a "T" prefix to indicate that this identifier is for a target. + // We must satisfy cmGeneratorExpression::IsValidTargetName so use no + // other special characters. + char buf[64]; + sprintf(buf, "::T%p", + static_cast<void const*>(gt)); // cast avoids format warning + std::string id = gt->GetName() + buf; + // We internally index pointers to non-const generator targets + // but our callers only have pointers to const generator targets. + // They will give up non-const privileges when looking up anyway. + this->GeneratorTargetSearchIndex[id] = const_cast<cmGeneratorTarget*>(gt); + return id; +} + void cmGlobalGenerator::IndexMakefile(cmMakefile* mf) { // FIXME: add_subdirectory supports multiple build directories @@ -2179,6 +2197,12 @@ void cmGlobalGenerator::IndexMakefile(cmMakefile* mf) MakefileMap::value_type(mf->GetCurrentSourceDirectory(), mf)); } +void cmGlobalGenerator::IndexLocalGenerator(cmLocalGenerator* lg) +{ + cmDirectoryId id = lg->GetMakefile()->GetDirectoryId(); + this->LocalGeneratorSearchIndex[id.String] = lg; +} + cmTarget* cmGlobalGenerator::FindTargetImpl(std::string const& name) const { TargetMap::const_iterator i = this->TargetSearchIndex.find(name); @@ -2430,7 +2454,7 @@ void cmGlobalGenerator::AddGlobalTarget_EditCache( std::string edit_cmd = this->GetEditCacheCommand(); if (!edit_cmd.empty()) { singleLine.push_back(std::move(edit_cmd)); - singleLine.push_back("-H$(CMAKE_SOURCE_DIR)"); + singleLine.push_back("-S$(CMAKE_SOURCE_DIR)"); singleLine.push_back("-B$(CMAKE_BINARY_DIR)"); gti.Message = "Running CMake cache editor..."; gti.UsesTerminal = true; @@ -2460,7 +2484,7 @@ void cmGlobalGenerator::AddGlobalTarget_RebuildCache( gti.UsesTerminal = true; cmCustomCommandLine singleLine; singleLine.push_back(cmSystemTools::GetCMakeCommand()); - singleLine.push_back("-H$(CMAKE_SOURCE_DIR)"); + singleLine.push_back("-S$(CMAKE_SOURCE_DIR)"); singleLine.push_back("-B$(CMAKE_BINARY_DIR)"); gti.CommandLines.push_back(std::move(singleLine)); targets.push_back(std::move(gti)); diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index c06ac52..1ea2d24 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -26,6 +26,9 @@ # include "cmFileLockPool.h" #endif +#define CMAKE_DIRECTORY_ID_SEP "::@" + +class cmDirectoryId; class cmExportBuildFileGenerator; class cmExternalMakefileProjectGenerator; class cmGeneratorTarget; @@ -230,7 +233,7 @@ public: const char* GetGlobalSetting(std::string const& name) const; bool GlobalSettingIsOn(std::string const& name) const; - const char* GetSafeGlobalSetting(std::string const& name) const; + std::string GetSafeGlobalSetting(std::string const& name) const; /** Add a file to the manifest of generated targets for a configuration. */ void AddToManifest(std::string const& f); @@ -284,8 +287,7 @@ public: bool NameResolvesToFramework(const std::string& libname) const; cmMakefile* FindMakefile(const std::string& start_dir) const; - ///! Find a local generator by its startdirectory - cmLocalGenerator* FindLocalGenerator(const std::string& start_dir) const; + cmLocalGenerator* FindLocalGenerator(cmDirectoryId const& id) const; /** Append the subdirectory for the given configuration. If anything is appended the given prefix and suffix will be appended around it, which @@ -305,6 +307,10 @@ public: void IndexTarget(cmTarget* t); void IndexGeneratorTarget(cmGeneratorTarget* gt); + // Index the target using a name that is unique to that target + // even if other targets have the same name. + std::string IndexGeneratorTargetUniquely(cmGeneratorTarget const* gt); + static bool IsReservedTarget(std::string const& name); virtual const char* GetAllTargetName() const { return "ALL_BUILD"; } @@ -514,6 +520,7 @@ private: typedef std::unordered_map<std::string, cmGeneratorTarget*> GeneratorTargetMap; typedef std::unordered_map<std::string, cmMakefile*> MakefileMap; + typedef std::unordered_map<std::string, cmLocalGenerator*> LocalGeneratorMap; // Map efficiently from target name to cmTarget instance. // Do not use this structure for looping over all targets. // It contains both normal and globally visible imported targets. @@ -525,6 +532,11 @@ private: // It may not contain all of them (see note in IndexMakefile method). MakefileMap MakefileSearchIndex; + // Map efficiently from source directory path to cmLocalGenerator instance. + // Do not use this structure for looping over all directories. + // Its order is not deterministic. + LocalGeneratorMap LocalGeneratorSearchIndex; + cmMakefile* TryCompileOuterMakefile; // If you add a new map here, make sure it is copied // in EnableLanguagesFromGenerator @@ -583,6 +595,7 @@ private: std::string const& reason) const; void IndexMakefile(cmMakefile* mf); + void IndexLocalGenerator(cmLocalGenerator* lg); virtual const char* GetBuildIgnoreErrorsFlag() const { return nullptr; } diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 0c80910..f513403 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -651,13 +651,13 @@ void cmGlobalNinjaGenerator::EnableLanguage( this->ResolveLanguageCompiler(l, mf, optional); } #ifdef _WIN32 - if (strcmp(mf->GetSafeDefinition("CMAKE_C_SIMULATE_ID"), "MSVC") != 0 && - strcmp(mf->GetSafeDefinition("CMAKE_CXX_SIMULATE_ID"), "MSVC") != 0 && + if ((mf->GetSafeDefinition("CMAKE_C_SIMULATE_ID") != "MSVC") && + (mf->GetSafeDefinition("CMAKE_CXX_SIMULATE_ID") != "MSVC") && (mf->IsOn("CMAKE_COMPILER_IS_MINGW") || - strcmp(mf->GetSafeDefinition("CMAKE_C_COMPILER_ID"), "GNU") == 0 || - strcmp(mf->GetSafeDefinition("CMAKE_CXX_COMPILER_ID"), "GNU") == 0 || - strcmp(mf->GetSafeDefinition("CMAKE_C_COMPILER_ID"), "Clang") == 0 || - strcmp(mf->GetSafeDefinition("CMAKE_CXX_COMPILER_ID"), "Clang") == 0)) { + (mf->GetSafeDefinition("CMAKE_C_COMPILER_ID") == "GNU") || + (mf->GetSafeDefinition("CMAKE_CXX_COMPILER_ID") == "GNU") || + (mf->GetSafeDefinition("CMAKE_C_COMPILER_ID") == "Clang") || + (mf->GetSafeDefinition("CMAKE_CXX_COMPILER_ID") == "Clang"))) { this->UsingGCCOnWindows = true; } #endif @@ -1340,7 +1340,7 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os) std::ostringstream cmd; cmd << lg->ConvertToOutputFormat(cmSystemTools::GetCMakeCommand(), cmOutputConverter::SHELL) - << " -H" + << " -S" << lg->ConvertToOutputFormat(lg->GetSourceDirectory(), cmOutputConverter::SHELL) << " -B" diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h index 6eb597c..63e6903 100644 --- a/Source/cmGlobalVisualStudio10Generator.h +++ b/Source/cmGlobalVisualStudio10Generator.h @@ -111,6 +111,8 @@ public: bool FindMakeProgram(cmMakefile* mf) override; + bool IsIPOSupported() const override { return true; } + static std::string GetInstalledNsightTegraVersion(); cmIDEFlagTable const* GetClFlagTable() const; diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx index 117d051..ba138c2 100644 --- a/Source/cmGlobalVisualStudio8Generator.cxx +++ b/Source/cmGlobalVisualStudio8Generator.cxx @@ -177,9 +177,9 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget() // Create a rule to re-run CMake. cmCustomCommandLine commandLine; commandLine.push_back(cmSystemTools::GetCMakeCommand()); - std::string argH = "-H"; - argH += lg->GetSourceDirectory(); - commandLine.push_back(argH); + std::string argS = "-S"; + argS += lg->GetSourceDirectory(); + commandLine.push_back(argS); std::string argB = "-B"; argB += lg->GetBinaryDirectory(); commandLine.push_back(argB); diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 7456d3c..e353a37 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -751,11 +751,10 @@ class XCodeGeneratorExpressionInterpreter public: XCodeGeneratorExpressionInterpreter(cmSourceFile* sourceFile, cmLocalGenerator* localGenerator, - cmGeneratorTarget* generatorTarget, + cmGeneratorTarget* headTarget, const std::string& lang) - : cmGeneratorExpressionInterpreter(localGenerator, generatorTarget, - "NO-PER-CONFIG-SUPPORT-IN-XCODE", - generatorTarget->GetName(), lang) + : cmGeneratorExpressionInterpreter( + localGenerator, "NO-PER-CONFIG-SUPPORT-IN-XCODE", headTarget, lang) , SourceFile(sourceFile) { } @@ -767,8 +766,7 @@ public: { const std::string& processed = this->cmGeneratorExpressionInterpreter::Evaluate(expression, property); - if (this->GetCompiledGeneratorExpression() - .GetHadContextSensitiveCondition()) { + if (this->CompiledGeneratorExpression->GetHadContextSensitiveCondition()) { std::ostringstream e; /* clang-format off */ e << @@ -777,7 +775,7 @@ public: "specified for source:\n" " " << this->SourceFile->GetFullPath() << "\n"; /* clang-format on */ - this->GetLocalGenerator()->IssueMessage(cmake::FATAL_ERROR, e.str()); + this->LocalGenerator->IssueMessage(cmake::FATAL_ERROR, e.str()); } return processed; diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx index d7fe777..6e33cf7 100644 --- a/Source/cmInstallCommand.cxx +++ b/Source/cmInstallCommand.cxx @@ -5,7 +5,6 @@ #include "cmsys/Glob.hxx" #include <sstream> #include <stddef.h> -#include <string.h> #include <utility> #include "cmAlgorithms.h" @@ -350,8 +349,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) // Check whether this is a DLL platform. bool dll_platform = - strcmp(this->Makefile->GetSafeDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX"), - "") != 0; + !this->Makefile->GetSafeDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX").empty(); for (std::string const& tgt : targetList.GetVector()) { diff --git a/Source/cmLinkItem.cxx b/Source/cmLinkItem.cxx new file mode 100644 index 0000000..69b6821 --- /dev/null +++ b/Source/cmLinkItem.cxx @@ -0,0 +1,72 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmLinkItem.h" + +#include "cmGeneratorTarget.h" + +#include <utility> // IWYU pragma: keep + +cmLinkItem::cmLinkItem() + : String() + , Target(nullptr) +{ +} + +cmLinkItem::cmLinkItem(std::string const& n) + : String(n) + , Target(nullptr) +{ +} + +cmLinkItem::cmLinkItem(cmGeneratorTarget const* t) + : String() + , Target(t) +{ +} + +std::string const& cmLinkItem::AsStr() const +{ + return this->Target ? this->Target->GetName() : this->String; +} + +bool operator<(cmLinkItem const& l, cmLinkItem const& r) +{ + // Order among targets. + if (l.Target && r.Target) { + return l.Target < r.Target; + } + // Order targets before strings. + if (l.Target) { + return true; + } + if (r.Target) { + return false; + } + // Order among strings. + return l.String < r.String; +} + +bool operator==(cmLinkItem const& l, cmLinkItem const& r) +{ + return l.Target == r.Target && l.String == r.String; +} + +std::ostream& operator<<(std::ostream& os, cmLinkItem const& item) +{ + return os << item.AsStr(); +} + +cmLinkImplItem::cmLinkImplItem() + : cmLinkItem() + , Backtrace() + , FromGenex(false) +{ +} + +cmLinkImplItem::cmLinkImplItem(cmLinkItem item, cmListFileBacktrace const& bt, + bool fromGenex) + : cmLinkItem(std::move(item)) + , Backtrace(bt) + , FromGenex(fromGenex) +{ +} diff --git a/Source/cmLinkItem.h b/Source/cmLinkItem.h index e8c9487..74fd298 100644 --- a/Source/cmLinkItem.h +++ b/Source/cmLinkItem.h @@ -7,6 +7,7 @@ #include <algorithm> #include <map> +#include <ostream> #include <string> #include <vector> @@ -17,40 +18,27 @@ class cmGeneratorTarget; // Basic information about each link item. -class cmLinkItem : public std::string +class cmLinkItem { - typedef std::string std_string; + std::string String; public: - cmLinkItem() - : std_string() - , Target(nullptr) - { - } - cmLinkItem(const std_string& n, cmGeneratorTarget const* t) - : std_string(n) - , Target(t) - { - } + cmLinkItem(); + explicit cmLinkItem(std::string const& s); + explicit cmLinkItem(cmGeneratorTarget const* t); + std::string const& AsStr() const; cmGeneratorTarget const* Target; + friend bool operator<(cmLinkItem const& l, cmLinkItem const& r); + friend bool operator==(cmLinkItem const& l, cmLinkItem const& r); + friend std::ostream& operator<<(std::ostream& os, cmLinkItem const& item); }; class cmLinkImplItem : public cmLinkItem { public: - cmLinkImplItem() - : cmLinkItem() - , Backtrace() - , FromGenex(false) - { - } - cmLinkImplItem(std::string const& n, cmGeneratorTarget const* t, - cmListFileBacktrace const& bt, bool fromGenex) - : cmLinkItem(n, t) - , Backtrace(bt) - , FromGenex(fromGenex) - { - } + cmLinkImplItem(); + cmLinkImplItem(cmLinkItem item, cmListFileBacktrace const& bt, + bool fromGenex); cmListFileBacktrace Backtrace; bool FromGenex; }; diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index c955af6..7030725 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -683,7 +683,7 @@ std::string cmLocalGenerator::GetIncludeFlags( std::string flagVar = "CMAKE_INCLUDE_FLAG_"; flagVar += lang; - const char* includeFlag = this->Makefile->GetSafeDefinition(flagVar); + std::string const& includeFlag = this->Makefile->GetSafeDefinition(flagVar); flagVar = "CMAKE_INCLUDE_FLAG_SEP_"; flagVar += lang; const char* sep = this->Makefile->GetDefinition(flagVar); @@ -1345,7 +1345,7 @@ void cmLocalGenerator::AddArchitectureFlags(std::string& flags, const std::string& lang, const std::string& config) { - // Only add Mac OS X specific flags on Darwin platforms (OSX and iphone): + // Only add macOS specific flags on Darwin platforms (macOS and iOS): if (this->Makefile->IsOn("APPLE") && this->EmitUniversalBinaryFlags) { std::vector<std::string> archs; target->GetAppleArchs(config, archs); @@ -1824,9 +1824,9 @@ bool cmLocalGenerator::GetShouldUseOldFlags(bool shared, std::string flagsVar = "CMAKE_SHARED_LIBRARY_"; flagsVar += lang; flagsVar += "_FLAGS"; - const char* flags = this->Makefile->GetSafeDefinition(flagsVar); + std::string const& flags = this->Makefile->GetSafeDefinition(flagsVar); - if (flags && flags != originalFlags) { + if (flags != originalFlags) { switch (this->GetPolicyStatus(cmPolicies::CMP0018)) { case cmPolicies::WARN: { std::ostringstream e; @@ -1859,7 +1859,7 @@ void cmLocalGenerator::AddPositionIndependentFlags(std::string& flags, std::string const& lang, int targetType) { - const char* picFlags = nullptr; + std::string picFlags; if (targetType == cmStateEnums::EXECUTABLE) { std::string flagsVar = "CMAKE_"; @@ -1867,13 +1867,13 @@ void cmLocalGenerator::AddPositionIndependentFlags(std::string& flags, flagsVar += "_COMPILE_OPTIONS_PIE"; picFlags = this->Makefile->GetSafeDefinition(flagsVar); } - if (!picFlags) { + if (picFlags.empty()) { std::string flagsVar = "CMAKE_"; flagsVar += lang; flagsVar += "_COMPILE_OPTIONS_PIC"; picFlags = this->Makefile->GetSafeDefinition(flagsVar); } - if (picFlags) { + if (!picFlags.empty()) { std::vector<std::string> options; cmSystemTools::ExpandListArgument(picFlags, options); for (std::string const& o : options) { diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 27a42b3..58b7762 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -300,14 +300,14 @@ public: std::string const& GetCurrentSourceDirectory() const; /** - * Generate a Mac OS X application bundle Info.plist file. + * Generate a macOS application bundle Info.plist file. */ void GenerateAppleInfoPList(cmGeneratorTarget* target, const std::string& targetName, const char* fname); /** - * Generate a Mac OS X framework Info.plist file. + * Generate a macOS framework Info.plist file. */ void GenerateFrameworkInfoPList(cmGeneratorTarget* target, const std::string& targetName, diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx index 360f73d..eb31478 100644 --- a/Source/cmLocalNinjaGenerator.cxx +++ b/Source/cmLocalNinjaGenerator.cxx @@ -564,8 +564,7 @@ std::string cmLocalNinjaGenerator::MakeCustomLauncher( return std::string(); } - // Expand rules in the empty string. It may insert the launcher and - // perform replacements. + // Expand rule variables referenced in the given launcher command. cmRulePlaceholderExpander::RuleVariables vars; std::string output; @@ -580,12 +579,10 @@ std::string cmLocalNinjaGenerator::MakeCustomLauncher( } vars.Output = output.c_str(); - std::string launcher = property_value; - launcher += " "; - std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander( this->CreateRulePlaceholderExpander()); + std::string launcher = property_value; rulePlaceholderExpander->ExpandRuleVariables(this, launcher, vars); if (!launcher.empty()) { launcher += " "; diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index bc83ce2..4d19b3a 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -773,7 +773,7 @@ void cmLocalUnixMakefileGenerator3::WriteSpecialTargetsBottom( std::string cmakefileName = cmake::GetCMakeFilesDirectoryPostSlash(); cmakefileName += "Makefile.cmake"; std::string runRule = - "$(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)"; + "$(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)"; runRule += " --check-build-system "; runRule += this->ConvertToOutputFormat(cmakefileName, cmOutputConverter::SHELL); @@ -967,8 +967,7 @@ void cmLocalUnixMakefileGenerator3::AppendCustomCommand( // Short-circuit if there is no launcher. const char* val = this->GetRuleLauncher(target, "RULE_LAUNCH_CUSTOM"); if (val && *val) { - // Expand rules in the empty string. It may insert the launcher and - // perform replacements. + // Expand rule variables referenced in the given launcher command. cmRulePlaceholderExpander::RuleVariables vars; vars.CMTargetName = target->GetName().c_str(); vars.CMTargetType = cmState::GetTargetTypeName(target->GetType()); @@ -986,7 +985,6 @@ void cmLocalUnixMakefileGenerator3::AppendCustomCommand( vars.Output = output.c_str(); launcher = val; - launcher += " "; rulePlaceholderExpander->ExpandRuleVariables(this, launcher, vars); if (!launcher.empty()) { launcher += " "; @@ -1424,7 +1422,8 @@ bool cmLocalUnixMakefileGenerator3::ScanDependencies( this->WriteDisclaimer(internalRuleFileStream); // for each language we need to scan, scan it - const char* langStr = mf->GetSafeDefinition("CMAKE_DEPENDS_LANGUAGES"); + std::string const& langStr = + mf->GetSafeDefinition("CMAKE_DEPENDS_LANGUAGES"); std::vector<std::string> langs; cmSystemTools::ExpandListArgument(langStr, langs); for (std::string const& lang : langs) { @@ -1684,7 +1683,7 @@ void cmLocalUnixMakefileGenerator3::WriteLocalAllRules( cmakefileName += "Makefile.cmake"; { std::string runRule = - "$(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)"; + "$(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)"; runRule += " --check-build-system "; runRule += this->ConvertToOutputFormat(cmakefileName, cmOutputConverter::SHELL); diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 13bd214..8428672 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -260,7 +260,7 @@ cmSourceFile* cmLocalVisualStudio7Generator::CreateVCProjBuildRule() std::string comment = "Building Custom Rule "; comment += makefileIn; std::string args; - args = "-H"; + args = "-S"; args += this->GetSourceDirectory(); commandLine.push_back(args); args = "-B"; @@ -1082,7 +1082,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool( // Use the NOINHERIT macro to avoid getting VS project default // libraries which may be set by the user to something bad. fout << "\t\t\t\tAdditionalDependencies=\"$(NOINHERIT) " - << this->Makefile->GetSafeDefinition(standardLibsVar.c_str()); + << this->Makefile->GetSafeDefinition(standardLibsVar); if (this->FortranProject) { this->Internal->OutputObjects(fout, target, configName, " "); } @@ -1167,7 +1167,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool( // Use the NOINHERIT macro to avoid getting VS project default // libraries which may be set by the user to something bad. fout << "\t\t\t\tAdditionalDependencies=\"$(NOINHERIT) " - << this->Makefile->GetSafeDefinition(standardLibsVar.c_str()); + << this->Makefile->GetSafeDefinition(standardLibsVar); if (this->FortranProject) { this->Internal->OutputObjects(fout, target, configName, " "); } @@ -1497,8 +1497,7 @@ cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo( lang = sourceLang; } - cmGeneratorExpressionInterpreter genexInterpreter(lg, gt, *i, - gt->GetName(), lang); + cmGeneratorExpressionInterpreter genexInterpreter(lg, *i, gt, lang); bool needfc = false; if (!objectName.empty()) { diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 5498ad2..ec5ce92 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -11,6 +11,7 @@ #include <iterator> #include <memory> // IWYU pragma: keep #include <sstream> +#include <stdio.h> #include <stdlib.h> #include <utility> @@ -48,6 +49,11 @@ class cmMessenger; +cmDirectoryId::cmDirectoryId(std::string s) + : String(std::move(s)) +{ +} + // default is not to be building executables cmMakefile::cmMakefile(cmGlobalGenerator* globalGenerator, cmStateSnapshot const& snapshot) @@ -111,6 +117,17 @@ cmMakefile::~cmMakefile() cmDeleteAll(this->EvaluationFiles); } +cmDirectoryId cmMakefile::GetDirectoryId() const +{ + // Use the instance pointer value to uniquely identify this directory. + // If we ever need to expose this to CMake language code we should + // add a read-only property in cmMakefile::GetProperty. + char buf[32]; + sprintf(buf, "<%p>", + static_cast<void const*>(this)); // cast avoids format warning + return std::string(buf); +} + void cmMakefile::IssueMessage(cmake::MessageType t, std::string const& text) const { @@ -1718,7 +1735,8 @@ void cmMakefile::AddCacheDefinition(const std::string& name, const char* value, cmStateEnums::CacheEntryType type, bool force) { - const char* existingValue = this->GetState()->GetInitializedCacheValue(name); + const std::string* existingValue = + this->GetState()->GetInitializedCacheValue(name); // must be outside the following if() to keep it alive long enough std::string nvalue; @@ -1728,7 +1746,7 @@ void cmMakefile::AddCacheDefinition(const std::string& name, const char* value, // if this is not a force, then use the value from the cache // if it is a force, then use the value being passed in if (!force) { - value = existingValue; + value = existingValue->c_str(); } if (type == cmStateEnums::PATH || type == cmStateEnums::FILEPATH) { std::vector<std::string>::size_type cc; @@ -1748,7 +1766,7 @@ void cmMakefile::AddCacheDefinition(const std::string& name, const char* value, } this->GetCMakeInstance()->AddCacheEntry(name, nvalue.c_str(), doc, type); - nvalue = this->GetState()->GetInitializedCacheValue(name); + nvalue = *this->GetState()->GetInitializedCacheValue(name); value = nvalue.c_str(); } } @@ -2368,29 +2386,25 @@ std::string cmMakefile::GetRequiredDefinition(const std::string& name) const bool cmMakefile::IsDefinitionSet(const std::string& name) const { - const char* def; - if (const std::string* d = this->StateSnapshot.GetDefinition(name)) { - def = d->c_str(); - } else { + const std::string* def = this->StateSnapshot.GetDefinition(name); + if (!def) { def = this->GetState()->GetInitializedCacheValue(name); } #ifdef CMAKE_BUILD_WITH_CMAKE if (cmVariableWatch* vv = this->GetVariableWatch()) { if (!def) { vv->VariableAccessed( - name, cmVariableWatch::UNKNOWN_VARIABLE_DEFINED_ACCESS, def, this); + name, cmVariableWatch::UNKNOWN_VARIABLE_DEFINED_ACCESS, nullptr, this); } } #endif return def != nullptr; } -const char* cmMakefile::GetDefinition(const std::string& name) const +const std::string* cmMakefile::GetDef(const std::string& name) const { - const char* def; - if (const std::string* d = this->StateSnapshot.GetDefinition(name)) { - def = d->c_str(); - } else { + const std::string* def = this->StateSnapshot.GetDefinition(name); + if (!def) { def = this->GetState()->GetInitializedCacheValue(name); } #ifdef CMAKE_BUILD_WITH_CMAKE @@ -2400,15 +2414,14 @@ const char* cmMakefile::GetDefinition(const std::string& name) const vv->VariableAccessed(name, def ? cmVariableWatch::VARIABLE_READ_ACCESS : cmVariableWatch::UNKNOWN_VARIABLE_READ_ACCESS, - def, this); + (def ? def->c_str() : nullptr), this); if (watch_function_executed) { // A callback was executed and may have caused re-allocation of the // variable storage. Look it up again for now. // FIXME: Refactor variable storage to avoid this problem. - if (const std::string* d = this->StateSnapshot.GetDefinition(name)) { - def = d->c_str(); - } else { + def = this->StateSnapshot.GetDefinition(name); + if (!def) { def = this->GetState()->GetInitializedCacheValue(name); } } @@ -2417,13 +2430,23 @@ const char* cmMakefile::GetDefinition(const std::string& name) const return def; } -const char* cmMakefile::GetSafeDefinition(const std::string& def) const +const char* cmMakefile::GetDefinition(const std::string& name) const { - const char* ret = this->GetDefinition(def); - if (!ret) { - return ""; + const std::string* def = GetDef(name); + if (!def) { + return nullptr; } - return ret; + return def->c_str(); +} + +const std::string& cmMakefile::GetSafeDefinition(const std::string& name) const +{ + static std::string const empty; + const std::string* def = GetDef(name); + if (!def) { + return empty; + } + return *def; } std::vector<std::string> cmMakefile::GetDefinitions() const diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 0ab4371..bb01c0b 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -47,6 +47,14 @@ class cmTest; class cmTestGenerator; class cmVariableWatch; +/** A type-safe wrapper for a string representing a directory id. */ +class cmDirectoryId +{ +public: + cmDirectoryId(std::string s); + std::string String; +}; + /** \class cmMakefile * \brief Process the input CMakeLists.txt file. * @@ -75,6 +83,8 @@ public: */ ~cmMakefile(); + cmDirectoryId GetDirectoryId() const; + bool ReadListFile(const char* filename); bool ReadDependentFile(const char* filename, bool noPolicyScope = true); @@ -422,7 +432,8 @@ public: * cache is then queried. */ const char* GetDefinition(const std::string&) const; - const char* GetSafeDefinition(const std::string&) const; + const std::string* GetDef(const std::string&) const; + const std::string& GetSafeDefinition(const std::string&) const; std::string GetRequiredDefinition(const std::string& name) const; bool IsDefinitionSet(const std::string&) const; /** diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index e8cf255..c8dc392 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -434,8 +434,7 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile( std::string config = this->LocalGenerator->GetConfigName(); std::string configUpper = cmSystemTools::UpperCase(config); cmGeneratorExpressionInterpreter genexInterpreter( - this->LocalGenerator, this->GeneratorTarget, config, - this->GeneratorTarget->GetName(), lang); + this->LocalGenerator, config, this->GeneratorTarget, lang); // Add Fortran format flags. if (lang == "Fortran") { diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h index f21362a..529b4db 100644 --- a/Source/cmMakefileTargetGenerator.h +++ b/Source/cmMakefileTargetGenerator.h @@ -71,7 +71,7 @@ protected: // write the depend rules for this target void WriteTargetDependRules(); - // write rules for Mac OS X Application Bundle content. + // write rules for macOS Application Bundle content. struct MacOSXContentGeneratorType : cmOSXBundleGenerator::MacOSXContentGeneratorType { @@ -237,7 +237,7 @@ protected: std::string TargetNameImport; std::string TargetNamePDB; - // Mac OS X content info. + // macOS content info. std::set<std::string> MacContentFolders; cmOSXBundleGenerator* OSXBundleGenerator; MacOSXContentGeneratorType* MacOSXContentGenerator; diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 1cfaac5..7ac8d1b 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -10,7 +10,6 @@ #include <map> #include <memory> // IWYU pragma: keep #include <sstream> -#include <string.h> #include "cmAlgorithms.h" #include "cmComputeLinkInformation.h" @@ -136,9 +135,8 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject( // Add source file specific flags. cmGeneratorExpressionInterpreter genexInterpreter( - this->LocalGenerator, this->GeneratorTarget, - this->LocalGenerator->GetConfigName(), this->GeneratorTarget->GetName(), - language); + this->LocalGenerator, this->LocalGenerator->GetConfigName(), + this->GeneratorTarget, language); const std::string COMPILE_FLAGS("COMPILE_FLAGS"); if (const char* cflags = source->GetProperty(COMPILE_FLAGS)) { @@ -175,9 +173,8 @@ void cmNinjaTargetGenerator::AddIncludeFlags(std::string& languageFlags, bool cmNinjaTargetGenerator::NeedDepTypeMSVC(const std::string& lang) const { - return strcmp(this->GetMakefile()->GetSafeDefinition("CMAKE_NINJA_DEPTYPE_" + - lang), - "msvc") == 0; + return (this->GetMakefile()->GetSafeDefinition("CMAKE_NINJA_DEPTYPE_" + + lang) == "msvc"); } // TODO: Refactor with @@ -188,8 +185,7 @@ std::string cmNinjaTargetGenerator::ComputeDefines(cmSourceFile const* source, std::set<std::string> defines; const std::string config = this->LocalGenerator->GetConfigName(); cmGeneratorExpressionInterpreter genexInterpreter( - this->LocalGenerator, this->GeneratorTarget, config, - this->GeneratorTarget->GetName(), language); + this->LocalGenerator, config, this->GeneratorTarget, language); const std::string COMPILE_DEFINITIONS("COMPILE_DEFINITIONS"); if (const char* compile_defs = source->GetProperty(COMPILE_DEFINITIONS)) { @@ -217,8 +213,7 @@ std::string cmNinjaTargetGenerator::ComputeIncludes( std::vector<std::string> includes; const std::string config = this->LocalGenerator->GetConfigName(); cmGeneratorExpressionInterpreter genexInterpreter( - this->LocalGenerator, this->GeneratorTarget, config, - this->GeneratorTarget->GetName(), language); + this->LocalGenerator, config, this->GeneratorTarget, language); const std::string INCLUDE_DIRECTORIES("INCLUDE_DIRECTORIES"); if (const char* cincludes = source->GetProperty(INCLUDE_DIRECTORIES)) { diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h index e58a8a0..373c693 100644 --- a/Source/cmNinjaTargetGenerator.h +++ b/Source/cmNinjaTargetGenerator.h @@ -135,7 +135,7 @@ protected: void EnsureDirectoryExists(const std::string& dir) const; void EnsureParentDirectoryExists(const std::string& path) const; - // write rules for Mac OS X Application Bundle content. + // write rules for macOS Application Bundle content. struct MacOSXContentGeneratorType : cmOSXBundleGenerator::MacOSXContentGeneratorType { diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx index ba50fb8..5caea7d 100644 --- a/Source/cmPolicies.cxx +++ b/Source/cmPolicies.cxx @@ -135,7 +135,7 @@ static bool GetPolicyDefault(cmMakefile* mf, std::string const& policy, cmPolicies::PolicyStatus* defaultSetting) { std::string defaultVar = "CMAKE_POLICY_DEFAULT_" + policy; - std::string defaultValue = mf->GetSafeDefinition(defaultVar); + std::string const& defaultValue = mf->GetSafeDefinition(defaultVar); if (defaultValue == "NEW") { *defaultSetting = cmPolicies::NEW; } else if (defaultValue == "OLD") { diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index 91ed924..4ffe803 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -230,7 +230,11 @@ class cmMakefile; SELECT(POLICY, CMP0077, "option() honors normal variables.", 3, 13, 0, \ cmPolicies::WARN) \ SELECT(POLICY, CMP0078, "UseSWIG generates standard target names.", 3, 13, \ - 0, cmPolicies::WARN) + 0, cmPolicies::WARN) \ + SELECT( \ + POLICY, CMP0079, \ + "target_link_libraries allows use with targets in other directories.", 3, \ + 13, 0, cmPolicies::WARN) #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1) #define CM_FOR_EACH_POLICY_ID(POLICY) \ diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx index 8bd985a..8a202a2 100644 --- a/Source/cmQtAutoGenInitializer.cxx +++ b/Source/cmQtAutoGenInitializer.cxx @@ -1126,7 +1126,7 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo() } }; auto MfDef = [makefile](const char* key) { - return std::string(makefile->GetSafeDefinition(key)); + return makefile->GetSafeDefinition(key); }; // Write diff --git a/Source/cmQtAutoGeneratorMocUic.cxx b/Source/cmQtAutoGeneratorMocUic.cxx index c364700..2e6f90f 100644 --- a/Source/cmQtAutoGeneratorMocUic.cxx +++ b/Source/cmQtAutoGeneratorMocUic.cxx @@ -1204,7 +1204,7 @@ bool cmQtAutoGeneratorMocUic::Init(cmMakefile* makefile) valueConf = makefile->GetDefinition(keyConf); } if (valueConf == nullptr) { - valueConf = makefile->GetSafeDefinition(key); + return makefile->GetSafeDefinition(key); } return std::string(valueConf); }; @@ -1226,7 +1226,7 @@ bool cmQtAutoGeneratorMocUic::Init(cmMakefile* makefile) Base_.MultiConfig = InfoGetBool("AM_MULTI_CONFIG"); { unsigned long num = Base_.NumThreads; - if (cmSystemTools::StringToULong(InfoGet("AM_PARALLEL"), &num)) { + if (cmSystemTools::StringToULong(InfoGet("AM_PARALLEL").c_str(), &num)) { num = std::max<unsigned long>(num, 1); num = std::min<unsigned long>(num, ParallelMax); Base_.NumThreads = static_cast<unsigned int>(num); @@ -1264,7 +1264,8 @@ bool cmQtAutoGeneratorMocUic::Init(cmMakefile* makefile) // - Qt environment { unsigned long qtv = Base_.QtVersionMajor; - if (cmSystemTools::StringToULong(InfoGet("AM_QT_VERSION_MAJOR"), &qtv)) { + if (cmSystemTools::StringToULong(InfoGet("AM_QT_VERSION_MAJOR").c_str(), + &qtv)) { Base_.QtVersionMajor = static_cast<unsigned int>(qtv); } } diff --git a/Source/cmQtAutoGeneratorRcc.cxx b/Source/cmQtAutoGeneratorRcc.cxx index 6caa0d8..65c6741 100644 --- a/Source/cmQtAutoGeneratorRcc.cxx +++ b/Source/cmQtAutoGeneratorRcc.cxx @@ -52,7 +52,7 @@ bool cmQtAutoGeneratorRcc::Init(cmMakefile* makefile) valueConf = makefile->GetDefinition(keyConf); } if (valueConf == nullptr) { - valueConf = makefile->GetSafeDefinition(key); + return makefile->GetSafeDefinition(key); } return std::string(valueConf); }; diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx index af4b466..2cad657 100644 --- a/Source/cmServerProtocol.cxx +++ b/Source/cmServerProtocol.cxx @@ -722,8 +722,8 @@ static void PopulateFileGroupData( ? languageDataMap.at(kInterfaceSourcesLanguageDataKey) : languageDataMap.at(fileData.Language); cmLocalGenerator* lg = target->GetLocalGenerator(); - cmGeneratorExpressionInterpreter genexInterpreter( - lg, target, config, target->GetName(), fileData.Language); + cmGeneratorExpressionInterpreter genexInterpreter(lg, config, target, + fileData.Language); std::string compileFlags = ld.Flags; const std::string COMPILE_FLAGS("COMPILE_FLAGS"); @@ -817,7 +817,7 @@ static Json::Value DumpSourceFilesList( auto targetProp = target->Target->GetProperty("INTERFACE_SOURCES"); if (targetProp != nullptr) { cmGeneratorExpressionInterpreter genexInterpreter( - target->GetLocalGenerator(), target, config, target->GetName(), ""); + target->GetLocalGenerator(), config, target); auto evaluatedSources = cmsys::SystemTools::SplitString( genexInterpreter.Evaluate(targetProp, "INTERFACE_SOURCES"), ';'); @@ -977,8 +977,7 @@ static void CreateInterfaceSourcesEntry( LanguageData& ld = languageDataMap[kInterfaceSourcesLanguageDataKey]; ld.Language = ""; - cmGeneratorExpressionInterpreter genexInterpreter(lg, target, config, - target->GetName(), ""); + cmGeneratorExpressionInterpreter genexInterpreter(lg, config, target); std::vector<std::string> propertyValue; GetTargetProperty(genexInterpreter, target, "INTERFACE_INCLUDE_DIRECTORIES", propertyValue); @@ -1340,20 +1339,20 @@ cmServerResponse cmServerProtocol1::ProcessConfigure( if (cm->LoadCache(buildDir)) { // build directory has been set up before - const char* cachedSourceDir = + const std::string* cachedSourceDir = cm->GetState()->GetInitializedCacheValue("CMAKE_HOME_DIRECTORY"); if (!cachedSourceDir) { return request.ReportError("No CMAKE_HOME_DIRECTORY found in cache."); } if (sourceDir.empty()) { - sourceDir = std::string(cachedSourceDir); + sourceDir = *cachedSourceDir; cm->SetHomeDirectory(sourceDir); } - const char* cachedGenerator = + const std::string* cachedGenerator = cm->GetState()->GetInitializedCacheValue("CMAKE_GENERATOR"); if (cachedGenerator) { - if (gg && gg->GetName() != cachedGenerator) { + if (gg && gg->GetName() != *cachedGenerator) { return request.ReportError("Configured generator does not match with " "CMAKE_GENERATOR found in cache."); } diff --git a/Source/cmState.cxx b/Source/cmState.cxx index 89738f4..c6667f6 100644 --- a/Source/cmState.cxx +++ b/Source/cmState.cxx @@ -140,7 +140,8 @@ const char* cmState::GetCacheEntryValue(std::string const& key) const return e->Value.c_str(); } -const char* cmState::GetInitializedCacheValue(std::string const& key) const +const std::string* cmState::GetInitializedCacheValue( + std::string const& key) const { return this->CacheManager->GetInitializedCacheValue(key); } @@ -658,6 +659,7 @@ cmStateSnapshot cmState::CreateBaseSnapshot() pos->IncludeDirectoryPosition = 0; pos->CompileDefinitionsPosition = 0; pos->CompileOptionsPosition = 0; + pos->LinkOptionsPosition = 0; pos->BuildSystemDirectory->DirectoryEnd = pos; pos->Policies = this->PolicyStack.Root(); pos->PolicyRoot = this->PolicyStack.Root(); @@ -809,6 +811,8 @@ cmStateSnapshot cmState::Pop(cmStateSnapshot const& originSnapshot) prevPos->BuildSystemDirectory->CompileDefinitions.size(); prevPos->CompileOptionsPosition = prevPos->BuildSystemDirectory->CompileOptions.size(); + prevPos->LinkOptionsPosition = + prevPos->BuildSystemDirectory->LinkOptions.size(); prevPos->BuildSystemDirectory->DirectoryEnd = prevPos; if (!pos->Keep && this->SnapshotData.IsLast(pos)) { diff --git a/Source/cmState.h b/Source/cmState.h index 38bdfec..ca7093a 100644 --- a/Source/cmState.h +++ b/Source/cmState.h @@ -68,7 +68,7 @@ public: std::vector<std::string> GetCacheEntryKeys() const; const char* GetCacheEntryValue(std::string const& key) const; - const char* GetInitializedCacheValue(std::string const& key) const; + const std::string* GetInitializedCacheValue(std::string const& key) const; cmStateEnums::CacheEntryType GetCacheEntryType(std::string const& key) const; void SetCacheEntryValue(std::string const& key, std::string const& value); void SetCacheValue(std::string const& key, std::string const& value); diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index cfcb31a..4e353c7 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -190,13 +190,11 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, // Check whether this is a DLL platform. this->DLLPlatform = - strcmp(this->Makefile->GetSafeDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX"), - "") != 0; + !this->Makefile->GetSafeDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX").empty(); // Check whether we are targeting an Android platform. this->IsAndroid = - strcmp(this->Makefile->GetSafeDefinition("CMAKE_SYSTEM_NAME"), - "Android") == 0; + (this->Makefile->GetSafeDefinition("CMAKE_SYSTEM_NAME") == "Android"); // Setup default property values. if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY && @@ -745,20 +743,27 @@ void cmTarget::GetTllSignatureTraces(std::ostream& s, TLLSignature sig) const void cmTarget::AddLinkLibrary(cmMakefile& mf, const std::string& lib, cmTargetLinkLibraryType llt) { - cmTarget* tgt = this->Makefile->FindTargetToUse(lib); + this->AddLinkLibrary(mf, lib, lib, llt); +} + +void cmTarget::AddLinkLibrary(cmMakefile& mf, std::string const& lib, + std::string const& libRef, + cmTargetLinkLibraryType llt) +{ + cmTarget* tgt = mf.FindTargetToUse(lib); { const bool isNonImportedTarget = tgt && !tgt->IsImported(); const std::string libName = (isNonImportedTarget && llt != GENERAL_LibraryType) - ? targetNameGenex(lib) - : lib; + ? targetNameGenex(libRef) + : libRef; this->AppendProperty( "LINK_LIBRARIES", this->GetDebugGeneratorExpressions(libName, llt).c_str()); } - if (cmGeneratorExpression::Find(lib) != std::string::npos || + if (cmGeneratorExpression::Find(lib) != std::string::npos || lib != libRef || (tgt && (tgt->GetType() == cmStateEnums::INTERFACE_LIBRARY || tgt->GetType() == cmStateEnums::OBJECT_LIBRARY)) || diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 7a3ab65..1f380df 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -142,6 +142,9 @@ public: void AddLinkLibrary(cmMakefile& mf, const std::string& lib, cmTargetLinkLibraryType llt); + void AddLinkLibrary(cmMakefile& mf, std::string const& lib, + std::string const& libRef, cmTargetLinkLibraryType llt); + enum TLLSignature { KeywordTLLSignature, diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx index 1bbcf46..ad33f98 100644 --- a/Source/cmTargetLinkLibrariesCommand.cxx +++ b/Source/cmTargetLinkLibrariesCommand.cxx @@ -359,30 +359,53 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib, } } + bool warnRemoteInterface = false; + bool rejectRemoteLinking = false; + bool encodeRemoteReference = false; + if (this->Makefile != this->Target->GetMakefile()) { + // The LHS target was created in another directory. + switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0079)) { + case cmPolicies::WARN: + warnRemoteInterface = true; + CM_FALLTHROUGH; + case cmPolicies::OLD: + rejectRemoteLinking = true; + break; + case cmPolicies::REQUIRED_ALWAYS: + case cmPolicies::REQUIRED_IF_USED: + case cmPolicies::NEW: + encodeRemoteReference = true; + break; + } + } + + std::string libRef; + if (encodeRemoteReference && !cmSystemTools::FileIsFullPath(lib)) { + // This is a library name added by a caller that is not in the + // same directory as the target was created. Add a suffix to + // the name to tell ResolveLinkItem to look up the name in the + // caller's directory. + cmDirectoryId const dirId = this->Makefile->GetDirectoryId(); + libRef = lib + CMAKE_DIRECTORY_ID_SEP + dirId.String; + } else { + // This is an absolute path or a library name added by a caller + // in the same directory as the target was created. We can use + // the original name directly. + libRef = lib; + } + // Handle normal case where the command was called with another keyword than // INTERFACE / LINK_INTERFACE_LIBRARIES or none at all. (The "LINK_LIBRARIES" // property of the target on the LHS shall be populated.) if (this->CurrentProcessingState != ProcessingKeywordLinkInterface && this->CurrentProcessingState != ProcessingPlainLinkInterface) { - // Assure that the target on the LHS was created in the current directory. - cmTarget* t = - this->Makefile->FindLocalNonAliasTarget(this->Target->GetName()); - if (!t) { - const std::vector<cmTarget*>& importedTargets = - this->Makefile->GetOwnedImportedTargets(); - for (cmTarget* importedTarget : importedTargets) { - if (importedTarget->GetName() == this->Target->GetName()) { - t = importedTarget; - break; - } - } - } - if (!t) { + if (rejectRemoteLinking) { std::ostringstream e; e << "Attempt to add link library \"" << lib << "\" to target \"" << this->Target->GetName() - << "\" which is not built in this directory."; + << "\" which is not built in this directory.\n" + << "This is allowed only when policy CMP0079 is set to NEW."; this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); return false; } @@ -404,7 +427,20 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib, this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); } - this->Target->AddLinkLibrary(*this->Makefile, lib, llt); + this->Target->AddLinkLibrary(*this->Makefile, lib, libRef, llt); + } + + if (warnRemoteInterface) { + std::ostringstream w; + /* clang-format off */ + w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0079) << "\n" + "Target\n " << this->Target->GetName() << "\nis not created in this " + "directory. For compatibility with older versions of CMake, link " + "library\n " << lib << "\nwill be looked up in the directory in " + "which the target was created rather than in this calling " + "directory."; + /* clang-format on */ + this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str()); } // Handle (additional) case where the command was called with PRIVATE / @@ -415,9 +451,9 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib, this->CurrentProcessingState == ProcessingPlainPrivateInterface) { if (this->Target->GetType() == cmStateEnums::STATIC_LIBRARY) { std::string configLib = - this->Target->GetDebugGeneratorExpressions(lib, llt); - if (cmGeneratorExpression::IsValidTargetName(lib) || - cmGeneratorExpression::Find(lib) != std::string::npos) { + this->Target->GetDebugGeneratorExpressions(libRef, llt); + if (cmGeneratorExpression::IsValidTargetName(libRef) || + cmGeneratorExpression::Find(libRef) != std::string::npos) { configLib = "$<LINK_ONLY:" + configLib + ">"; } this->Target->AppendProperty("INTERFACE_LINK_LIBRARIES", @@ -431,7 +467,7 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib, // property of the target on the LHS shall be populated.) this->Target->AppendProperty( "INTERFACE_LINK_LIBRARIES", - this->Target->GetDebugGeneratorExpressions(lib, llt).c_str()); + this->Target->GetDebugGeneratorExpressions(libRef, llt).c_str()); // Stop processing if called without any keyword. if (this->CurrentProcessingState == ProcessingLinkLibraries) { @@ -464,12 +500,12 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib, for (std::string const& dc : debugConfigs) { prop = "LINK_INTERFACE_LIBRARIES_"; prop += dc; - this->Target->AppendProperty(prop, lib.c_str()); + this->Target->AppendProperty(prop, libRef.c_str()); } } if (llt == OPTIMIZED_LibraryType || llt == GENERAL_LibraryType) { // Put in the non-DEBUG configuration interfaces. - this->Target->AppendProperty("LINK_INTERFACE_LIBRARIES", lib.c_str()); + this->Target->AppendProperty("LINK_INTERFACE_LIBRARIES", libRef.c_str()); // Make sure the DEBUG configuration interfaces exist so that the // general one will not be used as a fall-back. diff --git a/Source/cmTargetLinkOptionsCommand.cxx b/Source/cmTargetLinkOptionsCommand.cxx index f0f13fd..d6ed5ae 100644 --- a/Source/cmTargetLinkOptionsCommand.cxx +++ b/Source/cmTargetLinkOptionsCommand.cxx @@ -33,9 +33,9 @@ std::string cmTargetLinkOptionsCommand::Join( } bool cmTargetLinkOptionsCommand::HandleDirectContent( - cmTarget* tgt, const std::vector<std::string>& content, bool, bool) + cmTarget* tgt, const std::vector<std::string>& content, bool prepend, bool) { cmListFileBacktrace lfbt = this->Makefile->GetBacktrace(); - tgt->InsertLinkOption(this->Join(content), lfbt); + tgt->InsertLinkOption(this->Join(content), lfbt, prepend); return true; // Successfully handled. } diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 9e74335..c79b071 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -1122,6 +1122,9 @@ void cmVisualStudio10TargetGenerator::WriteMSToolConfigurationValues( this->GeneratorTarget->GetPropertyAsBool("VS_WINRT_EXTENSIONS")) { e1.Element("WindowsAppContainer", "true"); } + if (this->IPOEnabledConfigurations.count(config) > 0) { + e1.Element("WholeProgramOptimization", "true"); + } } void cmVisualStudio10TargetGenerator::WriteMSToolConfigurationValuesManaged( @@ -2117,8 +2120,7 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags( flagtable = gg->GetCSharpFlagTable(); } cmGeneratorExpressionInterpreter genexInterpreter( - this->LocalGenerator, this->GeneratorTarget, config, - this->GeneratorTarget->GetName(), lang); + this->LocalGenerator, config, this->GeneratorTarget, lang); cmVS10GeneratorOptions clOptions( this->LocalGenerator, cmVisualStudioGeneratorOptions::Compiler, flagtable, this); @@ -2371,9 +2373,11 @@ void cmVisualStudio10TargetGenerator::OutputLinkIncremental( Options& linkOptions = *(this->LinkOptions[configName]); const std::string cond = this->CalcCondition(configName); - const char* incremental = linkOptions.GetFlag("LinkIncremental"); - e1.WritePlatformConfigTag("LinkIncremental", cond, - (incremental ? incremental : "true")); + if (this->IPOEnabledConfigurations.count(configName) == 0) { + const char* incremental = linkOptions.GetFlag("LinkIncremental"); + e1.WritePlatformConfigTag("LinkIncremental", cond, + (incremental ? incremental : "true")); + } linkOptions.RemoveFlag("LinkIncremental"); const char* manifest = linkOptions.GetFlag("GenerateManifest"); @@ -2485,8 +2489,10 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions( clOptions.AddFlag("CompileAs", "CompileAsCpp"); } - // Check IPO related warning/error. - this->GeneratorTarget->IsIPOEnabled(linkLanguage, configName); + // Put the IPO enabled configurations into a set. + if (this->GeneratorTarget->IsIPOEnabled(linkLanguage, configName)) { + this->IPOEnabledConfigurations.insert(configName); + } // Get preprocessor definitions for this directory. std::string defineFlags = this->Makefile->GetDefineFlags(); @@ -2700,11 +2706,9 @@ bool cmVisualStudio10TargetGenerator::ComputeRcOptions( Options& rcOptions = *pOptions; std::string CONFIG = cmSystemTools::UpperCase(configName); - std::string rcConfigFlagsVar = std::string("CMAKE_RC_FLAGS_") + CONFIG; - std::string flags = - std::string(this->Makefile->GetSafeDefinition("CMAKE_RC_FLAGS")) + - std::string(" ") + - std::string(this->Makefile->GetSafeDefinition(rcConfigFlagsVar)); + std::string rcConfigFlagsVar = "CMAKE_RC_FLAGS_" + CONFIG; + std::string flags = this->Makefile->GetSafeDefinition("CMAKE_RC_FLAGS") + + " " + this->Makefile->GetSafeDefinition(rcConfigFlagsVar); rcOptions.Parse(flags); @@ -2758,10 +2762,8 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaOptions( // Get compile flags for CUDA in this directory. std::string CONFIG = cmSystemTools::UpperCase(configName); std::string configFlagsVar = std::string("CMAKE_CUDA_FLAGS_") + CONFIG; - std::string flags = - std::string(this->Makefile->GetSafeDefinition("CMAKE_CUDA_FLAGS")) + - std::string(" ") + - std::string(this->Makefile->GetSafeDefinition(configFlagsVar)); + std::string flags = this->Makefile->GetSafeDefinition("CMAKE_CUDA_FLAGS") + + " " + this->Makefile->GetSafeDefinition(configFlagsVar); this->LocalGenerator->AddCompileOptions(flags, this->GeneratorTarget, "CUDA", configName); @@ -2972,9 +2974,8 @@ bool cmVisualStudio10TargetGenerator::ComputeMasmOptions( std::string CONFIG = cmSystemTools::UpperCase(configName); std::string configFlagsVar = std::string("CMAKE_ASM_MASM_FLAGS_") + CONFIG; std::string flags = - std::string(this->Makefile->GetSafeDefinition("CMAKE_ASM_MASM_FLAGS")) + - std::string(" ") + - std::string(this->Makefile->GetSafeDefinition(configFlagsVar)); + this->Makefile->GetSafeDefinition("CMAKE_ASM_MASM_FLAGS") + " " + + this->Makefile->GetSafeDefinition(configFlagsVar); masmOptions.Parse(flags); @@ -3025,14 +3026,11 @@ bool cmVisualStudio10TargetGenerator::ComputeNasmOptions( Options& nasmOptions = *pOptions; std::string CONFIG = cmSystemTools::UpperCase(configName); - std::string configFlagsVar = std::string("CMAKE_ASM_NASM_FLAGS_") + CONFIG; + std::string configFlagsVar = "CMAKE_ASM_NASM_FLAGS_" + CONFIG; std::string flags = - std::string(this->Makefile->GetSafeDefinition("CMAKE_ASM_NASM_FLAGS")) + - std::string(" -f") + - std::string( - this->Makefile->GetSafeDefinition("CMAKE_ASM_NASM_OBJECT_FORMAT")) + - std::string(" ") + - std::string(this->Makefile->GetSafeDefinition(configFlagsVar)); + this->Makefile->GetSafeDefinition("CMAKE_ASM_NASM_FLAGS") + " -f" + + this->Makefile->GetSafeDefinition("CMAKE_ASM_NASM_OBJECT_FORMAT") + " " + + this->Makefile->GetSafeDefinition(configFlagsVar); nasmOptions.Parse(flags); // Get includes for this target diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h index 15e47b4..829d2bf 100644 --- a/Source/cmVisualStudio10TargetGenerator.h +++ b/Source/cmVisualStudio10TargetGenerator.h @@ -204,6 +204,7 @@ private: bool NsightTegra; unsigned int NsightTegraVersion[4]; bool TargetCompileAsWinRT; + std::set<std::string> IPOEnabledConfigurations; cmGlobalVisualStudio10Generator* const GlobalGenerator; cmLocalVisualStudio10Generator* const LocalGenerator; std::set<std::string> CSharpCustomCommandNames; diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 1bf8f7d..6c14834 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -319,9 +319,10 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args) bool haveValue = false; std::string cachedValue; if (this->WarnUnusedCli) { - if (const char* v = this->State->GetInitializedCacheValue(var)) { + if (const std::string* v = + this->State->GetInitializedCacheValue(var)) { haveValue = true; - cachedValue = v; + cachedValue = *v; } } @@ -331,7 +332,7 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args) if (this->WarnUnusedCli) { if (!haveValue || - cachedValue != this->State->GetInitializedCacheValue(var)) { + cachedValue != *this->State->GetInitializedCacheValue(var)) { this->WatchUnusedCli(var); } } @@ -611,19 +612,43 @@ void cmake::SetArgs(const std::vector<std::string>& args, bool havePlatform = false; for (unsigned int i = 1; i < args.size(); ++i) { std::string const& arg = args[i]; - if (arg.find("-H", 0) == 0) { + if (arg.find("-H", 0) == 0 || arg.find("-S", 0) == 0) { directoriesSet = true; std::string path = arg.substr(2); + if (path.empty()) { + ++i; + if (i >= args.size()) { + cmSystemTools::Error("No source directory specified for -S"); + return; + } + path = args[i]; + if (path[0] == '-') { + cmSystemTools::Error("No source directory specified for -S"); + return; + } + } + path = cmSystemTools::CollapseFullPath(path); cmSystemTools::ConvertToUnixSlashes(path); this->SetHomeDirectory(path); - } else if (arg.find("-S", 0) == 0) { - // There is no local generate anymore. Ignore -S option. } else if (arg.find("-O", 0) == 0) { // There is no local generate anymore. Ignore -O option. } else if (arg.find("-B", 0) == 0) { directoriesSet = true; std::string path = arg.substr(2); + if (path.empty()) { + ++i; + if (i >= args.size()) { + cmSystemTools::Error("No build directory specified for -B"); + return; + } + path = args[i]; + if (path[0] == '-') { + cmSystemTools::Error("No build directory specified for -B"); + return; + } + } + path = cmSystemTools::CollapseFullPath(path); cmSystemTools::ConvertToUnixSlashes(path); this->SetHomeOutputDirectory(path); @@ -835,20 +860,27 @@ void cmake::SetDirectoriesFromFile(const char* arg) this->SetHomeOutputDirectory(listPath); } else { // Source directory given on command line. Use current working - // directory as build tree. - std::string cwd = cmSystemTools::GetCurrentWorkingDirectory(); - this->SetHomeOutputDirectory(cwd); + // directory as build tree if -B hasn't been given already + if (this->GetHomeOutputDirectory().empty()) { + std::string cwd = cmSystemTools::GetCurrentWorkingDirectory(); + this->SetHomeOutputDirectory(cwd); + } } return; } - // We didn't find a CMakeLists.txt or CMakeCache.txt file from the - // argument. Assume it is the path to the source tree, and use the - // current working directory as the build tree. - std::string full = cmSystemTools::CollapseFullPath(arg); - std::string cwd = cmSystemTools::GetCurrentWorkingDirectory(); - this->SetHomeDirectory(full); - this->SetHomeOutputDirectory(cwd); + if (this->GetHomeDirectory().empty()) { + // We didn't find a CMakeLists.txt and it wasn't specified + // with -S. Assume it is the path to the source tree + std::string full = cmSystemTools::CollapseFullPath(arg); + this->SetHomeDirectory(full); + } + if (this->GetHomeOutputDirectory().empty()) { + // We didn't find a CMakeCache.txt and it wasn't specified + // with -B. Assume the current working directory as the build tree. + std::string cwd = cmSystemTools::GetCurrentWorkingDirectory(); + this->SetHomeOutputDirectory(cwd); + } } // at the end of this CMAKE_ROOT and CMAKE_COMMAND should be added to the @@ -1107,7 +1139,7 @@ int cmake::DoPreConfigureChecks() // do a sanity check on some values if (this->State->GetInitializedCacheValue("CMAKE_HOME_DIRECTORY")) { std::string cacheStart = - this->State->GetInitializedCacheValue("CMAKE_HOME_DIRECTORY"); + *this->State->GetInitializedCacheValue("CMAKE_HOME_DIRECTORY"); cacheStart += "/CMakeLists.txt"; std::string currentStart = this->GetHomeDirectory(); currentStart += "/CMakeLists.txt"; @@ -1276,14 +1308,14 @@ int cmake::ActualConfigure() // no generator specified on the command line if (!this->GlobalGenerator) { - const char* genName = + const std::string* genName = this->State->GetInitializedCacheValue("CMAKE_GENERATOR"); - const char* extraGenName = + const std::string* extraGenName = this->State->GetInitializedCacheValue("CMAKE_EXTRA_GENERATOR"); if (genName) { std::string fullName = cmExternalMakefileProjectGenerator::CreateFullGeneratorName( - genName, extraGenName ? extraGenName : ""); + *genName, extraGenName ? *extraGenName : ""); this->GlobalGenerator = this->CreateGlobalGenerator(fullName); } if (this->GlobalGenerator) { @@ -1301,14 +1333,14 @@ int cmake::ActualConfigure() } } - const char* genName = + const std::string* genName = this->State->GetInitializedCacheValue("CMAKE_GENERATOR"); if (genName) { - if (!this->GlobalGenerator->MatchesGeneratorName(genName)) { + if (!this->GlobalGenerator->MatchesGeneratorName(*genName)) { std::string message = "Error: generator : "; message += this->GlobalGenerator->GetName(); message += "\nDoes not match the generator used previously: "; - message += genName; + message += *genName; message += "\nEither remove the CMakeCache.txt file and CMakeFiles " "directory or choose a different binary directory."; cmSystemTools::Error(message.c_str()); @@ -1325,14 +1357,14 @@ int cmake::ActualConfigure() cmStateEnums::INTERNAL); } - if (const char* instance = + if (const std::string* instance = this->State->GetInitializedCacheValue("CMAKE_GENERATOR_INSTANCE")) { if (!this->GeneratorInstance.empty() && - this->GeneratorInstance != instance) { + this->GeneratorInstance != *instance) { std::string message = "Error: generator instance: "; message += this->GeneratorInstance; message += "\nDoes not match the instance used previously: "; - message += instance; + message += *instance; message += "\nEither remove the CMakeCache.txt file and CMakeFiles " "directory or choose a different binary directory."; cmSystemTools::Error(message.c_str()); @@ -1344,14 +1376,14 @@ int cmake::ActualConfigure() "Generator instance identifier.", cmStateEnums::INTERNAL); } - if (const char* platformName = + if (const std::string* platformName = this->State->GetInitializedCacheValue("CMAKE_GENERATOR_PLATFORM")) { if (!this->GeneratorPlatform.empty() && - this->GeneratorPlatform != platformName) { + this->GeneratorPlatform != *platformName) { std::string message = "Error: generator platform: "; message += this->GeneratorPlatform; message += "\nDoes not match the platform used previously: "; - message += platformName; + message += *platformName; message += "\nEither remove the CMakeCache.txt file and CMakeFiles " "directory or choose a different binary directory."; cmSystemTools::Error(message.c_str()); @@ -1363,13 +1395,13 @@ int cmake::ActualConfigure() "Name of generator platform.", cmStateEnums::INTERNAL); } - if (const char* tsName = + if (const std::string* tsName = this->State->GetInitializedCacheValue("CMAKE_GENERATOR_TOOLSET")) { - if (!this->GeneratorToolset.empty() && this->GeneratorToolset != tsName) { + if (!this->GeneratorToolset.empty() && this->GeneratorToolset != *tsName) { std::string message = "Error: generator toolset: "; message += this->GeneratorToolset; message += "\nDoes not match the toolset used previously: "; - message += tsName; + message += *tsName; message += "\nEither remove the CMakeCache.txt file and CMakeFiles " "directory or choose a different binary directory."; cmSystemTools::Error(message.c_str()); @@ -1685,7 +1717,8 @@ std::string cmake::StripExtension(const std::string& file) const const char* cmake::GetCacheDefinition(const std::string& name) const { - return this->State->GetInitializedCacheValue(name); + const std::string* p = this->State->GetInitializedCacheValue(name); + return p ? p->c_str() : nullptr; } void cmake::AddScriptingCommands() @@ -1868,14 +1901,14 @@ void cmake::PrintGeneratorList() void cmake::UpdateConversionPathTable() { // Update the path conversion table with any specified file: - const char* tablepath = + const std::string* tablepath = this->State->GetInitializedCacheValue("CMAKE_PATH_TRANSLATION_FILE"); if (tablepath) { - cmsys::ifstream table(tablepath); + cmsys::ifstream table(tablepath->c_str()); if (!table) { - cmSystemTools::Error("CMAKE_PATH_TRANSLATION_FILE set to ", tablepath, - ". CMake can not open file."); + cmSystemTools::Error("CMAKE_PATH_TRANSLATION_FILE set to ", + tablepath->c_str(), ". CMake can not open file."); cmSystemTools::ReportLastSystemError("CMake can not open file."); } else { std::string a, b; @@ -2527,11 +2560,11 @@ bool cmake::Open(const std::string& dir, bool dryRun) std::cerr << "Error: could not find CMAKE_GENERATOR in Cache\n"; return false; } - const char* extraGenName = + const std::string* extraGenName = this->State->GetInitializedCacheValue("CMAKE_EXTRA_GENERATOR"); std::string fullName = cmExternalMakefileProjectGenerator::CreateFullGeneratorName( - genName, extraGenName ? extraGenName : ""); + genName, extraGenName ? *extraGenName : ""); std::unique_ptr<cmGlobalGenerator> gen( this->CreateGlobalGenerator(fullName)); diff --git a/Source/cmake.h b/Source/cmake.h index 4b4c67c..f7dc3f7 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -556,7 +556,9 @@ private: }; #define CMAKE_STANDARD_OPTIONS_TABLE \ - { "-C <initial-cache>", "Pre-load a script to populate the cache." }, \ + { "-S <path-to-source>", "Explicitly specify a source directory." }, \ + { "-B <path-to-build>", "Explicitly specify a build directory." }, \ + { "-C <initial-cache>", "Pre-load a script to populate the cache." }, \ { "-D <var>[:<type>]=<value>", "Create or update a cmake cache entry." }, \ { "-U <globbing_expr>", "Remove matching entries from CMake cache." }, \ { "-G <generator-name>", "Specify a build system generator." }, \ diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index e3d94f6..75dabde 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -38,7 +38,8 @@ static const char* cmDocumentationName[][2] = { static const char* cmDocumentationUsage[][2] = { { nullptr, " cmake [options] <path-to-source>\n" - " cmake [options] <path-to-existing-build>" }, + " cmake [options] <path-to-existing-build>\n" + " cmake [options] -S <path-to-source> -B <path-to-build>" }, { nullptr, "Specify a source directory to (re-)generate a build system for " "it in the current working directory. Specify an existing build " diff --git a/Source/kwsys/ProcessWin32.c b/Source/kwsys/ProcessWin32.c index 9fa0cb1..2a2e737 100644 --- a/Source/kwsys/ProcessWin32.c +++ b/Source/kwsys/ProcessWin32.c @@ -973,8 +973,8 @@ void kwsysProcess_Execute(kwsysProcess* cp) wchar_t* wstdin = kwsysEncoding_DupToWide(cp->PipeFileSTDIN); DWORD error; cp->PipeChildStd[0] = - CreateFileW(wstdin, GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); + CreateFileW(wstdin, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, + OPEN_EXISTING, 0, 0); error = GetLastError(); /* Check now in case free changes this. */ free(wstdin); if (cp->PipeChildStd[0] == INVALID_HANDLE_VALUE) { diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx index 476fe08..0a4ad7a 100644 --- a/Source/kwsys/SystemTools.cxx +++ b/Source/kwsys/SystemTools.cxx @@ -3640,11 +3640,11 @@ bool SystemTools::Split(const std::string& str, while (lpos < data.length()) { std::string::size_type rpos = data.find_first_of(separator, lpos); if (rpos == std::string::npos) { - // Line ends at end of string without a newline. + // String ends at end of string without a separator. lines.push_back(data.substr(lpos)); return false; } else { - // Line ends in a "\n", remove the character. + // String ends in a separator, remove the character. lines.push_back(data.substr(lpos, rpos - lpos)); } lpos = rpos + 1; @@ -3658,7 +3658,7 @@ bool SystemTools::Split(const std::string& str, std::string data(str); std::string::size_type lpos = 0; while (lpos < data.length()) { - std::string::size_type rpos = data.find_first_of("\n", lpos); + std::string::size_type rpos = data.find_first_of('\n', lpos); if (rpos == std::string::npos) { // Line ends at end of string without a newline. lines.push_back(data.substr(lpos)); diff --git a/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt b/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt index e11f980..85ce1f7 100644 --- a/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt +++ b/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt @@ -130,3 +130,15 @@ target_link_libraries(newsignature1 PRIVATE depC INTERFACE depD PUBLIC depB PRIV assert_property(newsignature1 INTERFACE_LINK_LIBRARIES "depD;depB") assert_property(newsignature1 LINK_LIBRARIES "depC;depB;subdirlib") + +#---------------------------------------------------------------------------- +# Test cross-directory linking. +cmake_policy(PUSH) +cmake_policy(SET CMP0079 NEW) +add_executable(TopDir TopDir.c) +add_subdirectory(SubDirA) +add_subdirectory(SubDirB) +target_link_libraries(SubDirB TopDirImported) +add_library(TopDirImported IMPORTED INTERFACE) +target_compile_definitions(TopDirImported INTERFACE DEF_TopDirImported) +cmake_policy(POP) diff --git a/Tests/CMakeCommands/target_link_libraries/SubDirA/CMakeLists.txt b/Tests/CMakeCommands/target_link_libraries/SubDirA/CMakeLists.txt new file mode 100644 index 0000000..4dae103 --- /dev/null +++ b/Tests/CMakeCommands/target_link_libraries/SubDirA/CMakeLists.txt @@ -0,0 +1,15 @@ +add_executable(SubDirA SubDirA.c) + +# Link to a target imported in this directory that would not normally +# be visible to the directory in which TopDir is defined. +target_link_libraries(TopDir PUBLIC SameNameImported) + +# Link SubDirA to a target imported in this directory that has the same +# name as a target imported in SubDirB's directory. SubDirB will also +# tell us to link its copy. At compile time we verify both are linked. +target_link_libraries(SubDirA PRIVATE SameNameImported) + +# Import a target with the same name as a target imported in SubDirB. +# Distinguish this copy by having a unique usage requirement. +add_library(SameNameImported IMPORTED INTERFACE) +target_compile_definitions(SameNameImported INTERFACE DEF_SameNameImportedSubDirA) diff --git a/Tests/CMakeCommands/target_link_libraries/SubDirA/SubDirA.c b/Tests/CMakeCommands/target_link_libraries/SubDirA/SubDirA.c new file mode 100644 index 0000000..4706bb9 --- /dev/null +++ b/Tests/CMakeCommands/target_link_libraries/SubDirA/SubDirA.c @@ -0,0 +1,14 @@ +#ifndef DEF_SameNameImportedSubDirA +# error "DEF_SameNameImportedSubDirA is not defined but should be!" +#endif +#ifndef DEF_SameNameImportedSubDirB +# error "DEF_SameNameImportedSubDirB is not defined but should be!" +#endif +#ifdef DEF_TopDirImported +# error "DEF_TopDirImported is defined but should not be!" +#endif + +int main(void) +{ + return 0; +} diff --git a/Tests/CMakeCommands/target_link_libraries/SubDirB/CMakeLists.txt b/Tests/CMakeCommands/target_link_libraries/SubDirB/CMakeLists.txt new file mode 100644 index 0000000..7c918e6 --- /dev/null +++ b/Tests/CMakeCommands/target_link_libraries/SubDirB/CMakeLists.txt @@ -0,0 +1,15 @@ +add_executable(SubDirB SubDirB.c) + +# Link to a target imported in this directory that would not normally +# be visible to the directory in which TopDir is defined. +target_link_libraries(TopDir PUBLIC SameNameImported) + +# Link SubDirA to a target imported in this directory that has the same +# name as a target imported in SubDirA's directory. We verify when +# compiling SubDirA that it sees our target and its own. +target_link_libraries(SubDirA PRIVATE SameNameImported) + +# Import a target with the same name as a target imported in SubDirA. +# Distinguish this copy by having a unique usage requirement. +add_library(SameNameImported IMPORTED INTERFACE) +target_compile_definitions(SameNameImported INTERFACE DEF_SameNameImportedSubDirB) diff --git a/Tests/CMakeCommands/target_link_libraries/SubDirB/SubDirB.c b/Tests/CMakeCommands/target_link_libraries/SubDirB/SubDirB.c new file mode 100644 index 0000000..6e56729 --- /dev/null +++ b/Tests/CMakeCommands/target_link_libraries/SubDirB/SubDirB.c @@ -0,0 +1,14 @@ +#ifdef DEF_SameNameImportedSubDirA +# error "DEF_SameNameImportedSubDirA is defined but should not be!" +#endif +#ifdef DEF_SameNameImportedSubDirB +# error "DEF_SameNameImportedSubDirB is defined but should not be!" +#endif +#ifndef DEF_TopDirImported +# error "DEF_TopDirImported is not defined but should be!" +#endif + +int main(void) +{ + return 0; +} diff --git a/Tests/CMakeCommands/target_link_libraries/TopDir.c b/Tests/CMakeCommands/target_link_libraries/TopDir.c new file mode 100644 index 0000000..4706bb9 --- /dev/null +++ b/Tests/CMakeCommands/target_link_libraries/TopDir.c @@ -0,0 +1,14 @@ +#ifndef DEF_SameNameImportedSubDirA +# error "DEF_SameNameImportedSubDirA is not defined but should be!" +#endif +#ifndef DEF_SameNameImportedSubDirB +# error "DEF_SameNameImportedSubDirB is not defined but should be!" +#endif +#ifdef DEF_TopDirImported +# error "DEF_TopDirImported is defined but should not be!" +#endif + +int main(void) +{ + return 0; +} diff --git a/Tests/CMakeCommands/target_link_options/CMakeLists.txt b/Tests/CMakeCommands/target_link_options/CMakeLists.txt index 3bb6ff3..e84d041 100644 --- a/Tests/CMakeCommands/target_link_options/CMakeLists.txt +++ b/Tests/CMakeCommands/target_link_options/CMakeLists.txt @@ -24,3 +24,11 @@ get_target_property(result target_link_options_3 INTERFACE_LINK_OPTIONS) if (NOT result MATCHES "-INTERFACE_FLAG") message(SEND_ERROR "target_link_options not populated the INTERFACE_LINK_OPTIONS target property of static library") endif() + +add_library(target_link_options_4 SHARED EXCLUDE_FROM_ALL LinkOptionsLib.c) +target_link_options(target_link_options_4 PRIVATE -PRIVATE_FLAG) +target_link_options(target_link_options_4 BEFORE PRIVATE -BEFORE_PRIVATE_FLAG) +get_target_property(result target_link_options_4 LINK_OPTIONS) +if (NOT result MATCHES "-BEFORE_PRIVATE_FLAG.*-PRIVATE_FLAG") + message(SEND_ERROR "target_link_options not managing correctly 'BEFORE' keyword") +endif() diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 971d7ff..28aab1c 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -368,6 +368,7 @@ if(BUILD_TESTING) ADD_TEST_MACRO(CxxSubdirC CxxSubdirC) ADD_TEST_MACRO(IPO COnly/COnly) ADD_TEST_MACRO(OutDir runtime/OutDir) + ADD_TEST_MACRO(OutName exe.OutName.exe) ADD_TEST_MACRO(ObjectLibrary UseCshared) ADD_TEST_MACRO(NewlineArgs NewlineArgs) ADD_TEST_MACRO(SetLang SetLang) @@ -396,6 +397,7 @@ if(BUILD_TESTING) ADD_TEST_MACRO(CompatibleInterface CompatibleInterface) ADD_TEST_MACRO(AliasTarget AliasTarget) ADD_TEST_MACRO(StagingPrefix StagingPrefix) + ADD_TEST_MACRO(ImportedSameName ImportedSameName) ADD_TEST_MACRO(InterfaceLibrary InterfaceLibrary) if (CMAKE_BUILD_TYPE MATCHES "[Dd][Ee][Bb][Uu][Gg]") set(ConfigSources_BUILD_OPTIONS -DCMAKE_BUILD_TYPE=Debug) diff --git a/Tests/ExportImport/Export/CMakeLists.txt b/Tests/ExportImport/Export/CMakeLists.txt index fdb2fa1..cb048be 100644 --- a/Tests/ExportImport/Export/CMakeLists.txt +++ b/Tests/ExportImport/Export/CMakeLists.txt @@ -155,6 +155,13 @@ add_library(testStaticLibRequiredPrivate testStaticLibRequiredPrivate.c) target_link_libraries(testLibDepends PRIVATE testStaticLibRequiredPrivate) cmake_policy(POP) +cmake_policy(PUSH) +cmake_policy(SET CMP0079 NEW) +add_library(TopDirLib STATIC testTopDirLib.c) +add_subdirectory(SubDirLinkA) +add_subdirectory(SubDirLinkB) +cmake_policy(POP) + macro(add_include_lib _libName) file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${_libName}.c" "/* no content */\n") add_library(${_libName} "${CMAKE_CURRENT_BINARY_DIR}/${_libName}.c") @@ -508,6 +515,7 @@ install( testLibCycleA testLibCycleB testLibNoSONAME cmp0022NEW cmp0022OLD + TopDirLib SubDirLinkA systemlib EXPORT exp RUNTIME DESTINATION $<1:bin>$<0:/wrong> @@ -566,6 +574,7 @@ export(TARGETS testExe1 testLib1 testLib2 testLib3 testSharedLibRequired testSharedLibRequiredUser testSharedLibRequiredUser2 testSharedLibDepends renamed_on_export cmp0022NEW cmp0022OLD + TopDirLib SubDirLinkA systemlib NAMESPACE bld_ FILE ExportBuildTree.cmake diff --git a/Tests/ExportImport/Export/SubDirLinkA/CMakeLists.txt b/Tests/ExportImport/Export/SubDirLinkA/CMakeLists.txt new file mode 100644 index 0000000..1c3c9dc --- /dev/null +++ b/Tests/ExportImport/Export/SubDirLinkA/CMakeLists.txt @@ -0,0 +1,6 @@ +add_library(SubDirLinkAImported IMPORTED INTERFACE) +target_compile_definitions(SubDirLinkAImported INTERFACE DEF_SubDirLinkAImportedForExport) + +target_link_libraries(TopDirLib PUBLIC SubDirLinkAImported) + +add_library(SubDirLinkA STATIC SubDirLinkA.c) diff --git a/Tests/ExportImport/Export/SubDirLinkA/SubDirLinkA.c b/Tests/ExportImport/Export/SubDirLinkA/SubDirLinkA.c new file mode 100644 index 0000000..abf76f5 --- /dev/null +++ b/Tests/ExportImport/Export/SubDirLinkA/SubDirLinkA.c @@ -0,0 +1,11 @@ +#ifdef DEF_SubDirLinkAImportedForExport +# error "DEF_SubDirLinkAImportedForExport is defined but should not be!" +#endif +#ifndef DEF_SubDirLinkBImportedForExport +# error "DEF_SubDirLinkBImportedForExport is not defined but should be!" +#endif + +int testSubDirLinkA(void) +{ + return 0; +} diff --git a/Tests/ExportImport/Export/SubDirLinkB/CMakeLists.txt b/Tests/ExportImport/Export/SubDirLinkB/CMakeLists.txt new file mode 100644 index 0000000..22e168f --- /dev/null +++ b/Tests/ExportImport/Export/SubDirLinkB/CMakeLists.txt @@ -0,0 +1,4 @@ +add_library(SubDirLinkBImported IMPORTED INTERFACE) +target_compile_definitions(SubDirLinkBImported INTERFACE DEF_SubDirLinkBImportedForExport) + +target_link_libraries(SubDirLinkA PUBLIC SubDirLinkBImported) diff --git a/Tests/ExportImport/Export/testTopDirLib.c b/Tests/ExportImport/Export/testTopDirLib.c new file mode 100644 index 0000000..1ec68de --- /dev/null +++ b/Tests/ExportImport/Export/testTopDirLib.c @@ -0,0 +1,11 @@ +#ifndef DEF_SubDirLinkAImportedForExport +# error "DEF_SubDirLinkAImportedForExport is not defined but should be!" +#endif +#ifdef DEF_SubDirLinkBImportedForExport +# error "DEF_SubDirLinkBImportedForExport is defined but should not be!" +#endif + +int testTopDirLib(void) +{ + return 0; +} diff --git a/Tests/ExportImport/Import/A/CMakeLists.txt b/Tests/ExportImport/Import/A/CMakeLists.txt index 7510d7e..8791a19 100644 --- a/Tests/ExportImport/Import/A/CMakeLists.txt +++ b/Tests/ExportImport/Import/A/CMakeLists.txt @@ -1,3 +1,9 @@ +# Prepare imported targets that the exported project itself imported. +add_library(SubDirLinkAImported IMPORTED INTERFACE) +target_compile_definitions(SubDirLinkAImported INTERFACE DEF_SubDirLinkAImportedForImport) +add_library(SubDirLinkBImported IMPORTED INTERFACE) +target_compile_definitions(SubDirLinkBImported INTERFACE DEF_SubDirLinkBImportedForImport) + # Import targets from the exported build tree. include(${Import_BINARY_DIR}/../Export/ExportBuildTree.cmake) @@ -158,6 +164,11 @@ target_link_libraries(cmp0022OLD_exp_test exp_cmp0022OLD) add_executable(cmp0022NEW_exp_test cmp0022NEW_test_vs6_2.cpp) target_link_libraries(cmp0022NEW_exp_test exp_cmp0022NEW) +add_executable(SubDirLink_bld SubDirLink.c) +target_link_libraries(SubDirLink_bld PRIVATE bld_TopDirLib bld_SubDirLinkA) +add_executable(SubDirLink_exp SubDirLink.c) +target_link_libraries(SubDirLink_exp PRIVATE exp_TopDirLib exp_SubDirLinkA) + # Try building a plugin to an executable imported from the build tree. add_library(imp_mod1b MODULE imp_mod1.c) target_link_libraries(imp_mod1b bld_testExe2) diff --git a/Tests/ExportImport/Import/A/SubDirLink.c b/Tests/ExportImport/Import/A/SubDirLink.c new file mode 100644 index 0000000..eb4b860 --- /dev/null +++ b/Tests/ExportImport/Import/A/SubDirLink.c @@ -0,0 +1,14 @@ +#ifndef DEF_SubDirLinkAImportedForImport +# error "DEF_SubDirLinkAImportedForImport is not defined but should be!" +#endif +#ifndef DEF_SubDirLinkBImportedForImport +# error "DEF_SubDirLinkBImportedForImport is not defined but should be!" +#endif + +extern int testTopDirLib(void); +extern int testSubDirLinkA(void); + +int main(void) +{ + return (testTopDirLib() + testSubDirLinkA() + 0); +} diff --git a/Tests/GoogleTest/Test/CMakeLists.txt b/Tests/GoogleTest/Test/CMakeLists.txt index f798d31..baf00d5 100644 --- a/Tests/GoogleTest/Test/CMakeLists.txt +++ b/Tests/GoogleTest/Test/CMakeLists.txt @@ -44,12 +44,13 @@ endif() set_tests_properties(set2.GoogleTest.ConditionalFail.foo PROPERTIES WILL_FAIL YES) -# Search specific sources to get the test list -add_executable(test_gtest2 main2.cxx) +# Search specific sources to get the test list. Include an empty file +# to ensure they are handled correctly too. +add_executable(test_gtest2 main2.cxx empty.cxx) target_link_libraries(test_gtest2 GTest::Main) gtest_add_tests(TARGET test_gtest2 TEST_LIST testList - SOURCES main2.h + SOURCES main2.h empty.cxx ) set(expectedTests GoogleTest.SomethingElse diff --git a/Tests/GoogleTest/Test/empty.cxx b/Tests/GoogleTest/Test/empty.cxx new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tests/GoogleTest/Test/empty.cxx diff --git a/Tests/ImportedSameName/A/CMakeLists.txt b/Tests/ImportedSameName/A/CMakeLists.txt new file mode 100644 index 0000000..0a31b40 --- /dev/null +++ b/Tests/ImportedSameName/A/CMakeLists.txt @@ -0,0 +1,8 @@ +add_library(a STATIC a.c) +target_compile_definitions(a INTERFACE DEF_A) + +add_library(sameName INTERFACE IMPORTED) +target_link_libraries(sameName INTERFACE a) + +add_library(ifaceA INTERFACE) +target_link_libraries(ifaceA INTERFACE sameName) diff --git a/Tests/ImportedSameName/A/a.c b/Tests/ImportedSameName/A/a.c new file mode 100644 index 0000000..4ef3698 --- /dev/null +++ b/Tests/ImportedSameName/A/a.c @@ -0,0 +1,3 @@ +void a(void) +{ +} diff --git a/Tests/ImportedSameName/B/CMakeLists.txt b/Tests/ImportedSameName/B/CMakeLists.txt new file mode 100644 index 0000000..d930326 --- /dev/null +++ b/Tests/ImportedSameName/B/CMakeLists.txt @@ -0,0 +1,8 @@ +add_library(b STATIC b.c) +target_compile_definitions(b INTERFACE DEF_B) + +add_library(sameName INTERFACE IMPORTED) +target_link_libraries(sameName INTERFACE b) + +add_library(ifaceB INTERFACE) +target_link_libraries(ifaceB INTERFACE sameName) diff --git a/Tests/ImportedSameName/B/b.c b/Tests/ImportedSameName/B/b.c new file mode 100644 index 0000000..c7c7df4 --- /dev/null +++ b/Tests/ImportedSameName/B/b.c @@ -0,0 +1,3 @@ +void b(void) +{ +} diff --git a/Tests/ImportedSameName/CMakeLists.txt b/Tests/ImportedSameName/CMakeLists.txt new file mode 100644 index 0000000..4292c12 --- /dev/null +++ b/Tests/ImportedSameName/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.12) +project(ImportedSameName C) + +add_subdirectory(A) +add_subdirectory(B) + +add_executable(ImportedSameName main.c) +target_link_libraries(ImportedSameName PRIVATE ifaceA ifaceB) diff --git a/Tests/ImportedSameName/main.c b/Tests/ImportedSameName/main.c new file mode 100644 index 0000000..a0cb27f --- /dev/null +++ b/Tests/ImportedSameName/main.c @@ -0,0 +1,16 @@ +#ifndef DEF_A +# error "DEF_A not defined" +#endif +#ifndef DEF_B +# error "DEF_B not defined" +#endif + +extern void a(void); +extern void b(void); + +int main(void) +{ + a(); + b(); + return 0; +} diff --git a/Tests/OutName/CMakeLists.txt b/Tests/OutName/CMakeLists.txt new file mode 100644 index 0000000..f024def --- /dev/null +++ b/Tests/OutName/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.12) +project(OutName C) + +add_executable(OutName main.c) +set_property(TARGET OutName PROPERTY PREFIX exe.) +set_property(TARGET OutName PROPERTY SUFFIX .exe) diff --git a/Tests/OutName/main.c b/Tests/OutName/main.c new file mode 100644 index 0000000..8488f4e --- /dev/null +++ b/Tests/OutName/main.c @@ -0,0 +1,4 @@ +int main(void) +{ + return 0; +} diff --git a/Tests/RunCMake/CMP0069/RunCMakeTest.cmake b/Tests/RunCMake/CMP0069/RunCMakeTest.cmake index f44f840..456e6a6 100644 --- a/Tests/RunCMake/CMP0069/RunCMakeTest.cmake +++ b/Tests/RunCMake/CMP0069/RunCMakeTest.cmake @@ -5,6 +5,6 @@ run_cmake(CMP0069-NEW-cmake) run_cmake(CMP0069-NEW-compiler) run_cmake(CMP0069-WARN) -if(RunCMake_GENERATOR MATCHES "^Visual Studio ") +if(RunCMake_GENERATOR MATCHES "^Visual Studio 9 ") run_cmake(CMP0069-NEW-generator) endif() diff --git a/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake index 3033c9c..9e8d050 100644 --- a/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake +++ b/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake @@ -111,8 +111,8 @@ endfunction() set(ENV{__CTEST_FAKE_LOAD_AVERAGE_FOR_TESTING} 5) # Verify that new tests are not started when the load average exceeds -# our threshold. -run_TestLoad(test-load-fail 2) +# our threshold and that they then run once the load average drops. +run_TestLoad(test-load-wait 3) # Verify that warning message is displayed but tests still start when # an invalid argument is given. diff --git a/Tests/RunCMake/CTestCommandLine/test-load-fail-stderr.txt b/Tests/RunCMake/CTestCommandLine/test-load-fail-stderr.txt deleted file mode 100644 index eafba1c..0000000 --- a/Tests/RunCMake/CTestCommandLine/test-load-fail-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -No tests were found!!! diff --git a/Tests/RunCMake/CTestCommandLine/test-load-fail-stdout.txt b/Tests/RunCMake/CTestCommandLine/test-load-fail-stdout.txt deleted file mode 100644 index 153da09..0000000 --- a/Tests/RunCMake/CTestCommandLine/test-load-fail-stdout.txt +++ /dev/null @@ -1,2 +0,0 @@ -^Test project .*/Tests/RunCMake/CTestCommandLine/TestLoad -\*\*\*\*\* WAITING, System Load: 5, Max Allowed Load: 2, Smallest test TestLoad[1-2] requires 1\*\*\*\*\* diff --git a/Tests/RunCMake/CTestCommandLine/test-load-pass-stderr.txt b/Tests/RunCMake/CTestCommandLine/test-load-pass-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/CTestCommandLine/test-load-pass-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/CTestCommandLine/test-load-wait-stdout.txt b/Tests/RunCMake/CTestCommandLine/test-load-wait-stdout.txt new file mode 100644 index 0000000..11a768a --- /dev/null +++ b/Tests/RunCMake/CTestCommandLine/test-load-wait-stdout.txt @@ -0,0 +1,8 @@ +^Test project .*/Tests/RunCMake/CTestCommandLine/TestLoad +\*\*\*\*\* WAITING, System Load: 5, Max Allowed Load: 3, Smallest test TestLoad[1-2] requires 1\*\*\*\*\* + Start 1: TestLoad1 + Start 2: TestLoad2 +1/2 Test #[1-2]: TestLoad[1-2] ........................ Passed +[0-9.]+ sec +2/2 Test #[1-2]: TestLoad[1-2] ........................ Passed +[0-9.]+ sec ++ +100% tests passed, 0 tests failed out of 2 diff --git a/Tests/RunCMake/CheckIPOSupported/RunCMakeTest.cmake b/Tests/RunCMake/CheckIPOSupported/RunCMakeTest.cmake index e145569..b7d524c 100644 --- a/Tests/RunCMake/CheckIPOSupported/RunCMakeTest.cmake +++ b/Tests/RunCMake/CheckIPOSupported/RunCMakeTest.cmake @@ -8,6 +8,6 @@ run_cmake(not-supported-by-compiler) run_cmake(save-to-result) run_cmake(cmp0069-is-old) -if(RunCMake_GENERATOR MATCHES "^Visual Studio ") +if(RunCMake_GENERATOR MATCHES "^Visual Studio 9 ") run_cmake(not-supported-by-generator) endif() diff --git a/Tests/RunCMake/target_link_libraries/SubDirTarget-result.txt b/Tests/RunCMake/CommandLine/B-no-arg-result.txt index d00491f..d00491f 100644 --- a/Tests/RunCMake/target_link_libraries/SubDirTarget-result.txt +++ b/Tests/RunCMake/CommandLine/B-no-arg-result.txt diff --git a/Tests/RunCMake/CommandLine/B-no-arg-stderr.txt b/Tests/RunCMake/CommandLine/B-no-arg-stderr.txt new file mode 100644 index 0000000..2309c5e --- /dev/null +++ b/Tests/RunCMake/CommandLine/B-no-arg-stderr.txt @@ -0,0 +1 @@ +CMake Error: No build directory specified for -B diff --git a/Tests/RunCMake/CommandLine/B-no-arg2-result.txt b/Tests/RunCMake/CommandLine/B-no-arg2-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CommandLine/B-no-arg2-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLine/B-no-arg2-stderr.txt b/Tests/RunCMake/CommandLine/B-no-arg2-stderr.txt new file mode 100644 index 0000000..2309c5e --- /dev/null +++ b/Tests/RunCMake/CommandLine/B-no-arg2-stderr.txt @@ -0,0 +1 @@ +CMake Error: No build directory specified for -B diff --git a/Tests/RunCMake/CommandLine/ExplicitDirs/CMakeLists.txt b/Tests/RunCMake/CommandLine/ExplicitDirs/CMakeLists.txt new file mode 100644 index 0000000..0ca5a0a --- /dev/null +++ b/Tests/RunCMake/CommandLine/ExplicitDirs/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.0.0 FATAL_ERROR) +add_custom_command( + OUTPUT output.txt + COMMAND ${CMAKE_COMMAND} -E echo CustomCommand > output.txt + ) +add_custom_target(CustomTarget ALL DEPENDS output.txt) +add_custom_target(CustomTarget2 ALL DEPENDS output.txt) +add_custom_target(CustomTarget3 ALL DEPENDS output.txt) diff --git a/Tests/RunCMake/CommandLine/NoArgs-stdout.txt b/Tests/RunCMake/CommandLine/NoArgs-stdout.txt index 1cd3469..f1dafc8 100644 --- a/Tests/RunCMake/CommandLine/NoArgs-stdout.txt +++ b/Tests/RunCMake/CommandLine/NoArgs-stdout.txt @@ -2,6 +2,7 @@ cmake \[options\] <path-to-source> cmake \[options\] <path-to-existing-build> + cmake \[options\] -S <path-to-source> -B <path-to-build> Specify a source directory to \(re-\)generate a build system for it in the current working directory. Specify an existing build directory to diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake index 5c80281..9859df1 100644 --- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake +++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake @@ -48,6 +48,31 @@ run_cmake_command(cache-bad-entry run_cmake_command(cache-empty-entry ${CMAKE_COMMAND} --build ${RunCMake_SOURCE_DIR}/cache-empty-entry/) +function(run_ExplicitDirs) + set(source_dir ${RunCMake_SOURCE_DIR}/ExplicitDirs) + set(binary_dir ${RunCMake_BINARY_DIR}/ExplicitDirs-build) + + file(REMOVE_RECURSE "${binary_dir}") + file(MAKE_DIRECTORY "${binary_dir}") + run_cmake_command(S-arg ${CMAKE_COMMAND} -S ${source_dir} ${binary_dir}) + run_cmake_command(S-arg-reverse-order ${CMAKE_COMMAND} ${binary_dir} -S${source_dir} ) + run_cmake_command(S-no-arg ${CMAKE_COMMAND} -S ) + run_cmake_command(S-no-arg2 ${CMAKE_COMMAND} -S -T) + run_cmake_command(S-B ${CMAKE_COMMAND} -S ${source_dir} -B ${binary_dir}) + + # make sure that -B can explicitly construct build directories + file(REMOVE_RECURSE "${binary_dir}") + run_cmake_command(B-arg ${CMAKE_COMMAND} -B ${binary_dir} ${source_dir}) + file(REMOVE_RECURSE "${binary_dir}") + run_cmake_command(B-arg-reverse-order ${CMAKE_COMMAND} ${source_dir} -B${binary_dir}) + run_cmake_command(B-no-arg ${CMAKE_COMMAND} -B ) + run_cmake_command(B-no-arg2 ${CMAKE_COMMAND} -B -T) + file(REMOVE_RECURSE "${binary_dir}") + run_cmake_command(B-S ${CMAKE_COMMAND} -B${binary_dir} -S${source_dir}) + +endfunction() +run_ExplicitDirs() + function(run_BuildDir) # Use a single build tree for a few tests without cleaning. set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/BuildDir-build) diff --git a/Tests/RunCMake/CommandLine/S-no-arg-result.txt b/Tests/RunCMake/CommandLine/S-no-arg-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CommandLine/S-no-arg-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLine/S-no-arg-stderr.txt b/Tests/RunCMake/CommandLine/S-no-arg-stderr.txt new file mode 100644 index 0000000..d1a2ce3 --- /dev/null +++ b/Tests/RunCMake/CommandLine/S-no-arg-stderr.txt @@ -0,0 +1 @@ +CMake Error: No source directory specified for -S diff --git a/Tests/RunCMake/CommandLine/S-no-arg2-result.txt b/Tests/RunCMake/CommandLine/S-no-arg2-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CommandLine/S-no-arg2-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLine/S-no-arg2-stderr.txt b/Tests/RunCMake/CommandLine/S-no-arg2-stderr.txt new file mode 100644 index 0000000..d1a2ce3 --- /dev/null +++ b/Tests/RunCMake/CommandLine/S-no-arg2-stderr.txt @@ -0,0 +1 @@ +CMake Error: No source directory specified for -S diff --git a/Tests/RunCMake/Ninja/RunCMakeTest.cmake b/Tests/RunCMake/Ninja/RunCMakeTest.cmake index e0ddc9c..4b366a8 100644 --- a/Tests/RunCMake/Ninja/RunCMakeTest.cmake +++ b/Tests/RunCMake/Ninja/RunCMakeTest.cmake @@ -205,15 +205,16 @@ function(run_sub_cmake test ninja_output_path_prefix) set(cmd_prefix "") set(cmd_suffix "") endif() + set(fs_delay 3) # We assume the system as 1 sec timestamp resolution. file(WRITE "${top_build_ninja}" "\ subninja ${escaped_ninja_output_path_prefix}/build.ninja default ${escaped_ninja_output_path_prefix}/all -# Sleep for 1 second before to regenerate to make sure the timestamp of +# Sleep for long enough before regenerating to make sure the timestamp of # the top build.ninja will be strictly greater than the timestamp of the -# sub/build.ninja file. We assume the system as 1 sec timestamp resolution. +# sub/build.ninja file. rule RERUN - command = ${cmd_prefix}\"${escaped_CMAKE_COMMAND}\" -E sleep 1 && \"${escaped_CMAKE_COMMAND}\" -E touch \"${escaped_top_build_ninja}\"${cmd_suffix} + command = ${cmd_prefix}\"${escaped_CMAKE_COMMAND}\" -E sleep ${fs_delay} && \"${escaped_CMAKE_COMMAND}\" -E touch \"${escaped_top_build_ninja}\"${cmd_suffix} description = Testing regeneration generator = 1 @@ -239,7 +240,7 @@ build build.ninja: RERUN ${escaped_build_ninja_dep} || ${escaped_ninja_output_pa # Test regeneration rules run in order. set(main_cmakelists "${RunCMake_SOURCE_DIR}/CMakeLists.txt") - sleep(1) # Assume the system as 1 sec timestamp resolution. + sleep(${fs_delay}) touch("${main_cmakelists}") touch("${build_ninja_dep}") run_ninja("${top_build_dir}") diff --git a/Tests/RunCMake/ctest_start/NoAppendDifferentTrack-stdout.txt b/Tests/RunCMake/ctest_start/NoAppendDifferentTrack-stdout.txt new file mode 100644 index 0000000..4a6f1e9 --- /dev/null +++ b/Tests/RunCMake/ctest_start/NoAppendDifferentTrack-stdout.txt @@ -0,0 +1,8 @@ +Run dashboard with model Experimental + Source directory: .*/Tests/RunCMake/ctest_start/NoAppendDifferentTrack + Build directory: .*/Tests/RunCMake/ctest_start/NoAppendDifferentTrack-build + Track: ExperimentalDifferent + Reading ctest configuration file: .*/Tests/RunCMake/ctest_start/NoAppendDifferentTrack/CTestConfig.cmake + Site: test-site + Build name: test-build-name + Use ExperimentalDifferent tag: [0-9-]+ diff --git a/Tests/RunCMake/ctest_start/RunCMakeTest.cmake b/Tests/RunCMake/ctest_start/RunCMakeTest.cmake index 2e8aa75..9b57b1b 100644 --- a/Tests/RunCMake/ctest_start/RunCMakeTest.cmake +++ b/Tests/RunCMake/ctest_start/RunCMakeTest.cmake @@ -30,6 +30,7 @@ run_ctest_start(AppendSameModel Continuous APPEND) run_ctest_start(AppendDifferentModel Experimental APPEND) run_ctest_start(AppendNoModel APPEND) run_ctest_start(AppendDifferentTrack TRACK ExperimentalDifferent APPEND) +run_ctest_start(NoAppendDifferentTrack Experimental TRACK ExperimentalDifferent) run_ctest_start(AppendNoMatchingTrack Continuous APPEND) run_ctest_start(AppendOldContinuous Continuous APPEND) run_ctest_start(AppendOldNoModel APPEND) diff --git a/Tests/RunCMake/ctest_start/test.cmake.in b/Tests/RunCMake/ctest_start/test.cmake.in index 172baf7..8cd3cff 100644 --- a/Tests/RunCMake/ctest_start/test.cmake.in +++ b/Tests/RunCMake/ctest_start/test.cmake.in @@ -14,7 +14,7 @@ function(setup_tests) ctest_start(${ctest_start_args}) endfunction() -if("@CASE_NAME@" MATCHES "^Append") +if("@CASE_NAME@" MATCHES "^(No)?Append") if("@CASE_NAME@" MATCHES "^AppendNoMatchingTrack$") file(WRITE "${CTEST_BINARY_DIRECTORY}/Testing/TAG" "19551112-2204\nSomeWeirdTrackName\n") else() diff --git a/Tests/RunCMake/ctest_test/TestLoadFail-result.txt b/Tests/RunCMake/ctest_submit/CDashSubmitVerbose-result.txt index b57e2de..b57e2de 100644 --- a/Tests/RunCMake/ctest_test/TestLoadFail-result.txt +++ b/Tests/RunCMake/ctest_submit/CDashSubmitVerbose-result.txt diff --git a/Tests/RunCMake/ctest_submit/CDashSubmitVerbose-stderr.txt b/Tests/RunCMake/ctest_submit/CDashSubmitVerbose-stderr.txt new file mode 100644 index 0000000..a8f10b5 --- /dev/null +++ b/Tests/RunCMake/ctest_submit/CDashSubmitVerbose-stderr.txt @@ -0,0 +1 @@ + *Error message was: ([Cc]ould *n.t resolve host:? '?-no-site-'?.*|The requested URL returned error:.*) diff --git a/Tests/RunCMake/ctest_submit/CDashSubmitVerbose-stdout.txt b/Tests/RunCMake/ctest_submit/CDashSubmitVerbose-stdout.txt new file mode 100644 index 0000000..11a4edf --- /dev/null +++ b/Tests/RunCMake/ctest_submit/CDashSubmitVerbose-stdout.txt @@ -0,0 +1 @@ +Upload file: .* to http:\/\/-no-site-\?FileName=test-site___test-build-name___.*-Experimental___XML___Configure.xml&build=test-build-name&site=test-site&stamp=.*-Experimental&subproject=mysubproj&MD5=.* Size: .* diff --git a/Tests/RunCMake/ctest_submit/RunCMakeTest.cmake b/Tests/RunCMake/ctest_submit/RunCMakeTest.cmake index ed0e666..7661383 100644 --- a/Tests/RunCMake/ctest_submit/RunCMakeTest.cmake +++ b/Tests/RunCMake/ctest_submit/RunCMakeTest.cmake @@ -30,6 +30,7 @@ run_ctest_submit(CDashUploadNone CDASH_UPLOAD) run_ctest_submit(CDashUploadMissingFile CDASH_UPLOAD bad-upload) run_ctest_submit(CDashUploadRetry CDASH_UPLOAD ${CMAKE_CURRENT_LIST_FILE} CDASH_UPLOAD_TYPE foo RETRY_COUNT 2 RETRY_DELAY 1 INTERNAL_TEST_CHECKSUM) run_ctest_submit(CDashSubmitQuiet QUIET) +run_ctest_submit_debug(CDashSubmitVerbose) run_ctest_submit_debug(CDashSubmitHeaders HTTPHEADER "Authorization: Bearer asdf") run_ctest_submit_debug(CDashUploadHeaders CDASH_UPLOAD ${CMAKE_CURRENT_LIST_FILE} CDASH_UPLOAD_TYPE foo HTTPHEADER "Authorization: Bearer asdf") diff --git a/Tests/RunCMake/ctest_submit/test.cmake.in b/Tests/RunCMake/ctest_submit/test.cmake.in index ba826f1..35cd16a 100644 --- a/Tests/RunCMake/ctest_submit/test.cmake.in +++ b/Tests/RunCMake/ctest_submit/test.cmake.in @@ -9,6 +9,7 @@ set(CTEST_CMAKE_GENERATOR_PLATFORM "@RunCMake_GENERATOR_PLATFORM@") set(CTEST_CMAKE_GENERATOR_TOOLSET "@RunCMake_GENERATOR_TOOLSET@") set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}") +set_property(GLOBAL PROPERTY SubProject "mysubproj") ctest_start(Experimental) ctest_configure() diff --git a/Tests/RunCMake/ctest_test/CTestTestLoadFail-result.txt b/Tests/RunCMake/ctest_test/CTestTestLoadFail-result.txt deleted file mode 100644 index b57e2de..0000000 --- a/Tests/RunCMake/ctest_test/CTestTestLoadFail-result.txt +++ /dev/null @@ -1 +0,0 @@ -(-1|255) diff --git a/Tests/RunCMake/ctest_test/CTestTestLoadFail-stderr.txt b/Tests/RunCMake/ctest_test/CTestTestLoadFail-stderr.txt deleted file mode 100644 index eafba1c..0000000 --- a/Tests/RunCMake/ctest_test/CTestTestLoadFail-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -No tests were found!!! diff --git a/Tests/RunCMake/ctest_test/CTestTestLoadFail-stdout.txt b/Tests/RunCMake/ctest_test/CTestTestLoadFail-stdout.txt deleted file mode 100644 index e203c10..0000000 --- a/Tests/RunCMake/ctest_test/CTestTestLoadFail-stdout.txt +++ /dev/null @@ -1,2 +0,0 @@ -Test project .*/Tests/RunCMake/ctest_test/CTestTestLoadFail-build -\*\*\*\*\* WAITING, System Load: 5, Max Allowed Load: 4, Smallest test RunCMakeVersion requires 1\*\*\*\*\*$ diff --git a/Tests/RunCMake/ctest_test/CTestTestLoadWait-stdout.txt b/Tests/RunCMake/ctest_test/CTestTestLoadWait-stdout.txt new file mode 100644 index 0000000..2af3838 --- /dev/null +++ b/Tests/RunCMake/ctest_test/CTestTestLoadWait-stdout.txt @@ -0,0 +1,8 @@ +Test project .*/Tests/RunCMake/ctest_test/CTestTestLoadWait-build +\*\*\*\*\* WAITING, System Load: 5, Max Allowed Load: 4, Smallest test RunCMakeVersion requires 1\*\*\*\*\* + Start 1: RunCMakeVersion +1/1 Test #1: RunCMakeVersion .................. Passed +[0-9.]+ sec ++ +100% tests passed, 0 tests failed out of 1 ++ +Total Test time \(real\) = +[0-9.]+ sec$ diff --git a/Tests/RunCMake/ctest_test/RunCMakeTest.cmake b/Tests/RunCMake/ctest_test/RunCMakeTest.cmake index 1b31726..6877e6a 100644 --- a/Tests/RunCMake/ctest_test/RunCMakeTest.cmake +++ b/Tests/RunCMake/ctest_test/RunCMakeTest.cmake @@ -21,8 +21,8 @@ set(ENV{__CTEST_FAKE_LOAD_AVERAGE_FOR_TESTING} 5) run_ctest_test(TestLoadPass TEST_LOAD 6) # Verify that new tests are not started when the load average exceeds -# our threshold. -run_ctest_test(TestLoadFail TEST_LOAD 2) +# our threshold and that they then run once the load average drops. +run_ctest_test(TestLoadWait TEST_LOAD 2) # Verify that when an invalid "TEST_LOAD" value is given, a warning # message is displayed and the value is ignored. @@ -34,9 +34,9 @@ set(CASE_CTEST_TEST_LOAD 7) run_ctest_test(CTestTestLoadPass) # Verify that new tests are not started when the load average exceeds -# our threshold. +# our threshold and that they then run once the load average drops. set(CASE_CTEST_TEST_LOAD 4) -run_ctest_test(CTestTestLoadFail) +run_ctest_test(CTestTestLoadWait) # Verify that when an invalid "CTEST_TEST_LOAD" value is given, # a warning message is displayed and the value is ignored. diff --git a/Tests/RunCMake/ctest_test/TestLoadFail-stderr.txt b/Tests/RunCMake/ctest_test/TestLoadFail-stderr.txt deleted file mode 100644 index eafba1c..0000000 --- a/Tests/RunCMake/ctest_test/TestLoadFail-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -No tests were found!!! diff --git a/Tests/RunCMake/ctest_test/TestLoadFail-stdout.txt b/Tests/RunCMake/ctest_test/TestLoadFail-stdout.txt deleted file mode 100644 index 4d7ce48..0000000 --- a/Tests/RunCMake/ctest_test/TestLoadFail-stdout.txt +++ /dev/null @@ -1,2 +0,0 @@ -Test project .*/Tests/RunCMake/ctest_test/TestLoadFail-build -\*\*\*\*\* WAITING, System Load: 5, Max Allowed Load: 2, Smallest test RunCMakeVersion requires 1\*\*\*\*\*$ diff --git a/Tests/RunCMake/ctest_test/TestLoadWait-stdout.txt b/Tests/RunCMake/ctest_test/TestLoadWait-stdout.txt new file mode 100644 index 0000000..07f4ed3 --- /dev/null +++ b/Tests/RunCMake/ctest_test/TestLoadWait-stdout.txt @@ -0,0 +1,8 @@ +Test project .*/Tests/RunCMake/ctest_test/TestLoadWait-build +\*\*\*\*\* WAITING, System Load: 5, Max Allowed Load: 2, Smallest test RunCMakeVersion requires 1\*\*\*\*\* + Start 1: RunCMakeVersion +1/1 Test #1: RunCMakeVersion .................. Passed +[0-9.]+ sec ++ +100% tests passed, 0 tests failed out of 1 ++ +Total Test time \(real\) = +[0-9.]+ sec$ diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-iface-NEW-stdout.txt b/Tests/RunCMake/target_link_libraries/CMP0079-iface-NEW-stdout.txt new file mode 100644 index 0000000..89cd806 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-iface-NEW-stdout.txt @@ -0,0 +1 @@ +-- INTERFACE_LINK_LIBRARIES='foo::@<[Xx0-9A-Fa-f]+>' diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-iface-NEW.cmake b/Tests/RunCMake/target_link_libraries/CMP0079-iface-NEW.cmake new file mode 100644 index 0000000..82486c4 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-iface-NEW.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0079 NEW) +include(CMP0079-iface-common.cmake) diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-iface-OLD-stdout.txt b/Tests/RunCMake/target_link_libraries/CMP0079-iface-OLD-stdout.txt new file mode 100644 index 0000000..e575e16 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-iface-OLD-stdout.txt @@ -0,0 +1 @@ +-- INTERFACE_LINK_LIBRARIES='foo' diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-iface-OLD.cmake b/Tests/RunCMake/target_link_libraries/CMP0079-iface-OLD.cmake new file mode 100644 index 0000000..e04a2bb --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-iface-OLD.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0079 OLD) +include(CMP0079-iface-common.cmake) diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-iface-WARN-stderr.txt b/Tests/RunCMake/target_link_libraries/CMP0079-iface-WARN-stderr.txt new file mode 100644 index 0000000..6dd7d30 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-iface-WARN-stderr.txt @@ -0,0 +1,17 @@ +^CMake Warning \(dev\) at CMP0079-iface/CMakeLists.txt:[0-9]+ \(target_link_libraries\): + Policy CMP0079 is not set: target_link_libraries allows use with targets in + other directories. Run "cmake --help-policy CMP0079" for policy details. + Use the cmake_policy command to set the policy and suppress this warning. + + Target + + top + + is not created in this directory. For compatibility with older versions of + CMake, link library + + foo + + will be looked up in the directory in which the target was created rather + than in this calling directory. +This warning is for project developers. Use -Wno-dev to suppress it.$ diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-iface-WARN-stdout.txt b/Tests/RunCMake/target_link_libraries/CMP0079-iface-WARN-stdout.txt new file mode 100644 index 0000000..e575e16 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-iface-WARN-stdout.txt @@ -0,0 +1 @@ +-- INTERFACE_LINK_LIBRARIES='foo' diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-iface-WARN.cmake b/Tests/RunCMake/target_link_libraries/CMP0079-iface-WARN.cmake new file mode 100644 index 0000000..2041893 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-iface-WARN.cmake @@ -0,0 +1 @@ +include(CMP0079-iface-common.cmake) diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-iface-common.cmake b/Tests/RunCMake/target_link_libraries/CMP0079-iface-common.cmake new file mode 100644 index 0000000..3982ff2 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-iface-common.cmake @@ -0,0 +1,6 @@ +enable_language(C) + +add_executable(top empty.c) +add_subdirectory(CMP0079-iface) +get_property(libs TARGET top PROPERTY INTERFACE_LINK_LIBRARIES) +message(STATUS "INTERFACE_LINK_LIBRARIES='${libs}'") diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-iface/CMakeLists.txt b/Tests/RunCMake/target_link_libraries/CMP0079-iface/CMakeLists.txt new file mode 100644 index 0000000..4b15b32 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-iface/CMakeLists.txt @@ -0,0 +1 @@ +target_link_libraries(top INTERFACE foo) diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW-bogus-result.txt b/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW-bogus-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW-bogus-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW-bogus-stderr.txt b/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW-bogus-stderr.txt new file mode 100644 index 0000000..b9fe3f6 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW-bogus-stderr.txt @@ -0,0 +1,6 @@ +^CMake Error at CMP0079-link-NEW-bogus.cmake:[0-9]+ \(add_executable\): + Target "top" links to target "foo::@<0xdeadbeef>" but the target was not + found. Perhaps a find_package\(\) call is missing for an IMPORTED target, or + an ALIAS target is missing\? +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW-bogus.cmake b/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW-bogus.cmake new file mode 100644 index 0000000..8622f14 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW-bogus.cmake @@ -0,0 +1,6 @@ +cmake_policy(SET CMP0028 NEW) +cmake_policy(SET CMP0079 NEW) +enable_language(C) + +add_executable(top empty.c) +set_property(TARGET top APPEND PROPERTY LINK_LIBRARIES "foo::@<0xdeadbeef>") diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW-stdout.txt b/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW-stdout.txt new file mode 100644 index 0000000..84b30bd --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW-stdout.txt @@ -0,0 +1 @@ +-- LINK_LIBRARIES='foo::@<[Xx0-9A-Fa-f]+>' diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW.cmake b/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW.cmake new file mode 100644 index 0000000..72e4574 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0079 NEW) +include(CMP0079-link-common.cmake) diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-link-OLD-result.txt b/Tests/RunCMake/target_link_libraries/CMP0079-link-OLD-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-link-OLD-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-link-OLD-stderr.txt b/Tests/RunCMake/target_link_libraries/CMP0079-link-OLD-stderr.txt new file mode 100644 index 0000000..0b4c4c6 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-link-OLD-stderr.txt @@ -0,0 +1,5 @@ +^CMake Error at CMP0079-link/CMakeLists.txt:[0-9]+ \(target_link_libraries\): + Attempt to add link library "foo" to target "top" which is not built in + this directory. + + This is allowed only when policy CMP0079 is set to NEW.$ diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-link-OLD.cmake b/Tests/RunCMake/target_link_libraries/CMP0079-link-OLD.cmake new file mode 100644 index 0000000..caa7231 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-link-OLD.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0079 OLD) +include(CMP0079-link-common.cmake) diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-link-WARN-result.txt b/Tests/RunCMake/target_link_libraries/CMP0079-link-WARN-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-link-WARN-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-link-WARN-stderr.txt b/Tests/RunCMake/target_link_libraries/CMP0079-link-WARN-stderr.txt new file mode 100644 index 0000000..0b4c4c6 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-link-WARN-stderr.txt @@ -0,0 +1,5 @@ +^CMake Error at CMP0079-link/CMakeLists.txt:[0-9]+ \(target_link_libraries\): + Attempt to add link library "foo" to target "top" which is not built in + this directory. + + This is allowed only when policy CMP0079 is set to NEW.$ diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-link-WARN.cmake b/Tests/RunCMake/target_link_libraries/CMP0079-link-WARN.cmake new file mode 100644 index 0000000..e83818a --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-link-WARN.cmake @@ -0,0 +1 @@ +include(CMP0079-link-common.cmake) diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-link-common.cmake b/Tests/RunCMake/target_link_libraries/CMP0079-link-common.cmake new file mode 100644 index 0000000..4f9454f --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-link-common.cmake @@ -0,0 +1,6 @@ +enable_language(C) + +add_executable(top empty.c) +add_subdirectory(CMP0079-link) +get_property(libs TARGET top PROPERTY LINK_LIBRARIES) +message(STATUS "LINK_LIBRARIES='${libs}'") diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-link/CMakeLists.txt b/Tests/RunCMake/target_link_libraries/CMP0079-link/CMakeLists.txt new file mode 100644 index 0000000..8b2b3c9 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-link/CMakeLists.txt @@ -0,0 +1 @@ +target_link_libraries(top PUBLIC foo) diff --git a/Tests/RunCMake/target_link_libraries/CMakeLists.txt b/Tests/RunCMake/target_link_libraries/CMakeLists.txt index 12cd3c7..8f85fbf 100644 --- a/Tests/RunCMake/target_link_libraries/CMakeLists.txt +++ b/Tests/RunCMake/target_link_libraries/CMakeLists.txt @@ -1,3 +1,3 @@ cmake_minimum_required(VERSION 2.8.4) project(${RunCMake_TEST} NONE) -include(${RunCMake_TEST}.cmake) +include(${RunCMake_TEST}.cmake NO_POLICY_SCOPE) diff --git a/Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake b/Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake index 97b0888..a041d6d 100644 --- a/Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake +++ b/Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake @@ -4,11 +4,17 @@ run_cmake(CMP0023-WARN) run_cmake(CMP0023-NEW) run_cmake(CMP0023-WARN-2) run_cmake(CMP0023-NEW-2) +run_cmake(CMP0079-iface-WARN) +run_cmake(CMP0079-iface-OLD) +run_cmake(CMP0079-iface-NEW) +run_cmake(CMP0079-link-WARN) +run_cmake(CMP0079-link-OLD) +run_cmake(CMP0079-link-NEW) +run_cmake(CMP0079-link-NEW-bogus) run_cmake(ImportedTarget) run_cmake(ImportedTargetFailure) run_cmake(MixedSignature) run_cmake(Separate-PRIVATE-LINK_PRIVATE-uses) -run_cmake(SubDirTarget) run_cmake(SharedDepNotTarget) run_cmake(StaticPrivateDepNotExported) run_cmake(StaticPrivateDepNotTarget) diff --git a/Tests/RunCMake/target_link_libraries/SubDirTarget-stderr.txt b/Tests/RunCMake/target_link_libraries/SubDirTarget-stderr.txt deleted file mode 100644 index 5cd1f23..0000000 --- a/Tests/RunCMake/target_link_libraries/SubDirTarget-stderr.txt +++ /dev/null @@ -1,5 +0,0 @@ -^CMake Error at SubDirTarget.cmake:[0-9]+ \(target_link_libraries\): - Attempt to add link library "m" to target "subexe" which is not built in - this directory. -Call Stack \(most recent call first\): - CMakeLists.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/target_link_libraries/SubDirTarget.cmake b/Tests/RunCMake/target_link_libraries/SubDirTarget.cmake deleted file mode 100644 index 32431ce..0000000 --- a/Tests/RunCMake/target_link_libraries/SubDirTarget.cmake +++ /dev/null @@ -1,3 +0,0 @@ -enable_language(C) -add_subdirectory(SubDirTarget) -target_link_libraries(subexe m) diff --git a/Tests/RunCMake/target_link_libraries/SubDirTarget/CMakeLists.txt b/Tests/RunCMake/target_link_libraries/SubDirTarget/CMakeLists.txt deleted file mode 100644 index b0b2380..0000000 --- a/Tests/RunCMake/target_link_libraries/SubDirTarget/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -add_executable(subexe ../empty.c) @@ -352,6 +352,7 @@ CMAKE_CXX_SOURCES="\ cmInstallTargetsCommand \ cmInstalledFile \ cmLinkDirectoriesCommand \ + cmLinkItem \ cmLinkLineComputer \ cmListCommand \ cmListFileCache \ |