Our include_guard macro contains two branches, one for CMake below 3.10 and one for CMake 3.10 and higher:
macro(include_guard)
if (CMAKE_VERSION VERSION_LESS "3.10")
# ...
else()
# ...
endif()
endmacro()
If CMake version is below 3.10, we enter the first branch and an intrinsic include_guard is not available, so we define our own:
message(STATUS "calling our custom include_guard")
# if this macro is called the first time
# we start with an empty list
if(NOT DEFINED included_modules)
set(included_modules)
endif()
if ("${CMAKE_CURRENT_LIST_FILE}" IN_LIST included_modules)
message(WARNING "module ${CMAKE_CURRENT_LIST_FILE} processed more than once")
endif()
list(APPEND included_modules ${CMAKE_CURRENT_LIST_FILE})
If the macro is called the first time, then the included_modules variable is not defined so we set it to an empty list. We then check whether ${CMAKE_CURRENT_LIST_FILE} is an element of the included_modules list. If yes, we issue a warning. If no, we append ${CMAKE_CURRENT_LIST_FILE} to this list. In the CMake output, we can verify that a second include of the custom module indeed leads to the warning.
The situation is different for CMake 3.10 and higher; in this case, an intrinsic include_guard exists and we call it with the arguments received by our own macro:
macro(include_guard)
if (CMAKE_VERSION VERSION_LESS "3.10")
# ...
else()
message(STATUS "calling the built-in include_guard")
_include_guard(${ARGV})
endif()
endmacro()
Here, _include_guard(${ARGV}) points to the built-in include_guard. In this case, we have augmented the built-in command with a custom message ("calling the built-in include_guard"). This pattern provides us with a mechanism to redefine own or built-in functions and macros. This can be useful for debugging or logging purposes.