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