# cmake behaviour with add\_subdirectory

**URL:** <https://discourse.cmake.org/t/cmake-behaviour-with-add-subdirectory/3680>\
**Category:** Code\
**Created:** [July 2, 2021, 10:49am UTC](https://discourse.cmake.org/t/cmake-behaviour-with-add-subdirectory/3680 "2021-07-02T10:49:55Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![nakkore](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/n/bb73d2/32.png) [@nakkore](https://discourse.cmake.org/u/nakkore)\
**Post date:** [July 2, 2021, 10:49am UTC](https://discourse.cmake.org/t/cmake-behaviour-with-add-subdirectory/3680/1 "2021-07-02T10:49:55Z")

</div>

Hi guys,  
I can see a behaviour with a cmake project which I can’t explain.

I’ve got the following simplified project layout:  
.  
├── a  
│ ├── a.cpp  
│ ├── a.h  
│ └── CMakeLists.txt  
├── b  
│ ├── b.cpp  
│ ├── b.h  
│ └── CMakeLists.txt  
├── build  
└── CMakeLists.txt

where B is a static library, A is an executable which links B

**root CMakeList.txt:**  
cmake\_minimum\_required(VERSION 3.13)  
project(st)

add\_subdirectory(b)  
add\_subdirectory(a)

**A CMakeList.txt:**  
cmake\_minimum\_required(VERSION 3.13)  
project(a)

add\_executable(a a.cpp)  
add\_definitions(-DBUILDA)

target\_include\_directories(a PUBLIC ${CMAKE\_CURRENT\_SOURCE\_DIR}/…/b)

target\_link\_libraries(a LINK\_PUBLIC b)

**B CMakeList.txt:**  
cmake\_minimum\_required(VERSION 3.13)  
project(b)

add\_definitions(-DBUILDB)

add\_library(b STATIC)

target\_sources(b PUBLIC b.cpp)

When I run make I’ve got the following output:

```auto
/usr/bin/cmake -S/home/ollly/supertest -B/home/ollly/supertest/build --check-build-system CMakeFiles/Makefile.cmake 0
/usr/bin/cmake -E cmake_progress_start /home/ollly/supertest/build/CMakeFiles /home/ollly/supertest/build/CMakeFiles/progress.marks
make -f CMakeFiles/Makefile2 all
make[1]: Entering directory '/home/ollly/supertest/build'
make -f b/CMakeFiles/b.dir/build.make b/CMakeFiles/b.dir/depend
make[2]: Entering directory '/home/ollly/supertest/build'
cd /home/ollly/supertest/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/ollly/supertest /home/ollly/supertest/b /home/ollly/supertest/build /home/ollly/supertest/build/b /home/ollly/supertest/build/b/CMakeFiles/b.dir/DependInfo.cmake --color=
Scanning dependencies of target b
make[2]: Leaving directory '/home/ollly/supertest/build'
make -f b/CMakeFiles/b.dir/build.make b/CMakeFiles/b.dir/build
make[2]: Entering directory '/home/ollly/supertest/build'
**[20%] Building CXX object b/CMakeFiles/b.dir/b.cpp.o**
cd /home/ollly/supertest/build/b && /usr/bin/c++ -DBUILDB -o CMakeFiles/b.dir/b.cpp.o -c /home/ollly/supertest/b/b.cpp
[40%] Linking CXX static library libb.a
cd /home/ollly/supertest/build/b && /usr/bin/cmake -P CMakeFiles/b.dir/cmake_clean_target.cmake
cd /home/ollly/supertest/build/b && /usr/bin/cmake -E cmake_link_script CMakeFiles/b.dir/link.txt --verbose=1
/usr/bin/ar qc libb.a CMakeFiles/b.dir/b.cpp.o
/usr/bin/ranlib libb.a
make[2]: Leaving directory '/home/ollly/supertest/build'
[40%] Built target b
make -f a/CMakeFiles/a.dir/build.make a/CMakeFiles/a.dir/depend
make[2]: Entering directory '/home/ollly/supertest/build'
cd /home/ollly/supertest/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/ollly/supertest /home/ollly/supertest/a /home/ollly/supertest/build /home/ollly/supertest/build/a /home/ollly/supertest/build/a/CMakeFiles/a.dir/DependInfo.cmake --color=
Scanning dependencies of target a
make[2]: Leaving directory '/home/ollly/supertest/build'
make -f a/CMakeFiles/a.dir/build.make a/CMakeFiles/a.dir/build
make[2]: Entering directory '/home/ollly/supertest/build'
[60%] Building CXX object a/CMakeFiles/a.dir/a.cpp.o
cd /home/ollly/supertest/build/a && /usr/bin/c++ -DBUILDA -I/home/ollly/supertest/a/../b -o CMakeFiles/a.dir/a.cpp.o -c /home/ollly/supertest/a/a.cpp
**[80%] Building CXX object a/CMakeFiles/a.dir/__/b/b.cpp.o**
cd /home/ollly/supertest/build/a && /usr/bin/c++ -DBUILDA -I/home/ollly/supertest/a/../b -o CMakeFiles/a.dir/__/b/b.cpp.o -c /home/ollly/supertest/b/b.cpp
[100%] Linking CXX executable a
cd /home/ollly/supertest/build/a && /usr/bin/cmake -E cmake_link_script CMakeFiles/a.dir/link.txt --verbose=1
/usr/bin/c++ CMakeFiles/a.dir/a.cpp.o CMakeFiles/a.dir/__/b/b.cpp.o -o a ../b/libb.a 
make[2]: Leaving directory '/home/ollly/supertest/build'
[100%] Built target a
make[1]: Leaving directory '/home/ollly/supertest/build'
/usr/bin/cmake -E cmake_progress_start /home/ollly/supertest/build/CMakeFiles 0

```

In this output you can see that b.cpp is compiled twice and when the executable A is being built it doesn’t link B as a library (libb.a) but instead it prefers to recompilile b.cpp and link the object file

Keeping this project structure, how can I avoid make to recompile b.cpp and link directly libb.a ?

Thanks in advance.  
Jack

---

<div class="post-metadata">

**Author:** ![fenrir](https://discourse.cmake.org/user_avatar/discourse.cmake.org/fenrir/32/734_2.png) [@fenrir](https://discourse.cmake.org/u/fenrir)\
**Post date:** [July 2, 2021, 11:02am UTC](https://discourse.cmake.org/t/cmake-behaviour-with-add-subdirectory/3680/2 "2021-07-02T11:02:24Z")

</div>

`target_sources(b PUBLIC b.cpp)`  
For starters, make this PRIVATE

This [https://cmake.org/cmake/help/latest/command/target\_link\_libraries.html#libraries-for-a-target-and-or-its-dependents-legacy](https://cmake.org/cmake/help/latest/command/target_link_libraries.html#libraries-for-a-target-and-or-its-dependents-legacy) says that `LINK_PUBLIC` a) is deprtectaed; b) only sets `INTERFACE` properties (also does not link)

You probably want  
`target_link_libraries(a PRIVATE b)`

---

<div class="post-metadata">

**Author:** ![nakkore](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/n/bb73d2/32.png) [@nakkore](https://discourse.cmake.org/u/nakkore)\
**Post date:** [July 2, 2021, 11:06am UTC](https://discourse.cmake.org/t/cmake-behaviour-with-add-subdirectory/3680/3 "2021-07-02T11:06:06Z")

</div>

> [@fenrir](#):
>
> PRIVATE

HI Jakub,  
thanks for suggestions but that doesn’t answer my question.

---

<div class="post-metadata">

**Author:** ![fenrir](https://discourse.cmake.org/user_avatar/discourse.cmake.org/fenrir/32/734_2.png) [@fenrir](https://discourse.cmake.org/u/fenrir)\
**Post date:** [July 2, 2021, 11:09am UTC](https://discourse.cmake.org/t/cmake-behaviour-with-add-subdirectory/3680/4 "2021-07-02T11:09:29Z")

</div>

By making this PUBLIC you’re basically saying that each target thet links to b should add “b.cpp” to its own sources for compilation.

And have you read the entire response?

---

<div class="post-metadata">

**Author:** ![nakkore](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/n/bb73d2/32.png) [@nakkore](https://discourse.cmake.org/u/nakkore)\
**Post date:** [July 2, 2021, 11:10am UTC](https://discourse.cmake.org/t/cmake-behaviour-with-add-subdirectory/3680/5 "2021-07-02T11:10:12Z")

</div>

I’m sorry Jakub, you’re right. solved my issue. Thanks a lot.
