<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://trans.onionmixer.net/wiki/index.php?action=history&amp;feed=atom&amp;title=MastringCmakeVersion31%3AChapter_12</id>
	<title>MastringCmakeVersion31:Chapter 12 - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://trans.onionmixer.net/wiki/index.php?action=history&amp;feed=atom&amp;title=MastringCmakeVersion31%3AChapter_12"/>
	<link rel="alternate" type="text/html" href="https://trans.onionmixer.net/wiki/index.php?title=MastringCmakeVersion31:Chapter_12&amp;action=history"/>
	<updated>2026-05-08T11:39:12Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.3</generator>
	<entry>
		<id>https://trans.onionmixer.net/wiki/index.php?title=MastringCmakeVersion31:Chapter_12&amp;diff=5613&amp;oldid=prev</id>
		<title>Onionmixer: CMAKE Chapter 12</title>
		<link rel="alternate" type="text/html" href="https://trans.onionmixer.net/wiki/index.php?title=MastringCmakeVersion31:Chapter_12&amp;diff=5613&amp;oldid=prev"/>
		<updated>2020-09-21T12:09:23Z</updated>

		<summary type="html">&lt;p&gt;CMAKE Chapter 12&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;==CHAPTER TWELVE::TUTORIAL==&lt;br /&gt;
