Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
4 changes: 4 additions & 0 deletions compiler/rustc_codegen_llvm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,10 @@ impl CodegenBackend for LlvmCodegenBackend {
}
writeln!(out).unwrap();
}
PrintKind::BackendHasZstd => {
let has_zstd = llvm::LLVMRustLLVMHasZstdCompression();
writeln!(out, "{has_zstd}").unwrap();
}
Copy link
Member

Choose a reason for hiding this comment

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

There is no default implementation of this print request, which causes compiletest to break for all non-llvm backends unless they explicitly add an implementation for this.

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh, that's surprising, sorry.

I had intended to write this in a way that was friendly to other backends, but then I went back and changed things for other reasons and that property was lost.

Copy link
Member

Choose a reason for hiding this comment

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

Worked around this on the cg_clif side for now. cg_gcc would also need changes.

Copy link
Member Author

Choose a reason for hiding this comment

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

Does the failure only occur when a non-LLVM backend is the default? Or does it break even when LLVM is the default and a different backend is selected?

Copy link
Member Author

Choose a reason for hiding this comment

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

My tentative fix is to add this to llvm_has_zstd in src/tools/compiletest/src/directives/needs.rs:

    if !config.default_codegen_backend.is_llvm() {
        return false;
    }

But I can't get any non-LLVM backends to work on my system at the moment, so I have no way to test this fix.

Copy link
Member

Choose a reason for hiding this comment

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

Given that you don't pass -Zcodegen-backend even when the user selects a different codegen backend, this should right now only break when a non-LLVM codegen backend is the default.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, that probably explains why it wasn't caught by CI.

I have a backend-agnostic fix posted at #149764.

