# \`CMAKE\_PROJECT\_TOP\_LEVEL\_INCLUDES\` and \`CMAKE\_TOOLCHAIN\_FILE\`

**URL:** https://discourse.cmake.org/t/cmake-project-top-level-includes-and-cmake-toolchain-file/15463
**Category:** Usage
**Created:** [January 16, 2026, 8:50pm UTC](https://discourse.cmake.org/t/cmake-project-top-level-includes-and-cmake-toolchain-file/15463 "2026-01-16T20:50:04Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![planetmarshall](https://discourse.cmake.org/user_avatar/discourse.cmake.org/planetmarshall/32/4413_2.png) [@planetmarshall](https://discourse.cmake.org/u/planetmarshall)
#### Post date: [January 16, 2026, 8:50pm UTC](https://discourse.cmake.org/t/cmake-project-top-level-includes-and-cmake-toolchain-file/15463/1 "2026-01-16T20:50:04Z")

</div>

During the discussion about implementing `CMAKE_PROJECT_TOP_LEVEL_INCLUDES` ([https://gitlab.kitware.com/cmake/cmake/-/issues/22619](https://gitlab.kitware.com/cmake/cmake/-/issues/22619)) there was some discussion on whether the includes should be read before or after the toolchain file, and it was decided that would be the latter.

Is it possible for a dependency provider, implemented via `CMAKE_PROJECT_TOP_LEVEL_INCLUDES`, to influence variables typically specified in a toolchain eg `CMAKE_CXX_COMPILER`?

For a concrete example, say the [conan package integration](https://github.com/conan-io/cmake-conan) downloads an sdk package that provides a toolchain file. That file won’t be ready until the package is downloaded so it can’t be provided to `CMAKE_TOOLCHAIN_FILE` (unless the depdendency provider can set this var?).

The workaround is to invoke conan separately but this is not ideal and having CMake orchestrate the entire process is a better developer experience.

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: [February 9, 2026, 2:22am UTC](https://discourse.cmake.org/t/cmake-project-top-level-includes-and-cmake-toolchain-file/15463/2 "2026-02-09T02:22:31Z")

</div>

Could Conan provide a bootstrap toolchain file that downloads it if not yet done and just includes it if so?

---

<div class="post-metadata">

### Author: ![planetmarshall](https://discourse.cmake.org/user_avatar/discourse.cmake.org/planetmarshall/32/4413_2.png) [@planetmarshall](https://discourse.cmake.org/u/planetmarshall)
#### Post date: [February 10, 2026, 11:54am UTC](https://discourse.cmake.org/t/cmake-project-top-level-includes-and-cmake-toolchain-file/15463/3 "2026-02-10T11:54:40Z")

</div>

Oh that’s an interesting idea.

I’ll try it out and get back to you if it works.

---

<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 14, 2026, 5:21am UTC](https://discourse.cmake.org/t/cmake-project-top-level-includes-and-cmake-toolchain-file/15463/4 "2026-02-14T05:21:27Z")

</div>

> [@planetmarshall](#):
>
> Is it possible for a dependency provider, implemented via `CMAKE_PROJECT_TOP_LEVEL_INCLUDES`, to influence variables typically specified in a toolchain eg `CMAKE_CXX_COMPILER`?

By design, no it shouldn’t be. When the file included via `CMAKE_PROJECT_TOP_LEVEL_INCLUDES` is pulled in (which is where the dependency provider is registered), the project should be assuming the toolchain is fully set up and defined. This is so that things like dependency providers can query those details to decide how to provide the dependencies. The place to modify the toolchain details is the toolchain file. Don’t try to do that within the dependency provider, that’s not what a dependency provider is for.

In the case of cmake-conan, it looks at what the build is using and writes things like host and build profiles to match it. In more complex project hierarchies, being able to work with arbitrary toolchain files that come from outside the project and honouring what those toolchain files specify can be important. From personal experience, the less you mess with those things the better. Stay on the well-trodden happy path as much as you can. Once you stray from that, things quickly become hard to maintain and fragile.

> [@planetmarshall](#):
>
> The workaround is to invoke conan separately but this is not ideal and having CMake orchestrate the entire process is a better developer experience.

Where is your toolchain file coming from when you use cmake-conan? The developer building the project should be in control of that. You shouldn’t be needing to resort to having conan drive the whole build unless you’re creating conan binary packages for other builds to consume.

---

<div class="post-metadata">

### Author: ![planetmarshall](https://discourse.cmake.org/user_avatar/discourse.cmake.org/planetmarshall/32/4413_2.png) [@planetmarshall](https://discourse.cmake.org/u/planetmarshall)
#### Post date: [February 14, 2026, 9:41pm UTC](https://discourse.cmake.org/t/cmake-project-top-level-includes-and-cmake-toolchain-file/15463/5 "2026-02-14T21:41:20Z")

</div>

> [@craig.scott](#):
>
> You shouldn’t be needing to resort to having conan drive the whole build unless you’re creating conan binary packages for other builds to consume.

Conan doesn’t drive the build, it does however provide the artifacts needed for the build, which includes an sdk and toolchain binaries such as clang, libc++, compiler buitlins etc. These are versioned and under source control just like any other package that conan provides. It does this by means of a toolchain package, [described here](https://docs.conan.io/2/examples/cross_build/toolchain_packages.html). As cmake does not initially know where in the conan cache the compiler will be, the conan package generates a toolchain file containing the correct paths.

As long as the developer uses the typical two-stage conan developer flow:

1. `conan install ... `
2. `cmake --preset ...`

Then this works fine.

However, developers have to be reminded to run `conan install` whenever the dependencies or the toolchain needs to be updated.

What I’d really prefer, is for developers to be able to run a one-shot command, for example

```console
$ cmake --preset raspberry-pi

```

Which would leverage `cmake-conan` to automatically update the dependencies when required, possibly downloading and installing a toolchain, and configure the project.

Unfortunately I can’t do this (although I haven’t tried [Ben’s suggestion](https://discourse.cmake.org/t/cmake-project-top-level-includes-and-cmake-toolchain-file/15463/2) yet) because the first thing CMake does is load a toolchain file, and of course conan hasn’t generated it yet.

From the history of `CMAKE_PROJECT_TOP_LEVEL_INCLUDES`, it does seem that this workflow was considered at one point, and I was wondering if it’s still feasible (obviously not currently, but maybe with some changes that won’t break existing workflows) :

> ### Dedicated Provider Injection Point

> …This needs to happen early enough to support what some dependency providers may want to do, but not so early that some important things are not defined yet. Some providers want to control the toolchain details, potentially setting or overriding the `CMAKE_TOOLCHAIN_FILE`, which means they need a point before the first `project()` call starts doing things.

---

<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: [February 14, 2026, 10:28pm UTC](https://discourse.cmake.org/t/cmake-project-top-level-includes-and-cmake-toolchain-file/15463/6 "2026-02-14T22:28:28Z")

</div>

> [@craig.scott](#):
>
> When the file included via `CMAKE_PROJECT_TOP_LEVEL_INCLUDES` is pulled in (which is where the dependency provider is registered), the project should be assuming the toolchain is fully set up and defined.

Perhaps this is a separate issue, but I’ve run into issues in trying to access variables such as `CMAKE_CXX_COMPILER` from within the `CMAKE_PROJECT_TOP_LEVEL_INCLUDES`, which is indeed the documented behavior:

> The files will be included immediately after the toolchain file has been read (if one is specified) and platform variables have been set, but before any languages have been enabled. Therefore, language-specific variables, including things like **[`CMAKE_<LANG>_COMPILER`](https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_COMPILER.html#variable:CMAKE_%3CLANG%3E_COMPILER "CMAKE\_<LANG>\_COMPILER")**, might not be set.

This makes it quite difficult to do anything that reacts to the toolchain from within the top level includes file.
