From 8406d4c1d1d0371c933b6d142b1cd4522c289f83 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 16 Jun 2021 11:58:48 -0400 Subject: Utilities/Sphinx: Index guide section documents for cross-referencing Extend the change from commit 6185265800 (Utilities/Sphinx: Index guide-level documents for cross-referencing, 2019-12-06, v3.17.0-rc1~181^2~1) to name guide documents other than the top level using their docname instead of their title. This will allow them to be cross-referenced by a stable name even if their title changes. --- Utilities/Sphinx/cmake.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Utilities/Sphinx/cmake.py b/Utilities/Sphinx/cmake.py index 9fa56cd..9215e14 100644 --- a/Utilities/Sphinx/cmake.py +++ b/Utilities/Sphinx/cmake.py @@ -260,6 +260,8 @@ class CMakeTransform(Transform): # Insert the object link target. if objtype == 'command': targetname = title.lower() + elif objtype == 'guide' and not tail.endswith('/index'): + targetname = tail else: if objtype == 'genex': m = CMakeXRefRole._re_genex.match(title) @@ -312,6 +314,7 @@ class CMakeXRefRole(XRefRole): _re = re.compile(r'^(.+?)(\s*)(?$', re.DOTALL) _re_sub = re.compile(r'^([^()\s]+)\s*\(([^()]*)\)$', re.DOTALL) _re_genex = re.compile(r'^\$<([^<>:]+)(:[^<>]+)?>$', re.DOTALL) + _re_guide = re.compile(r'^([^<>/]+)/([^<>]*)$', re.DOTALL) def __call__(self, typ, rawtext, text, *args, **keys): # Translate CMake command cross-references of the form: @@ -326,6 +329,10 @@ class CMakeXRefRole(XRefRole): m = CMakeXRefRole._re_genex.match(text) if m: text = '%s <%s>' % (text, m.group(1)) + elif typ == 'cmake:guide': + m = CMakeXRefRole._re_guide.match(text) + if m: + text = '%s <%s>' % (m.group(2), text) # CMake cross-reference targets frequently contain '<' so escape # any explicit `` with '<' not preceded by whitespace. while True: @@ -369,6 +376,10 @@ class CMakeXRefTransform(Transform): continue objname = ref['reftarget'] + if objtype == 'guide' and CMakeXRefRole._re_guide.match(objname): + # Do not index cross-references to guide sections. + continue + targetnum = env.new_serialno('index-%s:%s' % (objtype, objname)) targetid = 'index-%s-%s:%s' % (targetnum, objtype, objname) -- cgit v0.12 From 13fdb263231598df2cec0fb7bc9515f1f56b5577 Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 17 Jun 2021 10:33:07 -0400 Subject: Tutorial: Break up intro paragraph --- Help/guide/tutorial/index.rst | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Help/guide/tutorial/index.rst b/Help/guide/tutorial/index.rst index 94753d5..7cdd844 100644 --- a/Help/guide/tutorial/index.rst +++ b/Help/guide/tutorial/index.rst @@ -10,12 +10,13 @@ Introduction The CMake tutorial provides a step-by-step guide that covers common build system issues that CMake helps address. Seeing how various topics all -work together in an example project can be very helpful. The tutorial -documentation and source code for examples can be found in the -``Help/guide/tutorial`` directory of the CMake source code tree. Each step has -its own subdirectory containing code that may be used as a starting point. The -tutorial examples are progressive so that each step provides the complete -solution for the previous step. +work together in an example project can be very helpful. + +The tutorial documentation and source code for examples can be found in +the ``Help/guide/tutorial`` directory of the CMake source code tree. +Each step has its own subdirectory containing code that may be used as a +starting point. The tutorial examples are progressive so that each step +provides the complete solution for the previous step. A Basic Starting Point (Step 1) =============================== -- cgit v0.12 From d1c3e7e78af0b3a4a5637e2bf3af86cfa5ba6e6f Mon Sep 17 00:00:00 2001 From: Josef Angstenberger Date: Thu, 10 Jun 2021 23:03:40 +0200 Subject: Tutorial: Split steps into separate files Fixes: #21737 --- Help/guide/tutorial/A Basic Starting Point.rst | 135 +++ .../guide/tutorial/Adding Export Configuration.rst | 88 ++ .../tutorial/Adding Generator Expressions.rst | 69 ++ .../Adding Support for a Testing Dashboard.rst | 51 ++ .../guide/tutorial/Adding System Introspection.rst | 50 ++ .../Adding Usage Requirements for a Library.rst | 46 + .../Adding a Custom Command and Generated File.rst | 75 ++ Help/guide/tutorial/Adding a Library.rst | 116 +++ Help/guide/tutorial/Installing and Testing.rst | 85 ++ .../guide/tutorial/Packaging Debug and Release.rst | 78 ++ Help/guide/tutorial/Packaging an Installer.rst | 55 ++ .../Selecting Static or Shared Libraries.rst | 66 ++ Help/guide/tutorial/index.rst | 949 +-------------------- 13 files changed, 932 insertions(+), 931 deletions(-) create mode 100644 Help/guide/tutorial/A Basic Starting Point.rst create mode 100644 Help/guide/tutorial/Adding Export Configuration.rst create mode 100644 Help/guide/tutorial/Adding Generator Expressions.rst create mode 100644 Help/guide/tutorial/Adding Support for a Testing Dashboard.rst create mode 100644 Help/guide/tutorial/Adding System Introspection.rst create mode 100644 Help/guide/tutorial/Adding Usage Requirements for a Library.rst create mode 100644 Help/guide/tutorial/Adding a Custom Command and Generated File.rst create mode 100644 Help/guide/tutorial/Adding a Library.rst create mode 100644 Help/guide/tutorial/Installing and Testing.rst create mode 100644 Help/guide/tutorial/Packaging Debug and Release.rst create mode 100644 Help/guide/tutorial/Packaging an Installer.rst create mode 100644 Help/guide/tutorial/Selecting Static or Shared Libraries.rst diff --git a/Help/guide/tutorial/A Basic Starting Point.rst b/Help/guide/tutorial/A Basic Starting Point.rst new file mode 100644 index 0000000..296b3c3 --- /dev/null +++ b/Help/guide/tutorial/A Basic Starting Point.rst @@ -0,0 +1,135 @@ +Step 1: A Basic Starting Point +============================== + +The most basic project is an executable built from source code files. +For simple projects, a three line ``CMakeLists.txt`` file is all that is +required. This will be the starting point for our tutorial. Create a +``CMakeLists.txt`` file in the ``Step1`` directory that looks like: + +.. code-block:: cmake + + cmake_minimum_required(VERSION 3.10) + + # set the project name + project(Tutorial) + + # add the executable + add_executable(Tutorial tutorial.cxx) + + +Note that this example uses lower case commands in the ``CMakeLists.txt`` file. +Upper, lower, and mixed case commands are supported by CMake. The source +code for ``tutorial.cxx`` is provided in the ``Step1`` directory and can be +used to compute the square root of a number. + +Adding a Version Number and Configured Header File +-------------------------------------------------- + +The first feature we will add is to provide our executable and project with a +version number. While we could do this exclusively in the source code, using +``CMakeLists.txt`` provides more flexibility. + +First, modify the ``CMakeLists.txt`` file to use the :command:`project` command +to set the project name and version number. + +.. literalinclude:: Step2/CMakeLists.txt + :language: cmake + :end-before: # specify the C++ standard + +Then, configure a header file to pass the version number to the source +code: + +.. literalinclude:: Step2/CMakeLists.txt + :language: cmake + :start-after: # to the source code + :end-before: # add the executable + +Since the configured file will be written into the binary tree, we +must add that directory to the list of paths to search for include +files. Add the following lines to the end of the ``CMakeLists.txt`` file: + +.. literalinclude:: Step2/CMakeLists.txt + :language: cmake + :start-after: # so that we will find TutorialConfig.h + +Using your favorite editor, create ``TutorialConfig.h.in`` in the source +directory with the following contents: + +.. literalinclude:: Step2/TutorialConfig.h.in + :language: cmake + +When CMake configures this header file the values for +``@Tutorial_VERSION_MAJOR@`` and ``@Tutorial_VERSION_MINOR@`` will be +replaced. + +Next modify ``tutorial.cxx`` to include the configured header file, +``TutorialConfig.h``. + +Finally, let's print out the executable name and version number by updating +``tutorial.cxx`` as follows: + +.. literalinclude:: Step2/tutorial.cxx + :language: c++ + :start-after: { + :end-before: // convert input to double + +Specify the C++ Standard +------------------------- + +Next let's add some C++11 features to our project by replacing ``atof`` with +``std::stod`` in ``tutorial.cxx``. At the same time, remove +``#include ``. + +.. literalinclude:: Step2/tutorial.cxx + :language: c++ + :start-after: // convert input to double + :end-before: // calculate square root + +We will need to explicitly state in the CMake code that it should use the +correct flags. The easiest way to enable support for a specific C++ standard +in CMake is by using the :variable:`CMAKE_CXX_STANDARD` variable. For this +tutorial, set the :variable:`CMAKE_CXX_STANDARD` variable in the +``CMakeLists.txt`` file to 11 and :variable:`CMAKE_CXX_STANDARD_REQUIRED` to +True. Make sure to add the ``CMAKE_CXX_STANDARD`` declarations above the call +to ``add_executable``. + +.. literalinclude:: Step2/CMakeLists.txt + :language: cmake + :end-before: # configure a header file to pass some of the CMake settings + +Build and Test +-------------- + +Run the :manual:`cmake ` executable or the +:manual:`cmake-gui ` to configure the project and then build it +with your chosen build tool. + +For example, from the command line we could navigate to the +``Help/guide/tutorial`` directory of the CMake source code tree and create a +build directory: + +.. code-block:: console + + mkdir Step1_build + +Next, navigate to the build directory and run CMake to configure the project +and generate a native build system: + +.. code-block:: console + + cd Step1_build + cmake ../Step1 + +Then call that build system to actually compile/link the project: + +.. code-block:: console + + cmake --build . + +Finally, try to use the newly built ``Tutorial`` with these commands: + +.. code-block:: console + + Tutorial 4294967296 + Tutorial 10 + Tutorial diff --git a/Help/guide/tutorial/Adding Export Configuration.rst b/Help/guide/tutorial/Adding Export Configuration.rst new file mode 100644 index 0000000..55cb3e2 --- /dev/null +++ b/Help/guide/tutorial/Adding Export Configuration.rst @@ -0,0 +1,88 @@ +Step 11: Adding Export Configuration +==================================== + +During `Installing and Testing (Step 4)`_ of the tutorial we added the ability +for CMake to install the library and headers of the project. During +`Building an Installer (Step 7)`_ we added the ability to package up this +information so it could be distributed to other people. + +The next step is to add the necessary information so that other CMake projects +can use our project, be it from a build directory, a local install or when +packaged. + +The first step is to update our :command:`install(TARGETS)` commands to not +only specify a ``DESTINATION`` but also an ``EXPORT``. The ``EXPORT`` keyword +generates and installs a CMake file containing code to import all targets +listed in the install command from the installation tree. So let's go ahead and +explicitly ``EXPORT`` the MathFunctions library by updating the ``install`` +command in ``MathFunctions/CMakeLists.txt`` to look like: + +.. literalinclude:: Complete/MathFunctions/CMakeLists.txt + :language: cmake + :start-after: # install rules + +Now that we have MathFunctions being exported, we also need to explicitly +install the generated ``MathFunctionsTargets.cmake`` file. This is done by +adding the following to the bottom of the top-level ``CMakeLists.txt``: + +.. literalinclude:: Complete/CMakeLists.txt + :language: cmake + :start-after: # install the configuration targets + :end-before: include(CMakePackageConfigHelpers) + +At this point you should try and run CMake. If everything is setup properly +you will see that CMake will generate an error that looks like: + +.. code-block:: console + + Target "MathFunctions" INTERFACE_INCLUDE_DIRECTORIES property contains + path: + + "/Users/robert/Documents/CMakeClass/Tutorial/Step11/MathFunctions" + + which is prefixed in the source directory. + +What CMake is trying to say is that during generating the export information +it will export a path that is intrinsically tied to the current machine and +will not be valid on other machines. The solution to this is to update the +MathFunctions :command:`target_include_directories` to understand that it needs +different ``INTERFACE`` locations when being used from within the build +directory and from an install / package. This means converting the +:command:`target_include_directories` call for MathFunctions to look like: + +.. literalinclude:: Step12/MathFunctions/CMakeLists.txt + :language: cmake + :start-after: # to find MathFunctions.h, while we don't. + :end-before: # should we use our own math functions + +Once this has been updated, we can re-run CMake and verify that it doesn't +warn anymore. + +At this point, we have CMake properly packaging the target information that is +required but we will still need to generate a ``MathFunctionsConfig.cmake`` so +that the CMake :command:`find_package` command can find our project. So let's go +ahead and add a new file to the top-level of the project called +``Config.cmake.in`` with the following contents: + +.. literalinclude:: Step12/Config.cmake.in + +Then, to properly configure and install that file, add the following to the +bottom of the top-level ``CMakeLists.txt``: + +.. literalinclude:: Step12/CMakeLists.txt + :language: cmake + :start-after: # install the configuration targets + :end-before: # generate the export + +At this point, we have generated a relocatable CMake Configuration for our +project that can be used after the project has been installed or packaged. If +we want our project to also be used from a build directory we only have to add +the following to the bottom of the top level ``CMakeLists.txt``: + +.. literalinclude:: Step12/CMakeLists.txt + :language: cmake + :start-after: # needs to be after the install(TARGETS ) command + +With this export call we now generate a ``Targets.cmake``, allowing the +configured ``MathFunctionsConfig.cmake`` in the build directory to be used by +other projects, without needing it to be installed. diff --git a/Help/guide/tutorial/Adding Generator Expressions.rst b/Help/guide/tutorial/Adding Generator Expressions.rst new file mode 100644 index 0000000..7a3abb1 --- /dev/null +++ b/Help/guide/tutorial/Adding Generator Expressions.rst @@ -0,0 +1,69 @@ +Step 10: Adding Generator Expressions +===================================== + +:manual:`Generator expressions ` are evaluated +during build system generation to produce information specific to each build +configuration. + +:manual:`Generator expressions ` are allowed in +the context of many target properties, such as :prop_tgt:`LINK_LIBRARIES`, +:prop_tgt:`INCLUDE_DIRECTORIES`, :prop_tgt:`COMPILE_DEFINITIONS` and others. +They may also be used when using commands to populate those properties, such as +:command:`target_link_libraries`, :command:`target_include_directories`, +:command:`target_compile_definitions` and others. + +:manual:`Generator expressions ` may be used +to enable conditional linking, conditional definitions used when compiling, +conditional include directories and more. The conditions may be based on the +build configuration, target properties, platform information or any other +queryable information. + +There are different types of +:manual:`generator expressions ` including +Logical, Informational, and Output expressions. + +Logical expressions are used to create conditional output. The basic +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 ` 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`. + +So the following code: + +.. literalinclude:: Step10/CMakeLists.txt + :language: cmake + :start-after: project(Tutorial VERSION 1.0) + :end-before: # control where the static and shared libraries are built so that on windows + +Would be replaced with: + +.. literalinclude:: Step11/CMakeLists.txt + :language: cmake + :start-after: project(Tutorial VERSION 1.0) + :end-before: # add compiler warning flags just when building this project via + + +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: + +.. literalinclude:: Step11/CMakeLists.txt + :language: cmake + :start-after: # the BUILD_INTERFACE genex + :end-before: # control where the static and shared libraries are built so that on windows + +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. + + +**Exercise**: Modify ``MathFunctions/CMakeLists.txt`` so that all targets have +a :command:`target_link_libraries` call to ``tutorial_compiler_flags``. diff --git a/Help/guide/tutorial/Adding Support for a Testing Dashboard.rst b/Help/guide/tutorial/Adding Support for a Testing Dashboard.rst new file mode 100644 index 0000000..41b772c --- /dev/null +++ b/Help/guide/tutorial/Adding Support for a Testing Dashboard.rst @@ -0,0 +1,51 @@ +Step 8: Adding Support for a Testing Dashboard +============================================== + +Adding support for submitting our test results to a dashboard is simple. We +already defined a number of tests for our project in `Testing Support`_. Now we +just have to run those tests and submit them to a dashboard. To include support +for dashboards we include the :module:`CTest` module in our top-level +``CMakeLists.txt``. + +Replace: + +.. code-block:: cmake + + # enable testing + enable_testing() + +With: + +.. code-block:: cmake + + # enable dashboard scripting + include(CTest) + +The :module:`CTest` module will automatically call ``enable_testing()``, so we +can remove it from our CMake files. + +We will also need to create a ``CTestConfig.cmake`` file in the top-level +directory where we can specify the name of the project and where to submit the +dashboard. + +.. literalinclude:: Step9/CTestConfig.cmake + :language: cmake + +The :manual:`ctest ` executable will read in this file when it runs. +To create a simple dashboard you can run the :manual:`cmake ` +executable or the :manual:`cmake-gui ` to configure the project, +but do not build it yet. Instead, change directory to the binary tree, and then +run: + + ctest [-VV] -D Experimental + +Remember, for multi-config generators (e.g. Visual Studio), the configuration +type must be specified:: + + ctest [-VV] -C Debug -D Experimental + +Or, from an IDE, build the ``Experimental`` target. + +The :manual:`ctest ` executable will build and test the project and +submit the results to Kitware's public dashboard: +https://my.cdash.org/index.php?project=CMakeTutorial. diff --git a/Help/guide/tutorial/Adding System Introspection.rst b/Help/guide/tutorial/Adding System Introspection.rst new file mode 100644 index 0000000..0ee360c --- /dev/null +++ b/Help/guide/tutorial/Adding System Introspection.rst @@ -0,0 +1,50 @@ +Step 5: Adding System Introspection +=================================== + +Let us consider adding some code to our project that depends on features the +target platform may not have. For this example, we will add some code that +depends on whether or not the target platform has the ``log`` and ``exp`` +functions. Of course almost every platform has these functions but for this +tutorial assume that they are not common. + +If the platform has ``log`` and ``exp`` then we will use them to compute the +square root in the ``mysqrt`` function. We first test for the availability of +these functions using the :module:`CheckSymbolExists` module in +``MathFunctions/CMakeLists.txt``. On some platforms, we will need to link to +the m library. If ``log`` and ``exp`` are not initially found, require the m +library and try again. + +.. literalinclude:: Step6/MathFunctions/CMakeLists.txt + :language: cmake + :start-after: # does this system provide the log and exp functions? + :end-before: # add compile definitions + +If available, use :command:`target_compile_definitions` to specify +``HAVE_LOG`` and ``HAVE_EXP`` as ``PRIVATE`` compile definitions. + +.. literalinclude:: Step6/MathFunctions/CMakeLists.txt + :language: cmake + :start-after: # add compile definitions + :end-before: # install rules + +If ``log`` and ``exp`` are available on the system, then we will use them to +compute the square root in the ``mysqrt`` function. Add the following code to +the ``mysqrt`` function in ``MathFunctions/mysqrt.cxx`` (don't forget the +``#endif`` before returning the result!): + +.. literalinclude:: Step6/MathFunctions/mysqrt.cxx + :language: c++ + :start-after: // if we have both log and exp then use them + :end-before: // do ten iterations + +We will also need to modify ``mysqrt.cxx`` to include ``cmath``. + +.. literalinclude:: Step6/MathFunctions/mysqrt.cxx + :language: c++ + :end-before: #include + +Run the :manual:`cmake ` executable or the +:manual:`cmake-gui ` to configure the project and then build it +with your chosen build tool and run the Tutorial executable. + +Which function gives better results now, sqrt or mysqrt? diff --git a/Help/guide/tutorial/Adding Usage Requirements for a Library.rst b/Help/guide/tutorial/Adding Usage Requirements for a Library.rst new file mode 100644 index 0000000..a625d90 --- /dev/null +++ b/Help/guide/tutorial/Adding Usage Requirements for a Library.rst @@ -0,0 +1,46 @@ +Step 3: Adding Usage Requirements for a Library +=============================================== + +Usage requirements allow for far better control over a library or executable's +link and include line while also giving more control over the transitive +property of targets inside CMake. The primary commands that leverage usage +requirements are: + + - :command:`target_compile_definitions` + - :command:`target_compile_options` + - :command:`target_include_directories` + - :command:`target_link_libraries` + +Let's refactor our code from `Adding a Library (Step 2)`_ to use the modern +CMake approach of usage requirements. We first state that anybody linking to +MathFunctions needs to include the current source directory, while +MathFunctions itself doesn't. So this can become an ``INTERFACE`` usage +requirement. + +Remember ``INTERFACE`` means things that consumers require but the producer +doesn't. Add the following lines to the end of +``MathFunctions/CMakeLists.txt``: + +.. literalinclude:: Step4/MathFunctions/CMakeLists.txt + :language: cmake + :start-after: # to find MathFunctions.h + +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: + +.. literalinclude:: Step4/CMakeLists.txt + :language: cmake + :start-after: # add the MathFunctions library + :end-before: # add the executable + +And here: + +.. literalinclude:: Step4/CMakeLists.txt + :language: cmake + :start-after: # so that we will find TutorialConfig.h + +Once this is done, run the :manual:`cmake ` executable or the +:manual:`cmake-gui ` to configure the project and then build it +with your chosen build tool or by using ``cmake --build .`` from the build +directory. 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 new file mode 100644 index 0000000..0e3e60c --- /dev/null +++ b/Help/guide/tutorial/Adding a Custom Command and Generated File.rst @@ -0,0 +1,75 @@ +Step 6: Adding a Custom Command and Generated File +================================================== + +Suppose, for the purpose of this tutorial, we decide that we never want to use +the platform ``log`` and ``exp`` functions and instead would like to +generate a table of precomputed values to use in the ``mysqrt`` function. +In this section, we will create the table as part of the build process, +and then compile that table into our application. + +First, let's remove the check for the ``log`` and ``exp`` functions in +``MathFunctions/CMakeLists.txt``. Then remove the check for ``HAVE_LOG`` and +``HAVE_EXP`` from ``mysqrt.cxx``. At the same time, we can remove +:code:`#include `. + +In the ``MathFunctions`` subdirectory, a new source file named +``MakeTable.cxx`` has been provided to generate the table. + +After reviewing the file, we can see that the table is produced as valid C++ +code and that the output filename is passed in as an argument. + +The next step is to add the appropriate commands to the +``MathFunctions/CMakeLists.txt`` file to build the MakeTable executable and +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. + +.. literalinclude:: Step7/MathFunctions/CMakeLists.txt + :language: cmake + :start-after: # first we add the executable that generates the table + :end-before: # add the command to generate the source code + +Then we add a custom command that specifies how to produce ``Table.h`` +by running MakeTable. + +.. literalinclude:: Step7/MathFunctions/CMakeLists.txt + :language: cmake + :start-after: # add the command to generate the source code + :end-before: # add the main library + +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 +of sources for the library MathFunctions. + +.. literalinclude:: Step7/MathFunctions/CMakeLists.txt + :language: cmake + :start-after: # add the main library + :end-before: # state that anybody linking + +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``. + +.. literalinclude:: Step7/MathFunctions/CMakeLists.txt + :language: cmake + :start-after: # state that we depend on our bin + :end-before: # install rules + +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: + +.. literalinclude:: Step7/MathFunctions/mysqrt.cxx + :language: c++ + :start-after: // a hack square root calculation using simple operations + +Run the :manual:`cmake ` executable or the +:manual:`cmake-gui ` to configure the project and then build it +with your chosen build tool. + +When this project is built it will first build the ``MakeTable`` executable. +It will then run ``MakeTable`` to produce ``Table.h``. Finally, it will +compile ``mysqrt.cxx`` which includes ``Table.h`` to produce the MathFunctions +library. + +Run the Tutorial executable and verify that it is using the table. diff --git a/Help/guide/tutorial/Adding a Library.rst b/Help/guide/tutorial/Adding a Library.rst new file mode 100644 index 0000000..3ff966c --- /dev/null +++ b/Help/guide/tutorial/Adding a Library.rst @@ -0,0 +1,116 @@ +Step 2: Adding a Library +======================== + +Now we will add a library to our project. This library will contain our own +implementation for computing the square root of a number. The executable can +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``. The source file has one +function called ``mysqrt`` that provides similar functionality to the +compiler's ``sqrt`` function. + +Add the following one line ``CMakeLists.txt`` file to the ``MathFunctions`` +directory: + +.. literalinclude:: Step3/MathFunctions/CMakeLists.txt + :language: cmake + +To make use of the new library we will add an :command:`add_subdirectory` +call in the top-level ``CMakeLists.txt`` file so that the library will get +built. We add the new library to the executable, and add ``MathFunctions`` as +an include directory so that the ``mysqrt.h`` header file can be found. The +last few lines of the top-level ``CMakeLists.txt`` file should now look like: + +.. code-block:: cmake + + # add the MathFunctions library + add_subdirectory(MathFunctions) + + # add the executable + add_executable(Tutorial tutorial.cxx) + + target_link_libraries(Tutorial PUBLIC MathFunctions) + + # add the binary tree to the search path for include files + # so that we will find TutorialConfig.h + target_include_directories(Tutorial PUBLIC + "${PROJECT_BINARY_DIR}" + "${PROJECT_SOURCE_DIR}/MathFunctions" + ) + +Now let us make the MathFunctions library optional. While for the tutorial +there really isn't any need to do so, for larger projects this is a common +occurrence. The first step is to add an option to the top-level +``CMakeLists.txt`` file. + +.. literalinclude:: Step3/CMakeLists.txt + :language: cmake + :start-after: # should we use our own math functions + :end-before: # add the MathFunctions library + +This option will be displayed in the :manual:`cmake-gui ` and +:manual:`ccmake ` +with a default value of ON that can be changed by the user. This setting will +be stored in the cache so that the user does not need to set the value each +time they run CMake on a build directory. + +The next change is to make building and linking the MathFunctions library +conditional. To do this we change the end of the top-level ``CMakeLists.txt`` +file to look like the following: + +.. literalinclude:: Step3/CMakeLists.txt + :language: cmake + :start-after: # add the MathFunctions library + +Note the use of the variable ``EXTRA_LIBS`` to collect up any optional +libraries to later be linked into the executable. The variable +``EXTRA_INCLUDES`` is used similarly for optional header files. This is a +classic approach when dealing with many optional components, we will cover +the modern approach in the next step. + +The corresponding changes to the source code are fairly straightforward. +First, in ``tutorial.cxx``, include the ``MathFunctions.h`` header if we +need it: + +.. literalinclude:: Step3/tutorial.cxx + :language: c++ + :start-after: // should we include the MathFunctions header + :end-before: int main + +Then, in the same file, make ``USE_MYMATH`` control which square root +function is used: + +.. literalinclude:: Step3/tutorial.cxx + :language: c++ + :start-after: // which square root function should we use? + :end-before: std::cout << "The square root of + +Since the source code now requires ``USE_MYMATH`` we can add it to +``TutorialConfig.h.in`` with the following line: + +.. literalinclude:: Step3/TutorialConfig.h.in + :language: c + :lines: 4 + +**Exercise**: Why is it important that we configure ``TutorialConfig.h.in`` +after the option for ``USE_MYMATH``? What would happen if we inverted the two? + +Run the :manual:`cmake ` executable or the +:manual:`cmake-gui ` to configure the project and then build it +with your chosen build tool. Then run the built Tutorial executable. + +Now let's update the value of ``USE_MYMATH``. The easiest way is to use the +:manual:`cmake-gui ` or :manual:`ccmake ` if you're +in the terminal. Or, alternatively, if you want to change the option from the +command-line, try: + +.. code-block:: console + + cmake ../Step2 -DUSE_MYMATH=OFF + +Rebuild and run the tutorial again. + +Which function gives better results, sqrt or mysqrt? diff --git a/Help/guide/tutorial/Installing and Testing.rst b/Help/guide/tutorial/Installing and Testing.rst new file mode 100644 index 0000000..3f85df3 --- /dev/null +++ b/Help/guide/tutorial/Installing and Testing.rst @@ -0,0 +1,85 @@ +Step 4: Installing and Testing +============================== + +Now we can start adding install rules and testing support to our project. + +Install Rules +------------- + +The install rules are fairly simple: for MathFunctions we want to install the +library and header file and for the application we want to install the +executable and configured header. + +So to the end of ``MathFunctions/CMakeLists.txt`` we add: + +.. literalinclude:: Step5/MathFunctions/CMakeLists.txt + :language: cmake + :start-after: # install rules + +And to the end of the top-level ``CMakeLists.txt`` we add: + +.. literalinclude:: Step5/CMakeLists.txt + :language: cmake + :start-after: # add the install targets + :end-before: # enable testing + +That is all that is needed to create a basic local install of the tutorial. + +Now run the :manual:`cmake ` executable or the +:manual:`cmake-gui ` to configure the project and then build it +with your chosen build tool. + +Then run the install step by using the ``install`` option of the +:manual:`cmake ` command (introduced in 3.15, older versions of +CMake must use ``make install``) from the command line. For +multi-configuration tools, don't forget to use the ``--config`` argument to +specify the configuration. If using an IDE, simply build the ``INSTALL`` +target. This step will install the appropriate header files, libraries, and +executables. For example: + +.. code-block:: console + + cmake --install . + +The CMake variable :variable:`CMAKE_INSTALL_PREFIX` is used to determine the +root of where the files will be installed. If using the ``cmake --install`` +command, the installation prefix can be overridden via the ``--prefix`` +argument. For example: + +.. code-block:: console + + cmake --install . --prefix "/home/myuser/installdir" + +Navigate to the install directory and verify that the installed Tutorial runs. + +Testing Support +--------------- + +Next let's test our application. At the end of the top-level ``CMakeLists.txt`` +file we can enable testing and then add a number of basic tests to verify that +the application is working correctly. + +.. literalinclude:: Step5/CMakeLists.txt + :language: cmake + :start-after: # enable testing + +The first test simply verifies that the application runs, does not segfault or +otherwise crash, and has a zero return value. This is the basic form of a +CTest test. + +The next test makes use of the :prop_test:`PASS_REGULAR_EXPRESSION` test +property to verify that the output of the test contains certain strings. In +this case, verifying that the usage message is printed when an incorrect number +of arguments are provided. + +Lastly, we have a function called ``do_test`` that runs the application and +verifies that the computed square root is correct for given input. For each +invocation of ``do_test``, another test is added to the project with a name, +input, and expected results based on the passed arguments. + +Rebuild the application and then cd to the binary directory and run the +:manual:`ctest ` executable: ``ctest -N`` and ``ctest -VV``. For +multi-config generators (e.g. Visual Studio), the configuration type must be +specified. To run tests in Debug mode, for example, use ``ctest -C Debug -VV`` +from the build directory (not the Debug subdirectory!). Alternatively, build +the ``RUN_TESTS`` target from the IDE. diff --git a/Help/guide/tutorial/Packaging Debug and Release.rst b/Help/guide/tutorial/Packaging Debug and Release.rst new file mode 100644 index 0000000..b73378c --- /dev/null +++ b/Help/guide/tutorial/Packaging Debug and Release.rst @@ -0,0 +1,78 @@ +Step 12: Packaging Debug and Release +==================================== + +**Note:** This example is valid for single-configuration generators and will +not work for multi-configuration generators (e.g. Visual Studio). + +By default, CMake's model is that a build directory only contains a single +configuration, be it Debug, Release, MinSizeRel, or RelWithDebInfo. It is +possible, however, to setup CPack to bundle multiple build directories and +construct a package that contains multiple configurations of the same project. + +First, we want to ensure that the debug and release builds use different names +for the executables and libraries that will be installed. Let's use `d` as the +postfix for the debug executable and libraries. + +Set :variable:`CMAKE_DEBUG_POSTFIX` near the beginning of the top-level +``CMakeLists.txt`` file: + +.. literalinclude:: Complete/CMakeLists.txt + :language: cmake + :start-after: project(Tutorial VERSION 1.0) + :end-before: target_compile_features(tutorial_compiler_flags + +And the :prop_tgt:`DEBUG_POSTFIX` property on the tutorial executable: + +.. literalinclude:: Complete/CMakeLists.txt + :language: cmake + :start-after: # add the executable + :end-before: # add the binary tree to the search path for include files + +Let's also add version numbering to the MathFunctions library. In +``MathFunctions/CMakeLists.txt``, set the :prop_tgt:`VERSION` and +:prop_tgt:`SOVERSION` properties: + +.. literalinclude:: Complete/MathFunctions/CMakeLists.txt + :language: cmake + :start-after: # setup the version numbering + :end-before: # install rules + +From the ``Step12`` directory, create ``debug`` and ``release`` +subbdirectories. The layout will look like: + +.. code-block:: none + + - Step12 + - debug + - release + +Now we need to setup debug and release builds. We can use +:variable:`CMAKE_BUILD_TYPE` to set the configuration type: + +.. code-block:: console + + cd debug + cmake -DCMAKE_BUILD_TYPE=Debug .. + cmake --build . + cd ../release + cmake -DCMAKE_BUILD_TYPE=Release .. + cmake --build . + +Now that both the debug and release builds are complete, we can use a custom +configuration file to package both builds into a single release. In the +``Step12`` directory, create a file called ``MultiCPackConfig.cmake``. In this +file, first include the default configuration file that was created by the +:manual:`cmake ` executable. + +Next, use the ``CPACK_INSTALL_CMAKE_PROJECTS`` variable to specify which +projects to install. In this case, we want to install both debug and release. + +.. literalinclude:: Complete/MultiCPackConfig.cmake + :language: cmake + +From the ``Step12`` directory, run :manual:`cpack ` specifying our +custom configuration file with the ``config`` option: + +.. code-block:: console + + cpack --config MultiCPackConfig.cmake diff --git a/Help/guide/tutorial/Packaging an Installer.rst b/Help/guide/tutorial/Packaging an Installer.rst new file mode 100644 index 0000000..037ae86 --- /dev/null +++ b/Help/guide/tutorial/Packaging an Installer.rst @@ -0,0 +1,55 @@ +Step 7: Packaging an Installer +============================== + +Next suppose that we want to distribute our project to other people so that +they can use it. We want to provide both binary and source distributions on a +variety of platforms. This is a little different from the install we did +previously in `Installing and Testing (Step 4)`_ , where we were +installing the binaries that we had built from the source code. In this +example we will be building installation packages that support binary +installations and package management features. To accomplish this we will use +CPack to create platform specific installers. Specifically we need to add a +few lines to the bottom of our top-level ``CMakeLists.txt`` file. + +.. literalinclude:: Step8/CMakeLists.txt + :language: cmake + :start-after: # setup installer + +That is all there is to it. We start by including +:module:`InstallRequiredSystemLibraries`. This module will include any runtime +libraries that are needed by the project for the current platform. Next we set +some CPack variables to where we have stored the license and version +information for this project. The version information was set earlier in this +tutorial and the ``license.txt`` has been included in the top-level source +directory for this step. + +Finally we include the :module:`CPack module ` which will use these +variables and some other properties of the current system to setup an +installer. + +The next step is to build the project in the usual manner and then run the +:manual:`cpack ` executable. To build a binary distribution, from the +binary directory run: + +.. code-block:: console + + cpack + +To specify the generator, use the ``-G`` option. For multi-config builds, use +``-C`` to specify the configuration. For example: + +.. code-block:: console + + cpack -G ZIP -C Debug + +To create a source distribution you would type: + +.. code-block:: console + + cpack --config CPackSourceConfig.cmake + +Alternatively, run ``make package`` or right click the ``Package`` target and +``Build Project`` from an IDE. + +Run the installer found in the binary directory. Then run the installed +executable and verify that it works. diff --git a/Help/guide/tutorial/Selecting Static or Shared Libraries.rst b/Help/guide/tutorial/Selecting Static or Shared Libraries.rst new file mode 100644 index 0000000..c9b5e31 --- /dev/null +++ b/Help/guide/tutorial/Selecting Static or Shared Libraries.rst @@ -0,0 +1,66 @@ +Step 9: Selecting Static or Shared Libraries +============================================ + +In this section we will show how the :variable:`BUILD_SHARED_LIBS` variable can +be used to control the default behavior of :command:`add_library`, +and allow control over how libraries without an explicit type (``STATIC``, +``SHARED``, ``MODULE`` or ``OBJECT``) are built. + +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:: Step10/CMakeLists.txt + :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. + +The end result is that ``MathFunctions/CMakeLists.txt`` should look like: + +.. literalinclude:: Step10/MathFunctions/CMakeLists.txt + :language: cmake + :lines: 1-36,42- + +Next, update ``MathFunctions/mysqrt.cxx`` to use the ``mathfunctions`` and +``detail`` namespaces: + +.. literalinclude:: Step10/MathFunctions/mysqrt.cxx + :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 + +Finally, update ``MathFunctions/MathFunctions.h`` to use dll export defines: + +.. literalinclude:: Step10/MathFunctions/MathFunctions.h + :language: c++ + +At this point, if you build everything, you may notice that linking fails +as we are combining a static library without position independent code with a +library that has position independent code. The solution to this is to +explicitly set the :prop_tgt:`POSITION_INDEPENDENT_CODE` target property of +SqrtLibrary to be True no matter the build type. + +.. literalinclude:: Step10/MathFunctions/CMakeLists.txt + :language: cmake + :lines: 37-42 + +**Exercise**: We modified ``MathFunctions.h`` to use dll export defines. +Using CMake documentation can you find a helper module to simplify this? diff --git a/Help/guide/tutorial/index.rst b/Help/guide/tutorial/index.rst index 7cdd844..8a765fd 100644 --- a/Help/guide/tutorial/index.rst +++ b/Help/guide/tutorial/index.rst @@ -1,10 +1,6 @@ CMake Tutorial ************** -.. only:: html - - .. contents:: - Introduction ============ @@ -12,936 +8,27 @@ The CMake tutorial provides a step-by-step guide that covers common build system issues that CMake helps address. Seeing how various topics all work together in an example project can be very helpful. +Steps +===== + The tutorial documentation and source code for examples can be found in the ``Help/guide/tutorial`` directory of the CMake source code tree. Each step has its own subdirectory containing code that may be used as a starting point. The tutorial examples are progressive so that each step provides the complete solution for the previous step. -A Basic Starting Point (Step 1) -=============================== - -The most basic project is an executable built from source code files. -For simple projects, a three line ``CMakeLists.txt`` file is all that is -required. This will be the starting point for our tutorial. Create a -``CMakeLists.txt`` file in the ``Step1`` directory that looks like: - -.. code-block:: cmake - - cmake_minimum_required(VERSION 3.10) - - # set the project name - project(Tutorial) - - # add the executable - add_executable(Tutorial tutorial.cxx) - - -Note that this example uses lower case commands in the ``CMakeLists.txt`` file. -Upper, lower, and mixed case commands are supported by CMake. The source -code for ``tutorial.cxx`` is provided in the ``Step1`` directory and can be -used to compute the square root of a number. - -Adding a Version Number and Configured Header File --------------------------------------------------- - -The first feature we will add is to provide our executable and project with a -version number. While we could do this exclusively in the source code, using -``CMakeLists.txt`` provides more flexibility. - -First, modify the ``CMakeLists.txt`` file to use the :command:`project` command -to set the project name and version number. - -.. literalinclude:: Step2/CMakeLists.txt - :language: cmake - :end-before: # specify the C++ standard - -Then, configure a header file to pass the version number to the source -code: - -.. literalinclude:: Step2/CMakeLists.txt - :language: cmake - :start-after: # to the source code - :end-before: # add the executable - -Since the configured file will be written into the binary tree, we -must add that directory to the list of paths to search for include -files. Add the following lines to the end of the ``CMakeLists.txt`` file: - -.. literalinclude:: Step2/CMakeLists.txt - :language: cmake - :start-after: # so that we will find TutorialConfig.h - -Using your favorite editor, create ``TutorialConfig.h.in`` in the source -directory with the following contents: - -.. literalinclude:: Step2/TutorialConfig.h.in - :language: cmake - -When CMake configures this header file the values for -``@Tutorial_VERSION_MAJOR@`` and ``@Tutorial_VERSION_MINOR@`` will be -replaced. - -Next modify ``tutorial.cxx`` to include the configured header file, -``TutorialConfig.h``. - -Finally, let's print out the executable name and version number by updating -``tutorial.cxx`` as follows: - -.. literalinclude:: Step2/tutorial.cxx - :language: c++ - :start-after: { - :end-before: // convert input to double - -Specify the C++ Standard -------------------------- - -Next let's add some C++11 features to our project by replacing ``atof`` with -``std::stod`` in ``tutorial.cxx``. At the same time, remove -``#include ``. - -.. literalinclude:: Step2/tutorial.cxx - :language: c++ - :start-after: // convert input to double - :end-before: // calculate square root - -We will need to explicitly state in the CMake code that it should use the -correct flags. The easiest way to enable support for a specific C++ standard -in CMake is by using the :variable:`CMAKE_CXX_STANDARD` variable. For this -tutorial, set the :variable:`CMAKE_CXX_STANDARD` variable in the -``CMakeLists.txt`` file to 11 and :variable:`CMAKE_CXX_STANDARD_REQUIRED` to -True. Make sure to add the ``CMAKE_CXX_STANDARD`` declarations above the call -to ``add_executable``. - -.. literalinclude:: Step2/CMakeLists.txt - :language: cmake - :end-before: # configure a header file to pass some of the CMake settings - -Build and Test --------------- - -Run the :manual:`cmake ` executable or the -:manual:`cmake-gui ` to configure the project and then build it -with your chosen build tool. - -For example, from the command line we could navigate to the -``Help/guide/tutorial`` directory of the CMake source code tree and create a -build directory: - -.. code-block:: console - - mkdir Step1_build - -Next, navigate to the build directory and run CMake to configure the project -and generate a native build system: - -.. code-block:: console - - cd Step1_build - cmake ../Step1 - -Then call that build system to actually compile/link the project: - -.. code-block:: console - - cmake --build . - -Finally, try to use the newly built ``Tutorial`` with these commands: - -.. code-block:: console - - Tutorial 4294967296 - Tutorial 10 - Tutorial - -Adding a Library (Step 2) -========================= - -Now we will add a library to our project. This library will contain our own -implementation for computing the square root of a number. The executable can -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``. The source file has one -function called ``mysqrt`` that provides similar functionality to the -compiler's ``sqrt`` function. - -Add the following one line ``CMakeLists.txt`` file to the ``MathFunctions`` -directory: - -.. literalinclude:: Step3/MathFunctions/CMakeLists.txt - :language: cmake - -To make use of the new library we will add an :command:`add_subdirectory` -call in the top-level ``CMakeLists.txt`` file so that the library will get -built. We add the new library to the executable, and add ``MathFunctions`` as -an include directory so that the ``mysqrt.h`` header file can be found. The -last few lines of the top-level ``CMakeLists.txt`` file should now look like: - -.. code-block:: cmake - - # add the MathFunctions library - add_subdirectory(MathFunctions) - - # add the executable - add_executable(Tutorial tutorial.cxx) - - target_link_libraries(Tutorial PUBLIC MathFunctions) - - # add the binary tree to the search path for include files - # so that we will find TutorialConfig.h - target_include_directories(Tutorial PUBLIC - "${PROJECT_BINARY_DIR}" - "${PROJECT_SOURCE_DIR}/MathFunctions" - ) - -Now let us make the MathFunctions library optional. While for the tutorial -there really isn't any need to do so, for larger projects this is a common -occurrence. The first step is to add an option to the top-level -``CMakeLists.txt`` file. - -.. literalinclude:: Step3/CMakeLists.txt - :language: cmake - :start-after: # should we use our own math functions - :end-before: # add the MathFunctions library - -This option will be displayed in the :manual:`cmake-gui ` and -:manual:`ccmake ` -with a default value of ON that can be changed by the user. This setting will -be stored in the cache so that the user does not need to set the value each -time they run CMake on a build directory. - -The next change is to make building and linking the MathFunctions library -conditional. To do this we change the end of the top-level ``CMakeLists.txt`` -file to look like the following: - -.. literalinclude:: Step3/CMakeLists.txt - :language: cmake - :start-after: # add the MathFunctions library - -Note the use of the variable ``EXTRA_LIBS`` to collect up any optional -libraries to later be linked into the executable. The variable -``EXTRA_INCLUDES`` is used similarly for optional header files. This is a -classic approach when dealing with many optional components, we will cover -the modern approach in the next step. - -The corresponding changes to the source code are fairly straightforward. -First, in ``tutorial.cxx``, include the ``MathFunctions.h`` header if we -need it: - -.. literalinclude:: Step3/tutorial.cxx - :language: c++ - :start-after: // should we include the MathFunctions header - :end-before: int main - -Then, in the same file, make ``USE_MYMATH`` control which square root -function is used: - -.. literalinclude:: Step3/tutorial.cxx - :language: c++ - :start-after: // which square root function should we use? - :end-before: std::cout << "The square root of - -Since the source code now requires ``USE_MYMATH`` we can add it to -``TutorialConfig.h.in`` with the following line: - -.. literalinclude:: Step3/TutorialConfig.h.in - :language: c - :lines: 4 - -**Exercise**: Why is it important that we configure ``TutorialConfig.h.in`` -after the option for ``USE_MYMATH``? What would happen if we inverted the two? - -Run the :manual:`cmake ` executable or the -:manual:`cmake-gui ` to configure the project and then build it -with your chosen build tool. Then run the built Tutorial executable. - -Now let's update the value of ``USE_MYMATH``. The easiest way is to use the -:manual:`cmake-gui ` or :manual:`ccmake ` if you're -in the terminal. Or, alternatively, if you want to change the option from the -command-line, try: - -.. code-block:: console - - cmake ../Step2 -DUSE_MYMATH=OFF - -Rebuild and run the tutorial again. - -Which function gives better results, sqrt or mysqrt? - -Adding Usage Requirements for Library (Step 3) -============================================== - -Usage requirements allow for far better control over a library or executable's -link and include line while also giving more control over the transitive -property of targets inside CMake. The primary commands that leverage usage -requirements are: - - - :command:`target_compile_definitions` - - :command:`target_compile_options` - - :command:`target_include_directories` - - :command:`target_link_libraries` - -Let's refactor our code from `Adding a Library (Step 2)`_ to use the modern -CMake approach of usage requirements. We first state that anybody linking to -MathFunctions needs to include the current source directory, while -MathFunctions itself doesn't. So this can become an ``INTERFACE`` usage -requirement. - -Remember ``INTERFACE`` means things that consumers require but the producer -doesn't. Add the following lines to the end of -``MathFunctions/CMakeLists.txt``: - -.. literalinclude:: Step4/MathFunctions/CMakeLists.txt - :language: cmake - :start-after: # to find MathFunctions.h - -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: - -.. literalinclude:: Step4/CMakeLists.txt - :language: cmake - :start-after: # add the MathFunctions library - :end-before: # add the executable - -And here: - -.. literalinclude:: Step4/CMakeLists.txt - :language: cmake - :start-after: # so that we will find TutorialConfig.h - -Once this is done, run the :manual:`cmake ` executable or the -:manual:`cmake-gui ` to configure the project and then build it -with your chosen build tool or by using ``cmake --build .`` from the build -directory. - -Installing and Testing (Step 4) -=============================== - -Now we can start adding install rules and testing support to our project. - -Install Rules -------------- - -The install rules are fairly simple: for MathFunctions we want to install the -library and header file and for the application we want to install the -executable and configured header. - -So to the end of ``MathFunctions/CMakeLists.txt`` we add: - -.. literalinclude:: Step5/MathFunctions/CMakeLists.txt - :language: cmake - :start-after: # install rules - -And to the end of the top-level ``CMakeLists.txt`` we add: - -.. literalinclude:: Step5/CMakeLists.txt - :language: cmake - :start-after: # add the install targets - :end-before: # enable testing - -That is all that is needed to create a basic local install of the tutorial. - -Now run the :manual:`cmake ` executable or the -:manual:`cmake-gui ` to configure the project and then build it -with your chosen build tool. - -Then run the install step by using the ``install`` option of the -:manual:`cmake ` command (introduced in 3.15, older versions of -CMake must use ``make install``) from the command line. For -multi-configuration tools, don't forget to use the ``--config`` argument to -specify the configuration. If using an IDE, simply build the ``INSTALL`` -target. This step will install the appropriate header files, libraries, and -executables. For example: - -.. code-block:: console - - cmake --install . - -The CMake variable :variable:`CMAKE_INSTALL_PREFIX` is used to determine the -root of where the files will be installed. If using the ``cmake --install`` -command, the installation prefix can be overridden via the ``--prefix`` -argument. For example: - -.. code-block:: console - - cmake --install . --prefix "/home/myuser/installdir" - -Navigate to the install directory and verify that the installed Tutorial runs. - -Testing Support ---------------- - -Next let's test our application. At the end of the top-level ``CMakeLists.txt`` -file we can enable testing and then add a number of basic tests to verify that -the application is working correctly. - -.. literalinclude:: Step5/CMakeLists.txt - :language: cmake - :start-after: # enable testing - -The first test simply verifies that the application runs, does not segfault or -otherwise crash, and has a zero return value. This is the basic form of a -CTest test. - -The next test makes use of the :prop_test:`PASS_REGULAR_EXPRESSION` test -property to verify that the output of the test contains certain strings. In -this case, verifying that the usage message is printed when an incorrect number -of arguments are provided. - -Lastly, we have a function called ``do_test`` that runs the application and -verifies that the computed square root is correct for given input. For each -invocation of ``do_test``, another test is added to the project with a name, -input, and expected results based on the passed arguments. - -Rebuild the application and then cd to the binary directory and run the -:manual:`ctest ` executable: ``ctest -N`` and ``ctest -VV``. For -multi-config generators (e.g. Visual Studio), the configuration type must be -specified. To run tests in Debug mode, for example, use ``ctest -C Debug -VV`` -from the build directory (not the Debug subdirectory!). Alternatively, build -the ``RUN_TESTS`` target from the IDE. - -Adding System Introspection (Step 5) -==================================== - -Let us consider adding some code to our project that depends on features the -target platform may not have. For this example, we will add some code that -depends on whether or not the target platform has the ``log`` and ``exp`` -functions. Of course almost every platform has these functions but for this -tutorial assume that they are not common. - -If the platform has ``log`` and ``exp`` then we will use them to compute the -square root in the ``mysqrt`` function. We first test for the availability of -these functions using the :module:`CheckSymbolExists` module in -``MathFunctions/CMakeLists.txt``. On some platforms, we will need to link to -the m library. If ``log`` and ``exp`` are not initially found, require the m -library and try again. - -.. literalinclude:: Step6/MathFunctions/CMakeLists.txt - :language: cmake - :start-after: # does this system provide the log and exp functions? - :end-before: # add compile definitions - -If available, use :command:`target_compile_definitions` to specify -``HAVE_LOG`` and ``HAVE_EXP`` as ``PRIVATE`` compile definitions. - -.. literalinclude:: Step6/MathFunctions/CMakeLists.txt - :language: cmake - :start-after: # add compile definitions - :end-before: # install rules - -If ``log`` and ``exp`` are available on the system, then we will use them to -compute the square root in the ``mysqrt`` function. Add the following code to -the ``mysqrt`` function in ``MathFunctions/mysqrt.cxx`` (don't forget the -``#endif`` before returning the result!): - -.. literalinclude:: Step6/MathFunctions/mysqrt.cxx - :language: c++ - :start-after: // if we have both log and exp then use them - :end-before: // do ten iterations - -We will also need to modify ``mysqrt.cxx`` to include ``cmath``. - -.. literalinclude:: Step6/MathFunctions/mysqrt.cxx - :language: c++ - :end-before: #include - -Run the :manual:`cmake ` executable or the -:manual:`cmake-gui ` to configure the project and then build it -with your chosen build tool and run the Tutorial executable. - -Which function gives better results now, sqrt or mysqrt? - -Adding a Custom Command and Generated File (Step 6) -=================================================== - -Suppose, for the purpose of this tutorial, we decide that we never want to use -the platform ``log`` and ``exp`` functions and instead would like to -generate a table of precomputed values to use in the ``mysqrt`` function. -In this section, we will create the table as part of the build process, -and then compile that table into our application. - -First, let's remove the check for the ``log`` and ``exp`` functions in -``MathFunctions/CMakeLists.txt``. Then remove the check for ``HAVE_LOG`` and -``HAVE_EXP`` from ``mysqrt.cxx``. At the same time, we can remove -:code:`#include `. - -In the ``MathFunctions`` subdirectory, a new source file named -``MakeTable.cxx`` has been provided to generate the table. - -After reviewing the file, we can see that the table is produced as valid C++ -code and that the output filename is passed in as an argument. - -The next step is to add the appropriate commands to the -``MathFunctions/CMakeLists.txt`` file to build the MakeTable executable and -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. - -.. literalinclude:: Step7/MathFunctions/CMakeLists.txt - :language: cmake - :start-after: # first we add the executable that generates the table - :end-before: # add the command to generate the source code - -Then we add a custom command that specifies how to produce ``Table.h`` -by running MakeTable. - -.. literalinclude:: Step7/MathFunctions/CMakeLists.txt - :language: cmake - :start-after: # add the command to generate the source code - :end-before: # add the main library - -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 -of sources for the library MathFunctions. - -.. literalinclude:: Step7/MathFunctions/CMakeLists.txt - :language: cmake - :start-after: # add the main library - :end-before: # state that anybody linking - -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``. - -.. literalinclude:: Step7/MathFunctions/CMakeLists.txt - :language: cmake - :start-after: # state that we depend on our bin - :end-before: # install rules - -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: - -.. literalinclude:: Step7/MathFunctions/mysqrt.cxx - :language: c++ - :start-after: // a hack square root calculation using simple operations - -Run the :manual:`cmake ` executable or the -:manual:`cmake-gui ` to configure the project and then build it -with your chosen build tool. - -When this project is built it will first build the ``MakeTable`` executable. -It will then run ``MakeTable`` to produce ``Table.h``. Finally, it will -compile ``mysqrt.cxx`` which includes ``Table.h`` to produce the MathFunctions -library. - -Run the Tutorial executable and verify that it is using the table. - -Building an Installer (Step 7) -============================== - -Next suppose that we want to distribute our project to other people so that -they can use it. We want to provide both binary and source distributions on a -variety of platforms. This is a little different from the install we did -previously in `Installing and Testing (Step 4)`_ , where we were -installing the binaries that we had built from the source code. In this -example we will be building installation packages that support binary -installations and package management features. To accomplish this we will use -CPack to create platform specific installers. Specifically we need to add a -few lines to the bottom of our top-level ``CMakeLists.txt`` file. - -.. literalinclude:: Step8/CMakeLists.txt - :language: cmake - :start-after: # setup installer - -That is all there is to it. We start by including -:module:`InstallRequiredSystemLibraries`. This module will include any runtime -libraries that are needed by the project for the current platform. Next we set -some CPack variables to where we have stored the license and version -information for this project. The version information was set earlier in this -tutorial and the ``license.txt`` has been included in the top-level source -directory for this step. - -Finally we include the :module:`CPack module ` which will use these -variables and some other properties of the current system to setup an -installer. - -The next step is to build the project in the usual manner and then run the -:manual:`cpack ` executable. To build a binary distribution, from the -binary directory run: - -.. code-block:: console - - cpack - -To specify the generator, use the ``-G`` option. For multi-config builds, use -``-C`` to specify the configuration. For example: - -.. code-block:: console - - cpack -G ZIP -C Debug - -To create a source distribution you would type: - -.. code-block:: console - - cpack --config CPackSourceConfig.cmake - -Alternatively, run ``make package`` or right click the ``Package`` target and -``Build Project`` from an IDE. - -Run the installer found in the binary directory. Then run the installed -executable and verify that it works. - -Adding Support for a Dashboard (Step 8) -======================================= - -Adding support for submitting our test results to a dashboard is simple. We -already defined a number of tests for our project in `Testing Support`_. Now we -just have to run those tests and submit them to a dashboard. To include support -for dashboards we include the :module:`CTest` module in our top-level -``CMakeLists.txt``. - -Replace: - -.. code-block:: cmake - - # enable testing - enable_testing() - -With: - -.. code-block:: cmake - - # enable dashboard scripting - include(CTest) - -The :module:`CTest` module will automatically call ``enable_testing()``, so we -can remove it from our CMake files. - -We will also need to create a ``CTestConfig.cmake`` file in the top-level -directory where we can specify the name of the project and where to submit the -dashboard. - -.. literalinclude:: Step9/CTestConfig.cmake - :language: cmake - -The :manual:`ctest ` executable will read in this file when it runs. -To create a simple dashboard you can run the :manual:`cmake ` -executable or the :manual:`cmake-gui ` to configure the project, -but do not build it yet. Instead, change directory to the binary tree, and then -run: - - ctest [-VV] -D Experimental - -Remember, for multi-config generators (e.g. Visual Studio), the configuration -type must be specified:: - - ctest [-VV] -C Debug -D Experimental - -Or, from an IDE, build the ``Experimental`` target. - -The :manual:`ctest ` executable will build and test the project and -submit the results to Kitware's public dashboard: -https://my.cdash.org/index.php?project=CMakeTutorial. - -Mixing Static and Shared (Step 9) -================================= - -In this section we will show how the :variable:`BUILD_SHARED_LIBS` variable can -be used to control the default behavior of :command:`add_library`, -and allow control over how libraries without an explicit type (``STATIC``, -``SHARED``, ``MODULE`` or ``OBJECT``) are built. - -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:: Step10/CMakeLists.txt - :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. - -The end result is that ``MathFunctions/CMakeLists.txt`` should look like: - -.. literalinclude:: Step10/MathFunctions/CMakeLists.txt - :language: cmake - :lines: 1-36,42- - -Next, update ``MathFunctions/mysqrt.cxx`` to use the ``mathfunctions`` and -``detail`` namespaces: - -.. literalinclude:: Step10/MathFunctions/mysqrt.cxx - :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 - -Finally, update ``MathFunctions/MathFunctions.h`` to use dll export defines: - -.. literalinclude:: Step10/MathFunctions/MathFunctions.h - :language: c++ - -At this point, if you build everything, you may notice that linking fails -as we are combining a static library without position independent code with a -library that has position independent code. The solution to this is to -explicitly set the :prop_tgt:`POSITION_INDEPENDENT_CODE` target property of -SqrtLibrary to be True no matter the build type. - -.. literalinclude:: Step10/MathFunctions/CMakeLists.txt - :language: cmake - :lines: 37-42 - -**Exercise**: We modified ``MathFunctions.h`` to use dll export defines. -Using CMake documentation can you find a helper module to simplify this? - - -Adding Generator Expressions (Step 10) -====================================== - -:manual:`Generator expressions ` are evaluated -during build system generation to produce information specific to each build -configuration. - -:manual:`Generator expressions ` are allowed in -the context of many target properties, such as :prop_tgt:`LINK_LIBRARIES`, -:prop_tgt:`INCLUDE_DIRECTORIES`, :prop_tgt:`COMPILE_DEFINITIONS` and others. -They may also be used when using commands to populate those properties, such as -:command:`target_link_libraries`, :command:`target_include_directories`, -:command:`target_compile_definitions` and others. - -:manual:`Generator expressions ` may be used -to enable conditional linking, conditional definitions used when compiling, -conditional include directories and more. The conditions may be based on the -build configuration, target properties, platform information or any other -queryable information. - -There are different types of -:manual:`generator expressions ` including -Logical, Informational, and Output expressions. - -Logical expressions are used to create conditional output. The basic -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 ` 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`. - -So the following code: - -.. literalinclude:: Step10/CMakeLists.txt - :language: cmake - :start-after: project(Tutorial VERSION 1.0) - :end-before: # control where the static and shared libraries are built so that on windows - -Would be replaced with: - -.. literalinclude:: Step11/CMakeLists.txt - :language: cmake - :start-after: project(Tutorial VERSION 1.0) - :end-before: # add compiler warning flags just when building this project via - - -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: - -.. literalinclude:: Step11/CMakeLists.txt - :language: cmake - :start-after: # the BUILD_INTERFACE genex - :end-before: # control where the static and shared libraries are built so that on windows - -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. - - -**Exercise**: Modify ``MathFunctions/CMakeLists.txt`` so that all targets have -a :command:`target_link_libraries` call to ``tutorial_compiler_flags``. - - -Adding Export Configuration (Step 11) -===================================== - -During `Installing and Testing (Step 4)`_ of the tutorial we added the ability -for CMake to install the library and headers of the project. During -`Building an Installer (Step 7)`_ we added the ability to package up this -information so it could be distributed to other people. - -The next step is to add the necessary information so that other CMake projects -can use our project, be it from a build directory, a local install or when -packaged. - -The first step is to update our :command:`install(TARGETS)` commands to not -only specify a ``DESTINATION`` but also an ``EXPORT``. The ``EXPORT`` keyword -generates and installs a CMake file containing code to import all targets -listed in the install command from the installation tree. So let's go ahead and -explicitly ``EXPORT`` the MathFunctions library by updating the ``install`` -command in ``MathFunctions/CMakeLists.txt`` to look like: - -.. literalinclude:: Complete/MathFunctions/CMakeLists.txt - :language: cmake - :start-after: # install rules - -Now that we have MathFunctions being exported, we also need to explicitly -install the generated ``MathFunctionsTargets.cmake`` file. This is done by -adding the following to the bottom of the top-level ``CMakeLists.txt``: - -.. literalinclude:: Complete/CMakeLists.txt - :language: cmake - :start-after: # install the configuration targets - :end-before: include(CMakePackageConfigHelpers) - -At this point you should try and run CMake. If everything is setup properly -you will see that CMake will generate an error that looks like: - -.. code-block:: console - - Target "MathFunctions" INTERFACE_INCLUDE_DIRECTORIES property contains - path: - - "/Users/robert/Documents/CMakeClass/Tutorial/Step11/MathFunctions" - - which is prefixed in the source directory. - -What CMake is trying to say is that during generating the export information -it will export a path that is intrinsically tied to the current machine and -will not be valid on other machines. The solution to this is to update the -MathFunctions :command:`target_include_directories` to understand that it needs -different ``INTERFACE`` locations when being used from within the build -directory and from an install / package. This means converting the -:command:`target_include_directories` call for MathFunctions to look like: - -.. literalinclude:: Step12/MathFunctions/CMakeLists.txt - :language: cmake - :start-after: # to find MathFunctions.h, while we don't. - :end-before: # should we use our own math functions - -Once this has been updated, we can re-run CMake and verify that it doesn't -warn anymore. - -At this point, we have CMake properly packaging the target information that is -required but we will still need to generate a ``MathFunctionsConfig.cmake`` so -that the CMake :command:`find_package` command can find our project. So let's go -ahead and add a new file to the top-level of the project called -``Config.cmake.in`` with the following contents: - -.. literalinclude:: Step12/Config.cmake.in - -Then, to properly configure and install that file, add the following to the -bottom of the top-level ``CMakeLists.txt``: - -.. literalinclude:: Step12/CMakeLists.txt - :language: cmake - :start-after: # install the configuration targets - :end-before: # generate the export - -At this point, we have generated a relocatable CMake Configuration for our -project that can be used after the project has been installed or packaged. If -we want our project to also be used from a build directory we only have to add -the following to the bottom of the top level ``CMakeLists.txt``: - -.. literalinclude:: Step12/CMakeLists.txt - :language: cmake - :start-after: # needs to be after the install(TARGETS ) command - -With this export call we now generate a ``Targets.cmake``, allowing the -configured ``MathFunctionsConfig.cmake`` in the build directory to be used by -other projects, without needing it to be installed. - -Packaging Debug and Release (Step 12) -===================================== - -**Note:** This example is valid for single-configuration generators and will -not work for multi-configuration generators (e.g. Visual Studio). - -By default, CMake's model is that a build directory only contains a single -configuration, be it Debug, Release, MinSizeRel, or RelWithDebInfo. It is -possible, however, to setup CPack to bundle multiple build directories and -construct a package that contains multiple configurations of the same project. - -First, we want to ensure that the debug and release builds use different names -for the executables and libraries that will be installed. Let's use `d` as the -postfix for the debug executable and libraries. - -Set :variable:`CMAKE_DEBUG_POSTFIX` near the beginning of the top-level -``CMakeLists.txt`` file: - -.. literalinclude:: Complete/CMakeLists.txt - :language: cmake - :start-after: project(Tutorial VERSION 1.0) - :end-before: target_compile_features(tutorial_compiler_flags - -And the :prop_tgt:`DEBUG_POSTFIX` property on the tutorial executable: - -.. literalinclude:: Complete/CMakeLists.txt - :language: cmake - :start-after: # add the executable - :end-before: # add the binary tree to the search path for include files - -Let's also add version numbering to the MathFunctions library. In -``MathFunctions/CMakeLists.txt``, set the :prop_tgt:`VERSION` and -:prop_tgt:`SOVERSION` properties: - -.. literalinclude:: Complete/MathFunctions/CMakeLists.txt - :language: cmake - :start-after: # setup the version numbering - :end-before: # install rules - -From the ``Step12`` directory, create ``debug`` and ``release`` -subbdirectories. The layout will look like: - -.. code-block:: none - - - Step12 - - debug - - release - -Now we need to setup debug and release builds. We can use -:variable:`CMAKE_BUILD_TYPE` to set the configuration type: - -.. code-block:: console - - cd debug - cmake -DCMAKE_BUILD_TYPE=Debug .. - cmake --build . - cd ../release - cmake -DCMAKE_BUILD_TYPE=Release .. - cmake --build . - -Now that both the debug and release builds are complete, we can use a custom -configuration file to package both builds into a single release. In the -``Step12`` directory, create a file called ``MultiCPackConfig.cmake``. In this -file, first include the default configuration file that was created by the -:manual:`cmake ` executable. - -Next, use the ``CPACK_INSTALL_CMAKE_PROJECTS`` variable to specify which -projects to install. In this case, we want to install both debug and release. - -.. literalinclude:: Complete/MultiCPackConfig.cmake - :language: cmake - -From the ``Step12`` directory, run :manual:`cpack ` specifying our -custom configuration file with the ``config`` option: - -.. code-block:: console - - cpack --config MultiCPackConfig.cmake +.. toctree:: + :maxdepth: 2 + + A Basic Starting Point + Adding a Library + Adding Usage Requirements for a Library + Installing and Testing + Adding System Introspection + Adding a Custom Command and Generated File + Packaging an Installer + Adding Support for a Testing Dashboard + Selecting Static or Shared Libraries + Adding Generator Expressions + Adding Export Configuration + Packaging Debug and Release -- cgit v0.12 From 25dde20cc5df77326f369c2dbcca3edcf687e581 Mon Sep 17 00:00:00 2001 From: Josef Angstenberger Date: Thu, 10 Jun 2021 23:16:18 +0200 Subject: Tutorial: Fix links after splitting steps --- Help/guide/tutorial/Adding Export Configuration.rst | 8 ++++---- Help/guide/tutorial/Adding Support for a Testing Dashboard.rst | 8 ++++---- .../guide/tutorial/Adding Usage Requirements for a Library.rst | 10 +++++----- Help/guide/tutorial/Installing and Testing.rst | 2 ++ Help/guide/tutorial/Packaging an Installer.rst | 2 +- 5 files changed, 16 insertions(+), 14 deletions(-) diff --git a/Help/guide/tutorial/Adding Export Configuration.rst b/Help/guide/tutorial/Adding Export Configuration.rst index 55cb3e2..6c283a6 100644 --- a/Help/guide/tutorial/Adding Export Configuration.rst +++ b/Help/guide/tutorial/Adding Export Configuration.rst @@ -1,10 +1,10 @@ Step 11: Adding Export Configuration ==================================== -During `Installing and Testing (Step 4)`_ of the tutorial we added the ability -for CMake to install the library and headers of the project. During -`Building an Installer (Step 7)`_ we added the ability to package up this -information so it could be distributed to other people. +During :guide:`tutorial/Installing and Testing` of the tutorial we added the +ability for CMake to install the library and headers of the project. During +:guide:`tutorial/Packaging an Installer` we added the ability to package up +this information so it could be distributed to other people. The next step is to add the necessary information so that other CMake projects can use our project, be it from a build directory, a local install or when diff --git a/Help/guide/tutorial/Adding Support for a Testing Dashboard.rst b/Help/guide/tutorial/Adding Support for a Testing Dashboard.rst index 41b772c..74d3f0f 100644 --- a/Help/guide/tutorial/Adding Support for a Testing Dashboard.rst +++ b/Help/guide/tutorial/Adding Support for a Testing Dashboard.rst @@ -2,10 +2,10 @@ Step 8: Adding Support for a Testing Dashboard ============================================== Adding support for submitting our test results to a dashboard is simple. We -already defined a number of tests for our project in `Testing Support`_. Now we -just have to run those tests and submit them to a dashboard. To include support -for dashboards we include the :module:`CTest` module in our top-level -``CMakeLists.txt``. +already defined a number of tests for our project in +:ref:`Testing Support `. Now we just have to run +those tests and submit them to a dashboard. To include support for dashboards +we include the :module:`CTest` module in our top-level ``CMakeLists.txt``. Replace: 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 a625d90..6146a5e 100644 --- a/Help/guide/tutorial/Adding Usage Requirements for a Library.rst +++ b/Help/guide/tutorial/Adding Usage Requirements for a Library.rst @@ -11,11 +11,11 @@ requirements are: - :command:`target_include_directories` - :command:`target_link_libraries` -Let's refactor our code from `Adding a Library (Step 2)`_ to use the modern -CMake approach of usage requirements. We first state that anybody linking to -MathFunctions needs to include the current source directory, while -MathFunctions itself doesn't. So this can become an ``INTERFACE`` usage -requirement. +Let's refactor our code from :guide:`tutorial/Adding a Library` to use the +modern CMake approach of usage requirements. We first state that anybody +linking to MathFunctions needs to include the current source directory, +while MathFunctions itself doesn't. So this can become an ``INTERFACE`` +usage requirement. Remember ``INTERFACE`` means things that consumers require but the producer doesn't. Add the following lines to the end of diff --git a/Help/guide/tutorial/Installing and Testing.rst b/Help/guide/tutorial/Installing and Testing.rst index 3f85df3..611749b 100644 --- a/Help/guide/tutorial/Installing and Testing.rst +++ b/Help/guide/tutorial/Installing and Testing.rst @@ -52,6 +52,8 @@ argument. For example: Navigate to the install directory and verify that the installed Tutorial runs. +.. _`Tutorial Testing Support`: + Testing Support --------------- diff --git a/Help/guide/tutorial/Packaging an Installer.rst b/Help/guide/tutorial/Packaging an Installer.rst index 037ae86..cee1da4 100644 --- a/Help/guide/tutorial/Packaging an Installer.rst +++ b/Help/guide/tutorial/Packaging an Installer.rst @@ -4,7 +4,7 @@ Step 7: Packaging an Installer Next suppose that we want to distribute our project to other people so that they can use it. We want to provide both binary and source distributions on a variety of platforms. This is a little different from the install we did -previously in `Installing and Testing (Step 4)`_ , where we were +previously in :guide:`tutorial/Installing and Testing`, where we were installing the binaries that we had built from the source code. In this example we will be building installation packages that support binary installations and package management features. To accomplish this we will use -- cgit v0.12 From fe60154fe8efc7528da92f6b9a6b17a6f9d4a179 Mon Sep 17 00:00:00 2001 From: Josef Angstenberger Date: Thu, 10 Jun 2021 23:42:39 +0200 Subject: Tutorial: Small formatting improvements - Use inline literals for all code fragments and names. - Add missing console code-blocks. - Always use c++, not c as code language. --- Help/guide/tutorial/A Basic Starting Point.rst | 8 ++++---- Help/guide/tutorial/Adding Export Configuration.rst | 10 +++++----- Help/guide/tutorial/Adding Generator Expressions.rst | 7 +++---- .../tutorial/Adding Support for a Testing Dashboard.rst | 6 +++++- Help/guide/tutorial/Adding System Introspection.rst | 6 +++--- .../tutorial/Adding Usage Requirements for a Library.rst | 6 +++--- .../Adding a Custom Command and Generated File.rst | 6 +++--- Help/guide/tutorial/Adding a Library.rst | 14 +++++++------- Help/guide/tutorial/Installing and Testing.rst | 4 ++-- Help/guide/tutorial/Packaging Debug and Release.rst | 2 +- .../tutorial/Selecting Static or Shared Libraries.rst | 13 +++++++------ 11 files changed, 43 insertions(+), 39 deletions(-) diff --git a/Help/guide/tutorial/A Basic Starting Point.rst b/Help/guide/tutorial/A Basic Starting Point.rst index 296b3c3..e5f7b91 100644 --- a/Help/guide/tutorial/A Basic Starting Point.rst +++ b/Help/guide/tutorial/A Basic Starting Point.rst @@ -56,7 +56,7 @@ Using your favorite editor, create ``TutorialConfig.h.in`` in the source directory with the following contents: .. literalinclude:: Step2/TutorialConfig.h.in - :language: cmake + :language: c++ When CMake configures this header file the values for ``@Tutorial_VERSION_MAJOR@`` and ``@Tutorial_VERSION_MINOR@`` will be @@ -89,9 +89,9 @@ We will need to explicitly state in the CMake code that it should use the correct flags. The easiest way to enable support for a specific C++ standard in CMake is by using the :variable:`CMAKE_CXX_STANDARD` variable. For this tutorial, set the :variable:`CMAKE_CXX_STANDARD` variable in the -``CMakeLists.txt`` file to 11 and :variable:`CMAKE_CXX_STANDARD_REQUIRED` to -True. Make sure to add the ``CMAKE_CXX_STANDARD`` declarations above the call -to ``add_executable``. +``CMakeLists.txt`` file to ``11`` and :variable:`CMAKE_CXX_STANDARD_REQUIRED` +to ``True``. Make sure to add the ``CMAKE_CXX_STANDARD`` declarations above the +call to ``add_executable``. .. literalinclude:: Step2/CMakeLists.txt :language: cmake diff --git a/Help/guide/tutorial/Adding Export Configuration.rst b/Help/guide/tutorial/Adding Export Configuration.rst index 6c283a6..b1d0f97 100644 --- a/Help/guide/tutorial/Adding Export Configuration.rst +++ b/Help/guide/tutorial/Adding Export Configuration.rst @@ -14,14 +14,14 @@ The first step is to update our :command:`install(TARGETS)` commands to not only specify a ``DESTINATION`` but also an ``EXPORT``. The ``EXPORT`` keyword generates and installs a CMake file containing code to import all targets listed in the install command from the installation tree. So let's go ahead and -explicitly ``EXPORT`` the MathFunctions library by updating the ``install`` +explicitly ``EXPORT`` the ``MathFunctions`` library by updating the ``install`` command in ``MathFunctions/CMakeLists.txt`` to look like: .. literalinclude:: Complete/MathFunctions/CMakeLists.txt :language: cmake :start-after: # install rules -Now that we have MathFunctions being exported, we also need to explicitly +Now that we have ``MathFunctions`` being exported, we also need to explicitly install the generated ``MathFunctionsTargets.cmake`` file. This is done by adding the following to the bottom of the top-level ``CMakeLists.txt``: @@ -45,10 +45,10 @@ you will see that CMake will generate an error that looks like: What CMake is trying to say is that during generating the export information it will export a path that is intrinsically tied to the current machine and will not be valid on other machines. The solution to this is to update the -MathFunctions :command:`target_include_directories` to understand that it needs -different ``INTERFACE`` locations when being used from within the build +``MathFunctions`` :command:`target_include_directories` to understand that it +needs different ``INTERFACE`` locations when being used from within the build directory and from an install / package. This means converting the -:command:`target_include_directories` call for MathFunctions to look like: +:command:`target_include_directories` call for ``MathFunctions`` to look like: .. literalinclude:: Step12/MathFunctions/CMakeLists.txt :language: cmake diff --git a/Help/guide/tutorial/Adding Generator Expressions.rst b/Help/guide/tutorial/Adding Generator Expressions.rst index 7a3abb1..f5a35f3 100644 --- a/Help/guide/tutorial/Adding Generator Expressions.rst +++ b/Help/guide/tutorial/Adding Generator Expressions.rst @@ -23,9 +23,9 @@ There are different types of Logical, Informational, and Output expressions. Logical expressions are used to create conditional output. The basic -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. +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 ` is to @@ -64,6 +64,5 @@ 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. - **Exercise**: Modify ``MathFunctions/CMakeLists.txt`` so that all targets have a :command:`target_link_libraries` call to ``tutorial_compiler_flags``. diff --git a/Help/guide/tutorial/Adding Support for a Testing Dashboard.rst b/Help/guide/tutorial/Adding Support for a Testing Dashboard.rst index 74d3f0f..775e8dd 100644 --- a/Help/guide/tutorial/Adding Support for a Testing Dashboard.rst +++ b/Help/guide/tutorial/Adding Support for a Testing Dashboard.rst @@ -37,10 +37,14 @@ executable or the :manual:`cmake-gui ` to configure the project, but do not build it yet. Instead, change directory to the binary tree, and then run: +.. code-block:: console + ctest [-VV] -D Experimental Remember, for multi-config generators (e.g. Visual Studio), the configuration -type must be specified:: +type must be specified: + +.. code-block:: console ctest [-VV] -C Debug -D Experimental diff --git a/Help/guide/tutorial/Adding System Introspection.rst b/Help/guide/tutorial/Adding System Introspection.rst index 0ee360c..924f904 100644 --- a/Help/guide/tutorial/Adding System Introspection.rst +++ b/Help/guide/tutorial/Adding System Introspection.rst @@ -11,8 +11,8 @@ If the platform has ``log`` and ``exp`` then we will use them to compute the square root in the ``mysqrt`` function. We first test for the availability of these functions using the :module:`CheckSymbolExists` module in ``MathFunctions/CMakeLists.txt``. On some platforms, we will need to link to -the m library. If ``log`` and ``exp`` are not initially found, require the m -library and try again. +the ``m`` library. If ``log`` and ``exp`` are not initially found, require the +``m`` library and try again. .. literalinclude:: Step6/MathFunctions/CMakeLists.txt :language: cmake @@ -47,4 +47,4 @@ Run the :manual:`cmake ` executable or the :manual:`cmake-gui ` to configure the project and then build it with your chosen build tool and run the Tutorial executable. -Which function gives better results now, sqrt or mysqrt? +Which function gives better results now, ``sqrt`` or ``mysqrt``? 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 6146a5e..ade75f0 100644 --- a/Help/guide/tutorial/Adding Usage Requirements for a Library.rst +++ b/Help/guide/tutorial/Adding Usage Requirements for a Library.rst @@ -13,8 +13,8 @@ requirements are: Let's refactor our code from :guide:`tutorial/Adding a Library` to use the modern CMake approach of usage requirements. We first state that anybody -linking to MathFunctions needs to include the current source directory, -while MathFunctions itself doesn't. So this can become an ``INTERFACE`` +linking to ``MathFunctions`` needs to include the current source directory, +while ``MathFunctions`` itself doesn't. So this can become an ``INTERFACE`` usage requirement. Remember ``INTERFACE`` means things that consumers require but the producer @@ -25,7 +25,7 @@ doesn't. Add the following lines to the end of :language: cmake :start-after: # to find MathFunctions.h -Now that we've specified usage requirements for MathFunctions we can safely +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: 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 0e3e60c..499df99 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 @@ -57,7 +57,7 @@ directories so that ``Table.h`` can be found and included by ``mysqrt.cxx``. :end-before: # install rules 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: +``Table.h``. Next, we can rewrite the ``mysqrt`` function to use the table: .. literalinclude:: Step7/MathFunctions/mysqrt.cxx :language: c++ @@ -69,7 +69,7 @@ with your chosen build tool. When this project is built it will first build the ``MakeTable`` executable. It will then run ``MakeTable`` to produce ``Table.h``. Finally, it will -compile ``mysqrt.cxx`` which includes ``Table.h`` to produce the MathFunctions -library. +compile ``mysqrt.cxx`` which includes ``Table.h`` to produce the +``MathFunctions`` library. Run the Tutorial executable and verify that it is using the table. diff --git a/Help/guide/tutorial/Adding a Library.rst b/Help/guide/tutorial/Adding a Library.rst index 3ff966c..4462aaa 100644 --- a/Help/guide/tutorial/Adding a Library.rst +++ b/Help/guide/tutorial/Adding a Library.rst @@ -41,7 +41,7 @@ last few lines of the top-level ``CMakeLists.txt`` file should now look like: "${PROJECT_SOURCE_DIR}/MathFunctions" ) -Now let us make the MathFunctions library optional. While for the tutorial +Now let us make the ``MathFunctions`` library optional. While for the tutorial there really isn't any need to do so, for larger projects this is a common occurrence. The first step is to add an option to the top-level ``CMakeLists.txt`` file. @@ -53,11 +53,11 @@ occurrence. The first step is to add an option to the top-level This option will be displayed in the :manual:`cmake-gui ` and :manual:`ccmake ` -with a default value of ON that can be changed by the user. This setting will -be stored in the cache so that the user does not need to set the value each -time they run CMake on a build directory. +with a default value of ``ON`` that can be changed by the user. This setting +will be stored in the cache so that the user does not need to set the value +each time they run CMake on a build directory. -The next change is to make building and linking the MathFunctions library +The next change is to make building and linking the ``MathFunctions`` library conditional. To do this we change the end of the top-level ``CMakeLists.txt`` file to look like the following: @@ -92,7 +92,7 @@ Since the source code now requires ``USE_MYMATH`` we can add it to ``TutorialConfig.h.in`` with the following line: .. literalinclude:: Step3/TutorialConfig.h.in - :language: c + :language: c++ :lines: 4 **Exercise**: Why is it important that we configure ``TutorialConfig.h.in`` @@ -113,4 +113,4 @@ command-line, try: Rebuild and run the tutorial again. -Which function gives better results, sqrt or mysqrt? +Which function gives better results, ``sqrt`` or ``mysqrt``? diff --git a/Help/guide/tutorial/Installing and Testing.rst b/Help/guide/tutorial/Installing and Testing.rst index 611749b..8bab454 100644 --- a/Help/guide/tutorial/Installing and Testing.rst +++ b/Help/guide/tutorial/Installing and Testing.rst @@ -6,8 +6,8 @@ Now we can start adding install rules and testing support to our project. Install Rules ------------- -The install rules are fairly simple: for MathFunctions we want to install the -library and header file and for the application we want to install the +The install rules are fairly simple: for ``MathFunctions`` we want to install +the library and header file and for the application we want to install the executable and configured header. So to the end of ``MathFunctions/CMakeLists.txt`` we add: diff --git a/Help/guide/tutorial/Packaging Debug and Release.rst b/Help/guide/tutorial/Packaging Debug and Release.rst index b73378c..1f90268 100644 --- a/Help/guide/tutorial/Packaging Debug and Release.rst +++ b/Help/guide/tutorial/Packaging Debug and Release.rst @@ -28,7 +28,7 @@ And the :prop_tgt:`DEBUG_POSTFIX` property on the tutorial executable: :start-after: # add the executable :end-before: # add the binary tree to the search path for include files -Let's also add version numbering to the MathFunctions library. In +Let's also add version numbering to the ``MathFunctions`` library. In ``MathFunctions/CMakeLists.txt``, set the :prop_tgt:`VERSION` and :prop_tgt:`SOVERSION` properties: diff --git a/Help/guide/tutorial/Selecting Static or Shared Libraries.rst b/Help/guide/tutorial/Selecting Static or Shared Libraries.rst index c9b5e31..4a7a86a 100644 --- a/Help/guide/tutorial/Selecting Static or Shared Libraries.rst +++ b/Help/guide/tutorial/Selecting Static or Shared Libraries.rst @@ -8,12 +8,13 @@ and allow control over how libraries without an explicit type (``STATIC``, 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. +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 +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. +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: @@ -22,7 +23,7 @@ The first step is to update the starting section of the top-level :language: cmake :end-before: # add the binary tree -Now that we have made MathFunctions always be used, we will need to update +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 @@ -45,7 +46,7 @@ uses ``USE_MYMATH``: #. Always include ``MathFunctions.h`` #. Always use ``mathfunctions::sqrt`` -#. Don't include cmath +#. Don't include ``cmath`` Finally, update ``MathFunctions/MathFunctions.h`` to use dll export defines: @@ -56,7 +57,7 @@ At this point, if you build everything, you may notice that linking fails as we are combining a static library without position independent code with a library that has position independent code. The solution to this is to explicitly set the :prop_tgt:`POSITION_INDEPENDENT_CODE` target property of -SqrtLibrary to be True no matter the build type. +SqrtLibrary to be ``True`` no matter the build type. .. literalinclude:: Step10/MathFunctions/CMakeLists.txt :language: cmake -- cgit v0.12 From 9e5bbb69eaa21830e1e306e0705ba32213def064 Mon Sep 17 00:00:00 2001 From: Josef Angstenberger Date: Fri, 11 Jun 2021 00:20:58 +0200 Subject: Tutorial: Add captions for code blocks --- Help/guide/tutorial/A Basic Starting Point.rst | 8 ++++++++ Help/guide/tutorial/Adding Export Configuration.rst | 6 ++++++ Help/guide/tutorial/Adding Generator Expressions.rst | 3 +++ Help/guide/tutorial/Adding Support for a Testing Dashboard.rst | 3 +++ Help/guide/tutorial/Adding System Introspection.rst | 4 ++++ Help/guide/tutorial/Adding Usage Requirements for a Library.rst | 3 +++ .../guide/tutorial/Adding a Custom Command and Generated File.rst | 5 +++++ Help/guide/tutorial/Adding a Library.rst | 7 +++++++ Help/guide/tutorial/Installing and Testing.rst | 3 +++ Help/guide/tutorial/Packaging Debug and Release.rst | 4 ++++ Help/guide/tutorial/Packaging an Installer.rst | 1 + Help/guide/tutorial/Selecting Static or Shared Libraries.rst | 5 +++++ 12 files changed, 52 insertions(+) diff --git a/Help/guide/tutorial/A Basic Starting Point.rst b/Help/guide/tutorial/A Basic Starting Point.rst index e5f7b91..20e4129 100644 --- a/Help/guide/tutorial/A Basic Starting Point.rst +++ b/Help/guide/tutorial/A Basic Starting Point.rst @@ -7,6 +7,7 @@ required. This will be the starting point for our tutorial. Create a ``CMakeLists.txt`` file in the ``Step1`` directory that looks like: .. code-block:: cmake + :caption: CMakeLists.txt cmake_minimum_required(VERSION 3.10) @@ -33,6 +34,7 @@ First, modify the ``CMakeLists.txt`` file to use the :command:`project` command to set the project name and version number. .. literalinclude:: Step2/CMakeLists.txt + :caption: CMakeLists.txt :language: cmake :end-before: # specify the C++ standard @@ -40,6 +42,7 @@ Then, configure a header file to pass the version number to the source code: .. literalinclude:: Step2/CMakeLists.txt + :caption: CMakeLists.txt :language: cmake :start-after: # to the source code :end-before: # add the executable @@ -49,6 +52,7 @@ must add that directory to the list of paths to search for include files. Add the following lines to the end of the ``CMakeLists.txt`` file: .. literalinclude:: Step2/CMakeLists.txt + :caption: CMakeLists.txt :language: cmake :start-after: # so that we will find TutorialConfig.h @@ -56,6 +60,7 @@ Using your favorite editor, create ``TutorialConfig.h.in`` in the source directory with the following contents: .. literalinclude:: Step2/TutorialConfig.h.in + :caption: TutorialConfig.h.in :language: c++ When CMake configures this header file the values for @@ -69,6 +74,7 @@ Finally, let's print out the executable name and version number by updating ``tutorial.cxx`` as follows: .. literalinclude:: Step2/tutorial.cxx + :caption: tutorial.cxx :language: c++ :start-after: { :end-before: // convert input to double @@ -81,6 +87,7 @@ Next let's add some C++11 features to our project by replacing ``atof`` with ``#include ``. .. literalinclude:: Step2/tutorial.cxx + :caption: tutorial.cxx :language: c++ :start-after: // convert input to double :end-before: // calculate square root @@ -94,6 +101,7 @@ to ``True``. Make sure to add the ``CMAKE_CXX_STANDARD`` declarations above the call to ``add_executable``. .. literalinclude:: Step2/CMakeLists.txt + :caption: CMakeLists.txt :language: cmake :end-before: # configure a header file to pass some of the CMake settings diff --git a/Help/guide/tutorial/Adding Export Configuration.rst b/Help/guide/tutorial/Adding Export Configuration.rst index b1d0f97..da0d877 100644 --- a/Help/guide/tutorial/Adding Export Configuration.rst +++ b/Help/guide/tutorial/Adding Export Configuration.rst @@ -18,6 +18,7 @@ explicitly ``EXPORT`` the ``MathFunctions`` library by updating the ``install`` command in ``MathFunctions/CMakeLists.txt`` to look like: .. literalinclude:: Complete/MathFunctions/CMakeLists.txt + :caption: MathFunctions/CMakeLists.txt :language: cmake :start-after: # install rules @@ -26,6 +27,7 @@ install the generated ``MathFunctionsTargets.cmake`` file. This is done by adding the following to the bottom of the top-level ``CMakeLists.txt``: .. literalinclude:: Complete/CMakeLists.txt + :caption: CMakeLists.txt :language: cmake :start-after: # install the configuration targets :end-before: include(CMakePackageConfigHelpers) @@ -51,6 +53,7 @@ directory and from an install / package. This means converting the :command:`target_include_directories` call for ``MathFunctions`` to look like: .. literalinclude:: Step12/MathFunctions/CMakeLists.txt + :caption: MathFunctions/CMakeLists.txt :language: cmake :start-after: # to find MathFunctions.h, while we don't. :end-before: # should we use our own math functions @@ -65,11 +68,13 @@ ahead and add a new file to the top-level of the project called ``Config.cmake.in`` with the following contents: .. literalinclude:: Step12/Config.cmake.in + :caption: Config.cmake.in Then, to properly configure and install that file, add the following to the bottom of the top-level ``CMakeLists.txt``: .. literalinclude:: Step12/CMakeLists.txt + :caption: CMakeLists.txt :language: cmake :start-after: # install the configuration targets :end-before: # generate the export @@ -80,6 +85,7 @@ we want our project to also be used from a build directory we only have to add the following to the bottom of the top level ``CMakeLists.txt``: .. literalinclude:: Step12/CMakeLists.txt + :caption: CMakeLists.txt :language: cmake :start-after: # needs to be after the install(TARGETS ) command diff --git a/Help/guide/tutorial/Adding Generator Expressions.rst b/Help/guide/tutorial/Adding Generator Expressions.rst index f5a35f3..b21fc62 100644 --- a/Help/guide/tutorial/Adding Generator Expressions.rst +++ b/Help/guide/tutorial/Adding Generator Expressions.rst @@ -38,6 +38,7 @@ instead of using :variable:`CMAKE_CXX_STANDARD`. So the following code: .. literalinclude:: Step10/CMakeLists.txt + :caption: CMakeLists.txt :language: cmake :start-after: project(Tutorial VERSION 1.0) :end-before: # control where the static and shared libraries are built so that on windows @@ -45,6 +46,7 @@ So the following code: Would be replaced with: .. literalinclude:: Step11/CMakeLists.txt + :caption: CMakeLists.txt :language: cmake :start-after: project(Tutorial VERSION 1.0) :end-before: # add compiler warning flags just when building this project via @@ -56,6 +58,7 @@ generator expression to control which flags to apply given a language and a set of compiler ids as seen below: .. literalinclude:: Step11/CMakeLists.txt + :caption: CMakeLists.txt :language: cmake :start-after: # the BUILD_INTERFACE genex :end-before: # control where the static and shared libraries are built so that on windows diff --git a/Help/guide/tutorial/Adding Support for a Testing Dashboard.rst b/Help/guide/tutorial/Adding Support for a Testing Dashboard.rst index 775e8dd..9cdbb34 100644 --- a/Help/guide/tutorial/Adding Support for a Testing Dashboard.rst +++ b/Help/guide/tutorial/Adding Support for a Testing Dashboard.rst @@ -10,6 +10,7 @@ we include the :module:`CTest` module in our top-level ``CMakeLists.txt``. Replace: .. code-block:: cmake + :caption: CMakeLists.txt # enable testing enable_testing() @@ -17,6 +18,7 @@ Replace: With: .. code-block:: cmake + :caption: CMakeLists.txt # enable dashboard scripting include(CTest) @@ -29,6 +31,7 @@ directory where we can specify the name of the project and where to submit the dashboard. .. literalinclude:: Step9/CTestConfig.cmake + :caption: CTestConfig.cmake :language: cmake The :manual:`ctest ` executable will read in this file when it runs. diff --git a/Help/guide/tutorial/Adding System Introspection.rst b/Help/guide/tutorial/Adding System Introspection.rst index 924f904..c11f793 100644 --- a/Help/guide/tutorial/Adding System Introspection.rst +++ b/Help/guide/tutorial/Adding System Introspection.rst @@ -15,6 +15,7 @@ the ``m`` library. If ``log`` and ``exp`` are not initially found, require the ``m`` library and try again. .. literalinclude:: Step6/MathFunctions/CMakeLists.txt + :caption: MathFunctions/CMakeLists.txt :language: cmake :start-after: # does this system provide the log and exp functions? :end-before: # add compile definitions @@ -23,6 +24,7 @@ If available, use :command:`target_compile_definitions` to specify ``HAVE_LOG`` and ``HAVE_EXP`` as ``PRIVATE`` compile definitions. .. literalinclude:: Step6/MathFunctions/CMakeLists.txt + :caption: MathFunctions/CMakeLists.txt :language: cmake :start-after: # add compile definitions :end-before: # install rules @@ -33,6 +35,7 @@ the ``mysqrt`` function in ``MathFunctions/mysqrt.cxx`` (don't forget the ``#endif`` before returning the result!): .. literalinclude:: Step6/MathFunctions/mysqrt.cxx + :caption: MathFunctions/mysqrt.cxx :language: c++ :start-after: // if we have both log and exp then use them :end-before: // do ten iterations @@ -40,6 +43,7 @@ the ``mysqrt`` function in ``MathFunctions/mysqrt.cxx`` (don't forget the We will also need to modify ``mysqrt.cxx`` to include ``cmath``. .. literalinclude:: Step6/MathFunctions/mysqrt.cxx + :caption: MathFunctions/mysqrt.cxx :language: c++ :end-before: #include 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 ade75f0..8ef9cc6 100644 --- a/Help/guide/tutorial/Adding Usage Requirements for a Library.rst +++ b/Help/guide/tutorial/Adding Usage Requirements for a Library.rst @@ -22,6 +22,7 @@ doesn't. Add the following lines to the end of ``MathFunctions/CMakeLists.txt``: .. literalinclude:: Step4/MathFunctions/CMakeLists.txt + :caption: MathFunctions/CMakeLists.txt :language: cmake :start-after: # to find MathFunctions.h @@ -30,6 +31,7 @@ remove our uses of the ``EXTRA_INCLUDES`` variable from the top-level ``CMakeLists.txt``, here: .. literalinclude:: Step4/CMakeLists.txt + :caption: CMakeLists.txt :language: cmake :start-after: # add the MathFunctions library :end-before: # add the executable @@ -37,6 +39,7 @@ remove our uses of the ``EXTRA_INCLUDES`` variable from the top-level And here: .. literalinclude:: Step4/CMakeLists.txt + :caption: CMakeLists.txt :language: cmake :start-after: # so that we will find TutorialConfig.h 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 499df99..c60379a 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 @@ -27,6 +27,7 @@ First, at the top of ``MathFunctions/CMakeLists.txt``, the executable for ``MakeTable`` is added as any other executable would be added. .. literalinclude:: Step7/MathFunctions/CMakeLists.txt + :caption: MathFunctions/CMakeLists.txt :language: cmake :start-after: # first we add the executable that generates the table :end-before: # add the command to generate the source code @@ -35,6 +36,7 @@ Then we add a custom command that specifies how to produce ``Table.h`` by running MakeTable. .. literalinclude:: Step7/MathFunctions/CMakeLists.txt + :caption: MathFunctions/CMakeLists.txt :language: cmake :start-after: # add the command to generate the source code :end-before: # add the main library @@ -44,6 +46,7 @@ file ``Table.h``. This is done by adding the generated ``Table.h`` to the list of sources for the library MathFunctions. .. literalinclude:: Step7/MathFunctions/CMakeLists.txt + :caption: MathFunctions/CMakeLists.txt :language: cmake :start-after: # add the main library :end-before: # state that anybody linking @@ -52,6 +55,7 @@ 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``. .. literalinclude:: Step7/MathFunctions/CMakeLists.txt + :caption: MathFunctions/CMakeLists.txt :language: cmake :start-after: # state that we depend on our bin :end-before: # install rules @@ -60,6 +64,7 @@ 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: .. literalinclude:: Step7/MathFunctions/mysqrt.cxx + :caption: MathFunctions/mysqrt.cxx :language: c++ :start-after: // a hack square root calculation using simple operations diff --git a/Help/guide/tutorial/Adding a Library.rst b/Help/guide/tutorial/Adding a Library.rst index 4462aaa..02f7ed1 100644 --- a/Help/guide/tutorial/Adding a Library.rst +++ b/Help/guide/tutorial/Adding a Library.rst @@ -16,6 +16,7 @@ Add the following one line ``CMakeLists.txt`` file to the ``MathFunctions`` directory: .. literalinclude:: Step3/MathFunctions/CMakeLists.txt + :caption: MathFunctions/CMakeLists.txt :language: cmake To make use of the new library we will add an :command:`add_subdirectory` @@ -25,6 +26,7 @@ an include directory so that the ``mysqrt.h`` header file can be found. The last few lines of the top-level ``CMakeLists.txt`` file should now look like: .. code-block:: cmake + :caption: CMakeLists.txt # add the MathFunctions library add_subdirectory(MathFunctions) @@ -47,6 +49,7 @@ occurrence. The first step is to add an option to the top-level ``CMakeLists.txt`` file. .. literalinclude:: Step3/CMakeLists.txt + :caption: CMakeLists.txt :language: cmake :start-after: # should we use our own math functions :end-before: # add the MathFunctions library @@ -62,6 +65,7 @@ conditional. To do this we change the end of the top-level ``CMakeLists.txt`` file to look like the following: .. literalinclude:: Step3/CMakeLists.txt + :caption: CMakeLists.txt :language: cmake :start-after: # add the MathFunctions library @@ -76,6 +80,7 @@ First, in ``tutorial.cxx``, include the ``MathFunctions.h`` header if we need it: .. literalinclude:: Step3/tutorial.cxx + :caption: tutorial.cxx :language: c++ :start-after: // should we include the MathFunctions header :end-before: int main @@ -84,6 +89,7 @@ Then, in the same file, make ``USE_MYMATH`` control which square root function is used: .. literalinclude:: Step3/tutorial.cxx + :caption: tutorial.cxx :language: c++ :start-after: // which square root function should we use? :end-before: std::cout << "The square root of @@ -92,6 +98,7 @@ Since the source code now requires ``USE_MYMATH`` we can add it to ``TutorialConfig.h.in`` with the following line: .. literalinclude:: Step3/TutorialConfig.h.in + :caption: TutorialConfig.h.in :language: c++ :lines: 4 diff --git a/Help/guide/tutorial/Installing and Testing.rst b/Help/guide/tutorial/Installing and Testing.rst index 8bab454..53f0363 100644 --- a/Help/guide/tutorial/Installing and Testing.rst +++ b/Help/guide/tutorial/Installing and Testing.rst @@ -13,12 +13,14 @@ executable and configured header. So to the end of ``MathFunctions/CMakeLists.txt`` we add: .. literalinclude:: Step5/MathFunctions/CMakeLists.txt + :caption: MathFunctions/CMakeLists.txt :language: cmake :start-after: # install rules And to the end of the top-level ``CMakeLists.txt`` we add: .. literalinclude:: Step5/CMakeLists.txt + :caption: CMakeLists.txt :language: cmake :start-after: # add the install targets :end-before: # enable testing @@ -62,6 +64,7 @@ file we can enable testing and then add a number of basic tests to verify that the application is working correctly. .. literalinclude:: Step5/CMakeLists.txt + :caption: CMakeLists.txt :language: cmake :start-after: # enable testing diff --git a/Help/guide/tutorial/Packaging Debug and Release.rst b/Help/guide/tutorial/Packaging Debug and Release.rst index 1f90268..c2bf1b5 100644 --- a/Help/guide/tutorial/Packaging Debug and Release.rst +++ b/Help/guide/tutorial/Packaging Debug and Release.rst @@ -17,6 +17,7 @@ Set :variable:`CMAKE_DEBUG_POSTFIX` near the beginning of the top-level ``CMakeLists.txt`` file: .. literalinclude:: Complete/CMakeLists.txt + :caption: CMakeLists.txt :language: cmake :start-after: project(Tutorial VERSION 1.0) :end-before: target_compile_features(tutorial_compiler_flags @@ -24,6 +25,7 @@ Set :variable:`CMAKE_DEBUG_POSTFIX` near the beginning of the top-level And the :prop_tgt:`DEBUG_POSTFIX` property on the tutorial executable: .. literalinclude:: Complete/CMakeLists.txt + :caption: CMakeLists.txt :language: cmake :start-after: # add the executable :end-before: # add the binary tree to the search path for include files @@ -33,6 +35,7 @@ Let's also add version numbering to the ``MathFunctions`` library. In :prop_tgt:`SOVERSION` properties: .. literalinclude:: Complete/MathFunctions/CMakeLists.txt + :caption: MathFunctions/CMakeLists.txt :language: cmake :start-after: # setup the version numbering :end-before: # install rules @@ -68,6 +71,7 @@ Next, use the ``CPACK_INSTALL_CMAKE_PROJECTS`` variable to specify which projects to install. In this case, we want to install both debug and release. .. literalinclude:: Complete/MultiCPackConfig.cmake + :caption: MultiCPackConfig.cmake :language: cmake From the ``Step12`` directory, run :manual:`cpack ` specifying our diff --git a/Help/guide/tutorial/Packaging an Installer.rst b/Help/guide/tutorial/Packaging an Installer.rst index cee1da4..f3a5e12 100644 --- a/Help/guide/tutorial/Packaging an Installer.rst +++ b/Help/guide/tutorial/Packaging an Installer.rst @@ -12,6 +12,7 @@ CPack to create platform specific installers. Specifically we need to add a few lines to the bottom of our top-level ``CMakeLists.txt`` file. .. literalinclude:: Step8/CMakeLists.txt + :caption: CMakeLists.txt :language: cmake :start-after: # setup installer diff --git a/Help/guide/tutorial/Selecting Static or Shared Libraries.rst b/Help/guide/tutorial/Selecting Static or Shared Libraries.rst index 4a7a86a..85dcbf5 100644 --- a/Help/guide/tutorial/Selecting Static or Shared Libraries.rst +++ b/Help/guide/tutorial/Selecting Static or Shared Libraries.rst @@ -20,6 +20,7 @@ The first step is to update the starting section of the top-level ``CMakeLists.txt`` to look like: .. literalinclude:: Step10/CMakeLists.txt + :caption: CMakeLists.txt :language: cmake :end-before: # add the binary tree @@ -32,6 +33,7 @@ explicitly require that SqrtLibrary is built statically. The end result is that ``MathFunctions/CMakeLists.txt`` should look like: .. literalinclude:: Step10/MathFunctions/CMakeLists.txt + :caption: MathFunctions/CMakeLists.txt :language: cmake :lines: 1-36,42- @@ -39,6 +41,7 @@ Next, update ``MathFunctions/mysqrt.cxx`` to use the ``mathfunctions`` and ``detail`` namespaces: .. literalinclude:: Step10/MathFunctions/mysqrt.cxx + :caption: MathFunctions/mysqrt.cxx :language: c++ We also need to make some changes in ``tutorial.cxx``, so that it no longer @@ -51,6 +54,7 @@ uses ``USE_MYMATH``: Finally, update ``MathFunctions/MathFunctions.h`` to use dll export defines: .. literalinclude:: Step10/MathFunctions/MathFunctions.h + :caption: MathFunctions/MathFunctions.h :language: c++ At this point, if you build everything, you may notice that linking fails @@ -60,6 +64,7 @@ explicitly set the :prop_tgt:`POSITION_INDEPENDENT_CODE` target property of SqrtLibrary to be ``True`` no matter the build type. .. literalinclude:: Step10/MathFunctions/CMakeLists.txt + :caption: MathFunctions/CMakeLists.txt :language: cmake :lines: 37-42 -- cgit v0.12 From 9c703ff7412c2f5ba3992674c3ed73e21d9d014b Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 17 Jun 2021 12:10:14 -0400 Subject: Tutorial: Add infrastructure to preserve old links when renaming steps --- Help/guide/tutorial/index.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Help/guide/tutorial/index.rst b/Help/guide/tutorial/index.rst index 8a765fd..8b20a2d 100644 --- a/Help/guide/tutorial/index.rst +++ b/Help/guide/tutorial/index.rst @@ -32,3 +32,12 @@ provides the complete solution for the previous step. Adding Generator Expressions Adding Export Configuration Packaging Debug and Release + +.. + Whenever a step above is renamed or removed, leave forwarding text in + its original document file, and list it below to preserve old links + to cmake.org/cmake/help/latest/ URLs. + +.. toctree:: + :maxdepth: 1 + :hidden: -- cgit v0.12