Previous Highlights:CMake Hello, WorldCMake VariablesCMake Official Tutorial (Basic Project Setup)CMake Official Tutorial (Library Creation)CMake Official Tutorial (Usage Requirements)CMake Official Tutorial (Installation and Testing)CMake Common Syntax (if Statements)CMake Common Syntax (Cache Variables)CMake Common Syntax (Environment Variables)
The math command in CMake is primarily used to perform simple integer mathematical operations during the build configuration phase, making it particularly useful in scenarios where dynamic value calculations and variable assignments are required.
The command syntax is as follows:
math(EXPR <variable> "<expression>" [OUTPUT_FORMAT <format>])
- • variable: Stores the result of the expression calculation
- • expression: The expression, which must be enclosed in double quotes, supports C-style operators (
<span>+</span>
,<span>-</span>
,<span>*</span>
,<span>/</span>
,<span>%</span>
,<span>|</span>
,<span>&</span>
,<span>^</span>
,<span>~</span>
,<span><<</span>
,<span>>></span>
, and parentheses<span>(...)</span>
) - • OUTPUT_FORMAT (optional): Controls the output format, can be HEXADECIMAL or DECIMAL (default)
The math command has the following limitations:
- 1. Integer-only operations: Floating-point numbers are not supported (e.g.,
<span>3/2=1</span>
) - 2. Value range limitations: The result must be a 64-bit signed integer (range:
<span>-2^63</span>
to<span>2^63-1</span>
) - 3. Complex expressions: Nested operations must use parentheses to clarify precedence, for example
<span>"((a + b) * c) >> 2"</span>
Here is a simple example:
set(expr "(3*10)+5")
math(EXPR out ${expr})
message("${expr}=${out}")
math(EXPR out ${expr} OUTPUT_FORMAT HEXADECIMAL)
message("${expr}=${out}")
The output will be:
(3*10)+5=35
(3*10)+5=0x23
Typical application scenarios are as follows:
Dynamic Version Number Generation
Combining the various parts of the version number (major, minor, patch) into a single value for embedding in code or filenames:
set(MAJOR 2)
set(MINOR 5)
set(PATCH 3)
math(EXPR VERSION_CODE "${MAJOR} * 10000 + ${MINOR} * 100 + ${PATCH}")
message("Version Code: ${VERSION_CODE}") # Outputs 20503
Path or File Offset Calculations
Calculating offsets in file paths, memory alignment, and other scenarios requiring integer operations:
# Calculate the address after memory alignment
set(BASE_ADDR 0x1000)
set(OFFSET 256)
math(EXPR ALIGNED_ADDR "${BASE_ADDR} + (${OFFSET} - ${BASE_ADDR} % ${OFFSET})")
message("Aligned Address: 0x${ALIGNED_ADDR}")
Numeric Configuration of Conditional Compilation Options
Dynamic calculation of macro definitions based on platform or compilation mode:
if(WIN32)
set(PLATFORM_FLAG 0x1)
else()
set(PLATFORM_FLAG 0x2)
endif()
math(EXPR CONFIG_FLAGS "0x8000 | ${PLATFORM_FLAG}" OUTPUT_FORMAT HEXADECIMAL)
add_definitions(-DCONFIG_FLAGS=${CONFIG_FLAG}) # Use CONFIG_FLAGS macro in code
Bit Width Calculation for Platform Adaptation
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(ADDR_BITS 64)
else()
set(ADDR_BITS 32)
endif()
math(EXPR BUFFER_SIZE "${ADDR_BITS} * 1024") # 64-bit system sets to 65536, 32-bit sets to 32768