Including a .cmake file

I have top-level cmakelists, with in subdirectory “cmake” a file “dependencies.cmake”. I cannot seem to include it following the approach in professional cmake book. See below? Can anybody explain what is going on? What is a portable approach for including a

Top-level cmakelists:

cmake_minimum_required (VERSION 3.21)
project ("projname" CXX)

# PROJECT WIDE SETUP

list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED YES)
set(CMAKE_CXX_EXTENSIONS NO)

#shows the correct path, so appending worked.
message(module ${CMAKE_MODULE_PATH})

# DEPENDENCIES
#does not work, even though this is listed in professional cmake book:
include(dependencies.cmake)
#does seem to work for MSVC, but is this portable?! 
#include(dependencies)

# etc. 

Output:

1> [CMake] -- The CXX compiler identification is MSVC 19.32.31329.0
1> [CMake] -- Detecting CXX compiler ABI info
1> [CMake] -- Detecting CXX compiler ABI info - done
1> [CMake] -- Check for working CXX compiler: C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.32.31326/bin/Hostx64/x64/cl.exe - skipped
1> [CMake] -- Detecting CXX compile features
1> [CMake] -- Detecting CXX compile features - done
1> [CMake] moduleC:/Users/<user>/source/repos/LibraryTests/cmake
1> [CMake] CMake Error at C:\Users\<user>\source\repos\LibraryTests\CMakeLists.txt:16 (include):
1> [CMake]   include could not find requested file:
1> [CMake] 
1> [CMake]     dependencies.cmake

Interestingly, when I put the dependencies.cmake in the outmost directory (alongside cmakelists.txt ) both cases work.

From the docs for include:

If a module is specified instead of a file, the file with name <modulename>.cmake is searched first in CMAKE_MODULE_PATH, then in the CMake module directory.

So CMake first searches for a file named dependencies.cmake relative to the CMAKE_CURRENT_LIST_DIR (I think; it might be CMAKE_CURRENT_SOURCE_DIR?). If it doesn’t find it, it searches for it in CMAKE_MODULE_PATH with a .cmake extension. So you can either use an absolute path or the name of the file (without .cmake) and use CMAKE_MODULE_PATH.

Ah, that clarifies, so calling include for the filename without appendix is the correct thing.

Strange typo in the book.

@craig.scott FYI

The last edition had some updates in that part of the book, but it could use further revising of some wording around the change from using add_subdirectory() to include() to bring in dependencies. My recommendation now is to put your dependencies.cmake in the top-most directory, not in a subdirectory. This is stated later in the text, but the earlier parts still read as though putting it in a subdirectory is recommended. I’ll address this in the next edition.

For your specific query, using include(dependencies.cmake) is correct, but the dependencies.cmake file should be in the same directory. I would not recommend using include(dependencies) and relying on CMAKE_MODULE_PATH because in this case, you want to load a very specific file at a specific location. You shouldn’t need to search for it.

Dear Craig:

THanks for your quick reaction. I was specifically confused about chapter 34.2 (13th edition), where the example includes the line:

list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake)

and then loads a module with include(dependencies.cmake). Since that is the only module loaded in the example, I concluded that it would reside in the cmake subdirectory (since otherwise above line would be superfluous). Anyhow, your response clarifies- thanks!