123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439 |
- ============
- CMake Primer
- ============
- .. contents::
- :local:
- .. warning::
- Disclaimer: This documentation is written by LLVM project contributors `not`
- anyone affiliated with the CMake project. This document may contain
- inaccurate terminology, phrasing, or technical details. It is provided with
- the best intentions.
- Introduction
- ============
- The LLVM project and many of the core projects built on LLVM build using CMake.
- This document aims to provide a brief overview of CMake for developers modifying
- LLVM projects or building their own projects on top of LLVM.
- The official CMake language references is available in the cmake-language
- manpage and `cmake-language online documentation
- <https://cmake.org/cmake/help/v3.4/manual/cmake-language.7.html>`_.
- 10,000 ft View
- ==============
- CMake is a tool that reads script files in its own language that describe how a
- software project builds. As CMake evaluates the scripts it constructs an
- internal representation of the software project. Once the scripts have been
- fully processed, if there are no errors, CMake will generate build files to
- actually build the project. CMake supports generating build files for a variety
- of command line build tools as well as for popular IDEs.
- When a user runs CMake it performs a variety of checks similar to how autoconf
- worked historically. During the checks and the evaluation of the build
- description scripts CMake caches values into the CMakeCache. This is useful
- because it allows the build system to skip long-running checks during
- incremental development. CMake caching also has some drawbacks, but that will be
- discussed later.
- Scripting Overview
- ==================
- CMake's scripting language has a very simple grammar. Every language construct
- is a command that matches the pattern _name_(_args_). Commands come in three
- primary types: language-defined (commands implemented in C++ in CMake), defined
- functions, and defined macros. The CMake distribution also contains a suite of
- CMake modules that contain definitions for useful functionality.
- The example below is the full CMake build for building a C++ "Hello World"
- program. The example uses only CMake language-defined functions.
- .. code-block:: cmake
- cmake_minimum_required(VERSION 3.2)
- project(HelloWorld)
- add_executable(HelloWorld HelloWorld.cpp)
- The CMake language provides control flow constructs in the form of foreach loops
- and if blocks. To make the example above more complicated you could add an if
- block to define "APPLE" when targeting Apple platforms:
- .. code-block:: cmake
- cmake_minimum_required(VERSION 3.2)
- project(HelloWorld)
- add_executable(HelloWorld HelloWorld.cpp)
- if(APPLE)
- target_compile_definitions(HelloWorld PUBLIC APPLE)
- endif()
-
- Variables, Types, and Scope
- ===========================
- Dereferencing
- -------------
- In CMake variables are "stringly" typed. All variables are represented as
- strings throughout evaluation. Wrapping a variable in ``${}`` dereferences it
- and results in a literal substitution of the name for the value. CMake refers to
- this as "variable evaluation" in their documentation. Dereferences are performed
- *before* the command being called receives the arguments. This means
- dereferencing a list results in multiple separate arguments being passed to the
- command.
- Variable dereferences can be nested and be used to model complex data. For
- example:
- .. code-block:: cmake
- set(var_name var1)
- set(${var_name} foo) # same as "set(var1 foo)"
- set(${${var_name}}_var bar) # same as "set(foo_var bar)"
-
- Dereferencing an unset variable results in an empty expansion. It is a common
- pattern in CMake to conditionally set variables knowing that it will be used in
- code paths that the variable isn't set. There are examples of this throughout
- the LLVM CMake build system.
- An example of variable empty expansion is:
- .. code-block:: cmake
- if(APPLE)
- set(extra_sources Apple.cpp)
- endif()
- add_executable(HelloWorld HelloWorld.cpp ${extra_sources})
-
- In this example the ``extra_sources`` variable is only defined if you're
- targeting an Apple platform. For all other targets the ``extra_sources`` will be
- evaluated as empty before add_executable is given its arguments.
- Lists
- -----
- In CMake lists are semi-colon delimited strings, and it is strongly advised that
- you avoid using semi-colons in lists; it doesn't go smoothly. A few examples of
- defining lists:
- .. code-block:: cmake
- # Creates a list with members a, b, c, and d
- set(my_list a b c d)
- set(my_list "a;b;c;d")
-
- # Creates a string "a b c d"
- set(my_string "a b c d")
- Lists of Lists
- --------------
- One of the more complicated patterns in CMake is lists of lists. Because a list
- cannot contain an element with a semi-colon to construct a list of lists you
- make a list of variable names that refer to other lists. For example:
- .. code-block:: cmake
- set(list_of_lists a b c)
- set(a 1 2 3)
- set(b 4 5 6)
- set(c 7 8 9)
-
- With this layout you can iterate through the list of lists printing each value
- with the following code:
- .. code-block:: cmake
- foreach(list_name IN LISTS list_of_lists)
- foreach(value IN LISTS ${list_name})
- message(${value})
- endforeach()
- endforeach()
-
- You'll notice that the inner foreach loop's list is doubly dereferenced. This is
- because the first dereference turns ``list_name`` into the name of the sub-list
- (a, b, or c in the example), then the second dereference is to get the value of
- the list.
- This pattern is used throughout CMake, the most common example is the compiler
- flags options, which CMake refers to using the following variable expansions:
- CMAKE_${LANGUAGE}_FLAGS and CMAKE_${LANGUAGE}_FLAGS_${CMAKE_BUILD_TYPE}.
- Other Types
- -----------
- Variables that are cached or specified on the command line can have types
- associated with them. The variable's type is used by CMake's UI tool to display
- the right input field. A variable's type generally doesn't impact evaluation,
- however CMake does have special handling for some variables such as PATH.
- You can read more about the special handling in `CMake's set documentation
- <https://cmake.org/cmake/help/v3.5/command/set.html#set-cache-entry>`_.
- Scope
- -----
- CMake inherently has a directory-based scoping. Setting a variable in a
- CMakeLists file, will set the variable for that file, and all subdirectories.
- Variables set in a CMake module that is included in a CMakeLists file will be
- set in the scope they are included from, and all subdirectories.
- When a variable that is already set is set again in a subdirectory it overrides
- the value in that scope and any deeper subdirectories.
- The CMake set command provides two scope-related options. PARENT_SCOPE sets a
- variable into the parent scope, and not the current scope. The CACHE option sets
- the variable in the CMakeCache, which results in it being set in all scopes. The
- CACHE option will not set a variable that already exists in the CACHE unless the
- FORCE option is specified.
- In addition to directory-based scope, CMake functions also have their own scope.
- This means variables set inside functions do not bleed into the parent scope.
- This is not true of macros, and it is for this reason LLVM prefers functions
- over macros whenever reasonable.
- .. note::
- Unlike C-based languages, CMake's loop and control flow blocks do not have
- their own scopes.
- Control Flow
- ============
- CMake features the same basic control flow constructs you would expect in any
- scripting language, but there are a few quirks because, as with everything in
- CMake, control flow constructs are commands.
- If, ElseIf, Else
- ----------------
- .. note::
- For the full documentation on the CMake if command go
- `here <https://cmake.org/cmake/help/v3.4/command/if.html>`_. That resource is
- far more complete.
- In general CMake if blocks work the way you'd expect:
- .. code-block:: cmake
- if(<condition>)
- message("do stuff")
- elseif(<condition>)
- message("do other stuff")
- else()
- message("do other other stuff")
- endif()
- The single most important thing to know about CMake's if blocks coming from a C
- background is that they do not have their own scope. Variables set inside
- conditional blocks persist after the ``endif()``.
- Loops
- -----
- The most common form of the CMake ``foreach`` block is:
- .. code-block:: cmake
- foreach(var ...)
- message("do stuff")
- endforeach()
- The variable argument portion of the ``foreach`` block can contain dereferenced
- lists, values to iterate, or a mix of both:
- .. code-block:: cmake
- foreach(var foo bar baz)
- message(${var})
- endforeach()
- # prints:
- # foo
- # bar
- # baz
- set(my_list 1 2 3)
- foreach(var ${my_list})
- message(${var})
- endforeach()
- # prints:
- # 1
- # 2
- # 3
- foreach(var ${my_list} out_of_bounds)
- message(${var})
- endforeach()
- # prints:
- # 1
- # 2
- # 3
- # out_of_bounds
- There is also a more modern CMake foreach syntax. The code below is equivalent
- to the code above:
- .. code-block:: cmake
- foreach(var IN ITEMS foo bar baz)
- message(${var})
- endforeach()
- # prints:
- # foo
- # bar
- # baz
- set(my_list 1 2 3)
- foreach(var IN LISTS my_list)
- message(${var})
- endforeach()
- # prints:
- # 1
- # 2
- # 3
- foreach(var IN LISTS my_list ITEMS out_of_bounds)
- message(${var})
- endforeach()
- # prints:
- # 1
- # 2
- # 3
- # out_of_bounds
- Similar to the conditional statements, these generally behave how you would
- expect, and they do not have their own scope.
- CMake also supports ``while`` loops, although they are not widely used in LLVM.
- Modules, Functions and Macros
- =============================
- Modules
- -------
- Modules are CMake's vehicle for enabling code reuse. CMake modules are just
- CMake script files. They can contain code to execute on include as well as
- definitions for commands.
- In CMake macros and functions are universally referred to as commands, and they
- are the primary method of defining code that can be called multiple times.
- In LLVM we have several CMake modules that are included as part of our
- distribution for developers who don't build our project from source. Those
- modules are the fundamental pieces needed to build LLVM-based projects with
- CMake. We also rely on modules as a way of organizing the build system's
- functionality for maintainability and re-use within LLVM projects.
- Argument Handling
- -----------------
- When defining a CMake command handling arguments is very useful. The examples
- in this section will all use the CMake ``function`` block, but this all applies
- to the ``macro`` block as well.
- CMake commands can have named arguments that are requried at every call site. In
- addition, all commands will implicitly accept a variable number of extra
- arguments (In C parlance, all commands are varargs functions). When a command is
- invoked with extra arguments (beyond the named ones) CMake will store the full
- list of arguments (both named and unnamed) in a list named ``ARGV``, and the
- sublist of unnamed arguments in ``ARGN``. Below is a trivial example of
- providing a wrapper function for CMake's built in function ``add_dependencies``.
- .. code-block:: cmake
- function(add_deps target)
- add_dependencies(${target} ${ARGN})
- endfunction()
- This example defines a new macro named ``add_deps`` which takes a required first
- argument, and just calls another function passing through the first argument and
- all trailing arguments.
- CMake provides a module ``CMakeParseArguments`` which provides an implementation
- of advanced argument parsing. We use this all over LLVM, and it is recommended
- for any function that has complex argument-based behaviors or optional
- arguments. CMake's official documentation for the module is in the
- ``cmake-modules`` manpage, and is also available at the
- `cmake-modules online documentation
- <https://cmake.org/cmake/help/v3.4/module/CMakeParseArguments.html>`_.
- .. note::
- As of CMake 3.5 the cmake_parse_arguments command has become a native command
- and the CMakeParseArguments module is empty and only left around for
- compatibility.
- Functions Vs Macros
- -------------------
- Functions and Macros look very similar in how they are used, but there is one
- fundamental difference between the two. Functions have their own scope, and
- macros don't. This means variables set in macros will bleed out into the calling
- scope. That makes macros suitable for defining very small bits of functionality
- only.
- The other difference between CMake functions and macros is how arguments are
- passed. Arguments to macros are not set as variables, instead dereferences to
- the parameters are resolved across the macro before executing it. This can
- result in some unexpected behavior if using unreferenced variables. For example:
- .. code-block:: cmake
- macro(print_list my_list)
- foreach(var IN LISTS my_list)
- message("${var}")
- endforeach()
- endmacro()
-
- set(my_list a b c d)
- set(my_list_of_numbers 1 2 3 4)
- print_list(my_list_of_numbers)
- # prints:
- # a
- # b
- # c
- # d
- Generally speaking this issue is uncommon because it requires using
- non-dereferenced variables with names that overlap in the parent scope, but it
- is important to be aware of because it can lead to subtle bugs.
- LLVM Project Wrappers
- =====================
- LLVM projects provide lots of wrappers around critical CMake built-in commands.
- We use these wrappers to provide consistent behaviors across LLVM components
- and to reduce code duplication.
- We generally (but not always) follow the convention that commands prefaced with
- ``llvm_`` are intended to be used only as building blocks for other commands.
- Wrapper commands that are intended for direct use are generally named following
- with the project in the middle of the command name (i.e. ``add_llvm_executable``
- is the wrapper for ``add_executable``). The LLVM ``add_*`` wrapper functions are
- all defined in ``AddLLVM.cmake`` which is installed as part of the LLVM
- distribution. It can be included and used by any LLVM sub-project that requires
- LLVM.
- .. note::
- Not all LLVM projects require LLVM for all use cases. For example compiler-rt
- can be built without LLVM, and the compiler-rt sanitizer libraries are used
- with GCC.
- Useful Built-in Commands
- ========================
- CMake has a bunch of useful built-in commands. This document isn't going to
- go into details about them because The CMake project has excellent
- documentation. To highlight a few useful functions see:
- * `add_custom_command <https://cmake.org/cmake/help/v3.4/command/add_custom_command.html>`_
- * `add_custom_target <https://cmake.org/cmake/help/v3.4/command/add_custom_target.html>`_
- * `file <https://cmake.org/cmake/help/v3.4/command/file.html>`_
- * `list <https://cmake.org/cmake/help/v3.4/command/list.html>`_
- * `math <https://cmake.org/cmake/help/v3.4/command/math.html>`_
- * `string <https://cmake.org/cmake/help/v3.4/command/string.html>`_
- The full documentation for CMake commands is in the ``cmake-commands`` manpage
- and available on `CMake's website <https://cmake.org/cmake/help/v3.4/manual/cmake-commands.7.html>`_
|