Skip to content

Commit 53ecbf2

Browse files
committed
Change stdlib build to depend on .swiftmodule's instead of .o's for swiftc deps.
Currently SwiftOnoneSupport.o waits on Swift.o to finish compiling before we start compiling SwiftOnoneSupport.o. We don't need the .o for compilation but instead just need Swift.swiftmodule which we were generating anyway. This change causes .o and { .swiftmodule, .swiftdoc } to be built independently of each other. Downstream compiles only wait on the module while downstream links wait on the .o. Given that .apinotes are sometimes used by swiftc invocations, this also separates out apinotes in to its own step which these other commands can both depend on. The result of this is a 30% improvement in building the stdlib with -R and 20% with -d. Specifically, -R drops from 3m to 2m and -d drops from 12m to just under 10m.
1 parent 74e5b33 commit 53ecbf2

File tree

2 files changed

+102
-31
lines changed

2 files changed

+102
-31
lines changed

cmake/modules/AddSwift.cmake

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,7 @@ endfunction()
446446
# _add_swift_library_single(
447447
# target
448448
# name
449+
# [MODULE_TARGET]
449450
# [SHARED]
450451
# [STATIC]
451452
# [SDK sdk]
@@ -474,6 +475,9 @@ endfunction()
474475
# name
475476
# Name of the library (e.g., swiftParse).
476477
#
478+
# MODULE_TARGET
479+
# Name of the module target (e.g., swiftParse-swiftmodule-IOS-armv7).
480+
#
477481
# SHARED
478482
# Build a shared library.
479483
#
@@ -543,7 +547,7 @@ function(_add_swift_library_single target name)
543547
API_NOTES_NON_OVERLAY DONT_EMBED_BITCODE)
544548
cmake_parse_arguments(SWIFTLIB_SINGLE
545549
"${SWIFTLIB_SINGLE_options}"
546-
"SDK;ARCHITECTURE;INSTALL_IN_COMPONENT;DEPLOYMENT_VERSION_IOS"
550+
"MODULE_TARGET;SDK;ARCHITECTURE;INSTALL_IN_COMPONENT;DEPLOYMENT_VERSION_IOS"
547551
"DEPENDS;LINK_LIBRARIES;FRAMEWORK_DEPENDS;FRAMEWORK_DEPENDS_WEAK;LLVM_COMPONENT_DEPENDS;C_COMPILE_FLAGS;SWIFT_COMPILE_FLAGS;LINK_FLAGS;PRIVATE_LINK_LIBRARIES;INTERFACE_LINK_LIBRARIES;INCORPORATE_OBJECT_LIBRARIES;FILE_DEPENDS"
548552
${ARGN})
549553

@@ -682,6 +686,7 @@ function(_add_swift_library_single target name)
682686
# just any swiftmodule files that are associated with them.
683687
handle_swift_sources(
684688
swift_object_dependency_target
689+
swift_module_dependency_target
685690
SWIFTLIB_SINGLE_SOURCES
686691
SWIFTLIB_SINGLE_EXTERNAL_SOURCES ${name}
687692
DEPENDS
@@ -700,6 +705,13 @@ function(_add_swift_library_single target name)
700705
INSTALL_IN_COMPONENT "${SWIFTLIB_INSTALL_IN_COMPONENT}")
701706
add_swift_source_group("${SWIFTLIB_SINGLE_EXTERNAL_SOURCES}")
702707

708+
# If there were any swift sources, then a .swiftmodule may have been created.
709+
# If that is the case, then add a target which is an alias of the module files.
710+
if(NOT "${SWIFTLIB_SINGLE_MODULE_TARGET}" STREQUAL "" AND NOT "${swift_module_dependency_target}" STREQUAL "")
711+
add_custom_target("${SWIFTLIB_SINGLE_MODULE_TARGET}"
712+
DEPENDS ${swift_module_dependency_target})
713+
endif()
714+
703715
set(VARIANT_SUFFIX "-${SWIFT_SDK_${SWIFTLIB_SINGLE_SDK}_LIB_SUBDIR}-${SWIFTLIB_SINGLE_ARCHITECTURE}")
704716
set(SWIFTLIB_INCORPORATED_OBJECT_LIBRARIES_EXPRESSIONS)
705717
foreach(object_library ${SWIFTLIB_SINGLE_INCORPORATE_OBJECT_LIBRARIES})
@@ -874,6 +886,7 @@ function(_add_swift_library_single target name)
874886
${SWIFTLIB_SINGLE_DEPENDS}
875887
${gyb_dependency_targets}
876888
"${swift_object_dependency_target}"
889+
"${swift_module_dependency_target}"
877890
${LLVM_COMMON_DEPENDS})
878891

