From 39bb1b23f904edf4a6bc3025d97902ca7150cfde Mon Sep 17 00:00:00 2001 From: 3405691582 Date: Mon, 6 Jul 2020 12:44:03 -0400 Subject: [PATCH 1/6] [NFC] Move ICU library flag handling to top level. --- stdlib/public/runtime/CMakeLists.txt | 43 ++++++++++++++-------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/stdlib/public/runtime/CMakeLists.txt b/stdlib/public/runtime/CMakeLists.txt index a43be7ce52b1d..3e7a0fd89a4c3 100644 --- a/stdlib/public/runtime/CMakeLists.txt +++ b/stdlib/public/runtime/CMakeLists.txt @@ -75,6 +75,28 @@ set(swift_runtime_library_compile_flags ${swift_runtime_compile_flags}) list(APPEND swift_runtime_library_compile_flags -DswiftCore_EXPORTS) list(APPEND swift_runtime_library_compile_flags -I${SWIFT_SOURCE_DIR}/stdlib/include/llvm/Support -I${SWIFT_SOURCE_DIR}/include) +if(SWIFT_${SWIFT_HOST_VARIANT_SDK}_${SWIFT_HOST_VARIANT_ARCH}_ICU_STATICLIB) + set(libicu_i18n_a -licui18nswift) + set(libicu_uc_a -licuucswift) + set(libicu_data_a -licudataswift) +else() + find_package(ICU REQUIRED COMPONENTS uc i18n) + get_filename_component(ICU_UC_LIBDIR "${ICU_UC_LIBRARIES}" DIRECTORY) + get_filename_component(ICU_I18N_LIBDIR "${ICU_I18N_LIBRARIES}" DIRECTORY) + + set(libicu_i18n_a -licui18n) + set(libicu_uc_a -licuuc) + set(libicu_data_a) + if(EXISTS ${ICU_I18N_LIBDIR}/libicui18n.a AND + EXISTS ${ICU_UC_LIBDIR}/libicuuc.a AND + EXISTS ${ICU_UC_LIBDIR}/libicudata.a) + set(libicu_i18n_a ${ICU_I18N_LIBDIR}/libicui18n.a) + set(libicu_uc_a ${ICU_UC_LIBDIR}/libicuuc.a) + set(libicu_data_a ${ICU_UC_LIBDIR}/libicudata.a) + endif() +endif() + + set(sdk "${SWIFT_HOST_VARIANT_SDK}") if(SWIFT_BUILD_STATIC_STDLIB AND "${sdk}" STREQUAL "LINUX") list(REMOVE_ITEM swift_runtime_sources ImageInspectionELF.cpp) @@ -254,27 +276,6 @@ foreach(sdk ${SWIFT_CONFIGURED_SDKS}) # 'GenericUnix' (eg linux) if(${SWIFT_SDK_${sdk}_OBJECT_FORMAT} STREQUAL ELF) string(TOLOWER "${sdk}" lowercase_sdk) - if(SWIFT_${SWIFT_HOST_VARIANT_SDK}_${SWIFT_HOST_VARIANT_ARCH}_ICU_STATICLIB) - set(libicu_i18n_a -licui18nswift) - set(libicu_uc_a -licuucswift) - set(libicu_data_a -licudataswift) - else() - find_package(ICU REQUIRED COMPONENTS uc i18n) - get_filename_component(ICU_UC_LIBDIR "${ICU_UC_LIBRARIES}" DIRECTORY) - get_filename_component(ICU_I18N_LIBDIR "${ICU_I18N_LIBRARIES}" DIRECTORY) - - set(libicu_i18n_a -licui18n) - set(libicu_uc_a -licuuc) - set(libicu_data_a) - if(EXISTS ${ICU_I18N_LIBDIR}/libicui18n.a AND - EXISTS ${ICU_UC_LIBDIR}/libicuuc.a AND - EXISTS ${ICU_UC_LIBDIR}/libicudata.a) - set(libicu_i18n_a ${ICU_I18N_LIBDIR}/libicui18n.a) - set(libicu_uc_a ${ICU_UC_LIBDIR}/libicuuc.a) - set(libicu_data_a ${ICU_UC_LIBDIR}/libicudata.a) - endif() - endif() - set(linkfile ${lowercase_sdk}/static-stdlib-args.lnk) file(WRITE "${SWIFTSTATICLIB_DIR}/${linkfile}" " -ldl From 02a79361cb3cf510dcefd302a53483d3fa22a3db Mon Sep 17 00:00:00 2001 From: 3405691582 Date: Mon, 6 Jul 2020 12:57:17 -0400 Subject: [PATCH 2/6] [NFC] Write lnk file dynamically from cmake. Instead of copying a static file from the repository, do what the cmakefile already does for static-stdlib-args.lnk and generate it dynamically. This means we can utilize the libicu flags set from the prior commit rather than requiring libicu be built as part of the Swift build just to ensure that the static link flags are correct. --- stdlib/public/runtime/CMakeLists.txt | 26 +++++++++++++++++--------- utils/static-executable-args.lnk | 16 ---------------- 2 files changed, 17 insertions(+), 25 deletions(-) delete mode 100644 utils/static-executable-args.lnk diff --git a/stdlib/public/runtime/CMakeLists.txt b/stdlib/public/runtime/CMakeLists.txt index 3e7a0fd89a4c3..0aef4ca7bbd18 100644 --- a/stdlib/public/runtime/CMakeLists.txt +++ b/stdlib/public/runtime/CMakeLists.txt @@ -143,15 +143,23 @@ if(SWIFT_BUILD_STATIC_STDLIB AND "${sdk}" STREQUAL "LINUX") # Generate the static-executable-args.lnk file used for ELF systems (eg linux) set(linkfile "${lowercase_sdk}/static-executable-args.lnk") - add_custom_command_target(swift_static_binary_${sdk}_args - COMMAND - "${CMAKE_COMMAND}" -E copy - "${SWIFT_SOURCE_DIR}/utils/static-executable-args.lnk" - "${SWIFTSTATICLIB_DIR}/${linkfile}" - OUTPUT - "${SWIFTSTATICLIB_DIR}/${linkfile}" - DEPENDS - "${SWIFT_SOURCE_DIR}/utils/static-executable-args.lnk") + file(WRITE "${SWIFTSTATICLIB_DIR}/${linkfile}" " +-static +-lswiftCore +-lswiftImageInspectionShared +-Xlinker +--defsym=__import_pthread_self=pthread_self +-Xlinker +--defsym=__import_pthread_once=pthread_once +-Xlinker +--defsym=__import_pthread_key_create=pthread_key_create +-lpthread +${libicu_i18n_a} +${libicu_uc_a} +${libicu_data_a} +-ldl +-lstdc++ +-lm") list(APPEND static_binary_lnk_file_list ${swift_static_binary_${sdk}_args}) swift_install_in_component(FILES "${SWIFTSTATICLIB_DIR}/${linkfile}" diff --git a/utils/static-executable-args.lnk b/utils/static-executable-args.lnk deleted file mode 100644 index 98b814164c242..0000000000000 --- a/utils/static-executable-args.lnk +++ /dev/null @@ -1,16 +0,0 @@ --static --lswiftCore --lswiftImageInspectionShared --Xlinker ---defsym=__import_pthread_self=pthread_self --Xlinker ---defsym=__import_pthread_once=pthread_once --Xlinker ---defsym=__import_pthread_key_create=pthread_key_create --lpthread --licui18nswift --licuucswift --licudataswift --ldl --lstdc++ --lm From 4c5b57fafaeaf4ee5ab724d345fcb9e8ff2e7cdd Mon Sep 17 00:00:00 2001 From: 3405691582 Date: Mon, 6 Jul 2020 14:58:22 -0400 Subject: [PATCH 3/6] [static] ELF platforms can build static binaries. Static binaries can be built on other platforms, not just Linux; we use the same check for ELF output to condition static binaries like for static stdlib. However, since some ELF platforms don't need -ldl, pull this out into a conditionally set variable. As a side note: on OpenBSD, lld at HEAD does not work to link the test binary, but the platform lld works fine, so XFAIL this temporarily. --- stdlib/public/runtime/CMakeLists.txt | 14 ++++++++++---- test/Driver/static-executable.swift | 1 + ...atic-stdlib-linux.swift => static-stdlib.swift} | 2 +- unittests/runtime/CMakeLists.txt | 3 ++- 4 files changed, 14 insertions(+), 6 deletions(-) rename test/Driver/{static-stdlib-linux.swift => static-stdlib.swift} (89%) diff --git a/stdlib/public/runtime/CMakeLists.txt b/stdlib/public/runtime/CMakeLists.txt index 0aef4ca7bbd18..e6a9faf098868 100644 --- a/stdlib/public/runtime/CMakeLists.txt +++ b/stdlib/public/runtime/CMakeLists.txt @@ -96,9 +96,15 @@ else() endif() endif() +# TODO: Put the logic for finding libdl in a module, similar to ICU. +set(libdl) +if(SWIFT_BUILD_STATIC_STDLIB AND "${sdk}" STREQUAL "LINUX") + set(libdl -ldl) +endif() + set(sdk "${SWIFT_HOST_VARIANT_SDK}") -if(SWIFT_BUILD_STATIC_STDLIB AND "${sdk}" STREQUAL "LINUX") +if(SWIFT_BUILD_STATIC_STDLIB AND ${SWIFT_SDK_${sdk}_OBJECT_FORMAT} STREQUAL ELF) list(REMOVE_ITEM swift_runtime_sources ImageInspectionELF.cpp) set(static_binary_lnk_file_list) string(TOLOWER "${sdk}" lowercase_sdk) @@ -157,7 +163,7 @@ if(SWIFT_BUILD_STATIC_STDLIB AND "${sdk}" STREQUAL "LINUX") ${libicu_i18n_a} ${libicu_uc_a} ${libicu_data_a} --ldl +${libdl} -lstdc++ -lm") @@ -166,7 +172,7 @@ ${libicu_data_a} DESTINATION "lib/swift_static/${lowercase_sdk}" COMPONENT stdlib) add_custom_target(static_binary_magic ALL DEPENDS ${static_binary_lnk_file_list}) - foreach(arch IN LISTS SWIFT_SDK_LINUX_ARCHITECTURES) + foreach(arch IN LISTS SWIFT_SDK_${sdk}_ARCHITECTURES) add_dependencies(static_binary_magic ${swift_image_inspection_${arch}_static}) endforeach() add_dependencies(static_binary_magic ${swift_image_inspection_static_primary_arch}) @@ -286,7 +292,7 @@ foreach(sdk ${SWIFT_CONFIGURED_SDKS}) string(TOLOWER "${sdk}" lowercase_sdk) set(linkfile ${lowercase_sdk}/static-stdlib-args.lnk) file(WRITE "${SWIFTSTATICLIB_DIR}/${linkfile}" " --ldl +${libdl} -lpthread -lswiftCore -lswiftImageInspectionShared diff --git a/test/Driver/static-executable.swift b/test/Driver/static-executable.swift index f81b9ac593eec..b7008961b0c1e 100644 --- a/test/Driver/static-executable.swift +++ b/test/Driver/static-executable.swift @@ -1,6 +1,7 @@ // Create a self contained binary // REQUIRES: OS=linux-gnu // REQUIRES: static_stdlib +// XFAIL: OS=openbsd print("hello world!") // RUN: %empty-directory(%t) // RUN: %target-swiftc_driver -static-executable -o %t/static-executable %s diff --git a/test/Driver/static-stdlib-linux.swift b/test/Driver/static-stdlib.swift similarity index 89% rename from test/Driver/static-stdlib-linux.swift rename to test/Driver/static-stdlib.swift index 59d5e290efe32..8cc9ec46baf39 100644 --- a/test/Driver/static-stdlib-linux.swift +++ b/test/Driver/static-stdlib.swift @@ -1,5 +1,5 @@ // Statically link a "hello world" program -// REQUIRES: OS=linux-gnu +// REQUIRES: OS=linux-gnu || OS=openbsd // REQUIRES: static_stdlib print("hello world!") // RUN: %empty-directory(%t) diff --git a/unittests/runtime/CMakeLists.txt b/unittests/runtime/CMakeLists.txt index 3ca27587f9e7b..1af2c2e4d38ae 100644 --- a/unittests/runtime/CMakeLists.txt +++ b/unittests/runtime/CMakeLists.txt @@ -29,7 +29,8 @@ if(("${SWIFT_HOST_VARIANT_SDK}" STREQUAL "${SWIFT_PRIMARY_VARIANT_SDK}") AND endif() set(swift_runtime_test_extra_libraries) - if(SWIFT_BUILD_STATIC_STDLIB AND "${SWIFT_HOST_VARIANT_SDK}" STREQUAL "LINUX") + if(SWIFT_BUILD_STATIC_STDLIB AND + ${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_OBJECT_FORMAT} STREQUAL ELF) list(APPEND swift_runtime_test_extra_libraries $) endif() From af31e09999e9f0e6759f28b7ff7b4ea4df24e698 Mon Sep 17 00:00:00 2001 From: 3405691582 Date: Mon, 6 Jul 2020 22:32:57 -0400 Subject: [PATCH 4/6] [static] Mark some tests unsupported. In the prior commit we opened static binaries for all ELF platforms when requested. For some reason, the ImageInspectionELF module is split out into its own library when building stdlib as a static library. However, there are still references to lookupSymbol from swiftCore to ImageInspectionELF, which cause lazy binding errors at runtime which foul up these unit tests. Currently it is unknown whether it is necessary to keep splitting out ImageInspectionELF like this; on its face, this seems rather unnecessary. Until then, mark these tests unsupported when stdlib exists as a static library, since these tests use the dynamic version of stdlib, and won't have the correct references to ImageInspectionELF. --- test/Frontend/crash-in-user-code.swift | 2 ++ test/Interpreter/enforce_exclusive_access.swift | 2 ++ test/Runtime/backtrace.swift | 2 ++ 3 files changed, 6 insertions(+) diff --git a/test/Frontend/crash-in-user-code.swift b/test/Frontend/crash-in-user-code.swift index 4a36a0c3b5a4c..c6133f206b8b3 100644 --- a/test/Frontend/crash-in-user-code.swift +++ b/test/Frontend/crash-in-user-code.swift @@ -1,3 +1,5 @@ +// See SR-13165 +// UNSUPPORTED: static_stdlib // RUN: echo %s > %t.filelist.txt // RUN: not --crash %target-swift-frontend -interpret -filelist %t.filelist.txt 2>&1 | %FileCheck %s diff --git a/test/Interpreter/enforce_exclusive_access.swift b/test/Interpreter/enforce_exclusive_access.swift index 321dc5dfcd38b..121a0f9e19998 100644 --- a/test/Interpreter/enforce_exclusive_access.swift +++ b/test/Interpreter/enforce_exclusive_access.swift @@ -1,3 +1,5 @@ +// See SR-13165 +// UNSUPPORTED: static_stdlib // RUN: %empty-directory(%t) // RUN: %target-build-swift -swift-version 4 %s -o %t/a.out -enforce-exclusivity=checked -Onone // diff --git a/test/Runtime/backtrace.swift b/test/Runtime/backtrace.swift index e425a0f8c3a1d..8ede2c142ad36 100644 --- a/test/Runtime/backtrace.swift +++ b/test/Runtime/backtrace.swift @@ -1,3 +1,5 @@ +// See SR-13165 +// UNSUPPORTED: static_stdlib // RUN: %empty-directory(%t) // RUN: %target-build-swift %s -o %t/a.out // RUN: %{python} %S/../Inputs/not.py "%target-run %t/a.out" 2>&1 | %{python} %utils/backtrace-check From 9cea66be2e2257baba57d7efce28d6cc6955db26 Mon Sep 17 00:00:00 2001 From: 3405691582 Date: Tue, 7 Jul 2020 14:55:46 -0400 Subject: [PATCH 5/6] [cmake] FindICU finds static libraries as well. As suggested in #32736, it would be ideal to use the FindICU generated variables to refer to the ICU library paths. However, as it stands, this only finds the dynamic libraries, so here we find the static libraries as well. --- cmake/modules/FindICU.cmake | 5 +++++ cmake/modules/SwiftConfigureSDK.cmake | 2 ++ 2 files changed, 7 insertions(+) diff --git a/cmake/modules/FindICU.cmake b/cmake/modules/FindICU.cmake index 611773c4a2d05..8ef66359a124b 100644 --- a/cmake/modules/FindICU.cmake +++ b/cmake/modules/FindICU.cmake @@ -22,6 +22,8 @@ foreach(MODULE ${ICU_FIND_COMPONENTS}) HINTS ${PC_ICU_${MODULE}_INCLUDE_DIRS}) find_library(ICU_${MODULE}_LIBRARIES NAMES icu${module} ${ICU_${MODULE}_LIB_NAME} HINTS ${PC_ICU_${MODULE}_LIBRARY_DIRS}) + find_library(ICU_${MODULE}_LIBRARIES_STATIC NAMES libicu${module}.a ${ICU_${MODULE}_LIB_NAME} + HINTS ${PC_ICU_${MODULE}_LIBRARY_DIRS}) endforeach() foreach(sdk ANDROID;FREEBSD;OPENBSD;LINUX;WINDOWS;HAIKU) @@ -33,6 +35,9 @@ foreach(sdk ANDROID;FREEBSD;OPENBSD;LINUX;WINDOWS;HAIKU) if("${SWIFT_${sdk}_${SWIFT_HOST_VARIANT_ARCH}_ICU_${MODULE}}" STREQUAL "") set(SWIFT_${sdk}_${SWIFT_HOST_VARIANT_ARCH}_ICU_${MODULE} ${ICU_${MODULE}_LIBRARIES} CACHE STRING "" FORCE) endif() + if("${SWIFT_${sdk}_${SWIFT_HOST_VARIANT_ARCH}_ICU_${MODULE}_STATIC}" STREQUAL "") + set(SWIFT_${sdk}_${SWIFT_HOST_VARIANT_ARCH}_ICU_${MODULE}_STATIC ${ICU_${MODULE}_LIBRARIES_STATIC} CACHE STRING "" FORCE) + endif() endforeach() endforeach() diff --git a/cmake/modules/SwiftConfigureSDK.cmake b/cmake/modules/SwiftConfigureSDK.cmake index 52c08025e62a0..c66b8c700bcb6 100644 --- a/cmake/modules/SwiftConfigureSDK.cmake +++ b/cmake/modules/SwiftConfigureSDK.cmake @@ -76,8 +76,10 @@ function(_report_sdk prefix) foreach(arch ${SWIFT_SDK_${prefix}_ARCHITECTURES}) message(STATUS " ${arch} ICU i18n INCLUDE: ${SWIFT_${prefix}_${arch}_ICU_I18N_INCLUDE}") message(STATUS " ${arch} ICU i18n LIB: ${SWIFT_${prefix}_${arch}_ICU_I18N}") + message(STATUS " ${arch} ICU i18n static LIB: ${SWIFT_${prefix}_${arch}_ICU_I18N_STATIC}") message(STATUS " ${arch} ICU unicode INCLUDE: ${SWIFT_${prefix}_${arch}_ICU_UC_INCLUDE}") message(STATUS " ${arch} ICU unicode LIB: ${SWIFT_${prefix}_${arch}_ICU_UC}") + message(STATUS " ${arch} ICU unicode static LIB: ${SWIFT_${prefix}_${arch}_ICU_UC_STATIC}") endforeach() endif() endif() From e1c80113641af4139c51946f77eb50207d3dffe2 Mon Sep 17 00:00:00 2001 From: 3405691582 Date: Tue, 7 Jul 2020 14:58:54 -0400 Subject: [PATCH 6/6] [static][stdlib] Use the FindICU variables. Instead of deriving the static library paths twice, use the variables generated by the FindICU cmake module. The base cmakefiles only find icui18n and icuuc, but icudata is required to complete a static link, so we have to invoke find_package again here to ensure the variable is set. --- stdlib/public/runtime/CMakeLists.txt | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/stdlib/public/runtime/CMakeLists.txt b/stdlib/public/runtime/CMakeLists.txt index e6a9faf098868..424382fe40347 100644 --- a/stdlib/public/runtime/CMakeLists.txt +++ b/stdlib/public/runtime/CMakeLists.txt @@ -80,20 +80,10 @@ if(SWIFT_${SWIFT_HOST_VARIANT_SDK}_${SWIFT_HOST_VARIANT_ARCH}_ICU_STATICLIB) set(libicu_uc_a -licuucswift) set(libicu_data_a -licudataswift) else() - find_package(ICU REQUIRED COMPONENTS uc i18n) - get_filename_component(ICU_UC_LIBDIR "${ICU_UC_LIBRARIES}" DIRECTORY) - get_filename_component(ICU_I18N_LIBDIR "${ICU_I18N_LIBRARIES}" DIRECTORY) - - set(libicu_i18n_a -licui18n) - set(libicu_uc_a -licuuc) - set(libicu_data_a) - if(EXISTS ${ICU_I18N_LIBDIR}/libicui18n.a AND - EXISTS ${ICU_UC_LIBDIR}/libicuuc.a AND - EXISTS ${ICU_UC_LIBDIR}/libicudata.a) - set(libicu_i18n_a ${ICU_I18N_LIBDIR}/libicui18n.a) - set(libicu_uc_a ${ICU_UC_LIBDIR}/libicuuc.a) - set(libicu_data_a ${ICU_UC_LIBDIR}/libicudata.a) - endif() + find_package(ICU REQUIRED COMPONENTS uc i18n data) + set(libicu_i18n_a ${SWIFT_${SWIFT_HOST_VARIANT_SDK}_${SWIFT_HOST_VARIANT_ARCH}_ICU_I18N_STATIC}) + set(libicu_uc_a ${SWIFT_${SWIFT_HOST_VARIANT_SDK}_${SWIFT_HOST_VARIANT_ARCH}_ICU_UC_STATIC}) + set(libicu_data_a ${SWIFT_${SWIFT_HOST_VARIANT_SDK}_${SWIFT_HOST_VARIANT_ARCH}_ICU_DATA_STATIC}) endif() # TODO: Put the logic for finding libdl in a module, similar to ICU.