Jackzz
Jackzz

Reputation: 1467

CMake: Function is callable while script, defined it, is no longer included

I have three folders in a location, say A,B and C. I have two cmake files in folder A: FindABC.cmake and UseABC.cmake. The former is for finding the libraries and the latter contains a function, say run_command(). CMakelists.txt in folder B and folder C contains the following lines:

find_package(ABC)
include(UseABC)
run_command()

It works as intended. Now If I comment find_package() and include() in CMakelists of folder C, as far as I know, Cmake should give an error telling unknown command - run_command(). But, the controls goes into the function and executes in unpredictable manner.

How come the control goes to the function when the include line is commented? The root CMakelists that lists the sub-directories does not have any find_package or include lines in it.

Edit:

UseABC.cmake:

set(ABC_COMPILE_DEBUG FALSE)
set(ABC_COMPILE_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/abc_gen")
message("USEABC1 - -> " ${ABC_COMPILE_OUTPUT_DIR})
function(run_command)
    message("USEABC2 - File recurs -> " ${ABC_COMPILE_OUTPUT_DIR})
    file(REMOVE_RECURSE "${ABC_COMPILE_OUTPUT_DIR}")
    file(MAKE_DIRECTORY "${ABC_COMPILE_OUTPUT_DIR}")
    add_custom_command() #command to be executed
endfunction()

Here, When nothing is commented(find_package and include is not commented in any CMakelists.txt), I get the correct path for the two messages I print.

When I comment include(UseABC) in the second CMakelists.txt, the configuration fails, the first message is not at all printed and the second message gets printed, but does not give the value of the variable. It also deletes all the files in Folder C (but the argument to REMOVE_RECURSE is empty).

Upvotes: 0

Views: 2148

Answers (1)

Tsyvarev
Tsyvarev

Reputation: 66288

If I correctly understand the situation, you have:

CMakeLists.txt:

add_subdirectory(B)
add_subdirectory(C)

B/CMakeLists.txt:

find_package(ABC)
include(UseABC)

In that case run_command function, defined in UseABC.cmake, is accessible in C/CMakeLists.txt, though this script doesn't define it.

In CMake function definitions are global.


By opposite, variable definitions are local to the scope, where they are defined. (Until variables are cached ones, in that case they have global visibility).

That is, variable ABC_COMPILE_DEBUG defined in UseABC.cmake is accessible in

  • UseABC.cmake script
  • B/CMakeLists.txt script, because it includes UseABC.cmake one, and include() command doesn't introduce a scope

but it is inaccessible in

  • CMakeLists.txt script, because add_subdirectory(B) does introduce a scope
  • C/CMakeLists.txt script

More details about variable's visibility can be found in documentation.

Upvotes: 2

Related Questions