From 3f10729d1badda6b5811285916ec0d4bcd2394d7 Mon Sep 17 00:00:00 2001 From: Henry Fredrick Schreiner Date: Fri, 6 Apr 2018 11:40:00 +0200 Subject: [PATCH] Adding more links, fix master links --- README.md | 13 +++++++------ book.json | 2 +- chapters/basics/functions.md | 16 ++++++---------- 3 files changed, 14 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 850f9e4..ceaf86b 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Certainly there are no shortage of problems when building. But I think that, in 2018, we have a very good solution to quite a few of those problems. It's CMake. Not CMake 2.8 though; that was released before C++11 even existed! Nor the horrible examples out there for CMake (even those posted on KitWare's own tutorials list). -I'm talking about [Modern CMake]. CMake 3.1+, maybe even CMake 3.11+! +I'm talking about Modern CMake. CMake 3.1+, maybe even CMake 3.11+! It's clean, powerful, and elegant, so you can spend most of your time coding, not adding lines to an unreadable, unmaintainable Make (Or CMake 2) file. And CMake 3.11 is significantly faster, as well! @@ -68,16 +68,17 @@ And, since CMake will dumb itself down to the minimum required version in your C 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. -This book tries to solve the problem of the poor examples and best practices that you'll find proliferating the web. A nice, slightly dated post with a similar intent can be found [here](https://rix0r.nl/blog/2015/08/13/cmake-guide/). You might also find that helpful for a fast introduction. +This book tries to solve the problem of the poor examples and best practices that you'll find proliferating the web. -## Other sources: +## Other sources + +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. * [Effective Modern CMake](https://gist.github.com/mbinna/c61dbb39bca0e4fb7d1f73b0d66a4fd1): A great list of do's and don'ts. -* [Embracing Modern CMake][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. +* [The Ultimate Guide to Modern CMake](https://rix0r.nl/blog/2015/08/13/cmake-guide/): A slightly dated post with similar intent. [^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. -[Modern CMake]: https://steveire.wordpress.com/2017/11/05/embracing-modern-cmake/ - diff --git a/book.json b/book.json index d5e9618..8e08444 100644 --- a/book.json +++ b/book.json @@ -9,7 +9,7 @@ }, "replace": { "substitutes": [ - {"pattern": "«cmake:([^`^»]+)»", "flags": "g", "substitute": "[$1](https://cmake.org/cmake/help/latest/$1.7.html)"}, + {"pattern": "«cmake:([^`^»]+)»", "flags": "g", "substitute": "[$1](https://cmake.org/cmake/help/latest/cmake-$1.7.html)"}, {"pattern": "«command:`?([^`^»]+)`?»", "flags": "g", "substitute": "[`$1`](https://cmake.org/cmake/help/latest/command/$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)"}, diff --git a/chapters/basics/functions.md b/chapters/basics/functions.md index 29e2754..bbecfb5 100644 --- a/chapters/basics/functions.md +++ b/chapters/basics/functions.md @@ -2,7 +2,7 @@ ## Control flow -CMake has an [if statement], though over the years is has become rather complex. There are a series of all caps keywords you can use inside an if statement, and you can often refer to variables by either directly by name or using the `${}` syntax (the if statement historically predates variable expansion). An example if statement: +CMake has an «command:`if`» statement, though over the years is has become rather complex. There are a series of all caps keywords you can use inside an if statement, and you can often refer to variables by either directly by name or using the `${}` syntax (the if statement historically predates variable expansion). An example if statement: ```cmake if(variable) @@ -13,7 +13,7 @@ endif() # If variable does not expand to one of the above, CMake will expand it then try again ``` -Since this can be a little confusing if you explicitly put a variable expansion, like `${variable}`, due to the potential expansion of an expansion, a policy was added in CMake 3.1+ that keeps a quoted expansion from being expanded yet again. So, as long as the minimum version of CMake is 3.1+, you can do: +Since this can be a little confusing if you explicitly put a variable expansion, like `${variable}`, due to the potential expansion of an expansion, a policy («policy:CMP0054») was added in CMake 3.1+ that keeps a quoted expansion from being expanded yet again. So, as long as the minimum version of CMake is 3.1+, you can do: ```cmake if("${variable}") @@ -30,9 +30,9 @@ There are a variety of keywords as well, such as: * Parentheses can be used to group -## Generator expressions +## «cmake:Generator-expressions» -[Generator expressions] are really powerful, but a bit odd and specialized. Most CMake commands happen at configure time, include the if statements seen above. But what if you need logic to occur at build time or even install time? Generator expressions were added for this purpose.[^1] They are evaluated in target properties. +«cmake:Generator-expressions> are really powerful, but a bit odd and specialized. Most CMake commands happen at configure time, include the if statements seen above. But what if you need logic to occur at build time or even install time? Generator expressions were added for this purpose.[^1] They are evaluated in target properties. The simplest generator expressions informational expressions, and are of the form `$`, and they evaluate to a piece of information relevant for the current configuration. The other form is `$`, where `KEYWORD` is a keyword that controls the evaluation, and value is the item to evaluate (an informational expression keyword is allowed here, too). If KEYWORD is a generator expression or variable that evaluates to 0 or 1, `value` is substituted if 1 and not if 0. You can nest generator expressions, and you can use variables to make reading nested variables bearable. Some @@ -68,7 +68,7 @@ That last one is very common. You'll see something like this in almost every pac ## Macros and Functions -You can define your own CMake functions or macros easily. The only difference between a function and a macro is scope; macros don't have one. So, if you set a variable in a function and want it to be visible outside, you'll need `PARENT_SCOPE`. Nesting functions therefore is a bit tricky, since you'll have to explicitly set the variables you want visible to the outside world to `PARENT_SCOPE` in each function. But, functions don't "leak" all their variables like macros do. For the +You can define your own CMake «command:`function`» or «command:`macro`» easily. The only difference between a function and a macro is scope; macros don't have one. So, if you set a variable in a function and want it to be visible outside, you'll need `PARENT_SCOPE`. Nesting functions therefore is a bit tricky, since you'll have to explicitly set the variables you want visible to the outside world to `PARENT_SCOPE` in each function. But, functions don't "leak" all their variables like macros do. For the following examples, I'll use functions. An example of a simple function is as follows: @@ -87,7 +87,7 @@ If you want positional arguments, they are listed explicitly, and all other argu ## Arguments -CMake has a named variable system that you've already seen in most of the build in CMake functions. You can use it with the [`cmake_parse_arguments` function][cmake_parse_arguments]. If you want to support a version of CMake less than 3.5, you'll want to also include the CMakeParseArguments module, which is where it used to live before becoming a built in command. Here is an example of how to use it: +CMake has a named variable system that you've already seen in most of the build in CMake functions. You can use it with the «command:`cmake_parse_arguments`» function. If you want to support a version of CMake less than 3.5, you'll want to also include the «module:CMakeParseArguments» module, which is where it used to live before becoming a built in command. Here is an example of how to use it: ```cmake function(COMPLEX) @@ -115,7 +115,3 @@ 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 statement]: https://cmake.org/cmake/help/latest/command/if.html -[Generator expressions]: https://cmake.org/cmake/help/latest/manual/cmake-generator-expressions.7.html -[cmake_parse_arguments]: https://cmake.org/cmake/help/latest/command/cmake_parse_arguments.html -