summaryrefslogtreecommitdiffstats
path: root/Help/guide
diff options
context:
space:
mode:
authorMarkus Ferrell <markus.ferrell@kitware.com>2022-07-21 17:43:58 (GMT)
committerMarkus Ferrell <markus.ferrell@kitware.com>2022-08-15 16:06:34 (GMT)
commitc59e1641554cb1b18f4b3a62d20559cfb689a9df (patch)
tree3c50e94d07da244c72ca3b8fafa902920dbac49c /Help/guide
parent1493ed10a1485053bb0b7101ccd71d0101977402 (diff)
downloadCMake-c59e1641554cb1b18f4b3a62d20559cfb689a9df.zip
CMake-c59e1641554cb1b18f4b3a62d20559cfb689a9df.tar.gz
CMake-c59e1641554cb1b18f4b3a62d20559cfb689a9df.tar.bz2
Tutorial: Add Step 1 background info and update style
Diffstat (limited to 'Help/guide')
-rw-r--r--Help/guide/tutorial/A Basic Starting Point.rst392
-rw-r--r--Help/guide/tutorial/Step1/CMakeLists.txt16
-rw-r--r--Help/guide/tutorial/Step1/TutorialConfig.h.in2
-rw-r--r--Help/guide/tutorial/Step1/tutorial.cxx7
4 files changed, 313 insertions, 104 deletions
diff --git a/Help/guide/tutorial/A Basic Starting Point.rst b/Help/guide/tutorial/A Basic Starting Point.rst
index d57cc35..33f712d 100644
--- a/Help/guide/tutorial/A Basic Starting Point.rst
+++ b/Help/guide/tutorial/A Basic Starting Point.rst
@@ -1,45 +1,81 @@
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
- :caption: CMakeLists.txt
- :name: CMakeLists.txt-start
-
- cmake_minimum_required(VERSION 3.10)
-
- # set the project name
- project(Tutorial)
-
- # add the executable
- add_executable(Tutorial tutorial.cxx)
-
+Where do I start with CMake? This step will provide an introduction to some of
+CMake's basic syntax, commands, and variables. As these concepts are
+introduced, we will work through three exercises and create a simple CMake
+project.
+
+Each exercise in this step will start with some background information. Then, a
+goal and list of helpful resources are provided. Each file in the
+``Files to Edit`` section is in the ``Step1`` directory and contains one or
+more ``TODO`` comments. Each ``TODO`` represents a line or two of code to
+change or add. The ``TODO`` s are intended to be completed in numerical order,
+first complete ``TODO 1`` then ``TODO 2``, etc. The ``Getting Started``
+section will give some helpful hints and guide you through the exercise. Then
+the ``Build and Run`` section will walk step-by-step through how to build and
+test the exercise. Finally, at the end of each exercise the intended solution
+is discussed.
+
+Also note that each step in the tutorial builds on the next. So, for example,
+the starting code for ``Step2`` is the complete solution to ``Step1``.
+
+Exercise 1 - Building a Basic Project
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The most basic CMake project is an executable built from a single source code
+file. For simple projects like this, a ``CMakeLists.txt`` file with three
+commands is all that is required.
+
+**Note:** Although upper, lower and mixed case commands are supported by CMake,
+lower case commands are preferred and will be used throughout the tutorial.
+
+Any project's top most CMakeLists.txt must start by specifying a minimum CMake
+version using the :command:`cmake_minimum_required` command. This establishes
+policy settings and ensures that the following CMake functions are run with a
+compatible version of CMake.
+
+To start a project, we use the :command:`project` command to set the project
+name. This call is required with every project and should be called soon after
+:command:`cmake_minimum_required`. As we will see later, this command can
+also be used to specify other project level information such as the language
+or version number.
+
+Finally, the :command:`add_executable` command tells CMake to create an
+executable using the specified source code files.
+
+Goal
+----
+
+Understand how to create a simple CMake project.
+
+Helpful Resources
+-----------------
+
+* :command:`add_executable`
+* :command:`cmake_minimum_required`
+* :command:`project`
+
+Files to Edit
+-------------
-Any project's top most ``CMakeLists.txt`` must start by specifying
-a minimum CMake version using :command:`cmake_minimum_required`. This ensures
-that the later CMake functions are run with a compatible version of CMake.
+* ``CMakeLists.txt``
-To start a project, we use :command:`project` to set the project name. This
-call is required with every project and should be called soon after
-:command:`cmake_minimum_required`.
+Getting Started
+----------------
-Lastly, we use :command:`add_executable` to specify we want an executable
-named Tutorial generated using ``tutorial.cxx`` as the source.
+The source code for ``tutorial.cxx`` is provided in the
+``Help/guide/tutorial/Step1`` directory and can be used to compute the square
+root of a number. This file does not need to be edited in this step.
-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.
+In the same directory is a ``CMakeLists.txt`` file which you will complete.
+Start with ``TODO 1`` and work through ``TODO 3``.
Build and Run
-------------
-That's all that is needed - we can build and run our project now! First, run
-the :manual:`cmake <cmake(1)>` executable or the
+Once ``TODO 1`` through ``TODO 3`` have been completed, we are ready to build
+and run our project! First, run the :manual:`cmake <cmake(1)>` executable or the
:manual:`cmake-gui <cmake-gui(1)>` to configure the project and then build it
with your chosen build tool.
@@ -51,8 +87,9 @@ build directory:
mkdir Step1_build
-Next, navigate to the build directory and run CMake to configure the project
-and generate a native build system:
+Next, navigate to that build directory and run
+:manual:`cmake <cmake(1)>` to configure the project and generate a native build
+system:
.. code-block:: console
@@ -73,115 +110,264 @@ Finally, try to use the newly built ``Tutorial`` with these commands:
Tutorial 10
Tutorial
+Solution
+--------
-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.
+As mentioned above, a three line ``CMakeLists.txt`` is all that we need to get
+up and running. The first line is to use :command:`cmake_minimum_required` to
+set the CMake version as follows:
.. literalinclude:: Step2/CMakeLists.txt
- :caption: CMakeLists.txt
- :name: CMakeLists.txt-project-VERSION
+ :caption: TODO 1: CMakeLists.txt
+ :name: CMakeLists.txt-cmake_minimum_required
:language: cmake
- :end-before: # specify the C++ standard
+ :end-before: # set the project name and version
-Then use :command:`configure_file` to pass the version number to the source
-code:
+The next step to make a basic project is to use the :command:`project`
+command as follows to set the project name:
-.. literalinclude:: Step2/CMakeLists.txt
- :caption: CMakeLists.txt
- :name: CMakeLists.txt-configure_file
- :language: cmake
- :start-after: # to the source code
- :end-before: # add the executable
+.. code-block:: cmake
+ :caption: TODO 2: CMakeLists.txt
+ :name: CMakeLists.txt-project
-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. Use :command:`target_include_directories` to add the following lines to
-the end of the ``CMakeLists.txt`` file:
+ project(Tutorial)
+
+
+The last command to call for a basic project is
+:command:`add_executable`. We call it as follows:
.. literalinclude:: Step2/CMakeLists.txt
- :caption: CMakeLists.txt
- :name: CMakeLists.txt-target_include_directories
+ :caption: TODO 3: CMakeLists.txt
+ :name: CMakeLists.txt-add_executable
:language: cmake
- :start-after: # so that we will find TutorialConfig.h
+ :start-after: # add the executable
+ :end-before: # add the binary tree to the search path for include files
-Using your favorite editor, create ``TutorialConfig.h.in`` in the source
-directory with the following contents:
+Exercise 2 - Specifying the C++ Standard
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-.. literalinclude:: Step2/TutorialConfig.h.in
- :caption: TutorialConfig.h.in
- :name: TutorialConfig.h.in
- :language: c++
+CMake has some special variables that are either created behind the scenes or
+have meaning to CMake when set by project code. Many of these variables start
+with ``CMAKE_``. Avoid this naming convention when creating variables for your
+projects. Two of these special user settable variables are
+:variable:`CMAKE_CXX_STANDARD` and :variable:`CMAKE_CXX_STANDARD_REQUIRED`.
+These may be used together to specify the C++ standard needed to build the
+project.
-When CMake configures this header file, the values for
-``@Tutorial_VERSION_MAJOR@`` and ``@Tutorial_VERSION_MINOR@`` will be
-replaced with the corresponding version numbers from the project.
+Goal
+----
-Next modify ``tutorial.cxx`` to include the configured header file,
-``TutorialConfig.h``.
+Add a feature that requires C++11.
-Finally, let's print out the executable name and version number by updating
-``tutorial.cxx`` as follows:
+Helpful Resources
+-----------------
-.. literalinclude:: Step2/tutorial.cxx
- :caption: tutorial.cxx
- :name: tutorial.cxx-print-version
- :language: c++
- :start-after: {
- :end-before: // convert input to double
+* :variable:`CMAKE_CXX_STANDARD`
+* :variable:`CMAKE_CXX_STANDARD_REQUIRED`
+* :command:`set`
+
+Files to Edit
+-------------
+
+* ``CMakeLists.txt``
+* ``tutorial.cxx``
+
+Getting Started
+---------------
-Specify the C++ Standard
--------------------------
+Continue editing files in the ``Step1`` directory. Start with ``TODO 4`` and
+complete through ``TODO 6``.
-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 <cstdlib>``.
+First, edit ``tutorial.cxx`` by adding a feature that requires C++11. Then
+update ``CMakeLists.txt`` to require C++11.
+
+Build and Run
+-------------
+
+Let's build our project again. Since we already created a build directory and
+ran CMake for Exercise 1, we can skip to the build step:
+
+.. code-block:: console
+
+ cd Step1_build
+ cmake --build .
+
+Now we can try to use the newly built ``Tutorial`` with same commands as
+before:
+
+.. code-block:: console
+
+ Tutorial 4294967296
+ Tutorial 10
+ Tutorial
+
+Solution
+--------
+
+We start by adding some C++11 features to our project by replacing
+``atof`` with ``std::stod`` in ``tutorial.cxx``. This looks like
+the following:
.. literalinclude:: Step2/tutorial.cxx
- :caption: tutorial.cxx
+ :caption: TODO 4: tutorial.cxx
:name: tutorial.cxx-cxx11
:language: c++
:start-after: // convert input to double
:end-before: // calculate square root
+To complete ``TODO 5``, simply remove ``#include <cstdlib>``.
+
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, :command:`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``.
+correct flags. One 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 :variable:`CMAKE_CXX_STANDARD` declarations above the call to
+:command:`add_executable`.
.. literalinclude:: Step2/CMakeLists.txt
- :caption: CMakeLists.txt
+ :caption: TODO 6: CMakeLists.txt
:name: CMakeLists.txt-CXX_STANDARD
:language: cmake
+ :start-after: # specify the C++ standard
:end-before: # configure a header file to pass some of the CMake settings
-Rebuild
--------
+Exercise 3 - Adding a Version Number and Configured Header File
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Sometimes it may be useful to have a variable that is defined in your
+``CMakelists.txt`` file also be available in your source code. In this case, we
+would like to print the project version.
+
+One way to accomplish this is by using a configured header file. We create an
+input file with one or more variables to replace. These variables have special
+syntax which looks like ``@VAR@``.
+Then, we use the :command:`configure_file` command to copy the input file to a
+given output file and replace these variables with the current value of ``VAR``
+in the ``CMakelists.txt`` file.
-Let's build our project again. We already created a build directory and ran
-CMake, so we can skip to the build step:
+While we could edit the version directly in the source code, using this
+feature is preferred since it creates a single source of truth and avoids
+duplication.
+
+Goal
+----
+
+Define and report the project's version number.
+
+Helpful Resources
+-----------------
+
+* :variable:`<PROJECT-NAME>_VERSION_MAJOR`
+* :variable:`<PROJECT-NAME>_VERSION_MINOR`
+* :command:`configure_file`
+* :command:`target_include_directories`
+
+Files to Edit
+-------------
+
+* ``CMakeLists.txt``
+* ``tutorial.cxx``
+
+Getting Started
+---------------
+
+Continue to edit files from ``Step1``. Start on ``TODO 7`` and complete through
+``TODO 12``. In this exercise, we start by adding a project version number in
+``CMakeLists.txt``. In that same file, use :command:`configure_file` to copy a
+given input file to an output file and substitute some variable values in the
+input file content.
+
+Next, create an input header file ``TutorialConfig.h.in`` defining version
+numbers which will accept variables passed from :command:`configure_file`.
+
+Finally, update ``tutorial.cxx`` to print out its version number.
+
+Build and Run
+-------------
+
+Let's build our project again. As before, we already created a build directory
+and ran CMake so we can skip to the build step:
.. code-block:: console
cd Step1_build
cmake --build .
-Now we can try to use the newly built ``Tutorial`` with same commands as before:
+Verify that the version number is now reported when running the executable
+without any arguments.
-.. code-block:: console
+Solution
+--------
- Tutorial 4294967296
- Tutorial 10
- Tutorial
+In this exercise, we improve our executable by printing a version number.
+While we could do this exclusively in the source code, using ``CMakeLists.txt``
+lets us maintain a single source of data for the version number.
+
+First, we modify the ``CMakeLists.txt`` file to use the
+:command:`project` command to set both the project name and version number.
+When the command:`project` command is called, CMake defines
+``Tutorial_VERSION_MAJOR`` and ``Tutorial_VERSION_MINOR`` behind the scenes.
+
+.. literalinclude:: Step2/CMakeLists.txt
+ :caption: TODO 7: CMakeLists.txt
+ :name: CMakeLists.txt-project-VERSION
+ :language: cmake
+ :start-after: # set the project name and version
+ :end-before: # specify the C++ standard
+
+Then we used :command:`configure_file` to copy the input file with the
+specified CMake variables replaced:
-Check that the version number is now reported when running the executable without
-any arguments.
+.. literalinclude:: Step2/CMakeLists.txt
+ :caption: TODO 8: CMakeLists.txt
+ :name: CMakeLists.txt-configure_file
+ :language: cmake
+ :start-after: # to the source code
+ :end-before: # add the executable
+
+Since the configured file will be written into the project binary
+directory, we must add that directory to the list of paths to search for
+include files.
+
+**Note:** Throughout this tutorial, we will refer to the project build and
+the project binary directory interchangeably. These are the same and are not
+meant to refer to a `bin/` directory.
+
+We used :command:`target_include_directories` to specify
+where the executable target should look for include files.
+
+.. literalinclude:: Step2/CMakeLists.txt
+ :caption: TODO 9: CMakeLists.txt
+ :name: CMakeLists.txt-target_include_directories
+ :language: cmake
+ :start-after: # so that we will find TutorialConfig.h
+
+``TutorialConfig.h.in`` is the input header file to be configured.
+When :command:`configure_file` is called from our ``CMakeLists.txt``, the
+values for ``@Tutorial_VERSION_MAJOR@`` and ``@Tutorial_VERSION_MINOR@`` will
+be replaced with the corresponding version numbers from the project in
+``TutorialConfig.h``.
+
+.. literalinclude:: Step2/TutorialConfig.h.in
+ :caption: TODO 10: TutorialConfig.h.in
+ :name: TutorialConfig.h.in
+ :language: c++
+
+Next, we need to modify ``tutorial.cxx`` to include the configured header file,
+``TutorialConfig.h``.
+
+.. code-block:: c++
+ :caption: TODO 11: tutorial.cxx
+
+ #include "TutorialConfig.h"
+
+Finally, we print out the executable name and version number by updating
+``tutorial.cxx`` as follows:
+
+.. literalinclude:: Step2/tutorial.cxx
+ :caption: TODO 12 : tutorial.cxx
+ :name: tutorial.cxx-print-version
+ :language: c++
+ :start-after: {
+ :end-before: // convert input to double
diff --git a/Help/guide/tutorial/Step1/CMakeLists.txt b/Help/guide/tutorial/Step1/CMakeLists.txt
new file mode 100644
index 0000000..282951a
--- /dev/null
+++ b/Help/guide/tutorial/Step1/CMakeLists.txt
@@ -0,0 +1,16 @@
+# TODO 1: Set the minimum required version of CMake to be 3.10
+
+# TODO 2: Create a project named Tutorial
+
+# TODO 7: Set the project version number as 1.0 in the above project command
+
+# TODO 6: Set the variable CMAKE_CXX_STANDARD to 11
+# and the variable CMAKE_CXX_REQUIRED_STANDARD to True
+
+# TODO 8: Use configure_file to configure and copy TutorialConfig.h.in to
+# TutorialConfig.h
+
+# TODO 3: Add an executable called Tutorial to the project
+# Hint: Be sure to specify the source file as tutorial.cxx
+
+# TODO 9: Use target_include_directories to include ${PROJECT_BINARY_DIR}
diff --git a/Help/guide/tutorial/Step1/TutorialConfig.h.in b/Help/guide/tutorial/Step1/TutorialConfig.h.in
new file mode 100644
index 0000000..990bfbd
--- /dev/null
+++ b/Help/guide/tutorial/Step1/TutorialConfig.h.in
@@ -0,0 +1,2 @@
+// the configured options and settings for Tutorial
+// TODO 10: Define Tutorial_VERSION_MAJOR and Tutorial_VERSION_MINOR
diff --git a/Help/guide/tutorial/Step1/tutorial.cxx b/Help/guide/tutorial/Step1/tutorial.cxx
index 08323bf..64d0916 100644
--- a/Help/guide/tutorial/Step1/tutorial.cxx
+++ b/Help/guide/tutorial/Step1/tutorial.cxx
@@ -1,17 +1,22 @@
// A simple program that computes the square root of a number
#include <cmath>
-#include <cstdlib>
+#include <cstdlib> // TODO 5: Remove this line
#include <iostream>
#include <string>
+// TODO 11: Include TutorialConfig.h
+
int main(int argc, char* argv[])
{
if (argc < 2) {
+ // TODO 12: Create a print statement using Tutorial_VERSION_MAJOR
+ // and Tutorial_VERSION_MINOR
std::cout << "Usage: " << argv[0] << " number" << std::endl;
return 1;
}
// convert input to double
+ // TODO 4: Replace atof(argv[1]) with std::stod(argv[1])
const double inputValue = atof(argv[1]);
// calculate square root