Why do we need cmake?
Asked Answered
S

3

20

I don't understand, why do we need cmake to build libraries ? I am sorry if my question is stupid, but i need to use some libraries on Widnows, and what ever library i choose i need to build it and/or compile it with cmake.. What is it for ? Why cant i just #include "path" the things that i need into my project, and than it can be compiled/built at the same time as my project ?

And also, sometimes i needed to install Ruby, Perl, Python all of them some specific version so cmake can build libraries... Why do i need those programs, and will i need them only to build library or later in my project too ? (concrete can i uninstall those programs after building libraries ?)

Sarisarid answered 17/10, 2016 at 10:10 Comment(3)
"Why cant i just #include "path" the things that i need into my project, and than it can be compiled/built at the same time as my project ?" - Sounds a lot like you don't even understand, which parts comprise a library, and how it is incorporated into a program. You need to get up to speed with respect to the basics here. Anyway, if a library requires CMake (don't be afraid to use a web search), it does so because that's the tool it chose to manage its build system.Risible
someone voted to close this as "opinion based". I think the bigger problem is that there are valuable questions hidden in this post, but the way they're presented lacks refinement, and the combination is probably too broad for a single question post.Margravine
We don't need it. Is just a flawed tool that many use.Emelinaemeline
T
17

Building things in c++ on different platforms is a mess currently.

There are several different build system out there and there is no standard way to do this. Just providing a visual studio solution wont help compilation on linux or mac.

If you add a makefile for linux or mac you need to repeat configurations between the solution and the makefiles. Which can result in a lot of maintenance overhead. Also makefiles are not really a good build tool compared to the new ones out there.

That you have only CMake libraries is mostly a coincidence. CMake is though a popular choice currently.

There are several solutions out there to unify builds. CMake is a build tool in a special way. It can create makefiles and build them but you can also tell cmake to create a visual studio solution if you like.

The same goes with external programs. They are the choice of the maintainer of the library you use and there are no standards for things like code generation.

While CMake may not be "the" solution (although the upcoming visual studio 2015 is integrating cmake support) but the trend for those build system which are cross-platform is going more and more in this direction.


To your question why you cannot only include the header:

Few libraries are header only and need to be compiled. Either you can get precompiled libs/dlls and just include the header + add the linker path. This is easier in linux because you can have -dev packages which just install a prebuild library and it's header via the package manager. Windows has no such thing natively.

Or you have to build it yourself with whatever buildtool the library uses.

Trophoblast answered 17/10, 2016 at 10:43 Comment(4)
"Windows has no such thing natively." - Native or not, Visual Studio uses NuGet for the same purpose, making deployment of dependencies equally simple. It is "the package manager for the Microsoft development platform". What's cool about NuGet: It's the only package manager, pulling packages from a single URL. You'll find a lot less resources searching for "NuGet troubleshooting" than you do for Linux package managers.Risible
I like your summary, just wanted add some links: CMake support in Visual Studio, The Architecture of Open Source Applications: CMake and About CMake.Bouleversement
@Risible thanks for the NuGet mention. I haven't worked with it yet so I could not add anything for this topic there.Trophoblast
Awesome! Good question, as it will definitely help new bees. And, of course a great answer by Hayt!Muleteer
F
8

The short answer is that you don't, but it would probably be difficult to build the project without it.

CMake does not build code, but is instead a build file generator. It was developed by KitWare (during the ITK project around 2000) to make building code across multiple platforms "simpler". It's not an easy language to use (which Kitware openly admits), but it unifies several things that Windows, Mac, and Linux do differently when building code.

  • On Linux, autoconf is typically used to make build files, which are then compiled by gcc/g++ (and/or clang)
  • On Windows, you would typically use the Visual Studio IDE and create what they call a "Solution" that is then compiled by msvc (the Microsoft Visual C++ compiler)
  • On Mac, I admit I am not familiar with the compiler used, but I believe it is something to do with XCode

CMake lets you write a single script you can use to build on multiple machines and specify different options for each.

Like C++, CMake has been divided between traditional/old-style CMake (version < 3.x) and modern CMake (version >= 3.0). Use modern CMake. The following are excellent tutorials:

  1. Effective CMake, by Daniel Pfeifer, C++Now 2017*
  2. Modern CMake Patterns, by Matheiu Ropert, CppCon 2017
  3. Better CMake
  4. CMake Tutorial

