You are on page 1of 27

CMake – Cross-Platform, Effective

Build System

King, 2011/4/18

Classification 4/18/2011 1
Build Systems under different OS
• Windows
– Microsoft Visual Studio
– Other IDES **
• Linux/FreeBSD

– Custom GNU/Makefiles
– Autotools (autoconf/automake)
• MacOS
– Xcode
GNU Build System
Developer User

source codes

autoconf configure ./configure


autoscan
Check necessary
libraries and
generate Makefile

configure.ac aclocal aclocal.m4

Makefile

autoheader config.h.in Use make to build &


install

Makefile.am automake Makefile.in make install


If need to build cross-platform
project…
• MS VS just work on Windows…
• Makefiles don’t work on Windows…
• Autotools is a little complicated…
• Xcode just work for Apple System…

So You have to
– Use different build system under different
platform?
Or
– Other solution?
CMake
• Open Source with complete online reference
manual
• One configuration, run every platform
– Windows, Linux/BSD, MacOS
• Can generate build control/project files
– Windows: MS VS workspace
– Linux/BSD: Makefile/KDevelop
– MacOS: XCode
• Simple Script Syntax to allow customization
• Used by Many Large Projects
– KDE4 (switch to CMake since 1996)
– Boost
– MySQL
– Others:
http://www.cmake.org/Wiki/CMake_Projects
CMake Build System

Cmake Build System

Native Build
CMakeLists.txt cmake
System

Executables Native Build


& Libraries Tools
Source Tree Structure
Folder to place 3rd package

Folder to place generated executables


Folder to place generated libraries
Folder to place build script/cache
Folder to place source codes

Each module,executable and src


folder need CMakeLists.txt file.

src/CMakeLists.txt
module1/CMakeLists.txt
module2/CMakeLists.txt
main_executable/CMakeLists.txt
Using CMake -- Command
• Create a build directory (“out-of-source-build”
concept)
– mkdir make ; cd make
• Configure the package for your system:
– cmake [options] <source_tree>
• Build the package:
– make
• Install it:
– make install
• The last 2 steps can be merged into one (just
“make install”)
Using CMake -- GUI
• Modify configure by UI
– Windows: CMakeSetup
– Linux/BSD: ccmake
CMakeLists.txt Files
• Very simple syntax:
– # This is a comment
– Commands syntax: COMMAND( arg1 arg2 ... )
– Lists A;B;C # semi-colon separated values
– Variables ${VAR}
– Conditional constructs
• IF() ... ELSE()/ELSEIF() ... ENDIF()
• Very useful: IF( APPLE ); IF( UNIX ); IF( WIN32 )
– WHILE() ... ENDWHILE()
– FOREACH() ... ENDFOREACH()
– Regular expressions (check CMake FAQ for details...)
CMakeLists.txt Files (Cont.)
• INCLUDE_DIRECTORIES( “dir1” “dir2” ... )
• AUX_SOURCE_DIRECTORY( “source” )
• ADD_EXECUTABLE
• ADD_LIBRARY
• ADD_CUSTOM_TARGET
• ADD_DEPENDENCIES( target1 t2 t3 ) # target1 depends on t2 and t3
• ADD_DEFINITIONS( “-Wall -ansi -pedantic”)
• TARGET_LINK_LIBRARIES( target-name lib1 lib2 ...) # Individual settings for each
target
• LINK_LIBRARIES( lib1 lib2 ...) # All targets link with the same set of libs
• SET_TARGET_PROPERTIES( ... ) # lots of properties... OUTPUT_NAME,
VERSION, ....
• MESSAGE( STATUS|FATAL_ERROR “message” )
• INSTALL( FILES “f1” “f2” “f3” DESTINATION . )
– – DESTINATION relative to ${CMAKE_INSTALL_PREFIX}
CMakeLists.txt Files (Cont.)
• SET( VAR value [CACHE TYPE DOCSTRING [FORCE]])
• LIST( APPEND|INSERT|LENGTH|GET|REMOVE_ITEM|REMOVE_AT|SORT ...)
• STRING( TOUPPER|TOLOWER|LENGTH|SUBSTRING|REPLACE|REGEX ...)
• SEPARATE_ARGUMENTS( VAR ) # convert space separated string to list
• FILE( WRITE | READ | APPEND | GLOB | GLOB_RECURSE | REMOVE |
MAKE_DIRECTORY ...)
• FIND_FILE
• FIND_LIBRARY
• FIND_PROGRAM
• FIND_PACKAGE
• EXEC_PROGRAM( bin [work_dir] ARGS <..> [OUTPUT_VARIABLE var] [RETURN_VALUE
var] )
• ● OPTION( OPTION_VAR “description string” *initial value+ )
CMake Tutorial
• Set Project Information

• Add preprocesser macro and flag for different


