From b80a42f5eefceb0cfceb9bb3cfd4e2188114de8a Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Mon, 3 Aug 2020 10:28:14 -0400 Subject: [PATCH] update: nicer discussion of min version --- chapters/basics.md | 66 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 51 insertions(+), 15 deletions(-) diff --git a/chapters/basics.md b/chapters/basics.md index d89f8ed..5c68cbb 100644 --- a/chapters/basics.md +++ b/chapters/basics.md @@ -3,46 +3,71 @@ ## Minimum Version -Here's the first line of every CMakeLists.txt, which is the required name of the file CMake looks for: +Here's the first line of every `CMakeLists.txt`, which is the required name of +the file CMake looks for: ```cmake cmake_minimum_required(VERSION 3.1) ``` -Let's mention a bit of CMake syntax. The command name «command:`cmake_minimum_required`» is case insensitive, so the common practice is to use lower case. [^1] The `VERSION` is a special keyword for this function. And the value of the version follows the keyword. Like everywhere in this book, just click on the command name to see the official documentation, and use the dropdown to switch documentation between CMake versions. +Let's mention a bit of CMake syntax. The command name +«command:`cmake_minimum_required`» is case insensitive, so the common practice +is to use lower case. [^1] The `VERSION` is a special keyword for this +function. And the value of the version follows the keyword. Like everywhere in +this book, just click on the command name to see the official documentation, +and use the dropdown to switch documentation between CMake versions. -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 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 hidden symbols behaviour, etc. A list of policies and versions is available at «cmake: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 +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 +hidden symbols behaviour, etc. A list of policies and versions is available at +«cmake:policies». -In CMake 3.12, this will support a range, such as `VERSION 3.1...3.12`; this means you support as low as 3.1 but have also tested it with the new policy settings up to 3.12. This is much nicer on users that need the better settings, and due to a trick in the syntax, it's backward compatible with older versions of CMake (though actually running CMake 3.2-3.11 will only set the 3.1 version of the policies in this example). New versions of policies tend to be most important for macOS and Windows users, who also -usually have a very recent version of CMake. +Starting in CMake 3.12, this supports a range, such as `VERSION 3.1...3.15`; +this means you support as low as 3.1 but have also tested it with the new +policy settings up to 3.15. This is much nicer on users that need the better +settings, and due to a trick in the syntax, it's backward compatible with older +versions of CMake (though actually running CMake 3.1-3.11 will only set the 3.1 +version of the policies in this example, since those versions didn't treat this +specially). New versions of policies tend to be most important for macOS and +Windows users, who also usually have a very recent version of CMake. This is what new projects should do: ```cmake -cmake_minimum_required(VERSION 3.1...3.15) +cmake_minimum_required(VERSION 3.7...3.18) if(${CMAKE_VERSION} VERSION_LESS 3.12) cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}) endif() ``` -If CMake version is less than 3.12, the if block will be true, and the policy will be set to the current CMake version. If CMake is 3.12 or higher, the if block will be false, but the new syntax in `cmake_minimum_required` will be respected and this will continue to work properly! +If CMake version is less than 3.12, the if block will be true, and the policy +will be set to the current CMake version. If CMake is 3.12 or higher, the if +block will be false, but the new syntax in `cmake_minimum_required` will be +respected and this will continue to work properly! -WARNING: MSVC's CMake server mode [originally had a bug](https://github.com/fmtlib/fmt/issues/809) in reading this format, so if you need to support non-command line Windows builds for older MSVC versions, you will want to do this instead: +WARNING: MSVC's CMake server mode [originally had a +bug](https://github.com/fmtlib/fmt/issues/809) in reading this format, so if +you need to support non-command line Windows builds for older MSVC versions, +you will want to do this instead: ```cmake -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.7) -if(${CMAKE_VERSION} VERSION_LESS 3.15) +if(${CMAKE_VERSION} VERSION_LESS 3.18) cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}) else() - cmake_policy(VERSION 3.15) + cmake_policy(VERSION 3.18) endif() ``` {% hint style='info' %} -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 specific policy. Please at least do this for your macOS users! +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 +specific policy. Please at least do this for your macOS users! {% endhint %} @@ -56,17 +81,28 @@ project(MyProject VERSION 1.0 LANGUAGES CXX) ``` -Now we see even more syntax. Strings are quoted, whitespace doesn't matter, and the name of the project is the first argument (positional). All the keyword arguments here are optional. The version sets a bunch of variables, like `MyProject_VERSION` and `PROJECT_VERSION`. The languages are `C`, `CXX`, `Fortran`, `ASM`, `CUDA` (CMake 3.8+), `CSharp` (3.8+), and `SWIFT` (CMake 3.15+ experimental). `C CXX` is the default. In CMake 3.9, `DESCRIPTION` was added to set a project description, as well. The documentation for «command:`project`» may be helpful. +Now we see even more syntax. Strings are quoted, whitespace doesn't matter, and +the name of the project is the first argument (positional). All the keyword +arguments here are optional. The version sets a bunch of variables, like +`MyProject_VERSION` and `PROJECT_VERSION`. The languages are `C`, `CXX`, +`Fortran`, `ASM`, `CUDA` (CMake 3.8+), `CSharp` (3.8+), and `SWIFT` (CMake +3.15+ experimental). `C CXX` is the default. In CMake 3.9, `DESCRIPTION` was +added to set a project description, as well. The documentation for +«command:`project`» may be helpful. {% hint style='info' %} -You can add [comments](https://cmake.org/cmake/help/latest/manual/cmake-language.7.html#comments) with the `#` character. CMake does have an inline syntax for comments too, but it is rarely needed, as whitespace doesn't matter. +You can add +[comments](https://cmake.org/cmake/help/latest/manual/cmake-language.7.html#comments) +with the `#` character. CMake does have an inline syntax for comments too, but +it's rarely used. {% endhint %} There's really nothing special about the project name. No targets are added at this point. ## Making an executable -Although libraries are much more interesting, and we'll spend most of our time with them, let's start with a simple executable. +Although libraries are much more interesting, and we'll spend most of our time +with them, let's start with a simple executable. ```cmake add_executable(one two.cpp three.h)