CMake: Difference between revisions

From SambaWiki
(Add an important reason why cmake might be the better tool.)
 
(26 intermediate revisions by 4 users not shown)
Line 1: Line 1:
CMake is a cross-platform, open-source meta build system to build, test and package software. It creates Makefile or other build files (KDevelop, Eclipse). The intention is to test it if people like it and if we could replace the current build system with CMake.
This is about the Samba build system which is around since quite some time. It has been created to satisfy the special needs of Samba. It works fine but it is undocumented, it is hard for people to understand it and there is no active development to improve it. CMake could be a very good replacement for the old dusty build system. CMake is a cross-platform, open-source meta build system to build, test and package software. It creates Makefile or other build files (KDevelop, Eclipse, XCode, MSVC). The intention is to test it and show it to you. This starts with a "Hands on" tutorial and goes into details later.

Give it a try!


= Hands on =
= Hands on =
Line 7: Line 9:
Lets start to do a checkout and compile something. Run some commands and then come back and talk about the features.
Lets start to do a checkout and compile something. Run some commands and then come back and talk about the features.


$ git clone git://gitorious.org/samba-wip/samba-wip.git
$ git clone git://gitorious.org/samba/gladiac-wip.git
$ cd samba-wip
$ cd samba-wip
$ git checkout -b cmake origin/cmake
$ cd lib/talloc
$ cd lib/talloc


Line 34: Line 35:
$ make help
$ make help


If you go to a source directory you have a target for each .c file.
If you go to the equivalent build directory to your source tree you have a target for each .c file.


$ cd replace
$ cd replace
Line 68: Line 69:
== CMakeLists.txt ==
== CMakeLists.txt ==


CMake is pretty simple to learn. The way to tell CMake what to do, is to create a CMakeLists.txt file in each source directory. If you want to get started I suggest to look at http://www.cmake.org/cmake/help/examples.html.
CMake is pretty simple to learn. The way to tell CMake what to do, is to create a CMakeLists.txt file in each source directory.

=== Hello World ===

The following example demonstrates some key ideas of CMake.

There are three directories involved. The top level directory has two subdirectories called ./demo and ./hello. In the directory ./hello, a library is built. In the directory ./demo, an executable is built by linking to the library. A total of three CMakeList.txt files are created: one for each directory.

The first, top-level directory contains the following CMakeLists.txt file.

<pre>
# The name of our project is "Hello". CMakeLists files in this project can
# refer to the root source directory of the project as ${HELLO_SOURCE_DIR} and
# to the root binary directory of the project as ${HELLO_BINARY_DIR}.
# The 'C' after the "Hello" means that it is a C project and CMake will only
# check for a C compiler and not for a C++ compiler.
project (Hello C)
cmake_minimum_required (VERSION 2.6)


# Recurse into the "Hello" and "Demo" subdirectories. This does not actually
# cause another cmake executable to run. The same process will walk through
# the project's entire directory structure.
add_subdirectory (hello)
add_subdirectory (demo)
</pre>

Then for each subdirectory specified, CMakeLists.txt files are created. In the ./hello directory, the following CMakeLists.txt file is created:

<pre>
# Create a library called "hello" which includes the source file "hello.c".
# The extension is already found. Any number of sources could be listed here.
add_library (hello hello.c)
</pre>

Finally, in the ./demo directory, the third and final CMakeLists.txt file is created:

<pre>
# Make sure the compiler can find include files from our hello library.
include_directories (${HELLO_SOURCE_DIR}/hello)

# Add executable called "hello_demo" that is built from the source files
# "demo.c" and "demo_b.c". The extensions are automatically found.
add_executable(hello_demo demo.c demo_b.c)

# Link the executable to the Hello library.
target_link_libraries (hello_demo hello)
</pre>

CMake when executed in the top-level directory will process the CMakeLists.txt file and then descend into the listed subdirectories. Variables, include paths, library paths, etc. are inherited. Depending on the system, Makefiles (Unix) or workspaces/projects (MSVC) will be built. These can then be used in the usual way to build the code.

Kitware made the tutorial from the 'Mastering CMake' book finally public, you can find it here:

http://www.cmake.org/cmake/help/cmake_tutorial.html

=== A bigger example ===


I've tried to document the CMakeLists.txt a bit to make it easier to start. Everything else is documented in 'man cmake'.
I've tried to document the CMakeLists.txt a bit to make it easier to start. Everything else is documented in 'man cmake'.