Platform

• Check 3rd Package

• Generate libraries (sub modules)

• Generate executable
CMakeList.txt Template (Top Level)
• ##------------------------------------------------------------------------------------
• ## set minimum required version number of cmake
• ##------------------------------------------------------------------------------------
• CMAKE_MINIMUM_REQUIRED(VERSION 2.8)

• ##------------------------------------------------------------------------------------
• ## set the project name
• ##------------------------------------------------------------------------------------
• PROJECT(TEST_PROJECT)

• ##------------------------------------------------------------------------------------
• ## set the version of generated libraries
• ##------------------------------------------------------------------------------------
• SET (PROJECT_LIB_VERSION 1.0)
• SET (PROJECT_LIB_SOVERSION 1)

• ##------------------------------------------------------------------------------------
• ## set the folder to hold target binary/libraries
• ##------------------------------------------------------------------------------------
• SET (PROJECT_OUTPUT_BIN_DIR ${PROJECT_SOURCE_DIR}/../bin)
• SET (PROJECT_OUTPUT_LIB_DIR ${PROJECT_SOURCE_DIR}/../lib)
CMakeList.txt Template (Top Level)

cont.
##------------------------------------------------------------------------------------
• ## add preprocesser macro and compile flag for different platform
• ##------------------------------------------------------------------------------------
• IF (CMAKE_SYSTEM_NAME STREQUAL "Windows")
• ADD_DEFINITIONS(-DDEBUG)
• SET (CMAKE_CXX_FLAGS "-O2")

• ELSEIF (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")


• ADD_DEFINITIONS(-DFreeBSD -DDEBUG)
• SET (CMAKE_CXX_FLAGS "-g -Wall -O0")

• ELSEIF (CMAKE_SYSTEM_NAME STREQUAL "Linux")


• ADD_DEFINITIONS(-DLinux -DDEBUG)
• SET (CMAKE_CXX_FLAGS "-g -Wall -O0")

• ELSE (CMAKE_SYSTEM_NAME STREQUAL "Windows")


• MESSAGE(STATUS "[INFO] Not supported OS: " ${CMAKE_SYSTEM_NAME})

• ENDIF (CMAKE_SYSTEM_NAME STREQUAL "Windows")


CMakeList.txt Template (Top Level)

cont.
##------------------------------------------------------------------------------------
• ## check if exist 3rd package: STLSoft
• ##------------------------------------------------------------------------------------
• INCLUDE(FindSTLSoft.cmake)
• IF (NOT STLSOFT_FOUND)
• SET(STLSOFT_MAKE_DIR "${PROJECT_SOURCE_DIR}\\..\\3rd_package\\stlsoft")
• IF (CMAKE_SYSTEM_NAME STREQUAL "Windows")
• STRING(REPLACE / \\ STLSOFT_MAKE_DIR "${STLSOFT_MAKE_DIR}")
• ADD_CUSTOM_COMMAND (
• OUTPUT stlsoft
• COMMAND chdir /d "${STLSOFT_MAKE_DIR}" && make\\build.bat)
• ADD_CUSTOM_TARGET (stlsoft__TARGET DEPENDS stlsoft)
• ELSE (CMAKE_SYSTEM_NAME STREQUAL "Windows")
• ADD_CUSTOM_COMMAND (
• OUTPUT stlsoft
• COMMAND cd STLSOFT_MAKE_DIR && ./make/build.sh)
• ADD_CUSTOM_TARGET (stlsoft__TARGET ALL DEPENDS stlsoft)
• ENDIF (CMAKE_SYSTEM_NAME STREQUAL "Windows")
• ENDIF (NOT STLSOFT_FOUND)
CMakeList.txt Template (Top Level)

cont.
##------------------------------------------------------------------------------------
• ## add depended modules folders and compile them
• ##------------------------------------------------------------------------------------
• SET (LOCAL_LIB_LIST
• module1
• module2
• )

• ## add local generated libraries to compile
• FOREACH (LIB_NAME ${LOCAL_LIB_LIST})
• ADD_SUBDIRECTORY(${PROJECT_SOURCE_DIR}/${LIB_NAME})
• ENDFOREACH(LIB_NAME ${LOCAL_LIB_LIST})

• ##------------------------------------------------------------------------------------
• ## add executable folder to compile it
• ##------------------------------------------------------------------------------------
• ADD_SUBDIRECTORY(${PROJECT_SOURCE_DIR}/main_executable)
CMakeList.txt Template (Library)
• ##------------------------------------------------------------------------------------
• ## set the module name, the name MUST be same as the folder name
• ##------------------------------------------------------------------------------------
• SET (TARGET_NAME module1)

• ##------------------------------------------------------------------------------------
• ## add header file folder to compile this module
• ##------------------------------------------------------------------------------------
• INCLUDE_DIRECTORIES(include)

• ##------------------------------------------------------------------------------------
• ## set the source files list
• ##------------------------------------------------------------------------------------
• AUX_SOURCE_DIRECTORY(src SRC_LIST)

• ##------------------------------------------------------------------------------------
• ## set the target path for generate library
• ##------------------------------------------------------------------------------------
• SET(LIBRARY_OUTPUT_PATH ${PROJECT_OUTPUT_LIB_DIR})
CMakeList.txt Template (Library) Cont.
• ##------------------------------------------------------------------------------------
• ## set the install target and create shared library: .so for non-windows
• ##------------------------------------------------------------------------------------
• IF (CMAKE_SYSTEM_NAME STREQUAL "Windows")
• ## for windows, just create .lib
• ADD_LIBRARY(${TARGET_NAME} STATIC ${SRC_LIST})
• INSTALL(TARGETS ${TARGET_NAME}
• ARCHIVE DESTINATION lib)
• ELSE (CMAKE_SYSTEM_NAME STREQUAL "Windows")
• ## for non-windows, will create both .a and .so
• ADD_LIBRARY(${TARGET_NAME}_static STATIC ${SRC_LIST})
• SET_TARGET_PROPERTIES(${TARGET_NAME}_static PROPERTIES OUTPUT_NAME ${TARGET_NAME})
• ADD_LIBRARY(${TARGET_NAME} SHARED ${SRC_LIST})
• SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES VERSION 1.0 SOVERSION 1)
• INSTALL(TARGETS ${TARGET_NAME} ${TARGET_NAME}_static
• LIBRARY DESTINATION lib
• ARCHIVE DESTINATION lib)
• ENDIF (CMAKE_SYSTEM_NAME STREQUAL "Windows")
CMakeList.txt Template (Executable)
• ##------------------------------------------------------------------------------------
• ## add header file folder to compile this module
• ##------------------------------------------------------------------------------------
• INCLUDE_DIRECTORIES(include)
• INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/../3rd_package/stlsoft/include)

