# PATCH\_COMMAND with ExternalProject works but with FetchContent an error is triggered

**URL:** <https://discourse.cmake.org/t/patch-command-with-externalproject-works-but-with-fetchcontent-an-error-is-triggered/15157>\
**Category:** Code\
**Tags:** os:linux\
**Created:** [September 7, 2025, 12:20pm UTC](https://discourse.cmake.org/t/patch-command-with-externalproject-works-but-with-fetchcontent-an-error-is-triggered/15157 "2025-09-07T12:20:43Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![snoriman](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/s/b9e5f3/32.png) [@snoriman](https://discourse.cmake.org/u/snoriman)\
**Post date:** [September 7, 2025, 12:20pm UTC](https://discourse.cmake.org/t/patch-command-with-externalproject-works-but-with-fetchcontent-an-error-is-triggered/15157/1 "2025-09-07T12:20:44Z")

</div>

I’ve got a PATCH\_COMMAND which fails with FetchContent but works  
with ExternalProject. The only difference (I can see at least) is  
that I change `FetchContent_Declare` to `ExternalProject_Add` and  
remove `FetchContent_MakeAvailable()` with adding a dependency to  
my target. From the docs it seems that the PATCH\_COMMAND option  
should be the same. Any ideas what might go wrong?

This is the error I get:

```bash
-- The C compiler identification is GNU 15.1.1
-- The CXX compiler identification is GNU 15.1.1
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
Cloning into 'glad'...
HEAD is now at 47c20c1 setup: Bumped version: 2.0.3.
error: unknown option `ignore-space-change'
usage: git restore [<options>] [--source=<branch>] <file>...

    -s, --[no-]source <tree-ish>
                          which tree-ish to checkout from
    -S, --[no-]staged restore the index
    -W, --[no-]worktree restore the working tree (default)
    --[no-]ignore-unmerged
                          ignore unmerged entries
    --[no-]overlay use overlay mode
    -q, --[no-]quiet suppress progress reporting
    --[no-]recurse-submodules[=<checkout>]
                          control recursive updating of submodules
    --[no-]progress force progress reporting
    -m, --[no-]merge perform a 3-way merge with the new branch
    --[no-]conflict <style>
                          conflict style (merge, diff3, or zdiff3)
    -2, --ours checkout our version for unmerged files
    -3, --theirs checkout their version for unmerged files
    -p, --[no-]patch select hunks interactively
    --[no-]ignore-skip-worktree-bits
                          do not limit pathspecs to sparse entries only
    --[no-]pathspec-from-file <file>
                          read pathspec from file
    --[no-]pathspec-file-nul
                          with --pathspec-from-file, pathspec elements are separated with NUL character

CMake Error at build.release/CMakeFiles/fc-tmp/glad/patch.cmake:7 (execute_process):
  execute_process last command failed
Call Stack (most recent call first):
  /usr/share/cmake/Modules/FetchContent.cmake:1753 (include)
  /usr/share/cmake/Modules/FetchContent.cmake:1716 (__FetchContent_doStepDirect)
  /usr/share/cmake/Modules/FetchContent.cmake:1607 (__FetchContent_populateDirect)
  /usr/share/cmake/Modules/FetchContent.cmake:2145:EVAL:2 (__FetchContent_doPopulation)
  /usr/share/cmake/Modules/FetchContent.cmake:2145 (cmake_language)
  /usr/share/cmake/Modules/FetchContent.cmake:2384 (__FetchContent_Populate)
  CMakeLists.txt:76 (FetchContent_MakeAvailable)

```

```cmake
set(glad_prefix ${CMAKE_CURRENT_BINARY_DIR}/glad)
set(glad_patch ${CMAKE_CURRENT_LIST_DIR}/glad.patch)

include(ExternalProject)
include(FetchContent)

FetchContent_Declare(
#ExternalProject_Add(
  glad
  GIT_REPOSITORY https://github.com/Dav1dde/glad.git
  GIT_TAG v2.0.3
  DOWNLOAD_EXTRACT_TIMESTAMP FALSE
  PATCH_COMMAND
    git restore <SOURCE_DIR>/cmake/CMakeLists.txt &&
    git apply --ignore-space-change --ignore-whitespace ${glad_patch}
  SOURCE_DIR ${glad_prefix}
)

```

---

<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:** [September 7, 2025, 10:34pm UTC](https://discourse.cmake.org/t/patch-command-with-externalproject-works-but-with-fetchcontent-an-error-is-triggered/15157/2 "2025-09-07T22:34:19Z")

</div>

You’re assuming a unix shell is used, and CMake does not guarantee that. Can you try the following to see if it works for you:

```cmake
FetchContent_Declare(
  glad
  GIT_REPOSITORY https://github.com/Dav1dde/glad.git
  GIT_TAG v2.0.3
  DOWNLOAD_EXTRACT_TIMESTAMP FALSE
  PATCH_COMMAND git restore <SOURCE_DIR>/cmake/CMakeLists.txt
  COMMAND git apply --ignore-space-change --ignore-whitespace ${glad_patch}
  SOURCE_DIR ${glad_prefix}
)

```

If you don’t want to split the commands like that, you should put the commands in a script file and run that as your `PATCH_COMMAND`. Don’t use shell redirection, pipes, etc. directly in `PATCH_COMMAND`.

---

<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:** [September 7, 2025, 10:36pm UTC](https://discourse.cmake.org/t/patch-command-with-externalproject-works-but-with-fetchcontent-an-error-is-triggered/15157/3 "2025-09-07T22:36:48Z")

</div>

Oh, I just re-read the error message more closely. The `--ignore-space-change` option isn’t recognised by your version of git. I don’t know how ExternalProject\_Add() is not causing an error as well. Maybe it is erroring, but that error is somehow slipping through unnoticed. You could also check whether ExternalProject and FetchContent are both invoking the same git executable. I don’t know how they could be different, but just putting it out there as something to check.

EDIT: Ignore this, I think I was right the first time. The error is saying an option you gave for the second command was not recognised by the first. That seems to confirm the `&&` isn’t doing what you expected. See my previous comment for the likely fix.

---

<div class="post-metadata">

**Author:** ![snoriman](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/s/b9e5f3/32.png) [@snoriman](https://discourse.cmake.org/u/snoriman)\
**Post date:** [September 10, 2025, 12:46pm UTC](https://discourse.cmake.org/t/patch-command-with-externalproject-works-but-with-fetchcontent-an-error-is-triggered/15157/4 "2025-09-10T12:46:07Z")

</div>

Thanks for your replies Craig!

For now I’m doing this test on Linux indeed. I don’t think the issue is related using `&&` to combine commands, that should be fine as far as I know. The thing is, ExternalProject\_Add with exactly the same command works, but FetchContent does not. Yeah I thought about my git not supporting –ignore-space-change, but that’s also not the case.

I’ve worked around it with a better solution for this particular dependency, however I’m still curious why FetchContent behaves differently when it comes to PATCH\_COMMAND.

---

<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:** [September 10, 2025, 9:35pm UTC](https://discourse.cmake.org/t/patch-command-with-externalproject-works-but-with-fetchcontent-an-error-is-triggered/15157/5 "2025-09-10T21:35:44Z")

</div>

While FetchContent uses a lot of ExternalProject’s internal implementation (and in older versions it uses ExternalProject directly), there can still be subtle differences in how some aspects are parsed, etc. I do think the `&&` is your problem, the error message confirms that the whole thing is seen as one command by the system, not two separate commands.
