Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Developing with CMake  (Read 3898 times)

0 Members and 1 Guest are viewing this topic.

Keeen

  • Newbie
  • *
  • Posts: 1
    • View Profile
Developing with CMake
« on: October 09, 2019, 01:27:04 pm »
Hello everyone,,
I have a rather general question concerning CMake. I often hear it simplifies things, for developers as well as for users. I understand, that when CMake is correctly configured, it can be used for a large amount of compilers and IDEs.

But until one can configure it correctly to support a wide range of compilers, it seems to be a real pain, especially in the beginning. I've been surprised a little bit by the big amount of script and config files required for CMake just to generate SFML. Besides, a lot of cases (e.g. VS or g++) are still differentiated manually, while CMake promises to relieve developers of exactly this process. The recent quotation mark issue shows me that there are still several things that don't work as expected (maybe I should inform the CMake team about that).

I have considered using CMake to build own libraries in the future, but at the moment I'm rather sceptical. Also I would have to learn the CMake script language...

What is your experience (Laurent and other people using CMake to build own projects)?
« Last Edit: October 09, 2019, 02:48:21 pm by Laurent »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Developing with CMake
« Reply #1 on: October 09, 2019, 03:00:25 pm »
At work, we develop with Qt and other platform-independant libraries. In this case, CMake scripts usually remain small and quite simple -- even with support for install, unit tests, doxygen generation, etc.; it's definitely worth it. There's no need for OS or compiler specific stuff, it works perfectly fine from the start.

For SFML, CMake scripts are polluted with platform specificities, and that's what makes it so ugly. Depending on the OS, we need different sources, different system libraries, and different compiler options. And CMake cannot help with that. This is even why SFML exists: to hide all this crap and provide a simple and unified abstraction.

Moreover, those scripts have accumulated specific contributions over the years, and besides the (relatively recent) move to modern CMake, nobody ever tried to maintain it as a whole. I'm pretty sure that a significant amount of those scripts could be removed, improved, simplified.
Laurent Gomila - SFML developer

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Developing with CMake
« Reply #2 on: October 09, 2019, 08:21:06 pm »
To maybe give you another example, you could have a look at my library Thor. It's an extension to SFML and thus depends on SFML (and transitively SFML's own dependencies), however Thor itself is written in pure C++.
https://github.com/Bromeon/Thor

As such, the CMake files are considerably simpler than for SFML, but there's still a few of them (for different build targets):

There are a few occurrences of explicit case differentiations:
(click to show/hide)
Plus a few ones for static/dynamic linking and choosing the right SFML versions.




I agree with your statement, that CMake cannot keep its promise of abstracting all its build steps. It has annoyed myself a lot in the past, and made me think why there is no better solution even after decades. In my opinion, there are several reasons for this, but at the core all lies the lack of standardization.

1. Linking C++ binaries is a hard problem
The lack of standardization is the root of a huge variety of problems related to building C++ code. It starts with no standardized ABI, meaning that even different versions of the same compiler, or slightly different compiler flags, lead to inherently incompatible binaries. This is a source of link, load and runtime errors on one hand, and a tedious exercise on the other. In many cases, the safest approach in 2019 is still "build the whole chain yourself".

The sheer existence of "header-only libraries" is a good proof of the status quo -- it's often such a pain to link libraries that library authors deliberately accept the disadvantage of repeatedly recompiling the same code just because it's much easier. No other language has this phenomenon, not even C. Ironically, linking C is comparably easy, because you have a standard ABI. If it weren't, then not every single programming language on this planet would have its own C binding.


2. All tooling is external
C++ has a slow standardization process and a tendency to not include features that are not considered "core enough" from the standard. The language specification does not make any statements about tooling, apart from the compiler itself. Compare this to languages like Go, which include a package manager, a build system, a documentation system (Godoc), even a formatter to enforce one code style out of the box.