&lt;br /&gt;
This chapter provides a step-by-step tutorial that covers common build system i ssues that CMake helps ad­&lt;br /&gt;
dress. Many of these topics have been introduced in prior chapters as separate issues, but seei ng how they&lt;br /&gt;
all work together in an example project can be very helpful. Thi s tutorial can be found in the Testsffutorial&lt;br /&gt;
directory of the CMake source code tree. Each step has its own subdirectory containing a complete copy of&lt;br /&gt;
the tutorial for that step.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===A Basic Starting Point (Step 1)===&lt;br /&gt;
&lt;br /&gt;
The most basic project is an executable built from source code files. For simple projects, a two line CMake­ Lists file is all that is required. This will be the starting point for our tutorial. The CMakeLists file looks like&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
cmake_minimum_required (2.6)&lt;br /&gt;
project (Tutorial)&lt;br /&gt;
&lt;br /&gt;
add_executable (Tutorial tutorial.cxx)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that this example uses lower case commands in the CMakeLists file. Upper, lower, and mixed case commands are supported by CMake. The source code for tutorial.cxx will compute the square root of a number and the first version of it is very simple, as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
// A simple program that computes the square root of a number&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;math.h&amp;gt;&lt;br /&gt;
int main (int argc, char *argv[})&lt;br /&gt;
{&lt;br /&gt;
  if (arge &amp;lt; 2)&lt;br /&gt;
    {&lt;br /&gt;
      fprintf(stdout, &amp;quot;Usage: %s number\n&amp;quot;,argv[0]);&lt;br /&gt;
      return 1;&lt;br /&gt;
    }&lt;br /&gt;
  double inputValue = atof(argv[1]);&lt;br /&gt;
  double outputValue = sqrt (inputValue);&lt;br /&gt;
  fprintf(stdout, &amp;quot;The square root of %g is %g\n&amp;quot;,&lt;br /&gt;
          inputValue, outputValue) ;&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Adding a Version Number and Configured Header File====&lt;br /&gt;
&lt;br /&gt;
The first feature we will add is to provide our executable and project with a version number. While you can&lt;br /&gt;
do this exclusively in the source code, doing it in the CMakeLists file provides more flexibility. To add a&lt;br /&gt;
version number we modify the CMakeLists file as follows&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
cmake_minimum_required (2.6)&lt;br /&gt;
project (Tutorial)&lt;br /&gt;
&lt;br /&gt;
# The version number.&lt;br /&gt;
set (Tutorial_VERSION_MAJOR 1)&lt;br /&gt;
set (Tutorial_VERSION_MINOR 0)&lt;br /&gt;
&lt;br /&gt;
# configure a header file to pass some of the CMake settings&lt;br /&gt;
# to the source code&lt;br /&gt;
configure_file (&lt;br /&gt;
  &amp;quot;${PROJECT_SOURCE_DIR}/TutorialConfig.h.in&amp;quot;&lt;br /&gt;
  &amp;quot;${PROJECT_BINARY_DIR}/TutorialConfig.h&amp;quot;&lt;br /&gt;
  )&lt;br /&gt;
&lt;br /&gt;
# add the binary tree to the search path for include files&lt;br /&gt;
# so that we will find TutorialConfig.h&lt;br /&gt;
include_directories (&amp;quot;${PROJECT_BINARY_DIR}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# add the executable&lt;br /&gt;
add_executable(Tutorial tutorial.cxx)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since the configured file will be written into the binary tree, we must add that directory to the list of paths&lt;br /&gt;
to search for include files. We then create a TutorialConfig.h.in file in the source tree with the following contents:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
// the configured options and settings for Tutorial&lt;br /&gt;
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@&lt;br /&gt;
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When CMake configures this header file, the values for @Tutorial_VERSION_MAJOR@ and @Tutorial_VERSION_MINOR@ will be replaced by the values from the CMakeLists file. Next, we mod­ify tutorial.cxx to include the configured header file and to make use of the version numbers. The resulting source code is listed below.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
// A simple program that computes the square root of a number&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;math.h&amp;gt;&lt;br /&gt;
#include &amp;quot;TutorialConfig.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[])&lt;br /&gt;
{&lt;br /&gt;
  if (arge &amp;lt; 2)&lt;br /&gt;
    {&lt;br /&gt;
    fprintf(stdout, &amp;quot;%s Version %d.%d\n&amp;quot;,&lt;br /&gt;
            argv[0],&lt;br /&gt;
            Tutorial_VERSION_MAJOR,&lt;br /&gt;
            Tutorial_VERSION_MINOR);&lt;br /&gt;
    fprintf(stdout, &amp;quot;Usage: %s number\n&amp;quot;,argv[0]);&lt;br /&gt;
&lt;br /&gt;
    return 1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
  double inputValue = atof(argv[1]);&lt;br /&gt;
  double outputValue = sqrt(inputValue);&lt;br /&gt;
  fprintf(stdout,&amp;quot;The square root of %g is %g\n&amp;quot;,&lt;br /&gt;
          inputValue, outputValue);&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main changes are the inclusion of the TutorialConfig.h header file and printing out a version number as part of the usage message.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Adding a Library (Step 2)===&lt;br /&gt;
&lt;br /&gt;
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. It will have the following one line CMakeLists file&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
add_library(MathFunctions mysqrt.cxx)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The source file mysqrt.cxx has one function called mysqrt that provides similar functionality to the compiler&amp;#039;s sqrt function. To make use of the new library we add an add_subdirectory() (page 277) call in the top level CMakeLists file so that the library will get built. We also add another include directory so that the MathFunctions/mysqrt.h header file can be found for the function prototype. The last change is to add the new library to the executable. The last few lines of the top level CMakeLists file now look like&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
include directories (&amp;quot;%${PROJECT_SOURCE_DIR}/MathFunctions&amp;quot;)&lt;br /&gt;
add_subdirectory (MathFunctions)&lt;br /&gt;
&lt;br /&gt;
# add the executable&lt;br /&gt;
&lt;br /&gt;
add_executable (Tutorial tutorial.cxx)&lt;br /&gt;
target_link_libraries (Tutorial MathFunctions)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, let us consider making the MathFunctions library optional. In this tutorial there really isn&amp;#039;t any reason to do so, but with larger libraries or libraries that rely on third party code you might want to. The first step is to add anoption() (page 327) to the top level CMakeLists file.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
# should we use our own math functions?&lt;br /&gt;
option (USE_MYMATH&lt;br /&gt;
        &amp;quot;Use tutorial provided math implementation&amp;quot; ON)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will show up in the CMake GUI with a default value of ON that the user can change as desired. This setting will be stored in the cache so that the user does not need to keep setting it each time they run CMake on this project. The next change is to make the build and linking of the MathFunctions library conditional. To do this we change the end of the top level CMakeLists file to look like the following&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
# add the MathFunctions library?&lt;br /&gt;
#&lt;br /&gt;
if (USE_MYMATH)&lt;br /&gt;
  include_directories (&amp;quot;${PROJECT_SOURCE_DIR}/MathFunctions&amp;quot;)&lt;br /&gt;
  add_subdirectory (MathFunctions)&lt;br /&gt;
  set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)&lt;br /&gt;
endif (USE_MYMATH)&lt;br /&gt;
&lt;br /&gt;
# add the executable&lt;br /&gt;
add_executable (Tutorial tutorial.cxx)&lt;br /&gt;
target_link_libraries (Tutorial ${EXTRA_LIBS})&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This uses the setting of USE_MYMATH to determine if the MathFunctions should be compiled and used. Note the use of a variable (EXTRA_LIBS in this case) to collect up any optional libraries to later be linked into the executable. This is a common approach used to keep larger projects with many optional components clean. The corresponding changes to the source code are fairly straight forward and leave us with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
// A simple program that computes the square root of a number&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;math.h&amp;gt;&lt;br /&gt;
#include &amp;quot;TutorialConfig.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#ifdef USE_MYMATH&lt;br /&gt;
#include &amp;quot;MathFunctions.h&amp;quot;&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv([))&lt;br /&gt;
{&lt;br /&gt;
  if (arge &amp;lt; 2)&lt;br /&gt;
    {&lt;br /&gt;
    fprintf(stdout, &amp;quot;%s Version $d.%d\n&amp;quot;, argv[0],&lt;br /&gt;
            Tutorial. VERSION_MAJOR,&lt;br /&gt;
            Tutorial_VERSION_MINOR) ;&lt;br /&gt;
    fprintf(stdout, &amp;quot;Usage: %s number\n&amp;quot;,argv[0]);&lt;br /&gt;
&lt;br /&gt;
    return 1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
double inputValue = atof(argv[1]);&lt;br /&gt;
&lt;br /&gt;
#ifdef USE_MATH&lt;br /&gt;
  double outputvalue = mysqrt(inputValue);&lt;br /&gt;
#else  &lt;br /&gt;
  double outputvalue = sqrt(inputValue);&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
  fprintf(stdout,&amp;quot;The square root of %g is %g\n&amp;quot;,&lt;br /&gt;
          inputValue, outputValue);&lt;br /&gt;
  return 0;&lt;br /&gt;
)  &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the source code we make use of USE_MYMATH as well. This is provided from CMake to the source code through the TutorialConfig.h.in configured file by adding the following line to it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
cmakedefine USE_MATH&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Installing and Testing (Step 3)===&lt;br /&gt;
&lt;br /&gt;
For the next step we will add install rules and testing support to our project. The install rules are fairly straight forward. For the MathFunctions library we setup the library and the header file to be installed by adding the following two lines to MathFunctions&amp;#039;CMakeLists file&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
install (TARGETS MathFunctions DESTINATION bin)&lt;br /&gt;
install (FILES MathFunctions.h DESTINATION include)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For the application, the following lines are added to the top level CMakeLists file to install the executable and the configured header file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
# add the install targets&lt;br /&gt;
install (TARGETS Tutorial DESTINATION bin)&lt;br /&gt;
install (FILES &amp;quot;${PROJECT_BINARY_DIR}/TutorialConfig.h&amp;quot;&lt;br /&gt;
         DESTINATION include)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That is all there is to it. At this point you should be able to build the tutorial, then type make install (or build the INSTALL target from an IDE), and it will install the appropriate header files, libraries, and executables. The CMake variable CMAKE_INSTALL_PREFIX is used to determine the root of where the files will be installed. Adding testing is also a fairly straight forward process. At the end of the top level CMakeLists file we can add a number of basic tests to verify that the application is working correctly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
# does the application run&lt;br /&gt;
add_test (TutorialRuns Tutorial 25)&lt;br /&gt;
&lt;br /&gt;
# does it sqrt of 25&lt;br /&gt;
add_test (TutorialComp25 Tutorial 25)&lt;br /&gt;
&lt;br /&gt;
set_tests_properties (TutorialComp25&lt;br /&gt;
  PROPERTIES PASS_REGULAR_EXPRESSION &amp;quot;25 is 5&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# does it handle negative numbers&lt;br /&gt;
add_test (TutorialNegative Tutorial -25)&lt;br /&gt;
set_tests_properties (TutorialNegative&lt;br /&gt;
  PROPERTIES PASS_REGULAR_EXPRESSION &amp;quot;-25 is 0&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# does it handle small numbers&lt;br /&gt;
add_test (TutorialSmall Tutorial 0.0001)&lt;br /&gt;
set_tests_properties (TutorialSmall&lt;br /&gt;
  PROPERTIES PASS_REGULAR_EXPRESSION &amp;quot;0.0001 is 0.01&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# does the usage message work?&lt;br /&gt;
add_test (TutorialUsage Tutorial)&lt;br /&gt;
set_tests_properties (TutorialUsage&lt;br /&gt;
  PROPERTIES&lt;br /&gt;
  PASS_REGULAR_EXPRESSION &amp;quot;Usage: .*number&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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 few tests all make use of the PASS_REGULAR_EXPRESSION test property to verify that the output of the test contains certain strings, in this case: verifying that the computed square root is what it should be and that the usage message is printed when an incorrect number of arguments are provided. If you wanted to add a lot of tests to test different input values you might consider creating a macro() (page 324) like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
#define a macro to simplify adding tests, then use it&lt;br /&gt;
Macro (do_test arg result)&lt;br /&gt;
  add_test (TutorialComp${arg} Tutorial ${arg})&lt;br /&gt;
  set_tests_properties (TutorialComp${arg}&lt;br /&gt;
    PROPERTIES PASS_REGULAR_EXPRESSION ${result})&lt;br /&gt;
endmacro (do_test)&lt;br /&gt;
&lt;br /&gt;
# do a bunch of result based tests&lt;br /&gt;
do_test (25 &amp;quot;25 is 5&amp;quot;)&lt;br /&gt;
do_test (-25 &amp;quot;-25 is 0&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For each invocation of do_test, another test is added to the project with a name, input, and results based on the passed arguments.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Adding System Introspection (Step 4)===&lt;br /&gt;
&lt;br /&gt;
Next 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 less common. If the platform has log then we will use that to compute the square root in the mysqrt function. We first test for the availability of these functions using the Check FunctionExists.cmake macro in the top level CMakeLists file as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
# does this system provide the log and exp functions?&lt;br /&gt;
include (CheckFunctionExists.cmake)&lt;br /&gt;
check_function_exists (log HAVE_LOG)&lt;br /&gt;
check_function_exists (exp HAVE_EXP)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next we modify the TutorialConfig.h.in to define those values if CMake found them on the platform as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
// does the platform provide exp and log functions?&lt;br /&gt;
#cmakedefine HAVE_LOG&lt;br /&gt;
#cmakedefine HAVE_EXP&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is important that the tests for log and exp are done before the configure_file() (page 282) com­mand for TutorialConfig.h. The configure_file command immediately configures the file using the current settings in CMake. Finally, in the mysqrt function we can provide an alternate implementation based on log and exp if they are available on the system using the following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
// if we have both log and exp then use them&lt;br /&gt;
#if defined (HAVE_LOG) &amp;amp;&amp;amp; defined (HAVE_EXP)&lt;br /&gt;
result = exp(log(x) * 0.5);&lt;br /&gt;
#else // otherwise use an iterative approach&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Adding a Generated File and Generator (Step 5)===&lt;br /&gt;
&lt;br /&gt;
In this section we will show how you can add a generated source file into the build process of an application. For this example, we will create a table of precomputed square roots as part of the build process, and then compile that table into our application. To accomplish this we first need a program that will generate the table. In the MathFunctions subdirectory a new source file named MakeTable.cxx will do just that.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
// A simple program that builds a sqrt table&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;math.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[])&lt;br /&gt;
{&lt;br /&gt;
  int i;&lt;br /&gt;
  double result;&lt;br /&gt;
&lt;br /&gt;
  // make sure we have enough arguments&lt;br /&gt;
  if (arge &amp;lt; 2)&lt;br /&gt;
    {&lt;br /&gt;
      return 1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
  // open the output file&lt;br /&gt;
  FILE *fout = fopen(argv[{1],&amp;quot;w&amp;quot;);&lt;br /&gt;
  if (!fout)&lt;br /&gt;
    {&lt;br /&gt;
      return 1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
  // create a source file with a table of square roots&lt;br /&gt;
  fprintf (fout,&amp;quot;double sqrtTable[] = {\n&amp;quot;);&lt;br /&gt;
  for (i = 0; i &amp;lt; 10; ++i)&lt;br /&gt;
    {&lt;br /&gt;
    result = sqrt (static_cast&amp;lt;double&amp;gt;(i));&lt;br /&gt;
    fprintf (fout, &amp;quot;%g, \n&amp;quot;, result);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
  // close the table with a zero&lt;br /&gt;
  fprintf (fout, &amp;quot;0);\n&amp;quot;);&lt;br /&gt;
  fclose (fout);&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the table is produced as valid C++ code and that the name of the file to write the output to is passed in as an argument. The next step is to add the appropriate commands to MathFunctions&amp;#039;CMakeLists file to build the MakeTable executable, and then run it as part of the build process. A few commands are needed to accomplish this, as shown below.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
# first we add the executable that generates the table&lt;br /&gt;
add_executable (MakeTable MakeTable.cxx)&lt;br /&gt;
&lt;br /&gt;
# add the command to generate the source code&lt;br /&gt;
add_custom_command (&lt;br /&gt;
  OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h&lt;br /&gt;
  COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h&lt;br /&gt;
  DEPENDS MakeTable&lt;br /&gt;
  )&lt;br /&gt;
&lt;br /&gt;
# add the binary tree directory to the search path for&lt;br /&gt;
# include files&lt;br /&gt;
include_directories( ${CMAKE_CURRENT_BINARY_DIR} )&lt;br /&gt;
&lt;br /&gt;
# add the main library&lt;br /&gt;
add_library (MathFunctions mysqrt.cxx&lt;br /&gt;
${CMAKE_CURRENT_BINARY_DIR}/Table.h )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
First, the executable for MakeTable is added as any other executable would be added. Then we add a custom command that specifies how to produce Table.h by running MakeTable. 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. 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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
At this point the top level CMakeLists file with all the features we have added looks like the following&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
cmake_minimum_required (2.6)&lt;br /&gt;
project (Tutorial)&lt;br /&gt;
&lt;br /&gt;
# The version number.&lt;br /&gt;
set (Tutorial_VERSION_MAJOR 1)&lt;br /&gt;
set (Tutorial_VERSION_MINOR Q)&lt;br /&gt;
&lt;br /&gt;
# does this system provide the log and exp functions?&lt;br /&gt;
include (${CMAKE_ROOT} /Modules/CheckFunctionExists.cmake)&lt;br /&gt;
&lt;br /&gt;
check_function_exists (log HAVE_LOG)&lt;br /&gt;
check_function_exists (exp HAVE_EXP)&lt;br /&gt;
&lt;br /&gt;
# should we use our own math functions&lt;br /&gt;
option (USE_MYMATH&lt;br /&gt;
  &amp;quot;Use tutorial provided math implementation&amp;quot; ON)&lt;br /&gt;
&lt;br /&gt;
# configure a header file to pass some of the CMake settings&lt;br /&gt;
# to the source code&lt;br /&gt;
configure_file (&lt;br /&gt;
  &amp;quot;${PROJECT_SOURCE_DIR}/TutorialConfig.h.in&amp;quot;&lt;br /&gt;
  &amp;quot;${PROJECT_BINARY_DIR}/TutorialConfig.h&amp;quot;&lt;br /&gt;
  )&lt;br /&gt;
&lt;br /&gt;
# add the binary tree to the search path for include files&lt;br /&gt;
# so that we will find TutorialConfig.h&lt;br /&gt;
include_directories (&amp;quot;${PROJECT_BINARY_DIR}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# add the MathFunctions library?&lt;br /&gt;
if (USE_MYMATH)&lt;br /&gt;
  include_directories (&amp;quot;${PROJECT_SOURCE_DIR}/MathFunctions&amp;quot;)&lt;br /&gt;
  add_subdirectory (MathFunctions)&lt;br /&gt;
  set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)&lt;br /&gt;
endif (USE_MYMATH)&lt;br /&gt;
&lt;br /&gt;
# add the executable&lt;br /&gt;
add_executable (Tutorial tutorial.cxx)&lt;br /&gt;
target_link_libraries (Tutorial ${EXTRA_LIBS})&lt;br /&gt;
&lt;br /&gt;
# add the install targets&lt;br /&gt;
install (TARGETS Tutorial DESTINATION bin)&lt;br /&gt;
install (FILES &amp;quot;${PROJECT_BINARY_DIR}/TutorialConfig.h&amp;quot;&lt;br /&gt;
         DESTINATION include)&lt;br /&gt;
&lt;br /&gt;
# does the application run&lt;br /&gt;
add_test (TutorialRuns Tutorial 25)&lt;br /&gt;
&lt;br /&gt;
# does the usage message work?&lt;br /&gt;
add_test (TutorialUsage Tutorial)&lt;br /&gt;
set_tests_ properties (TutorialUsage&lt;br /&gt;
  PROPERTIES&lt;br /&gt;
  PASS REGULAR_EXPRESSION &amp;quot;Usage: .*number&amp;quot;&lt;br /&gt;
  )&lt;br /&gt;
&lt;br /&gt;
#define a macro to simplify adding tests&lt;br /&gt;
macro (do_test arg result)&lt;br /&gt;
  add_test (TutorialComp${arg} Tutorial ${arg})&lt;br /&gt;
  set_tests_properties (TutorialComp${arg}&lt;br /&gt;
  PROPERTIES PASS_REGULAR_EXPRESSION ${result}&lt;br /&gt;
  )&lt;br /&gt;
endmacro (do_test)&lt;br /&gt;
&lt;br /&gt;
# do a bunch of result based tests&lt;br /&gt;
do_test (4 &amp;quot;4 is 2&amp;quot;)&lt;br /&gt;
do_test (9 &amp;quot;9 is 3&amp;quot;)&lt;br /&gt;
do_test (5 &amp;quot;5 is 2.236&amp;quot;)&lt;br /&gt;
do_test (7 &amp;quot;7 is 2.645&amp;quot;)&lt;br /&gt;
do_test (25 &amp;quot;25 is 5&amp;quot;)&lt;br /&gt;
do_test (-25 &amp;quot;-25 is 0&amp;quot;)&lt;br /&gt;
do_test (0.0001 &amp;quot;0.0001 is 0.01&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TutorialConfig.h looks like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
// the configured options and settings for Tutorial&lt;br /&gt;
#define Tutorial VERSION_MAJOR @Tutorial_VERSION_MAJOR@&lt;br /&gt;
#define Tutorial VERSION_MINOR @Tutorial_VERSION_MINOR@&lt;br /&gt;
#cmakedefine USE_MYMATH&lt;br /&gt;
&lt;br /&gt;
// does the platform provide exp and log functions?&lt;br /&gt;
#cmakedefine HAVE_LOG&lt;br /&gt;
#cmakedefine HAVE_EXP&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and the CMakeLists file for MathFunctions looks like&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
# first we add the executable that generates the table&lt;br /&gt;
add_executable (MakeTable MakeTable.cxx)&lt;br /&gt;
# add the command to generate the source code&lt;br /&gt;
add_custom_command (&lt;br /&gt;
  OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h&lt;br /&gt;
  DEPENDS MakeTable&lt;br /&gt;
  COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h&lt;br /&gt;
  )&lt;br /&gt;
# add the binary tree directory to the search path&lt;br /&gt;
# for include files&lt;br /&gt;
include_directories ( ${CMAKE_CURRENT_BINARY_DIR} )&lt;br /&gt;
&lt;br /&gt;
# add the main library&lt;br /&gt;
add_library (MathFunctions mysqrt.cxx&lt;br /&gt;
${CMAKE_CURRENT_BINARY_DIR}/Table.h)&lt;br /&gt;
&lt;br /&gt;
install (TARGETS MathFunctions DESTINATION bin)&lt;br /&gt;
install (FILES MathFunctions.h DESTINATION include)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Building an Installer (Step 6)===&lt;br /&gt;
&lt;br /&gt;
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 3), 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 as found in cygwin, debian, RPMs etc. To accomplish this we will use CPack to create platform specific installers as described in Chapter 9. Specifically, we need to add a few lines to the bottom of our toplevel CMakeLists.txt file.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
# build a CPack driven installer package&lt;br /&gt;
include (InstallRequiredSystemLibraries)&lt;br /&gt;
set (CPACK_RESOURCE_FILE_ LICENSE&lt;br /&gt;
    &amp;quot;${CMAKE_CURRENT_SOURCE_DIR}/License.txt&amp;quot;)&lt;br /&gt;
set (CPACK_PACKAGE_VERSION_MAJOR &amp;quot;${Tutorial_VERSION_MAJOR}&amp;quot;)&lt;br /&gt;
set (CPACK_PACKAGE_VERSION_MINOR &amp;quot;${Tutorial_VERSION_MINOR}&amp;quot;)&lt;br /&gt;
include (CPack)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That is all there is to it. We start by including InstallRequiredSystemLibraries. This module will include any&lt;br /&gt;
runtime libraries that are needed by the project for the current platform. Next, we set some CPack variables&lt;br /&gt;
to where we have stored the license and version information for this project. The version information makes&lt;br /&gt;
use of the variables we set earlier in this tutorial. Finally, we include the CPack module which will use these&lt;br /&gt;
variables and some other properties of the system you are on to setup an installer.&lt;br /&gt;
&lt;br /&gt;
The next step is to build the project in the usual manner and then run CPack on it. To build a binary distribu­tion, you would run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
cpack -C CPackConfig.cmake&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To create a source distribution, you would type&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
cpack -C CPackSourceConfig.cmake&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Adding Support for a Dashboard (Step 7)===&lt;br /&gt;
&lt;br /&gt;
Adding support for submitting our test results to a dashboard is very easy. We already defined a number of tests for our project in the earlier steps of this tutorial. We just have to run those tests and submit them to a dashboard. To include support for dashboards, we include the CTest module in our toplevel CMakeLists file.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
# enable dashboard scripting&lt;br /&gt;
include (CTest)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We also create a CTestConfig.cmake file where we can specify the name of this project for the dash­board.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
set (CTEST_PROJECT_NAME &amp;quot;Tutorial&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
CTest will read in this file when it runs. To create a simple dashboard you can run CMake on your project, change directory to the binary tree, and then run ctest -D Experimental. The results of your dashboard will be uploaded to Kitware&amp;#039;s public dashboard at:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
http://www.cdash.org/CDash/index.php?project=PublicDashboard&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:MastringCmakeVersion31]]&lt;/div&gt;</summary>
		<author><name>Onionmixer</name></author>
	</entry>
</feed>