*Awarded the most useful talk at the C++Now 2017 Conference

Watch these in the order listed. You will learn what Modern CMake looks like (and old-style CMake) and gain understanding of how

  1. CMake helps you specify build order and dependencies, and
  2. Modern CMake helps prevent creating cyclic dependencies and common bugs while scaling to larger projects.

Additionally, the last video introduces package managers for C++ (useful when using external libraries, like Boost, where you would use the CMake find_package() command), of which the two most common are:

  1. vcpkg, and
  2. Conan

In general,

  1. Think of targets as objects

    a. There are two kinds, executables and libraries, which are "constructed" with

add_executable(myexe ...)  # Creates an executable target "myexe"
add_library(mylib ...)  # Creates a library target "mylib"
  1. Each target has properties, which are variables for the target. However, they are specified with underscores, not dots, and (often) use capital letters
myexe_FOO_PROPERTY  # Foo property for myexe target
  1. Functions in CMake can also set some properties on target "objects" (under the hood) when run
target_compile_definitions()/features()/options()
target_sources()
target_include_directories()
target_link_libraries() 
  1. CMake is a command language, similar shell scripting, but there's no nesting or piping of commands. Instead

    a. Each command (function) is on its own line and does one thing
    b. The argument(s) to all commands (functions) are strings
    c. Unless the name of a target is explicitly passed to the function, the command applies to the target that was last created

add_executable(myexe ...)  # Create exe target

target_compile_definitions(...)  # Applies to "myexe"
target_include_directories(...)  # Applies to "myexe"
# ...etc.

add_library(mylib ...)  # Create lib target

target_sources(...)  # Applies to "mylib"
# ...etc.

d. Commands are executed in order, top-to-bottom, (NOTE: if a target needs another target, you must create the target first)

  1. The scope of execution is the currently active CMakeLists.txt file. Additional files can be run (added to the scope) using the add_subdirectory() command

    a. This operates much like the shell exec command; the current CMake environment (targets and properties, except PRIVATE properties) are "copied" over into a new scope ("shell"), where additional work is done.

    b. However, the "environment" is not the shell environment (CMake target properties are not passed to the shell as environment variables like $PATH). Instead, the CMake language maintains all targets and properties in the top-level global scope CACHE

  2. PRIVATE properties get used by the current module. INTERFACE properties get passed to subdirectory modules. PUBLIC is for the current module and submodules (the property is appropriate for the current module and applies to/should be used by modules that link against it).

  3. target_link_libraries is for direct module dependencies, but it also resolves all transitive dependencies. This means when you link to a library, you gets all the PUBLIC properties of the parent modules as well.

    a. If you want to link to a library that has a direct path, you can use target_link_libraries, and

    b. if you want to link to a module with a project and take its interface, you also use target_link_libraries

You run CMake on CMakeLists.txt files to generate the build files you want for your system (ninja, Visual Studio solution, Linux make, etc.) and the run those to compile and link the code.

Faze answered 22/11, 2021 at 17:44 Comment(1)
I really wanted to write an answer about the semantics and paradigms, the cmake language syntax offers. Then i read this and voted up your answer. The cmake syntax is the easiest avaliable, while supporting "faked object-oriented" programming. This has real advantages: For really small and simple projects you can create everything with just 10 lines of code, where other generators need 5 times the amount of code for project generation. For bigger complex projects, you can have it all with specialization, wich is one of the drawbacks. Cmake has a really high learning curve, but it worksPueblo
P
0

Using cmake since 15 years, even my old projects still work. With modifying 2 lines of code!

More complex recursive projects needed a little more modification but nothing that could be solved with 1 hour of work (if you know cmake in depth), even after not touching those projects with 2 major releases of cmake in between.

Example: Compile wxWidgets beforehand->switching to llvm on 3 different platforms->producing usable code with minimal effort of project generation code.

My biggest concern, when I started using cmake was, that the language symantic itselve would be changes to hold more paradigms. Gladly this never happened and the developers found ingenious ways to achive it all.

If you learn one tool, learn cmake even if it looks ugly at the beginning if you see the syntax of other generators. If you know cmake well, modifications to bigger projects (1000 of files and dependencies) take hours, not days as I needed with other tools.

Pueblo answered 29/12, 2023 at 11:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.