7fcc97fcc259c2ce1ed915bedf1a2351abd949c6
[platform/upstream/cmake.git] / Help / guide / tutorial / Adding Generator Expressions.rst
1 Step 10: Adding Generator Expressions
2 =====================================
3
4 :manual:`Generator expressions <cmake-generator-expressions(7)>` are evaluated
5 during build system generation to produce information specific to each build
6 configuration.
7
8 :manual:`Generator expressions <cmake-generator-expressions(7)>` are allowed in
9 the context of many target properties, such as :prop_tgt:`LINK_LIBRARIES`,
10 :prop_tgt:`INCLUDE_DIRECTORIES`, :prop_tgt:`COMPILE_DEFINITIONS` and others.
11 They may also be used when using commands to populate those properties, such as
12 :command:`target_link_libraries`, :command:`target_include_directories`,
13 :command:`target_compile_definitions` and others.
14
15 :manual:`Generator expressions <cmake-generator-expressions(7)>`  may be used
16 to enable conditional linking, conditional definitions used when compiling,
17 conditional include directories and more. The conditions may be based on the
18 build configuration, target properties, platform information or any other
19 queryable information.
20
21 There are different types of
22 :manual:`generator expressions <cmake-generator-expressions(7)>` including
23 Logical, Informational, and Output expressions.
24
25 Logical expressions are used to create conditional output. The basic
26 expressions are the ``0`` and ``1`` expressions. A ``$<0:...>`` results in the
27 empty string, and ``<1:...>`` results in the content of ``...``.  They can also
28 be nested.
29
30 A common usage of
31 :manual:`generator expressions <cmake-generator-expressions(7)>` is to
32 conditionally add compiler flags, such as those for language levels or
33 warnings. A nice pattern is to associate this information to an ``INTERFACE``
34 target allowing this information to propagate. Let's start by constructing an
35 ``INTERFACE`` target and specifying the required C++ standard level of ``11``
36 instead of using :variable:`CMAKE_CXX_STANDARD`.
37
38 So the following code:
39
40 .. literalinclude:: Step10/CMakeLists.txt
41   :caption: CMakeLists.txt
42   :name: CMakeLists.txt-CXX_STANDARD-variable-remove
43   :language: cmake
44   :start-after: project(Tutorial VERSION 1.0)
45   :end-before: # control where the static and shared libraries are built so that on windows
46
47 Would be replaced with:
48
49 .. literalinclude:: Step11/CMakeLists.txt
50   :caption: CMakeLists.txt
51   :name: CMakeLists.txt-cxx_std-feature
52   :language: cmake
53   :start-after: project(Tutorial VERSION 1.0)
54   :end-before: # add compiler warning flags just when building this project via
55
56 **Note**:  This upcoming section will require a change to the
57 :command:`cmake_minimum_required` usage in the code.  The Generator Expression
58 that is about to be used was introduced in `3.15`.  Update the call to require
59 that more recent version:
60
61 .. code-block:: cmake
62   :caption: CMakeLists.txt
63   :name: CMakeLists.txt-version-update
64
65   cmake_minimum_required(VERSION 3.15)
66
67 Next we add the desired compiler warning flags that we want for our project. As
68 warning flags vary based on the compiler we use the ``COMPILE_LANG_AND_ID``
69 generator expression to control which flags to apply given a language and a set
70 of compiler ids as seen below:
71
72 .. literalinclude:: Step11/CMakeLists.txt
73   :caption: CMakeLists.txt
74   :name: CMakeLists.txt-target_compile_options-genex
75   :language: cmake
76   :start-after: # the BUILD_INTERFACE genex
77   :end-before: # control where the static and shared libraries are built so that on windows
78
79 Looking at this we see that the warning flags are encapsulated inside a
80 ``BUILD_INTERFACE`` condition. This is done so that consumers of our installed
81 project will not inherit our warning flags.
82
83 **Exercise**: Modify ``MathFunctions/CMakeLists.txt`` so that all targets have
84 a :command:`target_link_libraries` call to ``tutorial_compiler_flags``.