879892
# HACK: On some systems or build directory setups, CMake will not find static
@@ -1320,6 +1333,8 @@ function(add_swift_library name)
13201333
# Configure variables for this subdirectory.
13211334
set(VARIANT_SUFFIX "-${SWIFT_SDK_${sdk}_LIB_SUBDIR}-${arch}")
13221335
set(VARIANT_NAME "${name}${VARIANT_SUFFIX}")
1336+
set(MODULE_VARIANT_SUFFIX "-swiftmodule${VARIANT_SUFFIX}")
1337+
set(MODULE_VARIANT_NAME "${name}${MODULE_VARIANT_SUFFIX}")
13231338

13241339
# Map dependencies over to the appropriate variants.
13251340
set(swiftlib_link_libraries)
@@ -1352,23 +1367,17 @@ function(add_swift_library name)
13521367
${SWIFTLIB_SWIFT_MODULE_DEPENDS_LINUX})
13531368
endif()
13541369

1370+
# Swift compiles depend on swift modules, while links depend on
1371+
# linked libraries. Find targets for both of these here.
13551372
set(swiftlib_module_dependency_targets)
1373+
set(swiftlib_private_link_libraries_targets)
13561374
foreach(mod ${swiftlib_module_depends_flattened})
13571375
list(APPEND swiftlib_module_dependency_targets
1376+
"swift${mod}${MODULE_VARIANT_SUFFIX}")
1377+
list(APPEND swiftlib_private_link_libraries_targets
13581378
"swift${mod}${VARIANT_SUFFIX}")
13591379
endforeach()
13601380

