From 6d5309a6c4d47e4c36b28d9124b0118c08d497d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Rodr=C3=ADguez=20Troiti=C3=B1o?= Date: Fri, 21 Sep 2018 11:26:26 -0700 Subject: [PATCH] [android] Modify test scripts for aarch64 and modern NDKs. Many places on the testing scripts for Android have the ARMv7 architecture hardcoded. Modify all those instances to support both ARMv7 and AArch64. Besides the paths being modified depending on the architecture, the script is also modified to adapt to NDK beyond r14, where the headers are not under the SDK root, but under a unified sysroot. Two new include paths are passed to the compiler invocations (one the general one, one the architecture specific one). In order to link correctly, the -tools-directory is passed to the Swift compiler invocation. In order to use a modern linker, the selected linker in the CMake script is written in the lit.site.cfg.in files. The system will prefer lld, but will fallback to gold. Plain ld will not be used, since it cannot link correctly the binaries. There's a new CMake variable named SWIFT_ANDROID_${ARCH}_ICU_DATA that should point to libicudataswift.so for each architecture. This part of ICU is necessary while running the test in the host, so it needs to be uploaded. Since it is normally side by side with other ICU products, the linker was finding it for free. --- test/CMakeLists.txt | 4 +- test/lit.cfg | 70 +++++++++++++++++++++++---------- test/lit.site.cfg.in | 6 +++ validation-test/lit.site.cfg.in | 7 +++- 4 files changed, 64 insertions(+), 23 deletions(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b43bfc627298a..e218789836e7d 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -229,13 +229,15 @@ foreach(SDK ${SWIFT_SDKS}) ${PYTHON_EXECUTABLE} "${SWIFT_SOURCE_DIR}/utils/android/adb_push_built_products.py" --ndk "${SWIFT_ANDROID_NDK_PATH}" --destination "${SWIFT_ANDROID_DEPLOY_DEVICE_PATH}" + --destination-arch "${ARCH}" # Build products like libswiftCore.so. "${SWIFTLIB_DIR}/android" # These two directories may contain the same libraries, # but upload both to device just in case. Duplicates will be # overwritten, and uploading doesn't take very long anyway. "${SWIFT_ANDROID_${ARCH}_ICU_UC}" - "${SWIFT_ANDROID_${ARCH}_ICU_I18N}") + "${SWIFT_ANDROID_${ARCH}_ICU_I18N}" + "${SWIFT_ANDROID_${ARCH}_ICU_DATA}") endif() add_custom_target("upload-stdlib${VARIANT_SUFFIX}" ${command_upload_stdlib} diff --git a/test/lit.cfg b/test/lit.cfg index 74378e71dbcf4..e1bca68ef9443 100644 --- a/test/lit.cfg +++ b/test/lit.cfg @@ -930,29 +930,57 @@ elif run_os in ['linux-gnu', 'linux-gnueabihf', 'freebsd', 'windows-cygnus', 'wi "clang++ -target %s %s" % (config.variant_triple, clang_mcp_opt)) config.target_ld = "ld -L%r" % (make_path(test_resource_dir, config.target_sdk_name)) -elif run_os == 'linux-androideabi': +elif run_os == 'linux-androideabi' or run_os == 'linux-android': + def get_architecture_value(**kwargs): + result = kwargs[run_cpu] + if result is None: + if run_cpu == "armv7s" or run_cpu == "armv7k": + result = kwargs["armv7"] + elif run_cpu == "arm64": + result = kwards["aarch64"] + return result + + ndk_platform_tuple = get_architecture_value(armv7="armeabi-v7a", + aarch64="arm64-v8a") + ndk_platform_triple = get_architecture_value(armv7="arm-linux-androideabi", + aarch64="aarch64-linux-android") + toolchain_directory_name = "{}-{}".format(ndk_platform_triple, config.android_ndk_gcc_version) + tools_directory = make_path(config.android_ndk_path, "toolchains", + toolchain_directory_name, "prebuilt", "linux-x86_64", + ndk_platform_triple, "bin") lit_config.note("Testing Android " + config.variant_triple) config.target_object_format = "elf" config.target_shared_library_prefix = 'lib' config.target_shared_library_suffix = ".so" + config.target_swiftmodule_name = get_architecture_value(armv7="arm.swiftmodule", + aarch64="arm64.swiftmodule") + config.target_swiftdoc_name = get_architecture_value(armv7="arm.swiftdoc", + aarch64="arm64.swiftdoc") config.target_runtime = "native" config.target_swift_autolink_extract = inferSwiftBinary("swift-autolink-extract") config.target_sdk_name = "android" - android_linker_opt = "-L {libcxx} -L {libgcc}".format( + android_link_paths_opt = "-L {libcxx} -L {libgcc}".format( libcxx=make_path(config.android_ndk_path, - "sources", "cxx-stl", "llvm-libc++", "libs", - "armeabi-v7a"), + "sources", "cxx-stl", "llvm-libc++", "libs", ndk_platform_tuple), libgcc=make_path(config.android_ndk_path, - "toolchains", - "arm-linux-androideabi-{}".format(config.android_ndk_gcc_version), - "prebuilt", "linux-x86_64", "lib", "gcc", - "arm-linux-androideabi", + "toolchains", toolchain_directory_name, "prebuilt", + "linux-x86_64", "lib", "gcc", ndk_platform_triple, "{}.x".format(config.android_ndk_gcc_version))) + # Since NDK r14 the headers are unified under $NDK_PATH/sysroot, so the -sdk + # switch is not enough. Additionally we have to include both the unified + # sysroot, and the architecture sysroot. + android_include_paths_opt = "-I {sysroot} -I {sysroot_arch}".format( + sysroot=make_path(config.android_ndk_path, "sysroot", "usr", "include"), + sysroot_arch=make_path(config.android_ndk_path, "sysroot", "usr", + "include", ndk_platform_triple)) config.target_build_swift = ( - '%s -target %s -sdk %r %s -Xlinker -pie %s %s %s %s %s' - % (config.swiftc, config.variant_triple, config.variant_sdk, - android_linker_opt, resource_dir_opt, mcp_opt, - config.swift_test_options, + '%s -target %s -sdk %r -tools-directory %r %s %s ' + '-use-ld=%s %s %s %s %s %s' + % (config.swiftc, + config.variant_triple, config.variant_sdk, + tools_directory, android_include_paths_opt, android_link_paths_opt, + config.android_linker_name, + resource_dir_opt, mcp_opt, config.swift_test_options, config.swift_driver_test_options, swift_execution_tests_extra_flags)) config.target_codesign = "echo" config.target_build_swift_dylib = ( @@ -960,9 +988,10 @@ elif run_os == 'linux-androideabi': % (config.target_build_swift)) config.target_add_rpath = r'-Xlinker -rpath -Xlinker \1' config.target_swift_frontend = ( - '%s -frontend -target %s -sdk %r %s %s %s %s' + '%s -frontend -target %s -sdk %r %s %s %s %s %s %s' % (config.swift, config.variant_triple, config.variant_sdk, - android_linker_opt, resource_dir_opt, mcp_opt, + android_include_paths_opt, android_link_paths_opt, resource_dir_opt, + mcp_opt, config.swift_test_options, config.swift_frontend_test_options)) subst_target_swift_frontend_mock_sdk = config.target_swift_frontend subst_target_swift_frontend_mock_sdk_after = "" @@ -978,19 +1007,18 @@ elif run_os == 'linux-androideabi': subst_target_swift_ide_test_mock_sdk = config.target_swift_ide_test subst_target_swift_ide_test_mock_sdk_after = "" config.target_swiftc_driver = ( - "%s -target %s -sdk %r %s %s %s" % + "%s -target %s -sdk %r -tools-directory %s %s %s %s -use-ld=%s" % (config.swiftc, config.variant_triple, config.variant_sdk, - android_linker_opt, resource_dir_opt, mcp_opt)) + tools_directory, android_link_paths_opt, resource_dir_opt, mcp_opt, + config.android_linker_name)) config.target_swift_modulewrap = ( '%s -modulewrap -target %s' % (config.swiftc, config.variant_triple)) config.target_clang = ( - "clang++ -target %s %s" % - (config.variant_triple, clang_mcp_opt)) + "clang++ -target %s %s %s" % + (config.variant_triple, clang_mcp_opt, android_include_paths_opt)) config.target_ld = "{} -L{}".format( - make_path(config.android_ndk_path, 'toolchains', - 'arm-linux-androideabi-{}'.format(config.android_ndk_gcc_version), - 'prebuilt', 'linux-x86_64', 'arm-linux-androideabi', 'bin'), + tools_directory, make_path(test_resource_dir, config.target_sdk_name)) # The Swift interpreter is not available when targeting Android. config.available_features.remove('swift_interpreter') diff --git a/test/lit.site.cfg.in b/test/lit.site.cfg.in index 77acd1febaaf3..ea0a583871bb1 100644 --- a/test/lit.site.cfg.in +++ b/test/lit.site.cfg.in @@ -91,6 +91,12 @@ if "@SWIFT_BUILD_SYNTAXPARSERLIB@" == "TRUE": if "@SWIFT_ENABLE_SOURCEKIT_TESTS@" == "TRUE": config.available_features.add('sourcekit') +if "@SWIFT_ENABLE_LLD_LINKER@" == "TRUE": + config.android_linker_name = "lld" +else: + # even if SWIFT_ENABLE_GOLD_LINKER isn't set, we cannot use BFD for Android + config.android_linker_name = "gold" + # Let the main config do the real work. if config.test_exec_root is None: config.test_exec_root = os.path.dirname(os.path.realpath(__file__)) diff --git a/validation-test/lit.site.cfg.in b/validation-test/lit.site.cfg.in index 60d175c30ff51..3adb7ac6edbf3 100644 --- a/validation-test/lit.site.cfg.in +++ b/validation-test/lit.site.cfg.in @@ -80,7 +80,12 @@ if "@CMAKE_GENERATOR@" == "Xcode": config.available_features.add("CMAKE_GENERATOR=@CMAKE_GENERATOR@") +if "@SWIFT_ENABLE_LLD_LINKER@" == "TRUE": + config.android_linker_name = "lld" +else: + # even if SWIFT_ENABLE_GOLD_LINKER isn't set, we cannot use BFD for Android + config.android_linker_name = "gold" + # Let the main config do the real work. config.test_exec_root = os.path.dirname(os.path.realpath(__file__)) lit_config.load_config(config, "@SWIFT_SOURCE_DIR@/validation-test/lit.cfg") -