From 70e79094e4206e6cfaddb917f0d6b94188f0d714 Mon Sep 17 00:00:00 2001 From: Simon Evans Date: Tue, 18 Oct 2016 09:33:28 +0100 Subject: [PATCH 1/4] Optionally compile libicu - Add --libicu option to compile icu from source. This allows the configuration to be controlled so that it is enabled for shared and static building and the static files dont require the use of the dynamic loader - Add --install-libicu option to install the shared libraries into $prefix/lib/swift and the static ones into $prefix/lib/swift_static. This avoids interference with system installed versions - Dont use find_package if building ICU from source --- stdlib/public/core/CMakeLists.txt | 10 +- utils/build-script | 22 ++++ utils/build-script-impl | 121 +++++++++++++++++- .../swift_build_support/products/__init__.py | 2 + .../swift_build_support/products/libicu.py | 17 +++ 5 files changed, 168 insertions(+), 4 deletions(-) create mode 100644 utils/swift_build_support/swift_build_support/products/libicu.py diff --git a/stdlib/public/core/CMakeLists.txt b/stdlib/public/core/CMakeLists.txt index 6ab835e1ae087..2be23b21ca8ee 100644 --- a/stdlib/public/core/CMakeLists.txt +++ b/stdlib/public/core/CMakeLists.txt @@ -177,9 +177,13 @@ else() # effort has been completed. #set(LINK_FLAGS # -Wl,--whole-archive swiftRuntime -Wl,--no-whole-archive) - find_package(ICU REQUIRED COMPONENTS uc i18n) - list(APPEND swift_core_private_link_libraries - ICU_UC ICU_I18N) + if("${SWIFT_PATH_TO_LIBICU_BUILD}" STREQUAL "") + find_package(ICU REQUIRED COMPONENTS uc i18n) + list(APPEND swift_core_private_link_libraries + ICU_UC ICU_I18N) + else() + list(APPEND swift_core_private_link_libraries -licui18n -licuuc -licudata) + endif() endif() if("${CMAKE_SYSTEM_NAME}" STREQUAL "CYGWIN") diff --git a/utils/build-script b/utils/build-script index 5d2dd9dbd1387..e0f4471bad1d6 100755 --- a/utils/build-script +++ b/utils/build-script @@ -280,6 +280,9 @@ class BuildScriptInvocation(object): if args.libdispatch_build_variant is None: args.libdispatch_build_variant = args.build_variant + if args.libicu_build_variant is None: + args.libicu_build_variant = args.build_variant + # Assertions are enabled by default. if args.assertions is None: args.assertions = True @@ -337,6 +340,7 @@ class BuildScriptInvocation(object): args.build_xctest = False args.build_foundation = False args.build_libdispatch = False + args.build_libicu = False args.build_playgroundlogger = False args.build_playgroundsupport = False @@ -585,6 +589,7 @@ class BuildScriptInvocation(object): "--lldb-build-type", args.lldb_build_variant, "--foundation-build-type", args.foundation_build_variant, "--libdispatch-build-type", args.libdispatch_build_variant, + "--libicu-build-type", args.libicu_build_variant, "--xctest-build-type", args.build_variant, "--swift-enable-assertions", str(args.swift_assertions).lower(), "--swift-stdlib-enable-assertions", str( @@ -664,6 +669,8 @@ class BuildScriptInvocation(object): impl_args += ["--skip-build-llbuild"] if not args.build_libdispatch: impl_args += ["--skip-build-libdispatch"] + if not args.build_libicu: + impl_args += ["--skip-build-libicu"] if not args.build_swiftpm: impl_args += ["--skip-build-swiftpm"] if not args.build_playgroundlogger: @@ -714,6 +721,7 @@ class BuildScriptInvocation(object): "--skip-test-xctest", "--skip-test-foundation", "--skip-test-libdispatch", + "--skip-test-libicu", "--skip-test-playgroundlogger", "--skip-test-playgroundsupport"] if args.skip_test_linux: @@ -881,6 +889,8 @@ class BuildScriptInvocation(object): product_classes = [] product_classes.append(products.CMark) product_classes.append(products.LLVM) + if self.args.build_libicu: + product_classes.append(products.LibICU) product_classes.append(products.Swift) if self.args.build_lldb: product_classes.append(products.LLDB) @@ -1130,6 +1140,7 @@ SWIFT_SOURCE_ROOT: a directory containing the source for LLVM, Clang, Swift. /swift-corelibs-xctest (optional) /swift-corelibs-foundation (optional) /swift-corelibs-libdispatch (optional) + /icu (optional) SWIFT_BUILD_ROOT: a directory in which to create out-of-tree builds. Defaults to "$SWIFT_SOURCE_ROOT/build/". @@ -1323,6 +1334,11 @@ details of the setups of other systems or automated environments.""") help="build libdispatch", action=arguments.action.optional_bool, dest="build_libdispatch") + projects_group.add_argument( + "--libicu", + help="build libicu", + action=arguments.action.optional_bool, + dest="build_libicu") projects_group.add_argument( "--playgroundlogger", help="build playgroundlogger", @@ -1422,6 +1438,12 @@ details of the setups of other systems or automated environments.""") action="store_const", const="Debug", dest="libdispatch_build_variant") + build_variant_override_group.add_argument( + "--debug-libicu", + help="build the Debug variant of libicu", + action="store_const", + const="Debug", + dest="libicu_build_variant") assertions_group = parser.add_mutually_exclusive_group(required=False) assertions_group.add_argument( diff --git a/utils/build-script-impl b/utils/build-script-impl index f0b3662304198..cabb17416dc3f 100755 --- a/utils/build-script-impl +++ b/utils/build-script-impl @@ -74,6 +74,7 @@ KNOWN_SETTINGS=( llbuild-build-type "Debug" "the CMake build variant for llbuild" foundation-build-type "Debug" "the build variant for Foundation" libdispatch-build-type "Debug" "the build variant for libdispatch" + libicu-build-type "Debug" "the build variant for libicu" playgroundlogger-build-type "Debug" "the build variant for PlaygroundLogger" playgroundsupport-build-type "Debug" "the build variant for PlaygroundSupport" xctest-build-type "Debug" "the build variant for xctest" @@ -117,6 +118,7 @@ KNOWN_SETTINGS=( skip-build-xctest "" "set to skip building xctest" skip-build-foundation "" "set to skip building foundation" skip-build-libdispatch "" "set to skip building libdispatch" + skip-build-libicu "" "set to skip building libicu" skip-build-benchmarks "" "set to skip building Swift Benchmark Suite" skip-build-playgroundlogger "" "set to skip building PlaygroundLogger" skip-build-playgroundsupport "" "set to skip building PlaygroundSupport" @@ -128,6 +130,7 @@ KNOWN_SETTINGS=( skip-test-xctest "" "set to skip testing xctest" skip-test-foundation "" "set to skip testing foundation" skip-test-libdispatch "" "set to skip testing libdispatch" + skip-test-libicu "" "set to skip testing libicu" skip-test-playgroundlogger "" "set to skip testing PlaygroundLogger" skip-test-playgroundsupport "" "set to skip testing PlaygroundSupport" skip-test-linux "" "set to skip testing Swift stdlibs for Linux" @@ -181,6 +184,7 @@ KNOWN_SETTINGS=( install-xctest "" "whether to install xctest" install-foundation "" "whether to install foundation" install-libdispatch "" "whether to install libdispatch" + install-libicu "" "whether to install libicu" install-playgroundlogger "" "whether to install PlaygroundLogger" install-playgroundsupport "" "whether to install PlaygroundSupport" darwin-install-extract-symbols "" "whether to extract symbols with dsymutil during installations" @@ -226,6 +230,7 @@ KNOWN_SETTINGS=( ninja-cmake-options "" "CMake options used for all ninja targets" foundation-cmake-options "" "CMake options used for all foundation targets" libdispatch-cmake-options "" "CMake options used for all libdispatch targets" + libicu-cmake-options "" "CMake options used for all libicu targets" llbuild-cmake-options "" "CMake options used for all llbuild targets" lldb-cmake-options "" "CMake options used for all lldb targets" llvm-cmake-options "" "CMake options used for all llvm targets" @@ -1195,6 +1200,7 @@ SWIFTPM_SOURCE_DIR="${WORKSPACE}/swiftpm" XCTEST_SOURCE_DIR="${WORKSPACE}/swift-corelibs-xctest" FOUNDATION_SOURCE_DIR="${WORKSPACE}/swift-corelibs-foundation" LIBDISPATCH_SOURCE_DIR="${WORKSPACE}/swift-corelibs-libdispatch" +LIBICU_SOURCE_DIR="${WORKSPACE}/icu" PLAYGROUNDLOGGER_SOURCE_DIR="${WORKSPACE}/swift-xcode-playground-support/PlaygroundLogger" PLAYGROUNDSUPPORT_SOURCE_DIR="${WORKSPACE}/swift-xcode-playground-support/PlaygroundSupport" @@ -1228,6 +1234,11 @@ if [[ ! "${SKIP_BUILD_LIBDISPATCH}" && ! -d ${LIBDISPATCH_SOURCE_DIR} ]]; then exit 1 fi +if [[ ! "${SKIP_BUILD_LIBICU}" && ! -d ${LIBICU_SOURCE_DIR} ]]; then + echo "Couldn't find libicu source directory." + exit 1 +fi + if [[ ! "${SKIP_BUILD_PLAYGROUNDLOGGER}" && ! -d ${PLAYGROUNDLOGGER_SOURCE_DIR} ]]; then echo "Couldn't find PlaygroundLogger source directory." exit 1 @@ -1259,7 +1270,11 @@ if [ -e "${WORKSPACE}/compiler-rt" ] ; then fi fi -PRODUCTS=(cmark llvm swift) +PRODUCTS=(cmark llvm) +if [[ ! "${SKIP_BUILD_LIBICU}" ]] ; then + PRODUCTS=("${PRODUCTS[@]}" libicu) +fi +PRODUCTS=("${PRODUCTS[@]}" swift) if [[ ! "${SKIP_BUILD_LLDB}" ]] ; then PRODUCTS=("${PRODUCTS[@]}" lldb) fi @@ -1571,6 +1586,8 @@ function build_directory_bin() { libdispatch) echo "${root}/${LIBDISPATCH_BUILD_TYPE}/bin" ;; + libicu) + ;; playgroundlogger) # FIXME: var name for build type echo "${root}/${PLAYGROUNDLOGGER_BUILD_TYPE}/bin" @@ -1699,6 +1716,8 @@ function cmake_config_opt() { ;; libdispatch) ;; + libicu) + ;; playgroundlogger) # FIXME: var name echo "--config ${PLAYGROUNDLOGGER_BUILD_TYPE}" @@ -1723,6 +1742,9 @@ function set_swiftpm_bootstrap_command() { LIBDISPATCH_BUILD_DIR="$(build_directory ${host} libdispatch)" LIBDISPATCH_BUILD_ARGS="--libdispatch-source-dir=${LIBDISPATCH_SOURCE_DIR} --libdispatch-build-dir=${LIBDISPATCH_BUILD_DIR}" fi + if [[ ! "${SKIP_BUILD_LIBICU}" ]] ; then + LIBICU_BUILD_DIR="$(build_directory ${host} libicu)" + fi if [[ ! "${SKIP_BUILD_XCTEST}" ]] ; then XCTEST_BUILD_DIR=$(build_directory ${host} xctest) fi @@ -2143,6 +2165,14 @@ for host in "${ALL_HOSTS[@]}"; do -DSWIFT_PATH_TO_LIBDISPATCH_BUILD:PATH="$(build_directory ${host} libdispatch)" ) + if [[ ! "${SKIP_BUILD_LIBICU}" ]] ; then + cmake_options=( + "${cmake_options[@]}" + -DSWIFT_PATH_TO_LIBICU_SOURCE:PATH="${LIBICU_SOURCE_DIR}" + -DSWIFT_PATH_TO_LIBICU_BUILD:PATH="$(build_directory ${host} libicu)" + ) + fi + if [[ "${CMAKE_GENERATOR}" == "Xcode" ]] ; then cmake_options=( "${cmake_options[@]}" @@ -2433,6 +2463,58 @@ for host in "${ALL_HOSTS[@]}"; do # libdispatch builds itself and doesn't use cmake continue ;; + libicu) + SWIFT_BUILD_PATH=$(build_directory ${host} swift) + LIBICU_BUILD_DIR=$(build_directory ${host} ${product}) + ICU_TMPINSTALL=$LIBICU_BUILD_DIR/tmp_install + ICU_TMPLIBDIR="${SWIFT_BUILD_PATH}/lib/swift/${SWIFT_HOST_VARIANT}/${SWIFT_HOST_VARIANT_ARCH}" + if [[ "${RECONFIGURE}" || ! -f "${LIBICU_BUILD_DIR}"/config.status ]]; then + echo "Reconfiguring libicu" + if [[ "$LIBICU_BUILD_TYPE" == "Release" ]] ; then + icu_build_variant_arg="--enable-release" + elif [[ "$LIBICU_BUILD_TYPE" == "RelWithDebInfo" ]]; then + icu_build_variant_arg="--enable-release" + else + icu_build_variant_arg="--enable-debug" + fi + call mkdir -p "${LIBICU_BUILD_DIR}" + with_pushd "${LIBICU_BUILD_DIR}" \ + call "${LIBICU_SOURCE_DIR}"/source/configure \ + ${icu_build_variant_arg} --prefix=${ICU_TMPINSTALL} \ + --libdir=${ICU_TMPLIBDIR} \ + --enable-shared --enable-static \ + --enable-strict --disable-icuio \ + --disable-plugins --disable-dyload --disable-extras \ + --disable-samples --with-data-packaging=auto + else + echo "Skipping reconfiguration of libicu" + fi + with_pushd "${LIBICU_BUILD_DIR}" \ + call make install + ICU_LIBDIR="$(build_directory ${host} swift)/lib/swift/${SWIFT_HOST_VARIANT}/${SWIFT_HOST_VARIANT_ARCH}" + ICU_LIBDIR_STATIC="$(build_directory ${host} swift)/lib/swift_static/${SWIFT_HOST_VARIANT}" + ICU_LIBDIR_STATIC_ARCH="$(build_directory ${host} swift)/lib/swift_static/${SWIFT_HOST_VARIANT}/${SWIFT_HOST_VARIANT_ARCH}" + mkdir -p "${ICU_LIBDIR_STATIC_ARCH}" + # Copy the static libs into the swift_static directory + for l in uc i18n data + do + lib="${ICU_LIBDIR}/libicu${l}.a" + cp "${lib}" "${ICU_LIBDIR_STATIC}" + cp "${lib}" "${ICU_LIBDIR_STATIC_ARCH}" + done + + # Set the PKG_CONFIG_PATH so that core-foundation can find the libraries and + # header files + export PKG_CONFIG_PATH="${ICU_TMPLIBDIR}/pkgconfig" + swift_cmake_options=( + "${swift_cmake_options[@]}" + -DSWIFT_${SWIFT_HOST_VARIANT_SDK}_ICU_UC_INCLUDE:STRING="${ICU_TMPINSTALL}/include" + -DSWIFT_${SWIFT_HOST_VARIANT_SDK}_ICU_I18N_INCLUDE:STRING="${ICU_TMPINSTALL}/include" + -DSWIFT_${SWIFT_HOST_VARIANT_SDK}_ICU_STATICLIB:BOOL=TRUE + ) + # libicu builds itself and doesn't use cmake + continue + ;; playgroundlogger) PLAYGROUNDLOGGER_BUILD_DIR=$(build_directory ${host} ${product}) SWIFTC_BIN="$(build_directory_bin ${host} swift)/swiftc" @@ -2754,6 +2836,17 @@ for host in "${ALL_HOSTS[@]}"; do echo "--- Finished tests for ${product} ---" continue ;; + libicu) + if [[ "${SKIP_TEST_LIBICU}" ]]; then + continue + fi + LIBICU_BUILD_DIR=$(build_directory ${host} ${product}) + echo "--- Running tests for ${product} ---" + with_pushd "${LIBICU_BUILD_DIR}/test" \ + call make + echo "--- Finished tests for ${product} ---" + continue + ;; playgroundlogger) SWIFT_DYLIB_PATH=$(build_directory ${host} swift)/lib/swift/macosx/ PLAYGROUNDLOGGER_FRAMEWORK_PATH=$(build_directory ${host} ${product}) @@ -2994,6 +3087,32 @@ for host in "${ALL_HOSTS[@]}"; do # As libdispatch installation is self-contained, we break early here. continue ;; + libicu) + if [[ -z "${INSTALL_LIBICU}" ]]; then + continue + fi + if [[ -z "${INSTALL_DESTDIR}" ]] ; then + echo "--install-destdir is required to install products." + exit 1 + fi + echo "--- Installing ${product} ---" + LIBICU_BUILD_DIR=$(build_directory ${host} ${product}) + ICU_LIBDIR="$(build_directory ${host} swift)/lib/swift/${SWIFT_HOST_VARIANT}/${SWIFT_HOST_VARIANT_ARCH}" + LIBICU_DEST_DIR="$(get_host_install_destdir ${host})$(get_host_install_prefix ${host})lib/swift/${SWIFT_HOST_VARIANT}" + LIBICU_DEST_DIR_STATIC="$(get_host_install_destdir ${host})$(get_host_install_prefix ${host})lib/swift_static/${SWIFT_HOST_VARIANT}" + mkdir -p ${LIBICU_DEST_DIR} + mkdir -p ${LIBICU_DEST_DIR_STATIC} + for l in uc i18n data + do + lib=${ICU_LIBDIR}/libicu${l} + echo "${lib} => ${LIBICU_DEST_DIR}" + cp -d ${lib}.so ${lib}.so.* ${LIBICU_DEST_DIR} + cp -d ${lib}.so ${lib}.so.* ${LIBICU_DEST_DIR} + cp -d ${lib}.a ${LIBICU_DEST_DIR_STATIC} + cp -d ${lib}.a ${LIBICU_DEST_DIR_STATIC} + done + continue + ;; playgroundlogger) if [[ -z "${INSTALL_PLAYGROUNDLOGGER}" ]] ; then continue diff --git a/utils/swift_build_support/swift_build_support/products/__init__.py b/utils/swift_build_support/swift_build_support/products/__init__.py index 0fa6154168b33..82b916d4e110b 100644 --- a/utils/swift_build_support/swift_build_support/products/__init__.py +++ b/utils/swift_build_support/swift_build_support/products/__init__.py @@ -13,6 +13,7 @@ from .cmark import CMark from .foundation import Foundation from .libdispatch import LibDispatch +from .libicu import LibICU from .llbuild import LLBuild from .lldb import LLDB from .llvm import LLVM @@ -26,6 +27,7 @@ 'Ninja', 'Foundation', 'LibDispatch', + 'LibICU', 'LLBuild', 'LLDB', 'LLVM', diff --git a/utils/swift_build_support/swift_build_support/products/libicu.py b/utils/swift_build_support/swift_build_support/products/libicu.py new file mode 100644 index 0000000000000..dc2385394a290 --- /dev/null +++ b/utils/swift_build_support/swift_build_support/products/libicu.py @@ -0,0 +1,17 @@ +# swift_build_support/products/libicu.py --------------------------*- python -*- +# +# This source file is part of the Swift.org open source project +# +# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +# Licensed under Apache License v2.0 with Runtime Library Exception +# +# See http://swift.org/LICENSE.txt for license information +# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +# +# ---------------------------------------------------------------------------- + +from . import product + + +class LibICU(product.Product): + pass From 1daa3ee1f882034d516e40206a71e272ddf518e2 Mon Sep 17 00:00:00 2001 From: Simon Evans Date: Tue, 18 Oct 2016 09:34:01 +0100 Subject: [PATCH 2/4] [SR-648] Add option to create statically linked binaries - Add ImageInspectionStatic.cpp to lookup protocol conformance and metadata sections in static binaries - For Linux, build libswiftImageInspectionShared.a and libswiftImageInspectionStatic.a for linking with libswiftCore.a. This allows static binaries to be built without linking to libdl. libswiftImageInspectionShared (ImageInspectionELF.cpp) is automatically compiled into libswiftCore.so - Adds -static-executable option to swiftc to use along with -emit-executable that uses linker arguments in static-executable-args.lnk. This also requires a libicu to be compiled using the --libicu which has configure options that dont require libdl for accessing ICU datafiles - Static binaries only work on Linux at this time --- cmake/modules/AddSwift.cmake | 20 +++++-- include/swift/Option/Options.td | 6 +++ lib/Driver/ToolChains.cpp | 32 +++++++++-- stdlib/public/core/CMakeLists.txt | 7 +++ stdlib/public/runtime/CMakeLists.txt | 44 +++++++++++++++ stdlib/public/runtime/ImageInspectionELF.cpp | 8 ++- .../public/runtime/ImageInspectionStatic.cpp | 54 +++++++++++++++++++ stdlib/public/runtime/swift_sections.S | 10 ++-- utils/static-executable-args.lnk | 13 +++++ 9 files changed, 179 insertions(+), 15 deletions(-) create mode 100644 stdlib/public/runtime/ImageInspectionStatic.cpp create mode 100644 utils/static-executable-args.lnk diff --git a/cmake/modules/AddSwift.cmake b/cmake/modules/AddSwift.cmake index cf67e0c2ee5af..71ff90da9f000 100644 --- a/cmake/modules/AddSwift.cmake +++ b/cmake/modules/AddSwift.cmake @@ -567,7 +567,7 @@ function(_add_swift_library_single target name) cmake_parse_arguments(SWIFTLIB_SINGLE "${SWIFTLIB_SINGLE_options}" "MODULE_TARGET;SDK;ARCHITECTURE;INSTALL_IN_COMPONENT;DEPLOYMENT_VERSION_OSX;DEPLOYMENT_VERSION_IOS;DEPLOYMENT_VERSION_TVOS;DEPLOYMENT_VERSION_WATCHOS" - "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" + "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;INCORPORATE_OBJECT_LIBRARIES_SHARED_ONLY;FILE_DEPENDS" ${ARGN}) set(SWIFTLIB_SINGLE_SOURCES ${SWIFTLIB_SINGLE_UNPARSED_ARGUMENTS}) @@ -739,6 +739,12 @@ function(_add_swift_library_single target name) $) endforeach() + set(SWIFTLIB_INCORPORATED_OBJECT_LIBRARIES_EXPRESSIONS_SHARED_ONLY) + foreach(object_library ${SWIFTLIB_SINGLE_INCORPORATE_OBJECT_LIBRARIES_SHARED_ONLY}) + list(APPEND SWIFTLIB_INCORPORATED_OBJECT_LIBRARIES_EXPRESSIONS_SHARED_ONLY + $) + endforeach() + set(SWIFTLIB_SINGLE_XCODE_WORKAROUND_SOURCES) if(XCODE AND SWIFTLIB_SINGLE_TARGET_LIBRARY) set(SWIFTLIB_SINGLE_XCODE_WORKAROUND_SOURCES @@ -747,11 +753,17 @@ function(_add_swift_library_single target name) ${SWIFT_SOURCE_DIR}/cmake/dummy.cpp) endif() + set(INCORPORATED_OBJECT_LIBRARIES_EXPRESSIONS ${SWIFTLIB_INCORPORATED_OBJECT_LIBRARIES_EXPRESSIONS}) + if(${libkind} STREQUAL "SHARED") + list(APPEND INCORPORATED_OBJECT_LIBRARIES_EXPRESSIONS + ${SWIFTLIB_INCORPORATED_OBJECT_LIBRARIES_EXPRESSIONS_SHARED_ONLY}) + endif() + add_library("${target}" ${libkind} ${SWIFT_SECTIONS_OBJECT_BEGIN} ${SWIFTLIB_SINGLE_SOURCES} ${SWIFTLIB_SINGLE_EXTERNAL_SOURCES} - ${SWIFTLIB_INCORPORATED_OBJECT_LIBRARIES_EXPRESSIONS} + ${INCORPORATED_OBJECT_LIBRARIES_EXPRESSIONS} ${SWIFTLIB_SINGLE_XCODE_WORKAROUND_SOURCES} ${SWIFT_SECTIONS_OBJECT_END}) _set_target_prefix_and_suffix("${target}" "${libkind}" "${SWIFTLIB_SINGLE_SDK}") @@ -1270,7 +1282,7 @@ function(add_swift_library name) cmake_parse_arguments(SWIFTLIB "${SWIFTLIB_options}" "INSTALL_IN_COMPONENT;DEPLOYMENT_VERSION_OSX;DEPLOYMENT_VERSION_IOS;DEPLOYMENT_VERSION_TVOS;DEPLOYMENT_VERSION_WATCHOS" - "DEPENDS;LINK_LIBRARIES;SWIFT_MODULE_DEPENDS;SWIFT_MODULE_DEPENDS_OSX;SWIFT_MODULE_DEPENDS_IOS;SWIFT_MODULE_DEPENDS_TVOS;SWIFT_MODULE_DEPENDS_WATCHOS;SWIFT_MODULE_DEPENDS_FREEBSD;SWIFT_MODULE_DEPENDS_LINUX;FRAMEWORK_DEPENDS;FRAMEWORK_DEPENDS_WEAK;FRAMEWORK_DEPENDS_OSX;FRAMEWORK_DEPENDS_IOS_TVOS;LLVM_COMPONENT_DEPENDS;FILE_DEPENDS;TARGET_SDKS;C_COMPILE_FLAGS;SWIFT_COMPILE_FLAGS;SWIFT_COMPILE_FLAGS_OSX;SWIFT_COMPILE_FLAGS_IOS;SWIFT_COMPILE_FLAGS_TVOS;SWIFT_COMPILE_FLAGS_WATCHOS;LINK_FLAGS;PRIVATE_LINK_LIBRARIES;INTERFACE_LINK_LIBRARIES;INCORPORATE_OBJECT_LIBRARIES" + "DEPENDS;LINK_LIBRARIES;SWIFT_MODULE_DEPENDS;SWIFT_MODULE_DEPENDS_OSX;SWIFT_MODULE_DEPENDS_IOS;SWIFT_MODULE_DEPENDS_TVOS;SWIFT_MODULE_DEPENDS_WATCHOS;SWIFT_MODULE_DEPENDS_FREEBSD;SWIFT_MODULE_DEPENDS_LINUX;FRAMEWORK_DEPENDS;FRAMEWORK_DEPENDS_WEAK;FRAMEWORK_DEPENDS_OSX;FRAMEWORK_DEPENDS_IOS_TVOS;LLVM_COMPONENT_DEPENDS;FILE_DEPENDS;TARGET_SDKS;C_COMPILE_FLAGS;SWIFT_COMPILE_FLAGS;SWIFT_COMPILE_FLAGS_OSX;SWIFT_COMPILE_FLAGS_IOS;SWIFT_COMPILE_FLAGS_TVOS;SWIFT_COMPILE_FLAGS_WATCHOS;LINK_FLAGS;PRIVATE_LINK_LIBRARIES;INTERFACE_LINK_LIBRARIES;INCORPORATE_OBJECT_LIBRARIES;INCORPORATE_OBJECT_LIBRARIES_SHARED_ONLY" ${ARGN}) set(SWIFTLIB_SOURCES ${SWIFTLIB_UNPARSED_ARGUMENTS}) @@ -1491,6 +1503,7 @@ function(add_swift_library name) LINK_FLAGS ${SWIFTLIB_LINK_FLAGS} PRIVATE_LINK_LIBRARIES ${swiftlib_private_link_libraries_targets} INCORPORATE_OBJECT_LIBRARIES ${SWIFTLIB_INCORPORATE_OBJECT_LIBRARIES} + INCORPORATE_OBJECT_LIBRARIES_SHARED_ONLY ${SWIFTLIB_INCORPORATE_OBJECT_LIBRARIES_SHARED_ONLY} ${SWIFTLIB_DONT_EMBED_BITCODE_keyword} ${SWIFTLIB_API_NOTES_NON_OVERLAY_keyword} ${SWIFTLIB_IS_STDLIB_keyword} @@ -1682,6 +1695,7 @@ function(add_swift_library name) PRIVATE_LINK_LIBRARIES ${SWIFTLIB_PRIVATE_LINK_LIBRARIES} INTERFACE_LINK_LIBRARIES ${SWIFTLIB_INTERFACE_LINK_LIBRARIES} INCORPORATE_OBJECT_LIBRARIES ${SWIFTLIB_INCORPORATE_OBJECT_LIBRARIES} + INCORPORATE_OBJECT_LIBRARIES_SHARED_ONLY ${SWIFTLIB_INCORPORATE_OBJECT_LIBRARIES_SHARED_ONLY} ${SWIFTLIB_DONT_EMBED_BITCODE_keyword} ${SWIFTLIB_API_NOTES_NON_OVERLAY_keyword} ${SWIFTLIB_IS_STDLIB_keyword} diff --git a/include/swift/Option/Options.td b/include/swift/Option/Options.td index 1043c610e912f..8edec1ba55aaa 100644 --- a/include/swift/Option/Options.td +++ b/include/swift/Option/Options.td @@ -282,6 +282,12 @@ def no_static_stdlib: Flag<["-"], "no-static-stdlib">, Flags<[HelpHidden]>, HelpText<"Don't statically link the Swift standard library">; +def static_executable : Flag<["-"], "static-executable">, + HelpText<"Statically link the executable">; +def no_static_executable : Flag<["-"], "no-static-executable">, + Flags<[HelpHidden]>, + HelpText<"Don't statically link the executable">; + def use_ld : Joined<["-"], "use-ld=">, Flags<[DoesNotAffectIncrementalBuild]>, HelpText<"Specifies the linker to be used">; diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index db8c2ef5bfde7..799f3652e4858 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -952,6 +952,12 @@ toolchains::Darwin::constructInvocation(const LinkJobAction &job, assert(context.Output.getPrimaryOutputType() == types::TY_Image && "Invalid linker output type."); + if (context.Args.hasFlag(options::OPT_static_executable, + options::OPT_no_static_executable, + false)) { + llvm::report_fatal_error("-static-executable is not supported on Darwin"); + } + const Driver &D = getDriver(); const llvm::Triple &Triple = getTriple(); @@ -1357,9 +1363,26 @@ toolchains::GenericUnix::constructInvocation(const LinkJobAction &job, // Link the standard library. Arguments.push_back("-L"); - if (context.Args.hasFlag(options::OPT_static_stdlib, - options::OPT_no_static_stdlib, - false)) { + if (context.Args.hasFlag(options::OPT_static_executable, + options::OPT_no_static_executable, + false)) { + SmallString<128> StaticRuntimeLibPath; + getRuntimeStaticLibraryPath(StaticRuntimeLibPath, context.Args, *this); + Arguments.push_back(context.Args.MakeArgString(StaticRuntimeLibPath)); + + SmallString<128> linkFilePath = StaticRuntimeLibPath; + llvm::sys::path::append(linkFilePath, "static-executable-args.lnk"); + auto linkFile = linkFilePath.str(); + + if (llvm::sys::fs::is_regular_file(linkFile)) { + Arguments.push_back(context.Args.MakeArgString(Twine("@") + linkFile)); + } else { + llvm::report_fatal_error("-static-executable not supported on this platform"); + } + } + else if (context.Args.hasFlag(options::OPT_static_stdlib, + options::OPT_no_static_stdlib, + false)) { SmallString<128> StaticRuntimeLibPath; getRuntimeStaticLibraryPath(StaticRuntimeLibPath, context.Args, *this); Arguments.push_back(context.Args.MakeArgString(StaticRuntimeLibPath)); @@ -1384,6 +1407,7 @@ toolchains::GenericUnix::constructInvocation(const LinkJobAction &job, } else { Arguments.push_back(context.Args.MakeArgString(RuntimeLibPath)); + Arguments.push_back("-lswiftCore"); } @@ -1404,8 +1428,6 @@ toolchains::GenericUnix::constructInvocation(const LinkJobAction &job, Twine("-u", llvm::getInstrProfRuntimeHookVarName()))); } - // Always add the stdlib - Arguments.push_back("-lswiftCore"); // Add any autolinking scripts to the arguments for (const Job *Cmd : context.Inputs) { diff --git a/stdlib/public/core/CMakeLists.txt b/stdlib/public/core/CMakeLists.txt index 2be23b21ca8ee..d1b949d507031 100644 --- a/stdlib/public/core/CMakeLists.txt +++ b/stdlib/public/core/CMakeLists.txt @@ -213,6 +213,12 @@ if(SWIFT_CHECK_ESSENTIAL_STDLIB) target_link_libraries(swift_stdlib_essential ${RUNTIME_DEPENDENCY}) endif() + +set(shared_only_libs) +if(SWIFT_BUILD_STATIC_STDLIB AND "${SWIFT_HOST_VARIANT_SDK}" STREQUAL "LINUX") + list(APPEND shared_only_libs swiftImageInspectionShared) +endif() + add_swift_library(swiftCore ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} IS_STDLIB IS_STDLIB_CORE ${SWIFTLIB_SOURCES} # The copy_shim_headers target dependency is required to let the @@ -228,5 +234,6 @@ add_swift_library(swiftCore ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} IS_STDLIB IS_STD LINK_FLAGS ${swift_core_link_flags} PRIVATE_LINK_LIBRARIES ${swift_core_private_link_libraries} INCORPORATE_OBJECT_LIBRARIES swiftRuntime swiftStdlibStubs + INCORPORATE_OBJECT_LIBRARIES_SHARED_ONLY ${shared_only_libs} FRAMEWORK_DEPENDS ${swift_core_framework_depends} INSTALL_IN_COMPONENT stdlib) diff --git a/stdlib/public/runtime/CMakeLists.txt b/stdlib/public/runtime/CMakeLists.txt index 232b1359a9788..e6bc6274ed1fe 100644 --- a/stdlib/public/runtime/CMakeLists.txt +++ b/stdlib/public/runtime/CMakeLists.txt @@ -62,6 +62,8 @@ set(LLVM_OPTIONAL_SOURCES MutexPThread.cpp MutexWin32.cpp CygwinPort.cpp + ImageInspectionELF.cpp + ImageInspectionStatic.cpp ${swift_runtime_sources} ${swift_runtime_objc_sources} ${swift_runtime_leaks_sources}) @@ -69,6 +71,48 @@ set(LLVM_OPTIONAL_SOURCES set(swift_runtime_library_compile_flags ${swift_runtime_compile_flags}) list(APPEND swift_runtime_library_compile_flags -DswiftCore_EXPORTS) +set(sdk "${SWIFT_HOST_VARIANT_SDK}") +if(SWIFT_BUILD_STATIC_STDLIB AND "${sdk}" STREQUAL "LINUX") + list(REMOVE_ITEM swift_runtime_sources ImageInspectionELF.cpp) + set(static_binary_lnk_file_list) + string(TOLOWER "${sdk}" lowercase_sdk) + + # These two libaries are only used with the static swiftcore + add_library(swiftImageInspectionStatic STATIC ImageInspectionStatic.cpp) + set_target_properties(swiftImageInspectionStatic PROPERTIES + ARCHIVE_OUTPUT_DIRECTORY "${SWIFTSTATICLIB_DIR}/${lowercase_sdk}") + + add_library(swiftImageInspectionShared STATIC ImageInspectionELF.cpp) + set_target_properties(swiftImageInspectionShared PROPERTIES + ARCHIVE_OUTPUT_DIRECTORY "${SWIFTSTATICLIB_DIR}/${lowercase_sdk}") + + swift_install_in_component(stdlib + TARGETS swiftImageInspectionStatic swiftImageInspectionShared + DESTINATION "lib/swift_static/${lowercase_sdk}") + + # 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/${lowercase}/static-executable-args.lnk" + "${SWIFTSTATICLIB_DIR}/${linkfile}" + OUTPUT + "${SWIFTSTATICLIB_DIR}/${linkfile}") + + list(APPEND static_binary_lnk_file_list ${swift_static_binary_${sdk}_args}) + swift_install_in_component(stdlib + FILES "${SWIFTSTATICLIB_DIR}/${linkfile}" + DESTINATION "lib/swift_static/${lowercase_sdk}") + add_custom_target(static_binary_magic ALL DEPENDS ${static_binary_lnk_file_list}) + + add_swift_library(swiftImageInspectionShared OBJECT_LIBRARY TARGET_LIBRARY + ImageInspectionELF.cpp + C_COMPILE_FLAGS ${swift_runtime_library_compile_flags} + LINK_FLAGS ${swift_runtime_linker_flags} + INSTALL_IN_COMPONENT never_install) +endif() + add_swift_library(swiftRuntime OBJECT_LIBRARY TARGET_LIBRARY ${swift_runtime_sources} ${swift_runtime_objc_sources} diff --git a/stdlib/public/runtime/ImageInspectionELF.cpp b/stdlib/public/runtime/ImageInspectionELF.cpp index 9b9b4ef0b7c41..4be1a29061379 100644 --- a/stdlib/public/runtime/ImageInspectionELF.cpp +++ b/stdlib/public/runtime/ImageInspectionELF.cpp @@ -19,6 +19,7 @@ #if defined(__ELF__) || defined(__ANDROID__) #include "ImageInspection.h" +#include "../SwiftShims/Visibility.h" #include #include #include @@ -29,11 +30,11 @@ using namespace swift; /// The symbol name in the image that identifies the beginning of the /// protocol conformances table. static const char ProtocolConformancesSymbol[] = - ".swift2_protocol_conformances_start"; + "__swift2_protocol_conformances_start"; /// The symbol name in the image that identifies the beginning of the /// type metadata record table. static const char TypeMetadataRecordsSymbol[] = - ".swift2_type_metadata_start"; + "__swift2_type_metadata_start"; /// Context arguments passed down from dl_iterate_phdr to its callback. struct InspectArgs { @@ -78,6 +79,7 @@ static int iteratePHDRCallback(struct dl_phdr_info *info, return 0; } +SWIFT_RUNTIME_EXPORT void swift::initializeProtocolConformanceLookup() { // Search the loaded dls. This only searches the already // loaded ones. @@ -90,6 +92,7 @@ void swift::initializeProtocolConformanceLookup() { dl_iterate_phdr(iteratePHDRCallback, &ProtocolConformanceArgs); } +SWIFT_RUNTIME_EXPORT void swift::initializeTypeMetadataRecordLookup() { InspectArgs TypeMetadataRecordArgs = { TypeMetadataRecordsSymbol, @@ -98,6 +101,7 @@ void swift::initializeTypeMetadataRecordLookup() { dl_iterate_phdr(iteratePHDRCallback, &TypeMetadataRecordArgs); } +SWIFT_RUNTIME_EXPORT int swift::lookupSymbol(const void *address, SymbolInfo *info) { Dl_info dlinfo; if (dladdr(address, &dlinfo) == 0) { diff --git a/stdlib/public/runtime/ImageInspectionStatic.cpp b/stdlib/public/runtime/ImageInspectionStatic.cpp new file mode 100644 index 0000000000000..36a27c044a5ca --- /dev/null +++ b/stdlib/public/runtime/ImageInspectionStatic.cpp @@ -0,0 +1,54 @@ +//===-- ImageInspectionStatic.cpp -------------------------------*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +// +// Implementation of functions to read data sections from static executable. +// +//===----------------------------------------------------------------------===// + +#include "ImageInspection.h" + +// Currently only tested on linux but should work for any ELF platform +#if defined(__ELF__) && defined(__linux__) + +// These are defined in swift_sections.S +// Used in swift_sections.S to mark the start of a section +struct SectionInfo { + uint64_t size; + const uint8_t data[0]; +}; +extern const SectionInfo __swift2_protocol_conformances_start; +extern const SectionInfo __swift2_type_metadata_start; + + +void +swift::initializeProtocolConformanceLookup() { + addImageProtocolConformanceBlockCallback( + __swift2_protocol_conformances_start.data, + __swift2_protocol_conformances_start.size); +} + +void +swift::initializeTypeMetadataRecordLookup() { + addImageTypeMetadataRecordBlockCallback( + __swift2_type_metadata_start.data, + __swift2_type_metadata_start.size); +} + +// This is called from Errors.cpp when dumping a stack trace entry. +// It could be implemented by parsing the ELF information in the +// executable. For now it returns 0 for error (cant lookup address). +int +swift::lookupSymbol(const void *address, SymbolInfo *info) { + return 0; +} + +#endif diff --git a/stdlib/public/runtime/swift_sections.S b/stdlib/public/runtime/swift_sections.S index a0f9d1caf2991..059d016b3ef02 100644 --- a/stdlib/public/runtime/swift_sections.S +++ b/stdlib/public/runtime/swift_sections.S @@ -31,14 +31,14 @@ .p2align 3 #if defined(SWIFT_BEGIN) - .globl .\()\name\()_start - .protected .\()\name\()_start -.\()\name\()_start: + .globl __\()\name\()_start + .protected __\()\name\()_start +__\()\name\()_start: #if defined(__BIG_ENDIAN__) .long 0 - .long .\()\name\()_end - .\()\name\()_start - 8 + .long .\()\name\()_end - __\()\name\()_start - 8 #else - .long .\()\name\()_end - .\()\name\()_start - 8 + .long .\()\name\()_end - __\()\name\()_start - 8 .long 0 #endif #endif diff --git a/utils/static-executable-args.lnk b/utils/static-executable-args.lnk new file mode 100644 index 0000000000000..6987433fc6185 --- /dev/null +++ b/utils/static-executable-args.lnk @@ -0,0 +1,13 @@ +-static +-lswiftCore +-lswiftImageInspectionStatic +-Xlinker +--defsym=__import_pthread_self=pthread_self +-Xlinker +--defsym=__import_pthread_once=pthread_once +-Xlinker +--defsym=__import_pthread_key_create=pthread_key_create +-lpthread +-licui18n +-licuuc +-licudata From f6866e76076a89ae4763100d796a7507a5cc0346 Mon Sep 17 00:00:00 2001 From: Simon Evans Date: Sun, 23 Oct 2016 11:34:05 +0100 Subject: [PATCH 3/4] [SR-648] Update -static-stdlib option on Linux with libicu changes - Create a file of linker arguments instead of a hardcoded list in ToolChains.cpp for use by -static-stdlib option --- lib/Driver/CMakeLists.txt | 30 +++++++++++++++++++++ lib/Driver/ToolChains.cpp | 25 ++++++----------- utils/gen-static-stdlib-link-args | 45 +++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+), 17 deletions(-) create mode 100755 utils/gen-static-stdlib-link-args diff --git a/lib/Driver/CMakeLists.txt b/lib/Driver/CMakeLists.txt index 7f9d1633f47bc..e0c8898987bde 100644 --- a/lib/Driver/CMakeLists.txt +++ b/lib/Driver/CMakeLists.txt @@ -19,3 +19,33 @@ add_swift_library(swiftDriver STATIC DEPENDS SwiftOptions LINK_LIBRARIES swiftAST swiftBasic swiftFrontend swiftOption) +# Generate the static-stdlib-args.lnk file used by -static-stdlib option +# for 'GenericUnix' (eg linux) +if(SWIFT_BUILD_STATIC_STDLIB) + set(static_stdlib_lnk_file_list) + foreach(sdk ${SWIFT_CONFIGURED_SDKS}) + if("${SWIFT_SDK_${sdk}_OBJECT_FORMAT}" STREQUAL "ELF") + string(TOLOWER "${sdk}" lowercase_sdk) + if(SWIFT_LINUX_ICU_STATICLIB) + set(ICU_STATICLIB "TRUE") + else() + set(ICU_STATICLIB "FALSE") + endif() + set(linkfile "${lowercase_sdk}/static-stdlib-args.lnk") + add_custom_command_target(swift_static_stdlib_${sdk}_args + COMMAND + "${SWIFT_SOURCE_DIR}/utils/gen-static-stdlib-link-args" + "${sdk}" + "${SWIFTSTATICLIB_DIR}/${linkfile}" + "${ICU_STATICLIB}" + OUTPUT + "${SWIFTSTATICLIB_DIR}/${linkfile}") + + list(APPEND static_stdlib_lnk_file_list ${swift_static_stdlib_${sdk}_args}) + swift_install_in_component(stdlib + FILES "${SWIFTSTATICLIB_DIR}/${linkfile}" + DESTINATION "lib/swift_static/${lowercase_sdk}") + endif() + endforeach() + add_custom_target(swift_static_lnk_args ALL DEPENDS ${static_stdlib_lnk_file_list}) +endif() diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index 799f3652e4858..a097f239ada7a 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -1386,24 +1386,15 @@ toolchains::GenericUnix::constructInvocation(const LinkJobAction &job, SmallString<128> StaticRuntimeLibPath; getRuntimeStaticLibraryPath(StaticRuntimeLibPath, context.Args, *this); Arguments.push_back(context.Args.MakeArgString(StaticRuntimeLibPath)); - // The following libraries are required to build a satisfactory - // static program - Arguments.push_back("-ldl"); - Arguments.push_back("-lpthread"); - Arguments.push_back("-lbsd"); - Arguments.push_back("-licui18n"); - Arguments.push_back("-licuuc"); - // The runtime uses dlopen to look for the protocol conformances. - // Therefore, we need to ensure they appear in the dynamic table. - // This happens automatically for dynamically-linked programs, but - // in this case we have to take additional measures. - Arguments.push_back("-Xlinker"); - Arguments.push_back("-export-dynamic"); - Arguments.push_back("-Xlinker"); - Arguments.push_back("--exclude-libs"); - Arguments.push_back("-Xlinker"); - Arguments.push_back("ALL"); + SmallString<128> linkFilePath = StaticRuntimeLibPath; + llvm::sys::path::append(linkFilePath, "static-stdlib-args.lnk"); + auto linkFile = linkFilePath.str(); + if (llvm::sys::fs::is_regular_file(linkFile)) { + Arguments.push_back(context.Args.MakeArgString(Twine("@") + linkFile)); + } else { + llvm::report_fatal_error(linkFile + " not found"); + } } else { Arguments.push_back(context.Args.MakeArgString(RuntimeLibPath)); diff --git a/utils/gen-static-stdlib-link-args b/utils/gen-static-stdlib-link-args new file mode 100755 index 0000000000000..092c9c0cf2d2a --- /dev/null +++ b/utils/gen-static-stdlib-link-args @@ -0,0 +1,45 @@ +#!/usr/bin/env bash + +# +# Generate the static-stdlib-args.lnk used by the -static-stdlib option for +# 'GenericUnix' (eg linux) plaforms. If libicu is built locally then include +# libicudata +# + +SDK=$1 +OUTPUTFILE=$2 +ICU_STATIC_LIB=$3 + + +if [ "${ICU_STATIC_LIB}" == "TRUE" ]; then + read -d '' ICU_LIBS <$OUTPUTFILE < Date: Wed, 30 Nov 2016 18:22:14 +0000 Subject: [PATCH 4/4] [SR-648] ELF static binary fixes - Revert the use of SWIFT_RUNTIME_EXPORT in ImageInspectionELF.cpp and fix the unittests by explicitly adding the file to the list - Revert the change of section data names --- stdlib/public/runtime/ImageInspectionELF.cpp | 8 ++--- .../public/runtime/ImageInspectionStatic.cpp | 32 ++++++++++++------- stdlib/public/runtime/swift_sections.S | 10 +++--- unittests/runtime/CMakeLists.txt | 6 ++++ unittests/runtime/LongTests/CMakeLists.txt | 1 + 5 files changed, 35 insertions(+), 22 deletions(-) diff --git a/stdlib/public/runtime/ImageInspectionELF.cpp b/stdlib/public/runtime/ImageInspectionELF.cpp index 4be1a29061379..9b9b4ef0b7c41 100644 --- a/stdlib/public/runtime/ImageInspectionELF.cpp +++ b/stdlib/public/runtime/ImageInspectionELF.cpp @@ -19,7 +19,6 @@ #if defined(__ELF__) || defined(__ANDROID__) #include "ImageInspection.h" -#include "../SwiftShims/Visibility.h" #include #include #include @@ -30,11 +29,11 @@ using namespace swift; /// The symbol name in the image that identifies the beginning of the /// protocol conformances table. static const char ProtocolConformancesSymbol[] = - "__swift2_protocol_conformances_start"; + ".swift2_protocol_conformances_start"; /// The symbol name in the image that identifies the beginning of the /// type metadata record table. static const char TypeMetadataRecordsSymbol[] = - "__swift2_type_metadata_start"; + ".swift2_type_metadata_start"; /// Context arguments passed down from dl_iterate_phdr to its callback. struct InspectArgs { @@ -79,7 +78,6 @@ static int iteratePHDRCallback(struct dl_phdr_info *info, return 0; } -SWIFT_RUNTIME_EXPORT void swift::initializeProtocolConformanceLookup() { // Search the loaded dls. This only searches the already // loaded ones. @@ -92,7 +90,6 @@ void swift::initializeProtocolConformanceLookup() { dl_iterate_phdr(iteratePHDRCallback, &ProtocolConformanceArgs); } -SWIFT_RUNTIME_EXPORT void swift::initializeTypeMetadataRecordLookup() { InspectArgs TypeMetadataRecordArgs = { TypeMetadataRecordsSymbol, @@ -101,7 +98,6 @@ void swift::initializeTypeMetadataRecordLookup() { dl_iterate_phdr(iteratePHDRCallback, &TypeMetadataRecordArgs); } -SWIFT_RUNTIME_EXPORT int swift::lookupSymbol(const void *address, SymbolInfo *info) { Dl_info dlinfo; if (dladdr(address, &dlinfo) == 0) { diff --git a/stdlib/public/runtime/ImageInspectionStatic.cpp b/stdlib/public/runtime/ImageInspectionStatic.cpp index 36a27c044a5ca..d57dacde78b7f 100644 --- a/stdlib/public/runtime/ImageInspectionStatic.cpp +++ b/stdlib/public/runtime/ImageInspectionStatic.cpp @@ -15,32 +15,42 @@ //===----------------------------------------------------------------------===// #include "ImageInspection.h" +#include // Currently only tested on linux but should work for any ELF platform #if defined(__ELF__) && defined(__linux__) -// These are defined in swift_sections.S -// Used in swift_sections.S to mark the start of a section +// These are defined in swift_sections.S to mark the start of a section with the +// length of the data followed immediately by the section data +struct alignas(uint64_t) Section; +extern const Section protocolConformancesStart asm(".swift2_protocol_conformances_start"); +extern const Section typeMetadataStart asm(".swift2_type_metadata_start"); + struct SectionInfo { uint64_t size; - const uint8_t data[0]; + const char *data; }; -extern const SectionInfo __swift2_protocol_conformances_start; -extern const SectionInfo __swift2_type_metadata_start; +static SectionInfo +getSectionInfo(const Section *section) { + SectionInfo info; + memcpy(&info.size, section, sizeof(uint64_t)); + info.data = reinterpret_cast(section) + sizeof(uint64_t); + return info; +} void swift::initializeProtocolConformanceLookup() { - addImageProtocolConformanceBlockCallback( - __swift2_protocol_conformances_start.data, - __swift2_protocol_conformances_start.size); + auto protocolConformances = getSectionInfo(&protocolConformancesStart); + addImageProtocolConformanceBlockCallback(protocolConformances.data, + protocolConformances.size); } void swift::initializeTypeMetadataRecordLookup() { - addImageTypeMetadataRecordBlockCallback( - __swift2_type_metadata_start.data, - __swift2_type_metadata_start.size); + auto typeMetadata = getSectionInfo(&typeMetadataStart); + addImageTypeMetadataRecordBlockCallback(typeMetadata.data, + typeMetadata.size); } // This is called from Errors.cpp when dumping a stack trace entry. diff --git a/stdlib/public/runtime/swift_sections.S b/stdlib/public/runtime/swift_sections.S index 059d016b3ef02..a0f9d1caf2991 100644 --- a/stdlib/public/runtime/swift_sections.S +++ b/stdlib/public/runtime/swift_sections.S @@ -31,14 +31,14 @@ .p2align 3 #if defined(SWIFT_BEGIN) - .globl __\()\name\()_start - .protected __\()\name\()_start -__\()\name\()_start: + .globl .\()\name\()_start + .protected .\()\name\()_start +.\()\name\()_start: #if defined(__BIG_ENDIAN__) .long 0 - .long .\()\name\()_end - __\()\name\()_start - 8 + .long .\()\name\()_end - .\()\name\()_start - 8 #else - .long .\()\name\()_end - __\()\name\()_start - 8 + .long .\()\name\()_end - .\()\name\()_start - 8 .long 0 #endif #endif diff --git a/unittests/runtime/CMakeLists.txt b/unittests/runtime/CMakeLists.txt index dff230838d541..797bbf0a6809f 100644 --- a/unittests/runtime/CMakeLists.txt +++ b/unittests/runtime/CMakeLists.txt @@ -1,6 +1,11 @@ if(("${SWIFT_HOST_VARIANT_SDK}" STREQUAL "${SWIFT_PRIMARY_VARIANT_SDK}") AND ("${SWIFT_HOST_VARIANT_ARCH}" STREQUAL "${SWIFT_PRIMARY_VARIANT_ARCH}")) + if(SWIFT_BUILD_STATIC_STDLIB AND "${SWIFT_HOST_VARIANT_SDK}" STREQUAL "LINUX") + set(swift_runtime_test_extra_sources + "${CMAKE_CURRENT_SOURCE_DIR}/../../stdlib/public/runtime/ImageInspectionELF.cpp") + endif() + add_subdirectory(LongTests) set(PLATFORM_SOURCES) @@ -36,6 +41,7 @@ if(("${SWIFT_HOST_VARIANT_SDK}" STREQUAL "${SWIFT_PRIMARY_VARIANT_SDK}") AND # from the swiftCore dylib, so we need to link to both the runtime archive # and the stdlib. $ + ${swift_runtime_test_extra_sources} ) # FIXME: cross-compile for all variants. diff --git a/unittests/runtime/LongTests/CMakeLists.txt b/unittests/runtime/LongTests/CMakeLists.txt index cd20ed38210ed..54befa11b67f6 100644 --- a/unittests/runtime/LongTests/CMakeLists.txt +++ b/unittests/runtime/LongTests/CMakeLists.txt @@ -32,6 +32,7 @@ if(("${SWIFT_HOST_VARIANT_SDK}" STREQUAL "${SWIFT_PRIMARY_VARIANT_SDK}") AND # from the swiftCore dylib, so we need to link to both the runtime archive # and the stdlib. $ + ${swift_runtime_test_extra_sources} ) # FIXME: cross-compile for all variants.