cmake-examples/03-code-generation/configure-files
Thom Troy b81da6f68b Update to minimum CMake 3.5
And modernise some examples.
2018-03-18 17:23:57 +00:00
..
CMakeLists.txt Update to minimum CMake 3.5 2018-03-18 17:23:57 +00:00
main.cpp add a configure_file example 2015-11-28 13:07:32 +00:00
path.h.in add a configure_file example 2015-11-28 13:07:32 +00:00
README.adoc link files from intro 2016-02-14 16:28:43 +00:00
ver.h.in add a configure_file example 2015-11-28 13:07:32 +00:00

= Configure Files Generation
:toc:
:toc-placement!:

toc::[]

# Introduction

During the call to cmake it is possible to create files that use variables from
the CMakeLists.txt and cmake cache. During CMake generation the file is copied to a
new location and any cmake variables are replaced.

The files in this tutorial are below:

```
$ tree
.
├── CMakeLists.txt
├── main.cpp
├── path.h.in
├── ver.h.in
```

  * link:CMakeLists.txt[] - Contains the CMake commands you wish to run
  * link:main.cpp[] - The source file with main
  * link:path.h.in[] - File to contain a path to the build directory
  * link:ver.h.in[] - File to contain the version of the project

# Concepts

## Configure Files

To do variable substitution in a file you can use the `configure_file()` function
in CMake. This core arguments for this function are source file and destination file.

[source,cmake]
----
configure_file(ver.h.in ${PROJECT_BINARY_DIR}/ver.h)

configure_file(path.h.in ${PROJECT_BINARY_DIR}/path.h @ONLY)
----

The first example above, allows the variable to be defined like a CMake variables using
the `${}` syntax or an `@@` in the ver.h.in file. After generation a new file ver.h will be available
in the `PROJECT_BINARY_DIR`.

```
const char* ver = "${cf_example_VERSION}";
```

The second example, only allows variables to be defined using the `@@` syntax in the path.h.in file.
After generation a new file path.h will be available in the `PROJECT_BINARY_DIR`.

```
const char* path = "@CMAKE_SOURCE_DIR@";
```

# Building the Example

[source,bash]
----
$ mkdir build

$ cd build/

$ cmake ..
-- The C compiler identification is GNU 4.8.4
-- The CXX compiler identification is GNU 4.8.4
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/matrim/workspace/cmake-examples/03-code-generation/configure-files/build

$ ls
CMakeCache.txt  CMakeFiles  cmake_install.cmake  Makefile  path.h  ver.h

$ cat path.h
#ifndef __PATH_H__
#define __PATH_H__

// version variable that will be substituted by cmake
// This shows an example using the @ variable type
const char* path = "/home/matrim/workspace/cmake-examples/03-code-generation/configure-files";

#endif

$ cat ver.h
#ifndef __VER_H__
#define __VER_H__

// version variable that will be substituted by cmake
// This shows an example using the $ variable type
const char* ver = "0.2.1";

#endif

$ make
Scanning dependencies of target cf_example
[100%] Building CXX object CMakeFiles/cf_example.dir/main.cpp.o
Linking CXX executable cf_example
[100%] Built target cf_example

$ ./cf_example
Hello Version 0.2.1!
Path is /home/matrim/workspace/cmake-examples/03-code-generation/configure-files
----