Skip to content
/ rust Public
forked from rust-lang/rust
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit e7a3465

Browse files
authoredMar 14, 2025
Rollup merge of rust-lang#138451 - Kobzol:gcc-ci-build-gcc, r=GuillaumeGomez
Build GCC on CI with GCC, not Clang It seems that GCC built with Clang misbehaves. I have tested that cg_gcc tests [pass](https://github.com/rust-lang/rust/actions/runs/13842365913/job/38732750617?pr=138451) on CI with a downloaded GCC that was built in this way. Prerequisite for rust-lang#138395. r? `@ghost`
2 parents 693bada + bf095f6 commit e7a3465

File tree

5 files changed

+91
-45
lines changed

5 files changed

+91
-45
lines changed
 

‎src/bootstrap/src/core/build_steps/dist.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2481,7 +2481,7 @@ impl Step for Gcc {
24812481
fn run(self, builder: &Builder<'_>) -> Self::Output {
24822482
let tarball = Tarball::new(builder, "gcc", &self.target.triple);
24832483
let output = builder.ensure(super::gcc::Gcc { target: self.target });
2484-
tarball.add_file(output.libgccjit, ".", 0o644);
2484+
tarball.add_file(output.libgccjit, "lib", 0o644);
24852485
tarball.generate()
24862486
}
24872487
}

‎src/bootstrap/src/core/build_steps/gcc.rs

+24-14
Original file line numberDiff line numberDiff line change
@@ -63,18 +63,23 @@ impl Step for Gcc {
6363
}
6464

6565
build_gcc(&metadata, builder, target);
66-
67-
let lib_alias = metadata.install_dir.join("lib/libgccjit.so.0");
68-
if !lib_alias.exists() {
69-
t!(builder.symlink_file(&libgccjit_path, lib_alias));
70-
}
66+
create_lib_alias(builder, &libgccjit_path);
7167

7268
t!(metadata.stamp.write());
7369

7470
GccOutput { libgccjit: libgccjit_path }
7571
}
7672
}
7773

74+
/// Creates a libgccjit.so.0 alias next to libgccjit.so if it does not
75+
/// already exist
76+
fn create_lib_alias(builder: &Builder<'_>, libgccjit: &PathBuf) {
77+
let lib_alias = libgccjit.parent().unwrap().join("libgccjit.so.0");
78+
if !lib_alias.exists() {
79+
t!(builder.symlink_file(libgccjit, lib_alias));
80+
}
81+
}
82+
7883
pub struct Meta {
7984
stamp: BuildStamp,
8085
out_dir: PathBuf,
@@ -109,8 +114,10 @@ fn try_download_gcc(builder: &Builder<'_>, target: TargetSelection) -> Option<Pa
109114
builder.config.download_ci_gcc(&sha, &root);
110115
t!(gcc_stamp.write());
111116
}
112-
// FIXME: put libgccjit.so into a lib directory in dist::Gcc
113-
Some(root.join("libgccjit.so"))
117+
118+
let libgccjit = root.join("lib").join("libgccjit.so");
119+
create_lib_alias(builder, &libgccjit);
120+
Some(libgccjit)
114121
}
115122

116123
#[cfg(test)]
@@ -177,6 +184,14 @@ fn libgccjit_built_path(install_dir: &Path) -> PathBuf {
177184
}
178185

