CMake creates software build systems for a wide variety of platforms based on a single, unified control file–it’s a makefile maker. You create the CMake control file once and based on this file, CMake will create almost any build environment for you: GNU Make for Linux, Eclipse project, Visual Studio solution for Windows, and the list goes on.
I found the relationship between certain groups of related CMake variables troublesome. I wrote my understanding of these variables to help myself remember, and I will share it with you. If you have an better (or more correct) explanation, please leave a comment.
With CMake, you generally do out of source builds. This means that when you build, you create a separate directory (folder), and build there, not in the same directory that contains the source code. Thus in CMake there are two sets of variables that refer to directories: one for the source code, and another for the binary code.
While a simple CMake project will have only a single CMakeLists.txt control file, larger projects will contain a hierarchy of CMakeLists.txt files, each in its own directory. These sub-control files are executed using the add_subdirectory command. As its name suggests, add_subdirectory also creates a directory in the build tree.
These variables contain the paths to various source code directories. Note how every one of them refers to a directory that contains a CMakeLists.txt file.
CMAKE_SOURCE_DIR: The path to the top level of the source tree. This is the directory that contains the top-level CMakeLists.txt file. That is, this is the source directory you specify to the
CMAKE_CURRENT_SOURCE_DIR: The path to the directory containing the CMakeLists.txt file that is currently being processed.
PROJECT_SOURCE_DIR: Top level source directory for the current project. Not every CMakeLists.txt file defines a project–this is the directory that contains the most recent CMakeLists.txt file that defined a project.
projectName_SOURCE_DIR: Source directory for the named project. This is the directory that contains the CMakeLists.txt file that contains the project(projectName) definition. Every CMakeLists.txt file need not define a project, but one reason to define a project is to create this variable so you can refer to its source files later, in other CMakeLists.txt files.
The build tree will contain a directory hierarchy corresponding to the hierarchy of directories in the source tree containing CMakeLists.txt files. Each of the following variables refers to a directory in the build tree corresponding to a source tree directory that contains a CMakeLists.txt file.
CMAKE_BINARY_DIR: The path to the top level of the build tree. This is the directory in which you ran the
CMAKE_CURRENT_BINARY_DIR: The path to the binary directory currently being processed. When an add_subdirectory command is encountered in a CMakeLists.txt file, a corresponding directory is created in the build directory. This variable contains that subdirectory.
PROJECT_BINARY_DIR: Top level binary directory for the current project. Not every CMakeLists.txt file defines a project–this is the directory in the build tree that corresponds to the most recent CMakeLists.txt file that defined a project.
projectName_BINARY_DIR: Binary directory for the named project. This is the directory in the build tree that corresponds to the CMakeLists.txt file that contains a project(projectName) definition. Every CMakeLists.txt file need not define a project, but one reason to define a project is to create this variable so you can refer to its binary files later, in other CMakeLists.txt files.
I invite you to add any part of this article to the CMake documentation.