Hi Josef:
Thanks for your suggestion (for the Unix Makefiles generator case) of the workaround of using a separate custom cp -pf
command (I have added f
to the cp
options for more robustness) for each individual file to be copied. I have implemented that for the simple test case, and it works. The modified CMakeLists.txt file now looks like this:
CMAKE_MINIMUM_REQUIRED(VERSION 3.18.4 FATAL_ERROR)
project(test_cp NONE)
set(name_list
announcement-2.2.0.html
announcement-2.2.1.html
)
option(WORKAROUND_BUG "Workaround parallel build bug for the Unix Makefiles generator" ON)
set(names)
set(staged_names)
foreach(name ${name_list})
if(WORKAROUND_BUG)
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${name}
COMMAND cp -pf ${CMAKE_CURRENT_SOURCE_DIR}/${name} ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${name}
VERBATIM
COMMAND_EXPAND_LISTS
)
endif(WORKAROUND_BUG)
list(APPEND names ${CMAKE_CURRENT_SOURCE_DIR}/${name})
list(APPEND staged_names ${CMAKE_CURRENT_BINARY_DIR}/${name})
endforeach(name ${name_list})
message(STATUS "DEBUG: names = ${names}")
message(STATUS "DEBUG: staged_names = ${staged_names}")
if(NOT WORKAROUND_BUG)
# This add_custom_command should have the same net effect as the collection
# of individual add_custom_commands above (which do individual file copies rather
# then the following mass file copy. But with the Unix Makefiles generator and
# -j make option this mass copy fails to give the correct old timestamps on the resulting files
# for unknown reasons, but the Ninja generator gives the correct result for this case.
add_custom_command(
OUTPUT ${staged_names}
COMMAND cp -pf ${names} ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS ${names}
VERBATIM
COMMAND_EXPAND_LISTS
)
endif(NOT WORKAROUND_BUG)
add_custom_target(build_staged_names
DEPENDS
${staged_names}
)
For Unix Makefiles and -j 18 option for make
the -DWORKAROUND_BUG=ON case just works as you suggested, and the -DWORKAROUND_BUG=OFF case is largely the equivalent of the previous test case and indeed does not work correctly (wrong timestamps) for the copied files.
You also suggested trying Ninja, and that just works regardless of whether WORKAROUND_BUG is OFF or ON.
One additional experiment I tried was running that full cp
command on the command line under both bash (the results I initially reported) and dash (the default SHELL for the Makefile), and the result was the desired original datestamps.
These combined results strongly suggests there is either a bug in make
or a bug in the Makefiles generated by CMake for the Unix Makefiles generator which interferes with the timestamps of the copied files for the make
-j18 option.
I would be happy to run any further test suggested by a CMake developer to try and sort out which of those two conclusions is correct. Of course, if it turns out to be the generator a fix would be great, but in the meanwhile I do have a workaround for my own FreeEOS build-system needs.