summaryrefslogtreecommitdiff
path: root/Help
diff options
context:
space:
mode:
authorMarkus Ferrell <markus.ferrell@kitware.com>2022-08-26 13:42:16 -0400
committerMarkus Ferrell <markus.ferrell@kitware.com>2022-09-28 11:38:28 -0400
commit37fceb6fd382bcfb85860b6b288bfc323e4f4ab7 (patch)
tree82a5fa19b78ebc814ca9d4464661b0ee717871f9 /Help
parent9b1b9b9aae371acb9d18b481d45bcaec2d312e27 (diff)
downloadcmake-37fceb6fd382bcfb85860b6b288bfc323e4f4ab7.tar.gz
Tutorial: Update step 4 style
Diffstat (limited to 'Help')
-rw-r--r--Help/guide/tutorial/Adding Generator Expressions.rst285
-rw-r--r--Help/guide/tutorial/Adding Usage Requirements for a Library.rst1
-rw-r--r--Help/guide/tutorial/Step10/MathFunctions/CMakeLists.txt1
-rw-r--r--Help/guide/tutorial/Step4/CMakeLists.txt26
-rw-r--r--Help/guide/tutorial/Step4/MathFunctions/CMakeLists.txt2
-rw-r--r--Help/guide/tutorial/Step5/MathFunctions/CMakeLists.txt1
-rw-r--r--Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt1
-rw-r--r--Help/guide/tutorial/Step7/MathFunctions/CMakeLists.txt1
-rw-r--r--Help/guide/tutorial/Step8/MathFunctions/CMakeLists.txt1
-rw-r--r--Help/guide/tutorial/Step9/MathFunctions/CMakeLists.txt1
10 files changed, 288 insertions, 32 deletions
diff --git a/Help/guide/tutorial/Adding Generator Expressions.rst b/Help/guide/tutorial/Adding Generator Expressions.rst
index 0efce8d3bd..ba728bd35a 100644
--- a/Help/guide/tutorial/Adding Generator Expressions.rst
+++ b/Help/guide/tutorial/Adding Generator Expressions.rst
@@ -27,58 +27,279 @@ expressions are the ``0`` and ``1`` expressions. A ``$<0:...>`` results in the
empty string, and ``<1:...>`` results in the content of ``...``. They can also
be nested.
-A common usage of
-:manual:`generator expressions <cmake-generator-expressions(7)>` is to
-conditionally add compiler flags, such as those for language levels or
-warnings. A nice pattern is to associate this information to an ``INTERFACE``
-target allowing this information to propagate. Let's start by constructing an
-``INTERFACE`` target and specifying the required C++ standard level of ``11``
-instead of using :variable:`CMAKE_CXX_STANDARD`.
+Exercise 1 - Setting the C++ Standard with Interface Libraries
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Before we use :manual:`generator expressions <cmake-generator-expressions(7)>`
+let's refactor our existing code to use an ``INTERFACE`` library. We will
+use that library in the next step to demonstrate a common use for
+:manual:`generator expressions <cmake-generator-expressions(7)>`.
+
+Goal
+----
+
+Add an ``INTERFACE`` library target to specify the required C++ standard.
+
+Helpful Resources
+-----------------
+
+* :command:`add_library`
+* :command:`target_compile_features`
+* :command:`target_link_libraries`
+
+Files to Edit
+-------------
+
+* ``CMakeLists.txt``
+* ``MathFunctions/CMakeLists.txt``
+
+Getting Started
+---------------
+
+In this exercise, we will refactor our code to use an ``INTERFACE`` library to
+specify the C++ standard.
+
+The starting source code is provided in the ``Step4`` directory. In this
+exercise, complete ``TODO 1`` through ``TODO 3``.
+
+Start by editing the top level ``CMakeLists.txt`` file. Construct an
+``INTERFACE`` library target called ``tutorial_compiler_flags`` and
+specify ``cxx_std_11`` as a target compiler feature.
+
+Modify ``CMakeLists.txt`` and ``MathFunctions/CMakeLists.txt`` so that all
+targets have a :command:`target_link_libraries` call to
+``tutorial_compiler_flags``.
+
+Build and Run
+-------------
+
+Make a new directory called ``Step4_build``, run the :manual:`cmake <cmake(1)>`
+executable or the :manual:`cmake-gui <cmake-gui(1)>` to configure the project
+and then build it with your chosen build tool or by using ``cmake --build .``
+from the build directory.
+
+Here's a refresher of what that looks like from the command line:
+
+.. code-block:: console
+
+ mkdir Step4_build
+ cd Step4_build
+ cmake ../Step4
+ cmake --build .
+
+Next, use the newly built ``Tutorial`` and verify that it is working as
+expected.
+
+Solution
+--------
+
+Let's update our code from the previous step to use interface libraries
+to set our C++ requirements.
-So the following code:
+To start, we need to remove the two :command:`set` calls on the variables
+:variable:`CMAKE_CXX_STANDARD` and :variable:`CMAKE_CXX_STANDARD_REQUIRED`.
+The specific lines to remove are as follows:
.. literalinclude:: Step4/CMakeLists.txt
:caption: CMakeLists.txt
:name: CMakeLists.txt-CXX_STANDARD-variable-remove
:language: cmake
- :start-after: project(Tutorial VERSION 1.0)
- :end-before: # should we use our own math functions
+ :start-after: # specify the C++ standard
+ :end-before: # TODO 5: Create helper variables
+
+Next, we need to create an interface library, ``tutorial_compiler_flags``. And
+then use :command:`target_compile_features` to add the compiler feature
+``cxx_std_11``.
+
-Would be replaced with:
+.. raw:: html
+
+ <details><summary>TODO 1: Click to show/hide answer</summary>
.. literalinclude:: Step5/CMakeLists.txt
- :caption: CMakeLists.txt
+ :caption: TODO 1: CMakeLists.txt
:name: CMakeLists.txt-cxx_std-feature
:language: cmake
- :start-after: project(Tutorial VERSION 1.0)
- :end-before: # add compiler warning flags just when building this project via
+ :start-after: # specify the C++ standard
+ :end-before: # add compiler warning flags just
+
+.. raw:: html
+
+ </details>
+
+Finally, with our interface library set up, we need to link our
+executable ``Target`` and our ``MathFunctions`` library to our new
+``tutorial_compiler_flags`` library. Respectively, the code will look like
+this:
+
+.. raw:: html
+
+ <details><summary>TODO 2: Click to show/hide answer</summary>
+
+.. literalinclude:: Step5/CMakeLists.txt
+ :caption: TODO 2: CMakeLists.txt
+ :name: CMakeLists.txt-target_link_libraries-step4
+ :language: cmake
+ :start-after: add_executable(Tutorial tutorial.cxx)
+ :end-before: # add the binary tree to the search path for include file
+
+.. raw:: html
+
+ </details>
+
+and this:
+
+.. raw:: html
+
+ <details><summary>TODO 3: Click to show/hide answer</summary>
+
+.. literalinclude:: Step5/MathFunctions/CMakeLists.txt
+ :caption: TODO 3: MathFunctions/CMakeLists.txt
+ :name: MathFunctions-CMakeLists.txt-target_link_libraries-step4
+ :language: cmake
+ :start-after: # link our compiler flags interface library
+
+.. raw:: html
+
+ </details>
+
+With this, all of our code still requires C++ 11 to build. Notice
+though that with this method, it gives us the ability to be specific about
+which targets get specific requirements. In addition, we create a single
+source of truth in our interface library.
+
+Exercise 2 - Adding Compiler Warning Flags with Generator Expressions
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+A common usage of
+:manual:`generator expressions <cmake-generator-expressions(7)>` is to
+conditionally add compiler flags, such as those for language levels or
+warnings. A nice pattern is to associate this information to an ``INTERFACE``
+target allowing this information to propagate.
+
+Goal
+----
+
+Add compiler warning flags when building but not for installed versions.
+
+Helpful Resources
+-----------------
+
+* :manual:`cmake-generator-expressions(7)`
+* :command:`cmake_minimum_required`
+* :command:`set`
+* :command:`target_compile_options`
+
+Files to Edit
+-------------
+
+* ``CMakeLists.txt``
+
+Getting Started
+---------------
+
+Start with the resulting files from Exercise 1. Complete ``TODO 4`` through
+``TODO 7``.
+
+First, in the top level ``CMakeLists.txt`` file, we need to set the
+:command:`cmake_minimum_required` to ``3.15``. In this exercise we are going
+to use a generator expression which was introduced in CMake 3.15.
+
+Next we add the desired compiler warning flags that we want for our project.
+As warning flags vary based on the compiler, we use the
+``COMPILE_LANG_AND_ID`` generator expression to control which flags to apply
+given a language and a set of compiler ids.
+
+Build and Run
+-------------
+
+Since we have our build directory already configured from Exercise 1, simply
+rebuild our code by calling the following:
+
+.. code-block:: console
+
+ cd Step4_build
+ cmake --build .
+
+Solution
+--------
+
+Update the :command:`cmake_minimum_required` to require at least CMake
+version ``3.15``:
+
+.. raw:: html
+
+ <details><summary>TODO 4: Click to show/hide answer</summary>
+
+.. literalinclude:: Step5/CMakeLists.txt
+ :caption: TODO 4: CMakeLists.txt
+ :name: MathFunctions-CMakeLists.txt-minimum-required-step4
+ :language: cmake
+ :end-before: # set the project name and version
+
+.. raw:: html
+
+ </details>
+
+Next we determine which compiler our system is currently using to build
+since warning flags vary based on the compiler we use. This is done with
+the ``COMPILE_LANG_AND_ID`` generator expression. We set the result in the
+variables ``gcc_like_cxx`` and ``msvc_cxx`` as follows:
+
+.. raw:: html
+
+ <details><summary>TODO 5: Click to show/hide answer</summary>
+
+.. literalinclude:: Step5/CMakeLists.txt
+ :caption: TODO 5: CMakeLists.txt
+ :name: CMakeLists.txt-compile_lang_and_id
+ :language: cmake
+ :start-after: # the BUILD_INTERFACE genex
+ :end-before: target_compile_options(tutorial_compiler_flags INTERFACE
-**Note**: This upcoming section will require a change to the
-:command:`cmake_minimum_required` usage in the code. The Generator Expression
-that is about to be used was introduced in `3.15`. Update the call to require
-that more recent version:
+.. raw:: html
+
+ </details>
+
+Next we add the desired compiler warning flags that we want for our project.
+Using our variables ``gcc_like_cxx`` and ``msvc_cxx``, we can use another
+generator expression to apply the respective flags only when the variables are
+true. We use :command:`target_compile_options` to apply these flags to our
+interface library.
+
+.. raw:: html
+
+ <details><summary>TODO 6: Click to show/hide answer</summary>
.. code-block:: cmake
- :caption: CMakeLists.txt
- :name: CMakeLists.txt-version-update
+ :caption: TODO 6: CMakeLists.txt
+ :name: CMakeLists.txt-compile_flags
+
+ target_compile_options(tutorial_compiler_flags INTERFACE
+ "$<${gcc_like_cxx}:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>"
+ "$<${msvc_cxx}:-W3>"
+ )
- cmake_minimum_required(VERSION 3.15)
+.. raw:: html
-Next we add the desired compiler warning flags that we want for our project. As
-warning flags vary based on the compiler we use the ``COMPILE_LANG_AND_ID``
-generator expression to control which flags to apply given a language and a set
-of compiler ids as seen below:
+ </details>
+
+Lastly, we only want these warning flags to be used during builds. Consumers
+of our installed project should not inherit our warning flags. To specify
+this, we wrap our flags in a generator expression using the ``BUILD_INTERFACE``
+condition. The resulting full code looks like the following:
+
+.. raw:: html
+
+ <details><summary>TODO 7: Click to show/hide answer</summary>
.. literalinclude:: Step5/CMakeLists.txt
- :caption: CMakeLists.txt
+ :caption: TODO 7: CMakeLists.txt
:name: CMakeLists.txt-target_compile_options-genex
:language: cmake
- :start-after: # the BUILD_INTERFACE genex
+ :start-after: set(msvc_cxx "$<COMPILE_LANG_AND_ID:CXX,MSVC>")
:end-before: # should we use our own math functions
-Looking at this we see that the warning flags are encapsulated inside a
-``BUILD_INTERFACE`` condition. This is done so that consumers of our installed
-project will not inherit our warning flags.
+.. raw:: html
-**Exercise**: Modify ``MathFunctions/CMakeLists.txt`` so that all targets have
-a :command:`target_link_libraries` call to ``tutorial_compiler_flags``.
+ </details>
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 b521896e90..aeb47c74db 100644
--- a/Help/guide/tutorial/Adding Usage Requirements for a Library.rst
+++ b/Help/guide/tutorial/Adding Usage Requirements for a Library.rst
@@ -96,6 +96,7 @@ follows:
:name: MathFunctions/CMakeLists.txt-target_include_directories-INTERFACE
:language: cmake
:start-after: # to find MathFunctions.h
+ :end-before: # TODO 3: Link to
.. raw:: html
diff --git a/Help/guide/tutorial/Step10/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step10/MathFunctions/CMakeLists.txt
index 746f966b0a..d7f30d64c8 100644
--- a/Help/guide/tutorial/Step10/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step10/MathFunctions/CMakeLists.txt
@@ -22,6 +22,7 @@ target_include_directories(MathFunctions
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
)
+# link our compiler flags interface library
target_link_libraries(MathFunctions tutorial_compiler_flags)
# install rules
diff --git a/Help/guide/tutorial/Step4/CMakeLists.txt b/Help/guide/tutorial/Step4/CMakeLists.txt
index 38e9b1f72c..fa4aab270b 100644
--- a/Help/guide/tutorial/Step4/CMakeLists.txt
+++ b/Help/guide/tutorial/Step4/CMakeLists.txt
@@ -1,12 +1,36 @@
+# TODO 4: Update the minimum required version to 3.15
+
cmake_minimum_required(VERSION 3.10)
# set the project name and version
project(Tutorial VERSION 1.0)
+# TODO 1: Replace the following code by:
+# * Creating an interface library called tutorial_compiler_flags
+# Hint: use add_library() with the INTERFACE signature
+# * Add compiler feature cxx_std_11 to tutorial_compiler_flags
+# Hint: Use target_compile_features()
+
# specify the C++ standard
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
+# TODO 5: Create helper variables to determine which compiler we are using:
+# * Create a new variable gcc_like_cxx that is true if we are using CXX and
+# any of the following compilers: ARMClang, AppleClang, Clang, GNU, LCC
+# * Create a new variable msvc_cxx that is true if we are using CXX and MSVC
+# Hint: Use set() and COMPILE_LANG_AND_ID
+
+# TODO 6: Add warning flag compile options to the interface library
+# tutorial_compiler_flags.
+# * For gcc_like_cxx, add flags -Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused
+# * For msvc_cxx, add flags -W3
+# Hint: Use target_compile_options()
+
+# TODO 7: With nested generator expressions, only use the flags for the
+# build-tree
+# Hint: Use BUILD_INTERFACE
+
# should we use our own math functions
option(USE_MYMATH "Use tutorial provided math implementation" ON)
@@ -23,6 +47,8 @@ endif()
# add the executable
add_executable(Tutorial tutorial.cxx)
+# TODO 2: Link to tutorial_compiler_flags
+
target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS})
# add the binary tree to the search path for include files
diff --git a/Help/guide/tutorial/Step4/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step4/MathFunctions/CMakeLists.txt
index 0515852a0c..5f7369cae7 100644
--- a/Help/guide/tutorial/Step4/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step4/MathFunctions/CMakeLists.txt
@@ -5,3 +5,5 @@ add_library(MathFunctions mysqrt.cxx)
target_include_directories(MathFunctions
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
)
+
+# TODO 3: Link to tutorial_compiler_flags
diff --git a/Help/guide/tutorial/Step5/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step5/MathFunctions/CMakeLists.txt
index e02f21168c..fc932afec8 100644
--- a/Help/guide/tutorial/Step5/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step5/MathFunctions/CMakeLists.txt
@@ -6,4 +6,5 @@ target_include_directories(MathFunctions
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
)
+# link our compiler flags interface library
target_link_libraries(MathFunctions tutorial_compiler_flags)
diff --git a/Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt
index 226099a966..e7667abb19 100644
--- a/Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt
@@ -6,6 +6,7 @@ target_include_directories(MathFunctions
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
)
+# link our compiler flags interface library
target_link_libraries(MathFunctions tutorial_compiler_flags)
# install rules
diff --git a/Help/guide/tutorial/Step7/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step7/MathFunctions/CMakeLists.txt
index 226099a966..e7667abb19 100644
--- a/Help/guide/tutorial/Step7/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step7/MathFunctions/CMakeLists.txt
@@ -6,6 +6,7 @@ target_include_directories(MathFunctions
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
)
+# link our compiler flags interface library
target_link_libraries(MathFunctions tutorial_compiler_flags)
# install rules
diff --git a/Help/guide/tutorial/Step8/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step8/MathFunctions/CMakeLists.txt
index a832003919..4a19684924 100644
--- a/Help/guide/tutorial/Step8/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step8/MathFunctions/CMakeLists.txt
@@ -6,6 +6,7 @@ target_include_directories(MathFunctions
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?
diff --git a/Help/guide/tutorial/Step9/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step9/MathFunctions/CMakeLists.txt
index 8a08157bc5..6a1a108f00 100644
--- a/Help/guide/tutorial/Step9/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step9/MathFunctions/CMakeLists.txt
@@ -24,6 +24,7 @@ target_include_directories(MathFunctions
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
)
+# link our compiler flags interface library
target_link_libraries(MathFunctions tutorial_compiler_flags)
# install rules