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
Cmake Use Tutorial (9) – About android cross compilation
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.
Cmake has two similar keywords, macro and function. Both of these create a piece of code with a name that you can call later, and you can pass arguments.
Macro is the same as function
The macro form is as follows:
macro(<name> [arg1 [arg2 [arg3 ...]]]) COMMAND1(ARGS ...) COMMAND2(ARGS ...) .endmacro(<name>)
Copy the code
Function form is as follows:
function(<name> [arg1 [arg2 [arg3 ...]]]) COMMAND1(ARGS ...) COMMAND2(ARGS ...) .function(<name>)
Copy the code
Define a macro (function) named name, arg1… Is the parameter passed in. In addition to using ${arg1} to reference variables, the system provides us with some special variables:
variable | instructions |
---|---|
ARGV# | # is a subscript, 0 refers to the first argument, sum |
ARGV | All definitions are required to pass in parameters |
ARGN | For example, if one macro (function) is required and three are entered, the remaining two are stored as an array in ARGN |
ARGC | The number of actual arguments passed, that is, the number of arguments passed to the calling function |
Macro The difference between a macro definition and a function
Macro arguments such as ARGN and ARGV are not variables in the usual CMake sense. They are string substitutions, much like the C preprocessor does with macros. Therefore, the following command is incorrect:
if(ARGV1) # ARGV1 is not a variable
if(DEFINED ARGV2) # ARGV2 is not a variable
if(ARGC GREATER 2) # ARGC is not a variable
foreach(loop_var IN LISTS ARGN) # ARGN is not a variable
Copy the code
The correct way to write it is as follows:
if(${ARGV1})
if(DEFINED ${ARGV2})
if(${ARGC} GREATER 2)
foreach(loop_var IN LISTS ${ARGN})
or
set(list_var "${ARGN}")
foreach(loop_var IN LISTS list_var)
Copy the code
A simple example
macro(FOO arg1 arg2 arg3)
message(STATUS "this is arg1:${arg1},ARGV0=${ARGV0}")
message(STATUS "this is arg2:${arg2},ARGV1=${ARGV1}")
message(STATUS "this is arg3:${arg3},ARGV2=${ARGV2}")
message(STATUS "this is argc:${ARGC}")
message(STATUS "this is args:${ARGV},ARGN=${ARGN}")
if(arg1 STREQUAL one)
message(STATUS "this is arg1")
endif(a)if(ARGV2 STREQUAL "two")
message(STATUS "this is arg2")
endif(a)set(${arg1} nine)
message(STATUS "after set arg1=${${arg1}}")
endmacro(FOO)
function(BAR arg1)
message(STATUS "this is arg1:${arg1},ARGV0=${ARGV0}")
message(STATUS "this is argn:${ARGN}")
if(arg1 STREQUAL first)
message(STATUS "this is first")
endif(a)set(arg1 ten)
message(STATUS "after set arg1=${arg1}")
endfunction(BAR arg1)
set(p1 one)
set(p2 two)
set(p3 three)
set(p4 four)
set(p5 five)
set(p6 first)
set(p7 second)
FOO(${p1} ${p2} ${p3} ${p4} ${p5})
BAR(${p6} ${p7})
message(STATUS "after bar p6=${p6}")
Copy the code
The output is as follows:
-- this is arg1:one,ARGV0=one -- this is arg2:two,ARGV1=two -- this is arg3:three,ARGV2=three -- this is argc:5 -- this is args:one; two; three; four; five,ARGN=four; five -- after set arg1=nine -- this is arg1:first,ARGV0=first -- this is argn:second -- this is first -- after set arg1=ten -- after bar p6=firstCopy the code
Here’s an example that makes our eggs break. I don’t want to use cmake:
macro(_bar)
foreach(arg IN LISTS ARGN)
message(STATUS "this is in macro ${arg}")
endforeach(a)endmacro(a)function(_foo)
foreach(arg IN LISTS ARGN)
message(STATUS "this in function is ${arg}")
endforeach()
_bar(x y z)
endfunction()
_foo(a b c)
Copy the code
Look at the output:
-- this in function is a
-- this in function is b
-- this in function is c
-- this is in macro a
-- this is in macro b
-- this is in macro c
Copy the code
Foreach (arg IN LISTS ${ARGN}) foreach(arg IN LISTS ${ARGN}) foreach(arg IN LISTS ${ARGN})
-- this in function is a
-- this in function is b
-- this in function is c
Copy the code
No output information in _bar. Why? Because the scope of this ARGN is in function, which is the ARGN in _foo. If you’re interested, try calling function from your Macro.