Skip to content

Commit 3f5029f

Browse files
authored
Merge pull request #66246 from apple/maxd/5.8-cmake-dispatch-fix
[5.8] CMake: fix missing `SWIFT_CONCURRENCY_GLOBAL_EXECUTOR` Explanation: Resolves issues with static linking on Linux Risk: Medium, affects Linux builds and top-level CMake declarations. Original PRs: #65795 and #64312 for `main`, #65824 and #64633 for `release/5.9` Reviewed by: @al45tair @drexin @etcwilde Resolves: some of the issues reported in #65097, also resolves #58380 Tests: Added in swiftlang/swift-integration-tests#118 `SWIFT_CONCURRENCY_GLOBAL_EXECUTOR` is defined in `stdlib/cmake/modules/StdlibOptions.cmake`, which is not included during the first pass of evaluation of the root `CMakeLists.txt`. It is available on subsequent evaluations after the value is stored in CMake cache. This led to subtle bugs, where `usr/lib/swift_static/linux/static-stdlib-args.lnk` didn't contain certain flags on clean toolchain builds, but did contain them in incremental builds. Not having these autolinking flags in toolchain builds leads to errors when statically linking executables on Linux. Additionally, since our trivial lit tests previously didn't link Dispatch statically, they didn't expose a bug where `%import-static-libdispatch` substitution had a missing value. To fix that I had to update `lit.cfg` and clean up some of the related path computations to infer a correct substitution value.
2 parents 85f8090 + 3fd9fdf commit 3f5029f

File tree

7 files changed

+74
-34
lines changed

7 files changed

+74
-34
lines changed

CMakeLists.txt

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -619,13 +619,6 @@ if(NOT EXISTS "${SWIFT_PATH_TO_SWIFT_SYNTAX_SOURCE}")
619619
message(SEND_ERROR "swift-syntax is required to build the Swift compiler. Please run update-checkout or specify SWIFT_PATH_TO_SWIFT_SYNTAX_SOURCE")
620620
endif()
621621

622-
# Use dispatch as the system scheduler by default.
623-
# For convenience, we set this to false when concurrency is disabled.
624-
set(SWIFT_CONCURRENCY_USES_DISPATCH FALSE)
625-
if(SWIFT_ENABLE_EXPERIMENTAL_CONCURRENCY AND "${SWIFT_CONCURRENCY_GLOBAL_EXECUTOR}" STREQUAL "dispatch")
626-
set(SWIFT_CONCURRENCY_USES_DISPATCH TRUE)
627-
endif()
628-
629622
set(SWIFT_BUILD_HOST_DISPATCH FALSE)
630623
if(SWIFT_ENABLE_DISPATCH AND NOT CMAKE_SYSTEM_NAME STREQUAL Darwin)
631624
# Only build libdispatch for the host if the host tools are being built and
@@ -634,9 +627,9 @@ if(SWIFT_ENABLE_DISPATCH AND NOT CMAKE_SYSTEM_NAME STREQUAL Darwin)
634627
set(SWIFT_BUILD_HOST_DISPATCH TRUE)
635628
endif()
636629

637-
if(SWIFT_BUILD_HOST_DISPATCH OR SWIFT_CONCURRENCY_USES_DISPATCH)
630+
if(SWIFT_BUILD_HOST_DISPATCH)
638631
if(NOT EXISTS "${SWIFT_PATH_TO_LIBDISPATCH_SOURCE}")
639-
message(SEND_ERROR "SourceKit and concurrency require libdispatch on non-Darwin hosts. Please specify SWIFT_PATH_TO_LIBDISPATCH_SOURCE")
632+
message(SEND_ERROR "SourceKit requires libdispatch on non-Darwin hosts. Please specify SWIFT_PATH_TO_LIBDISPATCH_SOURCE")
640633
endif()
641634
endif()
642635
endif()

