mirror of
1
0
Fork 0

Adding do/donots

This commit is contained in:
Henry Fredrick Schreiner 2018-03-30 14:26:33 +02:00
parent ebc704f4c9
commit 5a1632ae28
5 changed files with 60 additions and 9 deletions

View File

@ -4,7 +4,7 @@ People love to hate build systems.
Just watch the talks from CppCon17 to see examples of developers making the state of build systems the brunt of jokes.
This raises the question: Why?
Certainly there are no shortage of problems when building.
But I think that, in 2017, we have a very good solution to quite a few of those problems.
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+!
@ -59,7 +59,7 @@ But it had a 3.
And it followed 2.
And it was a hard, ugly, transition that is still ongoing in some places, even today.
I believe that CMake 3 had the bad luck to follow Python 3.
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 was something new.
And so, you'll find OS's like CentOS7 with GCC 4.8, with almost-complete C++14 support, and CMake 2.8, which came out before C++11.
@ -70,5 +70,13 @@ It's easy (1-2 lines in many cases), and you'll find that 5 minutes of work will
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.
## Other sources:
* [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
[^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/

View File

@ -3,6 +3,7 @@
* [An Introduction to Modern CMake](README.md)
* [Installing CMake](chapters/intro/installing.md)
* [Running CMake](chapters/intro/running.md)
* [Dos and Don'ts](chapters/intro/dodonot.md)
* [What's new in CMake](chapters/intro/newcmake.md)
* [Introduction to the Basics](chapters/basics.md)
* [Variables and the Cache](chapters/basics/variables.md)

43
chapters/intro/dodonot.md Normal file
View File

@ -0,0 +1,43 @@
# Do's and Don'ts
## CMake Version Choice
You'll need to pick a minimum required version of CMake. This will affect the CMake policies, and you should only use the features available in that version. Here are some common build environments and the CMake version you'll find on them. Feel free to install CMake yourself, it's 1-2 lines and there's nothing "special" about the built in version. It's also very backward compatible.
| Distribution | CMake version | Notes |
|---------------|---------------|-------|
| RHEL/CentOS 7 | 2.8.11 | Don't use the default on this system. Grab a new copy or use the EPEL repo. |
| EPEL for RHEL/CentOS | 3.6.3 | Called `cmake3` |
| Ubuntu 14.04 LTS | 2.8.12 | Don't use the default on this system. |
| Ubuntu 16.04 LTS | 3.5.1 | |
| Ubuntu 17.10 | 3.9.1 | |
| Ubuntu 18.04 LTS | 3.10.2 | |
| Python PyPI | 3.10 | Just `pip install cmake` on many systems. Add `--user` for local installs. |
| Homebrew on macOS | 3.11 | On macOS with Homebrew, this is only a few minutes behind cmake.org. |
| Chocolaty on Windows | 3.11 | Also up to date. The normal cmake.org installers are common on Windows, as well. |
| TravisCI | 3.9 | The December 2017 update added a recent version of clang and CMake! Finally! |
## CMake Antipatterns
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.
* **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.
* **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.
## CMake Patterns
* **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.
* **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.
* **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.
[Effective Modern CMake]: https://gist.github.com/mbinna/c61dbb39bca0e4fb7d1f73b0d66a4fd1

View File

@ -4,7 +4,7 @@
Your CMake version should be newer than your compiler. It should be newer than the libraries you are using (especially Boost). New versions work better for everyone.
{% endhint %}
If you have a built in copy of CMake, it isn't special or customized for your system. You can easily install a new one instead, either on the system level or the user level. Feel free to instruct your users here if they complain about a CMake requirement being set too high. Especially if they want < 3.1 support. Maybe even if they want CMake < 3.8 support...
If you have a built in copy of CMake, it isn't special or customized for your system. You can easily install a new one instead, either on the system level or the user level. Feel free to instruct your users here if they complain about a CMake requirement being set too high. Especially if they want < 3.1 support. Maybe even if they want CMake < 3.11 support...
## Official package
@ -13,20 +13,19 @@ You can [download CMake from KitWare][cmake-download]. This is how you'll probab
On Linux, there are binaries provided, but you'll need to pick an install location. If you already use `~/.local` for user-space packages, the following single line command will get CMake for you [^1]:
{% term %}
~ $ wget -qO- "https://cmake.org/files/v3.9/cmake-3.9.4-Linux-x86_64.tar.gz" | tar --strip-components=1 -xz -C ~/.local
~ $ wget -qO- "https://cmake.org/files/v3.11/cmake-3.11.0-Linux-x86_64.tar.gz" | tar --strip-components=1 -xz -C ~/.local
{% endterm %}
If you just want a local folder with CMake only:
{% term %}
~ $ mkdir -p cmake39 && wget -qO- "https://cmake.org/files/v3.9/cmake-3.9.4-Linux-x86_64.tar.gz" | tar --strip-components=1 -xz -C cmake39
~ $ mkdir -p cmake39 && wget -qO- "https://cmake.org/files/v3.11/cmake-3.11.0-Linux-x86_64.tar.gz" | tar --strip-components=1 -xz -C cmake39
~ $ export PATH=`pwd`/cmake39/bin:$PATH
{% endterm %}
You'll obviously want to append to the PATH every time you start a new terminal, or add it to your `.bashrc` or to an [LMod] system.
And, if you want a system install, install to `/usr/local`. (I'm only brave enough to run this in Docker):
And, if you want a system install, install to `/usr/local`. (I'm only brave enough to do this in Docker).
You can also build CMake on any system, it's pretty easy, but binaries are faster.
@ -43,7 +42,7 @@ And as long as a binary exists for your system, you'll be up-and-running almost
This has the benefit of respecting your current virtual environment, as well.
{% hint style='info' %}
Personally, on Linux, I put versions of CMake in folders, like `/opt/cmake39` or `~/opt/cmake39`, and then add them to [LMod]. See [`envmodule_setup`][envmodule_setup] for help setting up an LMod system on macOS or Linux. It's takes a bit to learn, but is a great way to manage package and compiler versions.
Personally, on Linux, I put versions of CMake in folders, like `/opt/cmake311` or `~/opt/cmake311`, and then add them to [LMod]. See [`envmodule_setup`][envmodule_setup] for help setting up an LMod system on macOS or Linux. It's takes a bit to learn, but is a great way to manage package and compiler versions.
[envmodule_setup]: https://github.com/CLIUtils/envmodule_setup
{% endhint %}

View File

@ -38,7 +38,7 @@ And you can pick a tool with `-G"My Tool"` (quotes only needed if spaces are in
## Setting options
You set options in CMake with `-D`. You can see a list of options with `-L`, or a list with human-readable help with `-LH`.
You set options in CMake with `-D`. You can see a list of options with `-L`, or a list with human-readable help with `-LH`. If you don't list the source/build directory, the listing will not rerun CMake (`cmake -L` instead of `cmake -L .`).
## Verbose and partial builds