# "Mapping" lists of dependents and dependees files?

**URL:** https://discourse.cmake.org/t/mapping-lists-of-dependents-and-dependees-files/1934
**Category:** Code
**Created:** [September 29, 2020, 3:10am UTC](https://discourse.cmake.org/t/mapping-lists-of-dependents-and-dependees-files/1934 "2020-09-29T03:10:28Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![swoo.quek](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/s/94ad74/32.png) [@swoo.quek](https://discourse.cmake.org/u/swoo.quek)
#### Post date: [September 29, 2020, 3:10am UTC](https://discourse.cmake.org/t/mapping-lists-of-dependents-and-dependees-files/1934/1 "2020-09-29T03:10:28Z")

</div>

Is there a way to “map” a list of dependants and dependees files?

Like below:

> set(IF\_f \< **file1.h** file2.h\>)

> add\_custom\_command(  
> OUTPUT \< **file1.obj** file2.obj\>  
> COMMAND ${CMAKE\_CXX\_COMPILER} -debug -nofpu -output=obj=\< **file1.obj** file2.obj\> \< **file1.c** file2.c\>  
> **DEPENDS ${IF\_f}**  
> VERBATIM  
> )

> add\_custom\_target(  
> what ALL  
> DEPENDS \< **file1.obj** file2.obj\>  
> VERBATIM  
> )

Sorry about the wrong use of `<>`, it is just fiducial to represent a list of files which are to be mapped

What I really want is:  
When **file1.h** changes, the command will be executed and **ONLY**  **file1.obj** is generated (not file2.obj)  
Likewise:  
When **file2.h** changes, the command will be executed and **ONLY**  **file2.obj** is generated (not file1.obj)

Is it possible in CMake?

---

<div class="post-metadata">

### Author: ![swoo.quek](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/s/94ad74/32.png) [@swoo.quek](https://discourse.cmake.org/u/swoo.quek)
#### Post date: [September 29, 2020, 3:28am UTC](https://discourse.cmake.org/t/mapping-lists-of-dependents-and-dependees-files/1934/2 "2020-09-29T03:28:00Z")

</div>

Can I do the following:

> foreach(fileN\_list)  
> set(IF\_f each\_file\_in\_the\_list)  
> add\_custom\_command(…)  
> add\_custom\_target(…)  
> endforeach(…)

Which means if I have 10 files, then there will be 10 sets of add\_custom\_command() and add\_custom\_target(), kind of brute-force method

---

<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 29, 2020, 7:42am UTC](https://discourse.cmake.org/t/mapping-lists-of-dependents-and-dependees-files/1934/3 "2020-09-29T07:42:57Z")

</div>

I believe the correct solution is half-way between the alternatives you have posted: one custom command per object file, and then one custom target to depend on all the object files. Very similar to how CMake handles native (non-custom) compilation:

```
set(object_list "")
foreach(file IN LISTS file_list)
  add_custom_command(
    OUTPUT ${file}.obj
    COMMAND ${CMAKE_CXX_COMPILER} -debug -nofpu -output=obj=${file}.obj ${file}.c
    DEPENDS ${file}.c ${other_dependencies_if_any}
    VERBATIM
  )
  list(APPEND object_list ${file}.obj)
endforeach()

add_custom_target(
  what ALL
  DEPENDS ${object_list}
)

```

That way, building the custom target `what` will always check that all the object files are up-to-date, but since each is produced by its own custom command, only those out of date will be recompiled.

* * *

However, this smells a bit of an [XY problem](http://xyproblem.info/). CMake has native support for compiling C[++] sources; it’s its primary purpose of existence, after all. Even if your desired final artifact are object files and not a library/executable, you should be able to achieve building them "CMake-natively’ using an OBJECT library. Are you sure you _need_ to use custom commands in your situation?

---

<div class="post-metadata">

### Author: ![swoo.quek](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/s/94ad74/32.png) [@swoo.quek](https://discourse.cmake.org/u/swoo.quek)
#### Post date: [September 29, 2020, 8:53am UTC](https://discourse.cmake.org/t/mapping-lists-of-dependents-and-dependees-files/1934/4 "2020-09-29T08:53:17Z")

</div>

Dear Petr,

Thanks for explaining. I will try the method you mentioned

> you should be able to achieve building them "CMake-natively’ using an OBJECT library

I will look it up!

Thanks!

---

<div class="post-metadata">

### Author: ![swoo.quek](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/s/94ad74/32.png) [@swoo.quek](https://discourse.cmake.org/u/swoo.quek)
#### Post date: [September 29, 2020, 1:30pm UTC](https://discourse.cmake.org/t/mapping-lists-of-dependents-and-dependees-files/1934/5 "2020-09-29T13:30:22Z")

</div>

Dear Petr,

Just one more question. Why wouldn’t the following work?

> add\_executable(${SOURCE} file1.h file2.h)

?

---

<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 29, 2020, 1:41pm UTC](https://discourse.cmake.org/t/mapping-lists-of-dependents-and-dependees-files/1934/6 "2020-09-29T13:41:13Z")

</div>

> [@swoo.quek](#):
>
> ust one more question. Why wouldn’t the following work?
> 
> > add\_executable(${SOURCE} file1.h file2.h)
> 
> ?

Whether that works or not depends on the contents of the variable `SOURCE`.

The first argument to `add_executable()` must be the name of the target being created (e.g. `MyExe`). The other arguments are source (and optionally header) files that constitute the target. So typical usage of `add_executable()` could look like this:

```
add_executable(
  MyExe
  main.c file1.c file2.c
  file1.h file2.h
)

```

That would create an executable named `MyExe` which is composed of 3 object files (which in turn are each compiled from one C file).

---

<div class="post-metadata">

### Author: ![swoo.quek](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/s/94ad74/32.png) [@swoo.quek](https://discourse.cmake.org/u/swoo.quek)
#### Post date: [September 29, 2020, 1:47pm UTC](https://discourse.cmake.org/t/mapping-lists-of-dependents-and-dependees-files/1934/7 "2020-09-29T13:47:00Z")

</div>

Thanks Petr,

My bad. You’re right, I meant to ask:

> Why add\_executable(MyExe ${SOURCE} file1.h file2.h) won’t work?  
> My expectation is that with above command, if file1.h is changed, “make all” will rebuild the target. This is not happening  
> Conversely, if anyone of the \*.c file is changed, “make all” will rebuild the target. This works fine  
> Or is my expectation wrong?

where SOURCE just consists of all \*.c file

Does add\_executable() ignore header files (I read somewhere)?

---

<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 29, 2020, 2:18pm UTC](https://discourse.cmake.org/t/mapping-lists-of-dependents-and-dependees-files/1934/8 "2020-09-29T14:18:54Z")

</div>

Listing header files as `add_executable` arguments has no effect on whether changing them causes the executable to rebuild. However, if the header files are `#include`-d normally by the source files of the exe, the dependency on them should be picked up automatically by CMake (and I can assure you that in normal cases, it works. I’ve verified that countless times in many projects, both work and personal).

Is the dependency on the header files somehow hidden in the source files? (Such as being produced by macro expansion)?

---

<div class="post-metadata">

### Author: ![swoo.quek](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/s/94ad74/32.png) [@swoo.quek](https://discourse.cmake.org/u/swoo.quek)
#### Post date: [September 29, 2020, 4:06pm UTC](https://discourse.cmake.org/t/mapping-lists-of-dependents-and-dependees-files/1934/9 "2020-09-29T16:06:24Z")

</div>

Dear Petr,

> if the header files are `#include` -d normally by the source files of the exe, the dependency on them should be picked up automatically by CMake

Could what you said above be compiler dependant? My project is an embedded project and uses compiler from the MCU vendor. Unfortunately, the “automatic pick up by CMake” _seems_ not supported

> Is the dependency on the header files somehow hidden in the source files? (Such as being produced by macro expansion)?

I think I know what you are getting at. If I build the project normally with the MCU’s **IDE (which has a built in builder, and GNU Make)**, then dependency files will be generated. In this case, `file1.c` will have a corresponding `file1.d` generated, where the content of `file1.d` looks like this:

> #makefile format  
> file1.obj file1.d: …/file1.c  
> file1.obj file1.d: …/file1.h  
> file1.h:  
> file1.obj file1.d: …/file1\_1.h  
> file1\_1.h:

`file1.d` therefore contains all dependencies information of `file1.obj`, which depends on:  
`file1.c`, `file1.h`, `file1_1.h`

Unfortunately, I do not know how to pass this dependencies information contained in `file1.d` to CMake

---

<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 30, 2020, 8:02am UTC](https://discourse.cmake.org/t/mapping-lists-of-dependents-and-dependees-files/1934/10 "2020-09-30T08:02:06Z")

</div>

> [@swoo.quek](#):
>
> > if the header files are `#include` -d normally by the source files of the exe, the dependency on them should be picked up automatically by CMake
> 
> Could what you said above be compiler dependant? My project is an embedded project and uses compiler from the MCU vendor. Unfortunately, the “automatic pick up by CMake” _seems_ not supported

I am afraid I don’t know enough about the internals of CMake’s header dependency discovery to answer that, sorry.
