@@ -12,6 +12,11 @@ set(AUX_TARGETS_FOLDER "${BASE_TARGETS_FOLDER}/Aux")
1212
1313get_cmake_property (with_multi_config_generator GENERATOR_IS_MULTI_CONFIG )
1414
15+ # Runtime-dependency and resource copies all land in the shared per-sub-project Binaries directory, and many targets copy
16+ # an overlapping set of files there. Running those copies concurrently races on the same destination files (intermittent
17+ # "Error copying file" failures under Ninja), so funnel them through a depth-1 job pool to serialize their execution.
18+ set_property (GLOBAL PROPERTY JOB_POOLS exp_copy=1)
19+
1520if (BUILD_TEST)
1621 enable_testing ()
1722 add_compile_definitions (BUILD_TEST=1 )
@@ -86,37 +91,6 @@ function(exp_gather_target_runtime_dependencies_recurse)
8691 set (${arg_OUT_DEP_TARGET} ${result_dep_target} PARENT_SCOPE )
8792endfunction ()
8893
89- function (exp_add_shared_copy_target )
90- set (options "" )
91- set (singleValueArgs KEY SRC DST MAKE_DIR OUTPUT_TARGET)
92- set (multiValueArgs DEPENDS)
93- cmake_parse_arguments (arg "${options} " "${singleValueArgs} " "${multiValueArgs} " ${ARGN} )
94-
95- string (MAKE_C_IDENTIFIER "${arg_KEY} " key_id)
96- set (registry_property EXP_SHARED_COPY_TARGET_${SUB_PROJECT_NAME} _${key_id} )
97-
98- get_property (copy_target GLOBAL PROPERTY ${registry_property} )
99- if (NOT copy_target)
100- set (copy_target ${SUB_PROJECT_NAME} .Copy.${key_id} )
101- if (DEFINED arg_MAKE_DIR)
102- set (copy_commands COMMAND ${CMAKE_COMMAND } -E make_directory ${arg_MAKE_DIR} )
103- else ()
104- set (copy_commands "" )
105- endif ()
106- list (APPEND copy_commands COMMAND ${CMAKE_COMMAND } -E copy_if_different ${arg_SRC} ${arg_DST} )
107-
108- add_custom_target (${copy_target} ${copy_commands} )
109- set_target_properties (${copy_target} PROPERTIES FOLDER ${AUX_TARGETS_FOLDER} )
110- set_property (GLOBAL PROPERTY ${registry_property} ${copy_target} )
111- endif ()
112-
113- if (arg_DEPENDS)
114- add_dependencies (${copy_target} ${arg_DEPENDS} )
115- endif ()
116-
117- set (${arg_OUTPUT_TARGET} ${copy_target} PARENT_SCOPE )
118- endfunction ()
119-
12094function (exp_process_runtime_dependencies )
12195 set (options NOT_INSTALL)
12296 set (singleValueArgs NAME)
@@ -136,37 +110,29 @@ function(exp_process_runtime_dependencies)
136110 OUT_DEP_TARGET dep_dep_targets
137111 )
138112 list (APPEND runtime_deps ${dep_target_runtime_deps} )
113+ list (APPEND dep_targets ${dep_dep_targets} )
139114 endforeach ()
140115
141- if (runtime_deps)
142- list (REMOVE_DUPLICATES runtime_deps)
143- endif ()
144-
145- exp_get_runtime_output_dir (OUTPUT out_dir )
146- foreach (r ${runtime_deps} )
147- set (copy_depends "" )
148- if ("${r} " MATCHES "^\\ $<TARGET_FILE :(.+)>$" )
149- set (producer ${CMAKE_MATCH_1} )
150- if (TARGET ${producer} )
151- get_target_property (producer_imported ${producer} IMPORTED )
152- if (NOT producer_imported)
153- set (copy_depends ${producer} )
154- endif ()
155- endif ()
156- endif ()
157-
158- exp_add_shared_copy_target (
159- KEY ${r}
160- SRC ${r}
161- DST ${out_dir}
162- MAKE_DIR ${out_dir}
163- DEPENDS ${copy_depends}
164- OUTPUT_TARGET copy_target
116+ set (copy_commands COMMAND ${CMAKE_COMMAND } -E make_directory $<TARGET_FILE_DIR :${arg_NAME} >)
117+ foreach (r ${runtime_deps} )
118+ list (APPEND copy_commands COMMAND ${CMAKE_COMMAND } -E copy_if_different ${r} $<TARGET_FILE_DIR :${arg_NAME} >)
119+ endforeach ()
120+ if (NOT "${copy_commands} " STREQUAL "" )
121+ set (custom_target_name ${arg_NAME} .CopyRuntimeDeps)
122+ add_custom_target (
123+ ${custom_target_name}
124+ ${copy_commands}
125+ JOB_POOL exp_copy
165126 )
166- add_dependencies (${arg_NAME} ${copy_target} )
167- endforeach ()
168127
169- if (NOT arg_NOT_INSTALL AND runtime_deps)
128+ add_dependencies (${arg_NAME} ${custom_target_name} )
129+ foreach (t ${dep_targets} )
130+ add_dependencies (${custom_target_name} ${t} )
131+ endforeach ()
132+
133+ set_target_properties (${custom_target_name} PROPERTIES FOLDER ${AUX_TARGETS_FOLDER} )
134+ endif ()
135+ if (NOT arg_NOT_INSTALL AND NOT "${runtime_deps} " STREQUAL "" )
170136 install (
171137 FILES ${runtime_deps} DESTINATION ${SUB_PROJECT_NAME} /Binaries
172138 )
@@ -193,28 +159,30 @@ function(exp_add_resources_copy_command)
193159 set (multiValueArgs RES)
194160 cmake_parse_arguments (arg "${options} " "${singleValueArgs} " "${multiValueArgs} " ${ARGN} )
195161
196- exp_get_runtime_output_dir (OUTPUT out_dir )
197162 foreach (r ${arg_RES} )
198163 exp_expand_resource_path_expression (
199164 INPUT ${r}
200165 OUTPUT_SRC src
201166 OUTPUT_DST dst
202167 )
203168
204- exp_add_shared_copy_target (
205- KEY ${dst}
206- SRC ${src}
207- DST ${out_dir} /${dst}
208- OUTPUT_TARGET copy_target
209- )
210- add_dependencies (${arg_NAME} ${copy_target} )
169+ list (APPEND copy_commands COMMAND ${CMAKE_COMMAND } -E copy_if_different ${src} $<TARGET_FILE_DIR :${arg_NAME} >/${dst} )
211170
212171 cmake_path (SET dst_path NORMALIZE "${SUB_PROJECT_NAME} /Binaries/${dst} " )
213172 cmake_path (GET dst_path PARENT_PATH dst_dir )
214173 if (NOT arg_NOT_INSTALL)
215174 install (FILES ${src} DESTINATION ${dst_dir} )
216175 endif ()
217176 endforeach ()
177+
178+ set (copy_res_target_name ${arg_NAME} .CopyRes)
179+ add_custom_target (
180+ ${copy_res_target_name}
181+ ${copy_commands}
182+ JOB_POOL exp_copy
183+ )
184+ set_target_properties (${copy_res_target_name} PROPERTIES FOLDER ${AUX_TARGETS_FOLDER} )
185+ add_dependencies (${arg_NAME} ${copy_res_target_name} )
218186endfunction ()
219187
220188function (exp_gather_target_libs )
0 commit comments