CMake >= v3.21
There's a boolean flag PROJECT_IS_TOP_LEVEL, which seems to indicate exactly this.
For more general querying (not only the current project), there's also <PROJECT-NAME>_IS_TOP_LEVEL.
CMake pre < v3.21
Disclaimer: This answer assumes that project
calls always happen in the first processed CMakeLists.txt
file that is processed for every project.
The best way to check for this (to my knowledge) would be to test whether the variables CMAKE_SOURCE_DIR
and PROJECT_SOURCE_DIR
(note: no CMAKE_
prefix) refer to the same path.
From the docs 1, 2:
CMAKE_SOURCE_DIR
The path to the top level of the source tree.
This is the full path to the top level of the current CMake source tree.
PROJECT_SOURCE_DIR
This is the source directory of the last call to the project() command made in the current directory scope or one of its parents. Note, it is not affected by calls to project() made within a child directory scope (i.e. from within a call to add_subdirectory() from the current scope).
So the gist of it is that if the project is built stand-alone, top-level source directory, is the one that contains your own CMakeLists.txt
file, which (as is normally the case) contains the project
call of your own project. Assuming you don't have multiple project
calls in your project (again: as is usually the case), that means that the directory in which the last project
call happened (and which does not lie in a sun directory of your current directory, which according to the docs don't count) is the same as the top-level source directory. Therefore, the mentioned variables will refer to the same path.
If, however, your project is embedded in someone else's CMake project, their CMakeLists.txt
location will define the top-level source directory. At some point, they will include your project, which starts by its own project
call, updating PROJECT_SOURCE_DIR
to the path to the directory in which your CMakeLists.txt
file lies. Therefore, CMAKE_SOURCE_DIR != PROJECT_SOURCE_DIR
.
TL;DR: This is the necessary check
if (CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
message(STATUS "Your project is standalone")
else()
message(STATUS "Your project is embedded")
endif()