Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

cmake check if Mac OS X, use APPLE or ${APPLE}

Tags:

cmake

I would like check whether I am in Mac OS X or not, and have the following code

cmake_minimum_required (VERSION 3.0)
project (test)
set (FOO 1)
if (${FOO} AND ${APPLE})
  message ("MAC OS X")
endif ()

It failed on non-OSX system with error message

CMake Error at CMakeLists.txt:4 (if):
  if given arguments:

    "1" "AND"

  Unknown arguments specified

If I replace ${APPLE} with APPLE, the error went away. But I am a little puzzled by this. When should we refer to a variable with ${VAR} and when should we not to?

Thanks in advance.

like image 856
Ying Xiong Avatar asked Dec 26 '14 17:12

Ying Xiong


2 Answers

Not 100% relevant but when googling for how to check for OSx in CMake this is the top post. For others who land here asking the same question this worked for me.

if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
    set(MACOSX TRUE)
endif()
like image 191
Matthew Hoggan Avatar answered Sep 26 '22 03:09

Matthew Hoggan


To put it shortly: Everything inside the if parentheses is evaluated as an expression, this is the semantic of the if keyword. So if you put APPLE there, it gets evaluated as a variable name and yields the correct result.

Now if you put ${APPLE} there, ${} will evaluate its contents before if evaluates the expression. Therefore, it's the same as if you'd written

if (1 AND )

(in the case that the variable APPLE isn't set, which is the case on non-OSX systems). This is invalid syntax and yields the error you get. You should write:

if (FOO AND APPLE)

Quoting from the CMake Documentation:

The if command was written very early in CMake’s history, predating the ${} variable evaluation syntax, and for convenience evaluates variables named by its arguments as shown in the above signatures. Note that normal variable evaluation with ${} applies before the if command even receives the arguments. Therefore code like:

set(var1 OFF)
set(var2 "var1")
if(${var2})

appears to the if command as:

if(var1)

and is evaluated according to the if() case documented above. The result is OFF which is false. However, if we remove the ${} from the example then the command sees:

if(var2)

which is true because var2 is defined to “var1” which is not a false constant.

like image 34
flyx Avatar answered Sep 25 '22 03:09

flyx