Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

For the cmake "include" command, what is the difference between a file and a module?

Tags:

cmake

People also ask

What is a module in CMake?

Utility modules are simply sections of CMake commands put into a file; they can then be included into other CMakeLists files using the include command. For example, the following commands will include the CheckTypeSize module from CMake and then use the macro it defines.

What is include in CMake?

include(<file|module> [OPTIONAL] [RESULT_VARIABLE <var>] [NO_POLICY_SCOPE]) Loads and runs CMake code from the file given. Variable reads and writes access the scope of the caller (dynamic scoping). If OPTIONAL is present, then no error is raised if the file does not exist.

What is CMake module path?

Semicolon-separated list of directories specifying a search path for CMake modules to be loaded by the include() or find_package() commands before checking the default modules that come with CMake. By default it is empty, it is intended to be set by the project.

How add include path CMake?

First, you use include_directories() to tell CMake to add the directory as -I to the compilation command line. Second, you list the headers in your add_executable() or add_library() call.


I believe that a CMake 'module' is simply a file that can be used with the find_package directive. That is, when you run find_package(Module), it searches for a file in the MODULE_PATH that is named FindModule.cmake.

That said, if you include a file without the extension, it too will search through your MODULE_PATH for that file.cmake. In a CMake project I'm working on, I have a very similar directory structure as to what you propose.

+ root/
  + CMakeLists.txt
  + cmake/
  | + FindMatlab.cmake
  | + TestInline.cmake
  | + stdint.cmake
  + src/
  + include/

In CMakeLists.txt I have:

set (CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${CMAKE_CURRENT_SOURCE_DIR}/cmake")
find_package (Matlab) # runs FindMatlab.cmake
include(TestInline) # defines a macro:
test_inline (CONFIG_C_INLINE)
include(stdint) # simply executes flat CMake code

Perhaps your issue is that you are trying to define the Module path from the environment. Instead, try to simply append to it within the very CMakeList you try to access the modules/files.


I had this same question after reading the CMake include() command documentation. It states:

Load and run CMake code from the file given. [...snip for brevity...] If a module is specified instead of a file, the file with name .cmake is searched first in CMAKE_MODULE_PATH, then in the CMake module directory.

This leaves a lot of interpretation as to what CMake considers a module vs. a file, because a CMake module is a file on the file system after all. So what's the difference?

The CMake source code is the only place I could find the answer. Basically CMake considers the argument to include() to be a file if it looks like an absolute path. This means:

  • On Linux/Unix
    • The argument starts with either '/' or '~'
  • On Windows
    • The argument's second character is ':' (as in C:)
    • The argument starts with '\'

CMake assumes anything else that doesn't meet the above criteria is a Module. In which case it appends '.cmake' to the argument and searches the CMAKE_MODULE_PATH for it.


File is CMake listfile, example is CMakeLists.txt. Use following command to get the list of command used in

cmake --help-command-list 

Module is a cmake file (*.cmake) which contain cmake commands.

As Matt B. put, the CMAKE_MODULE_PATH is not environment variable of your shell, but cmake variable.

To append your module path to CMAKE_MODULE_PATH

LIST(APPEND CMAKE_MODULE_PATH ${YourPath})

Or if you perfer your modules to be used first

LIST(INSERT CMAKE_MODULE_PATH 0 ${Yourpath})