CMake 入门/流程控制

流程控制指令 CMake 也支援一般程式语言常用的流程控制和副程式,因此撰写弹性很大。

条件叙述

编辑

CMake的条件叙述为 if、elseif、else、endif。

# 當 expr 值為下列其中之一時,執行 command1:
#    ON, 1, YES, TRUE, Y
# 當 expr 值為下列其中之一時,執行 command2:
#    OFF, 0, NO, FALSE, N, NOTFOUND, *-NOTFOUND, IGNORE 

if(expr)
    command1(arg)
else(expr)
    command2(arg)
endif(expr) 

版本较早的 CMake 要求在 else(...) 括号内必须填上对应的条件项目,然而很容易造成误导,例如

if(WIN32)
    ...
else(WIN32)
    command2(arg)
endif(WIN32) 

乍看之下会以为 WIN32 为 TRUE 时执行 command2,但原意其实是 WIN32 为 FALSE 才执行 command2 ,因此在较新的版本中已经不强迫了。

# 以下也合法
if(WIN32)
    ...
else()
    command2(arg)
endif() 

条件式计算规则

编辑

条件式的可以透过运算子组合,请参考运算子一章

if((expr) AND (expr OR (expr)))


在条件式当中即使不加 ${},if 也会先尝试解释成变数。

# 下面兩行意義相同
if (foo)
if (${foo})

# 下面兩行意義相同
if (foo AND bar)
if (${foo} AND ${bar})

这里用 if 为例,while 亦为同理。

循环叙述

编辑

CMake 的循环有两种:

  • foreach ... endforeach
  • while ... endwhile
set(V  alpha beta gamma)
message(${V})

foreach(i  ${V})
    message(${i})
endforeach() 

Output:

alphabetagamma
alpha
beta
gamma

函数与巨集

编辑

CMake 有两种设计子程序的方式:

  • function ... endfunction
  • macro ... endmacro

主要的差别在于 function 会建立 local的变数,而 macro 则会影响 global 变数。

# 定義名為 print1 的 macro 

macro(print1 MESSAGE)
    set(k ${MESSAGE})
    message(${MESSAGE})
endmacro(print1)

# 定義名為 print2 的 function
function(print2 MESSAGE)
    set(k ${MESSAGE})
    message(${MESSAGE})
endfunction(print2) 

print1("from print1")
print2("from print2")
message("k=${k}")

輸出結果為
from print1
from print2
k="from print1"