PrintKind::CodeModels => {
writeln!(out, "Available code models:").unwrap();
for name in &["tiny", "small", "kernel", "medium", "large"] {
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_driver_impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -799,6 +799,7 @@ fn print_crate_info(
println_info!("{}", calling_conventions.join("\n"));
}
RelocationModels
| BackendHasZstd
| CodeModels
| TlsModels
| TargetCPUs
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_session/src/config/print_request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub struct PrintRequest {
pub enum PrintKind {
// tidy-alphabetical-start
AllTargetSpecsJson,
BackendHasZstd,
CallingConventions,
Cfg,
CheckCfg,
Expand Down Expand Up @@ -59,6 +60,7 @@ impl PrintKind {
match self {
// tidy-alphabetical-start
AllTargetSpecsJson => "all-target-specs-json",
BackendHasZstd => "backend-has-zstd",
CallingConventions => "calling-conventions",
Cfg => "cfg",
CheckCfg => "check-cfg",
Expand Down Expand Up @@ -111,6 +113,7 @@ impl PrintKind {

// Unstable values:
AllTargetSpecsJson => false,
BackendHasZstd => false, // (perma-unstable, for use by compiletest)
CheckCfg => false,
CrateRootLintLevels => false,
SupportedCrateTypes => false,
Expand Down
6 changes: 5 additions & 1 deletion src/tools/compiletest/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1096,7 +1096,11 @@ fn supported_crate_types(config: &Config) -> HashSet<String> {
crate_types
}

fn query_rustc_output(config: &Config, args: &[&str], envs: HashMap<String, String>) -> String {
pub(crate) fn query_rustc_output(
config: &Config,
args: &[&str],
envs: HashMap<String, String>,
) -> String {
let query_rustc_path = config.query_rustc_path.as_deref().unwrap_or(&config.rustc_path);

let mut command = Command::new(query_rustc_path);
Expand Down
101 changes: 0 additions & 101 deletions src/tools/compiletest/src/directives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -885,107 +885,6 @@ pub fn extract_llvm_version_from_binary(binary_path: &str) -> Option<Version> {
None
}

/// For tests using the `needs-llvm-zstd` directive:
/// - for local LLVM builds, try to find the static zstd library in the llvm-config system libs.
/// - for `download-ci-llvm`, see if `lld` was built with zstd support.
pub fn llvm_has_libzstd(config: &Config) -> bool {
// Strategy 1: works for local builds but not with `download-ci-llvm`.
//
// We check whether `llvm-config` returns the zstd library. Bootstrap's `llvm.libzstd` will only
// ask to statically link it when building LLVM, so we only check if the list of system libs
// contains a path to that static lib, and that it exists.
//
// See compiler/rustc_llvm/build.rs for more details and similar expectations.
fn is_zstd_in_config(llvm_bin_dir: &Utf8Path) -> Option<()> {
let llvm_config_path = llvm_bin_dir.join("llvm-config");
let output = Command::new(llvm_config_path).arg("--system-libs").output().ok()?;
assert!(output.status.success(), "running llvm-config --system-libs failed");

let libs = String::from_utf8(output.stdout).ok()?;
for lib in libs.split_whitespace() {
if lib.ends_with("libzstd.a") && Utf8Path::new(lib).exists() {
return Some(());
}
}

None
}

// Strategy 2: `download-ci-llvm`'s `llvm-config --system-libs` will not return any libs to
// use.
//
// The CI artifacts also don't contain the bootstrap config used to build them: otherwise we
// could have looked at the `llvm.libzstd` config.
//
// We infer whether `LLVM_ENABLE_ZSTD` was used to build LLVM as a byproduct of testing whether
// `lld` supports it. If not, an error will be emitted: "LLVM was not built with
// LLVM_ENABLE_ZSTD or did not find zstd at build time".
#[cfg(unix)]
fn is_lld_built_with_zstd(llvm_bin_dir: &Utf8Path) -> Option<()> {
let lld_path = llvm_bin_dir.join("lld");
if lld_path.exists() {
// We can't call `lld` as-is, it expects to be invoked by a compiler driver using a
// different name. Prepare a temporary symlink to do that.
let lld_symlink_path = llvm_bin_dir.join("ld.lld");
if !lld_symlink_path.exists() {
std::os::unix::fs::symlink(lld_path, &lld_symlink_path).ok()?;
}

// Run `lld` with a zstd flag. We expect this command to always error here, we don't
// want to link actual files and don't pass any.
let output = Command::new(&lld_symlink_path)
.arg("--compress-debug-sections=zstd")
.output()
.ok()?;
assert!(!output.status.success());

// Look for a specific error caused by LLVM not being built with zstd support. We could
// also look for the "no input files" message, indicating the zstd flag was accepted.
let stderr = String::from_utf8(output.stderr).ok()?;
let zstd_available = !stderr.contains("LLVM was not built with LLVM_ENABLE_ZSTD");

// We don't particularly need to clean the link up (so the previous commands could fail
// in theory but won't in practice), but we can try.
std::fs::remove_file(lld_symlink_path).ok()?;

if zstd_available {
return Some(());
}
}

None
}

#[cfg(not(unix))]
fn is_lld_built_with_zstd(_llvm_bin_dir: &Utf8Path) -> Option<()> {
None
}

if let Some(llvm_bin_dir) = &config.llvm_bin_dir {
// Strategy 1: for local LLVM builds.
if is_zstd_in_config(llvm_bin_dir).is_some() {
return true;
}

// Strategy 2: for LLVM artifacts built on CI via `download-ci-llvm`.
//
// It doesn't work for cases where the artifacts don't contain the linker, but it's
// best-effort: CI has `llvm.libzstd` and `lld` enabled on the x64 linux artifacts, so it
// will at least work there.
//
// If this can be improved and expanded to less common cases in the future, it should.
if config.target == "x86_64-unknown-linux-gnu"
&& config.host == config.target
&& is_lld_built_with_zstd(llvm_bin_dir).is_some()
{
return true;
}
}

// Otherwise, all hope is lost.
false
}

/// Takes a directive of the form `"<version1> [- <version2>]"`, returns the numeric representation
/// of `<version1>` and `<version2>` as tuple: `(<version1>, <version2>)`.
///
Expand Down
23 changes: 20 additions & 3 deletions src/tools/compiletest/src/directives/needs.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use crate::common::{Config, KNOWN_CRATE_TYPES, KNOWN_TARGET_HAS_ATOMIC_WIDTHS, Sanitizer};
use crate::directives::{DirectiveLine, IgnoreDecision, llvm_has_libzstd};
use crate::common::{
Config, KNOWN_CRATE_TYPES, KNOWN_TARGET_HAS_ATOMIC_WIDTHS, Sanitizer, query_rustc_output,
};
use crate::directives::{DirectiveLine, IgnoreDecision};

pub(super) fn handle_needs(
cache: &CachedNeedsConditions,
Expand Down Expand Up @@ -377,7 +379,7 @@ impl CachedNeedsConditions {
.join(if config.host.contains("windows") { "rust-lld.exe" } else { "rust-lld" })
.exists(),

llvm_zstd: llvm_has_libzstd(&config),
llvm_zstd: llvm_has_zstd(&config),
dlltool: find_dlltool(&config),
symlinks: has_symlinks(),
}
Expand Down Expand Up @@ -428,3 +430,18 @@ fn has_symlinks() -> bool {
fn has_symlinks() -> bool {
true
}

fn llvm_has_zstd(config: &Config) -> bool {
// The compiler already knows whether LLVM was built with zstd or not,
// so compiletest can just ask the compiler.
let output = query_rustc_output(
config,
&["-Zunstable-options", "--print=backend-has-zstd"],
Default::default(),
);
match output.trim() {
"true" => true,
"false" => false,
_ => panic!("unexpected output from `--print=backend-has-zstd`: {output:?}"),
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
error: unknown print request: `xxx`
|
- = help: valid print requests are: `calling-conventions`, `cfg`, `code-models`, `crate-name`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `tls-models`
+ = help: valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `crate-root-lint-levels`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `target-spec-json-schema`, `tls-models`
+ = help: valid print requests are: `all-target-specs-json`, `backend-has-zstd`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `crate-root-lint-levels`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `target-spec-json-schema`, `tls-models`
= help: for more information, see the rustc book: https://doc.rust-lang.org/rustc/command-line-arguments.html#--print-print-compiler-information

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: unknown print request: `xxx`
|
= help: valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `crate-root-lint-levels`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `target-spec-json-schema`, `tls-models`
= help: valid print requests are: `all-target-specs-json`, `backend-has-zstd`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `crate-root-lint-levels`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `target-spec-json-schema`, `tls-models`
= help: for more information, see the rustc book: https://doc.rust-lang.org/rustc/command-line-arguments.html#--print-print-compiler-information

2 changes: 1 addition & 1 deletion tests/run-make/rustc-help/help-v.stdout
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Options:
--print <INFO>[=<FILE>]
Compiler information to print on stdout (or to a file)
INFO may be one of
<all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|crate-root-lint-levels|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|supported-crate-types|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|target-spec-json-schema|tls-models>.
<all-target-specs-json|backend-has-zstd|calling-conventions|cfg|check-cfg|code-models|crate-name|crate-root-lint-levels|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|supported-crate-types|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|target-spec-json-schema|tls-models>.
-g Equivalent to -C debuginfo=2
-O Equivalent to -C opt-level=3
-o <FILENAME> Write output to FILENAME
Expand Down
2 changes: 1 addition & 1 deletion tests/run-make/rustc-help/help.stdout
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Options:
--print <INFO>[=<FILE>]
Compiler information to print on stdout (or to a file)
INFO may be one of
<all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|crate-root-lint-levels|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|supported-crate-types|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|target-spec-json-schema|tls-models>.
<all-target-specs-json|backend-has-zstd|calling-conventions|cfg|check-cfg|code-models|crate-name|crate-root-lint-levels|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|supported-crate-types|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|target-spec-json-schema|tls-models>.
-g Equivalent to -C debuginfo=2
-O Equivalent to -C opt-level=3
-o <FILENAME> Write output to FILENAME
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/invalid-compile-flags/print-without-arg.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ error: Argument to option 'print' missing
--print <INFO>[=<FILE>]
Compiler information to print on stdout (or to a file)
INFO may be one of
<all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|crate-root-lint-levels|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|supported-crate-types|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|target-spec-json-schema|tls-models>.
<all-target-specs-json|backend-has-zstd|calling-conventions|cfg|check-cfg|code-models|crate-name|crate-root-lint-levels|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|supported-crate-types|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|target-spec-json-schema|tls-models>.

2 changes: 1 addition & 1 deletion tests/ui/invalid-compile-flags/print.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: unknown print request: `yyyy`
|
= help: valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `crate-root-lint-levels`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `target-spec-json-schema`, `tls-models`
= help: valid print requests are: `all-target-specs-json`, `backend-has-zstd`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `crate-root-lint-levels`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `target-spec-json-schema`, `tls-models`
= help: for more information, see the rustc book: https://doc.rust-lang.org/rustc/command-line-arguments.html#--print-print-compiler-information

8 changes: 8 additions & 0 deletions tests/ui/print-request/backend-has-zstd-unstable.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//! Check that `--print=backend-has-zstd` is unstable.
//!
//! That print value is intended for use by compiletest, and should probably
//! never be stabilized in this form.

//@ compile-flags: --print=backend-has-zstd

//~? ERROR: the `-Z unstable-options` flag must also be passed
2 changes: 2 additions & 0 deletions tests/ui/print-request/backend-has-zstd-unstable.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
error: the `-Z unstable-options` flag must also be passed to enable the `backend-has-zstd` print option

2 changes: 1 addition & 1 deletion tests/ui/print-request/print-lints-help.stderr
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
error: unknown print request: `lints`
|
= help: valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `crate-root-lint-levels`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `target-spec-json-schema`, `tls-models`
= help: valid print requests are: `all-target-specs-json`, `backend-has-zstd`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `crate-root-lint-levels`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `target-spec-json-schema`, `tls-models`
= help: use `-Whelp` to print a list of lints
= help: for more information, see the rustc book: https://doc.rust-lang.org/rustc/command-line-arguments.html#--print-print-compiler-information

Loading