summaryrefslogtreecommitdiffstats
path: root/Tests/RunCMake/Codegen
diff options
context:
space:
mode:
Diffstat (limited to 'Tests/RunCMake/Codegen')
-rw-r--r--Tests/RunCMake/Codegen/CMakeLists.txt7
-rw-r--r--Tests/RunCMake/Codegen/RunCMakeTest.cmake33
-rw-r--r--Tests/RunCMake/Codegen/add-custom-command-depends-build-check.cmake5
-rw-r--r--Tests/RunCMake/Codegen/add-custom-command-depends.cmake16
-rw-r--r--Tests/RunCMake/Codegen/add-dependencies-build-check.cmake5
-rw-r--r--Tests/RunCMake/Codegen/add-dependencies.cmake18
-rw-r--r--Tests/RunCMake/Codegen/append-implicit-depends-result.txt1
-rw-r--r--Tests/RunCMake/Codegen/append-implicit-depends-stderr.txt2
-rw-r--r--Tests/RunCMake/Codegen/append-implicit-depends.cmake19
-rw-r--r--Tests/RunCMake/Codegen/byproducts-build-check.cmake5
-rw-r--r--Tests/RunCMake/Codegen/byproducts.cmake19
-rw-r--r--Tests/RunCMake/Codegen/error.c1
-rw-r--r--Tests/RunCMake/Codegen/exclude-from-all.cmake11
-rw-r--r--Tests/RunCMake/Codegen/generated.h.in1
-rw-r--r--Tests/RunCMake/Codegen/implicit-depends-append-codegen-result.txt1
-rw-r--r--Tests/RunCMake/Codegen/implicit-depends-append-codegen-stderr.txt4
-rw-r--r--Tests/RunCMake/Codegen/implicit-depends-append-codegen.cmake18
-rw-r--r--Tests/RunCMake/Codegen/implicit-depends-result.txt1
-rw-r--r--Tests/RunCMake/Codegen/implicit-depends-stderr.txt4
-rw-r--r--Tests/RunCMake/Codegen/implicit-depends.cmake11
-rw-r--r--Tests/RunCMake/Codegen/main.c4
-rw-r--r--Tests/RunCMake/Codegen/min-graph-1-build-check.cmake13
-rw-r--r--Tests/RunCMake/Codegen/min-graph-1.cmake26
-rw-r--r--Tests/RunCMake/Codegen/min-graph-2-build-check.cmake5
-rw-r--r--Tests/RunCMake/Codegen/min-graph-2.cmake18
-rw-r--r--Tests/RunCMake/Codegen/min-graph-3-build-check.cmake5
-rw-r--r--Tests/RunCMake/Codegen/min-graph-3.cmake12
-rw-r--r--Tests/RunCMake/Codegen/no-codegen-check.cmake5
-rw-r--r--Tests/RunCMake/Codegen/no-codegen.cmake6
-rw-r--r--Tests/RunCMake/Codegen/no-output-result.txt1
-rw-r--r--Tests/RunCMake/Codegen/no-output-stderr.txt4
-rw-r--r--Tests/RunCMake/Codegen/no-output.cmake11
32 files changed, 292 insertions, 0 deletions
diff --git a/Tests/RunCMake/Codegen/CMakeLists.txt b/Tests/RunCMake/Codegen/CMakeLists.txt
new file mode 100644
index 0000000..f65150d
--- /dev/null
+++ b/Tests/RunCMake/Codegen/CMakeLists.txt
@@ -0,0 +1,7 @@
+cmake_minimum_required(VERSION 3.29)
+project(${RunCMake_TEST} LANGUAGES C)
+
+# This value is read from the top level CMakeLists.txt
+cmake_policy(SET CMP0171 NEW)
+
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/Codegen/RunCMakeTest.cmake b/Tests/RunCMake/Codegen/RunCMakeTest.cmake
new file mode 100644
index 0000000..bbd70b0
--- /dev/null
+++ b/Tests/RunCMake/Codegen/RunCMakeTest.cmake
@@ -0,0 +1,33 @@
+include(RunCMake)
+
+function(run_codegen case)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${case}-build)
+
+ run_cmake(${case})
+
+ set(RunCMake_TEST_NO_CLEAN 1)
+
+ run_cmake_command(${case}-build ${CMAKE_COMMAND} --build . --target codegen --config Debug)
+endfunction()
+
+# Builds codegen target when there are no custom commands marked codegen
+run_codegen("no-codegen")
+
+# We don't want codegen to drive parts of the project that are EXCLUDE_FROM_ALL
+run_codegen("exclude-from-all")
+
+# Ensures codegen builds minimal build graphs
+run_codegen("min-graph-1")
+run_codegen("min-graph-2")
+run_codegen("min-graph-3")
+
+# Handle specific cases that can affect codegen
+run_codegen("add-dependencies")
+run_codegen("add-custom-command-depends")
+run_codegen("byproducts")
+
+# Error handling
+run_cmake("implicit-depends")
+run_cmake("implicit-depends-append-codegen")
+run_cmake("append-implicit-depends")
+run_cmake("no-output")
diff --git a/Tests/RunCMake/Codegen/add-custom-command-depends-build-check.cmake b/Tests/RunCMake/Codegen/add-custom-command-depends-build-check.cmake
new file mode 100644
index 0000000..d371d73
--- /dev/null
+++ b/Tests/RunCMake/Codegen/add-custom-command-depends-build-check.cmake
@@ -0,0 +1,5 @@
+set(filename "${RunCMake_TEST_BINARY_DIR}/generated.hpp")
+if (NOT EXISTS "${filename}")
+ set(RunCMake_TEST_FAILED "expected file NOT created:\n ${filename}")
+ return()
+endif()
diff --git a/Tests/RunCMake/Codegen/add-custom-command-depends.cmake b/Tests/RunCMake/Codegen/add-custom-command-depends.cmake
new file mode 100644
index 0000000..793ab5f
--- /dev/null
+++ b/Tests/RunCMake/Codegen/add-custom-command-depends.cmake
@@ -0,0 +1,16 @@
+add_custom_target(foobar
+ COMMAND ${CMAKE_COMMAND} -E copy
+ ${CMAKE_CURRENT_SOURCE_DIR}/generated.h.in
+ ${CMAKE_CURRENT_BINARY_DIR}/generated.h
+)
+
+add_custom_command(
+ OUTPUT generated.hpp
+ # This test will fail if DEPENDS isn't accounted for in the codegen build graph
+ DEPENDS foobar
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/generated.h
+ ${CMAKE_CURRENT_BINARY_DIR}/generated.hpp
+ CODEGEN
+)
+
+add_custom_target(hpp_creator ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/generated.hpp)
diff --git a/Tests/RunCMake/Codegen/add-dependencies-build-check.cmake b/Tests/RunCMake/Codegen/add-dependencies-build-check.cmake
new file mode 100644
index 0000000..d371d73
--- /dev/null
+++ b/Tests/RunCMake/Codegen/add-dependencies-build-check.cmake
@@ -0,0 +1,5 @@
+set(filename "${RunCMake_TEST_BINARY_DIR}/generated.hpp")
+if (NOT EXISTS "${filename}")
+ set(RunCMake_TEST_FAILED "expected file NOT created:\n ${filename}")
+ return()
+endif()
diff --git a/Tests/RunCMake/Codegen/add-dependencies.cmake b/Tests/RunCMake/Codegen/add-dependencies.cmake
new file mode 100644
index 0000000..fbb7e99
--- /dev/null
+++ b/Tests/RunCMake/Codegen/add-dependencies.cmake
@@ -0,0 +1,18 @@
+add_custom_target(foobar
+ COMMAND ${CMAKE_COMMAND} -E copy
+ ${CMAKE_CURRENT_SOURCE_DIR}/generated.h.in
+ ${CMAKE_CURRENT_BINARY_DIR}/generated.h
+)
+
+add_custom_command(
+ OUTPUT generated.hpp
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/generated.h
+ ${CMAKE_CURRENT_BINARY_DIR}/generated.hpp
+ CODEGEN
+)
+
+add_custom_target(hpp_creator ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/generated.hpp)
+
+# This test will fail if add_dependencies isn't account for in the
+# codegen build graph
+add_dependencies(hpp_creator foobar)
diff --git a/Tests/RunCMake/Codegen/append-implicit-depends-result.txt b/Tests/RunCMake/Codegen/append-implicit-depends-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/Codegen/append-implicit-depends-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Codegen/append-implicit-depends-stderr.txt b/Tests/RunCMake/Codegen/append-implicit-depends-stderr.txt
new file mode 100644
index 0000000..c8ef03e
--- /dev/null
+++ b/Tests/RunCMake/Codegen/append-implicit-depends-stderr.txt
@@ -0,0 +1,2 @@
+CMake Error:
+ Cannot append IMPLICIT_DEPENDS to existing CODEGEN custom command\.
diff --git a/Tests/RunCMake/Codegen/append-implicit-depends.cmake b/Tests/RunCMake/Codegen/append-implicit-depends.cmake
new file mode 100644
index 0000000..d212fe5
--- /dev/null
+++ b/Tests/RunCMake/Codegen/append-implicit-depends.cmake
@@ -0,0 +1,19 @@
+add_custom_command(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/main.cpp
+ COMMAND
+ ${CMAKE_COMMAND} -E
+ copy ${CMAKE_CURRENT_SOURCE_DIR}/error.c
+ ${CMAKE_CURRENT_BINARY_DIR}/main.cpp
+ CODEGEN
+)
+
+add_custom_command(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/main.cpp
+
+ # ERROR out if IMPLICIT_DEPENDS is used with CODEGEN
+ IMPLICIT_DEPENDS C main.c
+
+ APPEND
+)
diff --git a/Tests/RunCMake/Codegen/byproducts-build-check.cmake b/Tests/RunCMake/Codegen/byproducts-build-check.cmake
new file mode 100644
index 0000000..d371d73
--- /dev/null
+++ b/Tests/RunCMake/Codegen/byproducts-build-check.cmake
@@ -0,0 +1,5 @@
+set(filename "${RunCMake_TEST_BINARY_DIR}/generated.hpp")
+if (NOT EXISTS "${filename}")
+ set(RunCMake_TEST_FAILED "expected file NOT created:\n ${filename}")
+ return()
+endif()
diff --git a/Tests/RunCMake/Codegen/byproducts.cmake b/Tests/RunCMake/Codegen/byproducts.cmake
new file mode 100644
index 0000000..ea0b6c7
--- /dev/null
+++ b/Tests/RunCMake/Codegen/byproducts.cmake
@@ -0,0 +1,19 @@
+add_custom_target(foobar
+ COMMAND ${CMAKE_COMMAND} -E copy
+ ${CMAKE_CURRENT_SOURCE_DIR}/generated.h.in
+ ${CMAKE_CURRENT_BINARY_DIR}/generated.h
+ BYPRODUCTS
+ ${CMAKE_CURRENT_BINARY_DIR}/generated.h
+)
+
+# This codegen step relies on the BYPRODUCTS of the previous command.
+# If foobar isn't properly accounted for as a dependency it will fail.
+add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/generated.hpp
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/generated.h
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/generated.h
+ ${CMAKE_CURRENT_BINARY_DIR}/generated.hpp
+ CODEGEN
+)
+
+add_custom_target(hpp_creator ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/generated.hpp)
diff --git a/Tests/RunCMake/Codegen/error.c b/Tests/RunCMake/Codegen/error.c
new file mode 100644
index 0000000..34cb350
--- /dev/null
+++ b/Tests/RunCMake/Codegen/error.c
@@ -0,0 +1 @@
+#error "This file should not be compiled"
diff --git a/Tests/RunCMake/Codegen/exclude-from-all.cmake b/Tests/RunCMake/Codegen/exclude-from-all.cmake
new file mode 100644
index 0000000..bcd4ac0
--- /dev/null
+++ b/Tests/RunCMake/Codegen/exclude-from-all.cmake
@@ -0,0 +1,11 @@
+add_custom_command(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/generated.h
+ COMMAND
+ ${CMAKE_COMMAND} -E false
+ CODEGEN
+)
+
+# We don't want codegen to drive parts of the project that are EXCLUDE_FROM_ALL.
+# This tests that foobar is properly excluded from the codegen build.
+add_executable(foobar EXCLUDE_FROM_ALL error.c ${CMAKE_CURRENT_BINARY_DIR}/generated.h)
diff --git a/Tests/RunCMake/Codegen/generated.h.in b/Tests/RunCMake/Codegen/generated.h.in
new file mode 100644
index 0000000..82ccf67
--- /dev/null
+++ b/Tests/RunCMake/Codegen/generated.h.in
@@ -0,0 +1 @@
+// hello
diff --git a/Tests/RunCMake/Codegen/implicit-depends-append-codegen-result.txt b/Tests/RunCMake/Codegen/implicit-depends-append-codegen-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/Codegen/implicit-depends-append-codegen-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Codegen/implicit-depends-append-codegen-stderr.txt b/Tests/RunCMake/Codegen/implicit-depends-append-codegen-stderr.txt
new file mode 100644
index 0000000..570cf62
--- /dev/null
+++ b/Tests/RunCMake/Codegen/implicit-depends-append-codegen-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at implicit-depends-append-codegen\.cmake:[0-9]+ \(add_custom_command\):
+ add_custom_command CODEGEN may not be used with APPEND\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/Codegen/implicit-depends-append-codegen.cmake b/Tests/RunCMake/Codegen/implicit-depends-append-codegen.cmake
new file mode 100644
index 0000000..76151cc
--- /dev/null
+++ b/Tests/RunCMake/Codegen/implicit-depends-append-codegen.cmake
@@ -0,0 +1,18 @@
+add_custom_command(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/main.cpp
+
+ # ERROR out if IMPLICIT_DEPENDS is used with CODEGEN
+ IMPLICIT_DEPENDS C main.c
+)
+
+add_custom_command(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/main.cpp
+ COMMAND
+ ${CMAKE_COMMAND} -E
+ copy ${CMAKE_CURRENT_SOURCE_DIR}/error.c
+ ${CMAKE_CURRENT_BINARY_DIR}/main.cpp
+ CODEGEN
+ APPEND
+)
diff --git a/Tests/RunCMake/Codegen/implicit-depends-result.txt b/Tests/RunCMake/Codegen/implicit-depends-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/Codegen/implicit-depends-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Codegen/implicit-depends-stderr.txt b/Tests/RunCMake/Codegen/implicit-depends-stderr.txt
new file mode 100644
index 0000000..b9ea8f4
--- /dev/null
+++ b/Tests/RunCMake/Codegen/implicit-depends-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at implicit-depends\.cmake:[0-9]+ \(add_custom_command\):
+ add_custom_command CODEGEN is not compatible with IMPLICIT_DEPENDS\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/Codegen/implicit-depends.cmake b/Tests/RunCMake/Codegen/implicit-depends.cmake
new file mode 100644
index 0000000..011d4b3
--- /dev/null
+++ b/Tests/RunCMake/Codegen/implicit-depends.cmake
@@ -0,0 +1,11 @@
+add_custom_command(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/main.cpp
+ COMMAND
+ ${CMAKE_COMMAND} -E
+ copy ${CMAKE_CURRENT_SOURCE_DIR}/error.c
+ ${CMAKE_CURRENT_BINARY_DIR}/main.cpp
+ CODEGEN
+ # ERROR out if IMPLICIT_DEPENDS is used with CODEGEN
+ IMPLICIT_DEPENDS C main.c
+)
diff --git a/Tests/RunCMake/Codegen/main.c b/Tests/RunCMake/Codegen/main.c
new file mode 100644
index 0000000..8488f4e
--- /dev/null
+++ b/Tests/RunCMake/Codegen/main.c
@@ -0,0 +1,4 @@
+int main(void)
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/Codegen/min-graph-1-build-check.cmake b/Tests/RunCMake/Codegen/min-graph-1-build-check.cmake
new file mode 100644
index 0000000..32e1557
--- /dev/null
+++ b/Tests/RunCMake/Codegen/min-graph-1-build-check.cmake
@@ -0,0 +1,13 @@
+set(filename "${RunCMake_TEST_BINARY_DIR}/generated.h")
+if (NOT EXISTS "${filename}")
+ set(RunCMake_TEST_FAILED "expected file NOT created:\n ${filename}")
+ return()
+endif()
+
+# foobar should be built since it was needed
+# by the code generation
+set(filename "${RunCMake_TEST_BINARY_DIR}/foobar.txt")
+if (NOT EXISTS "${filename}")
+ set(RunCMake_TEST_FAILED "expected file NOT created:\n ${filename}")
+ return()
+endif()
diff --git a/Tests/RunCMake/Codegen/min-graph-1.cmake b/Tests/RunCMake/Codegen/min-graph-1.cmake
new file mode 100644
index 0000000..ea47b8f
--- /dev/null
+++ b/Tests/RunCMake/Codegen/min-graph-1.cmake
@@ -0,0 +1,26 @@
+add_executable(foobar main.c)
+add_custom_command(
+ TARGET foobar POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E
+ copy ${CMAKE_CURRENT_SOURCE_DIR}/generated.h.in
+ ${CMAKE_CURRENT_BINARY_DIR}/foobar.txt
+)
+
+add_custom_command(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/generated.h
+ COMMAND
+ ${CMAKE_COMMAND} -E
+ copy ${CMAKE_CURRENT_SOURCE_DIR}/generated.h.in
+ ${CMAKE_CURRENT_BINARY_DIR}/generated.h
+ COMMAND
+ # Generate a header file that requires foobar
+ foobar
+ CODEGEN
+)
+
+add_library(errorlib
+ # If this library is built error.c will cause the build to fail
+ error.c
+ ${CMAKE_CURRENT_BINARY_DIR}/generated.h
+)
diff --git a/Tests/RunCMake/Codegen/min-graph-2-build-check.cmake b/Tests/RunCMake/Codegen/min-graph-2-build-check.cmake
new file mode 100644
index 0000000..fab168b
--- /dev/null
+++ b/Tests/RunCMake/Codegen/min-graph-2-build-check.cmake
@@ -0,0 +1,5 @@
+set(filename "${RunCMake_TEST_BINARY_DIR}/generated.h")
+if (NOT EXISTS "${filename}")
+ set(RunCMake_TEST_FAILED "expected file NOT created:\n ${filename}")
+ return()
+endif()
diff --git a/Tests/RunCMake/Codegen/min-graph-2.cmake b/Tests/RunCMake/Codegen/min-graph-2.cmake
new file mode 100644
index 0000000..277a901
--- /dev/null
+++ b/Tests/RunCMake/Codegen/min-graph-2.cmake
@@ -0,0 +1,18 @@
+add_custom_command(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/generated.h
+ COMMAND
+ ${CMAKE_COMMAND} -E
+ copy ${CMAKE_CURRENT_SOURCE_DIR}/generated.h.in
+ ${CMAKE_CURRENT_BINARY_DIR}/generated.h
+ CODEGEN
+)
+
+# This target should not be built. It has no reason
+# to be part of the codegen build graph
+add_custom_target(error_custom_target ALL
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/generated.h
+
+ # Cause the build to fail
+ COMMAND ${CMAKE_COMMAND} -E false
+)
diff --git a/Tests/RunCMake/Codegen/min-graph-3-build-check.cmake b/Tests/RunCMake/Codegen/min-graph-3-build-check.cmake
new file mode 100644
index 0000000..734777b
--- /dev/null
+++ b/Tests/RunCMake/Codegen/min-graph-3-build-check.cmake
@@ -0,0 +1,5 @@
+set(filename "${RunCMake_TEST_BINARY_DIR}/error_lib.c")
+if (NOT EXISTS "${filename}")
+ set(RunCMake_TEST_FAILED "expected file NOT created:\n ${filename}")
+ return()
+endif()
diff --git a/Tests/RunCMake/Codegen/min-graph-3.cmake b/Tests/RunCMake/Codegen/min-graph-3.cmake
new file mode 100644
index 0000000..c7d61dc
--- /dev/null
+++ b/Tests/RunCMake/Codegen/min-graph-3.cmake
@@ -0,0 +1,12 @@
+add_custom_command(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/error_lib.c
+ COMMAND
+ ${CMAKE_COMMAND} -E
+ copy ${CMAKE_CURRENT_SOURCE_DIR}/error.c
+ ${CMAKE_CURRENT_BINARY_DIR}/error_lib.c
+ CODEGEN
+)
+
+# This test will fail if error_lib.c is actually compiled
+add_executable(foobar ${CMAKE_CURRENT_BINARY_DIR}/error_lib.c)
diff --git a/Tests/RunCMake/Codegen/no-codegen-check.cmake b/Tests/RunCMake/Codegen/no-codegen-check.cmake
new file mode 100644
index 0000000..97fc46b
--- /dev/null
+++ b/Tests/RunCMake/Codegen/no-codegen-check.cmake
@@ -0,0 +1,5 @@
+# Verify generated.hpp was NOT created
+set(unexpected "${RunCMake_TEST_BINARY_DIR}/generated.hpp")
+if(EXISTS "${unexpected}")
+ set(RunCMake_TEST_FAILED "unexpected file created:\n ${unexpected}")
+endif()
diff --git a/Tests/RunCMake/Codegen/no-codegen.cmake b/Tests/RunCMake/Codegen/no-codegen.cmake
new file mode 100644
index 0000000..00ddd03
--- /dev/null
+++ b/Tests/RunCMake/Codegen/no-codegen.cmake
@@ -0,0 +1,6 @@
+add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/generated.hpp
+ COMMAND ${CMAKE_COMMAND} -E copy
+ ${CMAKE_CURRENT_SOURCE_DIR}/generated.h.in
+ ${CMAKE_CURRENT_BINARY_DIR}/generated.hpp
+)
diff --git a/Tests/RunCMake/Codegen/no-output-result.txt b/Tests/RunCMake/Codegen/no-output-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/Codegen/no-output-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Codegen/no-output-stderr.txt b/Tests/RunCMake/Codegen/no-output-stderr.txt
new file mode 100644
index 0000000..7aad679
--- /dev/null
+++ b/Tests/RunCMake/Codegen/no-output-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at no-output\.cmake:[0-9]+ \(add_custom_command\):
+ add_custom_command CODEGEN requires at least 1 OUTPUT\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/Codegen/no-output.cmake b/Tests/RunCMake/Codegen/no-output.cmake
new file mode 100644
index 0000000..61eb83c
--- /dev/null
+++ b/Tests/RunCMake/Codegen/no-output.cmake
@@ -0,0 +1,11 @@
+add_custom_target(foobar
+ COMMAND ${CMAKE_COMMAND} -E copy
+ ${CMAKE_CURRENT_SOURCE_DIR}/generated.h.in
+ ${CMAKE_CURRENT_BINARY_DIR}/generated.h
+)
+
+add_custom_command(TARGET foobar POST_BUILD
+ COMMAND
+ ${CMAKE_COMMAND} -E true
+ CODEGEN
+)