Reputation: 287
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 ?)
Upvotes: 20
Views: 15958
Reputation: 141
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.
Upvotes: 0
Reputation: 5653
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.
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:
*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
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:
In general,
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"
myexe_FOO_PROPERTY # Foo property for myexe target
target_compile_definitions()/features()/options()
target_sources()
target_include_directories()
target_link_libraries()
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)
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
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).
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.
Upvotes: 8
Reputation: 5370
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.
Upvotes: 17