summaryrefslogtreecommitdiffstats
path: root/Help/guide/tutorial/Adding a Library.rst
diff options
context:
space:
mode:
authorJosef Angstenberger <code@jtxa.de>2021-06-10 21:03:40 (GMT)
committerBrad King <brad.king@kitware.com>2021-06-17 15:53:55 (GMT)
commitd1c3e7e78af0b3a4a5637e2bf3af86cfa5ba6e6f (patch)
tree3b56495e87f31dcade321ea33ab81b74636cf8e0 /Help/guide/tutorial/Adding a Library.rst
parent13fdb263231598df2cec0fb7bc9515f1f56b5577 (diff)
downloadCMake-d1c3e7e78af0b3a4a5637e2bf3af86cfa5ba6e6f.zip
CMake-d1c3e7e78af0b3a4a5637e2bf3af86cfa5ba6e6f.tar.gz
CMake-d1c3e7e78af0b3a4a5637e2bf3af86cfa5ba6e6f.tar.bz2
Tutorial: Split steps into separate files
Fixes: #21737
Diffstat (limited to 'Help/guide/tutorial/Adding a Library.rst')
-rw-r--r--Help/guide/tutorial/Adding a Library.rst116
1 files changed, 116 insertions, 0 deletions
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 <cmake-gui(1)>` and
+:manual:`ccmake <ccmake(1)>`
+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 <cmake(1)>` executable or the
+:manual:`cmake-gui <cmake-gui(1)>` 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 <cmake-gui(1)>` or :manual:`ccmake <ccmake(1)>` 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?