Function vs. Macro in CMake

前端 未结 5 2073
执念已碎
执念已碎 2020-12-12 14:45

The official document of CMake 2.8.12 says about macro

When it is invoked, the commands recorded in the macro are first modified by rep

5条回答
  •  难免孤独
    2020-12-12 15:18

    The macro expansion, answered by Yantao Xie really opens my eyes!

    I also found the tutorial below comes with some concrete examples, which is helpful to understand the variable scope concept.

    Cited from Learn cmake in 15 mins:

    In CMake, you can use a pair of function/endfunction commands to define a function. Here’s one that doubles the numeric value of its argument, then prints the result:

    function(doubleIt VALUE)
        math(EXPR RESULT "${VALUE} * 2")
        message("${RESULT}")
    endfunction()
    
    doubleIt("4")                           # Prints: 8
    

    Functions run in their own scope. None of the variables defined in a function pollute the caller’s scope. If you want to return a value, you can pass the name of a variable to your function, then call the set command with the special argument PARENT_SCOPE:

    function(doubleIt VARNAME VALUE)
        math(EXPR RESULT "${VALUE} * 2")
        set(${VARNAME} "${RESULT}" PARENT_SCOPE)    # Set the named variable in caller's scope
    endfunction()
    
    doubleIt(RESULT "4")                    # Tell the function to set the variable named RESULT
    message("${RESULT}")                    # Prints: 8
    

    Similarly, a pair of macro/endmacro commands defines a macro. Unlike functions, macros run in the same scope as their caller. Therefore, all variables defined inside a macro are set in the caller’s scope. We can replace the previous function with the following:

    macro(doubleIt VARNAME VALUE)
        math(EXPR ${VARNAME} "${VALUE} * 2")        # Set the named variable in caller's scope
    endmacro()
    
    doubleIt(RESULT "4")                    # Tell the macro to set the variable named RESULT
    message("${RESULT}")                    # Prints: 8
    

    Both functions and macros accept an arbitrary number of arguments. Unnamed arguments are exposed to the function as a list, through a special variable named ARGN.

    Here’s a function that doubles every argument it receives, printing each one on a separate line:

    function(doubleEach)
        foreach(ARG ${ARGN})                # Iterate over each argument
            math(EXPR N "${ARG} * 2")       # Double ARG's numeric value; store result in N
            message("${N}")                 # Print N
        endforeach()
    endfunction()
    
    doubleEach(5 6 7 8)                     # Prints 10, 12, 14, 16 on separate lines
    

提交回复
热议问题