Cross-Platform Software Development Using CMake
CMake is in essence a simple interpreter. CMake input files have an extremely simple but powerful syntax. It consists of commands, primitive flow control constructs, macros and variables. All commands have exactly the same syntax:
COMMAND_NAME(ARGUMENT1 ARGUMENT2 ...)
For example, the ADD_LIBRARY command specifies that a library should be created. The first argument is the name of the library, the second optional argument is whether the library is static or shared and the remaining arguments are a list of sources. Do you want a shared library? Simply SHARED instead of STATIC. The list of all commands can be seen in the CMake documentation.
A few flow control constructs, such as IF and FOREACH are used. The IF construct uses one of several types of expressions, such as boolean (NOT, AND, OR), check if command exists (COMMAND) and check if file exists (EXISTS). Expressions, however, cannot contain other commands. An example of a commonly used IF statement would be:
IF(UNIX)
IF(APPLE)
SET(GUI "Cocoa"
ELSE(APPLE)
SET(GUI "X11"
ENDIF(APPLE)
ELSE(UNIX)
IF(WIN32)
SET(GUI "Win32"
ELSE(WIN32)
SET(GUI "Unknown"
ENDIF(WIN32)
ENDIF(UNIX)
MESSAGE("GUI system is ${GUI}")
This example shows a simple use of IF statements and variables.
FOREACH is used in the same fashion. The FOREACH command's arguments include the variable that traverses, and the list of items to traverse. For example, if a list of executables needs to be created, where every executable is created from a source file with the same name, the following FOREACH would be used:
SET(SOURCES source1 source2 source3)
FOREACH(source ${SOURCES})
ADD_EXECUTABLE(${source} ${source}.c)
ENDFOREACH(source)
Macros use a syntax of both commands and flow control constructs. To define a macro, the MACRO construct is used. Let's say we often create executables that link to some libraries. The following example macro, then makes our life a bit easier. In the example, CREATE_EXECUTABLE is the name of macro and the rest are arguments. Within the macro, all arguments are presented as variables. Once the macro is created, it can be used as a regular command. The definition and use of a CREATE_EXECUTABLE macro would be:
MACRO(CREATE_EXECUTABLE NAME
SOURCES LIBRARIES)
ADD_EXECUTABLE(${NAME} ${SOURCES})
TARGET_LINK_LIBRARIES(${NAME}
${LIBRARIES})
ENDMACRO(CREATE_EXECUTABLE)
ADD_LIBRARY(MyLibrary libSource.c)
CREATE_EXECUTABLE(MyProgram main.c MyLibrary)
Macros, however, are not equivalent to procedures or functions from programming languages and do not allow recursion.
An important feature of a good build process is the notion of turning on and off parts of the build. The build process also should be able to find and set locations to the system resources your project needs. All these functions are achieved in CMake using conditional compiling. Let me demonstrate with an example. Let's say your project has two modes, regular and debug. Debug mode adds debug code to all the regular code. So, your code is full of sections, such as:
#ifdef DEBUG
fprintf(stderr,
"The value of i is: %d\n", i);
#endif /* DEBUG */
In order to tell CMake to add -DDEBUG to compile lines, you can use the SET_SOURCE_FILE_PROPERTIES with the COMPILE_FLAGS property. But you probably do not want to edit the CMakeLists.txt file every time you switch between debug and regular builds. The OPTION command creates a boolean variable that can be set before building the project. The syntax for the previous example would look like this:
OPTION(MYPROJECT_DEBUG
"Build the project using debugging code"
ON)
IF(MYPROJECT_DEBUG)
SET_SOURCE_FILE_PROPERTIES(
libSource.c main.c
COMPILE_FLAGS -DDEBUG)
ENDIF(MYPROJECT_DEBUG)
Now, you ask, "how do I set this variable?" CMake comes with three flavors of GUI. On UNIX-like systems, there is a Curses GUI called ccmake. It is text-based and can be run through a remote connection. CMake also has GUIs for Microsoft Windows and Mac OS X.
When using CMake-generated Makefiles, if you have already run CMake for the first time, all you have to type is make edit_cache. This command runs an appropriate GUI. In all the GUIs, you have the option of setting variables. As you will see right away, CMake has several default options, for example, EXECUTABLE_OUTPUT_PATH and LIBRARY_OUTPUT_PATH (where executables and libraries go) and, in our case, MYPROJECT_DEBUG. After changing a value of some variable, you press the configure button or [c] (on ccmake).
In GUIs you can set several different types of entries. MYPROJECT_DEBUG is a boolean variable. Another common type variable is a path, which specifies the location of some file on the system. Say our program relies on the location of the file Python.h. We would put in the CMakeLists.txt file the following command, which tries to find a file:
FIND_PATH(PYTHON_INCLUDE_PATH Python.h /usr/include /usr/local/include)
But this command looks only in /usr/include and /usr/local/include, so you have to specify some other locations. Because it can be wasteful to specify all these locations in every single project, you can include other CMake files, called modules. CMake comes with several useful modules, from the type that search for different packages to the type that actually perform some tasks or define macros. For the list of all modules, check the Modules subdirectory of CMake. One example is a module called FindPythonLibs.cmake, which finds Python libraries and header files on almost every system. If, however, CMake does not find the file you need, you can always specify it in the GUI. If you are used to an Autoconf approach, where you specify configuration options on the command-line, you can use command line access to CMake variables. The following line sets the MYPROJECT_DEBUG variable to OFF:
cmake -DMYPROJECT_DEBUG:BOOL=OFF
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Sponsored by AMD
Built-in forensics, incident response, and security with Red Hat Enterprise Linux 6
Every security policy provides guidance and requirements for ensuring adequate protection of information and data, as well as high-level technical and administrative security requirements for a system in a given environment. Traditionally, providing security for a system focuses on the confidentiality of the information on it. However, protecting the data integrity and system and data availability is just as important. For example, when processing United States intelligence information, there are three attributes that require protection: confidentiality, integrity, and availability.
Learn more about catching the bad guy in this free white paper.
Sponsored by DLT Solutions
| Designing Electronics with Linux | May 22, 2013 |
| Dynamic DNS—an Object Lesson in Problem Solving | May 21, 2013 |
| Using Salt Stack and Vagrant for Drupal Development | May 20, 2013 |
| Making Linux and Android Get Along (It's Not as Hard as It Sounds) | May 16, 2013 |
| Drupal Is a Framework: Why Everyone Needs to Understand This | May 15, 2013 |
| Home, My Backup Data Center | May 13, 2013 |
- I once had a better way I
4 hours 55 min ago - Not only you I too assumed
5 hours 13 min ago - another very interesting
7 hours 6 min ago - Reply to comment | Linux Journal
8 hours 59 min ago - Reply to comment | Linux Journal
15 hours 53 min ago - Reply to comment | Linux Journal
16 hours 9 min ago - Favorite (and easily brute-forced) pw's
18 hours 1 min ago - Have you tried Boxen? It's a
23 hours 52 min ago - seo services in india
1 day 4 hours ago - For KDE install kio-mtp
1 day 4 hours ago
Enter to Win an Adafruit Pi Cobbler Breakout Kit for Raspberry Pi

It's Raspberry Pi month at Linux Journal. Each week in May, Adafruit will be giving away a Pi-related prize to a lucky, randomly drawn LJ reader. Winners will be announced weekly.
Fill out the fields below to enter to win this week's prize-- a Pi Cobbler Breakout Kit for Raspberry Pi.
Congratulations to our winners so far:
- 5-8-13, Pi Starter Pack: Jack Davis
- 5-15-13, Pi Model B 512MB RAM: Patrick Dunn
- 5-21-13, Prototyping Pi Plate Kit: Philip Kirby
- Next winner announced on 5-27-13!
Featured Jobs
| Linux Systems Administrator | Houston and Austin, Texas | Host Gator |
| Senior Perl Developer | Austin, Texas | Host Gator |
| Technical Support Rep | Houston and Austin, Texas | Host Gator |
| UX Designer | Austin, Texas | Host Gator |
| Web & UI Developer (JavaScript & j Query) | Austin, Texas | Host Gator |
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?



Comments
dependencies is an issue
sometimes dependencies not installed because of versions conflict. so you should select exact lib that you need.
SET_SOURCE_FILE_PROPERTIES sh
SET_SOURCE_FILE_PROPERTIES
should be changed to
SET_SOURCE_FILES_PROPERTIES
Re: Cross-Platform Software Development Using CMake
This sounds really cool. I may give CMake a try for my next new project.
Beware of the lack of documentation though...
One inconvenient of CMAKE is that the documentation available online is very brief. If you want to do anything serious with it, I think buying the book is really necessary.
No worse than autohell
The autotools suite suffers from the same lack of clear, simple docs and examples. CMake is at least easy to pick up.
Yep, needs documentation
Seems like a very cool project. I'm trying to pick it up without the book, and I'm having a pretty hard time of it. More publicly available samples of how to do things would go a long way to helping the project reach a critical mass within the community.
You'd think they'd make it more obvious
You can get a fairly comprehensive explanation of a lot of the variables using the command "cmake --help-html > cmake.html" - the resulting file is very useful and quite verbose.
Having said that, this still leaves you badly in need of worked examples.
How about teh KDE4 sources
> this still leaves you badly in need of worked examples
The KDE4 WebSVN might provide quite a few working examples.