Since C++ does not ship any of those, external providers emerge. And because different people have different preferences, there's not just one build system, one package manager and one documenting tool, but dozens. Dozens of each. Eventually a few ones become popular, but libraries are still partitioned, and if I have a huge project based on many libraries, I either have to fight with multiple toolchains or rewrite a lot myself.


3. There are 3000 conventions, for everything
The standard library went with a controversial snake_case naming and very limited feature set, effectively putting no effort in encouraging anyone except Boost to follow. 20 years later, every other library uses different naming, different way of namespacing, different string/network/filesystem/thread implementations. The C++ community is truly exceptional in the number of fundamental features that have been re-invented. While this alone is not making the linking per se difficult, it's making interoperability between libraries hard.

The same phenomenon is spreading over to library building: some use -d suffix for debug, some -debug, some nothing at all; some provide x86 and x64 builds with the same name, others have a proprietary naming scheme; some use semver, some not, other things like DLLs have no proper versioning at all. This is not exactly helping the situation.




It is near-impossible to cover all those conventions in a build system and make everyone happy. If there were standard ways on how to name, version and depend on third-party libraries, a lot of it could be automated. But there are not, so you see people write the same if(debug) link(this) until the end of time.

So, is CMake the right tool for the job?

On one hand, CMake is the epitome of Not-Invented-Here. It's already hard to grasp why CMake had to reinvent an entire programming language just for a meta-build system, but it's mindblowing that they managed to come up with a syntax far from any common language, instead competing with bash in WTF moments. But, in all this, they did a decent job at keeping the syntax very simple and consistent (everything is basically a function call with space-separated arguments). And once you get the basic principles, you can limit the time wasted on looking up how to do string operations.

Also, CMake is arguably the most powerful and prominent meta-build system in the C++ universe, being around for quite some time but still actively improving. Even if it has its problems, it's usually better for the community when the majority of projects are using one system and not 22. Fighting with CMake-specific problems (which are mostly solvable, also given its huge community) is a lot easier and more scalable than maintaining separate toolchains.

Keep in mind that CMake is a meta-build system and as such nowhere near an end-to-end solution. It solves the major task of linking C++ libraries and producing the build system input of your choice (Makefiles, VS solutions, etc.). However, package management, dependency management, documentation and easy distribution are -- to this day -- not solved in a satisfactory way. This is the same in other build systems.

Alas, this is one of the major drawbacks of C++ nowadays, and everyone who has worked with pip/npm/Composer/Cargo before -- where pulling a dependency from the Internet is one command -- will be left with many unanswered questions.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11032
    • View Profile
    • development blog
    • Email
Re: Developing with CMake
« Reply #3 on: October 09, 2019, 11:29:21 pm »
To maybe give you another example, you could have a look at my library Thor. It's an extension to SFML and thus depends on SFML (and transitively SFML's own dependencies), however Thor itself is written in pure C++.
https://github.com/Bromeon/Thor

As such, the CMake files are considerably simpler than for SFML, but there's still a few of them (for different build targets):
Not to undermine anything that Nexus said, but I just want to mention that while Thor might give you an idea of how CMake can be used more lightweight, Thor still uses older constructs of CMake which aren't necessarily recommended anymore (which of course is part of the problem with too many ways to do one thing).
If you want to learn CMake, Thor nor SFML might be the best examples to look at.

Here are some CMake resource links:

https://crascit.com/professional-cmake/
https://arne-mertz.de/2018/06/cmake-project-structure/
https://pabloariasal.github.io/2018/02/19/its-time-to-do-cmake-right/
http://unclejimbo.github.io/2018/06/08/Modern-CMake-for-Library-Developers/
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

RCD

  • Newbie
  • *
  • Posts: 1
    • View Profile
    • SPD Group
    • Email
Re: Developing with CMake
« Reply #4 on: October 17, 2019, 12:01:18 pm »
Thanks for the help, I am looking for more information on CMake development, and this is exactly what I need!
I am a tech writer at https://spd.group, providing articles on Artificial Intelligence and Machine Learning.