Yashwant kumar
Yashwant kumar

Reputation: 119

How to use macro in cmake?

I am trying to use the given macro for compiling my C++ program?

MACRO(HEADER_DIRECTORIES return_list)
    FILE(GLOB_RECURSE new_list *.h)
    SET(dir_list "")
    FOREACH(file_path ${new_list})
        GET_FILENAME_COMPONENT(dir_path ${file_path} PATH)
        SET(dir_list ${dir_list} ${dir_path})
    ENDFOREACH()
    LIST(REMOVE_DUPLICATES dir_list)
    SET(${return_list} ${dir_list})
ENDMACRO()

Can someone tell me how to pass parameter to the micro ans use the return list for including directories?

Upvotes: 4

Views: 3178

Answers (1)

ataraxis
ataraxis

Reputation: 1582

You can call a function (or macro) like in C, using its name. The name is defined by the first string inside the parenthesis - therefore you call your macro like that:

header_directories(...)

Your macro expects a single argument - a variable - therefore your CMakeLists.txt will look like:

cmake_minimum_required(VERSION 3.13)


macro(header_directories return_list)

    file(GLOB_RECURSE new_list *.h)
    set(dir_list "")

    foreach(file_path ${new_list})
        get_filename_component(dir_path ${file_path} PATH)
        set(dir_list ${dir_list} ${dir_path})
    endforeach()

    list(REMOVE_DUPLICATES dir_list)
    set(${return_list} ${dir_list})

endmacro()


header_directories(foobar_list)
message(${foobar_list})

In a directory which looks like the following

CMakeLists.txt
include/
    foo.h

the output will look like the following:

$ cmake .
/.../directoryname/include
-- Configuring done
-- Generating done
-- Build files have been written to: /.../directoryname/

If you now want to use the list, generated by your macro, for including those directories, simply use

include_directories(${foobar_list})

or, even better

target_include_directories(<target> <INTERFACE|PUBLIC|PRIVATE> ${foobar_list})

Please be aware that functions and macros in CMake do not support classic return values - in the sense you may be used to by using C.

In macros you can simply create a new variable (or use one which is passed as an argument - as above), in functions you can use the PARENT_SCOPE keyword to write something to a passed variable of the caller:

function(func result_variable)
    set(${result_variable} "result" PARENT_SCOPE)
endfunction()

func(ret)
message(${ret})

Upvotes: 2

Related Questions