# Is install() of a target with EXCLUDE\_FROM\_ALL == TRUE really undefined?

**URL:** <https://discourse.cmake.org/t/is-install-of-a-target-with-exclude-from-all-true-really-undefined/5666>\
**Category:** Code\
**Created:** [May 13, 2022, 8:06am UTC](https://discourse.cmake.org/t/is-install-of-a-target-with-exclude-from-all-true-really-undefined/5666 "2022-05-13T08:06:03Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![jobor](https://discourse.cmake.org/user_avatar/discourse.cmake.org/jobor/32/1230_2.png) [@jobor](https://discourse.cmake.org/u/jobor)\
**Post date:** [May 13, 2022, 8:06am UTC](https://discourse.cmake.org/t/is-install-of-a-target-with-exclude-from-all-true-really-undefined/5666/1 "2022-05-13T08:06:03Z")

</div>

In the documentation of the `install` command we can read:

> Installing a target with the [`EXCLUDE_FROM_ALL`](https://cmake.org/cmake/help/latest/prop_tgt/EXCLUDE_FROM_ALL.html#prop_tgt:EXCLUDE_FROM_ALL) target property set to `TRUE` has undefined behavior.

I wonder whether this is really the case. Installation seems to be skipped for such targets.

Assuming there is undefined behavior which we must avoid:  
For those targets I could skip `install` or call `install` with the `EXCLUDE_FROM_ALL` argument.

Now, the `EXCLUDE_FROM_ALL` target property however allows generator expressions.  
The `EXCLUDE_FROM_ALL` argument of `install` does not.  
For targets that have `EXCLUDE_FROM_ALL` set to some generator expression I cannot just skip `install` nor can I use `install`’s `EXCLUDE_FROM_ALL` option.

Can someone clarify whether the documentation is correct - and if yes, how to handle the latter case of targets with `EXCLUDE_FROM_ALL` set to a generator expression?

---

<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, 2022, 10:34am UTC](https://discourse.cmake.org/t/is-install-of-a-target-with-exclude-from-all-true-really-undefined/5666/2 "2022-05-13T10:34:26Z")

</div>

The main issue is that the install script has no idea how much of the build has completed. The `install` target just depends on `all`, so the installation of `EXCLUDE_FROM_ALL` targets doesn’t guarantee they’ll actually be available. The documentation is basically just a license for CMake to skip the `if (EXISTS)` check for complicated things (probably historical).

As for `install(EXCLUDE_FROM_ALL <genex>)`, the main question is in what context is the genex evaluated? It’s easy for `install(TARGETS)` (it’d be evaluated once per target), but `install(FILES)` won’t have any implicit target context. If such questions have reasonable answers, I think it’d just be a feature request.

---

<div class="post-metadata">

**Author:** ![benthevining](https://discourse.cmake.org/user_avatar/discourse.cmake.org/benthevining/32/1924_2.png) [@benthevining](https://discourse.cmake.org/u/benthevining)\
**Post date:** [May 13, 2022, 1:42pm UTC](https://discourse.cmake.org/t/is-install-of-a-target-with-exclude-from-all-true-really-undefined/5666/3 "2022-05-13T13:42:58Z")

</div>

what about if the install command is an EXCLUDE\_FROM\_ALL target, but the install cmd had the OPTIONAL flag? That should be well defined, no?

---

<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, 2022, 2:26pm UTC](https://discourse.cmake.org/t/is-install-of-a-target-with-exclude-from-all-true-really-undefined/5666/4 "2022-05-13T14:26:55Z")

</div>

That’s fine as `OPTIONAL` doesn’t care if the source file exists or not.

---

<div class="post-metadata">

**Author:** ![jobor](https://discourse.cmake.org/user_avatar/discourse.cmake.org/jobor/32/1230_2.png) [@jobor](https://discourse.cmake.org/u/jobor)\
**Post date:** [May 13, 2022, 2:31pm UTC](https://discourse.cmake.org/t/is-install-of-a-target-with-exclude-from-all-true-really-undefined/5666/5 "2022-05-13T14:31:03Z")

</div>

I see. Thanks for your answer!

For the `install(EXCLUDE_FROM_ALL <genex>)` case I was indeed thinking of `install(TARGETS)`, not `install(FILES)`.

---

<div class="post-metadata">

**Author:** ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)\
**Post date:** [February 14, 2023, 9:33pm UTC](https://discourse.cmake.org/t/is-install-of-a-target-with-exclude-from-all-true-really-undefined/5666/6 "2023-02-14T21:33:38Z")

</div>

**IMHO** : This is a bigger problem in use case with `FetchContent` or `CPM.cmake`!

see [Show the EXCLUDE\_FROM\_ALL problem by ClausKlein · Pull Request #5 · ClausKlein/ModernCmakeStarter · GitHub](https://github.com/ClausKlein/ModernCmakeStarter/pull/5)

We want to compile only the target we use, and we try to prevent compiler warnings and clang-tidy issues.

### But we need to install this target?

---

<div class="post-metadata">

**Author:** ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)\
**Post date:** [February 16, 2023, 4:44am UTC](https://discourse.cmake.org/t/is-install-of-a-target-with-exclude-from-all-true-really-undefined/5666/7 "2023-02-16T04:44:46Z")

</div>

@craig.scott Is this behaiviour really undefined or intended?

---

<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:** [February 16, 2023, 10:47pm UTC](https://discourse.cmake.org/t/is-install-of-a-target-with-exclude-from-all-true-really-undefined/5666/8 "2023-02-16T22:47:55Z")

</div>

> [@ClausKlein](#):
>
> Is this behaiviour really undefined or intended?

Can you be specific about which aspect of behavior you are referring to? Rather than me guess/assume, it would be better to be crystal clear what you want to clarify.

---

<div class="post-metadata">

**Author:** ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)\
**Post date:** [February 17, 2023, 6:01am UTC](https://discourse.cmake.org/t/is-install-of-a-target-with-exclude-from-all-true-really-undefined/5666/9 "2023-02-17T06:01:23Z")

</div>

### NOTE: EXCLUDE\_FROM\_ALL must be OFF or `fmt` target will NOT be installed! CK

```cmake
 option(FMT_INSTALL "create an installable target" YES)
 CPMAddPackage(
   NAME fmt
   GIT_TAG 9.1.0
   GITHUB_REPOSITORY fmtlib/fmt
   EXCLUDE_FROM_ALL NO
   SYSTEM YES # used if CMake v3.25 is available
 )

```

This use `FetchContent` to clone the git repo and `add_subdirectory(... fmt SYSTEM)`

---

<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:** [February 17, 2023, 6:12am UTC](https://discourse.cmake.org/t/is-install-of-a-target-with-exclude-from-all-true-really-undefined/5666/10 "2023-02-17T06:12:11Z")

</div>

I’m not familiar with the internals of what CPM does with the `EXCLUDE_FROM_ALL` keyword. FetchContent itself does not have that keyword, so you’d have to look at what CPM is doing with it. That keyword is used for a number of CMake commands, but not FetchContent. I think you should take that up with the CPM maintainers. Your query doesn’t seem to be directly aligned with the focus of this particular discussion topic (which does not involve FetchContent).

---

<div class="post-metadata">

**Author:** ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)\
**Post date:** [February 17, 2023, 6:15am UTC](https://discourse.cmake.org/t/is-install-of-a-target-with-exclude-from-all-true-really-undefined/5666/11 "2023-02-17T06:15:32Z")

</div>

> [@ClausKlein](#):
>
> This use `FetchContent` to clone the git repo and `add_subdirectory(... fmt SYSTEM)`

If set to ON, the default, it results in

```cmake
add_subdirectory(... fmt SYSTEM EXCLUCE_FROM_ALL)

```

---

<div class="post-metadata">

**Author:** ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)\
**Post date:** [February 17, 2023, 6:23am UTC](https://discourse.cmake.org/t/is-install-of-a-target-with-exclude-from-all-true-really-undefined/5666/12 "2023-02-17T06:23:30Z")

</div>

… and if I use `cmake -D FMT_INSTALL=NO`, it results in an CMake configure error:

```auto
CMake Error: install(EXPORT "greeterTargets" ...) includes target "greeter" which requires target "fmt" that is not in any export set.
-- Generating done
CMake Generate step failed. Build files cannot be regenerated correctly.
make: *** [install] Error 1
bash-3.2$ 

```

---

<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:** [February 17, 2023, 6:25am UTC](https://discourse.cmake.org/t/is-install-of-a-target-with-exclude-from-all-true-really-undefined/5666/13 "2023-02-17T06:25:30Z")

</div>

Please take the discussion of CPM and EXCLUDE\_FROM\_ALL to a separate thread. FetchContent does not add EXCLUDE\_FROM\_ALL anywhere. Let’s keep this discussion here focused on the original poster’s topic, which has more to do with the EXCLUDE\_FROM\_ALL target property and the same keyword with the `install()` command.

Regarding the overarching theme of excluding things from the ALL target and then installing them, the thing to remember is that if a target is excluded from ALL, then you the user are responsible for ensuring it is built if you then do something that wants to install that target. The documentation for the `install()` command calls this undefined behavior, but that’s perhaps a bit strong. In reality, my preceding sentence is the real constraint, as far as I’m aware (but I haven’t checked how export sets affect the picture).

---

<div class="post-metadata">

**Author:** ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)\
**Post date:** [February 17, 2023, 6:30am UTC](https://discourse.cmake.org/t/is-install-of-a-target-with-exclude-from-all-true-really-undefined/5666/14 "2023-02-17T06:30:18Z")

</div>

OK, thanks 😕

**IMHO** : It is too complicated! 🤯  
see too [CMake Error: install(EXPORT "ProjectTargets" ...) includes target "xxx" which requires target "yyy" that is not in any export set.](https://discourse.cmake.org/t/cmake-error-install-export-projecttargets-includes-target-xxx-which-requires-target-yyy-that-is-not-in-any-export-set/7344)

and [Feature/exclude from all problem by ClausKlein · Pull Request #7 · ClausKlein/ModernCmakeStarter · GitHub](https://github.com/ClausKlein/ModernCmakeStarter/pull/7)