1361-
set(swiftlib_framework_depends_flattened ${SWIFTLIB_FRAMEWORK_DEPENDS})
1362-
if("${sdk}" STREQUAL "OSX")
1363-
list(APPEND swiftlib_framework_depends_flattened
1364-
${SWIFTLIB_FRAMEWORK_DEPENDS_OSX})
1365-
elseif("${sdk}" STREQUAL "IOS" OR "${sdk}" STREQUAL "IOS_SIMULATOR" OR "${sdk}" STREQUAL "TVOS" OR "${sdk}" STREQUAL "TVOS_SIMULATOR")
1366-
list(APPEND swiftlib_framework_depends_flattened
1367-
${SWIFTLIB_FRAMEWORK_DEPENDS_IOS_TVOS})
1368-
endif()
1369-
1370-
set(swiftlib_private_link_libraries_targets
1371-
${swiftlib_module_dependency_targets})
13721381
foreach(lib ${SWIFTLIB_PRIVATE_LINK_LIBRARIES})
13731382
if("${lib}" STREQUAL "ICU_UC")
13741383
list(APPEND swiftlib_private_link_libraries_targets
@@ -1384,6 +1393,15 @@ function(add_swift_library name)
13841393
endif()
13851394
endforeach()
13861395

1396+
set(swiftlib_framework_depends_flattened ${SWIFTLIB_FRAMEWORK_DEPENDS})
1397+
if("${sdk}" STREQUAL "OSX")
1398+
list(APPEND swiftlib_framework_depends_flattened
1399+
${SWIFTLIB_FRAMEWORK_DEPENDS_OSX})
1400+
elseif("${sdk}" STREQUAL "IOS" OR "${sdk}" STREQUAL "IOS_SIMULATOR" OR "${sdk}" STREQUAL "TVOS" OR "${sdk}" STREQUAL "TVOS_SIMULATOR")
1401+
list(APPEND swiftlib_framework_depends_flattened
1402+
${SWIFTLIB_FRAMEWORK_DEPENDS_IOS_TVOS})
1403+
endif()
1404+
13871405
# Collect compiler flags
13881406
set(swiftlib_swift_compile_flags_all ${SWIFTLIB_SWIFT_COMPILE_FLAGS})
13891407
if("${sdk}" STREQUAL "OSX")
@@ -1421,6 +1439,7 @@ function(add_swift_library name)
14211439
${SWIFTLIB_STATIC_keyword}
14221440
${SWIFTLIB_OBJECT_LIBRARY_keyword}
14231441
${SWIFTLIB_SOURCES}
1442+
MODULE_TARGET ${MODULE_VARIANT_NAME}
14241443
SDK ${sdk}
14251444
ARCHITECTURE ${arch}
14261445
DEPENDS ${SWIFTLIB_DEPENDS}
@@ -1730,6 +1749,7 @@ function(_add_swift_executable_single name)
17301749

17311750
handle_swift_sources(
17321751
dependency_target
1752+
unused_module_dependency_target
17331753
SWIFTEXE_SINGLE_SOURCES SWIFTEXE_SINGLE_EXTERNAL_SOURCES ${name}
17341754
DEPENDS
17351755
${SWIFTEXE_SINGLE_DEPENDS}

cmake/modules/SwiftSource.cmake

Lines changed: 70 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
# Usage:
77
# handle_swift_sources(sourcesvar externalvar)
88
function(handle_swift_sources
9-
dependency_target_out_var_name sourcesvar externalvar name)
9+
dependency_target_out_var_name
10+
dependency_module_target_out_var_name
11+
sourcesvar externalvar name)
1012
cmake_parse_arguments(SWIFTSOURCES
1113
"IS_MAIN;IS_STDLIB;IS_STDLIB_CORE;IS_SDK_OVERLAY"
1214
"SDK;ARCHITECTURE;INSTALL_IN_COMPONENT"
@@ -38,6 +40,7 @@ function(handle_swift_sources
3840

3941
# Clear the result variable.
4042
set("${dependency_target_out_var_name}" "" PARENT_SCOPE)
43+
set("${dependency_module_target_out_var_name}" "" PARENT_SCOPE)
4144

4245
set(result)
4346
set(swift_sources)
@@ -78,6 +81,7 @@ function(handle_swift_sources
7881

7982
_compile_swift_files(
8083
dependency_target
84+
module_dependency_target
8185
OUTPUT ${swift_obj}
8286
SOURCES ${swift_sources}
8387
DEPENDS ${SWIFTSOURCES_DEPENDS}
@@ -93,6 +97,7 @@ function(handle_swift_sources
9397
${STATIC_arg}
9498
INSTALL_IN_COMPONENT "${SWIFTSOURCES_INSTALL_IN_COMPONENT}")
9599
set("${dependency_target_out_var_name}" "${dependency_target}" PARENT_SCOPE)
100+
set("${dependency_module_target_out_var_name}" "${module_dependency_target}" PARENT_SCOPE)
96101
list(APPEND result ${swift_obj})
97102
endif()
98103

@@ -134,7 +139,8 @@ endfunction()
134139
# [IS_STDLIB] # Install produced files.
135140
# [EMIT_SIB] # Emit the file as a sib file instead of a .o
136141
# )
137-
function(_compile_swift_files dependency_target_out_var_name)
142+
function(_compile_swift_files
143+
dependency_target_out_var_name dependency_module_target_out_var_name)
138144
cmake_parse_arguments(SWIFTFILE
139145
"IS_MAIN;IS_STDLIB;IS_STDLIB_CORE;IS_SDK_OVERLAY;EMIT_SIB"
140146
"OUTPUT;MODULE_NAME;INSTALL_IN_COMPONENT"
@@ -274,6 +280,7 @@ function(_compile_swift_files dependency_target_out_var_name)
274280
set(module_file)
275281
set(module_doc_file)
276282

283+
set(module_command)
277284
if(NOT SWIFTFILE_IS_MAIN)
278285
# Determine the directory where the module file should be placed.
279286
if(SWIFTFILE_MODULE_DIR)
@@ -284,16 +291,15 @@ function(_compile_swift_files dependency_target_out_var_name)
284291
message(FATAL_ERROR "Don't know where to put the module files")
285292
endif()
286293

294+
list(APPEND swift_flags "-parse-as-library")
287295
if (NOT SWIFTFILE_EMIT_SIB)
288296
# Right now sib files seem to not be output when we emit a module. So
289297
# don't emit it.
290298
set(module_file "${module_dir}/${SWIFTFILE_MODULE_NAME}.swiftmodule")
291299
set(module_doc_file "${module_dir}/${SWIFTFILE_MODULE_NAME}.swiftdoc")
292-
list(APPEND swift_flags
293-
"-parse-as-library"
294-
"-emit-module" "-emit-module-path" "${module_file}")
295-
else()
296-
list(APPEND swift_flags "-parse-as-library")
300+
list(APPEND module_command
301+
"-emit-module"
302+
"-o" "${module_file}")
297303
endif()
298304

299305
list(APPEND command_create_dirs
@@ -366,9 +372,9 @@ function(_compile_swift_files dependency_target_out_var_name)
366372
set(swift_compiler_tool "${SWIFT_SOURCE_DIR}/utils/check-incremental" "${swift_compiler_tool}")
367373
endif()
368374

369-
set(outputs
370-
${SWIFTFILE_OUTPUT} "${module_file}" "${module_doc_file}"
371-
${apinote_files})
375+
set(standard_outputs ${SWIFTFILE_OUTPUT})
376+
set(apinotes_outputs ${apinote_files})
377+
set(module_outputs "${module_file}" "${module_doc_file}")
372378

373379
if(XCODE)
374380
# HACK: work around an issue with CMake Xcode generator and the Swift
@@ -383,29 +389,74 @@ function(_compile_swift_files dependency_target_out_var_name)
383389
#
384390
# To work around this issue we touch the output files so that their mtime
385391
# always gets updated.
386-
set(command_touch_outputs
387-
COMMAND "${CMAKE_COMMAND}" -E touch ${outputs})
392+
set(command_touch_standard_outputs
393+
COMMAND "${CMAKE_COMMAND}" -E touch ${standard_outputs})
394+
set(command_touch_apinotes_outputs
395+
COMMAND "${CMAKE_COMMAND}" -E touch ${apinotes_outputs})
396+
set(command_touch_module_outputs
397+
COMMAND "${CMAKE_COMMAND}" -E touch ${module_outputs})
388398
endif()
389399

400+
# First generate the obj dirs
390401
add_custom_command_target(
391-
dependency_target
402+
obj_dirs_dependency_target
392403
${command_create_dirs}
393-
# Create API notes before compiling, because this will affect the APIs
394-
# the overlay sees.
395-
${command_create_apinotes}
404+
COMMAND ""
405+
OUTPUT ${obj_dirs}
406+
COMMENT "Generating obj dirs for ${first_output}")
407+
408+
# Generate the api notes if we need them.
409+
if (apinotes_outputs)
410+
add_custom_command_target(
411+
api_notes_dependency_target
412+
# Create API notes before compiling, because this will affect the APIs
413+
# the overlay sees.
414+
${command_create_apinotes}
415+
${command_touch_apinotes_outputs}
416+
COMMAND ""
417+
OUTPUT ${apinotes_outputs}
418+
DEPENDS
419+
${swift_compiler_tool_dep}
420+
${depends_create_apinotes}
421+
${obj_dirs_dependency_target}
422+
COMMENT "Generating API notes ${first_output}")
423+
endif()
424+
425+
# Then we can compile both the object files and the swiftmodule files
426+
# in parallel in this target for the object file, and ...
427+
add_custom_command_target(
428+
dependency_target
396429
COMMAND
397430
"${line_directive_tool}" "${source_files}" --
398431
"${swift_compiler_tool}" "${main_command}" ${swift_flags}
399432
${output_option} "${source_files}"
400-
${command_touch_outputs}
401-
OUTPUT ${outputs}
433+
${command_touch_standard_outputs}
434+
OUTPUT ${standard_outputs}
402435
DEPENDS
403436
${swift_compiler_tool_dep}
404437
${source_files} ${SWIFTFILE_DEPENDS}
405-
${swift_ide_test_dependency} ${depends_create_apinotes}
438+
${swift_ide_test_dependency} ${api_notes_dependency_target}
439+
${obj_dirs_dependency_target}
406440
COMMENT "Compiling ${first_output}")
407441
set("${dependency_target_out_var_name}" "${dependency_target}" PARENT_SCOPE)
408442

443+
# This is the target to generate the .swiftmodule and .swiftdoc
444+
add_custom_command_target(
445+
module_dependency_target
446+
COMMAND
447+
"${line_directive_tool}" "${source_files}" --
448+
"${swift_compiler_tool}" "${module_command}" ${swift_flags}
449+
"${source_files}"
450+
${command_touch_module_outputs}
451+
OUTPUT ${module_outputs}
452+
DEPENDS
453+
${swift_compiler_tool_dep}
454+
${source_files} ${SWIFTFILE_DEPENDS}
455+
${swift_ide_test_dependency} ${api_notes_dependency_target}
456+
${obj_dirs_dependency_target}
457+
COMMENT "Generating ${module_file}")
458+
set("${dependency_module_target_out_var_name}" "${module_dependency_target}" PARENT_SCOPE)
459+
409460
# Make sure the build system knows the file is a generated object file.
410461
set_source_files_properties(${SWIFTFILE_OUTPUT}
411462
PROPERTIES

0 commit comments

Comments
 (0)