Cmake (cmake)
Cmake Use tutorial (1) – start
Cmake Tutorial 2 – Adding libraries
Cmake use tutorial (3) – installation, testing, system self – check
Cmake Use tutorial (4) – file generator
Cmake Use tutorial (5) -cpack generate installation package
Cmake Use tutorial (6) – lousy syntax
Cmake Use Tutorial (7) – Processes and loops
Cmake: Macro and Function
This series of articles was translated from the official Cmake tutorial: CMake Tutorial.
Example program address: github.com/rangaofei/t…
It will not stop at the official tutorial. I as an Android developer, is really no Linux C program development experience, hope big guys forgive. The tutorial is done on MacOS, and I’ve tested most Linux as well, so IF there are special instructions, I’ll note them. This tutorial is based on cmake-3.10.2 and assumes that you have cmake installed.
The process to judge
Process judgment in Cmake is relatively simple and close to C language.
The form is as follows:
if(expression)
# then section.
COMMAND1(ARGS ...)
COMMAND2(ARGS ...)
#...
elseif(expression2)
# elseif section.
COMMAND1(ARGS ...)
COMMAND2(ARGS ...)
#...
else(expression)
# else section.
COMMAND1(ARGS ...)
COMMAND2(ARGS ...)
#...
endif(expression)
Copy the code
One caveat here: Else and Endif expressions can be omitted. At Beth Israel I have to add a SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS) to cover all of the expressions. I don’t have an API for that variable. That’s why I don’t even write it.
If expressions can be long, in order of precedence:
> EXISTS, COMMAND, DEFINED
> EQUAL, LESS, LESS_EQUAL, GREATER, GREATER_EQUAL, STREQUAL, STRLESS, STRLESS_EQUAL, STRGREATER, STRGREATER_EQUAL, VERSION_EQUAL, VERSION_LESS, VERSION_LESS_EQUAL, VERSION_GREATER, VERSION_GREATER_EQUAL, MATCHES
> NOT,AND,OR
Copy the code
This is a long list, but it doesn’t contain much:
expression | true | false | instructions |
---|---|---|---|
<constant> | 1, ON, YES, TRUE, Y, or a non-zero number | 0, OFF, NO, FALSE, N, IGNORE, NOTFOUND, empty string, or with the suffix -notfound | Boolean judgment values are case-insensitive |
<variable|string> | A variable that has been defined and is not false | Undefined or false variable | Variables are strings |
<NOT expression> | Expression is false | Expression is true | |
AND | Both conditions are true | At least one of them is false | |
COMAND command-name | A defined command,macro, or function | undefined | |
POLICY policy-id | The policy is | The policy was not found | In the form of CMP |
TARGET target-name | Targets have been defined with add_executable(), add_library(), or add_custom_target() | undefined | |
TEST test-name | Add_test () Specifies the name of the test that was created | Did not create | |
EXISTS path-to-file-or-directory | The file or path exists | File or path does not exist | This is the full path |
file1 IS_NEWER_THAN file2 | The timestamp of file1 is greater than that of file2 One of the files does not exist Both files have the same timestamp |
Other situations | The file path must be the full path |
IS_DIRECTORY path-to-directory | The given variable is a folder | Not a folder | The full path |
IS_SYMLINK file-name | Variables are links | not | The full path |
IS_ABSOLUTE path | Is the absolute path | not | |
<variable|string> MATCHES regex | The regular expression is successfully matched | Matching failure | |
<variable|string> LESS <variable|string> | The given variables are numbers and the left is less than the right | The left is bigger than the right | Used to compare the size of numbers LESS: LESS than GREATER. Is EQUAL to EQUAL: GREATER_EQUAL: indicates that the value must be greater than or equal to LESS_EQUAL: indicates that the value must be smaller than or equal to |
<variable|string> STRLESS <variable|string> | Lexicographically the left is less than the right | The left is bigger than the right | Used to compare strings LESS: LESS than STRGREATER: greater than STREQUAL: equal to STRLESS_EQUAL: the value must be less than or equal to STRGREATER_EQUAL: the value must be greater than or equal to |
<variable|string> VERSION_LESS <variable|string> | The version number on the left is smaller than the version number on the right | Is greater than | Used for comparison of version numbers LESS: LESS than VERSION_GREATER: greater than VERSION_EQUAL: equal to VERSION_LESS_EQUAL: the value must be smaller than or equal to VERSION_GREATER_EQUAL: the value must be greater than or equal to |
<variable | string> IN_LIST | The item on the right has the left | There is no |
DEFINED | Defined variable | Undefined variable | |
(expr1) AND (expr2 OR (expr3)) | One is true and at least one of two or three is true | Other situations |
In an if expression, you don’t need to use ${var} to get the value of the variable. For example, set two variables and compare the values:
set(var1 OFF)
set(var2 "var1")
Copy the code
If (var2) = false; if(var1) = false; If (${var2}) = if(${var1});
The foreach loop
1. First form
foreach(loop_var arg1 arg2 ...) COMMAND1(ARGS ...) COMMAND2(ARGS ...) . endforeach(loop_var)Copy the code
Note here that the variables of endforeach(loop_var) should not be omitted, because foreach loops rely on variables to break out of the loop.
All commands between foreach and matching endforeach are logged and not called. Once endforeach is found, the original logging command is executed. Before each iteration of the loop, ${loop_var} is set to a variable with the current value in the list.
foreach(i 0 1 2 3)
message(STATUS "current is ${i}")
endforeach(i)
message(STATUS "end")
endforeach(i)
Copy the code
A simple loop, but with an extra endforeach. Look at the results
Those who qualify can qualify can qualify onto university. ➜ StepTest git:(master) qualify cmake -p foreach. Cmake -- current is 0 -- current is 1 -- current is 2 -- current is 3 -- end CMake Error at foreach.cmake:5 (endforeach): endforeach An ENDFOREACH command was found outside of a proper FOREACH ENDFOREACH structure. Or its arguments did not match the opening FOREACH command.Copy the code
An error. No matching foreach.
2. The second form
foreach(loop_var RANGE total)
Copy the code
From 0 to the end of total (including total)
foreach(i RANGE 3)
message(STATUS "current is ${i}")
endforeach(i)
Copy the code
The range will be 0-3, check the result:
Those who qualify can qualify can qualify onto university. ➜ StepTest git:(master) qualify cmake -p foreach. Cmake -- current is 0 -- current is 1 -- current is 2 -- current is 3Copy the code
3. The Third form
foreach(loop_var RANGE start stop [step])
Copy the code
The value from start until the end of stop can be set to step.
foreach(i RANGE 0 3 1)
message(STATUS "current is ${i}")
endforeach(i)
Copy the code
The output is the same as above.
Note that the final result is not greater than the stop value, and the step value is converted to an integer when it is a float
4. Fourth form
foreach(loop_var IN [LISTS [list1 [...]]]
[ITEMS [item1 [...]]])
Copy the code
Also easier, more LIST keyword to loop LIST. Don’t tell.
The while loop
while(condition) COMMAND1(ARGS ...) COMMAND2(ARGS ...) . endwhile(condition)Copy the code
Note that conditions in endwhile are best left out. This condition is the same rule as the expression in if. The loop takes the form of a foreach loop, executing each instruction until it hits endwhile.
In while and foreach loops, use ${var} to fetch the value of a variable. Use “break” and “continue” in the same way as “c”.
In real projects, option is often used with if. Option is relatively simple to use:
option(<option_variable> "help string describing option"
[initial value])
Copy the code
Initial value can only be ON or OFF. If not set, the default value is False. Cmake_dependent_option is a module built into cmake that generates an option dependent on another option. This is a pain in the guts.
Look at a simple example:
include(${CMAKE_ROOT}/Modules/CMakeDependentOption.cmake)
option(USE_CURL "use libcurl" ON)
option(USE_MATH "use libm" ON)
cmake_dependent_option(DEPENT_USE_CURL "this is dependent on USE_CURL" ON "USE_CURL; NOT USE_MATH" OFF)
if(DEPENT_USE_CURL)
message(STATUS "using lib curl")
else(a)message(STATUS "not using lib curl")
endif(a)Copy the code
The first line contains the dependency modules we need.
The second and third lines define two options: USE_CURL,USE_MATH, ON.
This is dependent on USE_CURL; this is dependent on USE_CURL; this is dependent on USE_CURL; If NOT USE_MATH is true, take the front value, otherwise take the back value.
Lines 5-9 are an if statement that prints the desired result.
Output results:
Those who qualify can qualify can qualify onto university. ➜ StepTest git:(master) qualify cmake -p optionc.cmake -- not using lib curlCopy the code