Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use CMAKE_CURRENT_LIST_DIR, in a function

Tags:

cmake

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?

like image 287
Barry Avatar asked Mar 22 '18 07:03

Barry


People also ask

What is Cmake_current_list_dir?

CMAKE_CURRENT_LIST_DIR: Full directory of the listfile currently being processed. As CMake processes the listfiles in your project this variable will always be set to the directory where the listfile which is currently being processed (CMAKE_CURRENT_LIST_FILE) is located. The value has dynamic scope.

What is Cmake_source_dir?

The path to the top level of the source tree. This is the full path to the top level of the current CMake source tree. For an in-source build, this would be the same as CMAKE_BINARY_DIR .

What is CMake Listfile?

CMakeLists. txt listfiles loaded by add_subdirectory command will help you to create source/binary tree. This is a skeleton of your project. *. cmake modules help you to organize/reuse CMake code.

How do I use CMake_current_function_list_Dir inside a function?

Using CMAKE_CURRENT_FUNCTION_LIST_DIR inside the function instead eliminates the need for the extra variable which would otherwise be visible outside the function's scope. The above example can be written in the more concise and more robust form:

What is the use of a listfile in CMake?

New in version 3.17. When executing code inside a function (), this variable contains the full directory of the listfile that defined the current function. It is quite common practice in CMake for modules to use some additional files, such as templates to be copied in after substituting CMake variables.

What is a function variable in CMake?

When executing code inside a function (), this variable contains the full directory of the listfile that defined the current function. It is quite common practice in CMake for modules to use some additional files, such as templates to be copied in after substituting CMake variables.

What is CMake_current_list_file in C++?

As CMake processes the listfiles in your project this variable will always be set to the directory where the listfile which is currently being processed (CMAKE_CURRENT_LIST_FILE) is located. The value has dynamic scope. When CMake starts processing commands in a source file it sets this variable to the directory where this file is located.


2 Answers

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).

like image 92
Tsyvarev Avatar answered Oct 22 '22 18:10

Tsyvarev


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()
like image 38
Mizux Avatar answered Oct 22 '22 20:10

Mizux