Skip to content

Commit 6655c53

Browse files
authored
[cmake] Serialize native builds for Make generator (#121021)
The build system is fragile by allowing multiple invocation of subprocess builds in the native folder for Make generator. For example, during sub-invocation of the native llvm-config, llvm-min-tblgen is also built. If there is another sub-invocation of the native llvm-min-tblgen build running in parallel, they may overwrite each other's build results, and may lead to errors like "Text file busy". This patch adds a cmake script that uses file lock to serialize all native builds for Make generator.
1 parent 6ffc445 commit 6655c53

File tree

3 files changed

+30
-6
lines changed

3 files changed

+30
-6
lines changed

llvm/cmake/modules/CrossCompile.cmake

+13-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,14 @@ function(llvm_create_cross_target project_name target_name toolchain buildtype)
1212
message(STATUS "Setting native build dir to " ${${project_name}_${target_name}_BUILD})
1313
endif(NOT DEFINED ${project_name}_${target_name}_BUILD)
1414

15+
if(NOT DEFINED ${project_name}_${target_name}_STAMP)
16+
set(${project_name}_${target_name}_STAMP
17+
"${CMAKE_CURRENT_BINARY_DIR}/${target_name}-stamps")
18+
set(${project_name}_${target_name}_STAMP
19+
${${project_name}_${target_name}_STAMP} PARENT_SCOPE)
20+
message(STATUS "Setting native stamp dir to " ${${project_name}_${target_name}_STAMP})
21+
endif(NOT DEFINED ${project_name}_${target_name}_STAMP)
22+
1523
if (EXISTS ${LLVM_MAIN_SRC_DIR}/cmake/platforms/${toolchain}.cmake)
1624
set(CROSS_TOOLCHAIN_FLAGS_INIT
1725
-DCMAKE_TOOLCHAIN_FILE=\"${LLVM_MAIN_SRC_DIR}/cmake/platforms/${toolchain}.cmake\")
@@ -130,13 +138,16 @@ function(build_native_tool target output_path_var)
130138
set_property(GLOBAL APPEND PROPERTY ${PROJECT_NAME}_HOST_TARGETS ${output_path})
131139
endif()
132140

133-
llvm_ExternalProject_BuildCmd(build_cmd ${target} ${${PROJECT_NAME}_NATIVE_BUILD}
141+
llvm_ExternalProject_BuildCmd(build_cmd ${target}
142+
${${PROJECT_NAME}_NATIVE_BUILD}
143+
${${PROJECT_NAME}_NATIVE_STAMP}
134144
CONFIGURATION Release)
135145
add_custom_command(OUTPUT "${output_path}"
136146
COMMAND ${build_cmd}
137147
DEPENDS CONFIGURE_${PROJECT_NAME}_NATIVE ${ARG_DEPENDS} ${host_targets}
138148
WORKING_DIRECTORY "${${PROJECT_NAME}_NATIVE_BUILD}"
139149
COMMENT "Building native ${target}..."
140-
USES_TERMINAL)
150+
USES_TERMINAL
151+
VERBATIM)
141152
set(${output_path_var} "${output_path}" PARENT_SCOPE)
142153
endfunction()

llvm/cmake/modules/FileLock.cmake

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# CMake script that synchronizes process execution on a given file lock.
2+
#
3+
# Input variables:
4+
# LOCK_FILE_PATH - The file to be locked for the scope of the process of this cmake script.
5+
# COMMAND - The command to be executed.
6+
7+
file(LOCK ${LOCK_FILE_PATH})
8+
string(REPLACE "@" ";" command_args ${COMMAND})
9+
execute_process(COMMAND ${command_args} COMMAND_ERROR_IS_FATAL ANY)

llvm/cmake/modules/LLVMExternalProjectUtils.cmake

+8-4
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,18 @@ include(ExternalProject)
22

33
# llvm_ExternalProject_BuildCmd(out_var target)
44
# Utility function for constructing command lines for external project targets
5-
function(llvm_ExternalProject_BuildCmd out_var target bin_dir)
5+
function(llvm_ExternalProject_BuildCmd out_var target bin_dir stamp_dir)
66
cmake_parse_arguments(ARG "" "CONFIGURATION" "" ${ARGN})
77
if(NOT ARG_CONFIGURATION)
88
set(ARG_CONFIGURATION "$<CONFIG>")
99
endif()
1010
if (CMAKE_GENERATOR MATCHES "Make")
1111
# Use special command for Makefiles to support parallelism.
12-
set(${out_var} "$(MAKE)" "-C" "${bin_dir}" "${target}" PARENT_SCOPE)
12+
string(JOIN "@" make_cmd "$(MAKE)" "-C" "${bin_dir}" "${target}")
13+
set(file_lock_script "${LLVM_CMAKE_DIR}/FileLock.cmake")
14+
set(${out_var} ${CMAKE_COMMAND} "-DLOCK_FILE_PATH=${stamp_dir}/cmake.lock"
15+
"-DCOMMAND=${make_cmd}"
16+
"-P" "${file_lock_script}" PARENT_SCOPE)
1317
else()
1418
set(tool_args "${LLVM_EXTERNAL_PROJECT_BUILD_TOOL_ARGS}")
1519
if(NOT tool_args STREQUAL "")
@@ -409,7 +413,7 @@ function(llvm_ExternalProject_Add name source_dir)
409413
set(force_deps DEPENDS ${TOOLCHAIN_BINS})
410414
endif()
411415

412-
llvm_ExternalProject_BuildCmd(run_clean clean ${BINARY_DIR})
416+
llvm_ExternalProject_BuildCmd(run_clean clean ${BINARY_DIR} ${STAMP_DIR})
413417
ExternalProject_Add_Step(${name} clean
414418
COMMAND ${run_clean}
415419
COMMENT "Cleaning ${name}..."
@@ -449,7 +453,7 @@ function(llvm_ExternalProject_Add name source_dir)
449453
else()
450454
set(external_target "${target}")
451455
endif()
452-
llvm_ExternalProject_BuildCmd(build_runtime_cmd ${external_target} ${BINARY_DIR})
456+
llvm_ExternalProject_BuildCmd(build_runtime_cmd ${external_target} ${BINARY_DIR} ${STAMP_DIR})
453457
add_custom_target(${target}
454458
COMMAND ${build_runtime_cmd}
455459
DEPENDS ${name}-configure

0 commit comments

Comments
 (0)