Programming‎ > ‎Language‎ > ‎C++‎ > ‎

CMake

Documentation is for the weak

CMake is cross-platform build system that use textfiles to create the platform dependent project files.

How to run cmake from commandline
In the directory where you wish to have all your solutions files created run cmake with the generator-name command (-G) and the path to the cmake config file you wish to use. List of generators.

cmake -G "Visual Studio 12" ../src

Display a message
Use the message command to display information to the poor person that try to use your cmake file. The first parameter is the mode and there are a number to choose from such as STATUS, WARNING and FATAL_ERROR.

message(STATUS "Using libs from: ${EXTERNAL_DEPENDENCIES_PATH}")

Solution folders
To enable the use of Solution folders set the global property USE_FOLDERS to ON. Then for each target set the property FOLDER to select what folder or sub folder to put the project in.
   
SET_PROPERTY(GLOBAL PROPERTY USE_FOLDERS ON)       
SET_PROPERTY(TARGET physics PROPERTY FOLDER "Engine")

Custom build types (configurations)
Use CMAKE_CONFIGURATION_TYPES to specify your own custom configuration names. You can then specify per-config properties and variables in the form SOME_VAR_<CONFIG>. So the Developer config properties for CMAKE_RUNTIME_OUTPUT_DIRECTORY can be set with CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEVELOPER. The default configs are DEBUG, RELEASE, MINSIZEREL and RELWITHDEBINFO.

set(CMAKE_CONFIGURATION_TYPES Debug Developer Release CACHE TYPE INTERNAL FORCE)

Create the project
Create the project with the name project() command. It will set the name of the IDE files generated. 

project("ZeroFps")

Local Options
For custom options use include() with OPTIONAL. The file can then contain all the custom variables the user wish to add.

include("zerofps_options.txt" OPTIONAL)          
 
Detect 32 vs 64 bit Build
To detect if it's a 32 bit or 64 bit build check the size of CMAKE_SIZEOF_VOID_P. It will be 8 in 64 bit and 4 in 32 bit.
   
if(CMAKE_SIZEOF_VOID_P MATCHES 8)
   MESSAGE(STATUS "Detected 64-bit platform")   
else()
   MESSAGE(STATUS "Detected 32-bit platform")
endif()

Write to a .bat File
To write to files use the file manipulation command. WRITE creates (overwrites) to a file. APPEND writes more data at the end of a file.

    FILE(TO_NATIVE_PATH  ${QT_ROOT_PATH}  QT_ROOT_PATH)
    set(GET_QT_BIN ${EXECUTABLE_OUTPUT_PATH}/_getqt.bat)
    file(WRITE ${GET_QT_BIN} "copy ${QT_ROOT_PATH}\\QtCore4.dll .\n")
    file(APPEND ${GET_QT_BIN} "copy ${QT_ROOT_PATH}\\QtGui4.dll .\n")

Select Source Files
With the file commands GLOB and GLOB_RECURSE one can get a list of all the files of selected types from a directory and it's sub directory's. Another way is to use the list commands to APPEND the names one select to the list. The list or lists are then used when creating a target, like a exe (see topic below).

    file(GLOB EXULT_EXULT_SRC *.cc *.h)
    file(GLOB_RECURSE EXULT_FILES_SRC files/*.cc files/*.h)
    list(APPEND EXPACK_SRC 
       files/zip/zip.*
    files/zip/unzip.*
    data/crc.h
    )

Source Folders in a target
To sort files inside sub folders of a target use SOURCE_GROUP. First is the folder and next is the directory name of the source files.
   
    SOURCE_GROUP(views\\ssuw ../views/ssuw)
    SOURCE_GROUP(widgets REGULAR_EXPRESSION .*/widgets/.*)

Create a target
To create a executable target use add_executable() or to create a library use add_library(). The name will be the name of the target and the executable and needs to be a globally unique within a project. For a library also list the type as STATIC, SHARED, or MODULE. To add projects from sub directory's with separate cmake files use add_subdirectory(). It is also possible to create a custom build target that do not generate a output file but will always be build. It can run custom commands and sources can be added for convenience in editing them from the IDE even if they have no build rules.

    add_executable(zerofps ${SRC_FILES})        
    add_library(component STATIC ${SRC_FILES})
    add_subdirectory(graymer)
    add_custom_target(
        exult_flx
          COMMAND nmake /f $(solutionDir)../vs12/Makefile.data  build_ex /NOLOGO
          WORKING_DIRECTORY ../
SOURCES ${EXULTFLX_SRC} )

Set the build settings
  • ADD_DEFINITIONS: Add define flags to the source files.
  • CMAKE_CXX_FLAGS: Set the flags used by the compiler.
  • CMAKE_EXE_LINKER_FLAGS: Set the flags used by the linker on executable targets.
  • CMAKE_STATIC_LINKER_FLAGS: Set the flags used by the linker on static libs.
  • CMAKE_SHARED_LINKER_FLAGS: Set the flags used by the linker on dynamic libs.
  • include_directories: Add the given directories to those the compiler uses to search for include files.
  • link_directories: The directories in which the linker will look for libraries
ADD_DEFINITIONS(-DWIN32_LEAN_AND_MEAN)   
ADD_DEFINITIONS(-DZEROFPS_PATH="${ZEROFPS_PATH}")       
set(CMAKE_CXX_FLAGS "/D CONFIG_RELEASE /D NDEBUG /MD /O2 /GL")
set(CMAKE_EXE_LINKER_FLAGS "/INCREMENTAL:NO /LTCG")   
include_directories(${EXTERNAL_DEPENDENCIES_PATH}/win32/include)   
link_directories(${EXTERNAL_DEPENDENCIES_PATH}/win32/lib)

Set Target Build Settings
To change the settings of a selected target use the SET_TARGET_PROPERTIES command. 

SET_TARGET_PROPERTIES(expack PROPERTIES COMPILE_FLAGS "/FImsvc_kludges.h")
SET_TARGET_PROPERTIES(exult PROPERTIES COMPILE_DEFINITIONS "EXULT")

Select where to put built files
The four kinds of built files are Archive (.lib), library, runtime (.exe/.dll) and pdb (.pdb files for for visual studio). There is one CMAKE variable for each. When a target is created they will be used to initialize the target property with the same name without the CMAKE_ at the start. So a .exe will have a RUNTIME_OUTPUT_DIRECTORY property.

.lib    CMAKE_ARCHIVE_OUTPUT_DIRECTORY
.dll    CMAKE_LIBRARY_OUTPUT_DIRECTORY
.exe    CMAKE_RUNTIME_OUTPUT_DIRECTORY
.pdb    CMAKE_PDB_OUTPUT_DIRECTORY

There is also configuration variables for each of them that have the same name but with _[CONFIG] in the end. So if there is a config called Fish there will be a
CMAKE_RUNTIME_OUTPUT_DIRECTORY_FISH. Multi-configuration generators (like visual studio) append a per-configuration subdirectory to CMAKE_RUNTIME_OUTPUT_DIRECTORY but not to MAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE.

Change settings on a target

set_target_properties( targets PROPERTIES RUNTIME_OUTPUT_DIRECTORY "zerofps/bin")

Reference
Comments