summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Help/command/FIND_XXX.txt49
-rw-r--r--Help/command/find_package.rst42
-rw-r--r--Help/envvar/PackageName_ROOT.rst14
-rw-r--r--Help/guide/tutorial/A Basic Starting Point.rst9
-rw-r--r--Help/guide/tutorial/Adding Generator Expressions.rst2
-rw-r--r--Help/guide/tutorial/Adding System Introspection.rst5
-rw-r--r--Help/guide/tutorial/Adding Usage Requirements for a Library.rst4
-rw-r--r--Help/guide/tutorial/Adding a Custom Command and Generated File.rst36
-rw-r--r--Help/guide/tutorial/Adding a Library.rst219
-rw-r--r--Help/guide/tutorial/Complete/MathFunctions/MathFunctions.cxx1
-rw-r--r--Help/guide/tutorial/Selecting Static or Shared Libraries.rst45
-rw-r--r--Help/guide/tutorial/Step10/CMakeLists.txt13
-rw-r--r--Help/guide/tutorial/Step10/MathFunctions/CMakeLists.txt61
-rw-r--r--Help/guide/tutorial/Step10/MathFunctions/MathFunctions.cxx1
-rw-r--r--Help/guide/tutorial/Step10/MathFunctions/MathFunctions.h4
-rw-r--r--Help/guide/tutorial/Step10/MathFunctions/mysqrt.cxx4
-rw-r--r--Help/guide/tutorial/Step10/TutorialConfig.h.in1
-rw-r--r--Help/guide/tutorial/Step10/tutorial.cxx15
-rw-r--r--Help/guide/tutorial/Step11/MathFunctions/MathFunctions.cxx1
-rw-r--r--Help/guide/tutorial/Step12/MathFunctions/MathFunctions.cxx1
-rw-r--r--Help/guide/tutorial/Step2/CMakeLists.txt16
-rw-r--r--Help/guide/tutorial/Step2/MathFunctions/CMakeLists.txt5
-rw-r--r--Help/guide/tutorial/Step2/MathFunctions/MathFunctions.cxx15
-rw-r--r--Help/guide/tutorial/Step2/MathFunctions/MathFunctions.h6
-rw-r--r--Help/guide/tutorial/Step2/MathFunctions/mysqrt.cxx6
-rw-r--r--Help/guide/tutorial/Step2/MathFunctions/mysqrt.h7
-rw-r--r--Help/guide/tutorial/Step2/TutorialConfig.h.in2
-rw-r--r--Help/guide/tutorial/Step2/tutorial.cxx9
-rw-r--r--Help/guide/tutorial/Step3/CMakeLists.txt12
-rw-r--r--Help/guide/tutorial/Step3/MathFunctions/CMakeLists.txt8
-rw-r--r--Help/guide/tutorial/Step3/MathFunctions/MathFunctions.cxx19
-rw-r--r--Help/guide/tutorial/Step3/MathFunctions/MathFunctions.h6
-rw-r--r--Help/guide/tutorial/Step3/MathFunctions/mysqrt.cxx8
-rw-r--r--Help/guide/tutorial/Step3/MathFunctions/mysqrt.h7
-rw-r--r--Help/guide/tutorial/Step3/TutorialConfig.h.in1
-rw-r--r--Help/guide/tutorial/Step3/tutorial.cxx13
-rw-r--r--Help/guide/tutorial/Step4/CMakeLists.txt10
-rw-r--r--Help/guide/tutorial/Step4/MathFunctions/CMakeLists.txt12
-rw-r--r--Help/guide/tutorial/Step4/MathFunctions/MathFunctions.cxx19
-rw-r--r--Help/guide/tutorial/Step4/MathFunctions/MathFunctions.h6
-rw-r--r--Help/guide/tutorial/Step4/MathFunctions/mysqrt.cxx8
-rw-r--r--Help/guide/tutorial/Step4/MathFunctions/mysqrt.h7
-rw-r--r--Help/guide/tutorial/Step4/TutorialConfig.h.in1
-rw-r--r--Help/guide/tutorial/Step4/tutorial.cxx13
-rw-r--r--Help/guide/tutorial/Step5/CMakeLists.txt11
-rw-r--r--Help/guide/tutorial/Step5/MathFunctions/CMakeLists.txt14
-rw-r--r--Help/guide/tutorial/Step5/MathFunctions/MathFunctions.cxx19
-rw-r--r--Help/guide/tutorial/Step5/MathFunctions/MathFunctions.h6
-rw-r--r--Help/guide/tutorial/Step5/MathFunctions/mysqrt.cxx8
-rw-r--r--Help/guide/tutorial/Step5/MathFunctions/mysqrt.h7
-rw-r--r--Help/guide/tutorial/Step5/TutorialConfig.h.in1
-rw-r--r--Help/guide/tutorial/Step5/tutorial.cxx13
-rw-r--r--Help/guide/tutorial/Step6/CMakeLists.txt11
-rw-r--r--Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt14
-rw-r--r--Help/guide/tutorial/Step6/MathFunctions/MathFunctions.cxx19
-rw-r--r--Help/guide/tutorial/Step6/MathFunctions/MathFunctions.h6
-rw-r--r--Help/guide/tutorial/Step6/MathFunctions/mysqrt.cxx8
-rw-r--r--Help/guide/tutorial/Step6/MathFunctions/mysqrt.h7
-rw-r--r--Help/guide/tutorial/Step6/TutorialConfig.h.in1
-rw-r--r--Help/guide/tutorial/Step6/tutorial.cxx13
-rw-r--r--Help/guide/tutorial/Step7/CMakeLists.txt11
-rw-r--r--Help/guide/tutorial/Step7/MathFunctions/CMakeLists.txt46
-rw-r--r--Help/guide/tutorial/Step7/MathFunctions/MathFunctions.cxx19
-rw-r--r--Help/guide/tutorial/Step7/MathFunctions/MathFunctions.h6
-rw-r--r--Help/guide/tutorial/Step7/MathFunctions/mysqrt.cxx9
-rw-r--r--Help/guide/tutorial/Step7/MathFunctions/mysqrt.h7
-rw-r--r--Help/guide/tutorial/Step7/TutorialConfig.h.in1
-rw-r--r--Help/guide/tutorial/Step7/tutorial.cxx13
-rw-r--r--Help/guide/tutorial/Step8/CMakeLists.txt12
-rw-r--r--Help/guide/tutorial/Step8/MathFunctions/CMakeLists.txt61
-rw-r--r--Help/guide/tutorial/Step8/MathFunctions/MathFunctions.cxx19
-rw-r--r--Help/guide/tutorial/Step8/MathFunctions/MathFunctions.h6
-rw-r--r--Help/guide/tutorial/Step8/MathFunctions/mysqrt.cxx8
-rw-r--r--Help/guide/tutorial/Step8/MathFunctions/mysqrt.h7
-rw-r--r--Help/guide/tutorial/Step8/TutorialConfig.h.in1
-rw-r--r--Help/guide/tutorial/Step8/tutorial.cxx13
-rw-r--r--Help/guide/tutorial/Step9/CMakeLists.txt11
-rw-r--r--Help/guide/tutorial/Step9/MathFunctions/CMakeLists.txt61
-rw-r--r--Help/guide/tutorial/Step9/MathFunctions/MathFunctions.cxx19
-rw-r--r--Help/guide/tutorial/Step9/MathFunctions/MathFunctions.h6
-rw-r--r--Help/guide/tutorial/Step9/MathFunctions/mysqrt.cxx8
-rw-r--r--Help/guide/tutorial/Step9/MathFunctions/mysqrt.h7
-rw-r--r--Help/guide/tutorial/Step9/TutorialConfig.h.in1
-rw-r--r--Help/guide/tutorial/Step9/tutorial.cxx13
-rw-r--r--Help/manual/cmake-generator-expressions.7.rst43
-rw-r--r--Help/manual/cmake-policies.7.rst8
-rw-r--r--Help/policy/CMP0144.rst26
-rw-r--r--Help/release/dev/PATH-genex-support-list.rst5
-rw-r--r--Help/release/dev/find_package-PACKAGENAME_ROOT.rst7
-rw-r--r--Help/variable/PackageName_ROOT.rst8
-rw-r--r--Modules/FetchContent.cmake4
-rw-r--r--Modules/FindOpenSSL.cmake15
-rw-r--r--Modules/GenerateExportHeader.cmake2
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/cmFindPackageCommand.cxx126
-rw-r--r--Source/cmFindPackageCommand.h3
-rw-r--r--Source/cmGeneratorExpressionNode.cxx199
-rw-r--r--Source/cmMakefile.cxx47
-rw-r--r--Source/cmMakefile.h6
-rw-r--r--Source/cmPolicies.h5
-rw-r--r--Source/cmSystemTools.cxx26
-rw-r--r--Source/cmSystemTools.h3
-rw-r--r--Source/cmcmd.cxx42
-rw-r--r--Tests/MSManifest/Subdir/CMakeLists.txt5
-rw-r--r--Tests/MSManifest/Subdir2/CMakeLists.txt10
-rw-r--r--Tests/RunCMake/GenEx-PATH/ABSOLUTE_PATH.cmake.in24
-rw-r--r--Tests/RunCMake/GenEx-PATH/APPEND.cmake.in35
-rw-r--r--Tests/RunCMake/GenEx-PATH/CMAKE_PATH.cmake.in42
-rw-r--r--Tests/RunCMake/GenEx-PATH/CMakeLists.txt2
-rw-r--r--Tests/RunCMake/GenEx-PATH/GET_ITEM.cmake.in123
-rw-r--r--Tests/RunCMake/GenEx-PATH/NORMAL_PATH.cmake.in14
-rw-r--r--Tests/RunCMake/GenEx-PATH/RELATIVE_PATH.cmake.in14
-rw-r--r--Tests/RunCMake/GenEx-PATH/REMOVE_ITEM.cmake.in36
-rw-r--r--Tests/RunCMake/GenEx-PATH/REPLACE_ITEM.cmake.in36
-rw-r--r--Tests/RunCMake/GenerateExportHeader/GEH.cmake4
-rw-r--r--Tests/RunCMake/GenerateExportHeader/reference/Cygwin/libshared_export.h42
-rw-r--r--Tests/RunCMake/GenerateExportHeader/reference/Cygwin/libstatic_export.h42
-rw-r--r--Tests/RunCMake/GenerateExportHeader/reference/MinGW/libshared_export.h2
-rw-r--r--Tests/RunCMake/GenerateExportHeader/reference/MinGW/libstatic_export.h2
-rw-r--r--Tests/RunCMake/GenerateExportHeader/reference/Win32-Clang/libshared_export.h2
-rw-r--r--Tests/RunCMake/GenerateExportHeader/reference/Win32-Clang/libstatic_export.h2
-rw-r--r--Tests/RunCMake/find_package/CMP0144-NEW-CaseInsensitive-stderr.txt45
-rw-r--r--Tests/RunCMake/find_package/CMP0144-NEW-CaseInsensitive.cmake3
-rw-r--r--Tests/RunCMake/find_package/CMP0144-NEW-CaseSensitive-stderr.txt45
-rw-r--r--Tests/RunCMake/find_package/CMP0144-NEW-CaseSensitive.cmake3
-rw-r--r--Tests/RunCMake/find_package/CMP0144-OLD-CaseInsensitive-stderr.txt45
-rw-r--r--Tests/RunCMake/find_package/CMP0144-OLD-CaseInsensitive.cmake3
-rw-r--r--Tests/RunCMake/find_package/CMP0144-OLD-CaseSensitive-stderr.txt45
-rw-r--r--Tests/RunCMake/find_package/CMP0144-OLD-CaseSensitive.cmake3
-rw-r--r--Tests/RunCMake/find_package/CMP0144-WARN-CaseInsensitive-stderr.txt63
-rw-r--r--Tests/RunCMake/find_package/CMP0144-WARN-CaseInsensitive.cmake3
-rw-r--r--Tests/RunCMake/find_package/CMP0144-WARN-CaseSensitive-Mixed-stderr.txt45
-rw-r--r--Tests/RunCMake/find_package/CMP0144-WARN-CaseSensitive-Mixed.cmake3
-rw-r--r--Tests/RunCMake/find_package/CMP0144-WARN-CaseSensitive-stderr.txt68
-rw-r--r--Tests/RunCMake/find_package/CMP0144-WARN-CaseSensitive.cmake3
-rw-r--r--Tests/RunCMake/find_package/CMP0144-common.cmake78
-rw-r--r--Tests/RunCMake/find_package/RunCMakeTest.cmake11
137 files changed, 2040 insertions, 706 deletions
diff --git a/Help/command/FIND_XXX.txt b/Help/command/FIND_XXX.txt
index bd55e24..21236fa 100644
--- a/Help/command/FIND_XXX.txt
+++ b/Help/command/FIND_XXX.txt
@@ -140,21 +140,40 @@ If ``NO_DEFAULT_PATH`` is not specified, the search process is as follows:
|prefix_XXX_SUBDIR| for each ``<prefix>`` in
:variable:`CMAKE_SYSTEM_PREFIX_PATH`
-1. .. versionadded:: 3.12
- If called from within a find module or any other script loaded by a call to
- :command:`find_package(<PackageName>)`, search prefixes unique to the
- current package being found. Specifically, look in the
- :variable:`<PackageName>_ROOT` CMake variable and the
- :envvar:`<PackageName>_ROOT` environment variable.
- The package root variables are maintained as a stack, so if called from
- nested find modules or config packages, root paths from the parent's find
- module or config package will be searched after paths from the current
- module or package. In other words, the search order would be
- ``<CurrentPackage>_ROOT``, ``ENV{<CurrentPackage>_ROOT}``,
- ``<ParentPackage>_ROOT``, ``ENV{<ParentPackage>_ROOT}``, etc.
- This can be skipped if ``NO_PACKAGE_ROOT_PATH`` is passed or by setting
- the :variable:`CMAKE_FIND_USE_PACKAGE_ROOT_PATH` to ``FALSE``.
- See policy :policy:`CMP0074`.
+1. If called from within a find module or any other script loaded by a call to
+ :command:`find_package(<PackageName>)`, search prefixes unique to the
+ current package being found. See policy :policy:`CMP0074`.
+
+ .. versionadded:: 3.12
+
+ Specifically, search paths specified by the following variables, in order:
+
+ a. :variable:`<PackageName>_ROOT` CMake variable,
+ where ``<PackageName>`` is the case-preserved package name.
+
+ b. :variable:`<PACKAGENAME>_ROOT` CMake variable,
+ where ``<PACKAGENAME>`` is the upper-cased package name.
+ See policy :policy:`CMP0144`.
+
+ .. versionadded:: 3.27
+
+ c. :envvar:`<PackageName>_ROOT` environment variable,
+ where ``<PackageName>`` is the case-preserved package name.
+
+ d. :envvar:`<PACKAGENAME>_ROOT` environment variable,
+ where ``<PACKAGENAME>`` is the upper-cased package name.
+ See policy :policy:`CMP0144`.
+
+ .. versionadded:: 3.27
+
+ The package root variables are maintained as a stack, so if called from
+ nested find modules or config packages, root paths from the parent's find
+ module or config package will be searched after paths from the current
+ module or package. In other words, the search order would be
+ ``<CurrentPackage>_ROOT``, ``ENV{<CurrentPackage>_ROOT}``,
+ ``<ParentPackage>_ROOT``, ``ENV{<ParentPackage>_ROOT}``, etc.
+ This can be skipped if ``NO_PACKAGE_ROOT_PATH`` is passed or by setting
+ the :variable:`CMAKE_FIND_USE_PACKAGE_ROOT_PATH` to ``FALSE``.
* |FIND_PACKAGE_ROOT_PREFIX_PATH_XXX|
diff --git a/Help/command/find_package.rst b/Help/command/find_package.rst
index de4cb88..b82088e 100644
--- a/Help/command/find_package.rst
+++ b/Help/command/find_package.rst
@@ -367,17 +367,37 @@ The set of installation prefixes is constructed using the following
steps. If ``NO_DEFAULT_PATH`` is specified all ``NO_*`` options are
enabled.
-1. .. versionadded:: 3.12
- Search paths specified in the :variable:`<PackageName>_ROOT` CMake
- variable and the :envvar:`<PackageName>_ROOT` environment variable,
- where ``<PackageName>`` is the package to be found
- (the case-preserved first argument to ``find_package``).
- The package root variables are maintained as a stack so if
- called from within a find module, root paths from the parent's find
- module will also be searched after paths for the current package.
- This can be skipped if ``NO_PACKAGE_ROOT_PATH`` is passed or by setting
- the :variable:`CMAKE_FIND_USE_PACKAGE_ROOT_PATH` to ``FALSE``.
- See policy :policy:`CMP0074`.
+1. Search prefixes unique to the current ``<PackageName>`` being found.
+ See policy :policy:`CMP0074`.
+
+ .. versionadded:: 3.12
+
+ Specifically, search prefixes specified by the following variables,
+ in order:
+
+ a. :variable:`<PackageName>_ROOT` CMake variable,
+ where ``<PackageName>`` is the case-preserved package name.
+
+ b. :variable:`<PACKAGENAME>_ROOT` CMake variable,
+ where ``<PACKAGENAME>`` is the upper-cased package name.
+ See policy :policy:`CMP0144`.
+
+ .. versionadded:: 3.27
+
+ c. :envvar:`<PackageName>_ROOT` environment variable,
+ where ``<PackageName>`` is the case-preserved package name.
+
+ d. :envvar:`<PACKAGENAME>_ROOT` environment variable,
+ where ``<PACKAGENAME>`` is the upper-cased package name.
+ See policy :policy:`CMP0144`.
+
+ .. versionadded:: 3.27
+
+ The package root variables are maintained as a stack so if
+ called from within a find module, root paths from the parent's find
+ module will also be searched after paths for the current package.
+ This can be skipped if ``NO_PACKAGE_ROOT_PATH`` is passed or by setting
+ the :variable:`CMAKE_FIND_USE_PACKAGE_ROOT_PATH` to ``FALSE``.
2. Search paths specified in cmake-specific cache variables. These
are intended to be used on the command line with a :option:`-DVAR=VALUE <cmake -D>`.
diff --git a/Help/envvar/PackageName_ROOT.rst b/Help/envvar/PackageName_ROOT.rst
index fa8c385..6e9c744 100644
--- a/Help/envvar/PackageName_ROOT.rst
+++ b/Help/envvar/PackageName_ROOT.rst
@@ -17,3 +17,17 @@ by ``:`` on UNIX or ``;`` on Windows (the same as the ``PATH`` environment
variable convention on those platforms).
See also the :variable:`<PackageName>_ROOT` CMake variable.
+
+.. envvar:: <PACKAGENAME>_ROOT
+
+ .. versionadded:: 3.27
+
+ Calls to :command:`find_package(<PackageName>)` will also search in
+ prefixes specified by the upper-case ``<PACKAGENAME>_ROOT`` environment
+ variable. See policy :policy:`CMP0144`.
+
+.. note::
+
+ Note that the ``<PackageName>_ROOT`` and ``<PACKAGENAME>_ROOT``
+ environment variables are distinct only on platforms that have
+ case-sensitive environments.
diff --git a/Help/guide/tutorial/A Basic Starting Point.rst b/Help/guide/tutorial/A Basic Starting Point.rst
index 3dac68a..37b0668 100644
--- a/Help/guide/tutorial/A Basic Starting Point.rst
+++ b/Help/guide/tutorial/A Basic Starting Point.rst
@@ -160,7 +160,7 @@ The last command to call for a basic project is
:name: CMakeLists.txt-add_executable
:language: cmake
:start-after: # add the executable
- :end-before: # TODO 9:
+ :end-before: # TODO 3:
.. raw:: html
@@ -240,7 +240,7 @@ the following:
:name: tutorial.cxx-cxx11
:language: c++
:start-after: // convert input to double
- :end-before: // TODO 12:
+ :end-before: // TODO 6:
.. raw:: html
@@ -265,7 +265,7 @@ add the :variable:`CMAKE_CXX_STANDARD` declarations above the call to
:name: CMakeLists.txt-CXX_STANDARD
:language: cmake
:start-after: # specify the C++ standard
- :end-before: # TODO 7:
+ :end-before: # configure a header file
.. raw:: html
@@ -375,7 +375,7 @@ specified CMake variables replaced:
:name: CMakeLists.txt-configure_file
:language: cmake
:start-after: # to the source code
- :end-before: # TODO 8:
+ :end-before: # TODO 2:
.. raw:: html
@@ -420,7 +420,6 @@ be replaced with the corresponding version numbers from the project in
:caption: TODO 10: TutorialConfig.h.in
:name: TutorialConfig.h.in
:language: c++
- :end-before: // TODO 13:
.. raw:: html
diff --git a/Help/guide/tutorial/Adding Generator Expressions.rst b/Help/guide/tutorial/Adding Generator Expressions.rst
index 6f9714e..08f3eea 100644
--- a/Help/guide/tutorial/Adding Generator Expressions.rst
+++ b/Help/guide/tutorial/Adding Generator Expressions.rst
@@ -299,7 +299,7 @@ condition. The resulting full code looks like the following:
:name: CMakeLists.txt-target_compile_options-genex
:language: cmake
:start-after: set(msvc_cxx "$<COMPILE_LANG_AND_ID:CXX,MSVC>")
- :end-before: # should we use our own math functions
+ :end-before: # configure a header file to pass some of the CMake settings
.. raw:: html
diff --git a/Help/guide/tutorial/Adding System Introspection.rst b/Help/guide/tutorial/Adding System Introspection.rst
index b69abd2..b314773 100644
--- a/Help/guide/tutorial/Adding System Introspection.rst
+++ b/Help/guide/tutorial/Adding System Introspection.rst
@@ -119,7 +119,7 @@ our source code can tell what resources are available. If both ``log`` and
:name: MathFunctions/CMakeLists.txt-target_compile_definitions
:language: cmake
:start-after: # add compile definitions
- :end-before: # install libs
+ :end-before: # state
.. raw:: html
@@ -136,7 +136,8 @@ Since we may be using ``log`` and ``exp``, we need to modify
:caption: TODO 4: MathFunctions/mysqrt.cxx
:name: MathFunctions/mysqrt.cxx-include-cmath
:language: c++
- :end-before: #include <iostream>
+ :start-after: #include "mysqrt.h"
+ :end-before: include <iostream>
.. raw:: html
diff --git a/Help/guide/tutorial/Adding Usage Requirements for a Library.rst b/Help/guide/tutorial/Adding Usage Requirements for a Library.rst
index 4aef050..74b7496 100644
--- a/Help/guide/tutorial/Adding Usage Requirements for a Library.rst
+++ b/Help/guide/tutorial/Adding Usage Requirements for a Library.rst
@@ -100,7 +100,7 @@ follows:
:name: MathFunctions/CMakeLists.txt-target_include_directories-INTERFACE
:language: cmake
:start-after: # to find MathFunctions.h
- :end-before: # TODO 3: Link to
+ :end-before: option
.. raw:: html
@@ -119,7 +119,7 @@ safely remove our uses of the ``EXTRA_INCLUDES`` variable from the top-level
:name: CMakeLists.txt-remove-EXTRA_INCLUDES
:language: cmake
:start-after: # add the MathFunctions library
- :end-before: # add the executable
+ :end-before: # TODO 2: Link to tutorial_compiler_flags
.. raw:: html
diff --git a/Help/guide/tutorial/Adding a Custom Command and Generated File.rst b/Help/guide/tutorial/Adding a Custom Command and Generated File.rst
index b1f9840..9e6311e 100644
--- a/Help/guide/tutorial/Adding a Custom Command and Generated File.rst
+++ b/Help/guide/tutorial/Adding a Custom Command and Generated File.rst
@@ -23,15 +23,25 @@ The next step is to add the appropriate commands to the
then run it as part of the build process. A few commands are needed to
accomplish this.
-First, at the top of ``MathFunctions/CMakeLists.txt``, the executable for
-``MakeTable`` is added as any other executable would be added.
+First, in the ``USE_MYMATH`` section of ``MathFunctions/CMakeLists.txt``,
+we add an executable for ``MakeTable``.
.. literalinclude:: Step9/MathFunctions/CMakeLists.txt
:caption: MathFunctions/CMakeLists.txt
:name: MathFunctions/CMakeLists.txt-add_executable-MakeTable
:language: cmake
:start-after: # first we add the executable that generates the table
- :end-before: # add the command to generate the source code
+ :end-before: target_link_libraries
+
+After creating the executable, we add the ``tutorial_compiler_flags`` to our
+executable using :command:`target_link_libraries`.
+
+.. literalinclude:: Step9/MathFunctions/CMakeLists.txt
+ :caption: MathFunctions/CMakeLists.txt
+ :name: MathFunctions/CMakeLists.txt-link-tutorial-compiler-flags
+ :language: cmake
+ :start-after: add_executable
+ :end-before: # add the command to generate
Then we add a custom command that specifies how to produce ``Table.h``
by running MakeTable.
@@ -41,7 +51,7 @@ by running MakeTable.
:name: MathFunctions/CMakeLists.txt-add_custom_command-Table.h
:language: cmake
:start-after: # add the command to generate the source code
- :end-before: # add the main library
+ :end-before: # library that just does sqrt
Next we have to let CMake know that ``mysqrt.cxx`` depends on the generated
file ``Table.h``. This is done by adding the generated ``Table.h`` to the list
@@ -51,8 +61,8 @@ of sources for the library MathFunctions.
:caption: MathFunctions/CMakeLists.txt
:name: MathFunctions/CMakeLists.txt-add_library-Table.h
:language: cmake
- :start-after: # add the main library
- :end-before: # state that anybody linking
+ :start-after: # library that just does sqrt
+ :end-before: # state that we depend on
We also have to add the current binary directory to the list of include
directories so that ``Table.h`` can be found and included by ``mysqrt.cxx``.
@@ -62,7 +72,19 @@ directories so that ``Table.h`` can be found and included by ``mysqrt.cxx``.
:name: MathFunctions/CMakeLists.txt-target_include_directories-Table.h
:language: cmake
:start-after: # state that we depend on our bin
- :end-before: # install libs
+ :end-before: target_link_libraries
+
+As the last thing in our ``USE_MYMATH`` section, we need to link the our
+flags onto ``SqrtLibrary`` and then link ``SqrtLibrary`` onto
+``MathFunctions``. This makes the resulting ``USE_MYMATH`` section look like
+the following:
+
+.. literalinclude:: Step9/MathFunctions/CMakeLists.txt
+ :caption: MathFunctions/CMakeLists.txt
+ :name: MathFunctions/CMakeLists.txt-full_USE_MYMATH-section
+ :language: cmake
+ :start-after: if (USE_MYMATH)
+ :end-before: endif()
Now let's use the generated table. First, modify ``mysqrt.cxx`` to include
``Table.h``. Next, we can rewrite the ``mysqrt`` function to use the table:
diff --git a/Help/guide/tutorial/Adding a Library.rst b/Help/guide/tutorial/Adding a Library.rst
index a56c327..2dd731f 100644
--- a/Help/guide/tutorial/Adding a Library.rst
+++ b/Help/guide/tutorial/Adding a Library.rst
@@ -51,11 +51,13 @@ then use this library instead of the standard square root function provided by
the compiler.
For this tutorial we will put the library into a subdirectory called
-``MathFunctions``. This directory already contains a header file,
-``MathFunctions.h``, and a source file ``mysqrt.cxx``. We will not need to
-modify either of these files. The source file has one function called
+``MathFunctions``. This directory already contains the header files
+``MathFunctions.h`` and ``mysqrt.h``. Their respective source files
+``MathFunctions.cxx`` and ``mysqrt.cxx`` are also provided. We will not need
+to modify any of these files. ``mysqrt.cxx`` has one function called
``mysqrt`` that provides similar functionality to the compiler's ``sqrt``
-function.
+function. ``MathFunctions.cxx`` contains one function ``sqrt`` which serves
+to hide the implementation details of ``sqrt``.
From the ``Help/guide/tutorial/Step2`` directory, start with ``TODO 1`` and
complete through ``TODO 6``.
@@ -91,10 +93,10 @@ Solution
In the ``CMakeLists.txt`` file in the ``MathFunctions`` directory, we create
a library target called ``MathFunctions`` with :command:`add_library`. The
-source file for the library is passed as an argument to
+source files for the library are passed as an argument to
:command:`add_library`. This looks like the following line:
-.. raw:: html
+.. raw:: html/
<details><summary>TODO 1: Click to show/hide answer</summary>
@@ -171,36 +173,40 @@ Now let's use our library. In ``tutorial.cxx``, include ``MathFunctions.h``:
<details><summary>TODO 5: Click to show/hide answer</summary>
-.. code-block:: c++
- :caption: TODO 5 : tutorial.cxx
- :name: tutorial.cxx-include_MathFunctions.h
-
- #include "MathFunctions.h"
+.. literalinclude:: Step3/tutorial.cxx
+ :caption: TODO 5: tutorial.cxx
+ :name: CMakeLists.txt-include-MathFunctions.h
+ :language: cmake
+ :start-after: #include <string>
+ :end-before: #include "TutorialConfig.h"
.. raw:: html
</details>
-Lastly, replace ``sqrt`` with our library function ``mysqrt``.
+Lastly, replace ``sqrt`` with our library function ``mathfunctions::mysqrt``.
.. raw:: html
<details><summary>TODO 6: Click to show/hide answer</summary>
-.. code-block:: c++
- :caption: TODO 6 : tutorial.cxx
- :name: tutorial.cxx-call_mysqrt
-
- const double outputValue = mysqrt(inputValue);
+.. literalinclude:: Step3/tutorial.cxx
+ :caption: TODO 7: tutorial.cxx
+ :name: CMakeLists.txt-option
+ :language: cmake
+ :start-after: const double inputValue = std::stod(argv[1]);
+ :end-before: std::cout
.. raw:: html
</details>
-Exercise 2 - Making Our Library Optional
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Exercise 2 - Adding an Option
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-Now let us make the MathFunctions library optional. While for the tutorial
+Now let us add an option in the MathFunctions library to allow developers to
+select either the custom square root implementation or the built in standard
+implementation. While for the tutorial
there really isn't any need to do so, for larger projects this is a common
occurrence.
@@ -219,28 +225,26 @@ Helpful Resources
-----------------
* :command:`if`
-* :command:`list`
* :command:`option`
-* :command:`cmakedefine <configure_file>`
+* :command:`target_compile_definitions`
Files to Edit
-------------
-* ``CMakeLists.txt``
-* ``tutorial.cxx``
-* ``TutorialConfig.h.in``
+* ``MathFunctions/CMakeLists.txt``
+* ``MathFunctions/MathFunctions.cxx``
Getting Started
---------------
Start with the resulting files from Exercise 1. Complete ``TODO 7`` through
-``TODO 13``.
+``TODO 9``.
First create a variable ``USE_MYMATH`` using the :command:`option` command
-in the top-level ``CMakeLists.txt`` file. In that same file, use that option
-to determine whether to build and use the ``MathFunctions`` library.
+in ``MathFunctions/CMakeLists.txt``. In that same file, use that option
+to pass a compile definition to the ``MathFunctions`` library.
-Then, update ``tutorial.cxx`` and ``TutorialConfig.h.in`` to use
+Then, update ``MathFunctions.cxx`` to redirect compilation based on
``USE_MYMATH``.
Build and Run
@@ -279,7 +283,7 @@ or ``mysqrt``?
Solution
--------
-The first step is to add an option to the top-level ``CMakeLists.txt`` file.
+The first step is to add an option to ``MathFunctions/CMakeLists.txt``.
This option will be displayed in the :manual:`cmake-gui <cmake-gui(1)>` and
:manual:`ccmake <ccmake(1)>` with a default value of ``ON`` that can be
changed by the user.
@@ -288,172 +292,95 @@ changed by the user.
<details><summary>TODO 7: Click to show/hide answer</summary>
-.. literalinclude:: Step3/CMakeLists.txt
- :caption: TODO 7: CMakeLists.txt
- :name: CMakeLists.txt-option
+.. literalinclude:: Step3/MathFunctions/CMakeLists.txt
+ :caption: TODO 7: MathFunctions/CMakeLists.txt
+ :name: CMakeLists.txt-option-library-level
:language: cmake
:start-after: # should we use our own math functions
- :end-before: # configure a header file to pass some of the CMake settings
+ :end-before: if (USE_MYMATH)
.. raw:: html
</details>
-Next, make building and linking the ``MathFunctions`` library
-conditional.
-
-Start by creating a :command:`list` of the optional library targets for our
-project. At the moment, it is just ``MathFunctions``. Let's name our list
-``EXTRA_LIBS``.
+Next, make building and linking our library with ``mysqrt`` function
+conditional using this new option.
-Similarly, we need to make a :command:`list` for the optional includes which
-we will call ``EXTRA_INCLUDES``. In this list, we will ``APPEND`` the path of
-the header file needed for our library.
-
-Next, create an :command:`if` statement which checks the value of
+Create an :command:`if` statement which checks the value of
``USE_MYMATH``. Inside the :command:`if` block, put the
-:command:`add_subdirectory` command from Exercise 1 with the additional
-:command:`list` commands.
-
-When ``USE_MYMATH`` is ``ON``, the lists will be generated and will be added to
-our project. When ``USE_MYMATH`` is ``OFF``, the lists stay empty. With this
-strategy, we allow users to toggle ``USE_MYMATH`` to manipulate what library is
-used in the build.
-
-The top-level CMakeLists.txt file will now look like the following:
+:command:`target_compile_definitions` command with the compile
+definition ``USE_MYMATH``.
.. raw:: html
<details><summary>TODO 8: Click to show/hide answer</summary>
-.. literalinclude:: Step3/CMakeLists.txt
- :caption: TODO 8: CMakeLists.txt
+.. literalinclude:: Step3/MathFunctions/CMakeLists.txt
+ :caption: TODO 8: MathFunctions/CMakeLists.txt
:name: CMakeLists.txt-USE_MYMATH
:language: cmake
- :start-after: # add the MathFunctions library
- :end-before: # add the executable
+ :start-after: USE_MYMATH "Use tutorial provided math implementation" ON)
.. raw:: html
</details>
-Now that we have these two lists, we need to update
-:command:`target_link_libraries` and :command:`target_include_directories` to
-use them. Changing them is fairly straightforward.
-
-For :command:`target_link_libraries`, we replace the written out
-library names with ``EXTRA_LIBS``. This looks like the following:
+The corresponding changes to the source code are fairly straightforward.
+In ``MathFunctions.cxx``, we make ``USE_MYMATH`` control which square root
+function is used:
.. raw:: html
<details><summary>TODO 9: Click to show/hide answer</summary>
-.. literalinclude:: Step3/CMakeLists.txt
- :caption: TODO 9: CMakeLists.txt
- :name: CMakeLists.txt-target_link_libraries-EXTRA_LIBS
- :language: cmake
- :start-after: add_executable(Tutorial tutorial.cxx)
- :end-before: # TODO 3
+.. literalinclude:: Step3/MathFunctions/MathFunctions.cxx
+ :caption: TODO 9: MathFunctions/MathFunctions.cxx
+ :name: MathFunctions-USE_MYMATH-if
+ :language: c++
+ :start-after: which square root function should we use?
+ :end-before: }
.. raw:: html
</details>
-Then, we do the same thing with :command:`target_include_directories` and
-``EXTRA_INCLUDES``.
+Next, we need to include ``mysqrt.h`` if ``USE_MYMATH`` is defined.
.. raw:: html
<details><summary>TODO 10: Click to show/hide answer</summary>
-.. literalinclude:: Step3/CMakeLists.txt
- :caption: TODO 10 : CMakeLists.txt
- :name: CMakeLists.txt-target_link_libraries-EXTRA_INCLUDES
- :language: cmake
- :start-after: # so that we will find TutorialConfig.h
-
-.. raw:: html
-
- </details>
-
-Note that this is a classic approach when dealing with many components. We
-will cover the modern approach in the Step 3 of the tutorial.
-
-The corresponding changes to the source code are fairly straightforward.
-First, in ``tutorial.cxx``, we include the ``MathFunctions.h`` header if
-``USE_MYMATH`` is defined.
-
-.. raw:: html
-
- <details><summary>TODO 11: Click to show/hide answer</summary>
-
-.. literalinclude:: Step3/tutorial.cxx
- :caption: TODO 11 : tutorial.cxx
- :name: tutorial.cxx-ifdef-include
+.. literalinclude:: Step3/MathFunctions/MathFunctions.cxx
+ :caption: TODO 10: MathFunctions/MathFunctions.cxx
+ :name: MathFunctions-USE_MYMATH-if-include
:language: c++
- :start-after: // should we include the MathFunctions header
- :end-before: int main
+ :start-after: include <cmath>
+ :end-before: namespace mathfunctions
.. raw:: html
</details>
-Then, in the same file, we make ``USE_MYMATH`` control which square root
-function is used:
-
-.. raw:: html
-
- <details><summary>TODO 12: Click to show/hide answer</summary>
-
-.. literalinclude:: Step3/tutorial.cxx
- :caption: TODO 12 : tutorial.cxx
- :name: tutorial.cxx-ifdef-const
- :language: c++
- :start-after: // which square root function should we use?
- :end-before: std::cout << "The square root of
+Finally, we need to include ``cmath`` now that we are using ``std::sqrt``.
.. raw:: html
- </details>
-
-Since the source code now requires ``USE_MYMATH`` we can add it to
-``TutorialConfig.h.in`` with the following line:
-
-.. raw:: html
+ <details><summary>TODO 11: Click to show/hide answer</summary>
- <details><summary>TODO 13: Click to show/hide answer</summary>
+.. code-block:: c++
+ :caption: TODO 11 : MathFunctions/MathFunctions.cxx
+ :name: tutorial.cxx-include_cmath
-.. literalinclude:: Step3/TutorialConfig.h.in
- :caption: TODO 13 : TutorialConfig.h.in
- :name: TutorialConfig.h.in-cmakedefine
- :language: c++
- :lines: 4
+ #include <cmath>
.. raw:: html
</details>
-With these changes, our library is now completely optional to whoever is
-building and using it.
-
-Bonus Question
---------------
-
-Why is it important that we configure ``TutorialConfig.h.in``
-after the option for ``USE_MYMATH``? What would happen if we inverted the two?
-
-Answer
-------
+When ``USE_MYMATH`` is ``ON``, the compile definition ``USE_MYMATH`` will
+be set. We can then use this compile definition to enable or disable
+sections of our source code. With this strategy, we allow users to
+toggle ``USE_MYMATH`` to manipulate what library is used in the build.
-.. raw:: html
-
- <details><summary>Click to show/hide answer</summary>
-
-We configure after because ``TutorialConfig.h.in`` uses the value of
-``USE_MYMATH``. If we configure the file before
-calling :command:`option`, we won't be using the expected value of
-``USE_MYMATH``.
-
-.. raw:: html
-
- </details>
+With these changes, the ``mysqrt`` function is now completely optional to
+whoever is building and using the ``MathFunctions`` library.
diff --git a/Help/guide/tutorial/Complete/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Complete/MathFunctions/MathFunctions.cxx
index 0145300..c0991b9 100644
--- a/Help/guide/tutorial/Complete/MathFunctions/MathFunctions.cxx
+++ b/Help/guide/tutorial/Complete/MathFunctions/MathFunctions.cxx
@@ -10,6 +10,7 @@
namespace mathfunctions {
double sqrt(double x)
{
+// which square root function should we use?
#ifdef USE_MYMATH
return detail::mysqrt(x);
#else
diff --git a/Help/guide/tutorial/Selecting Static or Shared Libraries.rst b/Help/guide/tutorial/Selecting Static or Shared Libraries.rst
index 7befe1d..504e42f 100644
--- a/Help/guide/tutorial/Selecting Static or Shared Libraries.rst
+++ b/Help/guide/tutorial/Selecting Static or Shared Libraries.rst
@@ -10,49 +10,22 @@ To accomplish this we need to add :variable:`BUILD_SHARED_LIBS` to the
top-level ``CMakeLists.txt``. We use the :command:`option` command as it allows
users to optionally select if the value should be ``ON`` or ``OFF``.
-Next we are going to refactor ``MathFunctions`` to become a real library that
-encapsulates using ``mysqrt`` or ``sqrt``, instead of requiring the calling
-code to do this logic. This will also mean that ``USE_MYMATH`` will not control
-building ``MathFunctions``, but instead will control the behavior of this
-library.
-
-The first step is to update the starting section of the top-level
-``CMakeLists.txt`` to look like:
-
.. literalinclude:: Step11/CMakeLists.txt
:caption: CMakeLists.txt
:name: CMakeLists.txt-option-BUILD_SHARED_LIBS
:language: cmake
- :end-before: # add the binary tree
-
-Now that we have made ``MathFunctions`` always be used, we will need to update
-the logic of that library. So, in ``MathFunctions/CMakeLists.txt`` we need to
-create a SqrtLibrary that will conditionally be built and installed when
-``USE_MYMATH`` is enabled. Now, since this is a tutorial, we are going to
-explicitly require that SqrtLibrary is built statically.
+ :start-after: set(CMAKE_RUNTIME_OUTPUT_DIRECTORY
+ :end-before: # configure a header file to pass the version number only
-The end result is that ``MathFunctions/CMakeLists.txt`` should look like:
+Next, we need to specify output directories for our static and shared
+libraries.
-.. literalinclude:: Step11/MathFunctions/CMakeLists.txt
- :caption: MathFunctions/CMakeLists.txt
- :name: MathFunctions/CMakeLists.txt-add_library-STATIC
+.. literalinclude:: Step11/CMakeLists.txt
+ :caption: CMakeLists.txt
+ :name: CMakeLists.txt-cmake-output-directories
:language: cmake
- :lines: 1-36,42-
-
-Next, update ``MathFunctions/mysqrt.cxx`` to use the ``mathfunctions`` and
-``detail`` namespaces:
-
-.. literalinclude:: Step11/MathFunctions/mysqrt.cxx
- :caption: MathFunctions/mysqrt.cxx
- :name: MathFunctions/mysqrt.cxx-namespace
- :language: c++
-
-We also need to make some changes in ``tutorial.cxx``, so that it no longer
-uses ``USE_MYMATH``:
-
-#. Always include ``MathFunctions.h``
-#. Always use ``mathfunctions::sqrt``
-#. Don't include ``cmath``
+ :start-after: # we don't need to tinker with the path to run the executable
+ :end-before: # configure a header file to pass the version number only
Finally, update ``MathFunctions/MathFunctions.h`` to use dll export defines:
diff --git a/Help/guide/tutorial/Step10/CMakeLists.txt b/Help/guide/tutorial/Step10/CMakeLists.txt
index 5c661aa..2dd6db5 100644
--- a/Help/guide/tutorial/Step10/CMakeLists.txt
+++ b/Help/guide/tutorial/Step10/CMakeLists.txt
@@ -16,22 +16,15 @@ target_compile_options(tutorial_compiler_flags INTERFACE
"$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
)
-# should we use our own math functions
-option(USE_MYMATH "Use tutorial provided math implementation" ON)
-
-# configure a header file to pass some of the CMake settings
-# to the source code
+# configure a header file to pass the version number only
configure_file(TutorialConfig.h.in TutorialConfig.h)
# add the MathFunctions library
-if(USE_MYMATH)
- add_subdirectory(MathFunctions)
- list(APPEND EXTRA_LIBS MathFunctions)
-endif()
+add_subdirectory(MathFunctions)
# add the executable
add_executable(Tutorial tutorial.cxx)
-target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS} tutorial_compiler_flags)
+target_link_libraries(Tutorial PUBLIC MathFunctions tutorial_compiler_flags)
# add the binary tree to the search path for include files
# so that we will find TutorialConfig.h
diff --git a/Help/guide/tutorial/Step10/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step10/MathFunctions/CMakeLists.txt
index fa73321..6f6c430 100644
--- a/Help/guide/tutorial/Step10/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step10/MathFunctions/CMakeLists.txt
@@ -1,32 +1,51 @@
-# first we add the executable that generates the table
-add_executable(MakeTable MakeTable.cxx)
-
-# add the command to generate the source code
-add_custom_command(
- OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
- COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
- DEPENDS MakeTable
- )
-
-# add the main library
-add_library(MathFunctions
- mysqrt.cxx
- ${CMAKE_CURRENT_BINARY_DIR}/Table.h
- )
+# add the library that runs
+add_library(MathFunctions MathFunctions.cxx)
# state that anybody linking to us needs to include the current source dir
# to find MathFunctions.h, while we don't.
-# state that we depend on our binary dir to find Table.h
target_include_directories(MathFunctions
- INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
- PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
- )
+ INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
+ )
-# link our compiler flags interface library
-target_link_libraries(MathFunctions tutorial_compiler_flags)
+# should we use our own math functions
+option(USE_MYMATH "Use tutorial provided math implementation" ON)
+if(USE_MYMATH)
+
+ target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
+
+ # first we add the executable that generates the table
+ add_executable(MakeTable MakeTable.cxx)
+ target_link_libraries(MakeTable PRIVATE tutorial_compiler_flags)
+
+ # add the command to generate the source code
+ add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
+ COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
+ DEPENDS MakeTable
+ )
+
+ # library that just does sqrt
+ add_library(SqrtLibrary STATIC
+ mysqrt.cxx
+ ${CMAKE_CURRENT_BINARY_DIR}/Table.h
+ )
+
+ # state that we depend on our binary dir to find Table.h
+ target_include_directories(SqrtLibrary PRIVATE
+ ${CMAKE_CURRENT_BINARY_DIR}
+ )
+
+ target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)
+ target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
+endif()
+
+target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
# install libs
set(installable_libs MathFunctions tutorial_compiler_flags)
+if(TARGET SqrtLibrary)
+ list(APPEND installable_libs SqrtLibrary)
+endif()
install(TARGETS ${installable_libs} DESTINATION lib)
# install include headers
install(FILES MathFunctions.h DESTINATION include)
diff --git a/Help/guide/tutorial/Step10/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Step10/MathFunctions/MathFunctions.cxx
index 0145300..c0991b9 100644
--- a/Help/guide/tutorial/Step10/MathFunctions/MathFunctions.cxx
+++ b/Help/guide/tutorial/Step10/MathFunctions/MathFunctions.cxx
@@ -10,6 +10,7 @@
namespace mathfunctions {
double sqrt(double x)
{
+// which square root function should we use?
#ifdef USE_MYMATH
return detail::mysqrt(x);
#else
diff --git a/Help/guide/tutorial/Step10/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Step10/MathFunctions/MathFunctions.h
index cd36bcc..1e916e1 100644
--- a/Help/guide/tutorial/Step10/MathFunctions/MathFunctions.h
+++ b/Help/guide/tutorial/Step10/MathFunctions/MathFunctions.h
@@ -1 +1,3 @@
-double mysqrt(double x);
+namespace mathfunctions {
+double sqrt(double x);
+}
diff --git a/Help/guide/tutorial/Step10/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step10/MathFunctions/mysqrt.cxx
index 7d80ee9..8153f18 100644
--- a/Help/guide/tutorial/Step10/MathFunctions/mysqrt.cxx
+++ b/Help/guide/tutorial/Step10/MathFunctions/mysqrt.cxx
@@ -5,6 +5,8 @@
// include the generated table
#include "Table.h"
+namespace mathfunctions {
+namespace detail {
// a hack square root calculation using simple operations
double mysqrt(double x)
{
@@ -31,3 +33,5 @@ double mysqrt(double x)
return result;
}
+}
+}
diff --git a/Help/guide/tutorial/Step10/TutorialConfig.h.in b/Help/guide/tutorial/Step10/TutorialConfig.h.in
index e23f521..7e4d7fa 100644
--- a/Help/guide/tutorial/Step10/TutorialConfig.h.in
+++ b/Help/guide/tutorial/Step10/TutorialConfig.h.in
@@ -1,4 +1,3 @@
// the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
-#cmakedefine USE_MYMATH
diff --git a/Help/guide/tutorial/Step10/tutorial.cxx b/Help/guide/tutorial/Step10/tutorial.cxx
index b3c6a4f..37a0333 100644
--- a/Help/guide/tutorial/Step10/tutorial.cxx
+++ b/Help/guide/tutorial/Step10/tutorial.cxx
@@ -1,15 +1,11 @@
// A simple program that computes the square root of a number
-#include <cmath>
#include <iostream>
+#include <sstream>
#include <string>
+#include "MathFunctions.h"
#include "TutorialConfig.h"
-// should we include the MathFunctions header?
-#ifdef USE_MYMATH
-# include "MathFunctions.h"
-#endif
-
int main(int argc, char* argv[])
{
if (argc < 2) {
@@ -23,12 +19,7 @@ int main(int argc, char* argv[])
// convert input to double
const double inputValue = std::stod(argv[1]);
- // which square root function should we use?
-#ifdef USE_MYMATH
- const double outputValue = mysqrt(inputValue);
-#else
- const double outputValue = sqrt(inputValue);
-#endif
+ const double outputValue = mathfunctions::sqrt(inputValue);
std::cout << "The square root of " << inputValue << " is " << outputValue
<< std::endl;
diff --git a/Help/guide/tutorial/Step11/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Step11/MathFunctions/MathFunctions.cxx
index 0145300..c0991b9 100644
--- a/Help/guide/tutorial/Step11/MathFunctions/MathFunctions.cxx
+++ b/Help/guide/tutorial/Step11/MathFunctions/MathFunctions.cxx
@@ -10,6 +10,7 @@
namespace mathfunctions {
double sqrt(double x)
{
+// which square root function should we use?
#ifdef USE_MYMATH
return detail::mysqrt(x);
#else
diff --git a/Help/guide/tutorial/Step12/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Step12/MathFunctions/MathFunctions.cxx
index 0145300..c0991b9 100644
--- a/Help/guide/tutorial/Step12/MathFunctions/MathFunctions.cxx
+++ b/Help/guide/tutorial/Step12/MathFunctions/MathFunctions.cxx
@@ -10,6 +10,7 @@
namespace mathfunctions {
double sqrt(double x)
{
+// which square root function should we use?
#ifdef USE_MYMATH
return detail::mysqrt(x);
#else
diff --git a/Help/guide/tutorial/Step2/CMakeLists.txt b/Help/guide/tutorial/Step2/CMakeLists.txt
index 2b96128..0a06ed7 100644
--- a/Help/guide/tutorial/Step2/CMakeLists.txt
+++ b/Help/guide/tutorial/Step2/CMakeLists.txt
@@ -7,36 +7,20 @@ project(Tutorial VERSION 1.0)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
-# TODO 7: Create a variable USE_MYMATH using option and set default to ON
-
# configure a header file to pass some of the CMake settings
# to the source code
configure_file(TutorialConfig.h.in TutorialConfig.h)
-# TODO 8: Use list() and APPEND to create a list of optional libraries
-# called EXTRA_LIBS and a list of optional include directories called
-# EXTRA_INCLUDES. Add the MathFunctions library and source directory to
-# the appropriate lists.
-#
-# Only call add_subdirectory and only add MathFunctions specific values
-# to EXTRA_LIBS and EXTRA_INCLUDES if USE_MYMATH is true.
-
# TODO 2: Use add_subdirectory() to add MathFunctions to this project
# add the executable
add_executable(Tutorial tutorial.cxx)
-# TODO 9: Use EXTRA_LIBS instead of the MathFunctions specific values
-# in target_link_libraries.
-
# TODO 3: Use target_link_libraries to link the library to our executable
# TODO 4: Add MathFunctions to Tutorial's target_include_directories()
# Hint: ${PROJECT_SOURCE_DIR} is a path to the project source. AKA This folder!
-# TODO 10: Use EXTRA_INCLUDES instead of the MathFunctions specific values
-# in target_include_directories.
-
# add the binary tree to the search path for include files
# so that we will find TutorialConfig.h
target_include_directories(Tutorial PUBLIC
diff --git a/Help/guide/tutorial/Step2/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step2/MathFunctions/CMakeLists.txt
index b7779b7..c468b0e 100644
--- a/Help/guide/tutorial/Step2/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step2/MathFunctions/CMakeLists.txt
@@ -1,2 +1,7 @@
# TODO 1: Add a library called MathFunctions
# Hint: You will need the add_library command
+
+# TODO 7: Create a variable USE_MYMATH using option and set default to ON
+
+# TODO 8: If USE_MYMATH is ON, use target_compile_definitions to pass
+# USE_MYMATH as a precompiled definition to our source files
diff --git a/Help/guide/tutorial/Step2/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Step2/MathFunctions/MathFunctions.cxx
new file mode 100644
index 0000000..781d0ec
--- /dev/null
+++ b/Help/guide/tutorial/Step2/MathFunctions/MathFunctions.cxx
@@ -0,0 +1,15 @@
+#include "MathFunctions.h"
+
+// TODO 11: include cmath
+
+// TODO 10: Wrap the mysqrt include in a precompiled ifdef based on USE_MYMATH
+#include "mysqrt.h"
+
+namespace mathfunctions {
+double sqrt(double x)
+{
+ // TODO 9: If USE_MYMATH is defined, use detail::mysqrt.
+ // Otherwise, use std::sqrt.
+ return detail::mysqrt(x);
+}
+}
diff --git a/Help/guide/tutorial/Step2/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Step2/MathFunctions/MathFunctions.h
index cd36bcc..d5c2f22 100644
--- a/Help/guide/tutorial/Step2/MathFunctions/MathFunctions.h
+++ b/Help/guide/tutorial/Step2/MathFunctions/MathFunctions.h
@@ -1 +1,5 @@
-double mysqrt(double x);
+#pragma once
+
+namespace mathfunctions {
+double sqrt(double x);
+}
diff --git a/Help/guide/tutorial/Step2/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step2/MathFunctions/mysqrt.cxx
index 1e4d97a..ba0ac64 100644
--- a/Help/guide/tutorial/Step2/MathFunctions/mysqrt.cxx
+++ b/Help/guide/tutorial/Step2/MathFunctions/mysqrt.cxx
@@ -1,5 +1,9 @@
+#include "mysqrt.h"
+
#include <iostream>
+namespace mathfunctions {
+namespace detail {
// a hack square root calculation using simple operations
double mysqrt(double x)
{
@@ -20,3 +24,5 @@ double mysqrt(double x)
}
return result;
}
+}
+}
diff --git a/Help/guide/tutorial/Step2/MathFunctions/mysqrt.h b/Help/guide/tutorial/Step2/MathFunctions/mysqrt.h
new file mode 100644
index 0000000..593d41e
--- /dev/null
+++ b/Help/guide/tutorial/Step2/MathFunctions/mysqrt.h
@@ -0,0 +1,7 @@
+#pragma once
+
+namespace mathfunctions {
+namespace detail {
+double mysqrt(double x);
+}
+}
diff --git a/Help/guide/tutorial/Step2/TutorialConfig.h.in b/Help/guide/tutorial/Step2/TutorialConfig.h.in
index 6c09e1a..7e4d7fa 100644
--- a/Help/guide/tutorial/Step2/TutorialConfig.h.in
+++ b/Help/guide/tutorial/Step2/TutorialConfig.h.in
@@ -1,5 +1,3 @@
// the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
-
-// TODO 13: use cmakedefine to define USE_MYMATH
diff --git a/Help/guide/tutorial/Step2/tutorial.cxx b/Help/guide/tutorial/Step2/tutorial.cxx
index 87f5e0f..7a2a595 100644
--- a/Help/guide/tutorial/Step2/tutorial.cxx
+++ b/Help/guide/tutorial/Step2/tutorial.cxx
@@ -3,11 +3,8 @@
#include <iostream>
#include <string>
-#include "TutorialConfig.h"
-
-// TODO 11: Only include MathFunctions if USE_MYMATH is defined
-
// TODO 5: Include MathFunctions.h
+#include "TutorialConfig.h"
int main(int argc, char* argv[])
{
@@ -22,9 +19,7 @@ int main(int argc, char* argv[])
// convert input to double
const double inputValue = std::stod(argv[1]);
- // TODO 12: Use mysqrt if USE_MYMATH is defined and sqrt otherwise
-
- // TODO 6: Replace sqrt with mysqrt
+ // TODO 6: Replace sqrt with mathfunctions::sqrt
// calculate square root
const double outputValue = sqrt(inputValue);
diff --git a/Help/guide/tutorial/Step3/CMakeLists.txt b/Help/guide/tutorial/Step3/CMakeLists.txt
index 007770a..f051826 100644
--- a/Help/guide/tutorial/Step3/CMakeLists.txt
+++ b/Help/guide/tutorial/Step3/CMakeLists.txt
@@ -7,9 +7,6 @@ project(Tutorial VERSION 1.0)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
-# should we use our own math functions
-option(USE_MYMATH "Use tutorial provided math implementation" ON)
-
# configure a header file to pass some of the CMake settings
# to the source code
configure_file(TutorialConfig.h.in TutorialConfig.h)
@@ -17,16 +14,13 @@ configure_file(TutorialConfig.h.in TutorialConfig.h)
# TODO 2: Remove EXTRA_INCLUDES list
# add the MathFunctions library
-if(USE_MYMATH)
- add_subdirectory(MathFunctions)
- list(APPEND EXTRA_LIBS MathFunctions)
- list(APPEND EXTRA_INCLUDES "${PROJECT_SOURCE_DIR}/MathFunctions")
-endif()
+add_subdirectory(MathFunctions)
+list(APPEND EXTRA_INCLUDES "${PROJECT_SOURCE_DIR}/MathFunctions")
# add the executable
add_executable(Tutorial tutorial.cxx)
-target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS})
+target_link_libraries(Tutorial PUBLIC MathFunctions)
# TODO 3: Remove use of EXTRA_INCLUDES
diff --git a/Help/guide/tutorial/Step3/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step3/MathFunctions/CMakeLists.txt
index 7bf05e0..90d6c24 100644
--- a/Help/guide/tutorial/Step3/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step3/MathFunctions/CMakeLists.txt
@@ -1,5 +1,11 @@
-add_library(MathFunctions mysqrt.cxx)
+add_library(MathFunctions MathFunctions.cxx mysqrt.cxx)
# TODO 1: State that anybody linking to MathFunctions needs to include the
# current source directory, while MathFunctions itself doesn't.
# Hint: Use target_include_directories with the INTERFACE keyword
+
+# should we use our own math functions
+option(USE_MYMATH "Use tutorial provided math implementation" ON)
+if (USE_MYMATH)
+ target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
+endif()
diff --git a/Help/guide/tutorial/Step3/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Step3/MathFunctions/MathFunctions.cxx
new file mode 100644
index 0000000..dc28b4b
--- /dev/null
+++ b/Help/guide/tutorial/Step3/MathFunctions/MathFunctions.cxx
@@ -0,0 +1,19 @@
+#include "MathFunctions.h"
+
+#include <cmath>
+
+#ifdef USE_MYMATH
+# include "mysqrt.h"
+#endif
+
+namespace mathfunctions {
+double sqrt(double x)
+{
+// which square root function should we use?
+#ifdef USE_MYMATH
+ return detail::mysqrt(x);
+#else
+ return std::sqrt(x);
+#endif
+}
+}
diff --git a/Help/guide/tutorial/Step3/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Step3/MathFunctions/MathFunctions.h
index cd36bcc..d5c2f22 100644
--- a/Help/guide/tutorial/Step3/MathFunctions/MathFunctions.h
+++ b/Help/guide/tutorial/Step3/MathFunctions/MathFunctions.h
@@ -1 +1,5 @@
-double mysqrt(double x);
+#pragma once
+
+namespace mathfunctions {
+double sqrt(double x);
+}
diff --git a/Help/guide/tutorial/Step3/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step3/MathFunctions/mysqrt.cxx
index abe767d..ba0ac64 100644
--- a/Help/guide/tutorial/Step3/MathFunctions/mysqrt.cxx
+++ b/Help/guide/tutorial/Step3/MathFunctions/mysqrt.cxx
@@ -1,7 +1,9 @@
-#include <iostream>
+#include "mysqrt.h"
-#include "MathFunctions.h"
+#include <iostream>
+namespace mathfunctions {
+namespace detail {
// a hack square root calculation using simple operations
double mysqrt(double x)
{
@@ -22,3 +24,5 @@ double mysqrt(double x)
}
return result;
}
+}
+}
diff --git a/Help/guide/tutorial/Step3/MathFunctions/mysqrt.h b/Help/guide/tutorial/Step3/MathFunctions/mysqrt.h
new file mode 100644
index 0000000..593d41e
--- /dev/null
+++ b/Help/guide/tutorial/Step3/MathFunctions/mysqrt.h
@@ -0,0 +1,7 @@
+#pragma once
+
+namespace mathfunctions {
+namespace detail {
+double mysqrt(double x);
+}
+}
diff --git a/Help/guide/tutorial/Step3/TutorialConfig.h.in b/Help/guide/tutorial/Step3/TutorialConfig.h.in
index e23f521..7e4d7fa 100644
--- a/Help/guide/tutorial/Step3/TutorialConfig.h.in
+++ b/Help/guide/tutorial/Step3/TutorialConfig.h.in
@@ -1,4 +1,3 @@
// the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
-#cmakedefine USE_MYMATH
diff --git a/Help/guide/tutorial/Step3/tutorial.cxx b/Help/guide/tutorial/Step3/tutorial.cxx
index b3c6a4f..a3a2bdc 100644
--- a/Help/guide/tutorial/Step3/tutorial.cxx
+++ b/Help/guide/tutorial/Step3/tutorial.cxx
@@ -3,13 +3,9 @@
#include <iostream>
#include <string>
+#include "MathFunctions.h"
#include "TutorialConfig.h"
-// should we include the MathFunctions header?
-#ifdef USE_MYMATH
-# include "MathFunctions.h"
-#endif
-
int main(int argc, char* argv[])
{
if (argc < 2) {
@@ -23,12 +19,7 @@ int main(int argc, char* argv[])
// convert input to double
const double inputValue = std::stod(argv[1]);
- // which square root function should we use?
-#ifdef USE_MYMATH
- const double outputValue = mysqrt(inputValue);
-#else
- const double outputValue = sqrt(inputValue);
-#endif
+ const double outputValue = mathfunctions::sqrt(inputValue);
std::cout << "The square root of " << inputValue << " is " << outputValue
<< std::endl;
diff --git a/Help/guide/tutorial/Step4/CMakeLists.txt b/Help/guide/tutorial/Step4/CMakeLists.txt
index fa4aab2..dcda135 100644
--- a/Help/guide/tutorial/Step4/CMakeLists.txt
+++ b/Help/guide/tutorial/Step4/CMakeLists.txt
@@ -31,25 +31,19 @@ set(CMAKE_CXX_STANDARD_REQUIRED True)
# build-tree
# Hint: Use BUILD_INTERFACE
-# should we use our own math functions
-option(USE_MYMATH "Use tutorial provided math implementation" ON)
-
# configure a header file to pass some of the CMake settings
# to the source code
configure_file(TutorialConfig.h.in TutorialConfig.h)
# add the MathFunctions library
-if(USE_MYMATH)
- add_subdirectory(MathFunctions)
- list(APPEND EXTRA_LIBS MathFunctions)
-endif()
+add_subdirectory(MathFunctions)
# add the executable
add_executable(Tutorial tutorial.cxx)
# TODO 2: Link to tutorial_compiler_flags
-target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS})
+target_link_libraries(Tutorial PUBLIC MathFunctions)
# add the binary tree to the search path for include files
# so that we will find TutorialConfig.h
diff --git a/Help/guide/tutorial/Step4/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step4/MathFunctions/CMakeLists.txt
index 5f7369c..cc71d86 100644
--- a/Help/guide/tutorial/Step4/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step4/MathFunctions/CMakeLists.txt
@@ -1,9 +1,15 @@
-add_library(MathFunctions mysqrt.cxx)
+add_library(MathFunctions MathFunctions.cxx mysqrt.cxx)
# state that anybody linking to us needs to include the current source dir
# to find MathFunctions.h, while we don't.
target_include_directories(MathFunctions
- INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
- )
+ INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
+ )
+
+# should we use our own math functions
+option(USE_MYMATH "Use tutorial provided math implementation" ON)
+if (USE_MYMATH)
+ target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
+endif()
# TODO 3: Link to tutorial_compiler_flags
diff --git a/Help/guide/tutorial/Step4/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Step4/MathFunctions/MathFunctions.cxx
new file mode 100644
index 0000000..dc28b4b
--- /dev/null
+++ b/Help/guide/tutorial/Step4/MathFunctions/MathFunctions.cxx
@@ -0,0 +1,19 @@
+#include "MathFunctions.h"
+
+#include <cmath>
+
+#ifdef USE_MYMATH
+# include "mysqrt.h"
+#endif
+
+namespace mathfunctions {
+double sqrt(double x)
+{
+// which square root function should we use?
+#ifdef USE_MYMATH
+ return detail::mysqrt(x);
+#else
+ return std::sqrt(x);
+#endif
+}
+}
diff --git a/Help/guide/tutorial/Step4/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Step4/MathFunctions/MathFunctions.h
index cd36bcc..d5c2f22 100644
--- a/Help/guide/tutorial/Step4/MathFunctions/MathFunctions.h
+++ b/Help/guide/tutorial/Step4/MathFunctions/MathFunctions.h
@@ -1 +1,5 @@
-double mysqrt(double x);
+#pragma once
+
+namespace mathfunctions {
+double sqrt(double x);
+}
diff --git a/Help/guide/tutorial/Step4/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step4/MathFunctions/mysqrt.cxx
index abe767d..ba0ac64 100644
--- a/Help/guide/tutorial/Step4/MathFunctions/mysqrt.cxx
+++ b/Help/guide/tutorial/Step4/MathFunctions/mysqrt.cxx
@@ -1,7 +1,9 @@
-#include <iostream>
+#include "mysqrt.h"
-#include "MathFunctions.h"
+#include <iostream>
+namespace mathfunctions {
+namespace detail {
// a hack square root calculation using simple operations
double mysqrt(double x)
{
@@ -22,3 +24,5 @@ double mysqrt(double x)
}
return result;
}
+}
+}
diff --git a/Help/guide/tutorial/Step4/MathFunctions/mysqrt.h b/Help/guide/tutorial/Step4/MathFunctions/mysqrt.h
new file mode 100644
index 0000000..593d41e
--- /dev/null
+++ b/Help/guide/tutorial/Step4/MathFunctions/mysqrt.h
@@ -0,0 +1,7 @@
+#pragma once
+
+namespace mathfunctions {
+namespace detail {
+double mysqrt(double x);
+}
+}
diff --git a/Help/guide/tutorial/Step4/TutorialConfig.h.in b/Help/guide/tutorial/Step4/TutorialConfig.h.in
index e23f521..7e4d7fa 100644
--- a/Help/guide/tutorial/Step4/TutorialConfig.h.in
+++ b/Help/guide/tutorial/Step4/TutorialConfig.h.in
@@ -1,4 +1,3 @@
// the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
-#cmakedefine USE_MYMATH
diff --git a/Help/guide/tutorial/Step4/tutorial.cxx b/Help/guide/tutorial/Step4/tutorial.cxx
index b3c6a4f..a3a2bdc 100644
--- a/Help/guide/tutorial/Step4/tutorial.cxx
+++ b/Help/guide/tutorial/Step4/tutorial.cxx
@@ -3,13 +3,9 @@
#include <iostream>
#include <string>
+#include "MathFunctions.h"
#include "TutorialConfig.h"
-// should we include the MathFunctions header?
-#ifdef USE_MYMATH
-# include "MathFunctions.h"
-#endif
-
int main(int argc, char* argv[])
{
if (argc < 2) {
@@ -23,12 +19,7 @@ int main(int argc, char* argv[])
// convert input to double
const double inputValue = std::stod(argv[1]);
- // which square root function should we use?
-#ifdef USE_MYMATH
- const double outputValue = mysqrt(inputValue);
-#else
- const double outputValue = sqrt(inputValue);
-#endif
+ const double outputValue = mathfunctions::sqrt(inputValue);
std::cout << "The square root of " << inputValue << " is " << outputValue
<< std::endl;
diff --git a/Help/guide/tutorial/Step5/CMakeLists.txt b/Help/guide/tutorial/Step5/CMakeLists.txt
index 279ddf9..ad814f6 100644
--- a/Help/guide/tutorial/Step5/CMakeLists.txt
+++ b/Help/guide/tutorial/Step5/CMakeLists.txt
@@ -16,22 +16,17 @@ target_compile_options(tutorial_compiler_flags INTERFACE
"$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
)
-# should we use our own math functions
-option(USE_MYMATH "Use tutorial provided math implementation" ON)
-
# configure a header file to pass some of the CMake settings
# to the source code
configure_file(TutorialConfig.h.in TutorialConfig.h)
# add the MathFunctions library
-if(USE_MYMATH)
- add_subdirectory(MathFunctions)
- list(APPEND EXTRA_LIBS MathFunctions)
-endif()
+add_subdirectory(MathFunctions)
# add the executable
add_executable(Tutorial tutorial.cxx)
-target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS} tutorial_compiler_flags)
+
+target_link_libraries(Tutorial PUBLIC MathFunctions tutorial_compiler_flags)
# add the binary tree to the search path for include files
# so that we will find TutorialConfig.h
diff --git a/Help/guide/tutorial/Step5/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step5/MathFunctions/CMakeLists.txt
index 6cd88d7..000a786 100644
--- a/Help/guide/tutorial/Step5/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step5/MathFunctions/CMakeLists.txt
@@ -1,13 +1,19 @@
-add_library(MathFunctions mysqrt.cxx)
+add_library(MathFunctions MathFunctions.cxx mysqrt.cxx)
# state that anybody linking to us needs to include the current source dir
# to find MathFunctions.h, while we don't.
target_include_directories(MathFunctions
- INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
- )
+ INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
+ )
+
+# should we use our own math functions
+option(USE_MYMATH "Use tutorial provided math implementation" ON)
+if (USE_MYMATH)
+ target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
+endif()
# link our compiler flags interface library
-target_link_libraries(MathFunctions tutorial_compiler_flags)
+target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
# TODO 1: Create a variable called installable_libs that is a list of all
# libraries we want to install (e.g. MathFunctions and tutorial_compiler_flags)
diff --git a/Help/guide/tutorial/Step5/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Step5/MathFunctions/MathFunctions.cxx
new file mode 100644
index 0000000..dc28b4b
--- /dev/null
+++ b/Help/guide/tutorial/Step5/MathFunctions/MathFunctions.cxx
@@ -0,0 +1,19 @@
+#include "MathFunctions.h"
+
+#include <cmath>
+
+#ifdef USE_MYMATH
+# include "mysqrt.h"
+#endif
+
+namespace mathfunctions {
+double sqrt(double x)
+{
+// which square root function should we use?
+#ifdef USE_MYMATH
+ return detail::mysqrt(x);
+#else
+ return std::sqrt(x);
+#endif
+}
+}
diff --git a/Help/guide/tutorial/Step5/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Step5/MathFunctions/MathFunctions.h
index cd36bcc..d5c2f22 100644
--- a/Help/guide/tutorial/Step5/MathFunctions/MathFunctions.h
+++ b/Help/guide/tutorial/Step5/MathFunctions/MathFunctions.h
@@ -1 +1,5 @@
-double mysqrt(double x);
+#pragma once
+
+namespace mathfunctions {
+double sqrt(double x);
+}
diff --git a/Help/guide/tutorial/Step5/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step5/MathFunctions/mysqrt.cxx
index abe767d..ba0ac64 100644
--- a/Help/guide/tutorial/Step5/MathFunctions/mysqrt.cxx
+++ b/Help/guide/tutorial/Step5/MathFunctions/mysqrt.cxx
@@ -1,7 +1,9 @@
-#include <iostream>
+#include "mysqrt.h"
-#include "MathFunctions.h"
+#include <iostream>
+namespace mathfunctions {
+namespace detail {
// a hack square root calculation using simple operations
double mysqrt(double x)
{
@@ -22,3 +24,5 @@ double mysqrt(double x)
}
return result;
}
+}
+}
diff --git a/Help/guide/tutorial/Step5/MathFunctions/mysqrt.h b/Help/guide/tutorial/Step5/MathFunctions/mysqrt.h
new file mode 100644
index 0000000..593d41e
--- /dev/null
+++ b/Help/guide/tutorial/Step5/MathFunctions/mysqrt.h
@@ -0,0 +1,7 @@
+#pragma once
+
+namespace mathfunctions {
+namespace detail {
+double mysqrt(double x);
+}
+}
diff --git a/Help/guide/tutorial/Step5/TutorialConfig.h.in b/Help/guide/tutorial/Step5/TutorialConfig.h.in
index e23f521..7e4d7fa 100644
--- a/Help/guide/tutorial/Step5/TutorialConfig.h.in
+++ b/Help/guide/tutorial/Step5/TutorialConfig.h.in
@@ -1,4 +1,3 @@
// the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
-#cmakedefine USE_MYMATH
diff --git a/Help/guide/tutorial/Step5/tutorial.cxx b/Help/guide/tutorial/Step5/tutorial.cxx
index b3c6a4f..a3a2bdc 100644
--- a/Help/guide/tutorial/Step5/tutorial.cxx
+++ b/Help/guide/tutorial/Step5/tutorial.cxx
@@ -3,13 +3,9 @@
#include <iostream>
#include <string>
+#include "MathFunctions.h"
#include "TutorialConfig.h"
-// should we include the MathFunctions header?
-#ifdef USE_MYMATH
-# include "MathFunctions.h"
-#endif
-
int main(int argc, char* argv[])
{
if (argc < 2) {
@@ -23,12 +19,7 @@ int main(int argc, char* argv[])
// convert input to double
const double inputValue = std::stod(argv[1]);
- // which square root function should we use?
-#ifdef USE_MYMATH
- const double outputValue = mysqrt(inputValue);
-#else
- const double outputValue = sqrt(inputValue);
-#endif
+ const double outputValue = mathfunctions::sqrt(inputValue);
std::cout << "The square root of " << inputValue << " is " << outputValue
<< std::endl;
diff --git a/Help/guide/tutorial/Step6/CMakeLists.txt b/Help/guide/tutorial/Step6/CMakeLists.txt
index c11e307..a86d60a 100644
--- a/Help/guide/tutorial/Step6/CMakeLists.txt
+++ b/Help/guide/tutorial/Step6/CMakeLists.txt
@@ -16,22 +16,17 @@ target_compile_options(tutorial_compiler_flags INTERFACE
"$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
)
-# should we use our own math functions
-option(USE_MYMATH "Use tutorial provided math implementation" ON)
-
# configure a header file to pass some of the CMake settings
# to the source code
configure_file(TutorialConfig.h.in TutorialConfig.h)
# add the MathFunctions library
-if(USE_MYMATH)
- add_subdirectory(MathFunctions)
- list(APPEND EXTRA_LIBS MathFunctions)
-endif()
+add_subdirectory(MathFunctions)
# add the executable
add_executable(Tutorial tutorial.cxx)
-target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS} tutorial_compiler_flags)
+
+target_link_libraries(Tutorial PUBLIC MathFunctions tutorial_compiler_flags)
# add the binary tree to the search path for include files
# so that we will find TutorialConfig.h
diff --git a/Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt
index b4724c4..623cb74 100644
--- a/Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt
@@ -1,13 +1,19 @@
-add_library(MathFunctions mysqrt.cxx)
+add_library(MathFunctions MathFunctions.cxx mysqrt.cxx)
# state that anybody linking to us needs to include the current source dir
# to find MathFunctions.h, while we don't.
target_include_directories(MathFunctions
- INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
- )
+ INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
+ )
+
+# should we use our own math functions
+option(USE_MYMATH "Use tutorial provided math implementation" ON)
+if (USE_MYMATH)
+ target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
+endif()
# link our compiler flags interface library
-target_link_libraries(MathFunctions tutorial_compiler_flags)
+target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
# install libs
set(installable_libs MathFunctions tutorial_compiler_flags)
diff --git a/Help/guide/tutorial/Step6/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Step6/MathFunctions/MathFunctions.cxx
new file mode 100644
index 0000000..dc28b4b
--- /dev/null
+++ b/Help/guide/tutorial/Step6/MathFunctions/MathFunctions.cxx
@@ -0,0 +1,19 @@
+#include "MathFunctions.h"
+
+#include <cmath>
+
+#ifdef USE_MYMATH
+# include "mysqrt.h"
+#endif
+
+namespace mathfunctions {
+double sqrt(double x)
+{
+// which square root function should we use?
+#ifdef USE_MYMATH
+ return detail::mysqrt(x);
+#else
+ return std::sqrt(x);
+#endif
+}
+}
diff --git a/Help/guide/tutorial/Step6/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Step6/MathFunctions/MathFunctions.h
index cd36bcc..d5c2f22 100644
--- a/Help/guide/tutorial/Step6/MathFunctions/MathFunctions.h
+++ b/Help/guide/tutorial/Step6/MathFunctions/MathFunctions.h
@@ -1 +1,5 @@
-double mysqrt(double x);
+#pragma once
+
+namespace mathfunctions {
+double sqrt(double x);
+}
diff --git a/Help/guide/tutorial/Step6/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step6/MathFunctions/mysqrt.cxx
index abe767d..ba0ac64 100644
--- a/Help/guide/tutorial/Step6/MathFunctions/mysqrt.cxx
+++ b/Help/guide/tutorial/Step6/MathFunctions/mysqrt.cxx
@@ -1,7 +1,9 @@
-#include <iostream>
+#include "mysqrt.h"
-#include "MathFunctions.h"
+#include <iostream>
+namespace mathfunctions {
+namespace detail {
// a hack square root calculation using simple operations
double mysqrt(double x)
{
@@ -22,3 +24,5 @@ double mysqrt(double x)
}
return result;
}
+}
+}
diff --git a/Help/guide/tutorial/Step6/MathFunctions/mysqrt.h b/Help/guide/tutorial/Step6/MathFunctions/mysqrt.h
new file mode 100644
index 0000000..593d41e
--- /dev/null
+++ b/Help/guide/tutorial/Step6/MathFunctions/mysqrt.h
@@ -0,0 +1,7 @@
+#pragma once
+
+namespace mathfunctions {
+namespace detail {
+double mysqrt(double x);
+}
+}
diff --git a/Help/guide/tutorial/Step6/TutorialConfig.h.in b/Help/guide/tutorial/Step6/TutorialConfig.h.in
index e23f521..7e4d7fa 100644
--- a/Help/guide/tutorial/Step6/TutorialConfig.h.in
+++ b/Help/guide/tutorial/Step6/TutorialConfig.h.in
@@ -1,4 +1,3 @@
// the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
-#cmakedefine USE_MYMATH
diff --git a/Help/guide/tutorial/Step6/tutorial.cxx b/Help/guide/tutorial/Step6/tutorial.cxx
index b3c6a4f..a3a2bdc 100644
--- a/Help/guide/tutorial/Step6/tutorial.cxx
+++ b/Help/guide/tutorial/Step6/tutorial.cxx
@@ -3,13 +3,9 @@
#include <iostream>
#include <string>
+#include "MathFunctions.h"
#include "TutorialConfig.h"
-// should we include the MathFunctions header?
-#ifdef USE_MYMATH
-# include "MathFunctions.h"
-#endif
-
int main(int argc, char* argv[])
{
if (argc < 2) {
@@ -23,12 +19,7 @@ int main(int argc, char* argv[])
// convert input to double
const double inputValue = std::stod(argv[1]);
- // which square root function should we use?
-#ifdef USE_MYMATH
- const double outputValue = mysqrt(inputValue);
-#else
- const double outputValue = sqrt(inputValue);
-#endif
+ const double outputValue = mathfunctions::sqrt(inputValue);
std::cout << "The square root of " << inputValue << " is " << outputValue
<< std::endl;
diff --git a/Help/guide/tutorial/Step7/CMakeLists.txt b/Help/guide/tutorial/Step7/CMakeLists.txt
index d26a90c..97ec6aa 100644
--- a/Help/guide/tutorial/Step7/CMakeLists.txt
+++ b/Help/guide/tutorial/Step7/CMakeLists.txt
@@ -16,22 +16,17 @@ target_compile_options(tutorial_compiler_flags INTERFACE
"$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
)
-# should we use our own math functions
-option(USE_MYMATH "Use tutorial provided math implementation" ON)
-
# configure a header file to pass some of the CMake settings
# to the source code
configure_file(TutorialConfig.h.in TutorialConfig.h)
# add the MathFunctions library
-if(USE_MYMATH)
- add_subdirectory(MathFunctions)
- list(APPEND EXTRA_LIBS MathFunctions)
-endif()
+add_subdirectory(MathFunctions)
# add the executable
add_executable(Tutorial tutorial.cxx)
-target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS} tutorial_compiler_flags)
+
+target_link_libraries(Tutorial PUBLIC MathFunctions tutorial_compiler_flags)
# add the binary tree to the search path for include files
# so that we will find TutorialConfig.h
diff --git a/Help/guide/tutorial/Step7/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step7/MathFunctions/CMakeLists.txt
index e5bdc4d..c0d1e72 100644
--- a/Help/guide/tutorial/Step7/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step7/MathFunctions/CMakeLists.txt
@@ -1,33 +1,39 @@
-add_library(MathFunctions mysqrt.cxx)
+add_library(MathFunctions MathFunctions.cxx mysqrt.cxx)
# state that anybody linking to us needs to include the current source dir
# to find MathFunctions.h, while we don't.
target_include_directories(MathFunctions
- INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
- )
+ INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
+ )
-# link our compiler flags interface library
-target_link_libraries(MathFunctions tutorial_compiler_flags)
+# should we use our own math functions
+option(USE_MYMATH "Use tutorial provided math implementation" ON)
+if (USE_MYMATH)
+ target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
+
+ # TODO 1: Include CheckCXXSourceCompiles
-# TODO 1: Include CheckCXXSourceCompiles
+ # TODO 2: Use check_cxx_source_compiles with simple C++ code to verify
+ # availability of:
+ # * std::log
+ # * std::exp
+ # Store the results in HAVE_LOG and HAVE_EXP respectively.
-# TODO 2: Use check_cxx_source_compiles with simple C++ code to verify
-# availability of:
-# * std::log
-# * std::exp
-# Store the results in HAVE_LOG and HAVE_EXP respectively.
+ # Hint: Sample C++ code which uses log:
+ # #include <cmath>
+ # int main() {
+ # std::log(1.0);
+ # return 0;
+ # }
-# Hint: Sample C++ code which uses log:
-# #include <cmath>
-# int main() {
-# std::log(1.0);
-# return 0;
-# }
+ # TODO 3: Conditionally on HAVE_LOG and HAVE_EXP, add private compile
+ # definitions "HAVE_LOG" and "HAVE_EXP" to the MathFunctions target.
-# TODO 3: Conditionally on HAVE_LOG and HAVE_EXP, add private compile
-# definitions "HAVE_LOG" and "HAVE_EXP" to the MathFunctions target.
+ # Hint: Use target_compile_definitions()
+endif()
-#Hint: Use target_compile_definitions()
+# link our compiler flags interface library
+target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
# install libs
set(installable_libs MathFunctions tutorial_compiler_flags)
diff --git a/Help/guide/tutorial/Step7/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Step7/MathFunctions/MathFunctions.cxx
new file mode 100644
index 0000000..dc28b4b
--- /dev/null
+++ b/Help/guide/tutorial/Step7/MathFunctions/MathFunctions.cxx
@@ -0,0 +1,19 @@
+#include "MathFunctions.h"
+
+#include <cmath>
+
+#ifdef USE_MYMATH
+# include "mysqrt.h"
+#endif
+
+namespace mathfunctions {
+double sqrt(double x)
+{
+// which square root function should we use?
+#ifdef USE_MYMATH
+ return detail::mysqrt(x);
+#else
+ return std::sqrt(x);
+#endif
+}
+}
diff --git a/Help/guide/tutorial/Step7/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Step7/MathFunctions/MathFunctions.h
index cd36bcc..d5c2f22 100644
--- a/Help/guide/tutorial/Step7/MathFunctions/MathFunctions.h
+++ b/Help/guide/tutorial/Step7/MathFunctions/MathFunctions.h
@@ -1 +1,5 @@
-double mysqrt(double x);
+#pragma once
+
+namespace mathfunctions {
+double sqrt(double x);
+}
diff --git a/Help/guide/tutorial/Step7/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step7/MathFunctions/mysqrt.cxx
index 3d2492a..9963cff 100644
--- a/Help/guide/tutorial/Step7/MathFunctions/mysqrt.cxx
+++ b/Help/guide/tutorial/Step7/MathFunctions/mysqrt.cxx
@@ -1,8 +1,9 @@
-#include <iostream>
+#include "mysqrt.h"
-// TODO 4: include cmath
-#include "MathFunctions.h"
+#include <iostream>
+namespace mathfunctions {
+namespace detail {
// a hack square root calculation using simple operations
double mysqrt(double x)
{
@@ -32,3 +33,5 @@ double mysqrt(double x)
return result;
}
+}
+}
diff --git a/Help/guide/tutorial/Step7/MathFunctions/mysqrt.h b/Help/guide/tutorial/Step7/MathFunctions/mysqrt.h
new file mode 100644
index 0000000..593d41e
--- /dev/null
+++ b/Help/guide/tutorial/Step7/MathFunctions/mysqrt.h
@@ -0,0 +1,7 @@
+#pragma once
+
+namespace mathfunctions {
+namespace detail {
+double mysqrt(double x);
+}
+}
diff --git a/Help/guide/tutorial/Step7/TutorialConfig.h.in b/Help/guide/tutorial/Step7/TutorialConfig.h.in
index e23f521..7e4d7fa 100644
--- a/Help/guide/tutorial/Step7/TutorialConfig.h.in
+++ b/Help/guide/tutorial/Step7/TutorialConfig.h.in
@@ -1,4 +1,3 @@
// the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
-#cmakedefine USE_MYMATH
diff --git a/Help/guide/tutorial/Step7/tutorial.cxx b/Help/guide/tutorial/Step7/tutorial.cxx
index b3c6a4f..a3a2bdc 100644
--- a/Help/guide/tutorial/Step7/tutorial.cxx
+++ b/Help/guide/tutorial/Step7/tutorial.cxx
@@ -3,13 +3,9 @@
#include <iostream>
#include <string>
+#include "MathFunctions.h"
#include "TutorialConfig.h"
-// should we include the MathFunctions header?
-#ifdef USE_MYMATH
-# include "MathFunctions.h"
-#endif
-
int main(int argc, char* argv[])
{
if (argc < 2) {
@@ -23,12 +19,7 @@ int main(int argc, char* argv[])
// convert input to double
const double inputValue = std::stod(argv[1]);
- // which square root function should we use?
-#ifdef USE_MYMATH
- const double outputValue = mysqrt(inputValue);
-#else
- const double outputValue = sqrt(inputValue);
-#endif
+ const double outputValue = mathfunctions::sqrt(inputValue);
std::cout << "The square root of " << inputValue << " is " << outputValue
<< std::endl;
diff --git a/Help/guide/tutorial/Step8/CMakeLists.txt b/Help/guide/tutorial/Step8/CMakeLists.txt
index cb87281..97ec6aa 100644
--- a/Help/guide/tutorial/Step8/CMakeLists.txt
+++ b/Help/guide/tutorial/Step8/CMakeLists.txt
@@ -16,23 +16,17 @@ target_compile_options(tutorial_compiler_flags INTERFACE
"$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
)
-
-# should we use our own math functions
-option(USE_MYMATH "Use tutorial provided math implementation" ON)
-
# configure a header file to pass some of the CMake settings
# to the source code
configure_file(TutorialConfig.h.in TutorialConfig.h)
# add the MathFunctions library
-if(USE_MYMATH)
- add_subdirectory(MathFunctions)
- list(APPEND EXTRA_LIBS MathFunctions)
-endif()
+add_subdirectory(MathFunctions)
# add the executable
add_executable(Tutorial tutorial.cxx)
-target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS} tutorial_compiler_flags)
+
+target_link_libraries(Tutorial PUBLIC MathFunctions tutorial_compiler_flags)
# add the binary tree to the search path for include files
# so that we will find TutorialConfig.h
diff --git a/Help/guide/tutorial/Step8/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step8/MathFunctions/CMakeLists.txt
index f81b563..861014d 100644
--- a/Help/guide/tutorial/Step8/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step8/MathFunctions/CMakeLists.txt
@@ -1,36 +1,43 @@
-add_library(MathFunctions mysqrt.cxx)
+add_library(MathFunctions MathFunctions.cxx mysqrt.cxx)
+
+# should we use our own math functions
+option(USE_MYMATH "Use tutorial provided math implementation" ON)
+if (USE_MYMATH)
+ target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
+
+ # does this system provide the log and exp functions?
+ include(CheckCXXSourceCompiles)
+ check_cxx_source_compiles("
+ #include <cmath>
+ int main() {
+ std::log(1.0);
+ return 0;
+ }
+ " HAVE_LOG)
+ check_cxx_source_compiles("
+ #include <cmath>
+ int main() {
+ std::exp(1.0);
+ return 0;
+ }
+ " HAVE_EXP)
+
+ # add compile definitions
+ if(HAVE_LOG AND HAVE_EXP)
+ target_compile_definitions(MathFunctions
+ PRIVATE "HAVE_LOG" "HAVE_EXP"
+ )
+ endif()
+endif()
# state that anybody linking to us needs to include the current source dir
# to find MathFunctions.h, while we don't.
target_include_directories(MathFunctions
- INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
- )
+ INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
+ )
# link our compiler flags interface library
-target_link_libraries(MathFunctions tutorial_compiler_flags)
-
-# does this system provide the log and exp functions?
-include(CheckCXXSourceCompiles)
-check_cxx_source_compiles("
- #include <cmath>
- int main() {
- std::log(1.0);
- return 0;
- }
-" HAVE_LOG)
-check_cxx_source_compiles("
- #include <cmath>
- int main() {
- std::exp(1.0);
- return 0;
- }
-" HAVE_EXP)
-
-# add compile definitions
-if(HAVE_LOG AND HAVE_EXP)
- target_compile_definitions(MathFunctions
- PRIVATE "HAVE_LOG" "HAVE_EXP")
-endif()
+target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
# install libs
set(installable_libs MathFunctions tutorial_compiler_flags)
diff --git a/Help/guide/tutorial/Step8/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Step8/MathFunctions/MathFunctions.cxx
new file mode 100644
index 0000000..dc28b4b
--- /dev/null
+++ b/Help/guide/tutorial/Step8/MathFunctions/MathFunctions.cxx
@@ -0,0 +1,19 @@
+#include "MathFunctions.h"
+
+#include <cmath>
+
+#ifdef USE_MYMATH
+# include "mysqrt.h"
+#endif
+
+namespace mathfunctions {
+double sqrt(double x)
+{
+// which square root function should we use?
+#ifdef USE_MYMATH
+ return detail::mysqrt(x);
+#else
+ return std::sqrt(x);
+#endif
+}
+}
diff --git a/Help/guide/tutorial/Step8/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Step8/MathFunctions/MathFunctions.h
index cd36bcc..d5c2f22 100644
--- a/Help/guide/tutorial/Step8/MathFunctions/MathFunctions.h
+++ b/Help/guide/tutorial/Step8/MathFunctions/MathFunctions.h
@@ -1 +1,5 @@
-double mysqrt(double x);
+#pragma once
+
+namespace mathfunctions {
+double sqrt(double x);
+}
diff --git a/Help/guide/tutorial/Step8/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step8/MathFunctions/mysqrt.cxx
index 7eecd26..28ab042 100644
--- a/Help/guide/tutorial/Step8/MathFunctions/mysqrt.cxx
+++ b/Help/guide/tutorial/Step8/MathFunctions/mysqrt.cxx
@@ -1,8 +1,10 @@
+#include "mysqrt.h"
+
#include <cmath>
#include <iostream>
-#include "MathFunctions.h"
-
+namespace mathfunctions {
+namespace detail {
// a hack square root calculation using simple operations
double mysqrt(double x)
{
@@ -30,3 +32,5 @@ double mysqrt(double x)
#endif
return result;
}
+}
+}
diff --git a/Help/guide/tutorial/Step8/MathFunctions/mysqrt.h b/Help/guide/tutorial/Step8/MathFunctions/mysqrt.h
new file mode 100644
index 0000000..593d41e
--- /dev/null
+++ b/Help/guide/tutorial/Step8/MathFunctions/mysqrt.h
@@ -0,0 +1,7 @@
+#pragma once
+
+namespace mathfunctions {
+namespace detail {
+double mysqrt(double x);
+}
+}
diff --git a/Help/guide/tutorial/Step8/TutorialConfig.h.in b/Help/guide/tutorial/Step8/TutorialConfig.h.in
index e23f521..7e4d7fa 100644
--- a/Help/guide/tutorial/Step8/TutorialConfig.h.in
+++ b/Help/guide/tutorial/Step8/TutorialConfig.h.in
@@ -1,4 +1,3 @@
// the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
-#cmakedefine USE_MYMATH
diff --git a/Help/guide/tutorial/Step8/tutorial.cxx b/Help/guide/tutorial/Step8/tutorial.cxx
index b3c6a4f..a3a2bdc 100644
--- a/Help/guide/tutorial/Step8/tutorial.cxx
+++ b/Help/guide/tutorial/Step8/tutorial.cxx
@@ -3,13 +3,9 @@
#include <iostream>
#include <string>
+#include "MathFunctions.h"
#include "TutorialConfig.h"
-// should we include the MathFunctions header?
-#ifdef USE_MYMATH
-# include "MathFunctions.h"
-#endif
-
int main(int argc, char* argv[])
{
if (argc < 2) {
@@ -23,12 +19,7 @@ int main(int argc, char* argv[])
// convert input to double
const double inputValue = std::stod(argv[1]);
- // which square root function should we use?
-#ifdef USE_MYMATH
- const double outputValue = mysqrt(inputValue);
-#else
- const double outputValue = sqrt(inputValue);
-#endif
+ const double outputValue = mathfunctions::sqrt(inputValue);
std::cout << "The square root of " << inputValue << " is " << outputValue
<< std::endl;
diff --git a/Help/guide/tutorial/Step9/CMakeLists.txt b/Help/guide/tutorial/Step9/CMakeLists.txt
index d26a90c..97ec6aa 100644
--- a/Help/guide/tutorial/Step9/CMakeLists.txt
+++ b/Help/guide/tutorial/Step9/CMakeLists.txt
@@ -16,22 +16,17 @@ target_compile_options(tutorial_compiler_flags INTERFACE
"$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
)
-# should we use our own math functions
-option(USE_MYMATH "Use tutorial provided math implementation" ON)
-
# configure a header file to pass some of the CMake settings
# to the source code
configure_file(TutorialConfig.h.in TutorialConfig.h)
# add the MathFunctions library
-if(USE_MYMATH)
- add_subdirectory(MathFunctions)
- list(APPEND EXTRA_LIBS MathFunctions)
-endif()
+add_subdirectory(MathFunctions)
# add the executable
add_executable(Tutorial tutorial.cxx)
-target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS} tutorial_compiler_flags)
+
+target_link_libraries(Tutorial PUBLIC MathFunctions tutorial_compiler_flags)
# add the binary tree to the search path for include files
# so that we will find TutorialConfig.h
diff --git a/Help/guide/tutorial/Step9/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step9/MathFunctions/CMakeLists.txt
index 8e04f97..05c8616 100644
--- a/Help/guide/tutorial/Step9/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step9/MathFunctions/CMakeLists.txt
@@ -1,34 +1,49 @@
-# first we add the executable that generates the table
-add_executable(MakeTable MakeTable.cxx)
-
-# add the command to generate the source code
-add_custom_command(
- OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
- COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
- DEPENDS MakeTable
- )
-
-# add the main library
-add_library(MathFunctions
- mysqrt.cxx
- ${CMAKE_CURRENT_BINARY_DIR}/Table.h
- )
+add_library(MathFunctions MathFunctions.cxx)
# state that anybody linking to us needs to include the current source dir
# to find MathFunctions.h, while we don't.
-# state that we depend on Tutorial_BINARY_DIR but consumers don't, as the
-# TutorialConfig.h include is an implementation detail
-# state that we depend on our binary dir to find Table.h
target_include_directories(MathFunctions
- INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
- PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
- )
+ INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
+ )
-# link our compiler flags interface library
-target_link_libraries(MathFunctions tutorial_compiler_flags)
+# should we use our own math functions
+option(USE_MYMATH "Use tutorial provided math implementation" ON)
+if (USE_MYMATH)
+ target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
+
+ # first we add the executable that generates the table
+ add_executable(MakeTable MakeTable.cxx)
+ target_link_libraries(MakeTable PRIVATE tutorial_compiler_flags)
+
+ # add the command to generate the source code
+ add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
+ COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
+ DEPENDS MakeTable
+ )
+
+ # library that just does sqrt
+ add_library(SqrtLibrary STATIC
+ mysqrt.cxx
+ ${CMAKE_CURRENT_BINARY_DIR}/Table.h
+ )
+
+ # state that we depend on our binary dir to find Table.h
+ target_include_directories(SqrtLibrary PRIVATE
+ ${CMAKE_CURRENT_BINARY_DIR}
+ )
+
+ target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)
+ target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
+endif()
+
+target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
# install libs
set(installable_libs MathFunctions tutorial_compiler_flags)
+if(TARGET SqrtLibrary)
+ list(APPEND installable_libs SqrtLibrary)
+endif()
install(TARGETS ${installable_libs} DESTINATION lib)
# install include headers
install(FILES MathFunctions.h DESTINATION include)
diff --git a/Help/guide/tutorial/Step9/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Step9/MathFunctions/MathFunctions.cxx
new file mode 100644
index 0000000..dc28b4b
--- /dev/null
+++ b/Help/guide/tutorial/Step9/MathFunctions/MathFunctions.cxx
@@ -0,0 +1,19 @@
+#include "MathFunctions.h"
+
+#include <cmath>
+
+#ifdef USE_MYMATH
+# include "mysqrt.h"
+#endif
+
+namespace mathfunctions {
+double sqrt(double x)
+{
+// which square root function should we use?
+#ifdef USE_MYMATH
+ return detail::mysqrt(x);
+#else
+ return std::sqrt(x);
+#endif
+}
+}
diff --git a/Help/guide/tutorial/Step9/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Step9/MathFunctions/MathFunctions.h
index cd36bcc..d5c2f22 100644
--- a/Help/guide/tutorial/Step9/MathFunctions/MathFunctions.h
+++ b/Help/guide/tutorial/Step9/MathFunctions/MathFunctions.h
@@ -1 +1,5 @@
-double mysqrt(double x);
+#pragma once
+
+namespace mathfunctions {
+double sqrt(double x);
+}
diff --git a/Help/guide/tutorial/Step9/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step9/MathFunctions/mysqrt.cxx
index 7d80ee9..477d715 100644
--- a/Help/guide/tutorial/Step9/MathFunctions/mysqrt.cxx
+++ b/Help/guide/tutorial/Step9/MathFunctions/mysqrt.cxx
@@ -1,10 +1,12 @@
-#include <iostream>
+#include "mysqrt.h"
-#include "MathFunctions.h"
+#include <iostream>
// include the generated table
#include "Table.h"
+namespace mathfunctions {
+namespace detail {
// a hack square root calculation using simple operations
double mysqrt(double x)
{
@@ -31,3 +33,5 @@ double mysqrt(double x)
return result;
}
+}
+}
diff --git a/Help/guide/tutorial/Step9/MathFunctions/mysqrt.h b/Help/guide/tutorial/Step9/MathFunctions/mysqrt.h
new file mode 100644
index 0000000..593d41e
--- /dev/null
+++ b/Help/guide/tutorial/Step9/MathFunctions/mysqrt.h
@@ -0,0 +1,7 @@
+#pragma once
+
+namespace mathfunctions {
+namespace detail {
+double mysqrt(double x);
+}
+}
diff --git a/Help/guide/tutorial/Step9/TutorialConfig.h.in b/Help/guide/tutorial/Step9/TutorialConfig.h.in
index e23f521..7e4d7fa 100644
--- a/Help/guide/tutorial/Step9/TutorialConfig.h.in
+++ b/Help/guide/tutorial/Step9/TutorialConfig.h.in
@@ -1,4 +1,3 @@
// the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
-#cmakedefine USE_MYMATH
diff --git a/Help/guide/tutorial/Step9/tutorial.cxx b/Help/guide/tutorial/Step9/tutorial.cxx
index b3c6a4f..a3a2bdc 100644
--- a/Help/guide/tutorial/Step9/tutorial.cxx
+++ b/Help/guide/tutorial/Step9/tutorial.cxx
@@ -3,13 +3,9 @@
#include <iostream>
#include <string>
+#include "MathFunctions.h"
#include "TutorialConfig.h"
-// should we include the MathFunctions header?
-#ifdef USE_MYMATH
-# include "MathFunctions.h"
-#endif
-
int main(int argc, char* argv[])
{
if (argc < 2) {
@@ -23,12 +19,7 @@ int main(int argc, char* argv[])
// convert input to double
const double inputValue = std::stod(argv[1]);
- // which square root function should we use?
-#ifdef USE_MYMATH
- const double outputValue = mysqrt(inputValue);
-#else
- const double outputValue = sqrt(inputValue);
-#endif
+ const double outputValue = mathfunctions::sqrt(inputValue);
std::cout << "The square root of " << inputValue << " is " << outputValue
<< std::endl;
diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst
index c3e87d7..8a92b4b 100644
--- a/Help/manual/cmake-generator-expressions.7.rst
+++ b/Help/manual/cmake-generator-expressions.7.rst
@@ -446,16 +446,20 @@ command. All paths are expected to be in cmake-style format.
components from a path. See :ref:`Path Structure And Terminology` for the
meaning of each path component.
+ .. versionchanged:: 3.27
+ All operations now accept a list of paths as argument. When a list of paths
+ is specified, the operation will be applied to each path.
+
::
- $<PATH:GET_ROOT_NAME,path>
- $<PATH:GET_ROOT_DIRECTORY,path>
- $<PATH:GET_ROOT_PATH,path>
- $<PATH:GET_FILENAME,path>
- $<PATH:GET_EXTENSION[,LAST_ONLY],path>
- $<PATH:GET_STEM[,LAST_ONLY],path>
- $<PATH:GET_RELATIVE_PART,path>
- $<PATH:GET_PARENT_PATH,path>
+ $<PATH:GET_ROOT_NAME,path...>
+ $<PATH:GET_ROOT_DIRECTORY,path...>
+ $<PATH:GET_ROOT_PATH,path...>
+ $<PATH:GET_FILENAME,path...>
+ $<PATH:GET_EXTENSION[,LAST_ONLY],path...>
+ $<PATH:GET_STEM[,LAST_ONLY],path...>
+ $<PATH:GET_RELATIVE_PART,path...>
+ $<PATH:GET_PARENT_PATH,path...>
If a requested component is not present in the path, an empty string is
returned.
@@ -470,9 +474,14 @@ These expressions provide the generation-time capabilities equivalent to the
options of the :command:`cmake_path` command. All paths are expected to be
in cmake-style format.
+.. versionchanged:: 3.27
+ All operations now accept a list of paths as argument. When a list of paths
+ is specified, the operation will be applied to each path.
+
+
.. _GenEx PATH-CMAKE_PATH:
-.. genex:: $<PATH:CMAKE_PATH[,NORMALIZE],path>
+.. genex:: $<PATH:CMAKE_PATH[,NORMALIZE],path...>
.. versionadded:: 3.24
@@ -483,7 +492,7 @@ in cmake-style format.
When the ``NORMALIZE`` option is specified, the path is :ref:`normalized
<Normalization>` after the conversion.
-.. genex:: $<PATH:APPEND,path,input,...>
+.. genex:: $<PATH:APPEND,path...,input,...>
.. versionadded:: 3.24
@@ -493,7 +502,7 @@ in cmake-style format.
See :ref:`cmake_path(APPEND) <APPEND>` for more details.
-.. genex:: $<PATH:REMOVE_FILENAME,path>
+.. genex:: $<PATH:REMOVE_FILENAME,path...>
.. versionadded:: 3.24
@@ -503,7 +512,7 @@ in cmake-style format.
See :ref:`cmake_path(REMOVE_FILENAME) <REMOVE_FILENAME>` for more details.
-.. genex:: $<PATH:REPLACE_FILENAME,path,input>
+.. genex:: $<PATH:REPLACE_FILENAME,path...,input>
.. versionadded:: 3.24
@@ -513,7 +522,7 @@ in cmake-style format.
See :ref:`cmake_path(REPLACE_FILENAME) <REPLACE_FILENAME>` for more details.
-.. genex:: $<PATH:REMOVE_EXTENSION[,LAST_ONLY],path>
+.. genex:: $<PATH:REMOVE_EXTENSION[,LAST_ONLY],path...>
.. versionadded:: 3.24
@@ -521,7 +530,7 @@ in cmake-style format.
See :ref:`cmake_path(REMOVE_EXTENSION) <REMOVE_EXTENSION>` for more details.
-.. genex:: $<PATH:REPLACE_EXTENSION[,LAST_ONLY],path,input>
+.. genex:: $<PATH:REPLACE_EXTENSION[,LAST_ONLY],path...,input>
.. versionadded:: 3.24
@@ -530,14 +539,14 @@ in cmake-style format.
See :ref:`cmake_path(REPLACE_EXTENSION) <REPLACE_EXTENSION>` for more details.
-.. genex:: $<PATH:NORMAL_PATH,path>
+.. genex:: $<PATH:NORMAL_PATH,path...>
.. versionadded:: 3.24
Returns ``path`` normalized according to the steps described in
:ref:`Normalization`.
-.. genex:: $<PATH:RELATIVE_PATH,path,base_directory>
+.. genex:: $<PATH:RELATIVE_PATH,path...,base_directory>
.. versionadded:: 3.24
@@ -547,7 +556,7 @@ in cmake-style format.
See :ref:`cmake_path(RELATIVE_PATH) <cmake_path-RELATIVE_PATH>` for more
details.
-.. genex:: $<PATH:ABSOLUTE_PATH[,NORMALIZE],path,base_directory>
+.. genex:: $<PATH:ABSOLUTE_PATH[,NORMALIZE],path...,base_directory>
.. versionadded:: 3.24
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index 22e9eb2..e4c286d 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -51,6 +51,14 @@ The :variable:`CMAKE_MINIMUM_REQUIRED_VERSION` variable may also be used
to determine whether to report an error on use of deprecated macros or
functions.
+Policies Introduced by CMake 3.27
+=================================
+
+.. toctree::
+ :maxdepth: 1
+
+ CMP0144: find_package uses upper-case PACKAGENAME_ROOT variables. </policy/CMP0144>
+
Policies Introduced by CMake 3.26
=================================
diff --git a/Help/policy/CMP0144.rst b/Help/policy/CMP0144.rst
new file mode 100644
index 0000000..3959d96
--- /dev/null
+++ b/Help/policy/CMP0144.rst
@@ -0,0 +1,26 @@
+CMP0144
+-------
+
+.. versionadded:: 3.27
+
+:command:`find_package` uses upper-case ``<PACKAGENAME>_ROOT`` variables.
+
+In CMake 3.27 and above the :command:`find_package(<PackageName>)` command now
+searches prefixes specified by the upper-case :variable:`<PACKAGENAME>_ROOT`
+CMake variable and the :envvar:`<PACKAGENAME>_ROOT` environment variable
+in addition to the case-preserved :variable:`<PackageName>_ROOT` and
+:envvar:`<PackageName>_ROOT` variables used since policy :policy:`CMP0074`.
+This policy provides compatibility with projects that have not been
+updated to avoid using ``<PACKAGENAME>_ROOT`` variables for other purposes.
+
+The ``OLD`` behavior for this policy is to ignore ``<PACKAGENAME>_ROOT``
+variables if the original ``<PackageName>`` has lower-case characters.
+The ``NEW`` behavior for this policy is to use ``<PACKAGENAME>_ROOT``
+variables.
+
+This policy was introduced in CMake version 3.27. 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/release/dev/PATH-genex-support-list.rst b/Help/release/dev/PATH-genex-support-list.rst
new file mode 100644
index 0000000..ce87fdd
--- /dev/null
+++ b/Help/release/dev/PATH-genex-support-list.rst
@@ -0,0 +1,5 @@
+PATH-genex-supports-list
+------------------------
+
+* The :genex:`$<PATH>` generator expression learned to process list of paths
+ for decomposition and transformation operations.
diff --git a/Help/release/dev/find_package-PACKAGENAME_ROOT.rst b/Help/release/dev/find_package-PACKAGENAME_ROOT.rst
new file mode 100644
index 0000000..0388271
--- /dev/null
+++ b/Help/release/dev/find_package-PACKAGENAME_ROOT.rst
@@ -0,0 +1,7 @@
+find_package-PACKAGENAME_ROOT
+-----------------------------
+
+* The :command:`find_package` command now searches prefixes specified by
+ upper-case :variable:`<PACKAGENAME>_ROOT` CMake variables and upper-case
+ :envvar:`<PACKAGENAME>_ROOT` environment variables.
+ See policy :policy:`CMP0144`.
diff --git a/Help/variable/PackageName_ROOT.rst b/Help/variable/PackageName_ROOT.rst
index 6b17be3..8b728ba 100644
--- a/Help/variable/PackageName_ROOT.rst
+++ b/Help/variable/PackageName_ROOT.rst
@@ -14,3 +14,11 @@ This variable may hold a single prefix or a
:ref:`semicolon-separated list <CMake Language Lists>` of multiple prefixes.
See also the :envvar:`<PackageName>_ROOT` environment variable.
+
+.. variable:: <PACKAGENAME>_ROOT
+
+ .. versionadded:: 3.27
+
+ Calls to :command:`find_package(<PackageName>)` will also search in
+ prefixes specified by the upper-case ``<PACKAGENAME>_ROOT`` CMake
+ variable. See policy :policy:`CMP0144`.
diff --git a/Modules/FetchContent.cmake b/Modules/FetchContent.cmake
index 153563f..dd5f617 100644
--- a/Modules/FetchContent.cmake
+++ b/Modules/FetchContent.cmake
@@ -1536,7 +1536,9 @@ ExternalProject_Add_Step(${contentName}-populate copyfile
if(CMAKE_GENERATOR_TOOLSET)
list(APPEND subCMakeOpts "-T${CMAKE_GENERATOR_TOOLSET}")
endif()
-
+ if(CMAKE_GENERATOR_INSTANCE)
+ list(APPEND subCMakeOpts "-DCMAKE_GENERATOR_INSTANCE:INTERNAL=${CMAKE_GENERATOR_INSTANCE}")
+ endif()
if(CMAKE_MAKE_PROGRAM)
list(APPEND subCMakeOpts "-DCMAKE_MAKE_PROGRAM:FILEPATH=${CMAKE_MAKE_PROGRAM}")
endif()
diff --git a/Modules/FindOpenSSL.cmake b/Modules/FindOpenSSL.cmake
index ae1148d..4e8374c 100644
--- a/Modules/FindOpenSSL.cmake
+++ b/Modules/FindOpenSSL.cmake
@@ -120,12 +120,13 @@ macro(_OpenSSL_test_and_find_dependencies ssl_library crypto_library)
unset(_OpenSSL_has_dependency_zlib)
if(OPENSSL_USE_STATIC_LIBS)
set(_OpenSSL_libs "${_OPENSSL_STATIC_LIBRARIES}")
+ set(_OpenSSL_ldflags_other "${_OPENSSL_STATIC_LDFLAGS_OTHER}")
else()
set(_OpenSSL_libs "${_OPENSSL_LIBRARIES}")
+ set(_OpenSSL_ldflags_other "${_OPENSSL_LDFLAGS_OTHER}")
endif()
if(_OpenSSL_libs)
unset(_OpenSSL_has_dependency_dl)
- unset(_OpenSSL_has_dependency_threads)
foreach(_OPENSSL_DEP_LIB IN LISTS _OpenSSL_libs)
if (_OPENSSL_DEP_LIB STREQUAL "ssl" OR _OPENSSL_DEP_LIB STREQUAL "crypto")
# ignoring: these are the targets
@@ -141,10 +142,22 @@ macro(_OpenSSL_test_and_find_dependencies ssl_library crypto_library)
unset(_OPENSSL_DEP_LIB)
else()
set(_OpenSSL_has_dependency_dl TRUE)
+ endif()
+ if(_OpenSSL_ldflags_other)
+ unset(_OpenSSL_has_dependency_threads)
+ foreach(_OPENSSL_DEP_LDFLAG IN LISTS _OpenSSL_ldflags_other)
+ if (_OPENSSL_DEP_LDFLAG STREQUAL "-pthread")
+ set(_OpenSSL_has_dependency_threads TRUE)
+ find_package(Threads)
+ endif()
+ endforeach()
+ unset(_OPENSSL_DEP_LDFLAG)
+ else()
set(_OpenSSL_has_dependency_threads TRUE)
find_package(Threads)
endif()
unset(_OpenSSL_libs)
+ unset(_OpenSSL_ldflags_other)
else()
set(_OpenSSL_has_dependencies FALSE)
endif()
diff --git a/Modules/GenerateExportHeader.cmake b/Modules/GenerateExportHeader.cmake
index 7461a3e..ea8616a 100644
--- a/Modules/GenerateExportHeader.cmake
+++ b/Modules/GenerateExportHeader.cmake
@@ -293,7 +293,7 @@ macro(_DO_SET_MACRO_VALUES TARGET_LIBRARY)
set(DEFINE_IMPORT)
set(DEFINE_NO_EXPORT)
- if (COMPILER_HAS_DEPRECATED_ATTR)
+ if (COMPILER_HAS_DEPRECATED_ATTR AND NOT WIN32)
set(DEFINE_DEPRECATED "__attribute__ ((__deprecated__))")
elseif(COMPILER_HAS_DEPRECATED)
set(DEFINE_DEPRECATED "__declspec(deprecated)")
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 53f1136..6fc286a 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,7 +1,7 @@
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
set(CMake_VERSION_MINOR 26)
-set(CMake_VERSION_PATCH 20230223)
+set(CMake_VERSION_PATCH 20230225)
#set(CMake_VERSION_RC 0)
set(CMake_VERSION_IS_DIRTY 0)
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index c1b82ab..5f1a2c5 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -975,35 +975,7 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
}
}
- {
- // Allocate a PACKAGE_ROOT_PATH for the current find_package call.
- this->Makefile->FindPackageRootPathStack.emplace_back();
- std::vector<std::string>& rootPaths =
- this->Makefile->FindPackageRootPathStack.back();
-
- // Add root paths from <PackageName>_ROOT CMake and environment variables,
- // subject to CMP0074.
- switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0074)) {
- case cmPolicies::WARN:
- this->Makefile->MaybeWarnCMP0074(this->Name);
- CM_FALLTHROUGH;
- case cmPolicies::OLD:
- // OLD behavior is to ignore the <pkg>_ROOT variables.
- break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- this->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0074));
- break;
- case cmPolicies::NEW: {
- // NEW behavior is to honor the <pkg>_ROOT variables.
- std::string const rootVar = this->Name + "_ROOT";
- this->Makefile->GetDefExpandList(rootVar, rootPaths, false);
- cmSystemTools::GetPath(rootPaths, rootVar.c_str());
- } break;
- }
- }
+ this->PushFindPackageRootPathStack();
this->SetModuleVariables(components, componentVarDefs);
@@ -1129,8 +1101,7 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
// Restore original state of "_FIND_" variables set in SetModuleVariables()
this->RestoreFindDefinitions();
- // Pop the package stack
- this->Makefile->FindPackageRootPathStack.pop_back();
+ this->PopFindPackageRootPathStack();
if (!this->DebugBuffer.empty()) {
this->DebugMessage(this->DebugBuffer);
@@ -1834,6 +1805,99 @@ void cmFindPackageCommand::AppendSuccessInformation()
}
}
+void cmFindPackageCommand::PushFindPackageRootPathStack()
+{
+ // Allocate a PACKAGE_ROOT_PATH for the current find_package call.
+ this->Makefile->FindPackageRootPathStack.emplace_back();
+ std::vector<std::string>& rootPaths =
+ this->Makefile->FindPackageRootPathStack.back();
+
+ // Add root paths from <PackageName>_ROOT CMake and environment variables,
+ // subject to CMP0074.
+ std::string const rootVar = this->Name + "_ROOT";
+ cmValue rootDef = this->Makefile->GetDefinition(rootVar);
+ if (rootDef && rootDef.IsEmpty()) {
+ rootDef = nullptr;
+ }
+ cm::optional<std::string> rootEnv = cmSystemTools::GetEnvVar(rootVar);
+ if (rootEnv && rootEnv->empty()) {
+ rootEnv = cm::nullopt;
+ }
+ switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0074)) {
+ case cmPolicies::WARN:
+ this->Makefile->MaybeWarnCMP0074(rootVar, rootDef, rootEnv);
+ CM_FALLTHROUGH;
+ case cmPolicies::OLD:
+ // OLD behavior is to ignore the <PackageName>_ROOT variables.
+ return;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0074));
+ return;
+ case cmPolicies::NEW: {
+ // NEW behavior is to honor the <PackageName>_ROOT variables.
+ } break;
+ }
+
+ // Add root paths from <PACKAGENAME>_ROOT CMake and environment variables,
+ // if they are different than <PackageName>_ROOT, and subject to CMP0144.
+ std::string const rootVAR = cmSystemTools::UpperCase(rootVar);
+ cmValue rootDEF;
+ cm::optional<std::string> rootENV;
+ if (rootVAR != rootVar) {
+ rootDEF = this->Makefile->GetDefinition(rootVAR);
+ if (rootDEF && (rootDEF.IsEmpty() || rootDEF == rootDef)) {
+ rootDEF = nullptr;
+ }
+ rootENV = cmSystemTools::GetEnvVar(rootVAR);
+ if (rootENV && (rootENV->empty() || rootENV == rootEnv)) {
+ rootENV = cm::nullopt;
+ }
+ }
+
+ switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0144)) {
+ case cmPolicies::WARN:
+ this->Makefile->MaybeWarnCMP0144(rootVAR, rootDEF, rootENV);
+ CM_FALLTHROUGH;
+ case cmPolicies::OLD:
+ // OLD behavior is to ignore the <PACKAGENAME>_ROOT variables.
+ rootDEF = nullptr;
+ rootENV = cm::nullopt;
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0144));
+ return;
+ case cmPolicies::NEW: {
+ // NEW behavior is to honor the <PACKAGENAME>_ROOT variables.
+ } break;
+ }
+
+ if (rootDef) {
+ cmExpandList(*rootDef, rootPaths);
+ }
+ if (rootDEF) {
+ cmExpandList(*rootDEF, rootPaths);
+ }
+ if (rootEnv) {
+ std::vector<std::string> p = cmSystemTools::SplitEnvPath(*rootEnv);
+ std::move(p.begin(), p.end(), std::back_inserter(rootPaths));
+ }
+ if (rootENV) {
+ std::vector<std::string> p = cmSystemTools::SplitEnvPath(*rootENV);
+ std::move(p.begin(), p.end(), std::back_inserter(rootPaths));
+ }
+}
+
+void cmFindPackageCommand::PopFindPackageRootPathStack()
+{
+ this->Makefile->FindPackageRootPathStack.pop_back();
+}
+
void cmFindPackageCommand::ComputePrefixes()
{
this->FillPrefixesPackageRedirect();
diff --git a/Source/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h
index 28e00a1..18684c9 100644
--- a/Source/cmFindPackageCommand.h
+++ b/Source/cmFindPackageCommand.h
@@ -125,6 +125,9 @@ private:
void StoreVersionFound();
void SetConfigDirCacheVariable(const std::string& value);
+ void PushFindPackageRootPathStack();
+ void PopFindPackageRootPathStack();
+
void ComputePrefixes();
void FillPrefixesPackageRedirect();
void FillPrefixesPackageRoot();
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 5d761ac..5c7d217 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -688,6 +688,14 @@ static const struct PathNode : public cmGeneratorExpressionNode
const GeneratorExpressionContent* content,
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
{
+ static auto processList =
+ [](std::string const& arg,
+ std::function<void(std::string&)> transform) -> std::string {
+ auto list = cmExpandedList(arg);
+ std::for_each(list.begin(), list.end(), std::move(transform));
+ return cmJoin(list, ";");
+ };
+
static std::unordered_map<
cm::string_view,
std::function<std::string(cmGeneratorExpressionContext*,
@@ -698,38 +706,49 @@ static const struct PathNode : public cmGeneratorExpressionNode
[](cmGeneratorExpressionContext* ctx,
const GeneratorExpressionContent* cnt,
Arguments& args) -> std::string {
- return CheckPathParameters(ctx, cnt, "GET_ROOT_NAME"_s, args) &&
- !args.front().empty()
- ? cmCMakePath{ args.front() }.GetRootName().String()
- : std::string{};
+ if (CheckPathParameters(ctx, cnt, "GET_ROOT_NAME"_s, args) &&
+ !args.front().empty()) {
+ return processList(args.front(), [](std::string& value) {
+ value = cmCMakePath{ value }.GetRootName().String();
+ });
+ }
+ return std::string{};
} },
{ "GET_ROOT_DIRECTORY"_s,
[](cmGeneratorExpressionContext* ctx,
const GeneratorExpressionContent* cnt,
Arguments& args) -> std::string {
- return CheckPathParameters(ctx, cnt, "GET_ROOT_DIRECTORY"_s,
- args) &&
- !args.front().empty()
- ? cmCMakePath{ args.front() }.GetRootDirectory().String()
- : std::string{};
+ if (CheckPathParameters(ctx, cnt, "GET_ROOT_DIRECTORY"_s, args) &&
+ !args.front().empty()) {
+ return processList(args.front(), [](std::string& value) {
+ value = cmCMakePath{ value }.GetRootDirectory().String();
+ });
+ }
+ return std::string{};
} },
{ "GET_ROOT_PATH"_s,
[](cmGeneratorExpressionContext* ctx,
const GeneratorExpressionContent* cnt,
Arguments& args) -> std::string {
- return CheckPathParameters(ctx, cnt, "GET_ROOT_PATH"_s, args) &&
- !args.front().empty()
- ? cmCMakePath{ args.front() }.GetRootPath().String()
- : std::string{};
+ if (CheckPathParameters(ctx, cnt, "GET_ROOT_PATH"_s, args) &&
+ !args.front().empty()) {
+ return processList(args.front(), [](std::string& value) {
+ value = cmCMakePath{ value }.GetRootPath().String();
+ });
+ }
+ return std::string{};
} },
{ "GET_FILENAME"_s,
[](cmGeneratorExpressionContext* ctx,
const GeneratorExpressionContent* cnt,
Arguments& args) -> std::string {
- return CheckPathParameters(ctx, cnt, "GET_FILENAME"_s, args) &&
- !args.front().empty()
- ? cmCMakePath{ args.front() }.GetFileName().String()
- : std::string{};
+ if (CheckPathParameters(ctx, cnt, "GET_FILENAME"_s, args) &&
+ !args.front().empty()) {
+ return processList(args.front(), [](std::string& value) {
+ value = cmCMakePath{ value }.GetFileName().String();
+ });
+ }
+ return std::string{};
} },
{ "GET_EXTENSION"_s,
[](cmGeneratorExpressionContext* ctx,
@@ -746,9 +765,14 @@ static const struct PathNode : public cmGeneratorExpressionNode
if (args.front().empty()) {
return std::string{};
}
- return lastOnly
- ? cmCMakePath{ args.front() }.GetExtension().String()
- : cmCMakePath{ args.front() }.GetWideExtension().String();
+ if (lastOnly) {
+ return processList(args.front(), [](std::string& value) {
+ value = cmCMakePath{ value }.GetExtension().String();
+ });
+ }
+ return processList(args.front(), [](std::string& value) {
+ value = cmCMakePath{ value }.GetWideExtension().String();
+ });
}
return std::string{};
} },
@@ -766,9 +790,14 @@ static const struct PathNode : public cmGeneratorExpressionNode
if (args.front().empty()) {
return std::string{};
}
- return lastOnly
- ? cmCMakePath{ args.front() }.GetStem().String()
- : cmCMakePath{ args.front() }.GetNarrowStem().String();
+ if (lastOnly) {
+ return processList(args.front(), [](std::string& value) {
+ value = cmCMakePath{ value }.GetStem().String();
+ });
+ }
+ return processList(args.front(), [](std::string& value) {
+ value = cmCMakePath{ value }.GetNarrowStem().String();
+ });
}
return std::string{};
} },
@@ -776,19 +805,24 @@ static const struct PathNode : public cmGeneratorExpressionNode
[](cmGeneratorExpressionContext* ctx,
const GeneratorExpressionContent* cnt,
Arguments& args) -> std::string {
- return CheckPathParameters(ctx, cnt, "GET_RELATIVE_PART"_s,
- args) &&
- !args.front().empty()
- ? cmCMakePath{ args.front() }.GetRelativePath().String()
- : std::string{};
+ if (CheckPathParameters(ctx, cnt, "GET_RELATIVE_PART"_s, args) &&
+ !args.front().empty()) {
+ return processList(args.front(), [](std::string& value) {
+ value = cmCMakePath{ value }.GetRelativePath().String();
+ });
+ }
+ return std::string{};
} },
{ "GET_PARENT_PATH"_s,
[](cmGeneratorExpressionContext* ctx,
const GeneratorExpressionContent* cnt,
Arguments& args) -> std::string {
- return CheckPathParameters(ctx, cnt, "GET_PARENT_PATH"_s, args)
- ? cmCMakePath{ args.front() }.GetParentPath().String()
- : std::string{};
+ if (CheckPathParameters(ctx, cnt, "GET_PARENT_PATH"_s, args)) {
+ return processList(args.front(), [](std::string& value) {
+ value = cmCMakePath{ value }.GetParentPath().String();
+ });
+ }
+ return std::string{};
} },
{ "HAS_ROOT_NAME"_s,
[](cmGeneratorExpressionContext* ctx,
@@ -904,10 +938,12 @@ static const struct PathNode : public cmGeneratorExpressionNode
normalize ? "CMAKE_PATH,NORMALIZE"_s
: "CMAKE_PATH"_s,
args.size(), 1)) {
- auto path =
- cmCMakePath{ args.front(), cmCMakePath::auto_format };
- return normalize ? path.Normal().GenericString()
- : path.GenericString();
+ return processList(
+ args.front(), [normalize](std::string& value) {
+ auto path = cmCMakePath{ value, cmCMakePath::auto_format };
+ value = normalize ? path.Normal().GenericString()
+ : path.GenericString();
+ });
}
return std::string{};
} },
@@ -917,11 +953,16 @@ static const struct PathNode : public cmGeneratorExpressionNode
Arguments& args) -> std::string {
if (CheckPathParametersEx(ctx, cnt, "APPEND"_s, args.size(), 1,
false)) {
- cmCMakePath path;
- for (const auto& p : args) {
- path /= p;
- }
- return path.String();
+ auto const& list = args.front();
+ args.advance(1);
+
+ return processList(list, [&args](std::string& value) {
+ cmCMakePath path{ value };
+ for (const auto& p : args) {
+ path /= p;
+ }
+ value = path.String();
+ });
}
return std::string{};
} },
@@ -929,20 +970,26 @@ static const struct PathNode : public cmGeneratorExpressionNode
[](cmGeneratorExpressionContext* ctx,
const GeneratorExpressionContent* cnt,
Arguments& args) -> std::string {
- return CheckPathParameters(ctx, cnt, "REMOVE_FILENAME"_s, args) &&
- !args.front().empty()
- ? cmCMakePath{ args.front() }.RemoveFileName().String()
- : std::string{};
+ if (CheckPathParameters(ctx, cnt, "REMOVE_FILENAME"_s, args) &&
+ !args.front().empty()) {
+ return processList(args.front(), [](std::string& value) {
+ value = cmCMakePath{ value }.RemoveFileName().String();
+ });
+ }
+ return std::string{};
} },
{ "REPLACE_FILENAME"_s,
[](cmGeneratorExpressionContext* ctx,
const GeneratorExpressionContent* cnt,
Arguments& args) -> std::string {
- return CheckPathParameters(ctx, cnt, "REPLACE_FILENAME"_s, args, 2)
- ? cmCMakePath{ args[0] }
- .ReplaceFileName(cmCMakePath{ args[1] })
- .String()
- : std::string{};
+ if (CheckPathParameters(ctx, cnt, "REPLACE_FILENAME"_s, args, 2)) {
+ return processList(args.front(), [&args](std::string& value) {
+ value = cmCMakePath{ value }
+ .ReplaceFileName(cmCMakePath{ args[1] })
+ .String();
+ });
+ }
+ return std::string{};
} },
{ "REMOVE_EXTENSION"_s,
[](cmGeneratorExpressionContext* ctx,
@@ -959,9 +1006,14 @@ static const struct PathNode : public cmGeneratorExpressionNode
if (args.front().empty()) {
return std::string{};
}
- return lastOnly
- ? cmCMakePath{ args.front() }.RemoveExtension().String()
- : cmCMakePath{ args.front() }.RemoveWideExtension().String();
+ if (lastOnly) {
+ return processList(args.front(), [](std::string& value) {
+ value = cmCMakePath{ value }.RemoveExtension().String();
+ });
+ }
+ return processList(args.front(), [](std::string& value) {
+ value = cmCMakePath{ value }.RemoveWideExtension().String();
+ });
}
return std::string{};
} },
@@ -979,13 +1031,17 @@ static const struct PathNode : public cmGeneratorExpressionNode
: "REPLACE_EXTENSION"_s,
args.size(), 2)) {
if (lastOnly) {
- return cmCMakePath{ args[0] }
- .ReplaceExtension(cmCMakePath{ args[1] })
- .String();
+ return processList(args.front(), [&args](std::string& value) {
+ value = cmCMakePath{ value }
+ .ReplaceExtension(cmCMakePath{ args[1] })
+ .String();
+ });
}
- return cmCMakePath{ args[0] }
- .ReplaceWideExtension(cmCMakePath{ args[1] })
- .String();
+ return processList(args.front(), [&args](std::string& value) {
+ value = cmCMakePath{ value }
+ .ReplaceWideExtension(cmCMakePath{ args[1] })
+ .String();
+ });
}
return std::string{};
} },
@@ -993,18 +1049,24 @@ static const struct PathNode : public cmGeneratorExpressionNode
[](cmGeneratorExpressionContext* ctx,
const GeneratorExpressionContent* cnt,
Arguments& args) -> std::string {
- return CheckPathParameters(ctx, cnt, "NORMAL_PATH"_s, args) &&
- !args.front().empty()
- ? cmCMakePath{ args.front() }.Normal().String()
- : std::string{};
+ if (CheckPathParameters(ctx, cnt, "NORMAL_PATH"_s, args) &&
+ !args.front().empty()) {
+ return processList(args.front(), [](std::string& value) {
+ value = cmCMakePath{ value }.Normal().String();
+ });
+ }
+ return std::string{};
} },
{ "RELATIVE_PATH"_s,
[](cmGeneratorExpressionContext* ctx,
const GeneratorExpressionContent* cnt,
Arguments& args) -> std::string {
- return CheckPathParameters(ctx, cnt, "RELATIVE_PATH"_s, args, 2)
- ? cmCMakePath{ args[0] }.Relative(args[1]).String()
- : std::string{};
+ if (CheckPathParameters(ctx, cnt, "RELATIVE_PATH"_s, args, 2)) {
+ return processList(args.front(), [&args](std::string& value) {
+ value = cmCMakePath{ value }.Relative(args[1]).String();
+ });
+ }
+ return std::string{};
} },
{ "ABSOLUTE_PATH"_s,
[](cmGeneratorExpressionContext* ctx,
@@ -1018,8 +1080,11 @@ static const struct PathNode : public cmGeneratorExpressionNode
normalize ? "ABSOLUTE_PATH,NORMALIZE"_s
: "ABSOLUTE_PATH"_s,
args.size(), 2)) {
- auto path = cmCMakePath{ args[0] }.Absolute(args[1]);
- return normalize ? path.Normal().String() : path.String();
+ return processList(
+ args.front(), [&args, normalize](std::string& value) {
+ auto path = cmCMakePath{ value }.Absolute(args[1]);
+ value = normalize ? path.Normal().String() : path.String();
+ });
}
return std::string{};
} }
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index d963a5a..2fc2974 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -208,32 +208,47 @@ bool cmMakefile::CheckCMP0037(std::string const& targetName,
return true;
}
-void cmMakefile::MaybeWarnCMP0074(std::string const& pkg)
+void cmMakefile::MaybeWarnCMP0074(std::string const& rootVar, cmValue rootDef,
+ cm::optional<std::string> const& rootEnv)
{
- // Warn if a <pkg>_ROOT variable we may use is set.
- std::string const varName = pkg + "_ROOT";
- cmValue var = this->GetDefinition(varName);
- std::string env;
- cmSystemTools::GetEnv(varName, env);
-
- bool const haveVar = cmNonempty(var);
- bool const haveEnv = !env.empty();
- if ((haveVar || haveEnv) && this->WarnedCMP0074.insert(varName).second) {
+ // Warn if a <PackageName>_ROOT variable we may use is set.
+ if ((rootDef || rootEnv) && this->WarnedCMP0074.insert(rootVar).second) {
std::ostringstream w;
w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0074) << "\n";
- if (haveVar) {
- w << "CMake variable " << varName << " is set to:\n"
- << " " << *var << "\n";
+ if (rootDef) {
+ w << "CMake variable " << rootVar << " is set to:\n"
+ << " " << *rootDef << "\n";
}
- if (haveEnv) {
- w << "Environment variable " << varName << " is set to:\n"
- << " " << env << "\n";
+ if (rootEnv) {
+ w << "Environment variable " << rootVar << " is set to:\n"
+ << " " << *rootEnv << "\n";
}
w << "For compatibility, CMake is ignoring the variable.";
this->IssueMessage(MessageType::AUTHOR_WARNING, w.str());
}
}
+void cmMakefile::MaybeWarnCMP0144(std::string const& rootVAR, cmValue rootDEF,
+ cm::optional<std::string> const& rootENV)
+{
+ // Warn if a <PACKAGENAME>_ROOT variable we may use is set.
+ if ((rootDEF || rootENV) && this->WarnedCMP0144.insert(rootVAR).second) {
+ std::ostringstream w;
+ w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0144) << "\n";
+ if (rootDEF) {
+ w << "CMake variable " << rootVAR << " is set to:\n"
+ << " " << *rootDEF << "\n";
+ }
+ if (rootENV) {
+ w << "Environment variable " << rootVAR << " is set to:\n"
+ << " " << *rootENV << "\n";
+ }
+ w << "For compatibility, find_package is ignoring the variable, but "
+ "code in a .cmake module might still use it.";
+ this->IssueMessage(MessageType::AUTHOR_WARNING, w.str());
+ }
+}
+
cmBTStringRange cmMakefile::GetIncludeDirectoriesEntries() const
{
return this->StateSnapshot.GetDirectory().GetIncludeDirectoriesEntries();
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index 7b19c97..3cf6e61 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -1011,7 +1011,10 @@ public:
bool GetDebugFindPkgMode() const;
- void MaybeWarnCMP0074(std::string const& pkg);
+ void MaybeWarnCMP0074(std::string const& rootVar, cmValue rootDef,
+ cm::optional<std::string> const& rootEnv);
+ void MaybeWarnCMP0144(std::string const& rootVAR, cmValue rootDEF,
+ cm::optional<std::string> const& rootENV);
void MaybeWarnUninitialized(std::string const& variable,
const char* sourceFilename) const;
bool IsProjectFile(const char* filename) const;
@@ -1189,6 +1192,7 @@ private:
bool CheckSystemVars;
bool CheckCMP0000;
std::set<std::string> WarnedCMP0074;
+ std::set<std::string> WarnedCMP0144;
bool IsSourceFileTryCompile;
mutable bool SuppressSideEffects;
ImportedTargetScope CurrentImportedTargetScope = ImportedTargetScope::Local;
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index 568eca3..1eca586 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -434,7 +434,10 @@ class cmMakefile;
3, 25, 0, cmPolicies::WARN) \
SELECT(POLICY, CMP0143, \
"Global property USE_FOLDERS treated as ON by default", 3, 26, 0, \
- cmPolicies::WARN)
+ cmPolicies::WARN) \
+ SELECT(POLICY, CMP0144, \
+ "find_package uses upper-case <PACKAGENAME>_ROOT variables.", 3, 27, \
+ 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/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 3d61270..1fb0079 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -1648,6 +1648,32 @@ std::string cmSystemTools::RelativeIfUnder(std::string const& top,
return out;
}
+cm::optional<std::string> cmSystemTools::GetEnvVar(std::string const& var)
+{
+ cm::optional<std::string> result;
+ {
+ std::string value;
+ if (cmSystemTools::GetEnv(var, value)) {
+ result = std::move(value);
+ }
+ }
+ return result;
+}
+
+std::vector<std::string> cmSystemTools::SplitEnvPath(std::string const& value)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ static cm::string_view sep = ";"_s;
+#else
+ static cm::string_view sep = ":"_s;
+#endif
+ std::vector<std::string> paths = cmTokenize(value, sep);
+ for (std::string& p : paths) {
+ SystemTools::ConvertToUnixSlashes(p);
+ }
+ return paths;
+}
+
#ifndef CMAKE_BOOTSTRAP
bool cmSystemTools::UnsetEnv(const char* value)
{
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index 09f2bf0..7d55d4b 100644
--- a/Source/cmSystemTools.h
+++ b/Source/cmSystemTools.h
@@ -399,6 +399,9 @@ public:
static std::string RelativeIfUnder(std::string const& top,
std::string const& in);
+ static cm::optional<std::string> GetEnvVar(std::string const& var);
+ static std::vector<std::string> SplitEnvPath(std::string const& value);
+
#ifndef CMAKE_BOOTSTRAP
/** Remove an environment variable */
static bool UnsetEnv(const char* value);
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index d57b78b..a2a9e09 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -2329,6 +2329,9 @@ bool cmVSLink::Parse(std::vector<std::string>::const_iterator argBeg,
cmSystemTools::Strucmp(arg->c_str(), "/INCREMENTAL") == 0 ||
cmSystemTools::Strucmp(arg->c_str(), "-INCREMENTAL") == 0) {
this->Incremental = true;
+ } else if (cmSystemTools::Strucmp(arg->c_str(), "/INCREMENTAL:NO") == 0 ||
+ cmSystemTools::Strucmp(arg->c_str(), "-INCREMENTAL:NO") == 0) {
+ this->Incremental = false;
} else if (cmSystemTools::Strucmp(arg->c_str(), "/MANIFEST:NO") == 0 ||
cmSystemTools::Strucmp(arg->c_str(), "-MANIFEST:NO") == 0) {
this->LinkGeneratesManifest = false;
@@ -2353,17 +2356,11 @@ bool cmVSLink::Parse(std::vector<std::string>::const_iterator argBeg,
// pass it to the link command.
this->ManifestFileRC = intDir + "/manifest.rc";
this->ManifestFileRes = intDir + "/manifest.res";
- } else if (this->UserManifests.empty()) {
- // Prior to support for user-specified manifests CMake placed the
- // linker-generated manifest next to the binary (as if it were not to be
- // embedded) when not linking incrementally. Preserve this behavior.
- this->ManifestFile = this->TargetFile + ".manifest";
- this->LinkerManifestFile = this->ManifestFile;
- }
- if (this->LinkGeneratesManifest) {
- this->LinkCommand.emplace_back("/MANIFEST");
- this->LinkCommand.push_back("/MANIFESTFILE:" + this->LinkerManifestFile);
+ if (this->LinkGeneratesManifest) {
+ this->LinkCommand.emplace_back("/MANIFEST");
+ this->LinkCommand.push_back("/MANIFESTFILE:" + this->LinkerManifestFile);
+ }
}
return true;
@@ -2497,20 +2494,23 @@ int cmVSLink::LinkIncremental()
int cmVSLink::LinkNonIncremental()
{
- // Run the link command (possibly generates intermediate manifest).
- if (!RunCommand("LINK", this->LinkCommand, this->Verbose, FORMAT_DECIMAL)) {
- return -1;
- }
+ // Sort out any manifests.
+ if (this->LinkGeneratesManifest || !this->UserManifests.empty()) {
+ std::string opt =
+ std::string("/MANIFEST:EMBED,ID=") + (this->Type == 1 ? '1' : '2');
+ this->LinkCommand.emplace_back(opt);
- // If we have no manifest files we are done.
- if (!this->LinkGeneratesManifest && this->UserManifests.empty()) {
- return 0;
+ for (auto const& m : this->UserManifests) {
+ opt = "/MANIFESTINPUT:" + m;
+ this->LinkCommand.emplace_back(opt);
+ }
}
- // Run the manifest tool to embed the final manifest in the binary.
- std::string mtOut =
- "/outputresource:" + this->TargetFile + (this->Type == 1 ? ";#1" : ";#2");
- return this->RunMT(mtOut, false);
+ // Run the link command.
+ if (!RunCommand("LINK", this->LinkCommand, this->Verbose, FORMAT_DECIMAL)) {
+ return -1;
+ }
+ return 0;
}
int cmVSLink::RunMT(std::string const& out, bool notify)
diff --git a/Tests/MSManifest/Subdir/CMakeLists.txt b/Tests/MSManifest/Subdir/CMakeLists.txt
index 3b4fccc..68c66fe 100644
--- a/Tests/MSManifest/Subdir/CMakeLists.txt
+++ b/Tests/MSManifest/Subdir/CMakeLists.txt
@@ -5,6 +5,11 @@ if(MSVC AND NOT MSVC_VERSION LESS 1400)
add_test(NAME MSManifest.Single COMMAND
${CMAKE_COMMAND} -Dexe=$<TARGET_FILE:MSManifest>
-P ${CMAKE_CURRENT_SOURCE_DIR}/check.cmake)
+ add_executable(MSManifestNonIncremental main.c ${CMAKE_CURRENT_BINARY_DIR}/test.manifest)
+ set_property(TARGET MSManifestNonIncremental PROPERTY LINK_FLAGS "/INCREMENTAL:NO")
+ add_test(NAME MSManifest.Single.NonIncremental COMMAND
+ ${CMAKE_COMMAND} -Dexe=$<TARGET_FILE:MSManifestNonIncremental>
+ -P ${CMAKE_CURRENT_SOURCE_DIR}/check.cmake)
add_executable(MSManifestNone main.c)
set_property(TARGET MSManifestNone PROPERTY LINK_FLAGS "/MANIFEST:NO")
elseif(WIN32 AND CMAKE_C_COMPILER_ID MATCHES "Clang")
diff --git a/Tests/MSManifest/Subdir2/CMakeLists.txt b/Tests/MSManifest/Subdir2/CMakeLists.txt
index 0d960ad..bbc70dc 100644
--- a/Tests/MSManifest/Subdir2/CMakeLists.txt
+++ b/Tests/MSManifest/Subdir2/CMakeLists.txt
@@ -10,4 +10,14 @@ if((MSVC AND NOT MSVC_VERSION LESS 1400) OR (WIN32 AND CMAKE_C_COMPILER_ID MATCH
add_test(NAME MSManifest.Multiple COMMAND
${CMAKE_COMMAND} -Dexe=$<TARGET_FILE:MSMultipleManifest>
-P ${CMAKE_CURRENT_SOURCE_DIR}/check.cmake)
+ if(MSVC AND NOT MSVC_VERSION LESS 1400)
+ add_executable(MSMultipleManifestNonIncremental main.c
+ ${CMAKE_CURRENT_BINARY_DIR}/test_manifest1.manifest
+ ${CMAKE_CURRENT_BINARY_DIR}/test_manifest2.manifest
+ ${CMAKE_CURRENT_BINARY_DIR}/test_manifest3.manifest)
+ set_property(TARGET MSMultipleManifestNonIncremental PROPERTY LINK_FLAGS "/INCREMENTAL:NO")
+ add_test(NAME MSManifest.Multiple.NonIncremental COMMAND
+ ${CMAKE_COMMAND} -Dexe=$<TARGET_FILE:MSMultipleManifestNonIncremental>
+ -P ${CMAKE_CURRENT_SOURCE_DIR}/check.cmake)
+ endif()
endif()
diff --git a/Tests/RunCMake/GenEx-PATH/ABSOLUTE_PATH.cmake.in b/Tests/RunCMake/GenEx-PATH/ABSOLUTE_PATH.cmake.in
index cc5ff54..d1cb61b 100644
--- a/Tests/RunCMake/GenEx-PATH/ABSOLUTE_PATH.cmake.in
+++ b/Tests/RunCMake/GenEx-PATH/ABSOLUTE_PATH.cmake.in
@@ -31,4 +31,28 @@ if (NOT output STREQUAL reference)
endif()
+######################################
+## tests with list of paths
+######################################
+unset (reference)
+foreach(item IN ITEMS "../../a/d" "/a/d/../e")
+ cmake_path(ABSOLUTE_PATH item BASE_DIRECTORY "/x/y/a/f")
+ list(APPEND reference "${item}")
+endforeach()
+set(output "$<PATH:ABSOLUTE_PATH,../../a/d;/a/d/../e,/x/y/a/f>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "'${output}' instead of '${reference}'")
+endif()
+
+unset (reference)
+foreach(item IN ITEMS "../../a/d" "/a/d/../e")
+ cmake_path(ABSOLUTE_PATH item BASE_DIRECTORY "/x/y/a/f" NORMALIZE)
+ list(APPEND reference "${item}")
+endforeach()
+set(output "$<PATH:ABSOLUTE_PATH,NORMALIZE,../../a/d;/a/d/../e,/x/y/a/f>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "'${output}' instead of '${reference}'")
+endif()
+
+
check_errors("PATH:ABSOLUTE_PATH" ${errors})
diff --git a/Tests/RunCMake/GenEx-PATH/APPEND.cmake.in b/Tests/RunCMake/GenEx-PATH/APPEND.cmake.in
index ab967a2..1955480 100644
--- a/Tests/RunCMake/GenEx-PATH/APPEND.cmake.in
+++ b/Tests/RunCMake/GenEx-PATH/APPEND.cmake.in
@@ -65,4 +65,39 @@ if (WIN32)
endif()
endif()
+
+######################################
+## tests with list of paths
+######################################
+unset(reference)
+foreach(item IN ITEMS "/a/b" "/x/y")
+ cmake_path (APPEND result "${item}" "c")
+ list(APPEND reference "${result}")
+endforeach()
+set(output "$<PATH:APPEND,/a/b;/x/y,c>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "'${output}' instead of '${reference}'")
+endif()
+
+unset(reference)
+foreach(item IN ITEMS "a" "c")
+ cmake_path (APPEND item "")
+ list(APPEND reference "${item}")
+endforeach()
+set(output "$<PATH:APPEND,a;c,>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "'${output}' instead of '${reference}'")
+endif()
+
+unset(reference)
+foreach(item IN ITEMS "a/" "c/")
+ cmake_path (APPEND item "/b")
+ list(APPEND reference "${item}")
+endforeach()
+set(output "$<PATH:APPEND,a/;c/,/b>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "'${output}' instead of '${reference}'")
+endif()
+
+
check_errors ("PATH:APPEND" ${errors})
diff --git a/Tests/RunCMake/GenEx-PATH/CMAKE_PATH.cmake.in b/Tests/RunCMake/GenEx-PATH/CMAKE_PATH.cmake.in
index 41205fa..29ebf16 100644
--- a/Tests/RunCMake/GenEx-PATH/CMAKE_PATH.cmake.in
+++ b/Tests/RunCMake/GenEx-PATH/CMAKE_PATH.cmake.in
@@ -50,4 +50,46 @@ if (WIN32)
endif()
+######################################
+## tests with list of paths
+######################################
+set(reference "/x/y/z/../../a/d;/x/y/z/../../b/e")
+set(output "$<PATH:CMAKE_PATH,/x/y/z/../../a/d;/x/y/z/../../b/e>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "'${output}' instead of '${reference}'")
+endif()
+
+unset(reference)
+foreach(path IN ITEMS "/x/y/z/../../a/d" "/x/y/z/../../b/e")
+ cmake_path(SET result NORMALIZE "${path}")
+ list(APPEND reference "${result}")
+endforeach()
+set(output "$<PATH:CMAKE_PATH,NORMALIZE,/x/y/z/../../a/d;/x/y/z/../../b/e>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "'${output}' instead of '${reference}'")
+endif()
+
+if (WIN32)
+ unset(reference)
+ foreach(path IN ITEMS "/x\\y/z\\..\\../a/d" "/x\\y/z\\..\\../b/e")
+ cmake_path(SET result "${path}")
+ list(APPEND reference "${result}")
+ endforeach()
+ set(output "$<PATH:CMAKE_PATH,/x\y/z\..\../a/d;/x\y/z\..\../b/e>")
+ if (NOT output STREQUAL reference)
+ list (APPEND errors "'${output}' instead of '${reference}'")
+ endif()
+
+ unset(reference)
+ foreach(path IN ITEMS "/x\\y/z\\..\\../a/d" "/x\\y/z\\..\\../b/e")
+ cmake_path(SET result NORMALIZE "${path}")
+ list(APPEND reference "${result}")
+ endforeach()
+ set(output "$<PATH:CMAKE_PATH,NORMALIZE,/x\y/z\..\../a/d;/x\y/z\..\../b/e>")
+ if (NOT output STREQUAL reference)
+ list (APPEND errors "'${output}' instead of '${reference}'")
+ endif()
+endif()
+
+
check_errors("PATH:CMAKE_PATH" ${errors})
diff --git a/Tests/RunCMake/GenEx-PATH/CMakeLists.txt b/Tests/RunCMake/GenEx-PATH/CMakeLists.txt
index f9748e9..5161b99 100644
--- a/Tests/RunCMake/GenEx-PATH/CMakeLists.txt
+++ b/Tests/RunCMake/GenEx-PATH/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.18...3.24)
+cmake_minimum_required(VERSION 3.18...3.25)
project(${RunCMake_TEST} NONE)
diff --git a/Tests/RunCMake/GenEx-PATH/GET_ITEM.cmake.in b/Tests/RunCMake/GenEx-PATH/GET_ITEM.cmake.in
index b58998c..e2acde4 100644
--- a/Tests/RunCMake/GenEx-PATH/GET_ITEM.cmake.in
+++ b/Tests/RunCMake/GenEx-PATH/GET_ITEM.cmake.in
@@ -1,3 +1,4 @@
+cmake_policy(SET CMP0140 NEW)
include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
unset (errors)
@@ -308,4 +309,126 @@ if (NOT output STREQUAL reference)
endif()
+######################################
+## third, tests with list of paths
+######################################
+if (WIN32)
+ set (paths "C:/aa/bb/cc.ext1.ext2" "D:/xx/yy/zz.ext3.ext4")
+else()
+ set (paths "/aa/bb/cc.ext1.ext2" "/xx/yy/zz.ext3.ext4")
+endif()
+
+function (compute_reference action)
+ unset(reference)
+ foreach (path IN LISTS paths)
+ cmake_path(GET path ${ARGV} result)
+ list(APPEND reference "${result}")
+ endforeach()
+ if (reference STREQUAL "")
+ # define the list as 2 empty elements
+ set(reference ";")
+ endif()
+
+ return(PROPAGATE reference)
+endfunction()
+
+compute_reference(ROOT_NAME)
+if (WIN32)
+ set(output "$<PATH:GET_ROOT_NAME,C:/aa/bb/cc.ext1.ext2;D:/xx/yy/zz.ext3.ext4>")
+else()
+ set (output "$<PATH:GET_ROOT_NAME,/aa/bb/cc.ext1.ext2;/xx/yy/zz.ext3.ext4>")
+endif()
+if (NOT output STREQUAL reference)
+ list (APPEND errors "ROOT_NAME returns bad data: ${output}")
+endif()
+
+compute_reference(ROOT_DIRECTORY)
+if (WIN32)
+ set(output "$<PATH:GET_ROOT_DIRECTORY,C:/aa/bb/cc.ext1.ext2;D:/xx/yy/zz.ext3.ext4>")
+else()
+ set (output "$<PATH:GET_ROOT_DIRECTORY,/aa/bb/cc.ext1.ext2;/xx/yy/zz.ext3.ext4>")
+endif()
+if (NOT output STREQUAL reference)
+ list (APPEND errors "ROOT_DIRECTORY returns bad data: ${output}")
+endif()
+
+compute_reference(ROOT_PATH)
+if (WIN32)
+ set(output "$<PATH:GET_ROOT_PATH,C:/aa/bb/cc.ext1.ext2;D:/xx/yy/zz.ext3.ext4>")
+else()
+ set (output "$<PATH:GET_ROOT_PATH,/aa/bb/cc.ext1.ext2;/xx/yy/zz.ext3.ext4>")
+endif()
+if (NOT output STREQUAL reference)
+ list (APPEND errors "ROOT_PATH returns bad data: ${output}")
+endif()
+
+compute_reference(FILENAME)
+if (WIN32)
+ set(output "$<PATH:GET_FILENAME,C:/aa/bb/cc.ext1.ext2;D:/xx/yy/zz.ext3.ext4>")
+else()
+ set (output "$<PATH:GET_FILENAME,/aa/bb/cc.ext1.ext2;/xx/yy/zz.ext3.ext4>")
+endif()
+if (NOT output STREQUAL reference)
+ list (APPEND errors "FILENAME returns bad data: ${output}")
+endif()
+
+compute_reference(EXTENSION)
+if (WIN32)
+ set(output "$<PATH:GET_EXTENSION,C:/aa/bb/cc.ext1.ext2;D:/xx/yy/zz.ext3.ext4>")
+else()
+ set (output "$<PATH:GET_EXTENSION,/aa/bb/cc.ext1.ext2;/xx/yy/zz.ext3.ext4>")
+endif()
+if (NOT output STREQUAL reference)
+ list (APPEND errors "EXTENSION returns bad data: ${output}")
+endif()
+compute_reference(EXTENSION LAST_ONLY)
+if (WIN32)
+ set(output "$<PATH:GET_EXTENSION,LAST_ONLY,C:/aa/bb/cc.ext1.ext2;D:/xx/yy/zz.ext3.ext4>")
+else()
+ set (output "$<PATH:GET_EXTENSION,LAST_ONLY,/aa/bb/cc.ext1.ext2;/xx/yy/zz.ext3.ext4>")
+endif()
+if (NOT output STREQUAL reference)
+ list (APPEND errors "EXTENSION LAST_ONLY returns bad data: ${output}")
+endif()
+
+compute_reference(STEM)
+if (WIN32)
+ set(output "$<PATH:GET_STEM,C:/aa/bb/cc.ext1.ext2;D:/xx/yy/zz.ext3.ext4>")
+else()
+ set (output "$<PATH:GET_STEM,/aa/bb/cc.ext1.ext2;/xx/yy/zz.ext3.ext4>")
+endif()
+if (NOT output STREQUAL reference)
+ list (APPEND errors "STEM returns bad data: ${output}")
+endif()
+compute_reference(STEM LAST_ONLY)
+if (WIN32)
+ set(output "$<PATH:GET_STEM,LAST_ONLY,C:/aa/bb/cc.ext1.ext2;D:/xx/yy/zz.ext3.ext4>")
+else()
+ set (output "$<PATH:GET_STEM,LAST_ONLY,/aa/bb/cc.ext1.ext2;/xx/yy/zz.ext3.ext4>")
+endif()
+if (NOT output STREQUAL reference)
+ list (APPEND errors "STEM LAST_ONLY returns bad data: ${reference}")
+endif()
+
+compute_reference(RELATIVE_PART)
+if (WIN32)
+ set(output "$<PATH:GET_RELATIVE_PART,C:/aa/bb/cc.ext1.ext2;D:/xx/yy/zz.ext3.ext4>")
+else()
+ set (output "$<PATH:GET_RELATIVE_PART,/aa/bb/cc.ext1.ext2;/xx/yy/zz.ext3.ext4>")
+endif()
+if (NOT output STREQUAL reference)
+ list (APPEND errors "RELATIVE_PART returns bad data: ${output}")
+endif()
+
+compute_reference(PARENT_PATH)
+if (WIN32)
+ set(output "$<PATH:GET_PARENT_PATH,C:/aa/bb/cc.ext1.ext2;D:/xx/yy/zz.ext3.ext4>")
+else()
+ set (output "$<PATH:GET_PARENT_PATH,/aa/bb/cc.ext1.ext2;/xx/yy/zz.ext3.ext4>")
+endif()
+if (NOT output STREQUAL reference)
+ list (APPEND errors "PARENT_PATH returns bad data: ${output}")
+endif()
+
+
check_errors("PATH:GET..." ${errors})
diff --git a/Tests/RunCMake/GenEx-PATH/NORMAL_PATH.cmake.in b/Tests/RunCMake/GenEx-PATH/NORMAL_PATH.cmake.in
index e6cc4a3..81e4c0d 100644
--- a/Tests/RunCMake/GenEx-PATH/NORMAL_PATH.cmake.in
+++ b/Tests/RunCMake/GenEx-PATH/NORMAL_PATH.cmake.in
@@ -40,4 +40,18 @@ if (WIN32)
endif()
+######################################
+## tests with list of paths
+######################################
+unset (reference)
+foreach(item IN ITEMS "a/./b/.." "x/.//y/z//..")
+ cmake_path(NORMAL_PATH item)
+ list(APPEND reference "${item}")
+endforeach()
+set(output "$<PATH:NORMAL_PATH,a/./b/..;x/.//y/z//..>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "'${output}' instead of '${reference}'")
+endif()
+
+
check_errors("PATH:NORMAL_PATH" ${errors})
diff --git a/Tests/RunCMake/GenEx-PATH/RELATIVE_PATH.cmake.in b/Tests/RunCMake/GenEx-PATH/RELATIVE_PATH.cmake.in
index 11d73ad..7670f4f 100644
--- a/Tests/RunCMake/GenEx-PATH/RELATIVE_PATH.cmake.in
+++ b/Tests/RunCMake/GenEx-PATH/RELATIVE_PATH.cmake.in
@@ -61,4 +61,18 @@ if (WIN32)
endif()
+######################################
+## tests with list of paths
+######################################
+unset (reference)
+foreach(item IN ITEMS "/a//d" "/a/b/e")
+ cmake_path(RELATIVE_PATH item BASE_DIRECTORY "/a/b/c")
+ list(APPEND reference "${item}")
+endforeach()
+set(output "$<PATH:RELATIVE_PATH,/a//d;/a/b/e,/a/b/c>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "'${output}' instead of '${reference}'")
+endif()
+
+
check_errors("PATH:RELATIVE_PATH" ${errors})
diff --git a/Tests/RunCMake/GenEx-PATH/REMOVE_ITEM.cmake.in b/Tests/RunCMake/GenEx-PATH/REMOVE_ITEM.cmake.in
index cce4143..a365efe 100644
--- a/Tests/RunCMake/GenEx-PATH/REMOVE_ITEM.cmake.in
+++ b/Tests/RunCMake/GenEx-PATH/REMOVE_ITEM.cmake.in
@@ -1,3 +1,4 @@
+cmake_policy(SET CMP0140 NEW)
include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
unset (errors)
@@ -62,4 +63,39 @@ if (NOT output STREQUAL reference)
endif()
+######################################
+## tests with list of paths
+######################################
+function (compute_reference action)
+ unset(reference)
+ foreach (path IN LISTS paths)
+ cmake_path(${action} path ${ARGN})
+ list(APPEND reference "${path}")
+ endforeach()
+
+ return(PROPAGATE reference)
+endfunction()
+
+set (paths "a/b/c.e.f" "g/h/i.j.k")
+compute_reference(REMOVE_FILENAME)
+set(output "$<PATH:REMOVE_FILENAME,a/b/c.e.f;g/h/i.j.k>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "FILENAME: '${output}' instead of '${reference}'")
+endif()
+
+set (paths "a/b/c.e.f" "g/h/i.j.k")
+compute_reference(REMOVE_EXTENSION)
+set(output "$<PATH:REMOVE_EXTENSION,a/b/c.e.f;g/h/i.j.k>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "EXTENSION: '${output}' instead of '${reference}'")
+endif()
+
+set (reference "a/b/c.e.f" "g/h/i.j.k")
+compute_reference(REMOVE_EXTENSION LAST_ONLY)
+set(output "$<PATH:REMOVE_EXTENSION,LAST_ONLY,a/b/c.e.f;g/h/i.j.k>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "EXTENSION: '${output}' instead of '${reference}'")
+endif()
+
+
check_errors("PATH:REMOVE..." ${errors})
diff --git a/Tests/RunCMake/GenEx-PATH/REPLACE_ITEM.cmake.in b/Tests/RunCMake/GenEx-PATH/REPLACE_ITEM.cmake.in
index 5bb04c3..2d02152 100644
--- a/Tests/RunCMake/GenEx-PATH/REPLACE_ITEM.cmake.in
+++ b/Tests/RunCMake/GenEx-PATH/REPLACE_ITEM.cmake.in
@@ -1,3 +1,4 @@
+cmake_policy(SET CMP0140 NEW)
include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
unset (errors)
@@ -70,4 +71,39 @@ if (NOT output STREQUAL reference)
endif()
+######################################
+## tests with list of paths
+######################################
+function (compute_reference action new_value)
+ unset(reference)
+ foreach (path IN LISTS paths)
+ cmake_path(${action} path "${new_value}" ${ARGN})
+ list(APPEND reference "${path}")
+ endforeach()
+
+ return(PROPAGATE reference)
+endfunction()
+
+set (paths "a/b/c.e.f" "g/h/i.j.k")
+compute_reference(REPLACE_FILENAME "x.y")
+set(output "$<PATH:REPLACE_FILENAME,a/b/c.e.f;g/h/i.j.k,x.y>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "FILENAME: '${output}' instead of '${reference}'")
+endif()
+
+set (paths "a/b/c.e.f" "g/h/i.j.k")
+compute_reference(REPLACE_EXTENSION ".x")
+set(output "$<PATH:REPLACE_EXTENSION,a/b/c.e.f;g/h/i.j.k,.x>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "EXTENSION: '${output}' instead of '${reference}'")
+endif()
+
+set (paths "a/b/c.e.f" "g/h/i.j.k")
+compute_reference(REPLACE_EXTENSION ".x" LAST_ONLY)
+set(output "$<PATH:REPLACE_EXTENSION,LAST_ONLY,a/b/c.e.f;g/h/i.j.k,.x>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "EXTENSION: '${output}' instead of '${reference}'")
+endif()
+
+
check_errors("PATH:REPLACE..." ${errors})
diff --git a/Tests/RunCMake/GenerateExportHeader/GEH.cmake b/Tests/RunCMake/GenerateExportHeader/GEH.cmake
index bf9c302..3e35aa3 100644
--- a/Tests/RunCMake/GenerateExportHeader/GEH.cmake
+++ b/Tests/RunCMake/GenerateExportHeader/GEH.cmake
@@ -100,7 +100,9 @@ if (WIN32 OR CYGWIN)
set(_platform Win32-Clang)
elseif(MSVC AND COMPILER_HAS_DEPRECATED)
set(_platform Win32)
- elseif((MINGW OR CYGWIN) AND COMPILER_HAS_DEPRECATED)
+ elseif(CYGWIN AND COMPILER_HAS_DEPRECATED)
+ set(_platform Cygwin)
+ elseif(MINGW AND COMPILER_HAS_DEPRECATED)
set(_platform MinGW)
else()
set(_platform WinEmpty)
diff --git a/Tests/RunCMake/GenerateExportHeader/reference/Cygwin/libshared_export.h b/Tests/RunCMake/GenerateExportHeader/reference/Cygwin/libshared_export.h
new file mode 100644
index 0000000..dac4fda
--- /dev/null
+++ b/Tests/RunCMake/GenerateExportHeader/reference/Cygwin/libshared_export.h
@@ -0,0 +1,42 @@
+
+#ifndef LIBSHARED_EXPORT_H
+#define LIBSHARED_EXPORT_H
+
+#ifdef LIBSHARED_STATIC_DEFINE
+# define LIBSHARED_EXPORT
+# define LIBSHARED_NO_EXPORT
+#else
+# ifndef LIBSHARED_EXPORT
+# ifdef libshared_EXPORTS
+ /* We are building this library */
+# define LIBSHARED_EXPORT __declspec(dllexport)
+# else
+ /* We are using this library */
+# define LIBSHARED_EXPORT __declspec(dllimport)
+# endif
+# endif
+
+# ifndef LIBSHARED_NO_EXPORT
+# define LIBSHARED_NO_EXPORT
+# endif
+#endif
+
+#ifndef LIBSHARED_DEPRECATED
+# define LIBSHARED_DEPRECATED __attribute__ ((__deprecated__))
+#endif
+
+#ifndef LIBSHARED_DEPRECATED_EXPORT
+# define LIBSHARED_DEPRECATED_EXPORT LIBSHARED_EXPORT LIBSHARED_DEPRECATED
+#endif
+
+#ifndef LIBSHARED_DEPRECATED_NO_EXPORT
+# define LIBSHARED_DEPRECATED_NO_EXPORT LIBSHARED_NO_EXPORT LIBSHARED_DEPRECATED
+#endif
+
+#if 0 /* DEFINE_NO_DEPRECATED */
+# ifndef LIBSHARED_NO_DEPRECATED
+# define LIBSHARED_NO_DEPRECATED
+# endif
+#endif
+
+#endif /* LIBSHARED_EXPORT_H */
diff --git a/Tests/RunCMake/GenerateExportHeader/reference/Cygwin/libstatic_export.h b/Tests/RunCMake/GenerateExportHeader/reference/Cygwin/libstatic_export.h
new file mode 100644
index 0000000..b6e2a4a
--- /dev/null
+++ b/Tests/RunCMake/GenerateExportHeader/reference/Cygwin/libstatic_export.h
@@ -0,0 +1,42 @@
+
+#ifndef LIBSTATIC_EXPORT_H
+#define LIBSTATIC_EXPORT_H
+
+#ifdef LIBSTATIC_STATIC_DEFINE
+# define LIBSTATIC_EXPORT
+# define LIBSTATIC_NO_EXPORT
+#else
+# ifndef LIBSTATIC_EXPORT
+# ifdef libstatic_EXPORTS
+ /* We are building this library */
+# define LIBSTATIC_EXPORT
+# else
+ /* We are using this library */
+# define LIBSTATIC_EXPORT
+# endif
+# endif
+
+# ifndef LIBSTATIC_NO_EXPORT
+# define LIBSTATIC_NO_EXPORT
+# endif
+#endif
+
+#ifndef LIBSTATIC_DEPRECATED
+# define LIBSTATIC_DEPRECATED __attribute__ ((__deprecated__))
+#endif
+
+#ifndef LIBSTATIC_DEPRECATED_EXPORT
+# define LIBSTATIC_DEPRECATED_EXPORT LIBSTATIC_EXPORT LIBSTATIC_DEPRECATED
+#endif
+
+#ifndef LIBSTATIC_DEPRECATED_NO_EXPORT
+# define LIBSTATIC_DEPRECATED_NO_EXPORT LIBSTATIC_NO_EXPORT LIBSTATIC_DEPRECATED
+#endif
+
+#if 0 /* DEFINE_NO_DEPRECATED */
+# ifndef LIBSTATIC_NO_DEPRECATED
+# define LIBSTATIC_NO_DEPRECATED
+# endif
+#endif
+
+#endif /* LIBSTATIC_EXPORT_H */
diff --git a/Tests/RunCMake/GenerateExportHeader/reference/MinGW/libshared_export.h b/Tests/RunCMake/GenerateExportHeader/reference/MinGW/libshared_export.h
index dac4fda..3ba2d2e 100644
--- a/Tests/RunCMake/GenerateExportHeader/reference/MinGW/libshared_export.h
+++ b/Tests/RunCMake/GenerateExportHeader/reference/MinGW/libshared_export.h
@@ -22,7 +22,7 @@
#endif
#ifndef LIBSHARED_DEPRECATED
-# define LIBSHARED_DEPRECATED __attribute__ ((__deprecated__))
+# define LIBSHARED_DEPRECATED __declspec(deprecated)
#endif
#ifndef LIBSHARED_DEPRECATED_EXPORT
diff --git a/Tests/RunCMake/GenerateExportHeader/reference/MinGW/libstatic_export.h b/Tests/RunCMake/GenerateExportHeader/reference/MinGW/libstatic_export.h
index b6e2a4a..3c7e093 100644
--- a/Tests/RunCMake/GenerateExportHeader/reference/MinGW/libstatic_export.h
+++ b/Tests/RunCMake/GenerateExportHeader/reference/MinGW/libstatic_export.h
@@ -22,7 +22,7 @@
#endif
#ifndef LIBSTATIC_DEPRECATED
-# define LIBSTATIC_DEPRECATED __attribute__ ((__deprecated__))
+# define LIBSTATIC_DEPRECATED __declspec(deprecated)
#endif
#ifndef LIBSTATIC_DEPRECATED_EXPORT
diff --git a/Tests/RunCMake/GenerateExportHeader/reference/Win32-Clang/libshared_export.h b/Tests/RunCMake/GenerateExportHeader/reference/Win32-Clang/libshared_export.h
index dac4fda..3ba2d2e 100644
--- a/Tests/RunCMake/GenerateExportHeader/reference/Win32-Clang/libshared_export.h
+++ b/Tests/RunCMake/GenerateExportHeader/reference/Win32-Clang/libshared_export.h
@@ -22,7 +22,7 @@
#endif
#ifndef LIBSHARED_DEPRECATED
-# define LIBSHARED_DEPRECATED __attribute__ ((__deprecated__))
+# define LIBSHARED_DEPRECATED __declspec(deprecated)
#endif
#ifndef LIBSHARED_DEPRECATED_EXPORT
diff --git a/Tests/RunCMake/GenerateExportHeader/reference/Win32-Clang/libstatic_export.h b/Tests/RunCMake/GenerateExportHeader/reference/Win32-Clang/libstatic_export.h
index b6e2a4a..3c7e093 100644
--- a/Tests/RunCMake/GenerateExportHeader/reference/Win32-Clang/libstatic_export.h
+++ b/Tests/RunCMake/GenerateExportHeader/reference/Win32-Clang/libstatic_export.h
@@ -22,7 +22,7 @@
#endif
#ifndef LIBSTATIC_DEPRECATED
-# define LIBSTATIC_DEPRECATED __attribute__ ((__deprecated__))
+# define LIBSTATIC_DEPRECATED __declspec(deprecated)
#endif
#ifndef LIBSTATIC_DEPRECATED_EXPORT
diff --git a/Tests/RunCMake/find_package/CMP0144-NEW-CaseInsensitive-stderr.txt b/Tests/RunCMake/find_package/CMP0144-NEW-CaseInsensitive-stderr.txt
new file mode 100644
index 0000000..3ccd101
--- /dev/null
+++ b/Tests/RunCMake/find_package/CMP0144-NEW-CaseInsensitive-stderr.txt
@@ -0,0 +1,45 @@
+^----------
+FOO_ROOT : ''
+ENV{FOO_ROOT}: ''
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------
+FOO_ROOT : '<base>/foo/cmake_root'
+ENV{FOO_ROOT}: '<base>/foo/env_root'
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: <base>/foo/cmake_root/include/foo.h
+FOO_TEST_FILE_ZOT: <base>/foo/cmake_root/include/zot/zot.h
+FOO_TEST_PATH_FOO: <base>/foo/cmake_root/include
+FOO_TEST_PATH_ZOT: <base>/foo/cmake_root/include/zot
+FOO_TEST_PROG_FOO: <base>/foo/cmake_root/bin/foo.exe
+
+----------
+FOO_ROOT : '<base>/foo/cmake_root'
+ENV{FOO_ROOT}: ''
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: <base>/foo/cmake_root/include/foo.h
+FOO_TEST_FILE_ZOT: <base>/foo/cmake_root/include/zot/zot.h
+FOO_TEST_PATH_FOO: <base>/foo/cmake_root/include
+FOO_TEST_PATH_ZOT: <base>/foo/cmake_root/include/zot
+FOO_TEST_PROG_FOO: <base>/foo/cmake_root/bin/foo.exe
+
+----------
+FOO_ROOT : ''
+ENV{FOO_ROOT}: '<base>/foo/env_root'
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: <base>/foo/env_root/include/foo.h
+FOO_TEST_FILE_ZOT: <base>/foo/env_root/include/zot/zot.h
+FOO_TEST_PATH_FOO: <base>/foo/env_root/include
+FOO_TEST_PATH_ZOT: <base>/foo/env_root/include/zot
+FOO_TEST_PROG_FOO: <base>/foo/env_root/bin/foo.exe
+
+----------$
diff --git a/Tests/RunCMake/find_package/CMP0144-NEW-CaseInsensitive.cmake b/Tests/RunCMake/find_package/CMP0144-NEW-CaseInsensitive.cmake
new file mode 100644
index 0000000..f0853ee
--- /dev/null
+++ b/Tests/RunCMake/find_package/CMP0144-NEW-CaseInsensitive.cmake
@@ -0,0 +1,3 @@
+cmake_policy(VERSION 3.26)
+cmake_policy(SET CMP0144 NEW)
+include(CMP0144-common.cmake)
diff --git a/Tests/RunCMake/find_package/CMP0144-NEW-CaseSensitive-stderr.txt b/Tests/RunCMake/find_package/CMP0144-NEW-CaseSensitive-stderr.txt
new file mode 100644
index 0000000..3ccd101
--- /dev/null
+++ b/Tests/RunCMake/find_package/CMP0144-NEW-CaseSensitive-stderr.txt
@@ -0,0 +1,45 @@
+^----------
+FOO_ROOT : ''
+ENV{FOO_ROOT}: ''
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------
+FOO_ROOT : '<base>/foo/cmake_root'
+ENV{FOO_ROOT}: '<base>/foo/env_root'
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: <base>/foo/cmake_root/include/foo.h
+FOO_TEST_FILE_ZOT: <base>/foo/cmake_root/include/zot/zot.h
+FOO_TEST_PATH_FOO: <base>/foo/cmake_root/include
+FOO_TEST_PATH_ZOT: <base>/foo/cmake_root/include/zot
+FOO_TEST_PROG_FOO: <base>/foo/cmake_root/bin/foo.exe
+
+----------
+FOO_ROOT : '<base>/foo/cmake_root'
+ENV{FOO_ROOT}: ''
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: <base>/foo/cmake_root/include/foo.h
+FOO_TEST_FILE_ZOT: <base>/foo/cmake_root/include/zot/zot.h
+FOO_TEST_PATH_FOO: <base>/foo/cmake_root/include
+FOO_TEST_PATH_ZOT: <base>/foo/cmake_root/include/zot
+FOO_TEST_PROG_FOO: <base>/foo/cmake_root/bin/foo.exe
+
+----------
+FOO_ROOT : ''
+ENV{FOO_ROOT}: '<base>/foo/env_root'
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: <base>/foo/env_root/include/foo.h
+FOO_TEST_FILE_ZOT: <base>/foo/env_root/include/zot/zot.h
+FOO_TEST_PATH_FOO: <base>/foo/env_root/include
+FOO_TEST_PATH_ZOT: <base>/foo/env_root/include/zot
+FOO_TEST_PROG_FOO: <base>/foo/env_root/bin/foo.exe
+
+----------$
diff --git a/Tests/RunCMake/find_package/CMP0144-NEW-CaseSensitive.cmake b/Tests/RunCMake/find_package/CMP0144-NEW-CaseSensitive.cmake
new file mode 100644
index 0000000..f0853ee
--- /dev/null
+++ b/Tests/RunCMake/find_package/CMP0144-NEW-CaseSensitive.cmake
@@ -0,0 +1,3 @@
+cmake_policy(VERSION 3.26)
+cmake_policy(SET CMP0144 NEW)
+include(CMP0144-common.cmake)
diff --git a/Tests/RunCMake/find_package/CMP0144-OLD-CaseInsensitive-stderr.txt b/Tests/RunCMake/find_package/CMP0144-OLD-CaseInsensitive-stderr.txt
new file mode 100644
index 0000000..3274b82
--- /dev/null
+++ b/Tests/RunCMake/find_package/CMP0144-OLD-CaseInsensitive-stderr.txt
@@ -0,0 +1,45 @@
+^----------
+FOO_ROOT : ''
+ENV{FOO_ROOT}: ''
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------
+FOO_ROOT : '<base>/foo/cmake_root'
+ENV{FOO_ROOT}: '<base>/foo/env_root'
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: <base>/foo/env_root/include/foo.h
+FOO_TEST_FILE_ZOT: <base>/foo/env_root/include/zot/zot.h
+FOO_TEST_PATH_FOO: <base>/foo/env_root/include
+FOO_TEST_PATH_ZOT: <base>/foo/env_root/include/zot
+FOO_TEST_PROG_FOO: <base>/foo/env_root/bin/foo.exe
+
+----------
+FOO_ROOT : '<base>/foo/cmake_root'
+ENV{FOO_ROOT}: ''
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------
+FOO_ROOT : ''
+ENV{FOO_ROOT}: '<base>/foo/env_root'
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: <base>/foo/env_root/include/foo.h
+FOO_TEST_FILE_ZOT: <base>/foo/env_root/include/zot/zot.h
+FOO_TEST_PATH_FOO: <base>/foo/env_root/include
+FOO_TEST_PATH_ZOT: <base>/foo/env_root/include/zot
+FOO_TEST_PROG_FOO: <base>/foo/env_root/bin/foo.exe
+
+----------$
diff --git a/Tests/RunCMake/find_package/CMP0144-OLD-CaseInsensitive.cmake b/Tests/RunCMake/find_package/CMP0144-OLD-CaseInsensitive.cmake
new file mode 100644
index 0000000..f1560a9
--- /dev/null
+++ b/Tests/RunCMake/find_package/CMP0144-OLD-CaseInsensitive.cmake
@@ -0,0 +1,3 @@
+cmake_policy(VERSION 3.26)
+cmake_policy(SET CMP0144 OLD)
+include(CMP0144-common.cmake)
diff --git a/Tests/RunCMake/find_package/CMP0144-OLD-CaseSensitive-stderr.txt b/Tests/RunCMake/find_package/CMP0144-OLD-CaseSensitive-stderr.txt
new file mode 100644
index 0000000..c02a797
--- /dev/null
+++ b/Tests/RunCMake/find_package/CMP0144-OLD-CaseSensitive-stderr.txt
@@ -0,0 +1,45 @@
+^----------
+FOO_ROOT : ''
+ENV{FOO_ROOT}: ''
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------
+FOO_ROOT : '<base>/foo/cmake_root'
+ENV{FOO_ROOT}: '<base>/foo/env_root'
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------
+FOO_ROOT : '<base>/foo/cmake_root'
+ENV{FOO_ROOT}: ''
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------
+FOO_ROOT : ''
+ENV{FOO_ROOT}: '<base>/foo/env_root'
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------$
diff --git a/Tests/RunCMake/find_package/CMP0144-OLD-CaseSensitive.cmake b/Tests/RunCMake/find_package/CMP0144-OLD-CaseSensitive.cmake
new file mode 100644
index 0000000..f1560a9
--- /dev/null
+++ b/Tests/RunCMake/find_package/CMP0144-OLD-CaseSensitive.cmake
@@ -0,0 +1,3 @@
+cmake_policy(VERSION 3.26)
+cmake_policy(SET CMP0144 OLD)
+include(CMP0144-common.cmake)
diff --git a/Tests/RunCMake/find_package/CMP0144-WARN-CaseInsensitive-stderr.txt b/Tests/RunCMake/find_package/CMP0144-WARN-CaseInsensitive-stderr.txt
new file mode 100644
index 0000000..3540dc9
--- /dev/null
+++ b/Tests/RunCMake/find_package/CMP0144-WARN-CaseInsensitive-stderr.txt
@@ -0,0 +1,63 @@
+^----------
+FOO_ROOT : ''
+ENV{FOO_ROOT}: ''
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------
+FOO_ROOT : '<base>/foo/cmake_root'
+ENV{FOO_ROOT}: '<base>/foo/env_root'
++
+CMake Warning \(dev\) at CMP0144-common.cmake:[0-9]+ \(find_package\):
+ Policy CMP0144 is not set: find_package uses upper-case <PACKAGENAME>_ROOT
+ variables. Run "cmake --help-policy CMP0144" for policy details\. Use the
+ cmake_policy command to set the policy and suppress this warning\.
+
+ CMake variable FOO_ROOT is set to:
+
+ [^
+]*/Tests/RunCMake/find_package/PackageRoot/foo/cmake_root
+
+ For compatibility, find_package is ignoring the variable, but code in a
+ \.cmake module might still use it\.
+Call Stack \(most recent call first\):
+ CMP0144-common.cmake:[0-9]+ \(RunTestCase\)
+ CMP0144-WARN-CaseInsensitive.cmake:[0-9]+ \(include\)
+ CMakeLists.txt:[0-9]+ \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
++
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: <base>/foo/env_root/include/foo.h
+FOO_TEST_FILE_ZOT: <base>/foo/env_root/include/zot/zot.h
+FOO_TEST_PATH_FOO: <base>/foo/env_root/include
+FOO_TEST_PATH_ZOT: <base>/foo/env_root/include/zot
+FOO_TEST_PROG_FOO: <base>/foo/env_root/bin/foo.exe
+
+----------
+FOO_ROOT : '<base>/foo/cmake_root'
+ENV{FOO_ROOT}: ''
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------
+FOO_ROOT : ''
+ENV{FOO_ROOT}: '<base>/foo/env_root'
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: <base>/foo/env_root/include/foo.h
+FOO_TEST_FILE_ZOT: <base>/foo/env_root/include/zot/zot.h
+FOO_TEST_PATH_FOO: <base>/foo/env_root/include
+FOO_TEST_PATH_ZOT: <base>/foo/env_root/include/zot
+FOO_TEST_PROG_FOO: <base>/foo/env_root/bin/foo.exe
+
+----------$
diff --git a/Tests/RunCMake/find_package/CMP0144-WARN-CaseInsensitive.cmake b/Tests/RunCMake/find_package/CMP0144-WARN-CaseInsensitive.cmake
new file mode 100644
index 0000000..10f6b66
--- /dev/null
+++ b/Tests/RunCMake/find_package/CMP0144-WARN-CaseInsensitive.cmake
@@ -0,0 +1,3 @@
+cmake_policy(VERSION 3.26)
+# (do not set CMP0144)
+include(CMP0144-common.cmake)
diff --git a/Tests/RunCMake/find_package/CMP0144-WARN-CaseSensitive-Mixed-stderr.txt b/Tests/RunCMake/find_package/CMP0144-WARN-CaseSensitive-Mixed-stderr.txt
new file mode 100644
index 0000000..3ccd101
--- /dev/null
+++ b/Tests/RunCMake/find_package/CMP0144-WARN-CaseSensitive-Mixed-stderr.txt
@@ -0,0 +1,45 @@
+^----------
+FOO_ROOT : ''
+ENV{FOO_ROOT}: ''
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------
+FOO_ROOT : '<base>/foo/cmake_root'
+ENV{FOO_ROOT}: '<base>/foo/env_root'
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: <base>/foo/cmake_root/include/foo.h
+FOO_TEST_FILE_ZOT: <base>/foo/cmake_root/include/zot/zot.h
+FOO_TEST_PATH_FOO: <base>/foo/cmake_root/include
+FOO_TEST_PATH_ZOT: <base>/foo/cmake_root/include/zot
+FOO_TEST_PROG_FOO: <base>/foo/cmake_root/bin/foo.exe
+
+----------
+FOO_ROOT : '<base>/foo/cmake_root'
+ENV{FOO_ROOT}: ''
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: <base>/foo/cmake_root/include/foo.h
+FOO_TEST_FILE_ZOT: <base>/foo/cmake_root/include/zot/zot.h
+FOO_TEST_PATH_FOO: <base>/foo/cmake_root/include
+FOO_TEST_PATH_ZOT: <base>/foo/cmake_root/include/zot
+FOO_TEST_PROG_FOO: <base>/foo/cmake_root/bin/foo.exe
+
+----------
+FOO_ROOT : ''
+ENV{FOO_ROOT}: '<base>/foo/env_root'
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: <base>/foo/env_root/include/foo.h
+FOO_TEST_FILE_ZOT: <base>/foo/env_root/include/zot/zot.h
+FOO_TEST_PATH_FOO: <base>/foo/env_root/include
+FOO_TEST_PATH_ZOT: <base>/foo/env_root/include/zot
+FOO_TEST_PROG_FOO: <base>/foo/env_root/bin/foo.exe
+
+----------$
diff --git a/Tests/RunCMake/find_package/CMP0144-WARN-CaseSensitive-Mixed.cmake b/Tests/RunCMake/find_package/CMP0144-WARN-CaseSensitive-Mixed.cmake
new file mode 100644
index 0000000..10f6b66
--- /dev/null
+++ b/Tests/RunCMake/find_package/CMP0144-WARN-CaseSensitive-Mixed.cmake
@@ -0,0 +1,3 @@
+cmake_policy(VERSION 3.26)
+# (do not set CMP0144)
+include(CMP0144-common.cmake)
diff --git a/Tests/RunCMake/find_package/CMP0144-WARN-CaseSensitive-stderr.txt b/Tests/RunCMake/find_package/CMP0144-WARN-CaseSensitive-stderr.txt
new file mode 100644
index 0000000..b828f05
--- /dev/null
+++ b/Tests/RunCMake/find_package/CMP0144-WARN-CaseSensitive-stderr.txt
@@ -0,0 +1,68 @@
+^----------
+FOO_ROOT : ''
+ENV{FOO_ROOT}: ''
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------
+FOO_ROOT : '<base>/foo/cmake_root'
+ENV{FOO_ROOT}: '<base>/foo/env_root'
++
+CMake Warning \(dev\) at CMP0144-common.cmake:[0-9]+ \(find_package\):
+ Policy CMP0144 is not set: find_package uses upper-case <PACKAGENAME>_ROOT
+ variables. Run "cmake --help-policy CMP0144" for policy details\. Use the
+ cmake_policy command to set the policy and suppress this warning\.
+
+ CMake variable FOO_ROOT is set to:
+
+ [^
+]*/Tests/RunCMake/find_package/PackageRoot/foo/cmake_root
+
+ Environment variable FOO_ROOT is set to:
+
+ [^
+]*/Tests/RunCMake/find_package/PackageRoot/foo/env_root
+
+ For compatibility, find_package is ignoring the variable, but code in a
+ \.cmake module might still use it\.
+Call Stack \(most recent call first\):
+ CMP0144-common.cmake:[0-9]+ \(RunTestCase\)
+ CMP0144-WARN-CaseSensitive.cmake:[0-9]+ \(include\)
+ CMakeLists.txt:[0-9]+ \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
++
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------
+FOO_ROOT : '<base>/foo/cmake_root'
+ENV{FOO_ROOT}: ''
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------
+FOO_ROOT : ''
+ENV{FOO_ROOT}: '<base>/foo/env_root'
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------$
diff --git a/Tests/RunCMake/find_package/CMP0144-WARN-CaseSensitive.cmake b/Tests/RunCMake/find_package/CMP0144-WARN-CaseSensitive.cmake
new file mode 100644
index 0000000..10f6b66
--- /dev/null
+++ b/Tests/RunCMake/find_package/CMP0144-WARN-CaseSensitive.cmake
@@ -0,0 +1,3 @@
+cmake_policy(VERSION 3.26)
+# (do not set CMP0144)
+include(CMP0144-common.cmake)
diff --git a/Tests/RunCMake/find_package/CMP0144-common.cmake b/Tests/RunCMake/find_package/CMP0144-common.cmake
new file mode 100644
index 0000000..58eccca
--- /dev/null
+++ b/Tests/RunCMake/find_package/CMP0144-common.cmake
@@ -0,0 +1,78 @@
+# (includer selects CMP0144)
+list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_CURRENT_SOURCE_DIR}/PackageRoot)
+set(PackageRoot_BASE ${CMAKE_CURRENT_SOURCE_DIR}/PackageRoot)
+
+function(PrintPath label path)
+ string(REPLACE "${PackageRoot_BASE}" "<base>" out "${path}")
+ message("${label} ${out}")
+endfunction()
+
+macro(RunTestCase)
+ message("----------")
+ PrintPath("FOO_ROOT :" "'${FOO_ROOT}'")
+ PrintPath("ENV{FOO_ROOT}:" "'$ENV{FOO_ROOT}'")
+ message("")
+
+ find_package(Foo)
+ message("find_package(Foo)")
+ PrintPath("FOO_TEST_FILE_FOO:" "${FOO_TEST_FILE_FOO}")
+ PrintPath("FOO_TEST_FILE_ZOT:" "${FOO_TEST_FILE_ZOT}")
+ PrintPath("FOO_TEST_PATH_FOO:" "${FOO_TEST_PATH_FOO}")
+ PrintPath("FOO_TEST_PATH_ZOT:" "${FOO_TEST_PATH_ZOT}")
+ PrintPath("FOO_TEST_PROG_FOO:" "${FOO_TEST_PROG_FOO}")
+ message("")
+
+ unset(FOO_ROOT)
+ unset(ENV{FOO_ROOT})
+ if(NOT CMAKE_HOST_WIN32)
+ unset(Foo_ROOT)
+ unset(ENV{Foo_ROOT})
+ endif()
+ unset(FOO_TEST_FILE_FOO)
+ unset(FOO_TEST_FILE_ZOT)
+ unset(FOO_TEST_PATH_FOO)
+ unset(FOO_TEST_PATH_ZOT)
+ unset(FOO_TEST_PROG_FOO)
+ unset(FOO_TEST_FILE_FOO CACHE)
+ unset(FOO_TEST_FILE_ZOT CACHE)
+ unset(FOO_TEST_PATH_FOO CACHE)
+ unset(FOO_TEST_PATH_ZOT CACHE)
+ unset(FOO_TEST_PROG_FOO CACHE)
+endmacro()
+
+RunTestCase()
+
+set(FOO_ROOT ${PackageRoot_BASE}/foo/cmake_root)
+set(ENV{FOO_ROOT} ${PackageRoot_BASE}/foo/env_root)
+if(RunCMake_TEST MATCHES "CaseSensitive")
+ if(RunCMake_TEST STREQUAL "CMP0144-WARN-CaseSensitive-Mixed")
+ set(Foo_ROOT "${FOO_ROOT}")
+ set(ENV{Foo_ROOT} "$ENV{FOO_ROOT}")
+ else()
+ set(Foo_ROOT ${PackageRoot_BASE}/does_not_exist)
+ set(ENV{Foo_ROOT} ${PackageRoot_BASE}/does_not_exist)
+ endif()
+endif()
+RunTestCase()
+
+set(FOO_ROOT ${PackageRoot_BASE}/foo/cmake_root)
+if(RunCMake_TEST MATCHES "CaseSensitive")
+ if(RunCMake_TEST STREQUAL "CMP0144-WARN-CaseSensitive-Mixed")
+ set(Foo_ROOT "${FOO_ROOT}")
+ else()
+ set(Foo_ROOT ${PackageRoot_BASE}/does_not_exist)
+ endif()
+endif()
+RunTestCase()
+
+set(ENV{FOO_ROOT} ${PackageRoot_BASE}/foo/env_root)
+if(RunCMake_TEST MATCHES "CaseSensitive")
+ if(RunCMake_TEST STREQUAL "CMP0144-WARN-CaseSensitive-Mixed")
+ set(ENV{Foo_ROOT} "$ENV{FOO_ROOT}")
+ else()
+ set(ENV{Foo_ROOT} ${PackageRoot_BASE}/does_not_exist)
+ endif()
+endif()
+RunTestCase()
+
+message("----------")
diff --git a/Tests/RunCMake/find_package/RunCMakeTest.cmake b/Tests/RunCMake/find_package/RunCMakeTest.cmake
index fa41fc1..e7e3a0b 100644
--- a/Tests/RunCMake/find_package/RunCMakeTest.cmake
+++ b/Tests/RunCMake/find_package/RunCMakeTest.cmake
@@ -55,6 +55,17 @@ run_cmake(REGISTRY_VIEW-no-view)
run_cmake(REGISTRY_VIEW-wrong-view)
run_cmake(REGISTRY_VIEW-propagated)
+if(CMAKE_HOST_WIN32)
+ run_cmake(CMP0144-WARN-CaseInsensitive)
+ run_cmake(CMP0144-OLD-CaseInsensitive)
+ run_cmake(CMP0144-NEW-CaseInsensitive)
+else()
+ run_cmake(CMP0144-WARN-CaseSensitive)
+ run_cmake(CMP0144-WARN-CaseSensitive-Mixed)
+ run_cmake(CMP0144-OLD-CaseSensitive)
+ run_cmake(CMP0144-NEW-CaseSensitive)
+endif()
+
file(
GLOB SearchPaths_TEST_CASE_LIST
LIST_DIRECTORIES TRUE