# How to connect custom command to a target (add\_library) in a parent directory

**URL:** <https://discourse.cmake.org/t/how-to-connect-custom-command-to-a-target-add-library-in-a-parent-directory/8073>\
**Category:** Code\
**Created:** [May 7, 2023, 5:15pm UTC](https://discourse.cmake.org/t/how-to-connect-custom-command-to-a-target-add-library-in-a-parent-directory/8073 "2023-05-07T17:15:05Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![rturrado](https://discourse.cmake.org/user_avatar/discourse.cmake.org/rturrado/32/3499_2.png) [@rturrado](https://discourse.cmake.org/u/rturrado)\
**Post date:** [May 7, 2023, 5:15pm UTC](https://discourse.cmake.org/t/how-to-connect-custom-command-to-a-target-add-library-in-a-parent-directory/8073/1 "2023-05-07T17:15:05Z")

</div>

Hi all,

I have a few `add_custom_command`s that generate files (e.g. via `flex_target`). Those files are used as input by an `add_library` command. The [CMake documentation](https://cmake.org/cmake/help/latest/command/add_custom_command.html) is quite clear in that, for the `add_custom_command` _magic_ to happen, the command and the target should be in the same `CMakeLists.txt` (emphasis mine):

> A target created **in the same directory** (`CMakeLists.txt` file) that specifies any output of the custom command as a source file is given a rule to generate the file using the command at build time.

If I wanted to move those `add_custom_command`s to `CMakeLists.txt` into different subdirectories, would it be any way of still keeping the `add_custom_command` functionality/_magic_? E.g. this is what I’d like to have:

```auto
src/CMakeListst.txt:
    add_library(blah OBJECT ${files_1} ${files_2})
src/v1/CMakeLists.txt:
    add_custom_command(OUTPUT files_1)
src/v2/CMakeLists.txt:
    add_custom_command(OUTPUT files_2)

```

Thanks!

---

<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:** [May 8, 2023, 6:36pm UTC](https://discourse.cmake.org/t/how-to-connect-custom-command-to-a-target-add-library-in-a-parent-directory/8073/2 "2023-05-08T18:36:27Z")

</div>

I think you’d need to inject an `add_custom_target()` that `DEPENDS` on the files and then depend on them from the `blah` target.

---

<div class="post-metadata">

**Author:** ![rturrado](https://discourse.cmake.org/user_avatar/discourse.cmake.org/rturrado/32/3499_2.png) [@rturrado](https://discourse.cmake.org/u/rturrado)\
**Post date:** [May 12, 2023, 9:51am UTC](https://discourse.cmake.org/t/how-to-connect-custom-command-to-a-target-add-library-in-a-parent-directory/8073/3 "2023-05-12T09:51:26Z")

</div>

Thanks for the answer, Ben.

I may have done something wrong, but the following didn’t work for me:

```auto
src/CMakeListst.txt:
    add_subdirectory(v1)
    add_library(blah OBJECT ${files_1})
src/v1/CMakeLists.txt:
    add_custom_command(OUTPUT files_1)
    set(files_1 ${files_1} PARENT_SCOPE)
    add_custom_target(generate_files_1 DEPENDS ${files_1})

```

---

<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:** [May 12, 2023, 10:29am UTC](https://discourse.cmake.org/t/how-to-connect-custom-command-to-a-target-add-library-in-a-parent-directory/8073/4 "2023-05-12T10:29:21Z")

</div>

> [@rturrado](#):
>
> ```auto
> set(files_1 ${files_1} PARENT_SCOPE)
> add_custom_target(generate_files_1 DEPENDS ${files_1})
> 
> ```

Does it work if you flip these lines? `set(PARENT_SCOPE)` has some weird behavior on local variables (namely, it sets the value you request to the parent scope, but it also pulls the previous state down into the current scope).

---

<div class="post-metadata">

**Author:** ![rturrado](https://discourse.cmake.org/user_avatar/discourse.cmake.org/rturrado/32/3499_2.png) [@rturrado](https://discourse.cmake.org/u/rturrado)\
**Post date:** [May 12, 2023, 10:57am UTC](https://discourse.cmake.org/t/how-to-connect-custom-command-to-a-target-add-library-in-a-parent-directory/8073/5 "2023-05-12T10:57:20Z")

</div>

Unfortunately not!

---

<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:** [May 12, 2023, 9:53pm UTC](https://discourse.cmake.org/t/how-to-connect-custom-command-to-a-target-add-library-in-a-parent-directory/8073/6 "2023-05-12T21:53:26Z")

</div>

> [@ben.boeckel](#):
>
> `set(PARENT_SCOPE)` has some weird behavior on local variables (namely, it sets the value you request to the parent scope, but it also pulls the previous state down into the current scope).

@ben.boeckel Is there an issue open about this? This is the first I’ve heard of that behavior.

---

<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:** [May 13, 2023, 1:01pm UTC](https://discourse.cmake.org/t/how-to-connect-custom-command-to-a-target-add-library-in-a-parent-directory/8073/7 "2023-05-13T13:01:05Z")

</div>

I don’t think so; it’s Just the Way it’s Been™. A policy is probably useful, but it will have to be one of those silent policies and it is highly likely to actually cause subtle differences. The docs do cover this behavior:

> [@](#):
>
> The previous state of the variable’s value  
> stays the same in the current scope (e.g., if it was undefined before, it is  
> still undefined and if it had a value, it is still that value).

---

<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:** [May 13, 2023, 1:02pm UTC](https://discourse.cmake.org/t/how-to-connect-custom-command-to-a-target-add-library-in-a-parent-directory/8073/8 "2023-05-13T13:02:35Z")

</div>

In that case, I’d have to sit down and investigate it more. I’m afraid I don’t have time for that though right now ☹ . Could you please file an issue outlining the problem with a small example so that it’s easier to find. I suspect this will likely just end up as a documentation update to mention the limitation, but even that is an improvement.

---

<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:** [May 14, 2023, 8:23am UTC](https://discourse.cmake.org/t/how-to-connect-custom-command-to-a-target-add-library-in-a-parent-directory/8073/9 "2023-05-14T08:23:46Z")

</div>

> [@ben.boeckel](#):
>
> `set(PARENT_SCOPE)` has some weird behavior on local variables (namely, it sets the value you request to the parent scope, but it also pulls the previous state down into the current scope).

> [@ben.boeckel](#):
>
> The docs do cover this behavior:
> 
> > [@](#):
> >
> > The previous state of the variable’s value  
> > stays the same in the current scope (e.g., if it was undefined before, it is  
> > still undefined and if it had a value, it is still that value).

I read that differently to the way you seem to be interpreting it. To me, that says `set(var someValue PARENT_SCOPE)` leaves the value of `var` untouched in the current scope. And indeed, this is the behavior I see, as confirmed with the following smaller demonstrator (run this with `cmake -P`):

```cmake
cmake_minimum_required(VERSION 3.25)

set(var "first")

block()
    set(var "second")
    set(var "third" PARENT_SCOPE)
    message(STATUS "var = ${var}")
endblock()

```

This outputs `second`, as I would expect.

---

<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:** [May 14, 2023, 12:30pm UTC](https://discourse.cmake.org/t/how-to-connect-custom-command-to-a-target-add-library-in-a-parent-directory/8073/10 "2023-05-14T12:30:39Z")

</div>

Ok, so we agree, but we’re thinking about it from opposite directions 🙂 . In terms of implementation, it pulls the `cmDefinition` down into the current scope and then tells the parent scope about the new value.

> [@rturrado](#):
>
> ```auto
> set(files_1 ${files_1} PARENT_SCOPE)
> add_custom_target(generate_files_1 DEPENDS ${files_1})
> 
> ```

This code would set `files_1` in the parent scope and pull its definition “down”, probably leaving an empty/undefined/stale value to end up there for the `add_custom_target` command.

---

<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:** [May 14, 2023, 10:17pm UTC](https://discourse.cmake.org/t/how-to-connect-custom-command-to-a-target-add-library-in-a-parent-directory/8073/11 "2023-05-14T22:17:45Z")

</div>

> [@ben.boeckel](#):
>
> This code would set `files_1` in the parent scope and pull its definition “down”, probably leaving an empty/undefined/stale value to end up there for the `add_custom_target` command.

I still don’t follow this, and find it a bit confusing. From a user’s perspective, there is no “pulling down” like you describe. The variables in the current scope are copied from the parent when the current scope was first created. Any subsequent call to `set(files_1 ... PARENT_SCOPE)` should only be affecting the `files_1` variable in the parent scope, there should be no effect on variables in the current scope. I don’t see where any “pulling down” is occurring.

---

<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:** [May 14, 2023, 11:23pm UTC](https://discourse.cmake.org/t/how-to-connect-custom-command-to-a-target-add-library-in-a-parent-directory/8073/12 "2023-05-14T23:23:33Z")

</div>

Maybe my mental model is poisoned from when I attempted optimizations in this area. I’ll have to experiment again.

---

<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:** [May 15, 2023, 12:06am UTC](https://discourse.cmake.org/t/how-to-connect-custom-command-to-a-target-add-library-in-a-parent-directory/8073/13 "2023-05-15T00:06:17Z")

</div>

Yes, this is probably it. I had once attempted to make variable lookups go up the scope parentage looking for variables rather than copying them wholesale at scope creation (IIRC, I had tried to pull used definitions down to avoid chasing the chain all the time as well). The expected behaviors of `PARENT_SCOPE` had thrown a wrench into things somehow and it never went anywhere and this is where the “pull down” in my mind distilling probably comes from.

Looking at the code, it seems that it was eventually done, but it was just a quick glance.
