.. cmake-manual-description: CMake Generator Expressions
cmake-generator-expressions(7)
******************************
.. only:: html
.. contents::
Introduction
============
Generator expressions are evaluated during build system generation to produce
information specific to each build configuration. They have the form
``$<...>``. For example:
.. code-block:: cmake
target_include_directories(tgt PRIVATE /opt/include/$<CXX_COMPILER_ID>)
This would expand to ``/opt/include/GNU``, ``/opt/include/Clang``, etc.
depending on the C++ compiler used.
Generator expressions are allowed in the context of many target properties,
such as :prop_tgt:`LINK_LIBRARIES`, :prop_tgt:`INCLUDE_DIRECTORIES`,
:prop_tgt:`COMPILE_DEFINITIONS` and others. They may also be used when using
commands to populate those properties, such as :command:`target_link_libraries`,
:command:`target_include_directories`, :command:`target_compile_definitions`
and others. They enable conditional linking, conditional definitions used when
compiling, conditional include directories, and more. The conditions may be
based on the build configuration, target properties, platform information,
or any other queryable information.
Generator expressions can be nested:
.. code-block:: cmake
target_compile_definitions(tgt PRIVATE
$<$<VERSION_LESS:$<CXX_COMPILER_VERSION>,4.2.0>:OLD_COMPILER>
)
The above would expand to ``OLD_COMPILER`` if the
:variable:`CMAKE_CXX_COMPILER_VERSION <CMAKE_<LANG>_COMPILER_VERSION>` is less
than 4.2.0.
Whitespace And Quoting
======================
Generator expressions are typically parsed after command arguments.
If a generator expression contains spaces, new lines, semicolons or
other characters that may be interpreted as command argument separators,
the whole expression should be surrounded by quotes when passed to a
command. Failure to do so may result in the expression being split and
it may no longer be recognized as a generator expression.
When using :command:`add_custom_command` or :command:`add_custom_target`,
use the ``VERBATIM`` and ``COMMAND_EXPAND_LISTS`` options to obtain robust
argument splitting and quoting.
.. code-block:: cmake
# WRONG: Embedded space will be treated as an argument separator.
# This ends up not being seen as a generator expression at all.
add_custom_target(run_some_tool
COMMAND some_tool -I$<JOIN:$<TARGET_PROPERTY:tgt,INCLUDE_DIRECTORIES>, -I>
VERBATIM
)
.. code-block:: cmake
# Better, but still not robust. Quotes prevent the space from splitting the
# expression. However, the tool will receive the expanded value as a single
# argument.
add_custom_target(run_some_tool
COMMAND some_tool "-I$<JOIN:$<TARGET_PROPERTY:tgt,INCLUDE_DIRECTORIES>, -I>"
VERBATIM
)
.. code-block:: cmake
# Nearly correct. Using a semicolon to separate arguments and adding the
# COMMAND_EXPAND_LISTS option means that paths with spaces will be handled
# correctly. Quoting the whole expression ensures it is seen as a generator
# expression. But if the target property is empty, we will get a bare -I
# with nothing after it.
add_custom_target(run_some_tool
COMMAND some_tool "-I$<JOIN:$<TARGET_PROPERTY:tgt,INCLUDE_DIRECTORIES>,;-I>"
COMMAND_EXPAND_LISTS
VERBATIM
)
Using variables to build up a more complex generator expression is also a
good way to reduce errors and improve readability. The above example can be
improved further like so:
.. code-block:: cmake
# The $<BOOL:...> check prevents adding anything if the property is empty,
# assuming the property value cannot be one of CMake's false constants.
set(prop "$<TARGET_PROPERTY:tgt,INCLUDE_DIRECTORIES>")
add_custom_target(run_some_tool
COMMAND some_tool "$<$<BOOL:${prop}>:-I$<JOIN:${prop},;-I>>"
COMMAND_EXPAND_LISTS
VERBATIM
)
Finally, the above example can be expressed in a more simple and robust way
using an alternate generator expression:
.. code-block:: cmake
add_custom_target(run_some_tool
COMMAND some_tool "$<LIST:TRANSFORM,$<TARGET_PROPERTY:tgt,INCLUDE_DIRECTORIES>,PREPEND,-I>"
COMMAND_EXPAND_LISTS
VERBATIM
)
A common mistake is to try to split a generator expression across multiple
lines with indenting:
.. code-block:: cmake
# WRONG: New lines and spaces all treated as argument separators, so the
# generator expression is split and not recognized correctly.
target_compile_definitions(tgt PRIVATE
$<$<AND:
$<CXX_COMPILER_ID:GNU>,
$<VERSION_GREATER_EQUAL:$<CXX_COMPILER_VERSION>,5>
>:HAVE_5_OR_LATER>
)
Again, use helper variables with well-chosen names to build up a readable
expression instead:
.. code-block:: cmake
set(is_gnu "$<CXX_COMPILER_ID:GNU>")
set(v5_or_later "$<VERSION_GREATER_EQUAL:$<CXX_COMPILER_VERSION>,5>")
set(meet_requirements "$<AND:${is_gnu},${v5_or_later}>")
target_compile_definitions(tgt PRIVATE
"$<${meet_requirements}:HAVE_5_OR_LATER>"
)
Debugging
=========
Since generator expressions are evaluated during generation of the buildsystem,
and not during processing of ``CMakeLists.txt`` files, it is not possible to
inspect their result with the :command:`message()` command. One possible way
to generate debug messages is to add a custom target:
.. code-block:: cmake
add_custom_target(genexdebug COMMAND ${CMAKE_COMMAND} -E echo "$<...>")
After running :program:`cmake`, you can then build the ``genexdebug`` target to print
the result of the ``$<...>`` expression (i.e. run the command
:option:`cmake --build ... --target genexdebug <cmake--build --target>`).
Another way is to write debug messages to a file with :command:`file(GENERATE)`:
.. code-block:: cmake
file(GENERATE OUTPUT filename CONTENT "$<...>")
Generator Expression Reference
==============================
.. note::
This reference deviates from most of the CMake documentation in that it
omits angular brackets ``<...>`` around placeholders like ``condition``,
``string``, ``target``, etc. This is to prevent an opportunity for those
placeholders to be misinterpreted as generator expressions.
.. _`Conditional Generator Expressions`:
Conditional Expressions
-----------------------
A fundamental category of generator expressions relates to conditional logic.
Two forms of conditional generator expressions are supported:
.. genex:: $<condition:true_string>
Evaluates to ``true_string`` if ``condition`` is ``1``, or an empty string
if ``condition`` evaluates to ``0``. Any other value for ``condition``
results in an error.
.. genex:: $<IF:condition,true_string,false_string>
.. versionadded:: 3.8
Evaluates to ``true_string`` if ``condition`` is ``1``, or ``false_string``
if ``condition`` is ``0``. Any other value for ``condition`` results in an
error.
.. versionadded:: 3.28
This generator expression short-circuits such that generator expressions in
``false_string`` will not evaluate when ``condition`` is ``1``, and generator
expressions in ``true_string`` will not evaluate when condition is ``0``.
Typically, the ``condition`` is itself a generator expression. For instance,
the following expression expands to ``DEBUG_MODE`` when the ``Debug``
configuration is used, and the empty string for all other configurations:
.. code-block:: cmake
$<$<CONFIG:Debug>:DEBUG_MODE>
Boolean-like ``condition`` values other than ``1`` or ``0`` can be handled
by wrapping them with the ``$<BOOL:...>`` generator expression:
.. genex:: $<BOOL:string>
Converts ``string`` to ``0`` or ``1``. Evaluates to ``0`` if any of the
following is true:
* ``string`` is empty,
* ``string`` is a case-insensitive equal of
``0``, ``FALSE``, ``OFF``, ``N``, ``NO``, ``IGNORE``, or ``NOTFOUND``, or
* ``string`` ends in the suffix ``-NOTFOUND`` (case-sensitive).
Otherwise evaluates to ``1``.
The ``$<BOOL:...>`` generator expression is often used when a ``condition``
is provided by a CMake variable:
.. code-block:: cmake

