# Delay in operation of file(GENERATE ...

**URL:** <https://discourse.cmake.org/t/delay-in-operation-of-file-generate/1611>\
**Category:** Code\
**Created:** [July 22, 2020, 6:08pm UTC](https://discourse.cmake.org/t/delay-in-operation-of-file-generate/1611 "2020-07-22T18:08:02Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![EosPengwern](https://discourse.cmake.org/user_avatar/discourse.cmake.org/eospengwern/32/3904_2.png) [@EosPengwern](https://discourse.cmake.org/u/EosPengwern)\
**Post date:** [July 22, 2020, 6:08pm UTC](https://discourse.cmake.org/t/delay-in-operation-of-file-generate/1611/1 "2020-07-22T18:08:02Z")

</div>

This little bit of code:

```
file(GENERATE
     OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/empty_pch.cxx
     CONTENT "/* empty file */")
target_sources(CommonPCH_Lib PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/empty_pch.cxx)

```

… works perfectly using CMake 3.18.0 in Windows, but using 3.16.2 on Linux it fails:

```
  Cannot find source file:

    ~/dev//linux/empty_pch.cxx

  Tried extensions .c .C .c++ .cc .cpp .cxx .cu .m .M .mm .h .hh .h++ .hm
  .hpp .hxx .in .txx

```

If I keep a close eye on the binary directory during configuration, the file appears in the directory about a second after the error message is fired.

Is file(GENERATE … ) meant to be instantaneous, or is there some extra qualifier I can put on it to show the dependency and ensure it’s appeared before trying to add it to the target?

---

<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:** [July 22, 2020, 9:42pm UTC](https://discourse.cmake.org/t/delay-in-operation-of-file-generate/1611/2 "2020-07-22T21:42:45Z")

</div>

The output of `file(GENERATE)` is a bit unusual in that, unlike other `file()` commands, it returns before writing the file. The file is only written out during the _generation_ phase, which is after CMake has processed all the `CMakeLists.txt` file in the project. That would explain the delay you saw.

I’m intrigued by the path printed for that file. It has an unexpanded `~` at the front and a repeated `//`, both of which I thought should not be possible in the value of `CMAKE_CURRENT_BINARY_DIR`, but I can’t be certain. Can you provide a complete, minimal project and the command lines you used to trigger the problem on Linux?

---

<div class="post-metadata">

**Author:** ![EosPengwern](https://discourse.cmake.org/user_avatar/discourse.cmake.org/eospengwern/32/3904_2.png) [@EosPengwern](https://discourse.cmake.org/u/EosPengwern)\
**Post date:** [July 22, 2020, 10:48pm UTC](https://discourse.cmake.org/t/delay-in-operation-of-file-generate/1611/3 "2020-07-22T22:48:10Z")

</div>

Ah, you got me; I’d doctored the actual path so that I didn’t reveal the name of my project.

The two files attached will reproduce the problem, though in the CMakeLists.txt file you’d need to put the path your own Qt5 installation. I invoke CMake by going to a subdirectory and typing:

`cmake .. -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug`

I tried an even simpler example, which didn’t use Qt, and just tried to generate a PCH using C++ standard library headers, but that didn’t reproduce the problem - the file seemed to get generated in time.

For what it’s worth, the thing I’m trying to achieve here is to generate a library that does nothing except to compile a precompiled header for the Qt libraries I want to use. In CMake 3.16, the file(GENERATE …) step isn’t actually necessary, because automoc generates an empty mocs\_compilation.cpp file which is all that the compiler needs. As of 3.18, though (which I now use on Windows), the order of events has changed and automoc isn’t run until later, so it’s necessary to generate an empty .cpp file manually. See [https://gitlab.kitware.com/cmake/cmake/-/issues/20968](https://gitlab.kitware.com/cmake/cmake/-/issues/20968) for all the gory details.

[CMakeLists.txt](https://discourse.cmake.org/uploads/short-url/mnPDbIDtGZd4rKuInL7RG9gel7O.txt) (1016 Bytes) [CommonPCH.h](https://discourse.cmake.org/uploads/short-url/rTXI1JJKHNIX8f8AMdRXhrr9ILe.h) (299 Bytes)

---

<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:** [July 23, 2020, 12:26am UTC](https://discourse.cmake.org/t/delay-in-operation-of-file-generate/1611/4 "2020-07-23T00:26:19Z")

</div>

You could try using the new file(CONFIGURE) command (in 3.18+). It creates the file at configure time, instead of generation time, which is similar to configure\_file() and file(WRITE).

---

<div class="post-metadata">

**Author:** ![EosPengwern](https://discourse.cmake.org/user_avatar/discourse.cmake.org/eospengwern/32/3904_2.png) [@EosPengwern](https://discourse.cmake.org/u/EosPengwern)\
**Post date:** [July 23, 2020, 7:34am UTC](https://discourse.cmake.org/t/delay-in-operation-of-file-generate/1611/5 "2020-07-23T07:34:28Z")

</div>

All right, this seems to get the job done on both platforms:

```
if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.18.0") 
    file(CONFIGURE
         OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/empty_pch.cxx
         CONTENT "/* empty file */")
    target_sources(CommonPCH_Lib PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/empty_pch.cxx)
endif()
```

---

<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:** [July 23, 2020, 9:35pm UTC](https://discourse.cmake.org/t/delay-in-operation-of-file-generate/1611/6 "2020-07-23T21:35:38Z")

</div>

Since it is an essentially empty file with fixed content, `file(WRITE)` could be used rather than `file(CONFIGURE)`. The former works for any CMake version.

---

<div class="post-metadata">

**Author:** ![EosPengwern](https://discourse.cmake.org/user_avatar/discourse.cmake.org/eospengwern/32/3904_2.png) [@EosPengwern](https://discourse.cmake.org/u/EosPengwern)\
**Post date:** [July 23, 2020, 10:42pm UTC](https://discourse.cmake.org/t/delay-in-operation-of-file-generate/1611/7 "2020-07-23T22:42:12Z")

</div>

Good point. In this case it makes little difference, though, since for versions \< 3.18.0 it’s not necessary anyway; I can just rely on automoc to generate the empty .cpp file that I need.
