Difference between revisions of "Advanced CMake Features"

From wiki.emacinc.com
Jump to: navigation, search
Line 28: Line 28:
 
<!-- /*********************************************************************************************************/ -->
 
<!-- /*********************************************************************************************************/ -->
 
{{:Templateimpl:using | initials=KY | title=Advanced CMake Features | desc=Advanced features of the CMake build system for use with the EMAC SDK. | project=OE 5.0 }}
 
{{:Templateimpl:using | initials=KY | title=Advanced CMake Features | desc=Advanced features of the CMake build system for use with the EMAC SDK. | project=OE 5.0 }}
 +
===Adding a Version Number and Configured Header File===
 +
It is possible to provide the executable and project with a version number through CMake. While you can do this exclusively in the source code, doing it in the CMakeLists file provides more flexibility. To add a version number we modify the CMakeLists file as follows:
 +
<syntaxhighlight lang="cmake">
 +
# The version number.
 +
set (Example_VERSION_MAJOR 1)
 +
set (Example_VERSION_MINOR 0)
 +
 +
# configure a header file to pass some of the CMake settings
 +
# to the source code
 +
configure_file (
 +
  "${PROJECT_SOURCE_DIR}/ExampleConfig.h.in"
 +
  "${PROJECT_BINARY_DIR}/ExampleConfig.h"  )
 +
 +
 +
# add the binary tree to the search path for include files
 +
# so that we will find ExampleConfig.h
 +
include_directories("${PROJECT_BINARY_DIR}")
 +
 +
 +
# add the executable
 +
add_executable(example main.c)
 +
</syntaxhighlight>
 +
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. We then create an <code>ExampleConfig.h.in</code> file in the source tree with the following contents:
 +
<syntaxhighlight lang="c">
 +
// the configured options and settings for Tutorial
 +
#define Example_VERSION_MAJOR @Example_VERSION_MAJOR@
 +
#define Example_VERSION_MINOR @Example_VERSION_MINOR@
 +
</syntaxhighlight>
 +
When CMake configures this header file the values for <code>@Example_VERSION_MAJOR@</code> and <code>@Example_VERSION_MINOR@</code> will be replaced by the values from the CMakeLists file. Next we modify main.c to include the configured header file and to make use of the version numbers. The resulting source code is listed below.
 +
<syntaxhighlight lang="c">
 +
// A simple program that computes the square root of a number
 +
#include <stdio.h>
 +
#include <stdlib.h>
 +
#include <math.h>
 +
#include "ExampleConfig.h"
 +
 +
int main (int argc, char *argv[])
 +
{
 +
  if (argc < 2)
 +
    {    fprintf(stdout,"%s Version %d.%d\n",
 +
            argv[0],
 +
            Example_VERSION_MAJOR,
 +
            Example_VERSION_MINOR);
 +
    fprintf(stdout,"Usage: %s number\n",argv[0]);
 +
    return 1;
 +
    }
 +
  double inputValue = atof(argv[1]);
 +
  double outputValue = sqrt(inputValue);
 +
  fprintf(stdout,"The square root of %g is %g\n",
 +
          inputValue, outputValue);
 +
  return 0;}
 +
</syntaxhighlight>
 +
The main points of note are the inclusion of the <code>ExampleConfig.h</code> header file and printing out a version number as part of the usage message.
 
===Adding External Library Files===
 
===Adding External Library Files===
 
To add an external library to the CMake project, more changes will need to be made to the <code>CMakeLists.txt</code> file. Please refer to the code sample below. In this example, the ''ImageMagick'' library will be linked into the project.
 
To add an external library to the CMake project, more changes will need to be made to the <code>CMakeLists.txt</code> file. Please refer to the code sample below. In this example, the ''ImageMagick'' library will be linked into the project.
Line 36: Line 89:
 
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR} "/usr/include/ImageMagick")
 
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR} "/usr/include/ImageMagick")
  
ADD_EXECUTABLE(main main.cpp) # This should be here by default
+
ADD_EXECUTABLE(example main.cpp) # This should be here by default
  
TARGET_LINK_LIBRARIES(main MagickWand)
+
TARGET_LINK_LIBRARIES(example MagickWand)
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Line 66: Line 119:
 
ADD_LIBRARY(tools include/tools.cpp ${HEADER_FILES})
 
ADD_LIBRARY(tools include/tools.cpp ${HEADER_FILES})
 
ADD_LIBRARY(funcs include/funcs.cpp ${HEADER_FILES})
 
ADD_LIBRARY(funcs include/funcs.cpp ${HEADER_FILES})
ADD_EXECUTABLE(main main.cpp ${HEADER_FILES})
+
ADD_EXECUTABLE(example main.cpp ${HEADER_FILES})
  
  
Line 91: Line 144:
  
 
{{:Templateimpl:whatnext | initials=KY | title=Advanced CMake Features | desc=Advanced features of the CMake build system for use with the EMAC SDK. | project=OE 5.0 }}
 