weixin58692541
- 粉丝: 4128
- 资源: 7560
最新资源
- DSP280049C串口升级方案:全方位支持,包含Bootloader源码、上位机程序及用户示例工程,操作指南一览无余 ,DSP280049C串口升级方案:包含完整Bootloader源码与操作手册
- OBC&DCDC相关参数设计与计算
- 图书馆管理系统(SSH框架).zip(毕设&课设&实训&大作业&竞赛&项目)
- 基于BES秃鹰算法优化BP神经网络模型的多输入单输出拟合预测系统及其MATLAB程序实现,基于BES秃鹰智能算法的BP神经网络权值和阈值优化MATLAB实现,基于BES秃鹰智能算法优化BP神经网络模型
- JavaEE结课项目.zip(课设&实训&大作业&项目)
- 基于SSM+JSP的学生请假系统.zip(毕设&课设&实训&大作业&竞赛&项目)
- 全国大学生FPGA创新设计邀请赛的作品.zip
- 双层非线性优化模型:省内外电力市场及风险应对机制研究(以CVaR和线性转换为中心),基于CVaR方法的双层非线性优化模型在电力市场及省间交易中的研究与应用,主题:提出了一种双层非线性优化模型,将省内电
- 基于Qt的数据库应用课程设计-景点门票管理系统.zip(课设&实训&大作业&项目)
- Opencv实战基于python,银行卡识别、全景图片拼接、OCR图片识别.zip(毕设&课设&实训&大作业&竞赛&项目)
- 基于django的admin后台管理系统.zip(毕设&课设&实训&大作业&竞赛&项目)
- 前后端分离的简易博客项目(vue+springboot).zip(毕设&课设&实训&大作业&竞赛&项目)
- 基于西门子S7-1200的停车场车位智能控制系统:传感器检测、PLC控制及HM画面组态仿真,基于西门子S7-1200智能停车场的车位管理系统 - 传感器监控与PLC自动化控制方案 ,基于西门子120
- 基于Vue框架的Sparkle项目:TypeScript、JavaScript、HTML前端技术实践源码
- 基于AdminLTE +Django + Mysql 的会议室管理系统.zip(毕设&课设&实训&大作业&竞赛&项目)
- 西门子S7-1500 PLC在制药厂洁净空调系统中的精准控温控湿实践:包含冷水机组与洁净室空调机组案例研究,博图V15.1编程版本参考案例,西门子S7-1500 PLC在制药厂洁净空调系统中的精准控温
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈


