Skip to content

Commit

Permalink
Merge branch 'rust-lang:main' into EE/tvOS_Support
Browse files Browse the repository at this point in the history
  • Loading branch information
ErikEverson authored Feb 16, 2024
2 parents f3b1afd + 8bed330 commit 9b86e3f
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 84 deletions.
11 changes: 10 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
build: [stable, beta, nightly, linux32, macos, aarch64-ios, win32, win64, mingw32, mingw64, windows-2019]
build: [stable, beta, nightly, linux32, macos, aarch64-macos, aarch64-ios, win32, win64, mingw32, mingw64, windows-2019]
include:
- build: stable
os: ubuntu-latest
Expand All @@ -33,6 +33,10 @@ jobs:
os: macos-latest
rust: stable
target: x86_64-apple-darwin
- build: aarch64-macos
os: macos-14
rust: stable
target: aarch64-apple-darwin
- build: aarch64-ios
os: macos-latest
rust: stable
Expand Down Expand Up @@ -86,6 +90,7 @@ jobs:
sudo apt-get update
sudo apt-get install g++-multilib
if: matrix.build == 'linux32'
- uses: Swatinem/rust-cache@v2
- run: cargo test ${{ matrix.no_run }} --workspace --target ${{ matrix.target }}
- run: cargo test ${{ matrix.no_run }} --workspace --target ${{ matrix.target }} --release
- run: cargo test ${{ matrix.no_run }} --workspace --target ${{ matrix.target }} --features parallel
Expand All @@ -103,6 +108,7 @@ jobs:
rustup component add rust-src --toolchain nightly
rustup default nightly
shell: bash
- uses: Swatinem/rust-cache@v2
- run: cargo test -Z build-std=std --no-run --workspace --target aarch64-apple-tvos
- run: cargo test -Z build-std=std --no-run --workspace --target aarch64-apple-tvos --release
- run: cargo test -Z build-std=std --no-run --workspace --target aarch64-apple-tvos --features parallel
Expand All @@ -120,6 +126,7 @@ jobs:
sudo dpkg -i cuda-keyring_1.0-1_all.deb
sudo apt-get update
sudo apt-get -y install cuda-minimal-build-11-8
- uses: Swatinem/rust-cache@v2
- name: Test 'cudart' feature
shell: bash
run: |
Expand Down Expand Up @@ -157,6 +164,7 @@ jobs:
rustup toolchain install stable --no-self-update --profile minimal --component rustfmt
rustup default stable
shell: bash
- uses: Swatinem/rust-cache@v2
- run: cargo clippy