{{:Templateimpl:whatnext | initials=KY | title=Advanced CMake Features | desc=Advanced features of the CMake build system for use with the EMAC SDK. | project=OE 5.0 }}
*
+
*[[Creating_a_New_EMAC_OE_SDK_Project_with_CMake | Creating a New EMAC OE SDK Project with CMake]]
 +
<br />
 +
Some information on this page was provided by the official [http://www.cmake.org/cmake-tutorial/ CMake Documentation].

Revision as of 17:19, 18 September 2015

TODO: {{#todo: InProgress (09.14.2015-11:59->KY+)|Klint Youngmeyer|OE 5.0,KY}}

There are several advanced features of the CMake build system that may be of use on projects as they get larger. This is far from a comprehensive list, and information related to unlisted tasks may be found on official CMake documentation.

Background

This page is written with the assumption that the project being worked on has been created using the oe_init_project script or using the EMAC New C/C++ Project in Qt Creator.

Advanced CMake Features

Adding a Version Number and Configured Header File

It is possible to provide the executable and project with a version number through CMake. While you can do this exclusively in the source code, doing it in the CMakeLists file provides more flexibility. To add a version number we modify the CMakeLists file as follows:

# The version number.
set (Example_VERSION_MAJOR 1)
set (Example_VERSION_MINOR 0) 

# configure a header file to pass some of the CMake settings
# to the source code
configure_file (
  "${PROJECT_SOURCE_DIR}/ExampleConfig.h.in"
  "${PROJECT_BINARY_DIR}/ExampleConfig.h"  ) 


# add the binary tree to the search path for include files
# so that we will find ExampleConfig.h
include_directories("${PROJECT_BINARY_DIR}") 


# add the executable
add_executable(example main.c)

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. We then create an ExampleConfig.h.in file in the source tree with the following contents:

// the configured options and settings for Tutorial
#define Example_VERSION_MAJOR @Example_VERSION_MAJOR@
#define Example_VERSION_MINOR @Example_VERSION_MINOR@

When CMake configures this header file the values for @Example_VERSION_MAJOR@ and @Example_VERSION_MINOR@ will be replaced by the values from the CMakeLists file. Next we modify main.c to include the configured header file and to make use of the version numbers. The resulting source code is listed below.

// A simple program that computes the square root of a number
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "ExampleConfig.h"
 
int main (int argc, char *argv[])
{
  if (argc < 2)
    {    fprintf(stdout,"%s Version %d.%d\n",
            argv[0],
            Example_VERSION_MAJOR,
            Example_VERSION_MINOR);
    fprintf(stdout,"Usage: %s number\n",argv[0]);
    return 1;
    }
  double inputValue = atof(argv[1]);
  double outputValue = sqrt(inputValue);
  fprintf(stdout,"The square root of %g is %g\n",
          inputValue, outputValue);
  return 0;}

The main points of note are the inclusion of the ExampleConfig.h header file and printing out a version number as part of the usage message.

Adding External Library Files

To add an external library to the CMake project, more changes will need to be made to the CMakeLists.txt file. Please refer to the code sample below. In this example, the ImageMagick library will be linked into the project.

  1. The library directory must be included using the INCLUDE_DIRECTORIES() function. This function must be before the ADD_EXECUTABLE() function.
  2. Use the TARGET_LINK_LIBRARIES() function to link the desired library to the target binary. This function must be after the ADD_EXECUTABLE() function.
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR} "/usr/include/ImageMagick")

ADD_EXECUTABLE(example main.cpp) # This should be here by default

TARGET_LINK_LIBRARIES(example MagickWand)

Adding Additional C/C++ Sourrce Files as Libraries

Adding additional source files is accomplished similarly to adding external library files. See above.

  1. All included files must be included in the SOURCES list.
  2. All header files must be included in the HEADER_FILES list.
  3. Each C/C++ source file must be added as a library before adding the executable.
  4. Add the executable, including the ${HEADER_FILES}.
  5. Link the target libraries to the executable.
SET(SOURCES 
    ${PROJECT_SOURCE_DIR}/include/tools.cpp
    ${PROJECT_SOURCE_DIR}/include/funcs.cpp 
    ${PROJECT_SOURCE_DIR}/include/tools.h
    ${PROJECT_SOURCE_DIR}/include/funcs.h
    )


SET(HEADER_FILES
    ${PROJECT_SOURCE_DIR}/include/tools.h
    ${PROJECT_SOURCE_DIR}/include/funcs.h
    )


ADD_LIBRARY(tools include/tools.cpp ${HEADER_FILES})
ADD_LIBRARY(funcs include/funcs.cpp ${HEADER_FILES})
ADD_EXECUTABLE(example main.cpp ${HEADER_FILES})


TARGET_LINK_LIBRARIES(main tools funcs)


Conclusion

As stated previously, this guide is just a small list of common task requests. Please refer to official or other third-party documentation for more information.

Further Information

Where to Go Next
Pages with Related Content


Some information on this page was provided by the official CMake Documentation.