# AUTOMOC on the Visual Studio generators: two extra projects per target since 4.4.0 — could this be made configurable?

**URL:** https://discourse.cmake.org/t/automoc-on-the-visual-studio-generators-two-extra-projects-per-target-since-4-4-0-could-this-be-made-configurable/15768
**Category:** Development
**Created:** [August 1, 2026, 1:29am UTC](https://discourse.cmake.org/t/automoc-on-the-visual-studio-generators-two-extra-projects-per-target-since-4-4-0-could-this-be-made-configurable/15768 "2026-08-01T01:29:52Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![amoyer](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/a/b19c9b/32.png) [@amoyer](https://discourse.cmake.org/u/amoyer)
#### Post date: [August 1, 2026, 1:29am UTC](https://discourse.cmake.org/t/automoc-on-the-visual-studio-generators-two-extra-projects-per-target-since-4-4-0-could-this-be-made-configurable/15768/1 "2026-08-01T01:29:52Z")

</div>

Hi all,

We maintain a fairly large Qt-based software, with around 790 Visual Studio projects.  
Moving CMake from 4.3.4 to 4.4.0 took the solution to roughly 2210.  
Every target with `AUTOMOC` enabled now gets two extra ones, `<target>_autogen` and `<target>_autogen_timestamp_deps`.

I did some digging before posting.  
It comes from 680fbb112a (MR !11844), which enables depfile support for the Visual Studio and Xcode generators.  
A `PRE_BUILD` event cannot carry depfile dependencies, so `usePRE_BUILD` gets cleared and the autogen step becomes a separate target instead of a pre-build step on the origin target.

To be clear, I am not reporting a bug. The commit message is explicit about the trade-off, and the incremental-correctness win is real. We would rather have moc rerun when a transitively included header changes.  
The catch is the IDE cost. At around 2200 projects, loading and navigating the solution in Visual Studio gets noticeably slower. That is the exact concern recorded in the comment that still sits above the affected code:

> // Under VS use a PRE\_BUILD event instead of a separate target to  
> // reduce the number of targets loaded into the IDE.

As far as I can tell there is no way to keep the old path. `useDepfile` is decided from the generator name and the Qt version alone, and nothing is exposed through a variable, a target property or a policy.  
Hence my question.  
Would a `CMAKE_AUTOGEN_USE_DEPFILE` variable with a matching `AUTOGEN_USE_DEPFILE` target property be conceivable, with the current behaviour kept as the default?  
A per-target property would suit us best: we could enable depfiles on the few targets where accuracy matters and leave the rest alone.

There seems to be precedent nearby. `AUTOGEN_ORIGIN_DEPENDS`, `AUTOGEN_USE_SYSTEM_INCLUDE`, `AUTOGEN_PARALLEL` and `AUTOGEN_BETTER_GRAPH_MULTI_CONFIG` are each exposed as a variable plus a target property.  
I would rather ask for a durable knob than a policy.  
The trade-off between incremental accuracy and IDE target count is permanent, not a legacy behaviour waiting to be phased out.

Two side notes:

- The change is confined to the 4.4 series. 680fbb112a is reachable from `v4.4.0-rc1` onward and from no `v4.3.*` tag. Since the 4.3 branch ends at 4.3.4, staying there is a freeze rather than a workaround.
- The 4.4.2 docs still describe the old behaviour. [The `<ORIGIN>\_autogen_timestamp_deps` target](https://cmake.org/cmake/help/v4.4/manual/cmake-qt.7.html#the-origin-autogen-timestamp-deps-target) restricts the target to Ninja and Makefiles, and [Visual Studio Generators](https://cmake.org/cmake/help/v4.4/manual/cmake-qt.7.html#visual-studio-generators) still presents `PRE_BUILD` as the normal case, with three exceptions, none of them the depfile condition.

I tried the issue tracker first, but my account is new and got flagged as spam. 😕  
Happy to move this over there if that is the better place.

## What I measured

A single static library with one `Q_OBJECT` class, Visual Studio 17 2022, x64, Qt from vcpkg.

| CMake | Qt | autogen projects added | `PreBuildEvent` in `thing.vcxproj` |
| --- | --- | --- | --- |
| 4.3.4 | 5.15.12 | 0 | yes |
| 4.4.0 | 5.15.12 | 2 | no |
| 4.3.4 | 6.6.1 | 0 | yes |
| 4.4.0 | 6.6.1 | 2 | no |
| 4.3.4 | 6.11.1 | 0 | yes |
| 4.4.0 | 6.11.1 | 2 | no |

4.4.2 behaves like 4.4.0 (tested with Qt 6).

## Reproducer

`CMakeLists.txt`:

```cmake
# Project count generated by the Visual Studio generator:
# CMake 4.3.4 -> 3 (CompilerIdCXX, thing, VCTargetsPath)
# CMake 4.4.0 -> 5 (CompilerIdCXX, thing, thing_autogen, thing_autogen_timestamp_deps, VCTargetsPath)

cmake_minimum_required(VERSION 3.28)
project(autogen_vs_repro LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_AUTOMOC ON)

find_package(Qt5 QUIET COMPONENTS Core)
if (Qt5_FOUND)
  set(QT_CORE_TARGET Qt5::Core)
  set(QT_VERSION ${Qt5_VERSION})
else()
  find_package(Qt6 REQUIRED COMPONENTS Core)
  set(QT_CORE_TARGET Qt6::Core)
  set(QT_VERSION ${Qt6_VERSION})
endif()

add_library(thing STATIC thing.cpp thing.h)
target_link_libraries(thing PRIVATE ${QT_CORE_TARGET})

message(STATUS "CMake version ..... ${CMAKE_VERSION}")
message(STATUS "Qt version ........ ${QT_VERSION}")
message(STATUS "Generator ......... ${CMAKE_GENERATOR}")

```

`thing.h`:

```cpp
#pragma once
#include <QObject>

class Thing : public QObject
{
    Q_OBJECT
public:
    explicit Thing(QObject \*parent = nullptr);
};

```

`thing.cpp`:

```cpp
#include "thing.h"

Thing::Thing(QObject \*parent)
    : QObject(parent)
{
}

```

Configure with:

```auto
cmake -S . -B build -G "Visual Studio 17 2022" -A x64 -DCMAKE_TOOLCHAIN_FILE=<vcpkg>/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows

```

Any Qt installation works. The vcpkg toolchain is simply how ours is provided.

---

<div class="post-metadata">

### Author: ![brad.king](https://discourse.cmake.org/user_avatar/discourse.cmake.org/brad.king/32/11_2.png) [@brad.king](https://discourse.cmake.org/u/brad.king)
#### Post date: [August 3, 2026, 2:19pm UTC](https://discourse.cmake.org/t/automoc-on-the-visual-studio-generators-two-extra-projects-per-target-since-4-4-0-could-this-be-made-configurable/15768/2 "2026-08-03T14:19:15Z")

</div>

Cc: @jobor @alcroito

---

<div class="post-metadata">

### Author: ![xinouch](https://discourse.cmake.org/user_avatar/discourse.cmake.org/xinouch/32/6209_2.png) [@xinouch](https://discourse.cmake.org/u/xinouch)
#### Post date: [August 4, 2026, 9:37am UTC](https://discourse.cmake.org/t/automoc-on-the-visual-studio-generators-two-extra-projects-per-target-since-4-4-0-could-this-be-made-configurable/15768/3 "2026-08-04T09:37:18Z")

</div>

This is indeed quite surprising and no clear mention in the changelog.

It seems there is the `AUTOGEN_TARGET_FOLDER` to put all these new projects into one folder: [https://cmake.org/cmake/help/latest/prop\_gbl/AUTOGEN\_TARGETS\_FOLDER.html](https://cmake.org/cmake/help/latest/prop_gbl/AUTOGEN_TARGETS_FOLDER.html)

---

<div class="post-metadata">

### Author: ![amoyer](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/a/b19c9b/32.png) [@amoyer](https://discourse.cmake.org/u/amoyer)
#### Post date: [August 4, 2026, 9:58am UTC](https://discourse.cmake.org/t/automoc-on-the-visual-studio-generators-two-extra-projects-per-target-since-4-4-0-could-this-be-made-configurable/15768/4 "2026-08-04T09:58:57Z")

</div>

Thanks for the pointer.

We do use `AUTOGEN_TARGETS_FOLDER` and it does keep the solution navigable.  
It only groups the projects though, it doesn not reduce their number, so the load and navigation cost stays.

Worth noting: we also relied on that folder as a diagnostic.  
Under 4.3.4, an `_autogen`target showing up there was a signal. It meant that something had disabled the `PRE_BUILD` path for that target, usually a generated file being parsed by autogen.

Now that every AUTOMOC target has one, that signal is gone.

---

<div class="post-metadata">

### Author: ![alcroito](https://discourse.cmake.org/user_avatar/discourse.cmake.org/alcroito/32/186_2.png) [@alcroito](https://discourse.cmake.org/u/alcroito)
#### Post date: [August 10, 2026, 9:02am UTC](https://discourse.cmake.org/t/automoc-on-the-visual-studio-generators-two-extra-projects-per-target-since-4-4-0-could-this-be-made-configurable/15768/5 "2026-08-10T09:02:58Z")

</div>

It would of course be best if we can find some way to reduce the IDE load, while keeping the new dependency tracking.

If that ends up impossible, having an opt out probably makes sense, although that would come at the maintenance cost of never being able to remove the old code path that doesn’t use dep files.

Either way, I think you should file two bug reports: one for the IDE load, with a possible solution being opting out, and another for the outdated documentation.

---

<div class="post-metadata">

### Author: ![amoyer](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/a/b19c9b/32.png) [@amoyer](https://discourse.cmake.org/u/amoyer)
#### Post date: [August 10, 2026, 1:40pm UTC](https://discourse.cmake.org/t/automoc-on-the-visual-studio-generators-two-extra-projects-per-target-since-4-4-0-could-this-be-made-configurable/15768/6 "2026-08-10T13:40:35Z")

</div>

Thank you, I just did.

For reference:

- [outdated documentation](https://gitlab.kitware.com/cmake/cmake/-/work_items/28033)
- [IDE load issue](https://gitlab.kitware.com/cmake/cmake/-/work_items/28034)

---

<div class="post-metadata">

### Author: ![neundorf](https://discourse.cmake.org/user_avatar/discourse.cmake.org/neundorf/32/2075_2.png) [@neundorf](https://discourse.cmake.org/u/neundorf)
#### Post date: [August 10, 2026, 7:19pm UTC](https://discourse.cmake.org/t/automoc-on-the-visual-studio-generators-two-extra-projects-per-target-since-4-4-0-could-this-be-made-configurable/15768/7 "2026-08-10T19:19:59Z")

</div>

Slightly related: when I updated from CMake 3 to 4, I suddenly got a lot more targets. I think this was the C++ modules dependency scanning.  
This slowed the build down a bit, but it caused another problem for the developers under Windows: when cancelling the build, this often caused corrupted ninja build files. Which had the effect that ninja did not run anymore (but crashed), and more or less a full rebuild was needed.  
I disabled CMAKE\_CXX\_SCAN\_FOR\_MODULES, and the number of targets went down again, and Windows developers don’t complain about broken build files anymore.

I didn’t investigate much, but I assume that during the build, when the scanning for modules happens, ninja files are written. When Visual Studio cancels a build, it seems that when this happens while a file is written, this file can get corrupted.

Is this a known issue ?

---

<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: [August 10, 2026, 8:45pm UTC](https://discourse.cmake.org/t/automoc-on-the-visual-studio-generators-two-extra-projects-per-target-since-4-4-0-could-this-be-made-configurable/15768/8 "2026-08-10T20:45:00Z")

</div>

@neundorf Please re-post that as a new discussion thread. It is not related to autogen targets, which is what this thread is about.
