# parallel build (2) : add\_subdirectory to a non-subdirectory

**URL:** <https://discourse.cmake.org/t/parallel-build-2-add-subdirectory-to-a-non-subdirectory/1841>\
**Category:** Code\
**Created:** [September 14, 2020, 8:15pm UTC](https://discourse.cmake.org/t/parallel-build-2-add-subdirectory-to-a-non-subdirectory/1841 "2020-09-14T20:15:14Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![ProTur1](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/p/34f0e0/32.png) [@ProTur1](https://discourse.cmake.org/u/ProTur1)\
**Post date:** [September 14, 2020, 8:15pm UTC](https://discourse.cmake.org/t/parallel-build-2-add-subdirectory-to-a-non-subdirectory/1841/1 "2020-09-14T20:15:14Z")

</div>

```
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../myStaticLib ${BINARY_OUTPUT_PATH})
add_executable(${EXE_NAME} ${PROJECT_SOURCE_DIR}/exe.cpp)

```

Always fails if a parallel build is triggered (e.g. `make -j N`), and the the build in the subdirectory takes longer than the build of the exe.

How to wait for the results of `add_subdirectory` before, the build of `add_executable` is started?

---

<div class="post-metadata">

**Author:** ![Angew](https://discourse.cmake.org/user_avatar/discourse.cmake.org/angew/32/229_2.png) [@Angew](https://discourse.cmake.org/u/Angew)\
**Post date:** [September 15, 2020, 8:25am UTC](https://discourse.cmake.org/t/parallel-build-2-add-subdirectory-to-a-non-subdirectory/1841/2 "2020-09-15T08:25:50Z")

</div>

Such setup works quite normally for me. Please show how `above_lib` is defined in the file `${SRC}/../above_lib/CMakeLists.txt`.

---

<div class="post-metadata">

**Author:** ![ProTur1](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/p/34f0e0/32.png) [@ProTur1](https://discourse.cmake.org/u/ProTur1)\
**Post date:** [September 15, 2020, 5:33pm UTC](https://discourse.cmake.org/t/parallel-build-2-add-subdirectory-to-a-non-subdirectory/1841/3 "2020-09-15T17:33:25Z")

</div>

Changed the above code a little. The above\_lib which is `myStaticLib` is generated over a huge cmake file, which I would not paste here, For me to things happening:  
Due to the p_arallel build (i.e. the on several cores),_ the **exe files are build much quicker** , and thus it starts **linking against the myStaticLib before it is compiled**. Thus it complains about non-existing lib, which is supposed to be linked to.  
What information else, I could provide else ?

---

<div class="post-metadata">

**Author:** ![Angew](https://discourse.cmake.org/user_avatar/discourse.cmake.org/angew/32/229_2.png) [@Angew](https://discourse.cmake.org/u/Angew)\
**Post date:** [September 16, 2020, 7:02am UTC](https://discourse.cmake.org/t/parallel-build-2-add-subdirectory-to-a-non-subdirectory/1841/4 "2020-09-16T07:02:18Z")

</div>

> [@ProTur1](#):
>
> Due to the p _arallel build (i.e. the on several cores),_ the **exe files are build much quicker** , and thus it starts **linking against the myStaticLib before it is compiled**. Thus it complains about non-existing lib, which is supposed to be linked to.

That is not how CMake-generated buildsystems behave, _if_ you have set up your dependencies correctly.

Please show:

- The `add_library()` call which creates the static library
- The `target_link_libraries()` call which makes the executable link against the static library.

Ideally, you’d trim your buildsystem down to an [SSCCE](http://sscce.org/) and post that, but the above calls could be enough, so let’s start with them.

---

<div class="post-metadata">

**Author:** ![ProTur1](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/p/34f0e0/32.png) [@ProTur1](https://discourse.cmake.org/u/ProTur1)\
**Post date:** [September 16, 2020, 11:40am UTC](https://discourse.cmake.org/t/parallel-build-2-add-subdirectory-to-a-non-subdirectory/1841/5 "2020-09-16T11:40:54Z")

</div>

In the meanwhile, I could figure out what is the problem.

To mention also: its a `Linux` CMake build.

I had instead of this

- A `set(MY_STATIC_LIB_NAME myStaticLib)`

used this

- B `set(MY_STATIC_LIB_NAME libmyStaticLib.a)`

The call below (target\_link\_libraries) functions with both variants.

`target_link_libraries(${EXE_NAME} PUBLIC ${MY_STATIC_LIB_NAME})`

But the build behaves differently:

- A. Everything works fine, i.e. the lib is build in parallel, and the linker is called after its been built.
- B. CMake didn’t make a connection between `libmyStaticLib.a` and `myStaticLib` from the `add_subdirectory` call. Thus the two were build separately. The linker stripped though the libmyStaticLib.a to myStaticLib and issued an error (`/usr/bin/ld: cannot find -lmyStaticLib`) of not finding the library.

Two final questions

1. Is the above CMake behavior a bug or a feature ?
2. How does CMake internally handles build dependencies, so that it wont call the linker before everything is build, i.e. how is build order handled?

---

<div class="post-metadata">

**Author:** ![Angew](https://discourse.cmake.org/user_avatar/discourse.cmake.org/angew/32/229_2.png) [@Angew](https://discourse.cmake.org/u/Angew)\
**Post date:** [September 16, 2020, 11:50am UTC](https://discourse.cmake.org/t/parallel-build-2-add-subdirectory-to-a-non-subdirectory/1841/6 "2020-09-16T11:50:55Z")

</div>

> [@ProTur1](#):
>
> Is the above CMake behavior a bug or a feature ?

Feature.

`target_link_libraries(myExe myLib)` tells CMake to link the executable `myExe` to the library `myLib`, which is a CMake target built by this project. This tells CMake to ensure target dependencies and build order are correctly maintained etc. You don’t want to have to change the `target_link_libraries` call just because you later decide to turn `myLib` from a static library into a shared one (see also `BUILD_SHARED_LIBS`), or to accommodate the differences between Windows, Linux, MacOSX, etc.

In contrast, `target_link_libraries(myExe libmyLib.a)` tells CMake to link the executable `myExe` against a pre-existing library `libmyLib.a`, which is totally independent of the current buildsystem. You’d use this to link to a system library or a 3rd-party one (and you’d want to use an absolute path for the latter to ensure correct rebuilds when the library changes).

> [@ProTur1](#):
>
> How does CMake internally handles build dependencies, so that it wont call the linker before everything is build, i.e. how is build order handled?

By correctly encoding the dependencies in the generated buildsystem. When generating Makefiles, it will encode the dependency in the build rule, listing the library in the exeutable’s rule’s dependencies. When generating a Visual Studio solution, it will populate the `ProjectSection(ProjectDependencies)` section of the `.sln` file accordingly. And so on for other generators.

---

<div class="post-metadata">

**Author:** ![ProTur1](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/p/34f0e0/32.png) [@ProTur1](https://discourse.cmake.org/u/ProTur1)\
**Post date:** [September 16, 2020, 6:11pm UTC](https://discourse.cmake.org/t/parallel-build-2-add-subdirectory-to-a-non-subdirectory/1841/7 "2020-09-16T18:11:37Z")

</div>

> By correctly encoding the dependencies in the generated buildsystem. When generating Makefiles, it will encode the dependency in the build rule, listing the library in the exeutable’s rule’s dependencies.

Does it mean CMake take care of build order, or the build system is responsible for it?

---

<div class="post-metadata">

**Author:** ![Angew](https://discourse.cmake.org/user_avatar/discourse.cmake.org/angew/32/229_2.png) [@Angew](https://discourse.cmake.org/u/Angew)\
**Post date:** [September 17, 2020, 7:07am UTC](https://discourse.cmake.org/t/parallel-build-2-add-subdirectory-to-a-non-subdirectory/1841/8 "2020-09-17T07:07:39Z")

</div>

> [@ProTur1](#):
>
> Does it mean CMake take care of build order, or the build system is responsible for it?

CMake generates the buildsystem files and its work is done. It does not run as part of the build(1). I would answer your question thus: “CMake generates the buildsystem files in such a way that when the build tools run, they will follow the correct build order.” I don’t know which one (or both) you’d like to consider “responsible” given this.

* * *

(1) Even if you invoke your build as `cmake --build`, it’s not CMake doing any actual building. It just executes the correct build driver (devenv.exe, msbuild.exe, make, ninja, …) based on the generator which had been used to create the buildsystem.

---

<div class="post-metadata">

**Author:** ![erk](https://discourse.cmake.org/user_avatar/discourse.cmake.org/erk/32/114_2.png) [@erk](https://discourse.cmake.org/u/erk)\
**Post date:** [September 17, 2020, 7:34am UTC](https://discourse.cmake.org/t/parallel-build-2-add-subdirectory-to-a-non-subdirectory/1841/9 "2020-09-17T07:34:48Z")

</div>

> [@ProTur1](#):
>
> Does it mean CMake take care of build order, or the build system is responsible for it?

The **build** order is driven by the **build tool** as explained by @Angew not CMake.  
The effective order may (and will) vary in case of parallel build, e.g. ninja is processing a DAG of dependencies so that any node which is free will be built as soon as computing resource is available.

CMake is translating the dependencies explicitly (like in custom\_command DEPENDS) or implicitly (like with target\_link\_libraries) specified by the developer in the CMakeLists.txt.

From my experience when your parallel build fails this means that you (as a developer) forgot to specify dependency at CMake level so that CMake cannot put it right in the generated buildsystem.

I that case you have to investigate the dependencies.  
I know two means:

- GraphViz generation: [https://cmake.org/cmake/help/latest/module/CMakeGraphVizOptions.html](https://cmake.org/cmake/help/latest/module/CMakeGraphVizOptions.html)
- The File API: [https://cmake.org/cmake/help/git-stage/manual/cmake-file-api.7.html](https://cmake.org/cmake/help/git-stage/manual/cmake-file-api.7.html)

with those means you will be able to dump the dependencies seen/processed by CMake.
