--- language: cmake contributors: - ["Bruno Alano", "https://github.com/brunoalano"] filename: CMake --- CMake is a cross-platform, open-source build system. This tool will allow you to test, compile and create packages of your source code. The problem that CMake tries to solve it's the problem of Makefiles and Autoconfigure on cross-platform (different make interpreters have different command) and the ease-of-use on linking 3rd party libraries. CMake is an extensible, open-source system that manages the build process in an operating system and in a compiler-independent manner. Unlike many cross-platform systems, CMake is designed to be used in conjunction with the native build environment. Simple configuration files placed in each source directory (called CMakeLists.txt files) are used to generate standard build files (e.g., makefiles on Unix and projects/workspaces in Windows MSVC) which are used in the usual way. ```cmake # In CMake, this is a comment # To run our code, we will use these steps: # - mkdir build && cd build # - cmake .. # - make # # With those steps, we will follow the best pratice to compile into a subdir # and the second line will request to CMake to generate a new OS-dependant # Makefile. Finally, run the native Make command. #------------------------------------------------------------------------------ # Basic #------------------------------------------------------------------------------ # # The CMake file MUST be named as "CMakeLists.txt". # Setup the minimum version required of CMake to generate the Makefile cmake_minimum_required (VERSION 2.8) # Raises a FATAL_ERROR if version < 2.8 cmake_minimum_required (VERSION 2.8 FATAL_ERROR) # We setup the name for our project. After we do that, this will change some # directories naming convention genearted by CMake. We can send the LANG of # code as second param project (learncmake C) # Set the project source dir (just convention) set( LEARN_CMAKE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} ) set( LEARN_CMAKE_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR} ) # It's useful to setup the current version of our code in the build system # using a `semver` style set (LEARN_CMAKE_VERSION_MAJOR 1) set (LEARN_CMAKE_VERSION_MINOR 0) set (LEARN_CMAKE_VERSION_PATCH 0) # Send the variables (version number) to source code header configure_file ( "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in" "${PROJECT_BINARY_DIR}/TutorialConfig.h" ) # Include Directories # In GCC, this will invoke the "-I" command include_directories( include ) # Where are the additional libraries installed? Note: provide includes # path here, subsequent checks will resolve everything else set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/CMake/modules/" ) # Conditions if ( CONDITION ) # Output! # Incidental information message(STATUS "My message") # CMake Warning, continue processing message(WARNING "My message") # CMake Warning (dev), continue processing message(AUTHOR_WARNING "My message") # CMake Error, continue processing, but skip generation message(SEND_ERROR "My message") # CMake Error, stop processing and generation message(FATAL_ERROR "My message") endif() if( CONDITION ) elseif( CONDITION ) else( CONDITION ) endif( CONDITION ) # Loops foreach(loop_var arg1 arg2 ...) COMMAND1(ARGS ...) COMMAND2(ARGS ...) ... endforeach(loop_var) foreach(loop_var RANGE total) foreach(loop_var RANGE start stop [step]) foreach(loop_var IN [LISTS [list1 [...]]] [ITEMS [item1 [...]]]) while(condition) COMMAND1(ARGS ...) COMMAND2(ARGS ...) ... endwhile(condition) # Logic Operations if(FALSE AND (FALSE OR TRUE)) message("Don't display!") endif() # Set a normal, cache, or environment variable to a given value. # If the PARENT_SCOPE option is given the variable will be set in the scope # above the current scope. # `set( ... [PARENT_SCOPE])` # How to reference variables inside quoted and unquoted arguments # A variable reference is replaced by the value of the variable, or by the # empty string if the variable is not set ${variable_name} # Lists # Setup the list of source files set( LEARN_CMAKE_SOURCES src/main.c src/imagem.c src/pather.c ) # Calls the compiler # # ${PROJECT_NAME} refers to Learn_CMake add_executable( ${PROJECT_NAME} ${LEARN_CMAKE_SOURCES} ) # Link the libraries target_link_libraries( ${PROJECT_NAME} ${LIBS} m ) # Where are the additional libraries installed? Note: provide includes # path here, subsequent checks will resolve everything else set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/CMake/modules/" ) # Compiler Condition (gcc ; g++) if ( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" ) message( STATUS "Setting the flags for ${CMAKE_C_COMPILER_ID} compiler" ) add_definitions( --std=c99 ) endif() # Check for OS if( UNIX ) set( LEARN_CMAKE_DEFINITIONS "${LEARN_CMAKE_DEFINITIONS} -Wall -Wextra -Werror -Wno-deprecated-declarations -Wno-unused-parameter -Wno-comment" ) endif() ``` ### More Resources + [cmake tutorial](https://cmake.org/cmake-tutorial/) + [cmake documentation](https://cmake.org/documentation/) + [mastering cmake](http://amzn.com/1930934319/)