Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[compiler-rt] Allow running tests without installing first #83088

Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions compiler-rt/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,27 @@ string(APPEND COMPILER_RT_TEST_COMPILER_CFLAGS " ${stdlib_flag}")
string(REPLACE " " ";" COMPILER_RT_UNITTEST_CFLAGS "${COMPILER_RT_TEST_COMPILER_CFLAGS}")
set(COMPILER_RT_UNITTEST_LINK_FLAGS ${COMPILER_RT_UNITTEST_CFLAGS})

option(COMPILER_RT_TEST_STANDALONE_BUILD_LIBS
"When set to ON and testing in a standalone build, test the runtime \
libraries built by this standalone build rather than the runtime libraries \
shipped with the compiler (used for testing). When set to OFF and testing \
in a standalone build, test the runtime libraries shipped with the compiler \
(used for testing). This option has no effect if the compiler and this \
build are configured to use the same runtime library path."
ON)
if (COMPILER_RT_TEST_STANDALONE_BUILD_LIBS)
# Ensure that the unit tests can find the sanitizer headers prior to installation.
list(APPEND COMPILER_RT_UNITTEST_CFLAGS "-I${CMAKE_CURRENT_LIST_DIR}/include")
# Ensure that unit tests link against the just-built runtime libraries instead
# of the ones bundled with the compiler by overriding the resource directory.
#
if ("${COMPILER_RT_TEST_COMPILER_ID}" MATCHES "Clang")
list(APPEND COMPILER_RT_UNITTEST_LINK_FLAGS "-resource-dir=${CMAKE_CURRENT_BINARY_DIR}")
endif()
get_compiler_rt_output_dir(${COMPILER_RT_DEFAULT_TARGET_ARCH} output_dir)
list(APPEND COMPILER_RT_UNITTEST_LINK_FLAGS "-Wl,-rpath,${output_dir}")
endif()

if(COMPILER_RT_USE_LLVM_UNWINDER)
# We're linking directly against the libunwind that we're building so don't
# try to link in the toolchain's default libunwind which may be missing.
Expand Down
1 change: 1 addition & 0 deletions compiler-rt/cmake/Modules/AddCompilerRT.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -768,6 +768,7 @@ function(configure_compiler_rt_lit_site_cfg input output)
get_compiler_rt_output_dir(${COMPILER_RT_DEFAULT_TARGET_ARCH} output_dir)

string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} COMPILER_RT_RESOLVED_TEST_COMPILER ${COMPILER_RT_TEST_COMPILER})
string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} COMPILER_RT_RESOLVED_OUTPUT_DIR ${COMPILER_RT_OUTPUT_DIR})
string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} COMPILER_RT_RESOLVED_LIBRARY_OUTPUT_DIR ${output_dir})

configure_lit_site_cfg(${input} ${output})
Expand Down
8 changes: 0 additions & 8 deletions compiler-rt/test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,14 +1,6 @@
# Needed for lit support in standalone builds.
include(AddLLVM)

option(COMPILER_RT_TEST_STANDALONE_BUILD_LIBS
"When set to ON and testing in a standalone build, test the runtime \
libraries built by this standalone build rather than the runtime libraries \
shipped with the compiler (used for testing). When set to OFF and testing \
in a standalone build, test the runtime libraries shipped with the compiler \
(used for testing). This option has no effect if the compiler and this \
build are configured to use the same runtime library path."
ON)
pythonize_bool(COMPILER_RT_TEST_STANDALONE_BUILD_LIBS)

