# Add external headers and sources

**URL:** <https://discourse.cmake.org/t/add-external-headers-and-sources/4789>\
**Category:** Code\
**Created:** [January 6, 2022, 9:07pm UTC](https://discourse.cmake.org/t/add-external-headers-and-sources/4789 "2022-01-06T21:07:37Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![bremenpl](https://discourse.cmake.org/user_avatar/discourse.cmake.org/bremenpl/32/2080_2.png) [@bremenpl](https://discourse.cmake.org/u/bremenpl)\
**Post date:** [January 6, 2022, 9:07pm UTC](https://discourse.cmake.org/t/add-external-headers-and-sources/4789/1 "2022-01-06T21:07:37Z")

</div>

Hello,  
I am trying to figure out how to include files into my project, that are outside of the project directory. The files structure on the system looks the following:

 ![image](https://discourse.cmake.org/uploads/default/original/2X/f/fd04dbf95794497caf467a3814bff40d89a2b62a.png)

So my CMakeLists.txt is in MyProject dir, while the files directory is in some other, unrelated dir (MyLib). That dir also has subdirectories.

MyProject directory has no source or header files at all.

I would appreciate all help!

---

<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:** [January 7, 2022, 1:49pm UTC](https://discourse.cmake.org/t/add-external-headers-and-sources/4789/2 "2022-01-07T13:49:47Z")

</div>

This looks quite strange. Why do you want the CMake code to live so far away from the sources?

---

<div class="post-metadata">

**Author:** ![bremenpl](https://discourse.cmake.org/user_avatar/discourse.cmake.org/bremenpl/32/2080_2.png) [@bremenpl](https://discourse.cmake.org/u/bremenpl)\
**Post date:** [January 7, 2022, 2:00pm UTC](https://discourse.cmake.org/t/add-external-headers-and-sources/4789/3 "2022-01-07T14:00:07Z")

</div>

Hi,  
Its because source files are in a repo and I cannot commit my cmake file to the repo (I want to keep them in a separate repo).

---

<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:** [January 7, 2022, 2:00pm UTC](https://discourse.cmake.org/t/add-external-headers-and-sources/4789/4 "2022-01-07T14:00:52Z")

</div>

Then I would suggest adding the repo as a submodule (or whatever your VCS calls nested repositories) and keep the CMake code “above” where the sources live.

---

<div class="post-metadata">

**Author:** ![bremenpl](https://discourse.cmake.org/user_avatar/discourse.cmake.org/bremenpl/32/2080_2.png) [@bremenpl](https://discourse.cmake.org/u/bremenpl)\
**Post date:** [January 7, 2022, 2:07pm UTC](https://discourse.cmake.org/t/add-external-headers-and-sources/4789/5 "2022-01-07T14:07:09Z")

</div>

In that case I would need to keep a repo inside of a repo on purpose with gitignore- thats possible, but I am wondering- doesnt cmake support the way of manually providing the directory that is outside of the tree?

---

<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:** [January 7, 2022, 2:25pm UTC](https://discourse.cmake.org/t/add-external-headers-and-sources/4789/6 "2022-01-07T14:25:55Z")

</div>

CMake has notions about what is “in the source tree” and not based on the relationship to the top-level `CMakeLists.txt` in use for the build. These assumptions are in many places, so doing this is likely to trip over odd behaviors. You can make it work, but it isn’t as easy.

You can certainly give absolute paths to the sources to add to targets in the `projects` directory, but I suspect you’ll always get things like absolute paths to source files rather than any relative paths (for example).

---

<div class="post-metadata">

**Author:** ![bremenpl](https://discourse.cmake.org/user_avatar/discourse.cmake.org/bremenpl/32/2080_2.png) [@bremenpl](https://discourse.cmake.org/u/bremenpl)\
**Post date:** [January 7, 2022, 7:47pm UTC](https://discourse.cmake.org/t/add-external-headers-and-sources/4789/7 "2022-01-07T19:47:36Z")

</div>

I see, thank you for the explanation. So keeping this in mind, would this scheme be correct?

 ![image](https://discourse.cmake.org/uploads/default/original/2X/c/c0529df3431c8877b1ad8f8833ca9d136513d1de.png)

And now, assuming I would like to have a separate project for the library and an executable that uses that library:

1. Do I need 2 separate CMakeLists.txt files?
2. Does the library project dir has to be contained by the executable project dir

---

<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:** [January 8, 2022, 11:57am UTC](https://discourse.cmake.org/t/add-external-headers-and-sources/4789/8 "2022-01-08T11:57:00Z")

</div>

You can do it with one `CMakeLists.txt`; that’s fine. There’s no nesting requirements within a project either as all non-`IMPORTED` `add_{library,executable}` targets are global in scope.

---

<div class="post-metadata">

**Author:** ![bremenpl](https://discourse.cmake.org/user_avatar/discourse.cmake.org/bremenpl/32/2080_2.png) [@bremenpl](https://discourse.cmake.org/u/bremenpl)\
**Post date:** [January 8, 2022, 12:04pm UTC](https://discourse.cmake.org/t/add-external-headers-and-sources/4789/9 "2022-01-08T12:04:17Z")

</div>

Could you provide a minimum working example?

---

<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:** [January 8, 2022, 7:20pm UTC](https://discourse.cmake.org/t/add-external-headers-and-sources/4789/10 "2022-01-08T19:20:50Z")

</div>

Not really because I don’t have your source code 🙂 . But something like this (based on your image):

```cmake
cmake_minimum_required(VERSION 3.16) # pick whatever version has the features you want
project(MyProject)

add_library(Submodule1
  MyLib/Submodule1/foo.c
  MyLib/Submodule1/foo.c)
add_library(Submodule2
  MyLib/Submodule2/foo.c
  MyLib/Submodule2/foo.c)

add_library(MyLib
   MyLib/foo.c
   MyLib/foo.h)
target_link_libraries(MyLib PRIVATE # Choose the visibility as needed
  Submodule1 Submodule2)

```

That should at least start a build going. You’ll probably need boilerplate for testing, installation, flags, options, etc. The [tutorial](https://cmake.org/cmake/help/latest/guide/tutorial/index.html) has examples to follow.

---

<div class="post-metadata">

**Author:** ![bremenpl](https://discourse.cmake.org/user_avatar/discourse.cmake.org/bremenpl/32/2080_2.png) [@bremenpl](https://discourse.cmake.org/u/bremenpl)\
**Post date:** [January 8, 2022, 10:13pm UTC](https://discourse.cmake.org/t/add-external-headers-and-sources/4789/11 "2022-01-08T22:13:57Z")

</div>

Thanks for that! But just a question- in your example, do you assume that the Submodule1 and Submodule1 will be compiled as separate shared libraries? Or is it just an intermediate step and it is the target\_link\_libraries line which creates the output? Or in other words, is this:

```auto
add_library(Submodule1
  MyLib/Submodule1/foo.c
  MyLib/Submodule1/foo.h)
add_library(Submodule2
  MyLib/Submodule2/foo.c
  MyLib/Submodule2/foo.h)

add_library(MyLib
   MyLib/foo.c
   MyLib/foo.h)
target_link_libraries(MyLib PRIVATE # Choose the visibility as needed
  Submodule1 Submodule2)

```

Equal to this?

```auto
add_library(MyLib
   MyLib/Submodule1/foo.c
   MyLib/Submodule1/foo.c)
   MyLib/Submodule2/foo.c
   MyLib/Submodule2/foo.h)
   MyLib/foo.c
   MyLib/foo.h)

```

---

<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:** [January 8, 2022, 11:11pm UTC](https://discourse.cmake.org/t/add-external-headers-and-sources/4789/12 "2022-01-08T23:11:59Z")

</div>

Those are two separate effects. One makes 2 libraries and an executable (which links to them). The other makes a single executable. I would recommend going through the Tutorial.

---

<div class="post-metadata">

**Author:** ![bremenpl](https://discourse.cmake.org/user_avatar/discourse.cmake.org/bremenpl/32/2080_2.png) [@bremenpl](https://discourse.cmake.org/u/bremenpl)\
**Post date:** [January 9, 2022, 6:50am UTC](https://discourse.cmake.org/t/add-external-headers-and-sources/4789/13 "2022-01-09T06:50:04Z")

</div>

By “an executable (which links to them)” did you mean a shared library, or actual executable? Because from what I understand, in the end both scripts produce a shared lib?

I have already started the tutorial- no doubt I need it.

---

<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:** [January 9, 2022, 3:13pm UTC](https://discourse.cmake.org/t/add-external-headers-and-sources/4789/14 "2022-01-09T15:13:02Z")

</div>

Sorry, I thought I used `add_executable` (too much copy pasta). They’re all libraries in that example, yes. Use `add_executable` for executables.

---

<div class="post-metadata">

**Author:** ![bremenpl](https://discourse.cmake.org/user_avatar/discourse.cmake.org/bremenpl/32/2080_2.png) [@bremenpl](https://discourse.cmake.org/u/bremenpl)\
**Post date:** [January 9, 2022, 3:16pm UTC](https://discourse.cmake.org/t/add-external-headers-and-sources/4789/15 "2022-01-09T15:16:14Z")

</div>

So are the outputs of the 2 listings the same? Both produce the same shared lib output?

---

<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:** [January 9, 2022, 8:27pm UTC](https://discourse.cmake.org/t/add-external-headers-and-sources/4789/16 "2022-01-09T20:27:45Z")

</div>

No. One makes 3 shared libraries and the other makes 1.

---

<div class="post-metadata">

**Author:** ![bremenpl](https://discourse.cmake.org/user_avatar/discourse.cmake.org/bremenpl/32/2080_2.png) [@bremenpl](https://discourse.cmake.org/u/bremenpl)\
**Post date:** [January 9, 2022, 8:59pm UTC](https://discourse.cmake.org/t/add-external-headers-and-sources/4789/17 "2022-01-09T20:59:06Z")

</div>

Ok, now understood- thanks.