179186
fn build_gcc(metadata: &Meta, builder: &Builder<'_>, target: TargetSelection) {
187+
if builder.build.cc_tool(target).is_like_clang()
188+
|| builder.build.cxx_tool(target).is_like_clang()
189+
{
190+
panic!(
191+
"Attempting to build GCC using Clang, which is known to misbehave. Please use GCC as the host C/C++ compiler. "
192+
);
193+
}
194+
180195
let Meta { stamp: _, out_dir, install_dir, root } = metadata;
181196

182197
t!(fs::create_dir_all(out_dir));
@@ -203,18 +218,13 @@ fn build_gcc(metadata: &Meta, builder: &Builder<'_>, target: TargetSelection) {
203218
let mut configure_cmd = command(src_dir.join("configure"));
204219
configure_cmd
205220
.current_dir(out_dir)
206-
// On CI, we compile GCC with Clang.
207-
// The -Wno-everything flag is needed to make GCC compile with Clang 19.
208-
// `-g -O2` are the default flags that are otherwise used by Make.
209-
// FIXME(kobzol): change the flags once we have [gcc] configuration in config.toml.
210-
.env("CXXFLAGS", "-Wno-everything -g -O2")
211-
.env("CFLAGS", "-Wno-everything -g -O2")
212221
.arg("--enable-host-shared")
213-
.arg("--enable-languages=jit")
222+
.arg("--enable-languages=c,jit,lto")
214223
.arg("--enable-checking=release")
215224
.arg("--disable-bootstrap")
216225
.arg("--disable-multilib")
217226
.arg(format!("--prefix={}", install_dir.display()));
227+
218228
let cc = builder.build.cc(target).display().to_string();
219229
let cc = builder
220230
.build

‎src/bootstrap/src/lib.rs

+11
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ use std::{env, fs, io, str};
2727

2828
use build_helper::ci::gha;
2929
use build_helper::exit;
30+
use cc::Tool;
3031
use termcolor::{ColorChoice, StandardStream, WriteColor};
3132
use utils::build_stamp::BuildStamp;
3233
use utils::channel::GitInfo;
@@ -1218,6 +1219,16 @@ Executed at: {executed_at}"#,
12181219
self.cc.borrow()[&target].path().into()
12191220
}
12201221

1222+
/// Returns the internal `cc::Tool` for the C compiler.
1223+
fn cc_tool(&self, target: TargetSelection) -> Tool {
1224+
self.cc.borrow()[&target].clone()
1225+
}
1226+
1227+
/// Returns the internal `cc::Tool` for the C++ compiler.
1228+
fn cxx_tool(&self, target: TargetSelection) -> Tool {
1229+
self.cxx.borrow()[&target].clone()
1230+
}
1231+
12211232
/// Returns C flags that `cc-rs` thinks should be enabled for the
12221233
/// specified target by default.
12231234
fn cc_handled_clags(&self, target: TargetSelection, c: CLang) -> Vec<String> {

‎src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile

+3-1
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,9 @@ ENV SCRIPT python3 ../x.py build --set rust.debug=true opt-dist && \
101101
./build/$HOSTS/stage0-tools-bin/opt-dist linux-ci -- python3 ../x.py dist \
102102
--host $HOSTS --target $HOSTS \
103103
--include-default-paths \
104-
build-manifest bootstrap gcc
104+
build-manifest bootstrap && \
105+
# Use GCC for building GCC, as it seems to behave badly when built with Clang
106+
CC=/rustroot/bin/cc CXX=/rustroot/bin/c++ python3 ../x.py dist gcc
105107
ENV CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER=clang
106108

107109
# This is the only builder which will create source tarballs

‎src/tools/opt-dist/src/tests.rs

+52-29
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::path::Path;
2+
13
use anyhow::Context;
24
use camino::{Utf8Path, Utf8PathBuf};
35

@@ -86,36 +88,57 @@ llvm-config = "{llvm_config}"
8688
log::info!("Using following `config.toml` for running tests:\n{config_content}");
8789

8890
// Simulate a stage 0 compiler with the extracted optimized dist artifacts.
89-
std::fs::write("config.toml", config_content)?;
90-
91-
let x_py = env.checkout_path().join("x.py");
92-
let mut args = vec![
93-
env.python_binary(),
94-
x_py.as_str(),
95-
"test",
96-
"--build",
97-
env.host_tuple(),
98-
"--stage",
99-
"0",
100-
"tests/assembly",
101-
"tests/codegen",
102-
"tests/codegen-units",
103-
"tests/incremental",
104-
"tests/mir-opt",
105-
"tests/pretty",
106-
"tests/run-make/glibc-symbols-x86_64-unknown-linux-gnu",
107-
"tests/ui",
108-
"tests/crashes",
109-
];
110-
for test_path in env.skipped_tests() {
111-
args.extend(["--skip", test_path]);
91+
with_backed_up_file(Path::new("config.toml"), &config_content, || {
92+
let x_py = env.checkout_path().join("x.py");
93+
let mut args = vec![
94+
env.python_binary(),
95+
x_py.as_str(),
96+
"test",
97+
"--build",
98+
env.host_tuple(),
99+
"--stage",
100+
"0",
101+
"tests/assembly",
102+
"tests/codegen",
103+
"tests/codegen-units",
104+
"tests/incremental",
105+
"tests/mir-opt",
106+
"tests/pretty",
107+
"tests/run-make/glibc-symbols-x86_64-unknown-linux-gnu",
108+
"tests/ui",
109+
"tests/crashes",
110+
];
111+
for test_path in env.skipped_tests() {
112+
args.extend(["--skip", test_path]);
113+
}
114+
cmd(&args)
115+
.env("COMPILETEST_FORCE_STAGE0", "1")
116+
// Also run dist-only tests
117+
.env("COMPILETEST_ENABLE_DIST_TESTS", "1")
118+
.run()
119+
.context("Cannot execute tests")
120+
})
121+
}
122+
123+
/// Backup `path` (if it exists), then write `contents` into it, and then restore the original
124+
/// contents of the file.
125+
fn with_backed_up_file<F>(path: &Path, contents: &str, func: F) -> anyhow::Result<()>
126+
where
127+
F: FnOnce() -> anyhow::Result<()>,
128+
{
129+
let original_contents =
130+
if path.is_file() { Some(std::fs::read_to_string(path)?) } else { None };
131+
132+
// Overwrite it with new contents
133+
std::fs::write(path, contents)?;
134+
135+
let ret = func();
136+
137+
if let Some(original_contents) = original_contents {
138+
std::fs::write(path, original_contents)?;
112139
}
113-
cmd(&args)
114-
.env("COMPILETEST_FORCE_STAGE0", "1")
115-
// Also run dist-only tests
116-
.env("COMPILETEST_ENABLE_DIST_TESTS", "1")
117-
.run()
118-
.context("Cannot execute tests")
140+
141+
ret
119142
}
120143

121144
/// Tries to find the version of the dist artifacts (either nightly, beta, or 1.XY.Z).

0 commit comments

Comments
 (0)
Failed to load comments.