mirror of
https://github.com/adambard/learnxinyminutes-docs.git
synced 2024-11-25 20:14:30 +03:00
179 lines
5.2 KiB
Markdown
179 lines
5.2 KiB
Markdown
---
|
|
category: tool
|
|
tool: cmake
|
|
contributors:
|
|
- ["Bruno Alano", "https://github.com/brunoalano"]
|
|
filename: CMake
|
|
---
|
|
|
|
CMake is a cross-platform, open-source build system. This tool allows you to test,
|
|
compile, and create packages of your source code.
|
|
|
|
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.
|
|
|
|
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
|
|
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, please perform the following commands:
|
|
# - mkdir build && cd build
|
|
# - cmake ..
|
|
# - make
|
|
#
|
|
# 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)
|
|
|
|
# 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} )
|
|
|
|
# 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)
|
|
|
|
# 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()
|
|
|
|
# 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])`
|
|
|
|
# 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
|
|
|
|
+ [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/)
|