pythonize_bool(LLVM_ENABLE_EXPENSIVE_CHECKS)
Expand Down
1 change: 1 addition & 0 deletions compiler-rt/test/fuzzer/lit.cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ def generate_compiler_cmd(is_cpp=True, fuzzer_enabled=True, msan_enabled=False):
return " ".join(
[
compiler_cmd,
config.target_cflags,
std_cmd,
"-O2 -gline-tables-only",
sanitizers_cmd,
Expand Down
77 changes: 55 additions & 22 deletions compiler-rt/test/lit.common.cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,26 @@
import lit.util


def get_path_from_clang(args, allow_failure):
clang_cmd = [
config.clang.strip(),
f"--target={config.target_triple}",
*args,
]
path = None
try:
result = subprocess.run(
clang_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True
)
path = result.stdout.decode().strip()
except subprocess.CalledProcessError as e:
msg = f"Failed to run {clang_cmd}\nrc:{e.returncode}\nstdout:{e.stdout}\ne.stderr{e.stderr}"
if allow_failure:
lit_config.warning(msg)
else:
lit_config.fatal(msg)
return path, clang_cmd

def find_compiler_libdir():
"""
Returns the path to library resource directory used
Expand All @@ -26,26 +46,6 @@ def find_compiler_libdir():
# TODO: Support other compilers.
return None

def get_path_from_clang(args, allow_failure):
clang_cmd = [
config.clang.strip(),
f"--target={config.target_triple}",
]
clang_cmd.extend(args)
path = None
try:
result = subprocess.run(
clang_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True
)
path = result.stdout.decode().strip()
except subprocess.CalledProcessError as e:
msg = f"Failed to run {clang_cmd}\nrc:{e.returncode}\nstdout:{e.stdout}\ne.stderr{e.stderr}"
if allow_failure:
lit_config.warning(msg)
else:
lit_config.fatal(msg)
return path, clang_cmd

# Try using `-print-runtime-dir`. This is only supported by very new versions of Clang.
# so allow failure here.
runtime_dir, clang_cmd = get_path_from_clang(
Expand Down Expand Up @@ -168,10 +168,43 @@ def push_dynamic_library_lookup_path(config, new_path):
r"/i386(?=-[^/]+$)", "/x86_64", config.compiler_rt_libdir
)


# Check if the test compiler resource dir matches the local build directory
# (which happens with -DLLVM_ENABLE_PROJECTS=clang;compiler-rt) or if we are
# using an installed clang to test compiler-rt standalone. In the latter case
# we may need to override the resource dir to match the path of the just-built
# compiler-rt libraries.
test_cc_resource_dir, _ = get_path_from_clang(
shlex.split(config.target_cflags) + ["-print-resource-dir"], allow_failure=True
)
# Normalize the path for comparison
if test_cc_resource_dir is not None:
test_cc_resource_dir = os.path.realpath(test_cc_resource_dir)
if lit_config.debug:
lit_config.note(f"Resource dir for {config.clang} is {test_cc_resource_dir}")
local_build_resource_dir = os.path.realpath(config.compiler_rt_output_dir)
if test_cc_resource_dir != local_build_resource_dir:
if config.test_standalone_build_libs and config.compiler_id == "Clang":
if lit_config.debug:
lit_config.note(f'Overriding test compiler resource dir to use '
f'libraries in "{config.compiler_rt_libdir}"')
# Ensure that we use the just-built static libraries when linking by
# overriding the Clang resource directory. Additionally, we want to use
# the builtin headers shipped with clang (e.g. stdint.h), so we
# explicitly add this as an include path (since the headers are not
# going to be in the current compiler-rt build directory).
# We also tell the linker to add an RPATH entry for the local library
# directory so that the just-built shared libraries are used.
config.target_cflags += f" -nobuiltininc"
Copy link
Member

@MaskRay MaskRay Feb 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wondered whether target_cflags can be made to a list instead of space-separated str, but I think it doesn't really improve.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that this would be cleaner, I will submit an independent cleanup PR.

config.target_cflags += f" -I{config.compiler_rt_src_root}/include"
config.target_cflags += f" -idirafter {test_cc_resource_dir}/include"
config.target_cflags += f" -resource-dir={config.compiler_rt_output_dir}"
config.target_cflags += f" -Wl,-rpath,{config.compiler_rt_libdir}"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In addition to the fix for Windows that was made in 10b1864, this bit here also would need a similar condition - otherwise testing fails with the same error, see e.g. https://github.com/mstorsjo/llvm-mingw/actions/runs/8592846078/job/23549755414.

I see that this whole PR was reverted later, but when preparing for a reland, make sure to conditionalize this case of -Wl,-rpath as well.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense. Unfortunately I don't have a way of testing this on Windows, and I was hoping the pre-commit CI would have caught it but I guess that does not include mingw.


# Ask the compiler for the path to libraries it is going to use. If this
# doesn't match config.compiler_rt_libdir then it means we might be testing the
# compiler's own runtime libraries rather than the ones we just built.
# Warn about about this and handle appropriately.
# Warn about this and handle appropriately.
compiler_libdir = find_compiler_libdir()
if compiler_libdir:
compiler_rt_libdir_real = os.path.realpath(config.compiler_rt_libdir)
Expand All @@ -182,7 +215,7 @@ def push_dynamic_library_lookup_path(config, new_path):
f'compiler-rt libdir: "{compiler_rt_libdir_real}"'
)
if config.test_standalone_build_libs:
# Use just built runtime libraries, i.e. the the libraries this built just built.
# Use just built runtime libraries, i.e. the libraries this build just built.
if not config.test_suite_supports_overriding_runtime_lib_path:
# Test suite doesn't support this configuration.
# TODO(dliew): This should be an error but it seems several bots are
Expand Down
1 change: 1 addition & 0 deletions compiler-rt/test/lit.common.configured.in
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ set_default("compiler_id", "@COMPILER_RT_TEST_COMPILER_ID@")
set_default("python_executable", "@Python3_EXECUTABLE@")
set_default("compiler_rt_debug", @COMPILER_RT_DEBUG_PYBOOL@)
set_default("compiler_rt_intercept_libdispatch", @COMPILER_RT_INTERCEPT_LIBDISPATCH_PYBOOL@)
set_default("compiler_rt_output_dir", "@COMPILER_RT_RESOLVED_OUTPUT_DIR@")
set_default("compiler_rt_libdir", "@COMPILER_RT_RESOLVED_LIBRARY_OUTPUT_DIR@")
set_default("emulator", "@COMPILER_RT_EMULATOR@")
set_default("asan_shadow_scale", "@COMPILER_RT_ASAN_SHADOW_SCALE@")
Expand Down
4 changes: 2 additions & 2 deletions compiler-rt/test/safestack/lit.cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@

# Add clang substitutions.
config.substitutions.append(
("%clang_nosafestack ", config.clang + " -O0 -fno-sanitize=safe-stack ")
("%clang_nosafestack ", config.clang + config.target_cflags + " -O0 -fno-sanitize=safe-stack ")
)
config.substitutions.append(
("%clang_safestack ", config.clang + " -O0 -fsanitize=safe-stack ")
("%clang_safestack ", config.clang + config.target_cflags + " -O0 -fsanitize=safe-stack ")
)

if config.lto_supported:
Expand Down
Loading