1
0
mirror of synced 2024-12-22 04:30:01 +01:00

style: run pre-commit

This commit is contained in:
Henry Schreiner 2022-06-02 14:30:14 -04:00
parent 00aedfb6ed
commit 43b34728e1
No known key found for this signature in database
GPG Key ID: B9D0E45146A241E8
40 changed files with 4569 additions and 4590 deletions

View File

@ -15,14 +15,15 @@ And CMake 3.11+ is supposed to be significantly faster, as well!
Are you interested in using CMake to build Python packages? Read about a [proposal to work on Scikit-build here][skprop], and let me know if you have a science use case! Are you interested in using CMake to build Python packages? Read about a [proposal to work on Scikit-build here][skprop], and let me know if you have a science use case!
[skprop]: https://iscinumpy.gitlab.io/post/scikit-build-proposal/ [skprop]: https://iscinumpy.gitlab.io/post/scikit-build-proposal/
{% endhint %}
{% endhint %}
{% hint style='working' %} {% hint style='working' %}
This book is meant to be a living document. You can raise an issue or put in a merge request on [GitLab](https://gitlab.com/CLIUtils/modern-cmake). This book is meant to be a living document. You can raise an issue or put in a merge request on [GitLab](https://gitlab.com/CLIUtils/modern-cmake).
You can also [download a copy as a PDF](https://CLIUtils.gitlab.io/modern-cmake/modern-cmake.pdf). Be sure to check the [HSF CMake Training][], as well! You can also [download a copy as a PDF](https://CLIUtils.gitlab.io/modern-cmake/modern-cmake.pdf). Be sure to check the [HSF CMake Training][], as well!
[HSF CMake Training]: https://hsf-training.github.io/hsf-training-cmake-webpage/01-intro/index.html [hsf cmake training]: https://hsf-training.github.io/hsf-training-cmake-webpage/01-intro/index.html
{% endhint %} {% endhint %}
In short, here are the most likely questions in your mind if you are considering Modern CMake: In short, here are the most likely questions in your mind if you are considering Modern CMake:
@ -31,16 +32,16 @@ In short, here are the most likely questions in your mind if you are considering
Do any of the following apply to you? Do any of the following apply to you?
* You want to avoid hard-coding paths - You want to avoid hard-coding paths
* You need to build a package on more than one computer - You need to build a package on more than one computer
* You want to use CI (continuous integration) - You want to use CI (continuous integration)
* You need to support different OSs (maybe even just flavors of Unix) - You need to support different OSs (maybe even just flavors of Unix)
* You want to support multiple compilers - You want to support multiple compilers
* You want to use an IDE, but maybe not all of the time - You want to use an IDE, but maybe not all of the time
* You want to describe how your program is structured logically, not flags and commands - You want to describe how your program is structured logically, not flags and commands
* You want to use a library - You want to use a library
* You want to use tools, like Clang-Tidy, to help you code - You want to use tools, like Clang-Tidy, to help you code
* You want to use a debugger - You want to use a debugger
If so, you'll benefit from a CMake-like build system. If so, you'll benefit from a CMake-like build system.
@ -55,7 +56,6 @@ So, if you use a library that is designed to be included in your code, you have
And that will quickly be the common denominator if you include multiple projects. And that will quickly be the common denominator if you include multiple projects.
And, if you need a library that's preinstalled, the chances of it having a find CMake script or config CMake script are excellent. And, if you need a library that's preinstalled, the chances of it having a find CMake script or config CMake script are excellent.
## Why use a Modern CMake? ## Why use a Modern CMake?
Around CMake 2.6-2.8, CMake started taking over. It was in most of the package managers for Linux OS's, and was being used in lots of packages. Around CMake 2.6-2.8, CMake started taking over. It was in most of the package managers for Linux OS's, and was being used in lots of packages.
@ -72,9 +72,9 @@ I believe that CMake 3 had the bad luck to follow Python 3.[^1]
Even though every version of CMake is insanely backward compatible, the 3 series was treated as if it were something new. Even though every version of CMake is insanely backward compatible, the 3 series was treated as if it were something new.
And so, you'll find OSs like CentOS7 with GCC 4.8, with almost-complete C++14 support, and CMake 2.8, which came out years before C++11. And so, you'll find OSs like CentOS7 with GCC 4.8, with almost-complete C++14 support, and CMake 2.8, which came out years before C++11.
You really should *at least* use a version of CMake that came out after your compiler, since it needs to know compiler flags, etc, for that version. You really should _at least_ use a version of CMake that came out after your compiler, since it needs to know compiler flags, etc, for that version.
And, since CMake will dumb itself down to the minimum required version in your CMake file, installing a new CMake, even system wide, is pretty safe. And, since CMake will dumb itself down to the minimum required version in your CMake file, installing a new CMake, even system wide, is pretty safe.
You should *at least* install it locally. You should _at least_ install it locally.
It's easy (1-2 lines in many cases), and you'll find that 5 minutes of work will save you hundreds of lines and hours of `CMakeLists.txt` writing, and will be much easier to maintain in the long run. It's easy (1-2 lines in many cases), and you'll find that 5 minutes of work will save you hundreds of lines and hours of `CMakeLists.txt` writing, and will be much easier to maintain in the long run.
This book tries to solve the problem of the poor examples and best practices that you'll find proliferating the web. This book tries to solve the problem of the poor examples and best practices that you'll find proliferating the web.
@ -83,24 +83,24 @@ This book tries to solve the problem of the poor examples and best practices tha
Other material from the original author of this book: Other material from the original author of this book:
* [HSF CMake Training][] - [HSF CMake Training][]
* [Interactive Modern CMake talks](https://gitlab.com/CLIUtils/modern-cmake-interactive-talk) - [Interactive Modern CMake talks](https://gitlab.com/CLIUtils/modern-cmake-interactive-talk)
There are some other places to find good information on the web. Here are some of them: There are some other places to find good information on the web. Here are some of them:
* [The official help](https://cmake.org/cmake/help/latest/): Really amazing documentation. Nicely organized, great search, and you can toggle versions at the top. It just doesn't have a great "best practices tutorial", which is what this book tries to fill in. - [The official help](https://cmake.org/cmake/help/latest/): Really amazing documentation. Nicely organized, great search, and you can toggle versions at the top. It just doesn't have a great "best practices tutorial", which is what this book tries to fill in.
* [Effective Modern CMake](https://gist.github.com/mbinna/c61dbb39bca0e4fb7d1f73b0d66a4fd1): A great list of do's and don'ts. - [Effective Modern CMake](https://gist.github.com/mbinna/c61dbb39bca0e4fb7d1f73b0d66a4fd1): A great list of do's and don'ts.
* [Embracing Modern CMake](https://steveire.wordpress.com/2017/11/05/embracing-modern-cmake/): A post with good description of the term - [Embracing Modern CMake](https://steveire.wordpress.com/2017/11/05/embracing-modern-cmake/): A post with good description of the term
* [It's time to do CMake Right](https://pabloariasal.github.io/2018/02/19/its-time-to-do-cmake-right/): A nice set of best practices for Modern CMake projects. - [It's time to do CMake Right](https://pabloariasal.github.io/2018/02/19/its-time-to-do-cmake-right/): A nice set of best practices for Modern CMake projects.
* [The Ultimate Guide to Modern CMake](https://rix0r.nl/blog/2015/08/13/cmake-guide/): A slightly dated post with similar intent. - [The Ultimate Guide to Modern CMake](https://rix0r.nl/blog/2015/08/13/cmake-guide/): A slightly dated post with similar intent.
* [More Modern CMake](https://youtu.be/y7ndUhdQuU8): A great presentation from Meeting C++ 2018 that recommends CMake 3.12+. This talk makes calls CMake 3.0+ "Modern CMake" and CMake 3.12+ "More Modern CMake". - [More Modern CMake](https://youtu.be/y7ndUhdQuU8): A great presentation from Meeting C++ 2018 that recommends CMake 3.12+. This talk makes calls CMake 3.0+ "Modern CMake" and CMake 3.12+ "More Modern CMake".
* [Oh No! More Modern CMake](https://www.youtube.com/watch?v=y9kSr5enrSk): The sequel to More Modern CMake. - [Oh No! More Modern CMake](https://www.youtube.com/watch?v=y9kSr5enrSk): The sequel to More Modern CMake.
* [toeb/moderncmake](https://github.com/toeb/moderncmake): A nice presentation and examples about CMake 3.5+, with intro to syntax through project organization - [toeb/moderncmake](https://github.com/toeb/moderncmake): A nice presentation and examples about CMake 3.5+, with intro to syntax through project organization
## Credits ## Credits
Modern CMake was originally written by [Henry Schreiner](https://iscinumpy.gitlab.io). Other contributors can be found [listed on GitLab](https://gitlab.com/CLIUtils/modern-cmake/-/network/master). Modern CMake was originally written by [Henry Schreiner](https://iscinumpy.gitlab.io). Other contributors can be found [listed on GitLab](https://gitlab.com/CLIUtils/modern-cmake/-/network/master).
[HSF CMake Training]: https://hsf-training.github.io/hsf-training-cmake-webpage/01-intro/index.html [hsf cmake training]: https://hsf-training.github.io/hsf-training-cmake-webpage/01-intro/index.html
[^1]: CMake 3.0 also removed several long deprecated features from very old versions of CMake and make one very tiny backwards incompatible change to syntax related to square brackets, so this is not entirely fair; there might be some very, very old CMake files that would stop working with 3. I've never seen one, though. [^1]: CMake 3.0 also removed several long deprecated features from very old versions of CMake and make one very tiny backwards incompatible change to syntax related to square brackets, so this is not entirely fair; there might be some very, very old CMake files that would stop working with 3. I've never seen one, though.

View File

@ -1,46 +1,45 @@
# Summary # Summary
* [An Introduction to Modern CMake](README.md) - [An Introduction to Modern CMake](README.md)
* [Installing CMake](chapters/intro/installing.md) - [Installing CMake](chapters/intro/installing.md)
* [Running CMake](chapters/intro/running.md) - [Running CMake](chapters/intro/running.md)
* [Do's and Don'ts](chapters/intro/dodonot.md) - [Do's and Don'ts](chapters/intro/dodonot.md)
* [What's new in CMake](chapters/intro/newcmake.md) - [What's new in CMake](chapters/intro/newcmake.md)
* [Introduction to the Basics](chapters/basics.md) - [Introduction to the Basics](chapters/basics.md)
* [Variables and the Cache](chapters/basics/variables.md) - [Variables and the Cache](chapters/basics/variables.md)
* [Programming in CMake](chapters/basics/functions.md) - [Programming in CMake](chapters/basics/functions.md)
* [Communicating with your code](chapters/basics/comms.md) - [Communicating with your code](chapters/basics/comms.md)
* [How to Structure Your Project](chapters/basics/structure.md) - [How to Structure Your Project](chapters/basics/structure.md)
* [Running Other Programs](chapters/basics/programs.md) - [Running Other Programs](chapters/basics/programs.md)
* [A Simple Example](chapters/basics/example.md) - [A Simple Example](chapters/basics/example.md)
* [Adding Features](chapters/features.md) - [Adding Features](chapters/features.md)
* [C++11 and Beyond](chapters/features/cpp11.md) - [C++11 and Beyond](chapters/features/cpp11.md)
* [Small but common needs](chapters/features/small.md) - [Small but common needs](chapters/features/small.md)
* [Utilities](chapters/features/utilities.md) - [Utilities](chapters/features/utilities.md)
* [Useful modules](chapters/features/modules.md) - [Useful modules](chapters/features/modules.md)
* [IDEs](chapters/features/ides.md) - [IDEs](chapters/features/ides.md)
* [Debugging](chapters/features/debug.md) - [Debugging](chapters/features/debug.md)
* [Including Projects](chapters/projects.md) - [Including Projects](chapters/projects.md)
* [Submodule](chapters/projects/submodule.md) - [Submodule](chapters/projects/submodule.md)
* [DownloadProject](chapters/projects/download.md) - [DownloadProject](chapters/projects/download.md)
* [Fetch (CMake 3.11)](chapters/projects/fetch.md) - [Fetch (CMake 3.11)](chapters/projects/fetch.md)
* [Testing](chapters/testing.md) - [Testing](chapters/testing.md)
* [GoogleTest](chapters/testing/googletest.md) - [GoogleTest](chapters/testing/googletest.md)
* [Catch](chapters/testing/catch.md) - [Catch](chapters/testing/catch.md)
* [Exporting and Installing](chapters/install.md) - [Exporting and Installing](chapters/install.md)
* [Installing](chapters/install/installing.md) - [Installing](chapters/install/installing.md)
* [Exporting](chapters/install/exporting.md) - [Exporting](chapters/install/exporting.md)
* [Packaging](chapters/install/packaging.md) - [Packaging](chapters/install/packaging.md)
* [Looking for Libraries (Packages)](chapters/packages.md) - [Looking for Libraries (Packages)](chapters/packages.md)
* [CUDA](chapters/packages/CUDA.md) - [CUDA](chapters/packages/CUDA.md)
* [OpenMP](chapters/packages/OpenMP.md) - [OpenMP](chapters/packages/OpenMP.md)
* [Boost](chapters/packages/Boost.md) - [Boost](chapters/packages/Boost.md)
* [MPI](chapters/packages/MPI.md) - [MPI](chapters/packages/MPI.md)
* [ROOT](chapters/packages/ROOT.md) - [ROOT](chapters/packages/ROOT.md)
* [UseFile Example](examples/root-usefile/README.md) - [UseFile Example](examples/root-usefile/README.md)
* [Simple Example](examples/root-simple/README.md) - [Simple Example](examples/root-simple/README.md)
* [Dictionary Example](examples/root-dict/README.md) - [Dictionary Example](examples/root-dict/README.md)
* [Minuit2](chapters/packages/Minuit2.md) - [Minuit2](chapters/packages/Minuit2.md)
<!-- <!--
* [Download PDF](ref://modern-cmake.pdf) * [Download PDF](ref://modern-cmake.pdf)

View File

@ -1,22 +1,50 @@
{ {
"title": "Modern CMake", "title": "Modern CMake",
"description": "A guide to writing simple, powerful, and clean CMake 3.1+ builds.", "description": "A guide to writing simple, powerful, and clean CMake 3.1+ builds.",
"author": "Henry Schreiner", "author": "Henry Schreiner",
"plugins": ["replace", "hints", "term", "include-codeblock", "ace"], "plugins": ["replace", "hints", "term", "include-codeblock", "ace"],
"pluginsConfig": { "pluginsConfig": {
"include-codeblock": { "include-codeblock": {
"fixlang": true "fixlang": true
}, },
"replace": { "replace": {
"substitutes": [ "substitutes": [
{"pattern": "«cmake:([^`^»]+)»", "flags": "g", "substitute": "[$1](https://cmake.org/cmake/help/latest/manual/cmake-$1.7.html)"}, {
{"pattern": "«command:`?([^`^»]+)`?»", "flags": "g", "substitute": "[`$1`](https://cmake.org/cmake/help/latest/command/$1.html)"}, "pattern": "«cmake:([^`^»]+)»",
{"pattern": "«envvar:`?([^`^»]+)`?»", "flags": "g", "substitute": "[`$1`](https://cmake.org/cmake/help/latest/envvar/$1.html)"}, "flags": "g",
{"pattern": "«module:([^`^»]+)»", "flags": "g", "substitute": "[$1](https://cmake.org/cmake/help/latest/module/$1.html)"}, "substitute": "[$1](https://cmake.org/cmake/help/latest/manual/cmake-$1.7.html)"
{"pattern": "«policy:([^`^»]+)»", "flags": "g", "substitute": "[$1](https://cmake.org/cmake/help/latest/policy/$1.html)"}, },
{"pattern": "«variable:`?([^`^»]+)`?»", "flags": "g", "substitute": "[`$1`](https://cmake.org/cmake/help/latest//$1.html)"}, {
{"pattern": "«prop:([^:]+):`?([^`^»]+)`?»", "flags": "g", "substitute": "[`$2`](https://cmake.org/cmake/help/latest/prop_$1/$2.html)"} "pattern": "«command:`?([^`^»]+)`?»",
] "flags": "g",
} "substitute": "[`$1`](https://cmake.org/cmake/help/latest/command/$1.html)"
},
{
"pattern": "«envvar:`?([^`^»]+)`?»",
"flags": "g",
"substitute": "[`$1`](https://cmake.org/cmake/help/latest/envvar/$1.html)"
},
{
"pattern": "«module:([^`^»]+)»",
"flags": "g",
"substitute": "[$1](https://cmake.org/cmake/help/latest/module/$1.html)"
},
{
"pattern": "«policy:([^`^»]+)»",
"flags": "g",
"substitute": "[$1](https://cmake.org/cmake/help/latest/policy/$1.html)"
},
{
"pattern": "«variable:`?([^`^»]+)`?»",
"flags": "g",
"substitute": "[`$1`](https://cmake.org/cmake/help/latest//$1.html)"
},
{
"pattern": "«prop:([^:]+):`?([^`^»]+)`?»",
"flags": "g",
"substitute": "[`$2`](https://cmake.org/cmake/help/latest/prop_$1/$2.html)"
}
]
} }
}
} }

View File

@ -1,6 +1,5 @@
# Introduction to the basics # Introduction to the basics
## Minimum Version ## Minimum Version
Here's the first line of every `CMakeLists.txt`, which is the required name of Here's the first line of every `CMakeLists.txt`, which is the required name of
@ -18,8 +17,7 @@ this book, just click on the command name to see the official documentation,
and use the dropdown to switch documentation between CMake versions. and use the dropdown to switch documentation between CMake versions.
This line is special! [^2] The version of CMake will also dictate the policies, This line is special! [^2] The version of CMake will also dictate the policies,
which define behavior changes. So, if you set `minimum_required` to `VERSION which define behavior changes. So, if you set `minimum_required` to `VERSION 2.8`, you'll get the wrong linking behavior on macOS, for example, even in the
2.8`, you'll get the wrong linking behavior on macOS, for example, even in the
newest CMake versions. If you set it to 3.3 or less, you'll get the wrong newest CMake versions. If you set it to 3.3 or less, you'll get the wrong
hidden symbols behaviour, etc. A list of policies and versions is available at hidden symbols behaviour, etc. A list of policies and versions is available at
«cmake:policies». «cmake:policies».
@ -63,14 +61,12 @@ else()
endif() endif()
``` ```
{% hint style='info' %} {% hint style='info' %}
If you really need to set to a low value here, you can use If you really need to set to a low value here, you can use
«command:`cmake_policy`» to conditionally increase the policy level or set a «command:`cmake_policy`» to conditionally increase the policy level or set a
specific policy. Please at least do this for your macOS users! specific policy. Please at least do this for your macOS users!
{% endhint %} {% endhint %}
## Setting a project ## Setting a project
Now, every top-level CMake file will have the next line: Now, every top-level CMake file will have the next line:
@ -110,7 +106,6 @@ add_executable(one two.cpp three.h)
There are several things to unpack here. `one` is both the name of the executable file generated, and the name of the CMake target created (you'll hear a lot more about targets soon, I promise). The source file list comes next, and you can list as many as you'd like. CMake is smart, and will only compile source file extensions. The headers will be, for most intents and purposes, ignored; the only reason to list them is to get them to show up in IDEs. Targets show up as folders in many IDEs. More about the general build system and targets is available at «cmake:buildsystem». There are several things to unpack here. `one` is both the name of the executable file generated, and the name of the CMake target created (you'll hear a lot more about targets soon, I promise). The source file list comes next, and you can list as many as you'd like. CMake is smart, and will only compile source file extensions. The headers will be, for most intents and purposes, ignored; the only reason to list them is to get them to show up in IDEs. Targets show up as folders in many IDEs. More about the general build system and targets is available at «cmake:buildsystem».
## Making a library ## Making a library
Making a library is done with «command:`add_library`», and is just about as simple: Making a library is done with «command:`add_library`», and is just about as simple:
@ -133,7 +128,7 @@ Now we've specified a target, how do we add information about it? For example, m
target_include_directories(one PUBLIC include) target_include_directories(one PUBLIC include)
``` ```
«command:`target_include_directories» adds an include directory to a target. `PUBLIC` doesn't mean much for an executable; for a library it lets CMake know that any targets that link to this target must also need that include directory. Other options are `PRIVATE` (only affect the current target, not dependencies), and `INTERFACE` (only needed for dependencies). «command:`target_include_directories» adds an include directory to a target. `PUBLIC`doesn't mean much for an executable; for a library it lets CMake know that any targets that link to this target must also need that include directory. Other options are`PRIVATE`(only affect the current target, not dependencies), and`INTERFACE` (only needed for dependencies).
We can then chain targets: We can then chain targets:
@ -148,7 +143,6 @@ Focus on using targets everywhere, and keywords everywhere, and you'll be fine.
Targets can have include directories, linked libraries (or linked targets), compile options, compile definitions, compile features (see the C++11 chapter), and more. As you'll see in the two including projects chapters, you can often get targets (and always make targets) to represent all the libraries you use. Even things that are not true libraries, like OpenMP, can be represented with targets. This is why Modern CMake is great! Targets can have include directories, linked libraries (or linked targets), compile options, compile definitions, compile features (see the C++11 chapter), and more. As you'll see in the two including projects chapters, you can often get targets (and always make targets) to represent all the libraries you use. Even things that are not true libraries, like OpenMP, can be represented with targets. This is why Modern CMake is great!
## Dive in ## Dive in
See if you can follow the following file. It makes a simple C++11 library and a program using it. No dependencies. I'll discuss more C++ standard options later, using the CMake 3.8 system for now. See if you can follow the following file. It makes a simple C++11 library and a program using it. No dependencies. I'll discuss more C++ standard options later, using the CMake 3.8 system for now.
@ -167,9 +161,6 @@ target_link_libraries(calc PUBLIC calclib)
``` ```
[^1]: In this book, I'll mostly avoid showing you the wrong way to do things; you can find plenty of examples of that online. I'll mention alternatives occasionally, but these are not recommended unless they are absolutely necessary; often they are just there to help you read older CMake code. [^1]: In this book, I'll mostly avoid showing you the wrong way to do things; you can find plenty of examples of that online. I'll mention alternatives occasionally, but these are not recommended unless they are absolutely necessary; often they are just there to help you read older CMake code.
[^2]: You will sometimes see `FATAL_ERROR` here, that was needed to support nice failures when running this in CMake <2.6, which should not be a problem anymore. [^2]: You will sometimes see `FATAL_ERROR` here, that was needed to support nice failures when running this in CMake <2.6, which should not be a problem anymore.
[^3]: The `::` syntax was originally intended for `INTERFACE IMPORTED` libraries, which were explicitly supposed to be libraries defined outside the current project. But, because of this, most of the `target_*` commands don't work on `IMPORTED` libraries, making them hard to set up yourself. So don't use the `IMPORTED` keyword for now, and use an `ALIAS` target instead; it will be fine until you start exporting targets. This limitation was fixed in CMake 3.11. [^3]: The `::` syntax was originally intended for `INTERFACE IMPORTED` libraries, which were explicitly supposed to be libraries defined outside the current project. But, because of this, most of the `target_*` commands don't work on `IMPORTED` libraries, making them hard to set up yourself. So don't use the `IMPORTED` keyword for now, and use an `ALIAS` target instead; it will be fine until you start exporting targets. This limitation was fixed in CMake 3.11.

View File

@ -19,6 +19,7 @@ This functionality is used quite frequently; for example, on `Version.h.in`:
``` ```
#### CMake lines: #### CMake lines:
```cmake ```cmake
configure_file ( configure_file (
"${PROJECT_SOURCE_DIR}/include/My/Version.h.in" "${PROJECT_SOURCE_DIR}/include/My/Version.h.in"

View File

@ -1,7 +1,7 @@
# A simple example # A simple example
This is a simple yet complete example of a proper CMakeLists. For this program, we have one library (MyLibExample) with a header file and a source file, This is a simple yet complete example of a proper CMakeLists. For this program, we have one library (MyLibExample) with a header file and a source file,
and one application, MyExample, with one source file. and one application, MyExample, with one source file.
[import:'main', lang:'cmake'](../../examples/simple-project/CMakeLists.txt) [import:'main', lang:'cmake'](../../examples/simple-project/CMakeLists.txt)

View File

@ -25,10 +25,9 @@ endif()
There are a variety of keywords as well, such as: There are a variety of keywords as well, such as:
* Unary: `NOT`, `TARGET`, `EXISTS` (file), `DEFINED`, etc. - Unary: `NOT`, `TARGET`, `EXISTS` (file), `DEFINED`, etc.
* Binary: `STREQUAL`, `AND`, `OR`, `MATCHES` (regular expression), `VERSION_LESS`, `VERSION_LESS_EQUAL` (CMake 3.7+), etc. - Binary: `STREQUAL`, `AND`, `OR`, `MATCHES` (regular expression), `VERSION_LESS`, `VERSION_LESS_EQUAL` (CMake 3.7+), etc.
* Parentheses can be used to group - Parentheses can be used to group
## «cmake:generator-expressions» ## «cmake:generator-expressions»
@ -48,9 +47,9 @@ This is a newer, better way to add things than using specialized `*_DEBUG` varia
Other common uses for generator expressions: Other common uses for generator expressions:
* Limiting an item to a certain language only, such as CXX, to avoid it mixing with something like CUDA, or wrapping it so that it is different depending on target language. - Limiting an item to a certain language only, such as CXX, to avoid it mixing with something like CUDA, or wrapping it so that it is different depending on target language.
* Accessing configuration dependent properties, like target file location. - Accessing configuration dependent properties, like target file location.
* Giving a different location for build and install directories. - Giving a different location for build and install directories.
That last one is very common. You'll see something like this in almost every package that supports installing: That last one is very common. You'll see something like this in almost every package that supports installing:
@ -119,6 +118,5 @@ COMPLEX_PREFIX_MULTI_VALUES = "some;other;values"
If you look at the official page, you'll see a slightly different method using set to avoid explicitly writing the semicolons in the list; feel free to use the structure you like best. You can mix it with the positional arguments listed above; any remaining arguments (therefore optional positional arguments) are in `COMPLEX_PREFIX_UNPARSED_ARGUMENTS`. If you look at the official page, you'll see a slightly different method using set to avoid explicitly writing the semicolons in the list; feel free to use the structure you like best. You can mix it with the positional arguments listed above; any remaining arguments (therefore optional positional arguments) are in `COMPLEX_PREFIX_UNPARSED_ARGUMENTS`.
[^1]: They act as if they are evaluated at build/install time, though actually they are evaluated for each build configuration. [^1]: They act as if they are evaluated at build/install time, though actually they are evaluated for each build configuration.
[^2]: The CMake docs splits expressions into Informational, Logical, and Output. [^2]: The CMake docs splits expressions into Informational, Logical, and Output.

View File

@ -2,9 +2,9 @@
The following information is biased. But in a good way, I think. I'm going to tell you how to structure the directories in your project. This is based on convention, but will help you: The following information is biased. But in a good way, I think. I'm going to tell you how to structure the directories in your project. This is based on convention, but will help you:
* Easily read other projects following the same patterns, - Easily read other projects following the same patterns,
* Avoid a pattern that causes conflicts, - Avoid a pattern that causes conflicts,
* Keep from muddling and complicating your build. - Keep from muddling and complicating your build.
First, this is what your files should look like when you start if your project is creatively called `project`, with a library called `lib`, and a executable called `app`: First, this is what your files should look like when you start if your project is creatively called `project`, with a library called `lib`, and a executable called `app`:

View File

@ -1,13 +1,14 @@
# Variables and the Cache # Variables and the Cache
## Local Variables ## Local Variables
We will cover variables first. A local variable is set like this: We will cover variables first. A local variable is set like this:
```CMake ```CMake
set(MY_VARIABLE "value") set(MY_VARIABLE "value")
``` ```
The names of variables are usually all caps, and the value follows. You access a variable by using `${}`, such as `${MY_VARIABLE}`.[^1] CMake has the concept of scope; you can access the value of the variable after you set it as long as you are in the same scope. If you leave a function or a file in a sub directory, the variable will no longer be defined. You can set a variable in the scope immediately above your current one with `PARENT_SCOPE` at the end. The names of variables are usually all caps, and the value follows. You access a variable by using `${}`, such as `${MY_VARIABLE}`.[^1] CMake has the concept of scope; you can access the value of the variable after you set it as long as you are in the same scope. If you leave a function or a file in a sub directory, the variable will no longer be defined. You can set a variable in the scope immediately above your current one with `PARENT_SCOPE` at the end.
Lists are simply a series of values when you set them: Lists are simply a series of values when you set them:
@ -49,9 +50,9 @@ set(MY_CACHE_VARIABLE "VALUE" CACHE INTERNAL "")
Since `BOOL` is such a common variable type, you can set it more succinctly with the shortcut: Since `BOOL` is such a common variable type, you can set it more succinctly with the shortcut:
```cmake ```cmake
option(MY_OPTION "This is settable from the command line" OFF) option(MY_OPTION "This is settable from the command line" OFF)
``` ```
For the `BOOL` datatype, there are several different wordings for `ON` and `OFF`. For the `BOOL` datatype, there are several different wordings for `ON` and `OFF`.

View File

@ -2,7 +2,6 @@
This section covers adding common features to your CMake project. You'll learn how to add a variety of options commonly needed in C++ projects, like C++11 support, as well as how to support IDEs and more. This section covers adding common features to your CMake project. You'll learn how to add a variety of options commonly needed in C++ projects, like C++11 support, as well as how to support IDEs and more.
## Default build type ## Default build type
CMake normally does a "non-release, non debug" empty build type; if you prefer to set the default build type yourself, you can follow this CMake normally does a "non-release, non debug" empty build type; if you prefer to set the default build type yourself, you can follow this

View File

@ -2,7 +2,6 @@
C++11 is supported by CMake. Really. Just not in CMake 2.8, because, guess what, C++11 didn't exist in 2009 when 2.0 was released. As long as you are using CMake 3.1 or newer, you should be fine, there are two different ways to enable support. And as you'll soon see, there's even better support in CMake 3.8+. I'll start with that, since this is Modern CMake. C++11 is supported by CMake. Really. Just not in CMake 2.8, because, guess what, C++11 didn't exist in 2009 when 2.0 was released. As long as you are using CMake 3.1 or newer, you should be fine, there are two different ways to enable support. And as you'll soon see, there's even better support in CMake 3.8+. I'll start with that, since this is Modern CMake.
## CMake 3.8+: Meta compiler features ## CMake 3.8+: Meta compiler features
As long as you can require that a user install CMake, you'll have access to the newest way to enable C++ standards. This is the most powerful way, with the nicest syntax and the best support for new standards, and the best target behavior for mixing standards and options. Assuming you have a target named `myTarget`, it looks like this: As long as you can require that a user install CMake, you'll have access to the newest way to enable C++ standards. This is the most powerful way, with the nicest syntax and the best support for new standards, and the best target behavior for mixing standards and options. Assuming you have a target named `myTarget`, it looks like this:
@ -12,19 +11,16 @@ target_compile_features(myTarget PUBLIC cxx_std_11)
set_target_properties(myTarget PROPERTIES CXX_EXTENSIONS OFF) set_target_properties(myTarget PROPERTIES CXX_EXTENSIONS OFF)
``` ```
For the first line, we get to pick between `cxx_std_11`, `cxx_std_14`, and `cxx_std_17`. The second line is optional, but will avoid extensions being added; without it you'd get things like `-std=g++11` replacing `-std=c++11`. The first line even works on `INTERFACE` targets; only actual compiled targets can use the second line. For the first line, we get to pick between `cxx_std_11`, `cxx_std_14`, and `cxx_std_17`. The second line is optional, but will avoid extensions being added; without it you'd get things like `-std=g++11` replacing `-std=c++11`. The first line even works on `INTERFACE` targets; only actual compiled targets can use the second line.
If a target further down the dependency chain specifies a higher C++ level, this interacts nicely. It's really just a more advanced version of the following method, so it interacts nicely with that, too. If a target further down the dependency chain specifies a higher C++ level, this interacts nicely. It's really just a more advanced version of the following method, so it interacts nicely with that, too.
## CMake 3.1+: Compiler features ## CMake 3.1+: Compiler features
You can ask for specific compiler features to be available. This was more granular than asking for a C++ version, though it's a bit tricky to pick out just the features a package is using unless you wrote the package and have a good memory. Since this ultimately checks against a list of options CMake knows your compiler supports and picks the highest flag indicated in that list, you don't have to specify all the options you need, just the rarest ones. The syntax is identical to the section above, you just have a list of options to pick instead of `cxx_std_*` options. See the [whole list here](https://cmake.org/cmake/help/latest/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.html). You can ask for specific compiler features to be available. This was more granular than asking for a C++ version, though it's a bit tricky to pick out just the features a package is using unless you wrote the package and have a good memory. Since this ultimately checks against a list of options CMake knows your compiler supports and picks the highest flag indicated in that list, you don't have to specify all the options you need, just the rarest ones. The syntax is identical to the section above, you just have a list of options to pick instead of `cxx_std_*` options. See the [whole list here](https://cmake.org/cmake/help/latest/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.html).
If you have optional features, you can use the list `CMAKE_CXX_COMPILE_FEATURES` and use `if(... IN_LIST ...)` from CMake 3.3+ to see if that feature is supported, and add it conditionally. See [the docs here](https://cmake.org/cmake/help/latest/manual/cmake-compile-features.7.html) for other use cases. If you have optional features, you can use the list `CMAKE_CXX_COMPILE_FEATURES` and use `if(... IN_LIST ...)` from CMake 3.3+ to see if that feature is supported, and add it conditionally. See [the docs here](https://cmake.org/cmake/help/latest/manual/cmake-compile-features.7.html) for other use cases.
## CMake 3.1+: Global and property settings ## CMake 3.1+: Global and property settings
There is another way that C++ standards are supported; a specific set of three properties (both global and target level). The global properties are: There is another way that C++ standards are supported; a specific set of three properties (both global and target level). The global properties are:

View File

@ -30,7 +30,6 @@ cmake_print_properties(
) )
``` ```
### Tracing a run ### Tracing a run
Have you wanted to watch exactly what happens in your CMake file, and when? The `--trace-source="filename"` feature is fantastic. Every line run in the file that you give will be echoed to the screen when it is run, letting you follow exactly what is happening. There are related options as well, but they tend to bury you in output. Have you wanted to watch exactly what happens in your CMake file, and when? The `--trace-source="filename"` feature is fantastic. Every line run in the file that you give will be echoed to the screen when it is run, letting you follow exactly what is happening. There are related options as well, but they tend to bury you in output.
@ -43,7 +42,6 @@ cmake -S . -B build --trace-source=CMakeLists.txt
If you add `--trace-expand`, the variables will be expanded into their values. If you add `--trace-expand`, the variables will be expanded into their values.
## Building in debug mode ## Building in debug mode
For single-configuration generators, you can build your code with `-DCMAKE_BUILD_TYPE=Debug` to get debugging flags. In multi-configuration generators, like many IDEs, you can pick the configuration in the IDE. There are distinct flags for this mode (variables ending in `_DEBUG` as opposed to `_RELEASE`), as well as a generator expression value `CONFIG:Debug` or `CONFIG:Release`. For single-configuration generators, you can build your code with `-DCMAKE_BUILD_TYPE=Debug` to get debugging flags. In multi-configuration generators, like many IDEs, you can pick the configuration in the IDE. There are distinct flags for this mode (variables ending in `_DEBUG` as opposed to `_RELEASE`), as well as a generator expression value `CONFIG:Debug` or `CONFIG:Release`.

View File

@ -18,8 +18,6 @@ set_property(TARGET MyFile PROPERTY FOLDER "Scripts")
Folders can be nested with `/`. Folders can be nested with `/`.
You can control how files show up in each folder with regular expressions or explicit listings in [`source_group`](https://cmake.org/cmake/help/latest/command/source_group.html): You can control how files show up in each folder with regular expressions or explicit listings in [`source_group`](https://cmake.org/cmake/help/latest/command/source_group.html):
## Folders for files ## Folders for files
@ -47,5 +45,4 @@ CMake will strip the `TREE` path from the `FILE_LIST` path, it will add `PREFIX`
To use an IDE, either pass `-G"name of IDE"` if CMake can produce that IDE's files (like Xcode, Visual Studio), or open the CMakeLists.txt file from your IDE if that IDE has built in support for CMake (CLion, QtCreator, many others). To use an IDE, either pass `-G"name of IDE"` if CMake can produce that IDE's files (like Xcode, Visual Studio), or open the CMakeLists.txt file from your IDE if that IDE has built in support for CMake (CLion, QtCreator, many others).
[sorting]: http://blog.audio-tk.com/2015/09/01/sorting-source-files-and-projects-in-folders-with-cmake-and-visual-studioxcode/ [sorting]: http://blog.audio-tk.com/2015/09/01/sorting-source-files-and-projects-in-folders-with-cmake-and-visual-studioxcode/

View File

@ -31,11 +31,9 @@ Note that `BUILD_TESTING` is a better way to check for testing being enabled if
## «module:CMakePrintHelpers» ## «module:CMakePrintHelpers»
This module has a couple of handy output functions. `cmake_print_properties` lets you easily print properties. This module has a couple of handy output functions. `cmake_print_properties` lets you easily print properties.
And `cmake_print_variables` will print the names and values of any variables you give it. And `cmake_print_variables` will print the names and values of any variables you give it.
## «module:CheckCXXCompilerFlag» ## «module:CheckCXXCompilerFlag»
This checks to see if a flag is supported. For example: This checks to see if a flag is supported. For example:

View File

@ -35,11 +35,9 @@ endif()
You can pretty easily find `Find*.cmake`'s for this and other libraries that you need with a quick search; most major packages have a helper library of CMake modules. See the chapter on existing package inclusion for more. You can pretty easily find `Find*.cmake`'s for this and other libraries that you need with a quick search; most major packages have a helper library of CMake modules. See the chapter on existing package inclusion for more.
## Interprocedural optimization ## Interprocedural optimization
«prop:tgt:INTERPROCEDURAL_OPTIMIZATION», best known as *link time optimization* and the `-flto` flag, is available on very recent versions of CMake. You can turn this on with «variable:CMAKE_INTERPROCEDURAL_OPTIMIZATION» (CMake 3.9+ only) or the «prop:tgt:INTERPROCEDURAL_OPTIMIZATION» property on targets. Support for GCC and Clang was added in CMake 3.8. If you set `cmake_minimum_required(VERSION 3.9)` or better (see «policy:CMP0069»), setting this to `ON` on a target is an error if the compiler doesn't support it. You can use check_ipo_supported(), from the built-in «module:CheckIPOSupported» module, to see if support is available before hand. An example of 3.9 style usage: «prop:tgt:INTERPROCEDURAL*OPTIMIZATION», best known as \_link time optimization* and the `-flto` flag, is available on very recent versions of CMake. You can turn this on with «variable:CMAKE_INTERPROCEDURAL_OPTIMIZATION» (CMake 3.9+ only) or the «prop:tgt:INTERPROCEDURAL_OPTIMIZATION» property on targets. Support for GCC and Clang was added in CMake 3.8. If you set `cmake_minimum_required(VERSION 3.9)` or better (see «policy:CMP0069»), setting this to `ON` on a target is an error if the compiler doesn't support it. You can use check_ipo_supported(), from the built-in «module:CheckIPOSupported» module, to see if support is available before hand. An example of 3.9 style usage:
```cmake ```cmake
include(CheckIPOSupported) include(CheckIPOSupported)

View File

@ -8,7 +8,6 @@ All of these take `;` separated values (a standard list in CMake) that describe
Set the `CMAKE_<LANG>_COMPILER_LAUNCHER` variable or the `<LANG>_COMPILER_LAUNCHER` property on a target to use something like CCache to "wrap" the compilation of the target. Support for CCache has been expanding in the latest versions of CMake. In practice, this tends to look like this: Set the `CMAKE_<LANG>_COMPILER_LAUNCHER` variable or the `<LANG>_COMPILER_LAUNCHER` property on a target to use something like CCache to "wrap" the compilation of the target. Support for CCache has been expanding in the latest versions of CMake. In practice, this tends to look like this:
```cmake ```cmake
find_program(CCACHE_PROGRAM ccache) find_program(CCACHE_PROGRAM ccache)
if(CCACHE_PROGRAM) if(CCACHE_PROGRAM)
@ -17,15 +16,14 @@ if(CCACHE_PROGRAM)
endif() endif()
``` ```
## Utilities ## Utilities
Set the following properties or `CMAKE_*` initializer variables to the command line for the tools. Most of them are limited to C or CXX with make or ninja generators. Set the following properties or `CMAKE_*` initializer variables to the command line for the tools. Most of them are limited to C or CXX with make or ninja generators.
* `<LANG>_CLANG_TIDY`: CMake 3.6+ - `<LANG>_CLANG_TIDY`: CMake 3.6+
* `<LANG>_CPPCHECK` - `<LANG>_CPPCHECK`
* `<LANG>_CPPLINT` - `<LANG>_CPPLINT`
* `<LANG>_INCLUDE_WHAT_YOU_USE` - `<LANG>_INCLUDE_WHAT_YOU_USE`
## Clang tidy ## Clang tidy
@ -61,8 +59,7 @@ find_program(
## Include what you use ## Include what you use
This is an example for using include what you use. First, you'll need to have This is an example for using include what you use. First, you'll need to have
the tool, such as in a docker container or with brew (macOS) with `brew install the tool, such as in a docker container or with brew (macOS) with `brew install include-what-you-use`. Then, you can pass this into your build without
include-what-you-use`. Then, you can pass this into your build without
modifying the source: modifying the source:
```term ```term

View File

@ -20,7 +20,6 @@ add_library(MyLib::MyLib ALIAS MyLib)
to standardise the usage across all methods. This ALIAS target will not be exported below. to standardise the usage across all methods. This ALIAS target will not be exported below.
## Exporting ## Exporting
The third way is `*Config.cmake` scripts; that will be the topic of the next chapter in this session. The third way is `*Config.cmake` scripts; that will be the topic of the next chapter in this session.

View File

@ -25,7 +25,6 @@ write_basic_package_version_file(
) )
``` ```
You have two choices next. You need to make a `MyLibConfig.cmake`, but you can do it either by exporting your targets directly to it, or by writing it by hand, then including the targets file. The later option is what you'll need if you have any dependencies, even just OpenMP, so I'll illustrate that method. You have two choices next. You need to make a `MyLibConfig.cmake`, but you can do it either by exporting your targets directly to it, or by writing it by hand, then including the targets file. The later option is what you'll need if you have any dependencies, even just OpenMP, so I'll illustrate that method.
First, make an install targets file (very similar to the one you made in the build directory): First, make an install targets file (very similar to the one you made in the build directory):

View File

@ -4,24 +4,22 @@
The next two lists are heavily based on the excellent gist [Effective Modern CMake]. That list is much longer and more detailed, feel free to read it as well. The next two lists are heavily based on the excellent gist [Effective Modern CMake]. That list is much longer and more detailed, feel free to read it as well.
* **Do not use global functions**: This includes `link_directories`, `include_libraries`, and similar. - **Do not use global functions**: This includes `link_directories`, `include_libraries`, and similar.
* **Don't add unneeded PUBLIC requirements**: You should avoid forcing something on users that is not required (`-Wall`). Make these PRIVATE instead. - **Don't add unneeded PUBLIC requirements**: You should avoid forcing something on users that is not required (`-Wall`). Make these PRIVATE instead.
* **Don't GLOB files**: Make or another tool will not know if you add files without rerunning CMake. Note that CMake 3.12 adds a `CONFIGURE_DEPENDS` flag that makes this far better if you need to use it. - **Don't GLOB files**: Make or another tool will not know if you add files without rerunning CMake. Note that CMake 3.12 adds a `CONFIGURE_DEPENDS` flag that makes this far better if you need to use it.
* **Link to built files directly**: Always link to targets if available. - **Link to built files directly**: Always link to targets if available.
* **Never skip PUBLIC/PRIVATE when linking**: This causes all future linking to be keyword-less. - **Never skip PUBLIC/PRIVATE when linking**: This causes all future linking to be keyword-less.
## CMake Patterns ## CMake Patterns
* **Treat CMake as code**: It is code. It should be as clean and readable as all other code. - **Treat CMake as code**: It is code. It should be as clean and readable as all other code.
* **Think in targets**: Your targets should represent concepts. Make an (IMPORTED) INTERFACE target for anything that should stay together and link to that. - **Think in targets**: Your targets should represent concepts. Make an (IMPORTED) INTERFACE target for anything that should stay together and link to that.
* **Export your interface**: You should be able to run from build or install. - **Export your interface**: You should be able to run from build or install.
* **Write a Config.cmake file**: This is what a library author should do to support clients. - **Write a Config.cmake file**: This is what a library author should do to support clients.
* **Make ALIAS targets to keep usage consistent**: Using `add_subdirectory` and `find_package` should provide the same targets and namespaces. - **Make ALIAS targets to keep usage consistent**: Using `add_subdirectory` and `find_package` should provide the same targets and namespaces.
* **Combine common functionality into clearly documented functions or macros**: Functions are better usually. - **Combine common functionality into clearly documented functions or macros**: Functions are better usually.
* **Use lowercase function names**: CMake functions and macros can be called lower or upper case. Always use lower case. Upper case is for variables. - **Use lowercase function names**: CMake functions and macros can be called lower or upper case. Always use lower case. Upper case is for variables.
* **Use `cmake_policy` and/or range of versions**: Policies change for a reason. Only piecemeal set OLD policies if you have to. - **Use `cmake_policy` and/or range of versions**: Policies change for a reason. Only piecemeal set OLD policies if you have to.
## Selecting a minimum in 2022: ## Selecting a minimum in 2022:
@ -36,23 +34,22 @@ at least as new as your compiler.
### What minimum to choose - OS support: ### What minimum to choose - OS support:
* 3.4: The bare minimum. Never set less. - 3.4: The bare minimum. Never set less.
* 3.7: Debian old-stable. - 3.7: Debian old-stable.
* 3.10: Ubuntu 18.04. - 3.10: Ubuntu 18.04.
* 3.11: CentOS 8 (use EPEL or AppSteams, though) - 3.11: CentOS 8 (use EPEL or AppSteams, though)
* 3.13: Debian stable. - 3.13: Debian stable.
* 3.16: Ubuntu 20.04. - 3.16: Ubuntu 20.04.
* 3.19: First to support Apple Silicon. - 3.19: First to support Apple Silicon.
* latest: pip/conda-forge/homebew/chocolaty, etc. - latest: pip/conda-forge/homebew/chocolaty, etc.
### What minimum to choose - Features: ### What minimum to choose - Features:
* 3.8: C++ meta features, CUDA, lots more - 3.8: C++ meta features, CUDA, lots more
* 3.11: `IMPORTED INTERFACE` setting, faster, FetchContent, `COMPILE_LANGUAGE` in IDEs - 3.11: `IMPORTED INTERFACE` setting, faster, FetchContent, `COMPILE_LANGUAGE` in IDEs
* 3.12: C++20, `cmake --build build -j N`, `SHELL:`, FindPython - 3.12: C++20, `cmake --build build -j N`, `SHELL:`, FindPython
* 3.14/3.15: CLI, FindPython updates - 3.14/3.15: CLI, FindPython updates
* 3.16: Unity builds / precompiled headers, CUDA meta features - 3.16: Unity builds / precompiled headers, CUDA meta features
* 3.17/3.18: Lots more CUDA, metaprogramming - 3.17/3.18: Lots more CUDA, metaprogramming
[effective modern cmake]: https://gist.github.com/mbinna/c61dbb39bca0e4fb7d1f73b0d66a4fd1
[Effective Modern CMake]: https://gist.github.com/mbinna/c61dbb39bca0e4fb7d1f73b0d66a4fd1

View File

@ -10,23 +10,23 @@ If you have a built in copy of CMake, it isn't special or customized for your sy
Ordered by author preference: Ordered by author preference:
* All - All
- [Pip(x)][PyPI] (official, often updates same-day) - [Pip(x)][pypi] (official, often updates same-day)
- [Anaconda][] / [Conda-Forge][] - [Anaconda][] / [Conda-Forge][]
* Windows - Windows
- [Winget][] - [Winget][]
- [Chocolatey][] - [Chocolatey][]
- [Scoop][] - [Scoop][]
- [MSYS2][] - [MSYS2][]
- [Download binary][download] (official) - [Download binary][download] (official)
* MacOS - MacOS
- [Homebrew][] - [Homebrew][]
- [MacPorts][] - [MacPorts][]
- [Download binary][download] (official) - [Download binary][download] (official)
* Linux - Linux
- [Snapcraft][snap] (official) - [Snapcraft][snap] (official)
- [APT repository][apt] (Ubuntu/Debian only) (official) - [APT repository][apt] (Ubuntu/Debian only) (official)
- [Download binary][download] (official) - [Download binary][download] (official)
## Official package ## Official package
@ -53,7 +53,6 @@ And, if you want a system install, install to `/usr/local`; this is an excellent
docker $ wget -qO- "https://cmake.org/files/v3.23/cmake-3.23.1-linux-x86_64.tar.gz" | tar --strip-components=1 -xz -C /usr/local docker $ wget -qO- "https://cmake.org/files/v3.23/cmake-3.23.1-linux-x86_64.tar.gz" | tar --strip-components=1 -xz -C /usr/local
{% endterm %} {% endterm %}
If you are on a system without wget, replace `wget -qO-` with `curl -s`. If you are on a system without wget, replace `wget -qO-` with `curl -s`.
You can also build CMake on any system, it's pretty easy, but binaries are faster. You can also build CMake on any system, it's pretty easy, but binaries are faster.
@ -64,10 +63,10 @@ Here are some common build environments and the CMake version you'll find on the
### Windows ### Windows
[![Winget package](https://repology.org/badge/version-for-repo/winget/cmake.svg)][Winget] [![Winget package](https://repology.org/badge/version-for-repo/winget/cmake.svg)][winget]
[![Chocolatey package](https://repology.org/badge/version-for-repo/chocolatey/cmake.svg)][chocolatey] [![Chocolatey package](https://repology.org/badge/version-for-repo/chocolatey/cmake.svg)][chocolatey]
[![MSYS2 mingw package](https://repology.org/badge/version-for-repo/msys2_mingw/cmake.svg)][MSYS2] [![MSYS2 mingw package](https://repology.org/badge/version-for-repo/msys2_mingw/cmake.svg)][msys2]
[![MSYS2 msys2 package](https://repology.org/badge/version-for-repo/msys2_msys2/cmake.svg)][MSYS2] [![MSYS2 msys2 package](https://repology.org/badge/version-for-repo/msys2_msys2/cmake.svg)][msys2]
Also [Scoop][scoop] is generally up to date. The normal installers from CMake.org are common on Windows, too. Also [Scoop][scoop] is generally up to date. The normal installers from CMake.org are common on Windows, too.
@ -121,21 +120,20 @@ You should only use the default CMake on 18.04+; it's an LTS release with a pret
### General tools ### General tools
[![ConanCenter package](https://repology.org/badge/version-for-repo/conancenter/cmake.svg)][repology] [![ConanCenter package](https://repology.org/badge/version-for-repo/conancenter/cmake.svg)][repology]
[![PyPI](https://img.shields.io/pypi/v/cmake)][PyPI] [![PyPI](https://img.shields.io/pypi/v/cmake)][pypi]
[![Conda-forge](https://img.shields.io/conda/vn/conda-forge/cmake.svg)][Conda-Forge] [![Conda-forge](https://img.shields.io/conda/vn/conda-forge/cmake.svg)][conda-forge]
[![Anaconda](https://anaconda.org/anaconda/cmake/badges/version.svg?style=flat)][Anaconda] [![Anaconda](https://anaconda.org/anaconda/cmake/badges/version.svg?style=flat)][anaconda]
Just `pip install cmake` on many systems. Add `--user` if you have to (modern pip does this for you if needed). This does not supply Universal2 wheels yet. Just `pip install cmake` on many systems. Add `--user` if you have to (modern pip does this for you if needed). This does not supply Universal2 wheels yet.
### CI ### CI
| Distribution | CMake version | Notes | | Distribution | CMake version | Notes |
|---------------|---------------|-------| | ------------------------------------------------------------------------------------------------------------------------------------ | ------------- | ------------------------------------------------------------ |
| [TravisCI Xenial](https://docs.travis-ci.com/user/reference/xenial/#compilers-and-build-toolchain) | 3.12.4 | Mid November 2018 this image became ready for widescale use. | | [TravisCI Xenial](https://docs.travis-ci.com/user/reference/xenial/#compilers-and-build-toolchain) | 3.12.4 | Mid November 2018 this image became ready for widescale use. |
| [TravisCI Bionic](https://docs.travis-ci.com/user/reference/bionic/#compilers-and-build-toolchain) | 3.12.4 | Same as Xenial at the moment. | | [TravisCI Bionic](https://docs.travis-ci.com/user/reference/bionic/#compilers-and-build-toolchain) | 3.12.4 | Same as Xenial at the moment. |
| [Azure DevOps](https://docs.microsoft.com/en-us/azure/devops/pipelines/agents/hosted?view=azure-devops#use-a-microsoft-hosted-agent) | 3.23.3 | kept up to date | | [Azure DevOps](https://docs.microsoft.com/en-us/azure/devops/pipelines/agents/hosted?view=azure-devops#use-a-microsoft-hosted-agent) | 3.23.3 | kept up to date |
| [GitHub Actions 20.04](https://github.com/actions/virtual-environments/blob/main/images/linux/Ubuntu2004-Readme.md) | 3.23.3 | Same runners as Azure DevOps | | [GitHub Actions 20.04](https://github.com/actions/virtual-environments/blob/main/images/linux/Ubuntu2004-Readme.md) | 3.23.3 | Same runners as Azure DevOps |
If you are using GitHub Actions, also see the [jwlawson/actions-setup-cmake](https://github.com/marketplace/actions/actions-setup-cmake) action, which can install your selection of CMake, even in a docker action run. If you are using GitHub Actions, also see the [jwlawson/actions-setup-cmake](https://github.com/marketplace/actions/actions-setup-cmake) action, which can install your selection of CMake, even in a docker action run.
@ -145,12 +143,11 @@ Versions less than 3.10 are marked by a deeper color of red.
[![Full listing](https://repology.org/badge/vertical-allrepos/cmake.svg?columns=3&minversion=3.10.0)][repology] [![Full listing](https://repology.org/badge/vertical-allrepos/cmake.svg?columns=3&minversion=3.10.0)][repology]
Also see [pkgs.org/download/cmake](https://pkgs.org/download/cmake). Also see [pkgs.org/download/cmake](https://pkgs.org/download/cmake).
## Pip ## Pip
[This][PyPI] is also provided as an official package, maintained by the authors of CMake at KitWare and several PyPA members, including myself. It's now supported on special architectures, like PowerPC on Linux and Apple Silicon on macOS, and on MUSL systems like Alpine too. If you have pip (Python's package installer), you can do: [This][pypi] is also provided as an official package, maintained by the authors of CMake at KitWare and several PyPA members, including myself. It's now supported on special architectures, like PowerPC on Linux and Apple Silicon on macOS, and on MUSL systems like Alpine too. If you have pip (Python's package installer), you can do:
```term ```term
gitbook $ pip install cmake gitbook $ pip install cmake
@ -170,19 +167,19 @@ Personally, on Linux, I put versions of CMake in folders, like `/opt/cmake312` o
[^1]: I assume this is obvious, but you are downloading and running code, which exposes you to a man in the middle attack. If you are in a critical environment, you should download the file and check the checksum. (And, no, simply doing this in two steps does not make you any safer, only a checksum is safer). [^1]: I assume this is obvious, but you are downloading and running code, which exposes you to a man in the middle attack. If you are in a critical environment, you should download the file and check the checksum. (And, no, simply doing this in two steps does not make you any safer, only a checksum is safer).
[^2]: If you don't have a `.local` in your home directory, it's easy to start. Just make the folder, then add `export PATH="$HOME/.local/bin:$PATH"` to your `.bashrc` or `.bash_profile` or `.profile` file in your home directory. Now you can install any packages you build to `-DCMAKE_INSTALL_PREFIX=~/.local` instead of `/usr/local`! [^2]: If you don't have a `.local` in your home directory, it's easy to start. Just make the folder, then add `export PATH="$HOME/.local/bin:$PATH"` to your `.bashrc` or `.bash_profile` or `.profile` file in your home directory. Now you can install any packages you build to `-DCMAKE_INSTALL_PREFIX=~/.local` instead of `/usr/local`!
[repology]: https://repology.org/project/cmake/versions [repology]: https://repology.org/project/cmake/versions
[LMod]: http://lmod.readthedocs.io/en/latest/ [lmod]: http://lmod.readthedocs.io/en/latest/
[apt]: https://apt.kitware.com/ [apt]: https://apt.kitware.com/
[snap]: https://snapcraft.io/cmake [snap]: https://snapcraft.io/cmake
[PyPI]: https://pypi.org/project/cmake/ [pypi]: https://pypi.org/project/cmake/
[winget]: https://github.com/microsoft/winget-pkgs/tree/master/manifests/k/Kitware/CMake [winget]: https://github.com/microsoft/winget-pkgs/tree/master/manifests/k/Kitware/CMake
[chocolatey]: https://chocolatey.org/packages/cmake [chocolatey]: https://chocolatey.org/packages/cmake
[scoop]: https://github.com/ScoopInstaller/Main/blob/master/bucket/cmake.json [scoop]: https://github.com/ScoopInstaller/Main/blob/master/bucket/cmake.json
[MSYS2]: https://packages.msys2.org/base/mingw-w64-cmake [msys2]: https://packages.msys2.org/base/mingw-w64-cmake
[anaconda]: https://anaconda.org/anaconda/cmake [anaconda]: https://anaconda.org/anaconda/cmake
[conda-forge]: https://github.com/conda-forge/cmake-feedstock [conda-forge]: https://github.com/conda-forge/cmake-feedstock
[download]: https://cmake.org/download/ [download]: https://cmake.org/download/
[homebrew]: https://formulae.brew.sh/formula/cmake [homebrew]: https://formulae.brew.sh/formula/cmake
[homebrew-cask]: https://formulae.brew.sh/cask/cmake [homebrew-cask]: https://formulae.brew.sh/cask/cmake
[macports]: https://ports.macports.org/port/cmake/summary [macports]: https://ports.macports.org/port/cmake/summary
[centos]: https://rpms.remirepo.net/rpmphp/zoom.php?rpm=cmake [centos]: https://rpms.remirepo.net/rpmphp/zoom.php?rpm=cmake

View File

@ -1,156 +1,152 @@
# What's new in in CMake # What's new in in CMake
This is an abbreviated version of the CMake changelog with just the highlights for authors. Names for each release are arbitrarily picked by the author. This is an abbreviated version of the CMake changelog with just the highlights for authors. Names for each release are arbitrarily picked by the author.
## [CMake 3.0][] : Interface libraries ## [CMake 3.0][] : Interface libraries
There were a ton of additions to this version of CMake, primarily to fill out the target interface. Some bits of needed functionality were missed and implemented in CMake 3.1 instead. There were a ton of additions to this version of CMake, primarily to fill out the target interface. Some bits of needed functionality were missed and implemented in CMake 3.1 instead.
* Initially released [June 10, 2014](https://blog.kitware.com/cmake-3-0-0-available-for-download/) - Initially released [June 10, 2014](https://blog.kitware.com/cmake-3-0-0-available-for-download/)
* New documentation - New documentation
* INTERFACE libraries - INTERFACE libraries
* Project VERSION support - Project VERSION support
* Exporting build trees easily - Exporting build trees easily
* Bracket arguments and comments available (not widely used) - Bracket arguments and comments available (not widely used)
* Lots of improvements - Lots of improvements
## [CMake 3.1][] : C++11 and compile features ## [CMake 3.1][] : C++11 and compile features
This is the first release of CMake to support C++11. Combined with fixes to the new features of CMake 3.0, this is currently a common minimum version of CMake for libraries that want to support old CMake builds. This is the first release of CMake to support C++11. Combined with fixes to the new features of CMake 3.0, this is currently a common minimum version of CMake for libraries that want to support old CMake builds.
* Initially released [December 17, 2014](https://blog.kitware.com/cmake-3-1-0-released/) - Initially released [December 17, 2014](https://blog.kitware.com/cmake-3-1-0-released/)
* C++11 Support - C++11 Support
* Compile features support - Compile features support
* Sources can be added later with `target_sources` - Sources can be added later with `target_sources`
* Better support for generator expressions and INTERFACE targets - Better support for generator expressions and INTERFACE targets
## [CMake 3.2][] : UTF8 ## [CMake 3.2][] : UTF8
This is a smaller release, with mostly small features and fixes. Internal changes, like better Windows and UTF8 support, were the focus. This is a smaller release, with mostly small features and fixes. Internal changes, like better Windows and UTF8 support, were the focus.
* Initially released [March 11, 2015](https://blog.kitware.com/cmake-3-2-1-released/) - Initially released [March 11, 2015](https://blog.kitware.com/cmake-3-2-1-released/)
* `continue()` inside loops - `continue()` inside loops
* File and directory locks added - File and directory locks added
## [CMake 3.3][] : if IN_LIST ## [CMake 3.3][] : if IN_LIST
This is notable for the useful `IN_LIST` option for if, but it also added better library search using `$PATH` (See CMake 3.6), dependencies for INTERFACE libraries, and several other useful improvements. The addition of a `COMPILE_LANGUAGE` generator expression would prove very useful in the future as more languages are added. Makefiles now produce better output in parallel. This is notable for the useful `IN_LIST` option for if, but it also added better library search using `$PATH` (See CMake 3.6), dependencies for INTERFACE libraries, and several other useful improvements. The addition of a `COMPILE_LANGUAGE` generator expression would prove very useful in the future as more languages are added. Makefiles now produce better output in parallel.
* Initially released [July 23, 2015](https://blog.kitware.com/cmake-3-3-0-released/) - Initially released [July 23, 2015](https://blog.kitware.com/cmake-3-3-0-released/)
* `IN_LIST` added to `if` - `IN_LIST` added to `if`
* `*_INCLUDE_WHAT_YOU_USE` property added - `*_INCLUDE_WHAT_YOU_USE` property added
* `COMPILE_LANGUAGE` generator expression (limited support in some generators) - `COMPILE_LANGUAGE` generator expression (limited support in some generators)
## [CMake 3.4][] : Swift & CCache ## [CMake 3.4][] : Swift & CCache
This release adds lots of useful tools, support for the Swift language, and the usual improvements. It also started supporting compiler launchers, like CCache. This release adds lots of useful tools, support for the Swift language, and the usual improvements. It also started supporting compiler launchers, like CCache.
* Initially released [November 12, 2015](https://blog.kitware.com/cmake-3-4-0-released/) - Initially released [November 12, 2015](https://blog.kitware.com/cmake-3-4-0-released/)
* Added `Swift` language - Added `Swift` language
* Added `BASE_DIR` to `get_filename_component` - Added `BASE_DIR` to `get_filename_component`
* `if(TEST ...)` added - `if(TEST ...)` added
* `string(APPEND ...)` added - `string(APPEND ...)` added
* `CMAKE_*_COMPILER_LAUNCHER` added for make and ninja - `CMAKE_*_COMPILER_LAUNCHER` added for make and ninja
* `TARGET_MESSAGES` allow makefiles to print messages after target is completed - `TARGET_MESSAGES` allow makefiles to print messages after target is completed
* Imported targets are beginning to show up in the official `Find*.cmake` files - Imported targets are beginning to show up in the official `Find*.cmake` files
## [CMake 3.5][] : ARM ## [CMake 3.5][] : ARM
This release expanded CMake to more platforms, and make warnings easier to control from the command line. This release expanded CMake to more platforms, and make warnings easier to control from the command line.
* Initially released [March 8, 2016](https://blog.kitware.com/cmake-3-5-0-available-for-download/) - Initially released [March 8, 2016](https://blog.kitware.com/cmake-3-5-0-available-for-download/)
* Multiple input files supported for several of the `cmake -E` commands. - Multiple input files supported for several of the `cmake -E` commands.
* `cmake_parse_arguments` now builtin - `cmake_parse_arguments` now builtin
* Boost, GTest, and more now support imported targets - Boost, GTest, and more now support imported targets
* ARMCC now supported, better support for iOS - ARMCC now supported, better support for iOS
* XCode backslash fix - XCode backslash fix
## [CMake 3.6][] : Clang-Tidy ## [CMake 3.6][] : Clang-Tidy
This release added Clang-Tidy support, along with more utilities and improvements. It also removed the search of `$PATH` on Unix systems due to problems, instead users should use `$CMAKE_PREFIX_PATH`. This release added Clang-Tidy support, along with more utilities and improvements. It also removed the search of `$PATH` on Unix systems due to problems, instead users should use `$CMAKE_PREFIX_PATH`.
* Initially released [July 7, 2016](https://blog.kitware.com/cmake-3-6-0-available-for-download/) - Initially released [July 7, 2016](https://blog.kitware.com/cmake-3-6-0-available-for-download/)
* `EXCLUDE_FROM_ALL` for install - `EXCLUDE_FROM_ALL` for install
* `list(FILTER` added - `list(FILTER` added
* `CMAKE_*_STANDARD_INCLUDE_DIRECTORIES` and `CMAKE_*_STANDARD_LIBRARIES` added for toolchains - `CMAKE_*_STANDARD_INCLUDE_DIRECTORIES` and `CMAKE_*_STANDARD_LIBRARIES` added for toolchains
* Try-compile improvements - Try-compile improvements
* `*_CLANG_TIDY` property added - `*_CLANG_TIDY` property added
* External projects can now be shallow clones, and other improvements - External projects can now be shallow clones, and other improvements
## [CMake 3.7][] : Android & CMake Server ## [CMake 3.7][] : Android & CMake Server
You can now cross-compile to Android. Useful new if statement options really help clarify code. And the new server mode was supposed to improve integration with IDEs (but is being replaced by a different system in CMake 3.14+). Support for the VIM editor was also improved. You can now cross-compile to Android. Useful new if statement options really help clarify code. And the new server mode was supposed to improve integration with IDEs (but is being replaced by a different system in CMake 3.14+). Support for the VIM editor was also improved.
* Initially released [November 11, 2016](https://blog.kitware.com/cmake-3-7-0-available-for-download/) - Initially released [November 11, 2016](https://blog.kitware.com/cmake-3-7-0-available-for-download/)
* `PARSE_ARGV` mode for `cmake_parse_arguments` - `PARSE_ARGV` mode for `cmake_parse_arguments`
* Better 32-bit support on 64-bit machines - Better 32-bit support on 64-bit machines
* Lots of useful new if comparisons, like `VERSION_GREATER_EQUAL` (really, why did it take this long?) - Lots of useful new if comparisons, like `VERSION_GREATER_EQUAL` (really, why did it take this long?)
* `LINK_WHAT_YOU_USE` added - `LINK_WHAT_YOU_USE` added
* Lots of custom properties related to files and directories - Lots of custom properties related to files and directories
* CMake Server added - CMake Server added
* Added `--trace-source="filename"` to monitor certain files only - Added `--trace-source="filename"` to monitor certain files only
## [CMake 3.8][] : C# & CUDA ## [CMake 3.8][] : C# & CUDA
This adds CUDA as a language, as well as `cxx_std_11` as a compiler meta-feature. The new generator expression could be really useful if you can require CMake 3.8+! This adds CUDA as a language, as well as `cxx_std_11` as a compiler meta-feature. The new generator expression could be really useful if you can require CMake 3.8+!
* Initially released [April 10, 2017](https://blog.kitware.com/cmake-3-8-0-available-for-download/) - Initially released [April 10, 2017](https://blog.kitware.com/cmake-3-8-0-available-for-download/)
* Native support for C# as a language - Native support for C# as a language
* Native support for CUDA as a language - Native support for CUDA as a language
* Meta features cxx_std_11 (and 14, 17) added - Meta features cxx_std_11 (and 14, 17) added
* `try_compile` has better language support - `try_compile` has better language support
* `BUILD_RPATH` property added - `BUILD_RPATH` property added
* `COMPILE_FLAGS` now supports generator expression - `COMPILE_FLAGS` now supports generator expression
* `*_CPPLINT` added - `*_CPPLINT` added
* `$<IF:cond,true-value,false-value>` added (wow!) - `$<IF:cond,true-value,false-value>` added (wow!)
* `source_group(TREE` added (finally allowing IDEs to reflect the project folder structure!) - `source_group(TREE` added (finally allowing IDEs to reflect the project folder structure!)
## [CMake 3.9][] : IPO ## [CMake 3.9][] : IPO
Lots of fixes to CUDA support went into this release, including `PTX` support and MSVC generators. Interprocedural Optimizations are now supported properly. Lots of fixes to CUDA support went into this release, including `PTX` support and MSVC generators. Interprocedural Optimizations are now supported properly.
Even more modules provide imported targets, including MPI. Even more modules provide imported targets, including MPI.
* Initially released [July 18, 2017](https://blog.kitware.com/cmake-3-9-0-available-for-download/) - Initially released [July 18, 2017](https://blog.kitware.com/cmake-3-9-0-available-for-download/)
* CUDA supported for Windows - CUDA supported for Windows
* Better object library support in several situations - Better object library support in several situations
* `DESCRIPTION` added to `project` - `DESCRIPTION` added to `project`
* `separate_arguments` gets `NATIVE_COMMAND` - `separate_arguments` gets `NATIVE_COMMAND`
* `INTERPROCEDURAL_OPTIMIZATION` enforced (and `CMAKE_*` initializer added, CheckIPOSupported added, Clang and GCC support) - `INTERPROCEDURAL_OPTIMIZATION` enforced (and `CMAKE_*` initializer added, CheckIPOSupported added, Clang and GCC support)
* New `GoogleTest` module - New `GoogleTest` module
* `FindDoxygen` drastically improved - `FindDoxygen` drastically improved
## [CMake 3.10][] : CppCheck ## [CMake 3.10][] : CppCheck
CMake now is built with C++11 compilers. Lots of useful improvements help write cleaner code. CMake now is built with C++11 compilers. Lots of useful improvements help write cleaner code.
* Initially released [November 20, 2017](https://blog.kitware.com/cmake-3-10-0-available-for-download/) - Initially released [November 20, 2017](https://blog.kitware.com/cmake-3-10-0-available-for-download/)
* Support for flang Fortran compiler - Support for flang Fortran compiler
* Compiler launcher added to CUDA - Compiler launcher added to CUDA
* Indented `#cmakedefines` now supported for `configure_file` - Indented `#cmakedefines` now supported for `configure_file`
* `include_guard()` added to ensure a file gets included only once - `include_guard()` added to ensure a file gets included only once
* `string(PREPEND` added - `string(PREPEND` added
* `*_CPPCHECK` property added - `*_CPPCHECK` property added
* `LABELS` added to directories - `LABELS` added to directories
* FindMPI vastly expanded - FindMPI vastly expanded
* FindOpenMP improved - FindOpenMP improved
* Dynamic test discovery for `GoogleTest` - Dynamic test discovery for `GoogleTest`
* `cmake_host_system_information` can access much more information. - `cmake_host_system_information` can access much more information.
## [CMake 3.11][] : Faster & IMPORTED INTERFACE ## [CMake 3.11][] : Faster & IMPORTED INTERFACE
This release is [supposed to be][fastercmake] much faster. You can also finally directly add INTERFACE targets This release is [supposed to be][fastercmake] much faster. You can also finally directly add INTERFACE targets
to IMPORTED libraries (the internal `Find*.cmake` scripts should become much cleaner eventually). to IMPORTED libraries (the internal `Find*.cmake` scripts should become much cleaner eventually).
* Initially released [March 28, 2018](https://blog.kitware.com/cmake-3-11-0-available-for-download/) - Initially released [March 28, 2018](https://blog.kitware.com/cmake-3-11-0-available-for-download/)
* Fortran supports compiler launchers - Fortran supports compiler launchers
* Xcode and Visual Studio support `COMPILE_LANGUAGE` generator expressions finally - Xcode and Visual Studio support `COMPILE_LANGUAGE` generator expressions finally
* You can now add INTERFACE targets directly to IMPORTED INTERFACE libraries (Wow!) - You can now add INTERFACE targets directly to IMPORTED INTERFACE libraries (Wow!)
* Source file properties have been expanded - Source file properties have been expanded
* `FetchContent` module now allows downloads to happen at configure time (Wow) - `FetchContent` module now allows downloads to happen at configure time (Wow)
## [CMake 3.12][] : Version ranges and CONFIGURE_DEPENDS ## [CMake 3.12][] : Version ranges and CONFIGURE_DEPENDS
@ -162,66 +158,66 @@ rerun if needed! You can use the general `PackageName_ROOT`
for all `find_package` searches. Lots of additions to strings and lists, module updates, for all `find_package` searches. Lots of additions to strings and lists, module updates,
shiny new Python find module (2 and 3 versions too), and many more. shiny new Python find module (2 and 3 versions too), and many more.
* Initially released [July 17, 2018](https://blog.kitware.com/cmake-3-12-0-available-for-download/) - Initially released [July 17, 2018](https://blog.kitware.com/cmake-3-12-0-available-for-download/)
* Support for `cmake_minimum_required` ranges (backward compatible) - Support for `cmake_minimum_required` ranges (backward compatible)
* Support for `-j,--parallel` in `--build` mode (passed on to build tool) - Support for `-j,--parallel` in `--build` mode (passed on to build tool)
* Support for `SHELL:` strings in compile options (not deduplicated) - Support for `SHELL:` strings in compile options (not deduplicated)
* New FindPython module - New FindPython module
* `string(JOIN` and `list(JOIN`, and `list(TRANSFORM` - `string(JOIN` and `list(JOIN`, and `list(TRANSFORM`
* `file(TOUCH` and `file(GLOB CONFIGURE_DEPENDS` - `file(TOUCH` and `file(GLOB CONFIGURE_DEPENDS`
* C++20 support - C++20 support
* CUDA as a language improvements: CUDA 7 and 7.5 now supported - CUDA as a language improvements: CUDA 7 and 7.5 now supported
* Support for OpenMP on macOS (command line only) - Support for OpenMP on macOS (command line only)
* Several new properties and property initializers - Several new properties and property initializers
* CPack finally reads `CMAKE_PROJECT_VERSION` variables - CPack finally reads `CMAKE_PROJECT_VERSION` variables
## [CMake 3.13][] : Linking control ## [CMake 3.13][] : Linking control
You can now make symbolic links on Windows! Lots of new functions that fill out the You can now make symbolic links on Windows! Lots of new functions that fill out the
popular requests for CMake, such as `add_link_options`, `target_link_directories`, and popular requests for CMake, such as `add_link_options`, `target_link_directories`, and
`target_link_options`. You can now do quite a bit more modification to targets outside `target_link_options`. You can now do quite a bit more modification to targets outside
of the source directory, for better file separation. And, `target_sources` *finally* handles relative paths properly (policy 76). of the source directory, for better file separation. And, `target_sources` _finally_ handles relative paths properly (policy 76).
* Initially released [November 20, 2018](https://blog.kitware.com/cmake-3-13-0-available-for-download/) - Initially released [November 20, 2018](https://blog.kitware.com/cmake-3-13-0-available-for-download/)
* New `ctest --progress` option for live output - New `ctest --progress` option for live output
* `target_link_options` and `add_link_options` added - `target_link_options` and `add_link_options` added
* `target_link_directories` added - `target_link_directories` added
* Symbolic link creation, `-E create_symlink`, supported on Windows - Symbolic link creation, `-E create_symlink`, supported on Windows
* IPO supported on Windows - IPO supported on Windows
* You can use `-S` and `-B` for source and build directories - You can use `-S` and `-B` for source and build directories
* `target_link_libraries` and `install` work outside the current target directory - `target_link_libraries` and `install` work outside the current target directory
* `STATIC_LIBRARY_OPTIONS` property added - `STATIC_LIBRARY_OPTIONS` property added
* `target_sources` is now relative to the current source directory (CMP0076) - `target_sources` is now relative to the current source directory (CMP0076)
* If you use Xcode, you now can experimentally set schema fields - If you use Xcode, you now can experimentally set schema fields
## [CMake 3.14][] : File utilities (AKA [CMake π](https://blog.kitware.com/kitware-gets-mathematical-with-cmake-π-on-pi-day/)) ## [CMake 3.14][] : File utilities (AKA [CMake π](https://blog.kitware.com/kitware-gets-mathematical-with-cmake-π-on-pi-day/))
This release has lots of small cleanups, including several utilities for files. Generator expressions work in a few more places, and list handling is better with empty variables. This release has lots of small cleanups, including several utilities for files. Generator expressions work in a few more places, and list handling is better with empty variables.
Quite a few more find packages produce targets. The new Visual Studio 16 2019 generator is a bit different than older versions. Windows XP and Vista support has been dropped. Quite a few more find packages produce targets. The new Visual Studio 16 2019 generator is a bit different than older versions. Windows XP and Vista support has been dropped.
* Initially released [March 14, 2019](https://blog.kitware.com/cmake-3-14-0-available-for-download/) - Initially released [March 14, 2019](https://blog.kitware.com/cmake-3-14-0-available-for-download/)
* The cmake `--build` command gained `-v/--verbose`, to use verbose builds if your build tool supports it - The cmake `--build` command gained `-v/--verbose`, to use verbose builds if your build tool supports it
* The FILE command gained `CREATE_LINK`, `READ_SYMLINK`, and `SIZE` - The FILE command gained `CREATE_LINK`, `READ_SYMLINK`, and `SIZE`
* «command:get_filename_component» gained `LAST_EXT` and `NAME_WLE` to access just the *last* extension on a file, which would get `.zip` on a file such as `version.1.2.zip` (very handy!) - «command:get*filename_component» gained `LAST_EXT` and `NAME_WLE` to access just the \_last* extension on a file, which would get `.zip` on a file such as `version.1.2.zip` (very handy!)
* You can see if a variable is defined in the CACHE with `DEFINED CACHE{VAR}` in an «command:if» statement. - You can see if a variable is defined in the CACHE with `DEFINED CACHE{VAR}` in an «command:if» statement.
* `BUILD_RPATH_USE_ORIGIN` and CMake version were added to improve handling of RPath in the build directory. - `BUILD_RPATH_USE_ORIGIN` and CMake version were added to improve handling of RPath in the build directory.
* The CMake server mode is now being replaced with a file API, starting in this release. Will affect IDEs in the long run. - The CMake server mode is now being replaced with a file API, starting in this release. Will affect IDEs in the long run.
## [CMake 3.15][] : CLI upgrade ## [CMake 3.15][] : CLI upgrade
This release has many smaller polishing changes, include several of improvements to the CMake command line, such as control over the default generator through environment variables (so now it's easy to change the default generator to Ninja). Multiple targets are supported in `--build` mode, and `--install` mode added. CMake finally supports multiple levels of logging. Generator expressions gained a few handy tools. The still very new FindPython module continues to improve, and FindBoost is now more inline with Boost 1.70's new CONFIG This release has many smaller polishing changes, include several of improvements to the CMake command line, such as control over the default generator through environment variables (so now it's easy to change the default generator to Ninja). Multiple targets are supported in `--build` mode, and `--install` mode added. CMake finally supports multiple levels of logging. Generator expressions gained a few handy tools. The still very new FindPython module continues to improve, and FindBoost is now more inline with Boost 1.70's new CONFIG
module. `export(PACKAGE)` has drastically changed; it now no longer touches `$HOME/.cmake` by default (if CMake Minimum version is 3.15 or higher), and requires an extra step if a user wants to use it. This is generally less surprising. module. `export(PACKAGE)` has drastically changed; it now no longer touches `$HOME/.cmake` by default (if CMake Minimum version is 3.15 or higher), and requires an extra step if a user wants to use it. This is generally less surprising.
* Initially released [July 17, 2019](https://blog.kitware.com/cmake-3-15-0-available-for-download/) - Initially released [July 17, 2019](https://blog.kitware.com/cmake-3-15-0-available-for-download/)
* «envvar:CMAKE_GENERATOR» environment variable added to control default generator - «envvar:CMAKE_GENERATOR» environment variable added to control default generator
* Multiple target support in build mode, `cmake . --build --target a b` - Multiple target support in build mode, `cmake . --build --target a b`
* Shortcut `-t` for `--target` - Shortcut `-t` for `--target`
* Install support, `cmake . --install`, does not invoke the build system - Install support, `cmake . --install`, does not invoke the build system
* Support for `--loglevel` and `NOTICE`, `VERBOSE`, `DEBUG`, and `TRACE` for `message` - Support for `--loglevel` and `NOTICE`, `VERBOSE`, `DEBUG`, and `TRACE` for `message`
* The «command:list» command gained `PREPEND`, `POP_FRONT`, and `POP_BACK` - The «command:list» command gained `PREPEND`, `POP_FRONT`, and `POP_BACK`
* «command:execute_process» gained `COMMAND_ECHO` option («variable:CMAKE_EXECUTE_PROCESS_COMMAND_ECHO») allows you to automatically echo commands before running them - «command:execute_process» gained `COMMAND_ECHO` option («variable:CMAKE_EXECUTE_PROCESS_COMMAND_ECHO») allows you to automatically echo commands before running them
* Several Ninja improvements, include SWIFT language support - Several Ninja improvements, include SWIFT language support
* Compiler and list improvements to generator expressions - Compiler and list improvements to generator expressions
## [CMake 3.16][] : Unity builds ## [CMake 3.16][] : Unity builds
@ -229,14 +225,14 @@ A new unity build mode was added, allowing source files to be merged into a sing
precompiled headers (possibly preparing for C++20 modules, perhaps?) was added. Lots of other smaller precompiled headers (possibly preparing for C++20 modules, perhaps?) was added. Lots of other smaller
fixes were implemented, especially to newer features, such as to FindPython, FindDoxygen, and others. fixes were implemented, especially to newer features, such as to FindPython, FindDoxygen, and others.
* Initially released [November 26, 2019](https://blog.kitware.com/cmake-3-16-0-available-for-download/) - Initially released [November 26, 2019](https://blog.kitware.com/cmake-3-16-0-available-for-download/)
* Added support for Objective C and Objective C++ languages - Added support for Objective C and Objective C++ languages
* Support for precompiling headers, with `target_precompile_headers` - Support for precompiling headers, with `target_precompile_headers`
* Support for "Unity" or "Jumbo" builds (merging source files) with «variable:CMAKE_UNITY_BUILD» - Support for "Unity" or "Jumbo" builds (merging source files) with «variable:CMAKE_UNITY_BUILD»
* CTest: Can now skip based on regex, expand lists - CTest: Can now skip based on regex, expand lists
* Several new features to control RPath. - Several new features to control RPath.
* Generator expressions work in more places, like build and install paths - Generator expressions work in more places, like build and install paths
* Find locations can now be explicitly controlled through new variables - Find locations can now be explicitly controlled through new variables
## [CMake 3.17][] : More CUDA ## [CMake 3.17][] : More CUDA
@ -245,18 +241,18 @@ toolkit without enabling the CUDA language! CUDA now is a bit more configurable,
such as linking to shared libraries. Quite a bit more polish in the expected areas, such as linking to shared libraries. Quite a bit more polish in the expected areas,
as well, like FindPython. Finally, you can now iterate over multiple lists at a time. as well, like FindPython. Finally, you can now iterate over multiple lists at a time.
* Initially released [March 20, 2020](https://blog.kitware.com/cmake-3-17-0-available-for-download/) - Initially released [March 20, 2020](https://blog.kitware.com/cmake-3-17-0-available-for-download/)
* `CUDA_RUNTIME_LIBRARY` can finally be set to Shared! - `CUDA_RUNTIME_LIBRARY` can finally be set to Shared!
* FindCUDAToolkit finally added - FindCUDAToolkit finally added
* `cmake -E rm` replaces older remove commands - `cmake -E rm` replaces older remove commands
* CUDA has meta features like `cuda_std_03`, etc. - CUDA has meta features like `cuda_std_03`, etc.
* You can track the searches for packages with `--debug-find` - You can track the searches for packages with `--debug-find`
* ExternalProject can now disable recursive checkouts - ExternalProject can now disable recursive checkouts
* FindPython better integration with Conda - FindPython better integration with Conda
* DEPRECATION can be applied to targets - DEPRECATION can be applied to targets
* CMake gained a rm command - CMake gained a rm command
* Several new environment variables - Several new environment variables
* foreach can now do `ZIP_LISTS` (multiple lists at a time) - foreach can now do `ZIP_LISTS` (multiple lists at a time)
## [CMake 3.18][] : CUDA with Clang & CMake macro language ## [CMake 3.18][] : CUDA with Clang & CMake macro language
@ -268,44 +264,43 @@ designs available; calling functions by variable, evaluating arbitrary CMake by
string, and configure files directly from strings. Many other nice tiny string, and configure files directly from strings. Many other nice tiny
features and papercut fixes are sprinkled throughout, a small selection is below. features and papercut fixes are sprinkled throughout, a small selection is below.
* Initially released [July 15, 2020](https://blog.kitware.com/cmake-3-18-0-available-for-download/) - Initially released [July 15, 2020](https://blog.kitware.com/cmake-3-18-0-available-for-download/)
* `cmake` can `cat` files together now - `cmake` can `cat` files together now
* New profiling mode for `cmake` - New profiling mode for `cmake`
* `cmake_language` with `CALL` and `EVAL` - `cmake_language` with `CALL` and `EVAL`
* `export` requires `APPEND` if used multiple times (in CMake language level 3.18+) - `export` requires `APPEND` if used multiple times (in CMake language level 3.18+)
* You can archive directly from `file()` - You can archive directly from `file()`
* `file(CONFIGURE` is a nicer from of `configure_file` if you already have a string to produce - `file(CONFIGURE` is a nicer from of `configure_file` if you already have a string to produce
* Other `find_*` commands gain `find_package`'s `REQUIRED` flag - Other `find_*` commands gain `find_package`'s `REQUIRED` flag
* `NATURAL` sorting in `list(SORT` added - `NATURAL` sorting in `list(SORT` added
* More options for handling properties with DIRECTORY scope - More options for handling properties with DIRECTORY scope
* `CUDA_ARCHITECTURES` was added - `CUDA_ARCHITECTURES` was added
* New `LINK_LANGUAGE` generator expressions (`DEVICE`/`HOST` versions too) - New `LINK_LANGUAGE` generator expressions (`DEVICE`/`HOST` versions too)
* Source can be a subdirectory for `FetchContent` - Source can be a subdirectory for `FetchContent`
## [CMake 3.19][] : Presets ## [CMake 3.19][] : Presets
You can now add presets in JSON form, and users will get the preset default. You can now add presets in JSON form, and users will get the preset default.
`find_package` can now take a version range, and some specialty find modules, `find_package` can now take a version range, and some specialty find modules,
like FindPython, have custom support for it. A lot of new controls were added like FindPython, have custom support for it. A lot of new controls were added
for permissions. Further support for generator expressions in more places. for permissions. Further support for generator expressions in more places.
* Initially released [November 18, 2020](https://blog.kitware.com/cmake-3-19-0-available-for-download/) - Initially released [November 18, 2020](https://blog.kitware.com/cmake-3-19-0-available-for-download/)
* New [CMake presets files](https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html) now supported - you can set defaults for your project per generator, or you can make User presets. PSA: Please add `CMakeUserPresets.json` to your `.gitignore`, even if you do not use `CMakePresets.json`. - New [CMake presets files](https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html) now supported - you can set defaults for your project per generator, or you can make User presets. PSA: Please add `CMakeUserPresets.json` to your `.gitignore`, even if you do not use `CMakePresets.json`.
* CMake now uses the new build system introduced in XCode 12+ - CMake now uses the new build system introduced in XCode 12+
* MSVC for Android now supported - MSVC for Android now supported
* `cmake -E create_hardlink` was added - `cmake -E create_hardlink` was added
* `add_test` finally properly supports whitespace in test names - `add_test` finally properly supports whitespace in test names
* You can now `DEFER` `cmake_language` to run at the end of the directory processing - You can now `DEFER` `cmake_language` to run at the end of the directory processing
* Lots of new `file` options, like temporary downloads and `COMPRESSION_LEVEL` for `ARCHIVE_CREATE` - Lots of new `file` options, like temporary downloads and `COMPRESSION_LEVEL` for `ARCHIVE_CREATE`
* `find_package` supports a version range - `find_package` supports a version range
* `DIRECTORY` can now include a binary directory in property commands - `DIRECTORY` can now include a binary directory in property commands
* New `JSON` commands for `string` - New `JSON` commands for `string`
* New `OPTIMIZE_DEPENDENCIES` property and `CMAKE_*` variable for smartly dropping dependencies of static and object libraries. - New `OPTIMIZE_DEPENDENCIES` property and `CMAKE_*` variable for smartly dropping dependencies of static and object libraries.
* PCH support expanded with `PCH_INSTANTIATE_TEMPLATES` property and `CMAKE_*` variable. - PCH support expanded with `PCH_INSTANTIATE_TEMPLATES` property and `CMAKE_*` variable.
* Check modules have been expanded with `CUDA` and `ISPC` languages - Check modules have been expanded with `CUDA` and `ISPC` languages
* FindPython: `Python*_LINK_OPTIONS` added - FindPython: `Python*_LINK_OPTIONS` added
* `compute-sanitizer` for ctest now supports CUDA for memcheck - `compute-sanitizer` for ctest now supports CUDA for memcheck
## [CMake 3.20][] : Docs ## [CMake 3.20][] : Docs
@ -316,17 +311,16 @@ LANGUAGE is always respected. Quite a bit of cleanup was done; make sure your
code is tested with `...3.20` before deploying that as your maximum. Presets code is tested with `...3.20` before deploying that as your maximum. Presets
continue to be improved. continue to be improved.
* Initially released [March 23, 2021](https://blog.kitware.com/cmake-3-20-0-available-for-download/) - Initially released [March 23, 2021](https://blog.kitware.com/cmake-3-20-0-available-for-download/)
* Support added for C++23 - Support added for C++23
* CUDAARCHS environment variable for setting CUDA architectures - CUDAARCHS environment variable for setting CUDA architectures
* The new `IntelLLVM` compilers are now supported (OneAPI 2021.1), and `NVHPC` NVIDIA HPC SDK, as well - The new `IntelLLVM` compilers are now supported (OneAPI 2021.1), and `NVHPC` NVIDIA HPC SDK, as well
* Some expanded generator expression support in custom commands/targets, install renaming - Some expanded generator expression support in custom commands/targets, install renaming
* New `cmake_path` command for working with paths - New `cmake_path` command for working with paths
* `try_run` now has a `WORKING_DIRECTORY` - `try_run` now has a `WORKING_DIRECTORY`
* More features for the `file(GENERATE` command - More features for the `file(GENERATE` command
* Several removals, like `cmake-server`, `WriteCompilerDetectionHeader` (if policy set to 3.20+), and a few things that have newer methods now. - Several removals, like `cmake-server`, `WriteCompilerDetectionHeader` (if policy set to 3.20+), and a few things that have newer methods now.
* Source files must include the extension - Source files must include the extension
## [CMake 3.21][] : Colors ## [CMake 3.21][] : Colors
@ -335,65 +329,63 @@ to see if you are in the top level project. Lots of continued cleanup and
specialized new features, such as adding the HIP language and C17 and C23 specialized new features, such as adding the HIP language and C17 and C23
support. Presets continue to be improved. support. Presets continue to be improved.
* Initially released [July 14, 2021](https://blog.kitware.com/cmake-3-21-0-available-for-download/) - Initially released [July 14, 2021](https://blog.kitware.com/cmake-3-21-0-available-for-download/)
* Preliminary support for MSVC 2022 - Preliminary support for MSVC 2022
* `CMAKE_<LANG>_LINKER_LAUNCHER` added for make and ninja - `CMAKE_<LANG>_LINKER_LAUNCHER` added for make and ninja
* HIP added as a language - HIP added as a language
* C17 and C23 support added - C17 and C23 support added
* `--instal-prefix <dir>` and `--toolchain <file>` added when running CMake - `--instal-prefix <dir>` and `--toolchain <file>` added when running CMake
* Messages printed are colored by message type! - Messages printed are colored by message type!
* Support for MSYS, including `FindMsys` - Support for MSYS, including `FindMsys`
* The `file(` command got several updates, including `EXPAND_TILDE` - The `file(` command got several updates, including `EXPAND_TILDE`
* Support for runtime dependencies and artifacts added to `install` - Support for runtime dependencies and artifacts added to `install`
* `PROJECT_IS_TOP_LEVEL` and `<PROJECT-NAME>_IS_TOP_LEVEL` finally added - `PROJECT_IS_TOP_LEVEL` and `<PROJECT-NAME>_IS_TOP_LEVEL` finally added
* Caching improvements for the `find_` commands - Caching improvements for the `find_` commands
## [CMake 3.22][]: Handy env vars ## [CMake 3.22][]: Handy env vars
A smaller release with some nice improvements all around focused on supporting A smaller release with some nice improvements all around focused on supporting
common build situations. You can finally set `CMAKE_BUILD_TYPE` in your common build situations. You can finally set `CMAKE_BUILD_TYPE` in your
environment to set a default build type. There are several other new env vars environment to set a default build type. There are several other new env vars
and variables too. Compiler flags related to standards have been improved. and variables too. Compiler flags related to standards have been improved.
`cmake_host_system_information` got improved further (from 3.10) with OS `cmake_host_system_information` got improved further (from 3.10) with OS
information. information.
- Initially released [November 18, 2021](https://blog.kitware.com/cmake-3-22-0-available-for-download/)
* Initially released [November 18, 2021](https://blog.kitware.com/cmake-3-22-0-available-for-download/) - New environment variables for defaults, `CMAKE_BUILD_TYPE` and `CMAKE_CONFIGURATION_TYPES`
* New environment variables for defaults, `CMAKE_BUILD_TYPE` and `CMAKE_CONFIGURATION_TYPES` - New environment variable `CMAKE_INSTALL_MODE` for install types (symlinks)
* New environment variable `CMAKE_INSTALL_MODE` for install types (symlinks) - New `CMAKE_REQUIRE_FIND_PACKAGE_<PackageName>` variable to convert an optional find to a required one
* New `CMAKE_REQUIRE_FIND_PACKAGE_<PackageName>` variable to convert an optional find to a required one - `CMAKE_<LANG>_EXTENSIONS_DEFAULT` comes from the compiler
* `CMAKE_<LANG>_EXTENSIONS_DEFAULT` comes from the compiler - `CMakeDependentOption` uses normal conditional syntax now
* `CMakeDependentOption` uses normal conditional syntax now - CTest can now modify environment variables
* CTest can now modify environment variables - Some generators now use external (system) markers on includes for MSVC
* Some generators now use external (system) markers on includes for MSVC
## [CMake 3.23][]: Header only libraries ## [CMake 3.23][]: Header only libraries
A solid release focused on header only libraries, more user control, CMake A solid release focused on header only libraries, more user control, CMake
presets, and better CUDA support. There are some powerful new features for presets, and better CUDA support. There are some powerful new features for
header only libraries, like the various `*_SETS` target properties. There are header only libraries, like the various `*_SETS` target properties. There are
new controls like the ability to restrict paths for `find_` commands and the new controls like the ability to restrict paths for `find_` commands and the
ability to remove `SYSTEM` from an existing target. You also get expanded ability to remove `SYSTEM` from an existing target. You also get expanded
debugging features, and the ability to force all links to be to targets. debugging features, and the ability to force all links to be to targets.
Presets can include other files. CUDA and C# received new updates, and a Presets can include other files. CUDA and C# received new updates, and a
couple of compilers were added. couple of compilers were added.
* Initially released [March 29, 2022](https://blog.kitware.com/cmake-3-23-0-available-for-download/) - Initially released [March 29, 2022](https://blog.kitware.com/cmake-3-23-0-available-for-download/)
* CMake presets are a bit nicer, with the ability to include other files. - CMake presets are a bit nicer, with the ability to include other files.
* A couple of new supported compilers, and better C# support. - A couple of new supported compilers, and better C# support.
* `FILE_SET` for `install` and `target_sources` header-only source files. - `FILE_SET` for `install` and `target_sources` header-only source files.
* `<INTERFACE_>HEADER_SETS`, `<INTERFACE_>HEADER_DIRS` for target headers. - `<INTERFACE_>HEADER_SETS`, `<INTERFACE_>HEADER_DIRS` for target headers.
* `CUDA_ARCHITECTURES` support for all and all-major.a - `CUDA_ARCHITECTURES` support for all and all-major.a
* DEBUG messages from can be enabled for `find_*` or find modules. - DEBUG messages from can be enabled for `find_*` or find modules.
* `define_property()` has a handy `INITIALIZE_FROM_VARIABLE` option. - `define_property()` has a handy `INITIALIZE_FROM_VARIABLE` option.
* `CMAKE_<SYSTEM_>IGNORE_PREFIX_PATH` to control `find_*` commands. - `CMAKE_<SYSTEM_>IGNORE_PREFIX_PATH` to control `find_*` commands.
* `<CMAKE_>LINK_LIBRARIES_ONLY_TARGETS` added to force only targets linked - `<CMAKE_>LINK_LIBRARIES_ONLY_TARGETS` added to force only targets linked
(nice for finding mistakes!). (nice for finding mistakes!).
* `IMPORTED_NO_SYSTEM`, a new property to forcibly remove SYSTEM from a target. - `IMPORTED_NO_SYSTEM`, a new property to forcibly remove SYSTEM from a target.
* `FindGTest` now adds a `GMock` target if found. - `FindGTest` now adds a `GMock` target if found.
## [CMake 3.24][cmake master]: WIP
## [CMake 3.24][CMake master]: WIP
The next release is shaping up to be a fantastic release. Package writers are The next release is shaping up to be a fantastic release. Package writers are
getting integration between `find_package` and `FetchContent` that will allow getting integration between `find_package` and `FetchContent` that will allow
@ -402,44 +394,43 @@ warnings as errors can be set by a package and removed by packagers, as well
(still make sure not to do this unless you are being build as the main (still make sure not to do this unless you are being build as the main
project!). project!).
- `--fresh` option removes the old cache when running.
- `find_package` and `FetchContent` now have integration - you have options to download missing dependencies.
- `find_package` has a new `GLOBAL` option.
- `CMAKE_PROJECT_TOP_LEVEL_INCLUDES` allows a user (like packagers) to inject pre-project code.
- `PATH` management for generator expressions.
- `CMAKE_COLOR_DIAGNOSTICS` env var & variable added, replacing `CMAKE_COLOR_MAKEFILE`.
- You can disable `find_*` searching the install prefix.
- `COMPILE_WARNING_AS_ERROR` property and `CMAKE_` variable, and `--compile-no-warning-as-error` to disable it.
- CUDA supports `native` to compile for the current GPUs detected.
- `SYSTEM` includes now are respected on MSVC generators.
- Better support for MSVC, XCode, and others.
- `LLVMFlang` compiler support.
* `--fresh` option removes the old cache when running. [releases]: https://cmake.org/cmake/help/latest/release/index.html
* `find_package` and `FetchContent` now have integration - you have options to download missing dependencies. [cmake 3.0]: https://cmake.org/cmake/help/latest/release/3.0.html
* `find_package` has a new `GLOBAL` option. [cmake 3.1]: https://cmake.org/cmake/help/latest/release/3.1.html
* `CMAKE_PROJECT_TOP_LEVEL_INCLUDES` allows a user (like packagers) to inject pre-project code. [cmake 3.2]: https://cmake.org/cmake/help/latest/release/3.2.html
* `PATH` management for generator expressions. [cmake 3.3]: https://cmake.org/cmake/help/latest/release/3.3.html
* `CMAKE_COLOR_DIAGNOSTICS` env var & variable added, replacing `CMAKE_COLOR_MAKEFILE`. [cmake 3.4]: https://cmake.org/cmake/help/latest/release/3.4.html
* You can disable `find_*` searching the install prefix. [cmake 3.5]: https://cmake.org/cmake/help/latest/release/3.5.html
* `COMPILE_WARNING_AS_ERROR` property and `CMAKE_` variable, and `--compile-no-warning-as-error` to disable it. [cmake 3.6]: https://cmake.org/cmake/help/latest/release/3.6.html
* CUDA supports `native` to compile for the current GPUs detected. [cmake 3.7]: https://cmake.org/cmake/help/latest/release/3.7.html
* `SYSTEM` includes now are respected on MSVC generators. [cmake 3.8]: https://cmake.org/cmake/help/latest/release/3.8.html
* Better support for MSVC, XCode, and others. [cmake 3.9]: https://cmake.org/cmake/help/latest/release/3.9.html
* `LLVMFlang` compiler support. [cmake 3.10]: https://cmake.org/cmake/help/latest/release/3.10.html
[cmake 3.11]: https://cmake.org/cmake/help/latest/release/3.11.html
[Releases]: https://cmake.org/cmake/help/latest/release/index.html [cmake 3.12]: https://cmake.org/cmake/help/latest/release/3.12.html
[CMake 3.0]: https://cmake.org/cmake/help/latest/release/3.0.html [cmake 3.13]: https://cmake.org/cmake/help/latest/release/3.13.html
[CMake 3.1]: https://cmake.org/cmake/help/latest/release/3.1.html [cmake 3.14]: https://cmake.org/cmake/help/latest/release/3.14.html
[CMake 3.2]: https://cmake.org/cmake/help/latest/release/3.2.html [cmake 3.15]: https://cmake.org/cmake/help/latest/release/3.15.html
[CMake 3.3]: https://cmake.org/cmake/help/latest/release/3.3.html [cmake 3.16]: https://cmake.org/cmake/help/latest/release/3.16.html
[CMake 3.4]: https://cmake.org/cmake/help/latest/release/3.4.html [cmake 3.17]: https://cmake.org/cmake/help/latest/release/3.17.html
[CMake 3.5]: https://cmake.org/cmake/help/latest/release/3.5.html [cmake 3.18]: https://cmake.org/cmake/help/latest/release/3.18.html
[CMake 3.6]: https://cmake.org/cmake/help/latest/release/3.6.html [cmake 3.19]: https://cmake.org/cmake/help/latest/release/3.19.html
[CMake 3.7]: https://cmake.org/cmake/help/latest/release/3.7.html [cmake 3.20]: https://cmake.org/cmake/help/latest/release/3.20.html
[CMake 3.8]: https://cmake.org/cmake/help/latest/release/3.8.html [cmake 3.21]: https://cmake.org/cmake/help/latest/release/3.21.html
[CMake 3.9]: https://cmake.org/cmake/help/latest/release/3.9.html [cmake 3.22]: https://cmake.org/cmake/help/latest/release/3.22.html
[CMake 3.10]: https://cmake.org/cmake/help/latest/release/3.10.html [cmake 3.23]: https://cmake.org/cmake/help/latest/release/3.23.html
[CMake 3.11]: https://cmake.org/cmake/help/latest/release/3.11.html [cmake master]: https://cmake.org/cmake/help/git-master/release/index.html
[CMake 3.12]: https://cmake.org/cmake/help/latest/release/3.12.html
[CMake 3.13]: https://cmake.org/cmake/help/latest/release/3.13.html
[CMake 3.14]: https://cmake.org/cmake/help/latest/release/3.14.html
[CMake 3.15]: https://cmake.org/cmake/help/latest/release/3.15.html
[CMake 3.16]: https://cmake.org/cmake/help/latest/release/3.16.html
[CMake 3.17]: https://cmake.org/cmake/help/latest/release/3.17.html
[CMake 3.18]: https://cmake.org/cmake/help/latest/release/3.18.html
[CMake 3.19]: https://cmake.org/cmake/help/latest/release/3.19.html
[CMake 3.20]: https://cmake.org/cmake/help/latest/release/3.20.html
[CMake 3.21]: https://cmake.org/cmake/help/latest/release/3.21.html
[CMake 3.22]: https://cmake.org/cmake/help/latest/release/3.22.html
[CMake 3.23]: https://cmake.org/cmake/help/latest/release/3.23.html
[CMake master]: https://cmake.org/cmake/help/git-master/release/index.html
[fastercmake]: https://blog.kitware.com/improving-cmakes-runtime-performance/ [fastercmake]: https://blog.kitware.com/improving-cmakes-runtime-performance/

View File

@ -3,6 +3,7 @@
Before writing CMake, let's make sure you know how to run it to make things. This is true for almost all CMake projects, which is almost everything. Before writing CMake, let's make sure you know how to run it to make things. This is true for almost all CMake projects, which is almost everything.
## Building a project ## Building a project
Unless otherwise noted, you should always make a build directory and build from there. You can technically do an in-source build, but you'll have to be careful not to overwrite files or add them to git, so just don't. Unless otherwise noted, you should always make a build directory and build from there. You can technically do an in-source build, but you'll have to be careful not to overwrite files or add them to git, so just don't.
Here's the Classic CMake Build Procedure (TM): Here's the Classic CMake Build Procedure (TM):
@ -21,23 +22,26 @@ You can replace the make line with `cmake --build .` if you'd like, and it will
~/package $ cmake --build build ~/package $ cmake --build build
{% endterm %} {% endterm %}
Any *one* of these commands will install: Any _one_ of these commands will install:
{% term %} {% term %}
# From the build directory (pick one) # From the build directory (pick one)
~/package/build $ make install ~/package/build $ make install
~/package/build $ cmake --build . --target install ~/package/build $ cmake --build . --target install
~/package/build $ cmake --install . # CMake 3.15+ only ~/package/build $ cmake --install . # CMake 3.15+ only
# From the source directory (pick one) # From the source directory (pick one)
~/package $ make -C build install ~/package $ make -C build install
~/package $ cmake --build build --target install ~/package $ cmake --build build --target install
~/package $ cmake --install build # CMake 3.15+ only ~/package $ cmake --install build # CMake 3.15+ only
{% endterm %} {% endterm %}
So which set of methods should you use? As long as you *do not forget* to type the build directory as the argument, staying out of the build directory is shorter, and making source changes is easier from the source directory. You should try to get used to using `--build`, as that will free you from using only `make` to build. Note that working from the build directory is historically much more common, and some tools and commands (including CTest <3.20) still require running from the build directory. So which set of methods should you use? As long as you _do not forget_ to type the build directory as the argument, staying out of the build directory is shorter, and making source changes is easier from the source directory. You should try to get used to using `--build`, as that will free you from using only `make` to build. Note that working from the build directory is historically much more common, and some tools and commands (including CTest <3.20) still require running from the build directory.
Just to clarify, you can point CMake at either the source directory *from the build directory*, or at an *existing* build directory from anywhere. Just to clarify, you can point CMake at either the source directory _from the build directory_, or at an _existing_ build directory from anywhere.
If you use `cmake --build` instead of directly calling the underlying build system, you can use `-v` for verbose builds (CMake 3.14+), `-j N` for parallel builds on N cores (CMake 3.12+), and `--target` (any version of CMake) or `-t` (CMake 3.15+) to pick a target. Otherwise, these commands vary between build systems, such as `VERBOSE=1 make` and `ninja -v`. You can instead use the environment variables for these, as well, such as `CMAKE_BUILD_PARALLEL_LEVEL` (CMake 3.12+) and `VERBOSE` (CMake 3.14+). If you use `cmake --build` instead of directly calling the underlying build system, you can use `-v` for verbose builds (CMake 3.14+), `-j N` for parallel builds on N cores (CMake 3.12+), and `--target` (any version of CMake) or `-t` (CMake 3.15+) to pick a target. Otherwise, these commands vary between build systems, such as `VERBOSE=1 make` and `ninja -v`. You can instead use the environment variables for these, as well, such as `CMAKE_BUILD_PARALLEL_LEVEL` (CMake 3.12+) and `VERBOSE` (CMake 3.14+).
@ -88,10 +92,10 @@ CMake has support for cached options. A Variable in CMake can be marked as "cach
These are common CMake options to most packages: These are common CMake options to most packages:
* `-DCMAKE_BUILD_TYPE=` Pick from Release, RelWithDebInfo, Debug, or sometimes more. - `-DCMAKE_BUILD_TYPE=` Pick from Release, RelWithDebInfo, Debug, or sometimes more.
* `-DCMAKE_INSTALL_PREFIX=` The location to install to. System install on UNIX would often be `/usr/local` (the default), user directories are often `~/.local`, or you can pick a folder. - `-DCMAKE_INSTALL_PREFIX=` The location to install to. System install on UNIX would often be `/usr/local` (the default), user directories are often `~/.local`, or you can pick a folder.
* `-DBUILD_SHARED_LIBS=` You can set this `ON` or `OFF` to control the default for shared libraries (the author can pick one vs. the other explicitly instead of using the default, though) - `-DBUILD_SHARED_LIBS=` You can set this `ON` or `OFF` to control the default for shared libraries (the author can pick one vs. the other explicitly instead of using the default, though)
* `-DBUILD_TESTING=` This is a common name for enabling tests, not all packages use it, though, sometimes with good reason. - `-DBUILD_TESTING=` This is a common name for enabling tests, not all packages use it, though, sometimes with good reason.
## Debugging your CMake files ## Debugging your CMake files

View File

@ -10,7 +10,7 @@ set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF) set(Boost_USE_STATIC_RUNTIME OFF)
``` ```
In CMake 3.5, imported targets were added. These targets handle dependencies for you as well, so they are a very nice way to add Boost libraries. However, CMake has the dependency information baked into it for all known versions of Boost, so CMake must be newer than Boost for these to work. In a recent [merge request][MROldBoost], CMake started assuming that the dependencies hold from the last version it knows about, and will use that (along with giving a warning). This In CMake 3.5, imported targets were added. These targets handle dependencies for you as well, so they are a very nice way to add Boost libraries. However, CMake has the dependency information baked into it for all known versions of Boost, so CMake must be newer than Boost for these to work. In a recent [merge request][mroldboost], CMake started assuming that the dependencies hold from the last version it knows about, and will use that (along with giving a warning). This
functionality was backported into CMake 3.9. functionality was backported into CMake 3.9.
The import targets are in the `Boost::` namespace. `Boost::boost` is the header only part. The other compiled libraries are available, and include dependencies as needed. The import targets are in the `Boost::` namespace. `Boost::boost` is the header only part. The other compiled libraries are available, and include dependencies as needed.
@ -37,7 +37,5 @@ endif()
target_link_libraries(MyExeOrLibrary PUBLIC Boost::filesystem) target_link_libraries(MyExeOrLibrary PUBLIC Boost::filesystem)
``` ```
[findboost]: https://cmake.org/cmake/help/latest/module/FindBoost.html
[mroldboost]: https://gitlab.kitware.com/cmake/cmake/merge_requests/1172
[FindBoost]: https://cmake.org/cmake/help/latest/module/FindBoost.html
[MROldBoost]: https://gitlab.kitware.com/cmake/cmake/merge_requests/1172

View File

@ -1,10 +1,9 @@
# CUDA # CUDA
CUDA support is available in two flavors. The new method, introduced in CMake 3.8 (3.9 for Windows), should be strongly preferred over the old, hacky method - I only mention the old method due to the high chances of an old package somewhere having it. Unlike the older languages, CUDA support has been rapidly evolving, and building CUDA is hard, so I would recommend you *require a very recent version* of CMake! CMake 3.17 and 3.18 have a lot of improvements directly targeting CUDA. CUDA support is available in two flavors. The new method, introduced in CMake 3.8 (3.9 for Windows), should be strongly preferred over the old, hacky method - I only mention the old method due to the high chances of an old package somewhere having it. Unlike the older languages, CUDA support has been rapidly evolving, and building CUDA is hard, so I would recommend you _require a very recent version_ of CMake! CMake 3.17 and 3.18 have a lot of improvements directly targeting CUDA.
A good resource for CUDA and Modern CMake is [this talk](http://on-demand.gputechconf.com/gtc/2017/presentation/S7438-robert-maynard-build-systems-combining-cuda-and-machine-learning.pdf) by CMake developer Robert Maynard at GTC 2017. A good resource for CUDA and Modern CMake is [this talk](http://on-demand.gputechconf.com/gtc/2017/presentation/S7438-robert-maynard-build-systems-combining-cuda-and-machine-learning.pdf) by CMake developer Robert Maynard at GTC 2017.
## Adding the CUDA Language ## Adding the CUDA Language
There are two ways to enable CUDA support. If CUDA is not optional: There are two ways to enable CUDA support. If CUDA is not optional:
@ -31,7 +30,7 @@ You can see if CUDA is present by checking `CMAKE_CUDA_COMPILER` (was missing
until CMake 3.11). until CMake 3.11).
You can check variables like `CMAKE_CUDA_COMPILER_ID` (for nvcc, this is You can check variables like `CMAKE_CUDA_COMPILER_ID` (for nvcc, this is
`"NVIDIA"`, Clang was added in CMake 3.18). You can check the version with `"NVIDIA"`, Clang was added in CMake 3.18). You can check the version with
`CMAKE_CUDA_COMPILER_VERSION`. `CMAKE_CUDA_COMPILER_VERSION`.
## Variables for CUDA ## Variables for CUDA
@ -52,7 +51,7 @@ you are already used to from the `cxx` versions.
### Adding a library / executable ### Adding a library / executable
This is the easy part; as long as you use `.cu` for CUDA files, you can just add libraries *exactly like you normally would*. This is the easy part; as long as you use `.cu` for CUDA files, you can just add libraries _exactly like you normally would_.
You can also use separable compilation: You can also use separable compilation:
@ -97,8 +96,8 @@ endfunction()
### Useful variables ### Useful variables
* `CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES`: Place for built-in Thrust, etc - `CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES`: Place for built-in Thrust, etc
* `CMAKE_CUDA_COMPILER`: NVCC with location - `CMAKE_CUDA_COMPILER`: NVCC with location
You can use You can use
[`FindCUDAToolkit`](https://cmake.org/cmake/help/git-stage/module/FindCUDAToolkit.html) [`FindCUDAToolkit`](https://cmake.org/cmake/help/git-stage/module/FindCUDAToolkit.html)
@ -107,9 +106,9 @@ CUDA language.
> ### Note that FindCUDA is deprecated, but for for versions of CMake < 3.18, the following functions required FindCUDA: > ### Note that FindCUDA is deprecated, but for for versions of CMake < 3.18, the following functions required FindCUDA:
> >
> * CUDA version checks / picking a version > - CUDA version checks / picking a version
> * Architecture detection (Note: 3.12 fixes this partially) > - Architecture detection (Note: 3.12 fixes this partially)
> * Linking to CUDA libraries from non-.cu files > - Linking to CUDA libraries from non-.cu files
## Classic FindCUDA [WARNING: DO NOT USE] (for reference only) ## Classic FindCUDA [WARNING: DO NOT USE] (for reference only)

View File

@ -2,19 +2,14 @@
To add MPI, like OpenMP, you'll be best off with CMake 3.9+. To add MPI, like OpenMP, you'll be best off with CMake 3.9+.
```cmake ```cmake
find_package(MPI REQUIRED) find_package(MPI REQUIRED)
message(STATUS "Run: ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} EXECUTABLE ${MPIEXEC_POSTFLAGS} ARGS") message(STATUS "Run: ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} EXECUTABLE ${MPIEXEC_POSTFLAGS} ARGS")
target_link_libraries(MyTarget PUBLIC MPI::MPI_CXX) target_link_libraries(MyTarget PUBLIC MPI::MPI_CXX)
``` ```
However, you can imitate this on CMake 3.1+ with: However, you can imitate this on CMake 3.1+ with:
```cmake ```cmake
find_package(MPI REQUIRED) find_package(MPI REQUIRED)

View File

@ -17,7 +17,6 @@ find_package(Minuit2 CONFIG) # Either build or install
target_link_libraries(MyProgram PRIVATE Minuit2::Minuit2) target_link_libraries(MyProgram PRIVATE Minuit2::Minuit2)
``` ```
## Development ## Development
Minuit2 is a good example of potential solutions to the problem of integrating a modern (CMake 3.1+) build into an existing framework. Minuit2 is a good example of potential solutions to the problem of integrating a modern (CMake 3.1+) build into an existing framework.
@ -37,8 +36,8 @@ make package_source
make purge make purge
``` ```
This is only intended for developers wanting to produce source packages - a normal user *does not pass this option* and will not create source copies. This is only intended for developers wanting to produce source packages - a normal user _does not pass this option_ and will not create source copies.
You can use `make install` or `make package` (binary packages) without adding this `standalone` option, either from inside the ROOT source or from a standalone package. You can use `make install` or `make package` (binary packages) without adding this `standalone` option, either from inside the ROOT source or from a standalone package.
[Minuit2]: https://root.cern.ch [minuit2]: https://root.cern.ch

View File

@ -2,7 +2,6 @@
[OpenMP] support was drastically improved in CMake 3.9+. The Modern(TM) way to add OpenMP to a target is: [OpenMP] support was drastically improved in CMake 3.9+. The Modern(TM) way to add OpenMP to a target is:
```cmake ```cmake
find_package(OpenMP) find_package(OpenMP)
if(OpenMP_CXX_FOUND) if(OpenMP_CXX_FOUND)
@ -12,7 +11,6 @@ endif()
This not only is cleaner than the old method, it will also correctly set the library link line differently from the compile line if needed. In CMake 3.12+, this will even support OpenMP on macOS (if the library is available, such as with `brew install libomp`). However, if you need to support older CMake, the following works on CMake 3.1+: This not only is cleaner than the old method, it will also correctly set the library link line differently from the compile line if needed. In CMake 3.12+, this will even support OpenMP on macOS (if the library is available, such as with `brew install libomp`). However, if you need to support older CMake, the following works on CMake 3.1+:
```cmake ```cmake
# For CMake < 3.9, we need to make the target ourselves # For CMake < 3.9, we need to make the target ourselves
if(NOT TARGET OpenMP::OpenMP_CXX) if(NOT TARGET OpenMP::OpenMP_CXX)
@ -32,4 +30,4 @@ target_link_libraries(MyTarget PUBLIC OpenMP::OpenMP_CXX)
Warning: CMake < 3.4 has a bug in the Threads package that requires you to have the `C` language enabled. Warning: CMake < 3.4 has a bug in the Threads package that requires you to have the `C` language enabled.
{% endhint %} {% endhint %}
[OpenMP]: https://cmake.org/cmake/help/latest/module/FindOpenMP.html [openmp]: https://cmake.org/cmake/help/latest/module/FindOpenMP.html

View File

@ -1,9 +1,8 @@
# ROOT # ROOT
ROOT is a C++ Toolkit for High Energy Physics. It is huge. There are really a lot of ways to use it in CMake, though many/most of the examples you'll find are probably wrong. Here's my recommendation. ROOT is a C++ Toolkit for High Energy Physics. It is huge. There are really a lot of ways to use it in CMake, though many/most of the examples you'll find are probably wrong. Here's my recommendation.
Most importantly, there are *lots of improvements* in CMake support in more recent versions of ROOT - Using 6.16+ is much, much easier! If you really must support 6.14 or earlier, see the section at the end. There were further improvements in 6.20, as well, it behaves much more like a proper CMake project, and exports C++ standard features for targets, etc. Most importantly, there are _lots of improvements_ in CMake support in more recent versions of ROOT - Using 6.16+ is much, much easier! If you really must support 6.14 or earlier, see the section at the end. There were further improvements in 6.20, as well, it behaves much more like a proper CMake project, and exports C++ standard features for targets, etc.
## Finding ROOT ## Finding ROOT
@ -13,7 +12,6 @@ ROOT 6.10+ supports config file discovery, so you can just do:
to attempt to find ROOT. If you don't have your paths set up, you can pass `-DROOT_DIR=$ROOTSYS/cmake` to find ROOT. (But, really, you should source `thisroot.sh`). to attempt to find ROOT. If you don't have your paths set up, you can pass `-DROOT_DIR=$ROOTSYS/cmake` to find ROOT. (But, really, you should source `thisroot.sh`).
## The right way (Targets) ## The right way (Targets)
ROOT 6.12 and earlier do not add the include directory for imported targets. ROOT 6.14+ has corrected this error, and required target properties have been getting better. This method is rapidly becoming easier to use (see the example at the end of this page for the older ROOT details). ROOT 6.12 and earlier do not add the include directory for imported targets. ROOT 6.14+ has corrected this error, and required target properties have been getting better. This method is rapidly becoming easier to use (see the example at the end of this page for the older ROOT details).
@ -24,25 +22,25 @@ To link, just pick the libraries you want to use:
If you'd like to see the default list, run `root-config --libs` on the command line. In Homebrew ROOT 6.18 this would be: If you'd like to see the default list, run `root-config --libs` on the command line. In Homebrew ROOT 6.18 this would be:
* `ROOT::Core` - `ROOT::Core`
* `ROOT::Gpad` - `ROOT::Gpad`
* `ROOT::Graf3d` - `ROOT::Graf3d`
* `ROOT::Graf` - `ROOT::Graf`
* `ROOT::Hist` - `ROOT::Hist`
* `ROOT::Imt` - `ROOT::Imt`
* `ROOT::MathCore` - `ROOT::MathCore`
* `ROOT::Matrix` - `ROOT::Matrix`
* `ROOT::MultiProc` - `ROOT::MultiProc`
* `ROOT::Net` - `ROOT::Net`
* `ROOT::Physics` - `ROOT::Physics`
* `ROOT::Postscript` - `ROOT::Postscript`
* `ROOT::RIO` - `ROOT::RIO`
* `ROOT::ROOTDataFrame` - `ROOT::ROOTDataFrame`
* `ROOT::ROOTVecOps` - `ROOT::ROOTVecOps`
* `ROOT::Rint` - `ROOT::Rint`
* `ROOT::Thread` - `ROOT::Thread`
* `ROOT::TreePlayer` - `ROOT::TreePlayer`
* `ROOT::Tree` - `ROOT::Tree`
## The old global way ## The old global way
@ -59,12 +57,14 @@ Find ROOT allows you to specify components. It will add anything you list to `${
## Dictionary generation ## Dictionary generation
Dictionary generation is ROOT's way of working around the missing reflection feature in C++. It allows ROOT to learn the details of your class so it can save it, show methods in the Cling interpreter, etc. Your source code will need the following modifications to support dictionary generation: Dictionary generation is ROOT's way of working around the missing reflection feature in C++. It allows ROOT to learn the details of your class so it can save it, show methods in the Cling interpreter, etc. Your source code will need the following modifications to support dictionary generation:
* Your class definition should end with `ClassDef(MyClassName, 1)`
* Your class implementation should have `ClassImp(MyClassName)` in it - Your class definition should end with `ClassDef(MyClassName, 1)`
- Your class implementation should have `ClassImp(MyClassName)` in it
ROOT provides `rootcling` and `genreflex` (a legacy interface to `rootcling`) binaries which produce the source files required to build the dictionary. It also defines `root_generate_dictionary`, a CMake function to invoke `rootcling` during the build process. ROOT provides `rootcling` and `genreflex` (a legacy interface to `rootcling`) binaries which produce the source files required to build the dictionary. It also defines `root_generate_dictionary`, a CMake function to invoke `rootcling` during the build process.
To load this function, first include the ROOT macros: To load this function, first include the ROOT macros:
```cmake ```cmake
include("${ROOT_DIR}/modules/RootNewMacros.cmake") include("${ROOT_DIR}/modules/RootNewMacros.cmake")
# For ROOT versions than 6.16, things break # For ROOT versions than 6.16, things break
@ -79,6 +79,7 @@ The `if(...)` condition is added to fix a bug in the NewMacros file that causes
`rootcling` uses a special header file with a [specific formula][linkdef-root] to determine which parts to generate dictionaries for. The name of this file may have any prefix, but **must** end with `LinkDef.h`. Once you have written this header file, the dictionary generation function can be invoked. `rootcling` uses a special header file with a [specific formula][linkdef-root] to determine which parts to generate dictionaries for. The name of this file may have any prefix, but **must** end with `LinkDef.h`. Once you have written this header file, the dictionary generation function can be invoked.
### Manually building the dictionary ### Manually building the dictionary
Sometimes, you might want to ask ROOT to generate the dictionary, and then add the source file to your library target yourself. You can call the `root_generate_dictionary` with the name of the dictionary, e.g. `G__Example`, any required header files, and finally the special `LinkDef.h` file, listed after `LINKDEF`: Sometimes, you might want to ask ROOT to generate the dictionary, and then add the source file to your library target yourself. You can call the `root_generate_dictionary` with the name of the dictionary, e.g. `G__Example`, any required header files, and finally the special `LinkDef.h` file, listed after `LINKDEF`:
```cmake ```cmake
@ -86,14 +87,16 @@ root_generate_dictionary(G__Example Example.h LINKDEF ExampleLinkDef.h)
``` ```
This command will create three files: This command will create three files:
* `${NAME}.cxx`: This file should be included in your sources when you make your library.
* `lib{NAME}.rootmap` (`G__` prefix removed): The rootmap file in plain text - `${NAME}.cxx`: This file should be included in your sources when you make your library.
* `lib{NAME}_rdict.pcm` (`G__` prefix removed): A [ROOT pre-compiled module file][] - `lib{NAME}.rootmap` (`G__` prefix removed): The rootmap file in plain text
The name (`${NAME}`) of the targetthat you must create is determined by the dictionary name; if the dictionary name starts with `G__`, it will be removed. Otherwise, the name is used directly. - `lib{NAME}_rdict.pcm` (`G__` prefix removed): A [ROOT pre-compiled module file][]
The name (`${NAME}`) of the targetthat you must create is determined by the dictionary name; if the dictionary name starts with `G__`, it will be removed. Otherwise, the name is used directly.
The final two output files must sit next to the library output. This is done by checking `CMAKE_LIBRARY_OUTPUT_DIRECTORY` (it will not pick up local target settings). If you have a libdir set but you don't have (global) install locations set, you'll also need to set `ARG_NOINSTALL` to `TRUE`. The final two output files must sit next to the library output. This is done by checking `CMAKE_LIBRARY_OUTPUT_DIRECTORY` (it will not pick up local target settings). If you have a libdir set but you don't have (global) install locations set, you'll also need to set `ARG_NOINSTALL` to `TRUE`.
### Building the dictionary with an existing target ### Building the dictionary with an existing target
Instead of manually adding the generated to your library sources, you can ask ROOT to do this for you by passing a `MODULE` argument. This argument should specify the name of an existing build target: Instead of manually adding the generated to your library sources, you can ask ROOT to do this for you by passing a `MODULE` argument. This argument should specify the name of an existing build target:
```cmake ```cmake
@ -103,9 +106,8 @@ root_generate_dictionary(G__Example Example.h MODULE Example LINKDEF ExampleLink
The full name of the dictionary (e.g. `G__Example`) should not be identical to the `MODULE` argument. The full name of the dictionary (e.g. `G__Example`) should not be identical to the `MODULE` argument.
[linkdef-root]: https://root.cern.ch/selecting-dictionary-entries-linkdefh [linkdef-root]: https://root.cern.ch/selecting-dictionary-entries-linkdefh
[ROOT pre-compiled module file]: https://inspirehep.net/literature/1413967 [root pre-compiled module file]: https://inspirehep.net/literature/1413967
--- ---

View File

@ -4,7 +4,6 @@
Until CMake 3.11, the primary download method for packages was done at build time. This causes several issues; most important of which is that `add_subdirectory` doesn't work on a file that doesn't exist yet! The built-in tool for this, ExternalProject, has to work around this by doing the build itself. (It can, however, build non-CMake packages as well).[^1] Until CMake 3.11, the primary download method for packages was done at build time. This causes several issues; most important of which is that `add_subdirectory` doesn't work on a file that doesn't exist yet! The built-in tool for this, ExternalProject, has to work around this by doing the build itself. (It can, however, build non-CMake packages as well).[^1]
[^1]: Note that ExternalData is the tool for non-package data. [^1]: Note that ExternalData is the tool for non-package data.
## Downloading Method: configure time ## Downloading Method: configure time

View File

@ -4,9 +4,9 @@ Often, you would like to do your download of data or packages as part of the con
The [FetchContent] module has excellent documentation that I won't try to repeat. The key ideas are: The [FetchContent] module has excellent documentation that I won't try to repeat. The key ideas are:
* Use `FetchContent_Declare(MyName)` to get data or a package. You can set URLs, Git repositories, and more. - Use `FetchContent_Declare(MyName)` to get data or a package. You can set URLs, Git repositories, and more.
* Use `FetchContent_GetProperties(MyName)` on the name you picked in the first step to get `MyName_*` variables. - Use `FetchContent_GetProperties(MyName)` on the name you picked in the first step to get `MyName_*` variables.
* Check `MyName_POPULATED`, and if not populated, use `FetchContent_Populate(MyName)` (and if a package, `add_subdirectory("${MyName_SOURCE_DIR}" "${MyName_BINARY_DIR}")`) - Check `MyName_POPULATED`, and if not populated, use `FetchContent_Populate(MyName)` (and if a package, `add_subdirectory("${MyName_SOURCE_DIR}" "${MyName_BINARY_DIR}")`)
For example, to download Catch2: For example, to download Catch2:
@ -50,4 +50,4 @@ Now you have the CMake 3.14+ syntax in CMake 3.11+.
See the example [here](https://gitlab.com/CLIUtils/modern-cmake/-/tree/master/examples/fetch). See the example [here](https://gitlab.com/CLIUtils/modern-cmake/-/tree/master/examples/fetch).
[FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html [fetchcontent]: https://cmake.org/cmake/help/latest/module/FetchContent.html

View File

@ -43,7 +43,6 @@ add_subdirectory(extern/repo)
Or, you can build an interface library target yourself if it is a header only project. Or, you can use `find_package` if that is supported, probably preparing the initial search directory to be the one you've added (check the docs or the file for the `Find*.cmake` file you are using). You can also include a CMake helper file directory if you append to your `CMAKE_MODULE_PATH`, for example to add `pybind11`'s improved `FindPython*.cmake` files. Or, you can build an interface library target yourself if it is a header only project. Or, you can use `find_package` if that is supported, probably preparing the initial search directory to be the one you've added (check the docs or the file for the `Find*.cmake` file you are using). You can also include a CMake helper file directory if you append to your `CMAKE_MODULE_PATH`, for example to add `pybind11`'s improved `FindPython*.cmake` files.
### Bonus: Git version number ### Bonus: Git version number
Move this to Git section: Move this to Git section:

View File

@ -44,7 +44,6 @@ add_test(NAME TestName COMMAND $<TARGET_FILE:${TESTNAME}>)
which would use the output location (thus, the executable) of the produced target. which would use the output location (thus, the executable) of the produced target.
## Building as part of a test ## Building as part of a test
If you want to run CMake to build a project as part of a test, you can do that too (in fact, this is how CMake tests itself). For example, if your master project was called `MyProject` and you had an `examples/simple` project that could build by itself, this would look like: If you want to run CMake to build a project as part of a test, you can do that too (in fact, this is how CMake tests itself). For example, if your master project was called `MyProject` and you had an `examples/simple` project that could build by itself, this would look like:
@ -66,6 +65,6 @@ add_test(
Look at the subchapters for recipes for popular frameworks. Look at the subchapters for recipes for popular frameworks.
* [GoogleTest](testing/googletest.md): A popular option from Google. Development can be a bit slow. - [GoogleTest](testing/googletest.md): A popular option from Google. Development can be a bit slow.
* [Catch2](testing/catch.md): A modern, PyTest-like framework with clever macros. - [Catch2](testing/catch.md): A modern, PyTest-like framework with clever macros.
* [DocTest](https://github.com/onqtam/doctest): A replacement for Catch2 that is supposed to compile much faster and be cleaner. See Catch2 chapter and replace with DocTest. - [DocTest](https://github.com/onqtam/doctest): A replacement for Catch2 that is supposed to compile much faster and be cleaner. See Catch2 chapter and replace with DocTest.

View File

@ -1,6 +1,5 @@
# Catch # Catch
[Catch2] (C++11 only version) is a powerful, idomatic testing solutions similar in philosophy to PyTest for Python. It supports a wider range of compilers than GTest, and is quick to support new things, like M1 builds on macOS. It also has a smaller but faster twin, [doctest](https://github.com/onqtam/doctest), which is quick to compile but misses features like matchers. To use Catch in a CMake project, there are several options. [Catch2] (C++11 only version) is a powerful, idomatic testing solutions similar in philosophy to PyTest for Python. It supports a wider range of compilers than GTest, and is quick to support new things, like M1 builds on macOS. It also has a smaller but faster twin, [doctest](https://github.com/onqtam/doctest), which is quick to compile but misses features like matchers. To use Catch in a CMake project, there are several options.
## Configure methods ## Configure methods
@ -46,11 +45,10 @@ set_property(Catch2::Catch PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${CATCH_INCLU
Then, you would link to Catch2::Catch. This would have been okay as an INTERFACE target since you won't be exporting your tests. Then, you would link to Catch2::Catch. This would have been okay as an INTERFACE target since you won't be exporting your tests.
## Direct inclusion ## Direct inclusion
If you add the library using ExternalProject, FetchContent, or git submodules, you can also `add_subdirectory` Catch (CMake 3.1+). If you add the library using ExternalProject, FetchContent, or git submodules, you can also `add_subdirectory` Catch (CMake 3.1+).
Catch also provides two CMake modules that you can use to register the individual tests with CMake. Catch also provides two CMake modules that you can use to register the individual tests with CMake.
[Catch2]: https://github.com/catchorg/Catch2 [catch2]: https://github.com/catchorg/Catch2

View File

@ -24,7 +24,6 @@ endif()
I would recommend using something like `PROJECT_NAME STREQUAL CMAKE_PROJECT_NAME` to set the default for the `PACKAGE_TESTS` option, since this should only build by default if this is the current project. I would recommend using something like `PROJECT_NAME STREQUAL CMAKE_PROJECT_NAME` to set the default for the `PACKAGE_TESTS` option, since this should only build by default if this is the current project.
As mentioned before, you have to do the `enable_testing` in your main CMakeLists. As mentioned before, you have to do the `enable_testing` in your main CMakeLists.
Now, in your tests directory: Now, in your tests directory:
```cmake ```cmake
@ -75,7 +74,7 @@ package_add_test(test1 test1.cpp)
``` ```
This will allow you to quickly and simply add tests. Feel free to adjust to suit your needs. If you haven't seen it before, `ARGN` is "every argument after the listed ones". This will allow you to quickly and simply add tests. Feel free to adjust to suit your needs. If you haven't seen it before, `ARGN` is "every argument after the listed ones".
Modify the macro to meet your needs. For example, if you're testing libraries and need to link in different libraries for different tests, you might use this: Modify the macro to meet your needs. For example, if you're testing libraries and need to link in different libraries for different tests, you might use this:
```cmake ```cmake
macro(package_add_test_with_libraries TESTNAME FILES LIBRARIES TEST_WORKING_DIRECTORY) macro(package_add_test_with_libraries TESTNAME FILES LIBRARIES TEST_WORKING_DIRECTORY)
@ -91,10 +90,9 @@ endmacro()
package_add_test_with_libraries(test1 test1.cpp lib_to_test "${PROJECT_DIR}/european-test-data/") package_add_test_with_libraries(test1 test1.cpp lib_to_test "${PROJECT_DIR}/european-test-data/")
``` ```
## Download method ## Download method
You can use the downloader in my [CMake helper repository][CLIUtils/cmake], using CMake's `include` command. You can use the downloader in my [CMake helper repository][cliutils/cmake], using CMake's `include` command.
This is a downloader for [GoogleTest], based on the excellent [DownloadProject] tool. Downloading a copy for each project is the recommended way to use GoogleTest (so much so, in fact, that they have disabled the automatic CMake install target), so this respects that design decision. This method downloads the project at configure time, so that IDEs correctly find the libraries. Using it is simple: This is a downloader for [GoogleTest], based on the excellent [DownloadProject] tool. Downloading a copy for each project is the recommended way to use GoogleTest (so much so, in fact, that they have disabled the automatic CMake install target), so this respects that design decision. This method downloads the project at configure time, so that IDEs correctly find the libraries. Using it is simple:
@ -111,6 +109,7 @@ add_gtest(SimpleTest)
``` ```
> Note: `add_gtest` is just a macro that adds `gtest`, `gmock`, and `gtest_main`, and then runs `add_test` to create a test with the same name: > Note: `add_gtest` is just a macro that adds `gtest`, `gmock`, and `gtest_main`, and then runs `add_test` to create a test with the same name:
>
> ```cmake > ```cmake
> target_link_libraries(SimpleTest gtest gmock gtest_main) > target_link_libraries(SimpleTest gtest gmock gtest_main)
> add_test(SimpleTest SimpleTest) > add_test(SimpleTest SimpleTest)
@ -138,7 +137,6 @@ endif()
[^1]: Here I've assumed that you are working on a GitHub repository by using the relative path to googletest. [^1]: Here I've assumed that you are working on a GitHub repository by using the relative path to googletest.
[cliutils/cmake]: https://github.com/CLIUtils/cmake
[CLIUtils/cmake]: https://github.com/CLIUtils/cmake [googletest]: https://github.com/google/googletest
[GoogleTest]: https://github.com/google/googletest [downloadproject]: https://github.com/Crascit/DownloadProject
[DownloadProject]: https://github.com/Crascit/DownloadProject

View File

@ -2,11 +2,11 @@ This is an example project using CMake.
The requirements are: The requirements are:
* CMake 3.11 or better; 3.14+ highly recommended. - CMake 3.11 or better; 3.14+ highly recommended.
* A C++17 compatible compiler - A C++17 compatible compiler
* The Boost libararies (header only part is fine) - The Boost libararies (header only part is fine)
* Git - Git
* Doxygen (optional) - Doxygen (optional)
To configure: To configure:

View File

@ -1,4 +1,4 @@
# Documentation for Modern Library {#mainpage} # Documentation for Modern Library {#mainpage}
This is the documentation for my simple example library. This is the documentation for my simple example library.

View File

@ -5,6 +5,7 @@ ROOT suggested flags, we will manually add threading via `find_package`, which i
important flag in the list on most systems. important flag in the list on most systems.
#### examples/root-dict/CMakeLists.txt #### examples/root-dict/CMakeLists.txt
[import:'main', lang:'cmake'](CMakeLists.txt) [import:'main', lang:'cmake'](CMakeLists.txt)
## Supporting files ## Supporting files
@ -12,14 +13,17 @@ important flag in the list on most systems.
This is just a simple-as-possible class definition, with one method: This is just a simple-as-possible class definition, with one method:
#### examples/root-dict/DictExample.cxx #### examples/root-dict/DictExample.cxx
[import, lang:'c_cpp'](DictExample.cxx) [import, lang:'c_cpp'](DictExample.cxx)
#### examples/root-dict/DictExample.h #### examples/root-dict/DictExample.h
[import, lang:'c_cpp'](DictExample.h) [import, lang:'c_cpp'](DictExample.h)
We need a `LinkDef.h`, as well. We need a `LinkDef.h`, as well.
#### examples/root-dict/DictLinkDef.h #### examples/root-dict/DictLinkDef.h
[import, lang:'c_cpp'](DictLinkDef.h) [import, lang:'c_cpp'](DictLinkDef.h)
## Testing it ## Testing it
@ -27,4 +31,5 @@ We need a `LinkDef.h`, as well.
This is an example of a macro that tests the correct generation from the files listed above. This is an example of a macro that tests the correct generation from the files listed above.
#### examples/root-dict/CheckLoad.C #### examples/root-dict/CheckLoad.C
[import, lang:'c_cpp'](CheckLoad.C) [import, lang:'c_cpp'](CheckLoad.C)

View File

@ -3,6 +3,7 @@
This is a minimal example of a ROOT project using the target system and without a dictionary. This is a minimal example of a ROOT project using the target system and without a dictionary.
#### examples/root-simple/CMakeLists.txt #### examples/root-simple/CMakeLists.txt
[import:'main', lang:'cmake'](CMakeLists.txt) [import:'main', lang:'cmake'](CMakeLists.txt)
#### examples/root-simple/SimpleExample.cxx #### examples/root-simple/SimpleExample.cxx

View File

@ -3,6 +3,7 @@
This is a minimal example of a ROOT project using the UseFile system and without a dictionary. This is a minimal example of a ROOT project using the UseFile system and without a dictionary.
#### examples/root-usefile/CMakeLists.txt #### examples/root-usefile/CMakeLists.txt
[import:'main', lang:'cmake'](CMakeLists.txt) [import:'main', lang:'cmake'](CMakeLists.txt)
#### examples/root-usefile/SimpleExample.cxx #### examples/root-usefile/SimpleExample.cxx

8030
package-lock.json generated

File diff suppressed because it is too large Load Diff