Skip to content

Commit 1be839d

Browse files
committed
Fixed a file generation bug where bin2cpp_unittest would start compiling before the the end of the generation script. This would create compilation failures since some required files were not generated yet.
1 parent 4dc8a8a commit 1be839d

File tree

1 file changed

+43
-13
lines changed

1 file changed

+43
-13
lines changed

test/bin2cpp_unittest/CMakeLists.txt

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -208,9 +208,26 @@ endif()
208208

209209
set(TEMPLATE_SCRIPT_FILE ${BIN2CPP_UNITTEST_SOURCE_DIR}/generate_test_files.${SCRIPT_FILE_EXTENSION}.in)
210210

211-
# https://stackoverflow.com/questions/18427877/add-custom-build-step-in-cmake
211+
# Define a dummy file to act as a stamp for file generation completion
212+
set(GENERATION_STAMP ${GENERATED_TEST_FILES_DIR}/generated_files.stamp)
213+
214+
# The script generates multiple files from a single command, but if I try to list all of them as OUTPUT of the add_custom_command it won't work.
215+
# CMake assumes each output is independently produced, so it starts compiling as soon as any one is generated, not necessarily all.
216+
#
217+
# CMake tracks outputs individually, so even if I have `OUTPUT ${GENERATED_TEST_FILES}`, it sees each output as possibly ready at different times.
218+
# When one appears on disk (even partially), it may trigger compilation of bin2cpp_unittest, before the script finishes generating all files.
219+
#
220+
# To work around this behavior, is using a stamp file which is created after the generation script has run which indicates to CMake we are ready to compile bin2cpp_unittest.
221+
# Required steps:
222+
# Only the stamp file is listed as OUTPUT. This prevents CMake from checking each generated file independently.
223+
# The actual source files are listed as BYPRODUCTS, so CMake knows they will appear but doesn't rely on their timestamps individually.
224+
# add_dependencies() ensures the executable only starts compiling after the stamp file is created, i.e., after the script finishes.
225+
#
226+
# To force CMake to regenerate the files, delete the stamp file.
227+
#
212228
if (WIN32)
213-
add_custom_command( OUTPUT ${GENERATED_TEST_FILES}
229+
add_custom_command( OUTPUT ${GENERATION_STAMP}
230+
BYPRODUCTS ${GENERATED_TEST_FILES}
214231
# Execute prebuild copy
215232
COMMAND ${CMAKE_COMMAND}
216233
-DBIN2CPP_TARGET_FILE=$<TARGET_FILE:bin2cpp>
@@ -223,10 +240,17 @@ if (WIN32)
223240
# Execute generator script
224241
COMMAND echo Calling 'generate_test_files.bat' script...
225242
COMMAND cd /d ${CMAKE_CURRENT_BINARY_DIR} && call generate_test_files.bat
243+
244+
# Tell CMake that we generated the last file of the series
245+
COMMAND ${CMAKE_COMMAND} -E touch ${GENERATION_STAMP}
246+
247+
COMMENT "Generating test files"
248+
VERBATIM
226249
)
227250
else()
228251
# Linux build
229-
add_custom_command( OUTPUT ${GENERATED_TEST_FILES}
252+
add_custom_command( OUTPUT ${GENERATION_STAMP}
253+
BYPRODUCTS ${GENERATED_TEST_FILES}
230254
# Execute prebuild copy
231255
COMMAND ${CMAKE_COMMAND}
232256
-DBIN2CPP_TARGET_FILE=$<TARGET_FILE:bin2cpp>
@@ -235,21 +259,23 @@ else()
235259
-DBIN2CPP_UNITTEST_PROJECT_DIR=${CMAKE_CURRENT_BINARY_DIR}
236260
-DBIN2CPP_UNITTEST_OUTPUT_DIR=${CMAKE_BINARY_DIR}/bin
237261
-P ${CMAKE_CURRENT_SOURCE_DIR}/generate_test_files.cmake
238-
262+
239263
# Execute generator script
240264
COMMAND echo Calling 'generate_test_files.sh' script...
241265
COMMAND cd ${CMAKE_CURRENT_BINARY_DIR} && ./generate_test_files.sh
266+
267+
# Tell CMake that we generated the last file of the series
268+
COMMAND ${CMAKE_COMMAND} -E touch ${GENERATION_STAMP}
269+
270+
COMMENT "Generating test files"
271+
VERBATIM
242272
)
243273
endif()
244274

245-
# target build_test_files is always built
246-
add_custom_target(build_test_files ALL
247-
COMMAND echo "Building unit test files..."
248-
249-
# If the files exists, then commands related to these files won't be executed
250-
# DONOT let other target depends on the same OUTPUT as current target,
251-
# or it may be bad when doing parallel make
252-
DEPENDS ${GENERATED_TEST_FILES}
275+
# Create a custom target that depends on the generated files
276+
add_custom_target(generate_test_files
277+
DEPENDS ${GENERATION_STAMP}
278+
COMMENT "Ensuring file generation stamp exist"
253279
)
254280

255281
# Show all generated files in a common folder
@@ -261,6 +287,9 @@ source_group("External Files" FILES
261287
${CMAKE_SOURCE_DIR}/src/bin2cpp/wildcard.h
262288
)
263289

290+
# Ensure source files are properly recognized as generated
291+
set_source_files_properties(${GENERATED_TEST_FILES} PROPERTIES GENERATED TRUE)
292+
264293
add_executable(bin2cpp_unittest
265294
${BIN2CPP_VERSION_HEADER}
266295
${BIN2CPP_CONFIG_HEADER}
@@ -288,7 +317,8 @@ add_executable(bin2cpp_unittest
288317

289318
add_dependencies(bin2cpp_unittest bin2cpp)
290319
add_dependencies(bin2cpp_unittest testfilegenerator)
291-
add_dependencies(bin2cpp_unittest build_test_files)
320+
add_dependencies(bin2cpp_unittest generate_test_files)
321+
292322

293323
# Unit test projects requires to link with pthread if also linking with gtest
294324
if(NOT WIN32)

0 commit comments

Comments
 (0)