summaryrefslogtreecommitdiff
path: root/Help/guide/tutorial/Adding Usage Requirements for a Library.rst
diff options
context:
space:
mode:
Diffstat (limited to 'Help/guide/tutorial/Adding Usage Requirements for a Library.rst')
-rw-r--r--Help/guide/tutorial/Adding Usage Requirements for a Library.rst188
1 files changed, 182 insertions, 6 deletions
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 74b7496688..227306393e 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: option
+ :end-before: # should we use our own
.. raw:: html
@@ -108,24 +108,26 @@ follows:
Now that we've specified usage requirements for ``MathFunctions`` we can
safely remove our uses of the ``EXTRA_INCLUDES`` variable from the top-level
-``CMakeLists.txt``, here:
+``CMakeLists.txt``.
+
+Remove this line:
.. raw:: html
<details><summary>TODO 2: Click to show/hide answer</summary>
-.. literalinclude:: Step4/CMakeLists.txt
+.. literalinclude:: Step3/CMakeLists.txt
:caption: TODO 2: CMakeLists.txt
:name: CMakeLists.txt-remove-EXTRA_INCLUDES
:language: cmake
- :start-after: # add the MathFunctions library
- :end-before: # TODO 2: Link to tutorial_compiler_flags
+ :start-after: add_subdirectory(MathFunctions)
+ :end-before: # add the executable
.. raw:: html
</details>
-And here:
+And the lines:
.. raw:: html
@@ -141,7 +143,181 @@ And here:
</details>
+The remaining code looks like:
+
+.. raw:: html
+
+ <details><summary>Click to show/hide the resulting code</summary>
+
+.. literalinclude:: Step4/CMakeLists.txt
+ :caption: Remaining code after removing EXTRA_INCLUDES
+ :name: CMakeLists.txt-after-removing-EXTRA_INCLUDES
+ :language: cmake
+ :start-after: add_subdirectory(MathFunctions)
+
+.. raw:: html
+
+ </details>
+
+
Notice that with this technique, the only thing our executable target does to
use our library is call :command:`target_link_libraries` with the name
of the library target. In larger projects, the classic method of specifying
library dependencies manually becomes very complicated very quickly.
+
+Exercise 2 - Setting the C++ Standard with Interface Libraries
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Now that we have switched our code to a more modern approach, let's demonstrate
+a modern technique to set properties to multiple targets.
+
+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.
+
+Start this exercise from what we left at the end of Step3 exercise 1. You will
+have to complete ``TODO 4`` through ``TODO 7``.
+
+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
+-------------
+
+Since we have our build directory already configured from Exercise 1, simply
+rebuild our code by calling the following:
+
+.. code-block:: console
+
+ cd Step3_build
+ 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.
+
+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:: Step3/CMakeLists.txt
+ :caption: CMakeLists.txt
+ :name: CMakeLists.txt-CXX_STANDARD-variable-remove
+ :language: cmake
+ :start-after: # specify the C++ standard
+ :end-before: # configure a header file
+
+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``.
+
+
+.. raw:: html
+
+ <details><summary>TODO 4: Click to show/hide answer</summary>
+
+.. literalinclude:: Step4/CMakeLists.txt
+ :caption: TODO 4: CMakeLists.txt
+ :name: CMakeLists.txt-cxx_std-feature
+ :language: cmake
+ :start-after: # specify the C++ standard
+ :end-before: # TODO 2: Create helper
+
+.. raw:: html
+
+ </details>
+
+Finally, with our interface library set up, we need to link our
+executable ``Target``, our ``MathFunctions`` library, and our ``SqrtLibrary``
+library to our new
+``tutorial_compiler_flags`` library. Respectively, the code will look like
+this:
+
+.. raw:: html
+
+ <details><summary>TODO 5: Click to show/hide answer</summary>
+
+.. literalinclude:: Step4/CMakeLists.txt
+ :caption: TODO 5: 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>
+
+this:
+
+.. raw:: html
+
+ <details><summary>TODO 6: Click to show/hide answer</summary>
+
+.. literalinclude:: Step4/MathFunctions/CMakeLists.txt
+ :caption: TODO 6: MathFunctions/CMakeLists.txt
+ :name: MathFunctions-CMakeLists.txt-target_link_libraries-step4
+ :language: cmake
+ :start-after: # link our compiler flags interface library
+ :end-before: target_link_libraries(MathFunctions
+
+.. raw:: html
+
+ </details>
+
+and this:
+
+.. raw:: html
+
+ <details><summary>TODO 7: Click to show/hide answer</summary>
+
+.. literalinclude:: Step4/MathFunctions/CMakeLists.txt
+ :caption: TODO 7: MathFunctions/CMakeLists.txt
+ :name: MathFunctions-SqrtLibrary-target_link_libraries-step4
+ :language: cmake
+ :start-after: target_link_libraries(SqrtLibrary
+ :end-before: endif()
+
+.. 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.