Barry
Barry

Reputation: 302842

Use CMAKE_CURRENT_LIST_DIR, in a function

I have a CMakeLists.txt that defines a function, that needs to refer to its own path because it needs to use a file in its own directory:

├── path/to/a:
|   ├── CMakeLists.txt
|   └── file_i_need.in
└── different/path/here:
    └── CMakeLists.txt

The path/to/a/CMakeLists.txt file has a function that needs to configure_file():

function(do_something_interesting ...)
    configure_file(
        file_i_need.in  ## <== how do I get the path to this file
        file_out        ## <== this one I don't need to path
        )
endfunction()

I can write path/to/a/file_i_need.in on that line, but that seems overly cumbersome. I can use ${CMAKE_CURRENT_LIST_DIR} outside of the function, but inside of the function when called by different/path/here/CMakeLists.txt it'll be different/path/here instead.

Is there a way to refer to the path of this CMakeLists.txt?

Upvotes: 6

Views: 1984

Answers (2)

Mizux
Mizux

Reputation: 9291

Just as an update, since release CMake 3.17 you can now use CMAKE_CURRENT_FUNCTION_LIST_DIR.
ref: https://cmake.org/cmake/help/v3.17/variable/CMAKE_CURRENT_FUNCTION_LIST_DIR.html

So your sample becomes:

function(do_something_interesting ...)
    configure_file(
        ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/file_i_need.in  ## <== Path to the file in current CMake script
        file_out        ## <== this one I don't need to path
        )
endfunction()

Upvotes: 5

Tsyvarev
Tsyvarev

Reputation: 65908

Outside of any function store value of CMAKE_CURRENT_LIST_DIR into a variable, then use that variable in a function, defined in that file.

Definition of a variable depends on visibility relation between a script, which defines a function (define-script) and a script, which could use that function(use-script).

  1. use-script is executed in the scope of define-script.

    This is most common case, when use-script is included into define-script or one of its parents.

    The variable can be defined as a simple variable:

    set(_my_dir ${CMAKE_CURRENT_LIST_DIR})
    
  2. use-script is executed out of the scope of define-script. Note, that a function's definition is global, so it is visible anywhere.

    This case corresponds to the code in the question post, where CMakeLists.txt files, corresponded to use-script and define-script, belongs to different subtrees.

    The variable can be defined as a CACHE variable:

    set(_my_dir ${CMAKE_CURRENT_LIST_DIR} CACHE INTERNAL "")
    

The function definition is the same in both cases:

function(do_something_interesting ...)
    configure_file(
        ${_my_dir}/file_i_need.in  ## <== Path to the file in current CMake script
        file_out        ## <== this one I don't need to path
        )
endfunction()

In both cases name of variable (_my_dir) should be somehow unique. It could include a project's name (for scripts CMakeLists.txt) or a script name (for scripts <name>.cmake).

Upvotes: 5

Related Questions