# How to let subdirectories decide what other subdirectories are added by parent

**URL:** https://discourse.cmake.org/t/how-to-let-subdirectories-decide-what-other-subdirectories-are-added-by-parent/6274
**Category:** Code
**Created:** [August 15, 2022, 5:08pm UTC](https://discourse.cmake.org/t/how-to-let-subdirectories-decide-what-other-subdirectories-are-added-by-parent/6274 "2022-08-15T17:08:47Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![deorder](https://discourse.cmake.org/user_avatar/discourse.cmake.org/deorder/32/2680_2.png) [@deorder](https://discourse.cmake.org/u/deorder)
#### Post date: [August 15, 2022, 5:08pm UTC](https://discourse.cmake.org/t/how-to-let-subdirectories-decide-what-other-subdirectories-are-added-by-parent/6274/1 "2022-08-15T17:08:47Z")

</div>

How to let a subdirectory of the same project decide if the parent should add a subdirectory. Those subdirectories (`x`, `y`) are dependencies of one or more subdirectories (`a`, `b`), but not on the parent/root. Sometimes this dependency can contain only a header file (`y`), sometimes it can contain both a header file and a source file (`x`).

I have the following situation:

Directory structure:

```auto
a/
  CMakeLists.txt
  a.c
  a.h
  b/
    CMakeLists.txt
    b.c
    b.h
  c/
    CMakeLists.txt
    c.c
    c.h
  x/
    CMakeLists.txt
    x.c
    x.h
  y/
    CMakeLists.txt
    y.h

```

a/CMakeLists.txt:

```auto
cmake_minimum_required(VERSION 3.23)
project(a)

set(CMAKE_C_STANDARD 99)

add_library(${PROJECT_NAME} STATIC a.c)

target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

add_subdirectory(b)
add_subdirectory(c)

# TODO: x should only be added if 'b/CMakeLists.txt' and/or 'c/CMakeLists.txt' says so
add_subdirectory(x)

# TODO: y should only be added if 'c/CMakeLists.txt' says so
add_subdirectory(y)

```

b/CMakeLists.txt (`c` is similar):

```auto
cmake_minimum_required(VERSION 3.23)

target_sources(${PROJECT_NAME} PRIVATE b.c)

target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

# TODO: Tell parent it should add x as a dependency to add to the target

# This works for includes, but it will not let the parent build any required C files.
# target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/x)

```

---

<div class="post-metadata">

### Author: ![deorder](https://discourse.cmake.org/user_avatar/discourse.cmake.org/deorder/32/2680_2.png) [@deorder](https://discourse.cmake.org/u/deorder)
#### Post date: [August 15, 2022, 6:33pm UTC](https://discourse.cmake.org/t/how-to-let-subdirectories-decide-what-other-subdirectories-are-added-by-parent/6274/2 "2022-08-15T18:33:42Z")

</div>

I solved it by moving everything to a CMakeLists.txt in the project’s root directory:

```auto
cmake_minimum_required(VERSION 3.23)
project(a)

set(CMAKE_C_STANDARD 99)

add_library(${PROJECT_NAME} STATIC a.c a.h)
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

if(USE_B)
  target_sources(${PROJECT_NAME} PRIVATE b/b.c)
  target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/b)
  set(USE_X 1)
endif()

if(USE_C)
  target_sources(${PROJECT_NAME} PRIVATE c/c.c)
  target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/c)
  set(USE_X 1)
endif()

if(USE_X)
  target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/x)
  target_sources(${PROJECT_NAME} PRIVATE x/x.c)
endif()

```

---

<div class="post-metadata">

### Author: ![vdamewood](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/v/7ab992/32.png) [@vdamewood](https://discourse.cmake.org/u/vdamewood)
#### Post date: [August 16, 2022, 7:33pm UTC](https://discourse.cmake.org/t/how-to-let-subdirectories-decide-what-other-subdirectories-are-added-by-parent/6274/3 "2022-08-16T19:33:18Z")

</div>

If you want to keep the subdirectory structure, I can see two ways to handle this.

You could use `set(... PARENT_SCOPE)` to set a variable that will also be set in the parent directory .

Or, you can use `INTERFACE` libraries. You make them with `add_library(LibName INTERFACE)`. You can put the `INTERFACE` libraries in the subdirectories. the ‘libraries’ won’t be built themselves, but anything you add to them with the `INTERFACE` specifier will be applied to anything that uses `target_link_libraries` to depend on the `INTERFACE` library. You can also use `if(TARGET TargetName)` as a condition for `add_subdirectory`.

```auto
cmake_minimum_required(VERSION 3.23)
project(MyProject)

add_executable(Baz)
target_sources(Baz PRIVATE baz.c)

if(USE_FOO)
	add_library(Foo INTERFACE)
	target_sources(Foo INTERFACE foo.c foo.h)
	target_compile_definitions(Foo INTERFACE USE_FOO=1)
	target_link_libraries(Baz PRIVATE Foo)
endif()

if(TARGET Foo)
  add_subdirectory(bar)
endif

```

And in `bar/CMakeLists.txt`:

```auto
add_library(Bar INTERFACE)
target_sources(Bar INTERFACE bar.c bar.h)
target_compile_definitions(Foo INTERFACE USE_BAR=1)
target_link_libraries(Baz PRIVATE Bar)

```
