86

This page contains a good summary of variables CMake already defines for us. I feel that some variables are the same. Take the example of CMAKE_SOURCE_DIR and PROJECT_SOURCE_DIR for example. They are the same, referring to the folder where the top level CMakeLists.txt is defined. So my question is: are there subtle difference between them? Thanks.

F14
  • 67
  • 2
  • 6
feelfree
  • 11,175
  • 20
  • 96
  • 167

2 Answers2

147

There is a difference between these variables. CMAKE_SOURCE_DIR does indeed refer to the folder where the top-level CMakeLists.txt is defined. However, PROJECT_SOURCE_DIR refers to the folder of the CMakeLists.txt containing the most recent project() command.

For example, say you have a top-level project called Outer and this contains a subdirectory with its own project called Inner. Outer's CMakeLists.txt has:

project(Outer)
add_subdirectory(Inner)

and Inner's:

project(Inner)

Then in both of these CMakeLists files, CMAKE_SOURCE_DIR will refer to Outer's source dir. But while PROJECT_SOURCE_DIR for Outer is also this same dir, this is not the case for Inner. Inner's PROJECT_SOURCE_DIR is the subdirectory containing its CMakeLists.txt.

This difference applies to all PROJECT_<var> vs CMAKE_<var> variables.

starball
  • 20,030
  • 7
  • 43
  • 238
Fraser
  • 74,704
  • 20
  • 238
  • 215
  • 17
    Could you also add the difference with `CMAKE_CURRENT_SOURCE_DIR`? – Svalorzen Jun 27 '17 at 12:15
  • So (in a single CMakeLists.txt project) it is a bad idea to put it in a subdirectory (say cmake)? – Sandburg Jan 21 '19 at 08:04
  • 2
    there is a need **to emphasize** that `PROJECT_SOURCE_DIR` requires the call of `project(aaa)` in order for `PROJECT_SOURCE_DIR` to have a value. – daparic Aug 25 '21 at 11:05
12

Following Fraser's excellent answer.

CMAKE_CURRENT_SOURCE_DIR is the build directory being processed.

Let's say you have a directory called Inner1 containing a CMakeLists.txt file without calling project inside of it. Then PROJECT_SOURCE_DIR is not set with Inner1's dir path, but the CMAKE_CURRENT_SOURCE_DIR is set when being processed.

You may also find CMAKE_CURRENT_LIST_DIR interesting and the definition of listfile useful.

Izana
  • 2,537
  • 27
  • 33
  • This is an old comment now, but the `CMAKE_CURRENT_SOURCE_DIR` link points to the older documentation for `CMAKE_CURRENT_BINARY_DIR`. – jvstech Feb 16 '22 at 20:47