Assume we have created a Find Module for finding talloc (see lib/tevent/cmake/Modules/FindTalloc.cmake).
A short example:


Assume we have created a Find Module for finding talloc (see lib/tevent/cmake/Modules/FindTalloc.cmake; this was created using a script I've written). The way to compile a library if you have such a Find Module, cmake has more than 100 shipped by default, is fairly easy.
The way to compile a library if you have such a Find Module, cmake has more than 100 shipped by default, is fairly easy.


<pre>
<pre>
Line 120: Line 176:
* Reruns itself if one of the input files has changed
* Reruns itself if one of the input files has changed
* Compiler independent
* Compiler independent
* The words ''cmake'' and ''cake'' share 80% of their characters


http://www.cdash.org/CDash/index.php?project=CMake
http://www.cdash.org/CDash/index.php?project=CMake
Line 125: Line 182:
= Migration =
= Migration =


The migration to CMake can be done beside the current build system. As you write CMakeLists.txt file and do out of source build you don't have to touch the current build system. You can work on CMake and still have a working build using the old system. As soon as CMake is fully working you can remove the old build system.
The migration to CMake can be done in parallel to the current build system. As you write CMakeLists.txt file and do out of source build you don't have to touch the current build system. You can work on CMake and still have a working build using the old system. As soon as CMake is fully working you can remove the old build system.


== Requirements ==

We would require CMake 2.6 which has been released in May 2008. They ensure that CMake is backward compatible. CMake is shipped on every Linux Distributions, OpenSolaris, BSDs cause there is a lot of software which depends on it, e.g. KDE, Wireshark ...

Binaires are available on the CMake website for:

* Linux i386
* Windows
* SunOS Sparc
* IRIX64 64
* IRIX64 n32
* HPUX 9000/785
* AIX powerpc

CMake bootstraps on several other platforms like Tru64, OSF1, OpenVMS, SCO_VS, BeOS, RISCos, ...

I'm sure if we could do Nightly build on exotic platforms they will fix bugs for these platform.


= CTest and CDash =
= CTest and CDash =


CMake would allow us to easily use CTest and CDash for automatic testing. It has some nice features like running tests and check the how long they run. Then create a graph out of it. Do code coverage and run automatically valgrind on each test. Everything is reported to CDash.
CMake would allow us to easily use CTest and CDash for automatic testing. It has some nice features like running tests and check how long they run. Then create a graph out of it. Do code coverage and run automatically valgrind on each test. Everything is reported to CDash.


http://www.cdash.org/CDash/index.php?project=CMake
http://www.cdash.org/CDash/index.php?project=CMake

= Samba Custom Build System vs CMake =

{| border="1" cellpadding="2" style="border-style: solid; border-color: black; border-spacing: 0px; padding: 3px;"
|-
!
! style="background:#efefef;" | Samba Custom Build System
! style="background:#ffdead;" | CMake
|-
| Languages
| 4 (autoconf (m4), perl, shell, make)
| 2 (CMake, make)
|-
| Community
| Some people know it, you have to wait until they are available
| Big community, mailinglists and IRC channels available
|-
| Testing and debugging of binaires
| Build static or set environment variables to run them in the build dir
| Simply works with shared libraries cause of RPATH in build dir
|-
| Documentation
| Autotools are documented, but Samba specific stuff has minimal documentation
| Good documentation and Wiki available
|-
| Development
| Some?
| Active development and maintenance community
|-
| Out of source build
| Possible, but is broken since a long time. Still creates files in the source tree.
| Default, no files inside the source tree are touched
|-
| Parallel build of Samba3 and Samba4
| Requirement of "make clean" and very often "git clean" as the clean directives are wrong very often
| No "make clean" required while working on shared codebase and testing builds for Samba3 and Samba4 because a out of tree build (see above) is possible. This will greatly speed up the development process.
|}

Latest revision as of 13:00, 3 January 2011

This is about the Samba build system which is around since quite some time. It has been created to satisfy the special needs of Samba. It works fine but it is undocumented, it is hard for people to understand it and there is no active development to improve it. CMake could be a very good replacement for the old dusty build system. CMake is a cross-platform, open-source meta build system to build, test and package software. It creates Makefile or other build files (KDevelop, Eclipse, XCode, MSVC). The intention is to test it and show it to you. This starts with a "Hands on" tutorial and goes into details later.

Give it a try!

Hands on

talloc

Lets start to do a checkout and compile something. Run some commands and then come back and talk about the features.

 $ git clone git://gitorious.org/samba/gladiac-wip.git
 $ cd samba-wip
 $ cd lib/talloc

CMake is designed to build out of the source. This has several advantages. You don't have to create thousand of entries in .gitignore. You can create a build directory for *every local git branch* you create. CMake can be invoked by differnet executables:

  • cmake: the commandline tool
  • ccmake: a ncurses based gui
  • cmake-gui: a Qt gui.
 $ mkdir build
 $ cd build
 $ cmake ..

This is a talloc stand alone build. Normally you have to copy libreplace in the talloc dir but there is a check to look for ../replace, if you're in the Samba tree. It does all the required configure checks here to build on Linux as this is just a test.

 $ make

I think you know what it does. What's nice it shows only what it's building and the warnings and errors. If you want to see how make/cmake invokes the compiler, try the following:

 $ make clean
 $ make VERBOSE=1

To see what targets are availalbe, you can use

 $ make help

If you go to the equivalent build directory to your source tree you have a target for each .c file.

 $ cd replace
 $ make help
 $ cd ..

You can execute every binary in the build directory and it will work. CMake uses rpath to build executables so that test scripts are able to find the right libraries, and things like make test can be run from the build directory without requiring you to install or build everything static. Executables are re-linked at install time to remove the rpath restriction. http://www.cmake.org/Wiki/CMake_RPATH_handling See:

 $ ldd talloc_testsuite

Building with RPATH can be disabled with 'cmake -DSKIP_BUILD_RPATH=OFF ..'. You have to set environment variables in this case to get executables working.

tevent

Lets look at tevent. I've created a way to let tevent use talloc from the system or compile it in source if you're in the samba tree.

 $ cd lib/tevent
 $ mkdir build
 $ cd build
 $ cmake ..
 $ make

This will build against the talloc system library. CMake uses so called "Find Packages" to find a library. There is no standard way to search for libraries and header files so CMake created a way to to it. You write a module and all you have to do is call 'find_package(Talloc REQUIRED)'. You can take a look at 'cmake/Modules/FindTalloc.cmake' in the tevent source directory if you want. Here is the way to build it in the Samba source tree.

 $ cd lib/tevent/build
 $ rm CMakeCache.txt
 $ cmake -DWITH_SYSTEM_TALLOC=OFF ..
 $ make

CMakeLists.txt

CMake is pretty simple to learn. The way to tell CMake what to do, is to create a CMakeLists.txt file in each source directory.

Hello World

The following example demonstrates some key ideas of CMake.

There are three directories involved. The top level directory has two subdirectories called ./demo and ./hello. In the directory ./hello, a library is built. In the directory ./demo, an executable is built by linking to the library. A total of three CMakeList.txt files are created: one for each directory.

The first, top-level directory contains the following CMakeLists.txt file.

# The name of our project is "Hello". CMakeLists files in this project can
# refer to the root source directory of the project as ${HELLO_SOURCE_DIR} and
# to the root binary directory of the project as ${HELLO_BINARY_DIR}.
# The 'C' after the "Hello" means that it is a C project and CMake will only
# check for a C compiler and not for a C++ compiler.
project (Hello C)
cmake_minimum_required (VERSION 2.6)


# Recurse into the "Hello" and "Demo" subdirectories. This does not actually
# cause another cmake executable to run. The same process will walk through
# the project's entire directory structure.
add_subdirectory (hello)
add_subdirectory (demo)

Then for each subdirectory specified, CMakeLists.txt files are created. In the ./hello directory, the following CMakeLists.txt file is created:

# Create a library called "hello" which includes the source file "hello.c".
# The extension is already found. Any number of sources could be listed here.
add_library (hello hello.c)

Finally, in the ./demo directory, the third and final CMakeLists.txt file is created:

# Make sure the compiler can find include files from our hello library.
include_directories (${HELLO_SOURCE_DIR}/hello)

# Add executable called "hello_demo" that is built from the source files
# "demo.c" and "demo_b.c". The extensions are automatically found.
add_executable(hello_demo demo.c demo_b.c)

# Link the executable to the Hello library.
target_link_libraries (hello_demo hello)

CMake when executed in the top-level directory will process the CMakeLists.txt file and then descend into the listed subdirectories. Variables, include paths, library paths, etc. are inherited. Depending on the system, Makefiles (Unix) or workspaces/projects (MSVC) will be built. These can then be used in the usual way to build the code.

Kitware made the tutorial from the 'Mastering CMake' book finally public, you can find it here:

http://www.cmake.org/cmake/help/cmake_tutorial.html

A bigger example

I've tried to document the CMakeLists.txt a bit to make it easier to start. Everything else is documented in 'man cmake'.

Assume we have created a Find Module for finding talloc (see lib/tevent/cmake/Modules/FindTalloc.cmake).

The way to compile a library if you have such a Find Module, cmake has more than 100 shipped by default, is fairly easy.

  # find the talloc package and require it!
  find_package(Talloc REQUIRED)

  include_directories(${TALLOC_INCLUDE_DIRS})

  # set the source files
  set(tevent_SRCS
    tevent.c
    tevent_debug.c
    tevent_fd.c
  )

  # create a library target
  add_library(tevent SHARED ${tevent_SRCS})
  target_link_libraries(tevent ${TALLOC_LIBRARIES})

  # install it
  install(TARGETS tevent LIBRARY DESTINATION lib)

Isn't this easy to write and understand?

If you want to use functions or macros which are not covered by the cmake documentation then you find it at the top of each file. They are in '/usr/share/cmake/Modules' or in cmake/Modules if you look at replace/talloc/tevent here.

Help

If you need help with cmake there are different sources:

Advantages of CMake

  • Out of source build
  • Automatic dependency generation (parallel builds)
  • Build system in *one* language
  • Good documentation (man cmake)
  • Works on a lot of different machines and operating systems -> http://www.cdash.org/CDash/index.php?project=CMake
  • Support for complex custom commands like qt moc, yacc, pidl! This means compile a source generator, then use the source generator to generate source code from special input files (compile pidl then: foo.idl -> pidl -> foo.c)
  • Reruns itself if one of the input files has changed
  • Compiler independent
  • The words cmake and cake share 80% of their characters

http://www.cdash.org/CDash/index.php?project=CMake

Migration

The migration to CMake can be done in parallel to the current build system. As you write CMakeLists.txt file and do out of source build you don't have to touch the current build system. You can work on CMake and still have a working build using the old system. As soon as CMake is fully working you can remove the old build system.

Requirements

We would require CMake 2.6 which has been released in May 2008. They ensure that CMake is backward compatible. CMake is shipped on every Linux Distributions, OpenSolaris, BSDs cause there is a lot of software which depends on it, e.g. KDE, Wireshark ...

Binaires are available on the CMake website for:

  • Linux i386
  • Windows
  • SunOS Sparc
  • IRIX64 64
  • IRIX64 n32
  • HPUX 9000/785
  • AIX powerpc

CMake bootstraps on several other platforms like Tru64, OSF1, OpenVMS, SCO_VS, BeOS, RISCos, ...

I'm sure if we could do Nightly build on exotic platforms they will fix bugs for these platform.

CTest and CDash

CMake would allow us to easily use CTest and CDash for automatic testing. It has some nice features like running tests and check how long they run. Then create a graph out of it. Do code coverage and run automatically valgrind on each test. Everything is reported to CDash.

http://www.cdash.org/CDash/index.php?project=CMake

Samba Custom Build System vs CMake

Samba Custom Build System CMake
Languages 4 (autoconf (m4), perl, shell, make) 2 (CMake, make)
Community Some people know it, you have to wait until they are available Big community, mailinglists and IRC channels available
Testing and debugging of binaires Build static or set environment variables to run them in the build dir Simply works with shared libraries cause of RPATH in build dir
Documentation Autotools are documented, but Samba specific stuff has minimal documentation Good documentation and Wiki available
Development Some? Active development and maintenance community
Out of source build Possible, but is broken since a long time. Still creates files in the source tree. Default, no files inside the source tree are touched
Parallel build of Samba3 and Samba4 Requirement of "make clean" and very often "git clean" as the clean directives are wrong very often No "make clean" required while working on shared codebase and testing builds for Samba3 and Samba4 because a out of tree build (see above) is possible. This will greatly speed up the development process.