Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I tell, within a CMakeLists.txt, whether it's used with add_subdirectory()? [duplicate]

I have this code project can be built either independently or as a subproject of a larger repository (checking it our as a sub-repository). In the latter case, I have a top-level CMakeLists.txt for the main project which has

add_subdirectory(${MY_SUBPROJ_SUBDIR})

now, I want the subproject to behave somewhat differently in case it's used via the add_directory(). Obviously, I would be using a large if instruction. But what condition do I check? How can CMake "tell", when running for some CMakeLists.txt, whether it's a subdir file or the main file?

like image 442
einpoklum Avatar asked Mar 10 '17 10:03

einpoklum


People also ask

What does Add_subdirectory do in CMake?

Add a subdirectory to the build. Adds a subdirectory to the build. The source_dir specifies the directory in which the source CMakeLists.

How does CMakeLists TXT work?

CMakeLists. txt file contains a set of directives and instructions describing the project's source files and targets (executable, library, or both). When you create a new project, CLion generates CMakeLists. txt file automatically and places it in the project root directory.

What is 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. For an in-source build, this would be the same as CMAKE_BINARY_DIR .

Where is the CMakeLists txt?

CMakeLists. txt is placed at the root of the source tree of any application, library it will work for. If there are multiple modules, and each module can be compiled and built separately, CMakeLists. txt can be inserted into the sub folder.


1 Answers

  1. After the project() call in project's CMakeLists.txt and in the project's subdirectories you may use:

     if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
         # I am top-level project.
     else()
         # I am called from other project with add_subdirectory().
     endif()
    

    NOTE: As stated in the comments, this approach may to not work on Windows, where CMAKE_SOURCE_DIR contains lower-case version of PROJECT_SOURCE_DIR and thus cannot be compared directly for equality. For that case approach with checking PARENT_DIRECTORY property, as described in that answer to the duplicate question, seems to be more robust.

  2. Alternative for use before the project() call:

     if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
         # I am top-level project.
     else()
         # I am called from other project with add_subdirectory().
     endif()
    

    This alternative can also be used anywhere in project's CMakeLists.txt (but not in subdirectories).


Assume you have a project A with two CMakeLists.txt: one in the project's directory, and one in subdirectory src/. Scheme for use approaches described above:

CMakeLists.txt:

cmake_minimum_required(...)
...
<only approach *2* can be used there>
...
project(A)
...
<approach *1* or *2* can be used there>
...
add_subdirectory(src)
...

src/CMakeLists.txt:

...
<only approach *1* can be used there>
...

With given scheme project A may detect, whether it is built standalone (top-level project) or as a part of another project B.

like image 81
Tsyvarev Avatar answered Sep 25 '22 17:09

Tsyvarev