• ## check if set the library folder, if yes, use such folder as link folder
• IF(DEFINED PROJECT_OUTPUT_LIB_DIR)
• LINK_DIRECTORIES(${PROJECT_OUTPUT_LIB_DIR})
• ENDIF(DEFINED PROJECT_OUTPUT_LIB_DIR)

• ##------------------------------------------------------------------------------------
• ## set the source files.
• ##------------------------------------------------------------------------------------
• AUX_SOURCE_DIRECTORY(src SRC_LIST)
• ##------------------------------------------------------------------------------------
• ## set the output folder.
• ##------------------------------------------------------------------------------------
• SET (EXECUTABLE_OUTPUT_PATH ${PROJECT_OUTPUT_BIN_DIR})
CMakeList.txt Template (Executable) Cont.

• ##------------------------------------------------------------------------------------
• ## let cmake compile the target
• ##------------------------------------------------------------------------------------
• ADD_EXECUTABLE(${TARGET_NAME} ${SRC_LIST})

• ##------------------------------------------------------------------------------------
• ## set the link library: -llibrary
• ##------------------------------------------------------------------------------------
• TARGET_LINK_LIBRARIES(${TARGET_NAME} ${LINK_LOCAL_LIB_LIST} ${LINK_SYSTEM_LIB_LIST})

• ##------------------------------------------------------------------------------------
• ## add dependencies
• ##------------------------------------------------------------------------------------
• ADD_DEPENDENCIES(${TARGET_NAME} ${LINK_LOCAL_LIB_LIST} stlsoft__TARGET)

• ##------------------------------------------------------------------------------------
• ## set install parth
• ##------------------------------------------------------------------------------------
• INSTALL(TARGETS ${TARGET_NAME}
• RUNTIME DESTINATION bin)
Work Together

Demo
Summary
 Build System

 CMake Introduction

 CMake Tutorial

Classification 4/18/2011 23
Q&A
THANK YOU!

Classification 4/18/2011 25
Classification 4/18/2011 26
Reference
• [1] CMake: http://www.cmake.org/
– Include: Document, Wiki, FAQ, etc
• [2] CMake Tutorial, Jan Engels, 2007
• [3] 猫也会的CMake, Jim Huang, 2008
• [4] CMake - Cross-Platform Make, R. Douglas Barbieri, 2009
• [5] CMake Practice, Cjacker, 2009
• [6] STLSoft: http://www.stlsoft.org
• [7] GNU build system: http://en.wikipedia.org/wiki/GNU_build_system
• [8] Build System:
http://en.wikipedia.org/wiki/Comparison_of_integrated_development_environments#C.2F
C.2B.2B
• [9] CMake API: http://www.scintilla.org/cmake.api

Classification 4/18/2011 27