[test] Generalize runtime library searching

Allow detecting the compiler runtime libraries for
non-Darwin platforms, allowing us to test that
programs relying on these libraries link successfully.
This commit is contained in:
Hamish Knight
2024-07-15 10:22:36 +01:00
parent 7b7110061f
commit 251182cf52
2 changed files with 68 additions and 28 deletions

View File

@@ -21,6 +21,9 @@
// REQUIRES: profile_runtime
// REQUIRES: executable_test
// FIXME: Currently fails on non-Darwin (https://github.com/swiftlang/swift/issues/75240)
// REQUIRES: OS=macosx
//--- a.swift
@_transparent
public func foo() {}

View File

@@ -375,6 +375,12 @@ if test_resource_dir:
config.resource_dir_opt = ("-resource-dir %s" % test_resource_dir)
else:
test_resource_dir = make_path(config.swift_lib_dir, 'swift')
lit_config.note('Using resource dir: ' + test_resource_dir)
test_clang_resource_dir = lit.util.executeCommand([config.clang, '-print-resource-dir'])[0].rstrip()
lit_config.note('Using Clang resource dir: ' + test_clang_resource_dir)
config.swift_system_overlay_opt = ""
config.clang_system_overlay_opt = ""
config.windows_vfs_overlay_opt = ""
@@ -396,9 +402,9 @@ config.substitutions.append( ('%windows_vfs_overlay_opt', config.windows_vfs_ove
stdlib_resource_dir_opt = config.resource_dir_opt
sourcekitd_framework_dir = config.swift_lib_dir
config.substitutions.append( ('%test-resource-dir', test_resource_dir) )
lit_config.note('Using resource dir: ' + test_resource_dir)
# Parse the variant triple.
# FIXME: We ought to parse 'run_environment' separately from 'run_os'.
(run_cpu, run_vendor, run_os, run_vers) = re.match('([^-]+)-([^-]+)-([^0-9]+)(.*)', config.variant_triple).groups()
if run_os == 'ios' and run_vers.endswith('-macabi'):
run_vers = run_vers[0:-len('-macabi')]
@@ -2235,8 +2241,7 @@ if config.target_sdk_name in simulator_sdks:
else:
config.substitutions.append(('%target-is-simulator', 'false'))
config.compiler_rt_libs = []
config.compiler_rt_platform = {
config.compiler_rt_darwin_platform = {
'iphoneos': 'ios',
'appletvos': 'tvos',
'watchos': 'watchos',
@@ -2246,24 +2251,66 @@ config.compiler_rt_platform = {
'appletvsimulator': 'tvossim',
'xrsimulator': 'xrossim',
'macosx': 'osx'
}.get(config.target_sdk_name, run_cpu)
}.get(config.target_sdk_name, run_os)
def source_compiler_rt_libs(path):
def find_compiler_rt_libs():
base = make_path(test_clang_resource_dir, 'lib')
libs = {}
# First check to see if this is 'clang/lib/darwin', it has its own custom filename pattern.
path = make_path(base, 'darwin')
if os.path.exists(path):
config.compiler_rt_libs.extend([lib for lib in
os.listdir(path)
if lib.startswith('libclang_rt.')
and config.compiler_rt_platform in lib])
for lib in os.listdir(path):
# Include any libraries with the platform name.
match = re.match(r'libclang_rt\.(?:(\w+)_)?' + config.compiler_rt_darwin_platform, lib)
if not match:
continue
component = match[1]
# An empty component corresponds to the 'builtins' library.
if not component:
component = 'builtins'
libs[component] = lib
compiler_rt_dir = make_path(test_resource_dir, 'clang', 'lib',
platform.system().lower())
source_compiler_rt_libs(compiler_rt_dir)
return (path, libs)
# Next check for the old scheme 'clang/lib/<os-name>', ignoring
# any target environment which is currently part of 'run_os'.
path = make_path(base, run_os.split('-')[0])
if os.path.exists(path):
# We should then have the architecture in the name.
for lib in os.listdir(path):
match = re.match(r'(?:lib)?clang_rt\.(\w+)-' + run_cpu, lib)
if match:
libs[match[1]] = lib
return (path, libs)
# Finally, check the new scheme 'clang/lib/<target>'
path = make_path(base, config.variant_triple)
if os.path.exists(path):
# We can include all the libraries here that match the base pattern.
for lib in os.listdir(path):
match = re.match(r'(?:lib)?clang_rt\.(\w+)\.', lib)
if match:
libs[match[1]] = lib
return (path, libs)
lit_config.warning("Couldn't find clang_rt directory")
return (None, {})
(compiler_rt_path, compiler_rt_libs) = find_compiler_rt_libs()
if compiler_rt_path:
lit_config.note("Using clang_rt directory: " + compiler_rt_path)
if compiler_rt_libs:
lit_config.note("Found clang_rt libs: {}".format(compiler_rt_libs))
else:
lit_config.warning("Couldn't find any clang_rt libs for %s" % config.variant_triple)
def check_runtime_libs(features_to_check):
for lib in config.compiler_rt_libs:
for (libname, feature) in features_to_check.items():
if lib.startswith("libclang_rt." + libname + "_"):
config.available_features.add(feature)
for (libname, feature) in features_to_check.items():
if libname in compiler_rt_libs:
config.available_features.add(feature)
runtime_libs = {
'profile': 'profile_runtime',
@@ -2271,7 +2318,8 @@ runtime_libs = {
'ubsan': 'ubsan_runtime',
'scudo': 'scudo_runtime',
'safestack': 'safestack_runtime',
'fuzzer': 'fuzzer_runtime'
'fuzzer': 'fuzzer_runtime',
'builtins': 'c_runtime'
}
if run_ptrsize == '64' and 'libdispatch' in config.available_features:
@@ -2279,17 +2327,6 @@ if run_ptrsize == '64' and 'libdispatch' in config.available_features:
check_runtime_libs(runtime_libs)
# From https://stackoverflow.com/a/2393022
def strip_right(text, suffix):
if not text.endswith(suffix):
return text
return text[:len(text)-len(suffix)]
base_runtime_lib_name = (
'libclang_rt.' + strip_right(config.compiler_rt_platform, 'sim') + '.a')
if os.path.exists(make_path(compiler_rt_dir, base_runtime_lib_name)):
config.available_features.add('c_runtime')
config.substitutions.append(('%target-objc-interop', run_objc_interop))
# For testing the remote-run utility itself, see if we can find an sftp-server