lib/DriverTool/autolink_extract_main.cpp

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -243,15 +243,50 @@ int autolink_extract_main(ArrayRef<const char *> Args, const char *Argv0,
243243
std::vector<std::string> LinkerFlags;
244244

245245
// Keep track of whether we've already added the common
246-
// Swift libraries that ususally have autolink directives
247-
// in most object fiels
248-
std::unordered_map<std::string, bool> SwiftRuntimeLibraries = {
249-
{"-lswiftSwiftOnoneSupport", false},
250-
{"-lswiftCore", false},
251-
{"-lswift_Concurrency", false},
252-
{"-lswift_StringProcessing", false},
253-
{"-lswift_RegexParser", false}
246+
// Swift libraries that usually have autolink directives
247+
// in most object files
248+
249+
std::vector<std::string> SwiftRuntimeLibsOrdered = {
250+
// Common Swift runtime libs
251+
"-lswiftSwiftOnoneSupport",
252+
"-lswiftCore",
253+
"-lswift_Concurrency",
254+
"-lswift_StringProcessing",
255+
"-lswift_RegexBuilder",
256+
"-lswift_RegexParser",
257+
"-lswift_Backtracing",
258+
"-lswiftGlibc",
259+
"-lBlocksRuntime",
260+
// Dispatch-specific Swift runtime libs
261+
"-ldispatch",
262+
"-lDispatchStubs",
263+
"-lswiftDispatch",
264+
// CoreFoundation and Foundation Swift runtime libs
265+
"-lCoreFoundation",
266+
"-lFoundation",
267+
"-lFoundationNetworking",
268+
"-lFoundationXML",
269+
// Foundation support libs
270+
"-lcurl",
271+
"-lxml2",
272+
"-luuid",
273+
// XCTest runtime libs (must be first due to http://github.com/apple/swift-corelibs-xctest/issues/432)
274+
"-lXCTest",
275+
// ICU Swift runtime libs
276+
"-licui18nswift",
277+
"-licuucswift",
278+
"-licudataswift",
279+
// Common-use ordering-agnostic Linux system libs
280+
"-lm",
281+
"-lpthread",
282+
"-lutil",
283+
"-ldl",
284+
"-lz",
254285
};
286+
std::unordered_map<std::string, bool> SwiftRuntimeLibraries;
287+
for (const auto &RuntimeLib : SwiftRuntimeLibsOrdered) {
288+
SwiftRuntimeLibraries[RuntimeLib] = false;
289+
}
255290

256291
// Extract the linker flags from the objects.
257292
for (const auto &BinaryFileName : Invocation.getInputFilenames()) {
@@ -288,9 +323,11 @@ int autolink_extract_main(ArrayRef<const char *> Args, const char *Argv0,
288323
OutOS << Flag << '\n';
289324
}
290325

291-
for (const auto &RuntimeLib : SwiftRuntimeLibraries) {
292-
if (RuntimeLib.second)
293-
OutOS << RuntimeLib.first << '\n';
326+
for (const auto &RuntimeLib : SwiftRuntimeLibsOrdered) {
327+
auto entry = SwiftRuntimeLibraries.find(RuntimeLib);
328+
if (entry != SwiftRuntimeLibraries.end() && entry->second) {
329+
OutOS << entry->first << '\n';
330+
}
294331
}
295332

296333

stdlib/cmake/modules/StdlibOptions.cmake

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,3 +228,16 @@ option(SWIFT_STDLIB_CONCURRENCY_TRACING
228228
"Enable concurrency tracing in the runtime; assumes the presence of os_log(3)
229229
and the os_signpost(3) API."
230230
"${SWIFT_STDLIB_CONCURRENCY_TRACING_default}")
231+
232+
# Use dispatch as the system scheduler by default.
233+
# For convenience, we set this to false when concurrency is disabled.
234+
set(SWIFT_CONCURRENCY_USES_DISPATCH FALSE)
235+
if(SWIFT_ENABLE_EXPERIMENTAL_CONCURRENCY AND "${SWIFT_CONCURRENCY_GLOBAL_EXECUTOR}" STREQUAL "dispatch")
236+
set(SWIFT_CONCURRENCY_USES_DISPATCH TRUE)
237+
endif()
238+
239+
if(SWIFT_CONCURRENCY_USES_DISPATCH AND NOT CMAKE_SYSTEM_NAME STREQUAL Darwin)
240+
if(NOT EXISTS "${SWIFT_PATH_TO_LIBDISPATCH_SOURCE}")
241+
message(SEND_ERROR "Concurrency requires libdispatch on non-Darwin hosts. Please specify SWIFT_PATH_TO_LIBDISPATCH_SOURCE")
242+
endif()
243+
endif()

test/Driver/static-stdlib-autolink-linux.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@
77
// RUN: echo 'public func asyncFunc() async { print("Hello") }' > %t/asyncModule.swift
88

99
// RUN: %target-swiftc_driver -emit-library -emit-module -module-name asyncModule -module-link-name asyncModule %t/asyncModule.swift -static -static-stdlib -o %t/libasyncModule.a
10-
// TODO: "-ldispatch -lBlocksRuntime" should be told by asyncModule.swiftmodule transitively
11-
// RUN: %target-swiftc_driver -parse-as-library -static -static-stdlib -module-name main %s %import-static-libdispatch -I%t -L%t -ldispatch -lBlocksRuntime -o %t/main
10+
// RUN: %target-swiftc_driver -parse-as-library -static -static-stdlib -module-name main %s %import-static-libdispatch -I%t -L%t -o %t/main
1211

1312
// RUN: %t/main | %FileCheck %s
1413
// CHECK: Hello

test/Driver/static-stdlib-linux.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// REQUIRES: static_stdlib
44
print("hello world!")
55
// RUN: %empty-directory(%t)
6-
// RUN: %target-swiftc_driver -static-stdlib -o %t/static-stdlib %s
6+
// RUN: %target-swiftc_driver %import-static-libdispatch -static-stdlib -o %t/static-stdlib %s
77
// RUN: %t/static-stdlib | %FileCheck %s
88
// RUN: ldd %t/static-stdlib | %FileCheck %s --check-prefix=LDD
99
// CHECK: hello world!

test/lit.cfg

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1483,19 +1483,13 @@ elif (run_os in ['linux-gnu', 'linux-gnueabihf', 'freebsd', 'openbsd', 'windows-
14831483
config.import_libdispatch = ('-I %s -I %s -L %s'
14841484
% (libdispatch_source_dir, libdispatch_swift_module_dir, libdispatch_artifact_dir))
14851485

1486-
libdispatch_static_artifact_dir = config.libdispatch_static_build_path
1487-
libdispatch_swift_static_module_dir = make_path(libdispatch_static_artifact_dir, 'src', 'swift', 'swift')
1486+
libdispatch_static_artifact_dir = os.path.join(config.libdispatch_static_build_path, 'lib')
14881487
libdispatch_static_artifacts = [
1489-
make_path(libdispatch_static_artifact_dir, 'src', 'libdispatch.a'),
1490-
make_path(libdispatch_static_artifact_dir, 'src', 'swift', 'libswiftDispatch.a'),
1491-
make_path(libdispatch_swift_static_module_dir, 'Dispatch.swiftmodule')]
1488+
make_path(libdispatch_static_artifact_dir, 'libdispatch.a'),
1489+
make_path(libdispatch_static_artifact_dir, 'libBlocksRuntime.a')]
14921490
if (all(os.path.exists(p) for p in libdispatch_static_artifacts)):
14931491
config.available_features.add('libdispatch_static')
1494-
config.import_libdispatch_static = ('-I %s -I %s -L %s -L %s -L %s'
1495-
% (libdispatch_source_dir, libdispatch_swift_static_module_dir,
1496-
make_path(libdispatch_static_artifact_dir, 'src'),
1497-
make_path(libdispatch_static_artifact_dir, 'src', 'BlocksRuntime'),
1498-
make_path(libdispatch_static_artifact_dir, 'src', 'swift')))
1492+
config.import_libdispatch_static = '-L %s' % libdispatch_static_artifact_dir
14991493

15001494
config.target_build_swift = (
15011495
'%s -target %s -toolchain-stdlib-rpath %s %s %s %s %s'
@@ -2519,6 +2513,10 @@ run_filecheck = '%s %s --allow-unused-prefixes --sanitize BUILD_DIR=%s --sanitiz
25192513
config.substitutions.append(('%FileCheck', run_filecheck))
25202514
config.substitutions.append(('%raw-FileCheck', shell_quote(config.filecheck)))
25212515
config.substitutions.append(('%import-libdispatch', getattr(config, 'import_libdispatch', '')))
2516+
# WARNING: the order of components in a substitution name has to be different from the previous one, as lit does
2517+
# a pure string substitution without understanding that these components are grouped together. That is, the following
2518+
# subsitution name can't be `%import-libdispatch-static`, otherwise the first two components will be substituted with
2519+
# the value of `%import-libdispatch` substitution with `-static` string appended to it.
25222520
config.substitutions.append(('%import-static-libdispatch', getattr(config, 'import_libdispatch_static', '')))
25232521

25242522
# Disable COW sanity checks in the swift runtime by default.

utils/build-script-impl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2011,7 +2011,7 @@ for host in "${ALL_HOSTS[@]}"; do
20112011
-DSWIFT_PATH_TO_CMARK_BUILD:PATH="$(build_directory ${host} cmark)"
20122012
-DSWIFT_PATH_TO_LIBDISPATCH_SOURCE:PATH="${LIBDISPATCH_SOURCE_DIR}"
20132013
-DSWIFT_PATH_TO_LIBDISPATCH_BUILD:PATH="$(build_directory ${host} libdispatch)"
2014-
-DSWIFT_PATH_TO_LIBDISPATCH_STATIC_BUILD:PATH="$(build_directory ${host} libdispatch_static)"
2014+
-DSWIFT_PATH_TO_LIBDISPATCH_STATIC_BUILD:PATH="$(build_directory ${host} swift)/$(basename $(build_directory ${host} libdispatch))-static-prefix"
20152015
)
20162016

20172017
if [[ "${SWIFT_SDKS}" ]] ; then

0 commit comments

Comments
 (0)