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?
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.
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 .
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.
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:
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.
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.
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.
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).
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})
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
).
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()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With