rustfmt:
Expand All @@ -169,4 +177,5 @@ jobs:
rustup toolchain install stable --no-self-update --profile minimal --component rustfmt
rustup default stable
shell: bash
- uses: Swatinem/rust-cache@v2
- run: cargo fmt -- --check
3 changes: 2 additions & 1 deletion src/command_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,8 @@ impl StderrForwarder {
pub(crate) fn set_non_blocking(&mut self) -> Result<(), Error> {
assert!(!self.is_non_blocking);

if let Some((stderr, _)) = self.inner.as_mut() {
#[cfg(unix)]
if let Some((stderr, _)) = self.inner.as_ref() {
crate::parallel::stderr::set_non_blocking(stderr)?;
}

Expand Down
41 changes: 35 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ pub struct Build {
apple_sdk_root_cache: Arc<Mutex<HashMap<String, OsString>>>,
apple_versions_cache: Arc<Mutex<HashMap<String, String>>>,
emit_rerun_if_env_changed: bool,
cached_compiler_family: Arc<Mutex<HashMap<Box<Path>, ToolFamily>>>,
}

/// Represents the types of errors that may occur while using cc-rs.
Expand Down Expand Up @@ -406,6 +407,7 @@ impl Build {
apple_sdk_root_cache: Arc::new(Mutex::new(HashMap::new())),
apple_versions_cache: Arc::new(Mutex::new(HashMap::new())),
emit_rerun_if_env_changed: true,
cached_compiler_family: Arc::default(),
}
}

Expand Down Expand Up @@ -2588,7 +2590,11 @@ impl Build {

fn get_base_compiler(&self) -> Result<Tool, Error> {
if let Some(c) = &self.compiler {
return Ok(Tool::new((**c).to_owned(), &self.cargo_output));
return Ok(Tool::new(
(**c).to_owned(),
&self.cached_compiler_family,
&self.cargo_output,
));
}
let host = self.get_host()?;
let target = self.get_target()?;
Expand Down Expand Up @@ -2624,7 +2630,12 @@ impl Build {
// semi-buggy build scripts which are shared in
// makefiles/configure scripts (where spaces are far more
// lenient)
let mut t = Tool::with_clang_driver(tool, driver_mode, &self.cargo_output);
let mut t = Tool::with_clang_driver(
tool,
driver_mode,
&self.cached_compiler_family,
&self.cargo_output,
);
if let Some(cc_wrapper) = wrapper {
t.cc_wrapper_path = Some(PathBuf::from(cc_wrapper));
}
Expand All @@ -2638,12 +2649,20 @@ impl Build {
let tool = if self.cpp { "em++" } else { "emcc" };
// Windows uses bat file so we have to be a bit more specific
if cfg!(windows) {
let mut t = Tool::new(PathBuf::from("cmd"), &self.cargo_output);
let mut t = Tool::new(
PathBuf::from("cmd"),
&self.cached_compiler_family,
&self.cargo_output,
);
t.args.push("/c".into());
t.args.push(format!("{}.bat", tool).into());
Some(t)
} else {
Some(Tool::new(PathBuf::from(tool), &self.cargo_output))
Some(Tool::new(
PathBuf::from(tool),
&self.cached_compiler_family,
&self.cargo_output,
))
}
} else {
None
Expand Down Expand Up @@ -2698,7 +2717,11 @@ impl Build {
default.to_string()
};

let mut t = Tool::new(PathBuf::from(compiler), &self.cargo_output);
let mut t = Tool::new(
PathBuf::from(compiler),
&self.cached_compiler_family,
&self.cargo_output,
);
if let Some(cc_wrapper) = Self::rustc_wrapper_fallback() {
t.cc_wrapper_path = Some(PathBuf::from(cc_wrapper));
}
Expand All @@ -2715,7 +2738,13 @@ impl Build {
Err(_) => PathBuf::from("nvcc"),
Ok(nvcc) => PathBuf::from(&*nvcc),
};
let mut nvcc_tool = Tool::with_features(nvcc, None, self.cuda, &self.cargo_output);
let mut nvcc_tool = Tool::with_features(
nvcc,
None,
self.cuda,
&self.cached_compiler_family,
&self.cargo_output,
);
nvcc_tool
.args
.push(format!("-ccbin={}", tool.path.display()).into());
Expand Down
28 changes: 26 additions & 2 deletions src/parallel/job_token/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,33 @@ mod inherited_jobserver {
.or_else(|| var_os("MAKEFLAGS"))
.or_else(|| var_os("MFLAGS"))?;

let inner = sys::JobServerClient::open(var)?;
#[cfg(unix)]
let var = std::os::unix::ffi::OsStrExt::as_bytes(var.as_os_str());
#[cfg(not(unix))]
let var = var.to_str()?.as_bytes();

Some(Self {
let makeflags = var.split(u8::is_ascii_whitespace);

// `--jobserver-auth=` is the only documented makeflags.
// `--jobserver-fds=` is actually an internal only makeflags, so we should
// always prefer `--jobserver-auth=`.
//
// Also, according to doc of makeflags, if there are multiple `--jobserver-auth=`
// the last one is used
if let Some(flag) = makeflags
.clone()
.filter_map(|s| s.strip_prefix(b"--jobserver-auth="))
.last()
{
sys::JobServerClient::open(flag)
} else {
sys::JobServerClient::open(
makeflags
.filter_map(|s| s.strip_prefix(b"--jobserver-fds="))
.last()?,
)
}
.map(|inner| Self {
inner,
global_implicit_token: AtomicBool::new(true),
})
Expand Down
46 changes: 10 additions & 36 deletions src/parallel/job_token/unix.rs
Original file line number Diff line number Diff line change
@@ -1,39 +1,28 @@
use std::{
ffi::{OsStr, OsString},
ffi::OsStr,
fs::{self, File},
io::{self, Read, Write},
mem::ManuallyDrop,
os::{
raw::c_int,
unix::{
ffi::{OsStrExt, OsStringExt},
prelude::*,
},
unix::{ffi::OsStrExt, prelude::*},
},
path::Path,
};

use crate::parallel::stderr::set_non_blocking;

pub(super) struct JobServerClient {
read: File,
write: Option<File>,
}

impl JobServerClient {
pub(super) unsafe fn open(var: OsString) -> Option<Self> {
let bytes = var.into_vec();

let s = bytes
.split(u8::is_ascii_whitespace)
.filter_map(|arg| {
arg.strip_prefix(b"--jobserver-fds=")
.or_else(|| arg.strip_prefix(b"--jobserver-auth="))
})
.find(|bytes| !bytes.is_empty())?;

if let Some(fifo) = s.strip_prefix(b"fifo:") {
pub(super) unsafe fn open(var: &[u8]) -> Option<Self> {
if let Some(fifo) = var.strip_prefix(b"fifo:") {
Self::from_fifo(Path::new(OsStr::from_bytes(fifo)))
} else {
Self::from_pipe(OsStr::from_bytes(s).to_str()?)
Self::from_pipe(OsStr::from_bytes(var).to_str()?)
}
}

Expand All @@ -48,7 +37,7 @@ impl JobServerClient {
if is_pipe(&file)? {
// File in Rust is always closed-on-exec as long as it's opened by
// `File::open` or `fs::OpenOptions::open`.
set_nonblocking(&file)?;
set_non_blocking(&file).ok()?;

Some(Self {
read: file,
Expand Down Expand Up @@ -92,8 +81,8 @@ impl JobServerClient {
let write = write.try_clone().ok()?;

// Set read and write end to nonblocking
set_nonblocking(&read)?;
set_nonblocking(&write)?;
set_non_blocking(&read).ok()?;
set_non_blocking(&write).ok()?;

Some(Self {
read,
Expand Down Expand Up @@ -148,21 +137,6 @@ impl JobServerClient {
}
}

fn set_nonblocking(file: &File) -> Option<()> {
// F_SETFL can only set the O_APPEND, O_ASYNC, O_DIRECT, O_NOATIME, and
// O_NONBLOCK flags.
//
// For pipe, only O_NONBLOCK is meaningful, so it is ok to
// not issue a F_GETFL fcntl syscall.
let ret = unsafe { libc::fcntl(file.as_raw_fd(), libc::F_SETFL, libc::O_NONBLOCK) };

if ret == -1 {
None
} else {
Some(())
}
}

fn cvt(t: c_int) -> io::Result<c_int> {
if t == -1 {
Err(io::Error::last_os_error())
Expand Down
16 changes: 4 additions & 12 deletions src/parallel/job_token/windows.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
use std::{
ffi::{CString, OsString},
io, ptr,
};
use std::{ffi::CString, io, ptr, str};

use crate::windows::windows_sys::{
OpenSemaphoreA, ReleaseSemaphore, WaitForSingleObject, FALSE, HANDLE, SEMAPHORE_MODIFY_STATE,
Expand All @@ -16,8 +13,8 @@ unsafe impl Sync for JobServerClient {}
unsafe impl Send for JobServerClient {}

impl JobServerClient {
pub(super) unsafe fn open(var: OsString) -> Option<Self> {
let var = var.to_str()?;
pub(super) unsafe fn open(var: &[u8]) -> Option<Self> {
let var = str::from_utf8(var).ok()?;
if !var.is_ascii() {
// `OpenSemaphoreA` only accepts ASCII, not utf-8.
//
Expand All @@ -29,12 +26,7 @@ impl JobServerClient {
return None;
}

let s = var
.split_ascii_whitespace()
.filter_map(|arg| arg.strip_prefix("--jobserver-auth="))
.find(|s| !s.is_empty())?;

let name = CString::new(s).ok()?;
let name = CString::new(var).ok()?;

let sem = OpenSemaphoreA(
THREAD_SYNCHRONIZE | SEMAPHORE_MODIFY_STATE,
Expand Down
43 changes: 23 additions & 20 deletions src/parallel/stderr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,32 @@ use crate::{Error, ErrorKind};
#[cfg(all(not(unix), not(windows)))]
compile_error!("Only unix and windows support non-blocking pipes! For other OSes, disable the parallel feature.");

#[allow(unused_variables)]
pub fn set_non_blocking(stderr: &mut ChildStderr) -> Result<(), Error> {
#[cfg(unix)]
pub fn set_non_blocking(pipe: &impl std::os::unix::io::AsRawFd) -> Result<(), Error> {
// On Unix, switch the pipe to non-blocking mode.
// On Windows, we have a different way to be non-blocking.
#[cfg(unix)]
{
use std::os::unix::io::AsRawFd;
let fd = stderr.as_raw_fd();
debug_assert_eq!(
unsafe { libc::fcntl(fd, libc::F_GETFL, 0) },
0,
"stderr should have no flags set"
);
let fd = pipe.as_raw_fd();
let flags = unsafe { libc::fcntl(fd, libc::F_GETFL, 0) };
if flags == -1 {
return Err(Error::new(
ErrorKind::IOError,
format!(
"Failed to get flags for pipe {}: {}",
fd,
std::io::Error::last_os_error()
),
));
}

if unsafe { libc::fcntl(fd, libc::F_SETFL, libc::O_NONBLOCK) } != 0 {
return Err(Error::new(
ErrorKind::IOError,
format!(
"Failed to set flags for child stderr: {}",
std::io::Error::last_os_error()
),
));
}
if unsafe { libc::fcntl(fd, libc::F_SETFL, flags | libc::O_NONBLOCK) } == -1 {
return Err(Error::new(
ErrorKind::IOError,
format!(
"Failed to set flags for pipe {}: {}",
fd,
std::io::Error::last_os_error()
),
));
}

Ok(())
Expand Down
Loading

0 comments on commit 9b86e3f

Please sign in to comment.