# How to add "out-of-tree" common source files

**URL:** <https://discourse.cmake.org/t/how-to-add-out-of-tree-common-source-files/4442>\
**Category:** Code\
**Created:** [November 6, 2021, 8:55pm UTC](https://discourse.cmake.org/t/how-to-add-out-of-tree-common-source-files/4442 "2021-11-06T20:55:50Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![larienna](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/l/d9b06d/32.png) [@larienna](https://discourse.cmake.org/u/larienna)\
**Post date:** [November 6, 2021, 8:55pm UTC](https://discourse.cmake.org/t/how-to-add-out-of-tree-common-source-files/4442/1 "2021-11-06T20:55:50Z")

</div>

I have a project with the following directory structure

```auto
server
  | daemon
  | | src
  | service
  | | src
  | commons

```

The `daemon` is the linux version and `service` contains the windows version. Originally, I made 2 separate cmake projects in those 2 folders and it worked. But I had to copy paste code between both projects. Now I want to move sources with common code into the `commons` folder. So that each project includes the sources from the common folder instead of copy pasting code.

Within Code::Blocks, it works, I just add the commons files to the project and it works.

For CMake, it works only on header files using a command like:

`include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../commons)`

in the `scr` directory. Now the problem is when I want to include source files in the same directory. I cannot manage it to make it work, it does not find the source files. Adding a new sub directory does not work since it’s not a sub directory.

`add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../../commons commons)`

I don’t seem to be able to build the commons folder without using `add_executable` or `add_library`. Making a library could work, but I though generating a library would be an overkill since it will not be reused elsewhere than this project.

Then I though that maybe I could create the project in the root directory and add 2 projects for the whole tree structure. But adding 2 projects in the same file seems impossible. I also have the constraint that I don’t want to build every thing all the time. When I am in linux, I want to build `daemon` and `commons` while when I am in windows, I want to build `service` and `commons`.

The internet did not yield any good solution so far. So I am trying this forum:

Is it possible to add “out-of-tree” source files?  
Else is it possible to have multiple projects in the same cmake file and only build a portion of the projects?  
Else is there other solutions than building a static library?

---

<div class="post-metadata">

**Author:** ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)\
**Post date:** [November 7, 2021, 12:13pm UTC](https://discourse.cmake.org/t/how-to-add-out-of-tree-common-source-files/4442/2 "2021-11-07T12:13:17Z")

</div>

This might be where an `OBJECT` library can help. It’s like a static library except the objects go directly on the consumer’s link line rather than through an actual static library. Since it seems you’re building executables, the oddities one has to deal with for exporting symbols from object libraries isn’t relevant here.

---

<div class="post-metadata">

**Author:** ![larienna](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/l/d9b06d/32.png) [@larienna](https://discourse.cmake.org/u/larienna)\
**Post date:** [November 7, 2021, 8:41pm UTC](https://discourse.cmake.org/t/how-to-add-out-of-tree-common-source-files/4442/3 "2021-11-07T20:41:41Z")

</div>

Ok, it works. Here is what I did for those who stumble on this thread. First I defined a config file in my commons directory. I added a library as type OBJECT with the matching C files and I want to include headers in the same folder. My “library” name is going to be `cvpcommons`

```auto
include_directories(.)
add_library(cvpcommons OBJECT tcpconnection.c commons.c)

```

Then I added the “sub-directory” in the project root config file by specifying an alternate location to store the built files. In my case it was `src/commons`.

```auto
cmake_minimum_required(VERSION 3.7)
project(cvpd)
add_subdirectory(src)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../commons src/commons)

```

Finally, the `src` directory config must add the common folder for includes and linking directories. Then you must add the library to the executable using the `$<TARGET_OBJECTS:...>` directive.

```auto
include_directories(.)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../commons)
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../commons)
add_executable(cvpd main.c keypress.c $<TARGET_OBJECTS:cvpcommons>)
target_link_libraries(cvpd X11 Xtst )
install(TARGETS cvpd RUNTIME DESTINATION ${PROJECT_SOURCE_DIR})

```

This is how I managed to make it work.

---

<div class="post-metadata">

**Author:** ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)\
**Post date:** [November 7, 2021, 8:52pm UTC](https://discourse.cmake.org/t/how-to-add-out-of-tree-common-source-files/4442/4 "2021-11-07T20:52:39Z")

</div>

You could just add a single target at the `server` level, then add sources from `common` and one of `daemon` or `service` depending on platform. Based on what you’ve described you want to do, this is how I would structure it:

_server/CMakeLists.txt:_

```cmake
add_executable(cvpcommons)

add_subdirectory(commons)
if(WIN32)
    add_subdirectory(service)
else()
    add_subdirectory(daemon)
endif()

```

_service/CMakeLists.txt:_

```cmake
target_sources(cvpcommons file1.cpp file2.cpp ...)

```

_daemon/CMakeLists.txt:_

```cmake
target_sources(cvpcommons file3.cpp file4.cpp ...)

```

_commons/CMakeLists.txt:_

```cmake
target_sources(cvpcommons file5.cpp file6.cpp ...)

# Make this directory part of the header search path so the others find it
target_include_directories(cvpcommons PRIVATE .)

```

Some further reading: [Enhanced source file handling with target\_sources() - Crascit](https://crascit.com/2016/01/31/enhanced-source-file-handling-with-target_sources/)
