# How to check whether a source file exists, even if generated?

**URL:** https://discourse.cmake.org/t/how-to-check-whether-a-source-file-exists-even-if-generated/5615
**Category:** Code
**Created:** [May 4, 2022, 9:15pm UTC](https://discourse.cmake.org/t/how-to-check-whether-a-source-file-exists-even-if-generated/5615 "2022-05-04T21:15:23Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![alex](https://discourse.cmake.org/user_avatar/discourse.cmake.org/alex/32/125_2.png) [@alex](https://discourse.cmake.org/u/alex)
#### Post date: [May 4, 2022, 9:15pm UTC](https://discourse.cmake.org/t/how-to-check-whether-a-source-file-exists-even-if-generated/5615/1 "2022-05-04T21:15:23Z")

</div>

Is there a way to check whether a file exists either on disk _or_ as a `GENERATED` file? Calling `get_source_file_properties` on a non-existent file without a custom command defined for it results in a fatal error.

---

<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 5, 2022, 1:13am UTC](https://discourse.cmake.org/t/how-to-check-whether-a-source-file-exists-even-if-generated/5615/2 "2022-05-05T01:13:43Z")

</div>

If you’re talking about the `file(GENERATE)` command, I don’t think there’s a way to tell what files will be generated.

For files generated during cmake configuration, you can use `if (EXISTS)` just like any other file, but you need to know its absolute path.

---

<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 5, 2022, 1:09pm UTC](https://discourse.cmake.org/t/how-to-check-whether-a-source-file-exists-even-if-generated/5615/3 "2022-05-05T13:09:14Z")

</div>

What are you trying to do here? There may be another way (I smell an XY problem here).

---

<div class="post-metadata">

### Author: ![triddlelover69](https://discourse.cmake.org/user_avatar/discourse.cmake.org/triddlelover69/32/1326_2.png) [@triddlelover69](https://discourse.cmake.org/u/triddlelover69)
#### Post date: [May 12, 2022, 12:43pm UTC](https://discourse.cmake.org/t/how-to-check-whether-a-source-file-exists-even-if-generated/5615/4 "2022-05-12T12:43:14Z")

</div>

> [@benthevining](#):
>
> If you’re talking about the `file(GENERATE)` command, I don’t think there’s a way to tell what files will be generated.
> 
> For files generated during cmake configuration, you can use `if (EXISTS)` just like any other file, but you need to know its absolute path.

@benthevining What are you saying here? I am unable to understand what you are talking about.

---

<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 12, 2022, 1:55pm UTC](https://discourse.cmake.org/t/how-to-check-whether-a-source-file-exists-even-if-generated/5615/5 "2022-05-12T13:55:41Z")

</div>

For normal files, you can just do:

```cmake
if (EXISTS "${path_to_files}")
  ...
else()
  ...
endif()

```

However, there is also a [file(GENERATE)](https://cmake.org/cmake/help/latest/command/file.html#generate) command which creates files specific to each build configuration. These files are written at the end of CMake’s processing, when it actually outputs the buildsystem, so if you were to use the above method to check if they exist during the script processing phase, you would find that they do not exist yet.

---

<div class="post-metadata">

### Author: ![alex](https://discourse.cmake.org/user_avatar/discourse.cmake.org/alex/32/125_2.png) [@alex](https://discourse.cmake.org/u/alex)
#### Post date: [May 12, 2022, 9:55pm UTC](https://discourse.cmake.org/t/how-to-check-whether-a-source-file-exists-even-if-generated/5615/6 "2022-05-12T21:55:42Z")

</div>

I’m writing a CMake helper function to distribute with my package that takes either (a) a CMake target name or (b) the name of a Python script file and runs it as a custom command (with some toolchain/environment dependent arguments).

I want to warn the user if they have a typo in the (b) case since it currently fails during the build, rather than at configure time.

---

<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 12, 2022, 10:02pm UTC](https://discourse.cmake.org/t/how-to-check-whether-a-source-file-exists-even-if-generated/5615/7 "2022-05-12T22:02:09Z")

</div>

that’s a good idea for a helper function!

how exactly are you checking for the existence of the python script file when the function is called? It sounds like the regular `if (EXISTS)` should work, because I would expect the python script to have to exist at the time the function is called (otherwise there would be no possible way to check for typos in the passed script name).

You could do something like this:

```cmake
function (add_python_command script)

    if (NOT IS_ABSOLUTE "${script}")
        set (script "${CMAKE_CURRENT_LIST_DIR}/${script}")
    endif()

    if(NOT EXISTS "${script}")
        message (FATAL_ERROR "Error: python script ${script} does not exist!")
    endif()

    ...

endfunction()

```

---

<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, 2022, 11:40pm UTC](https://discourse.cmake.org/t/how-to-check-whether-a-source-file-exists-even-if-generated/5615/8 "2022-05-12T23:40:09Z")

</div>

> [@alex](#):
>
> I want to warn the user if they have a typo in the (b) case since it currently fails during the build, rather than at configure time.

I would do something like:

```cmake
# Determine it isn't a target.
# Make absolute as in the previous comment.
if (NOT EXISTS "${script}")
  if (…) # Check if under `CMAKE_BINARY_DIR`
    # Assume it will be generated (`AUTHOR_WARNING` perhaps).
  else ()
    # Error
  endif ()
endif ()

```

If it is generated, your target needs to grow a dependency on a target or command that will make it available. You could accept this as an argument to your helper. If it isn’t set, then it can’t be generated (as there’s no way to guarantee its presence otherwise) and must exist. Otherwise assume it will (maybe with `message(AUTHOR_WARNING)` to at least make some noise about the missing dependency to ensure its existence).
