learnxinyminutes-docs/cmake.md

179 lines
5.2 KiB
Markdown
Raw Permalink Normal View History

---
category: tool
name: CMake
contributors:
- ["Bruno Alano", "https://github.com/brunoalano"]
filename: CMake
---
2020-02-27 20:32:44 +00:00
CMake is a cross-platform, open-source build system. This tool allows you to test,
compile, and create packages of your source code.
2020-02-27 20:32:44 +00:00
The problem that CMake tries to solve is the problem of Makefiles and
Autoconfigure on cross-platforms (different make interpreters have different
commands) and the ease-of-use on linking 3rd party libraries.
2020-02-27 20:32:44 +00:00
CMake is an extensible, open-source system that manages the build process in
an operating system and compiler-agnostic 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
2020-02-27 20:32:44 +00:00
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
2020-02-27 20:32:44 +00:00
# To run our code, please perform the following commands:
# - mkdir build && cd build
# - cmake ..
# - make
#
2017-08-23 08:14:39 +00:00
# With those steps, we will follow the best practice to compile into a subdir
# and the second line will request to CMake to generate a new OS-dependent
# 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)
2020-02-27 20:32:44 +00:00
# We define the name of our project, and this changes some directories
# naming convention generated by CMake. We can send the LANG of code
# as the 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} )
2020-02-27 20:32:44 +00:00
# It's useful to set up 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)
2020-02-27 20:32:44 +00:00
# Send the variables (version number) to the 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()
2020-02-27 20:32:44 +00:00
# Set a regular, 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(<variable> <value>... [PARENT_SCOPE])`
2020-02-27 20:32:44 +00:00
# How to reference variables inside quoted and unquoted arguments?
# A variable reference is replaced by either the variable value 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
2020-02-27 20:32:44 +00:00
+ [CMake tutorial](https://cmake.org/cmake-tutorial/)
+ [CMake documentation](https://cmake.org/documentation/)
+ [Mastering CMake](http://amzn.com/1930934319/)
+ [An Introduction to Modern CMake](https://cliutils.gitlab.io/modern-cmake/)