Skip to content

Commit

Permalink
refactor: reduce code duplication
Browse files Browse the repository at this point in the history
  • Loading branch information
messense committed Dec 22, 2024
1 parent d3e6db4 commit d67035d
Show file tree
Hide file tree
Showing 9 changed files with 240 additions and 237 deletions.
67 changes: 11 additions & 56 deletions src/compiler/clang.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ use fs_err as fs;
use path_slash::PathExt;
use serde::Deserialize;

use crate::common::{
use crate::compiler::common::{
adjust_canonicalization, default_build_target_from_config, get_rustflags, http_agent,
symlink_llvm_tool, XWinOptions,
setup_cmake_env, setup_compiler_env, setup_llvm_tools, setup_macos_llvm_paths,
setup_target_env,
};
use crate::options::XWinOptions;

const MSVC_SYSROOT_REPOSITORY: &str = "trcrsired/windows-msvc-sysroot";
const MSVC_SYSROOT_ASSET_NAME: &str = "windows-msvc-sysroot.tar.xz";
Expand All @@ -32,27 +34,7 @@ impl<'a> Clang<'a> {
cargo: &cargo_options::CommonOptions,
cmd: &mut Command,
) -> Result<()> {
let cache_dir = self.xwin_options.xwin_cache_dir.clone().unwrap_or_else(|| {
dirs::cache_dir()
// If the really is no cache dir, cwd will also do
.unwrap_or_else(|| env::current_dir().expect("Failed to get current dir"))
.join(env!("CARGO_PKG_NAME"))
});
fs::create_dir_all(&cache_dir)?;
let cache_dir = cache_dir.canonicalize()?;

let env_path = env::var("PATH").unwrap_or_default();
let mut env_paths: Vec<_> = env::split_paths(&env_path).collect();

let env_path = if cfg!(target_os = "macos") {
let mut new_path = env_path;
new_path.push_str(":/opt/homebrew/opt/llvm/bin");
new_path.push_str(":/usr/local/opt/llvm/bin");
new_path
} else {
env_path
};
env_paths.push(cache_dir.clone());
let mut compiler_env = setup_compiler_env(self.xwin_options.xwin_cache_dir.clone())?;

let workdir = manifest_path
.and_then(|p| p.parent().map(|x| x.to_path_buf()))
Expand All @@ -70,26 +52,14 @@ impl<'a> Clang<'a> {

for target in &targets {
if target.contains("msvc") {
let msvc_sysroot_dir = self.setup_msvc_sysroot(cache_dir.clone())?;
let msvc_sysroot_dir = self.setup_msvc_sysroot(compiler_env.cache_dir.clone())?;
// x86_64-pc-windows-msvc -> x86_64-windows-msvc
let target_no_vendor = target.replace("-pc-", "-");
let target_unknown_vendor = target.replace("-pc-", "-unknown-");
let env_target = target.to_lowercase().replace('-', "_");

symlink_llvm_tool("rust-lld", "lld-link", env_path.clone(), &cache_dir)?;
symlink_llvm_tool("llvm-ar", "llvm-lib", env_path.clone(), &cache_dir)?;
symlink_llvm_tool("llvm-ar", "llvm-dlltool", env_path.clone(), &cache_dir)?;

cmd.env("TARGET_CC", "clang");
cmd.env("TARGET_CXX", "clang++");
cmd.env(format!("CC_{}", env_target), "clang");
cmd.env(format!("CXX_{}", env_target), "clang++");
cmd.env("TARGET_AR", "llvm-lib");
cmd.env(format!("AR_{}", env_target), "llvm-lib");
cmd.env(
format!("CARGO_TARGET_{}_LINKER", env_target.to_uppercase()),
"lld-link",
);
setup_llvm_tools(&compiler_env.env_path, &compiler_env.cache_dir)?;
setup_target_env(cmd, &env_target, "clang")?;

let user_set_c_flags = env::var("CFLAGS").unwrap_or_default();
let user_set_cxx_flags = env::var("CXXFLAGS").unwrap_or_default();
Expand Down Expand Up @@ -126,27 +96,12 @@ impl<'a> Clang<'a> {
));
cmd.env("CARGO_ENCODED_RUSTFLAGS", rustflags.encode()?);

#[cfg(target_os = "macos")]
{
let usr_llvm = "/usr/local/opt/llvm/bin".into();
let opt_llvm = "/opt/homebrew/opt/llvm/bin".into();
if cfg!(target_arch = "x86_64") && !env_paths.contains(&usr_llvm) {
env_paths.push(usr_llvm);
} else if cfg!(target_arch = "aarch64") && !env_paths.contains(&opt_llvm) {
env_paths.push(opt_llvm);
}
}

cmd.env("PATH", env::join_paths(env_paths.clone())?);
setup_macos_llvm_paths(&mut compiler_env.env_paths);
cmd.env("PATH", env::join_paths(compiler_env.env_paths.clone())?);

// CMake support
let cmake_toolchain = self.setup_cmake_toolchain(target, &sysroot_dir)?;
cmd.env("CMAKE_GENERATOR", "Ninja")
.env("CMAKE_SYSTEM_NAME", "Windows")
.env(
format!("CMAKE_TOOLCHAIN_FILE_{}", env_target),
cmake_toolchain,
);
setup_cmake_env(cmd, target, cmake_toolchain)?;
}
}
Ok(())
Expand Down
84 changes: 12 additions & 72 deletions src/compiler/clang_cl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ use anyhow::{Context, Result};
use fs_err as fs;
use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
use path_slash::PathExt;
use which::{which, which_in};
use xwin::util::ProgressTarget;

use crate::common::{
use crate::compiler::common::{
adjust_canonicalization, default_build_target_from_config, get_rustflags, http_agent,
symlink_llvm_tool, XWinOptions,
setup_clang_symlink, setup_cmake_env, setup_compiler_env, setup_llvm_tools,
setup_macos_llvm_paths, setup_target_env,
};
use crate::options::XWinOptions;

#[derive(Debug)]
pub struct ClangCl<'a> {
Expand All @@ -38,27 +39,15 @@ impl<'a> ClangCl<'a> {
.clone()
.unwrap_or_else(|| {
dirs::cache_dir()
// If the really is no cache dir, cwd will also do
.unwrap_or_else(|| env::current_dir().expect("Failed to get current dir"))
.join(env!("CARGO_PKG_NAME"))
})
.join("xwin");
fs::create_dir_all(&xwin_cache_dir)?;
let xwin_cache_dir = xwin_cache_dir.canonicalize()?;

let env_path = env::var("PATH").unwrap_or_default();
let mut env_paths: Vec<_> = env::split_paths(&env_path).collect();

let env_path = if cfg!(target_os = "macos") {
let mut new_path = env_path;
new_path.push_str(":/opt/homebrew/opt/llvm/bin");
new_path.push_str(":/usr/local/opt/llvm/bin");
new_path
} else {
env_path
};
let cache_dir = xwin_cache_dir.parent().unwrap();
env_paths.push(cache_dir.to_path_buf());
let mut compiler_env =
setup_compiler_env(Some(xwin_cache_dir.parent().unwrap().to_path_buf()))?;

let workdir = manifest_path
.and_then(|p| p.parent().map(|x| x.to_path_buf()))
Expand All @@ -79,42 +68,9 @@ impl<'a> ClangCl<'a> {
self.setup_msvc_crt(xwin_cache_dir.clone())?;
let env_target = target.to_lowercase().replace('-', "_");

if which_in("clang-cl", Some(env_path.clone()), env::current_dir()?).is_err() {
if let Ok(clang) = which("clang") {
#[cfg(windows)]
{
let symlink = cache_dir.join("clang-cl.exe");
if symlink.exists() {
fs::remove_file(&symlink)?;
}
std::os::windows::fs::symlink_file(clang, symlink)?;
}

#[cfg(unix)]
{
let symlink = cache_dir.join("clang-cl");
if symlink.exists() {
fs::remove_file(&symlink)?;
}
std::os::unix::fs::symlink(clang, symlink)?;
}
}
}
symlink_llvm_tool("rust-lld", "lld-link", env_path.clone(), cache_dir)?;
symlink_llvm_tool("llvm-ar", "llvm-lib", env_path.clone(), cache_dir)?;
symlink_llvm_tool("llvm-ar", "llvm-dlltool", env_path.clone(), cache_dir)?;

cmd.env("TARGET_CC", "clang-cl");
cmd.env("TARGET_CXX", "clang-cl");
cmd.env(format!("CC_{}", env_target), "clang-cl");
cmd.env(format!("CXX_{}", env_target), "clang-cl");
cmd.env("TARGET_AR", "llvm-lib");
cmd.env(format!("AR_{}", env_target), "llvm-lib");

cmd.env(
format!("CARGO_TARGET_{}_LINKER", env_target.to_uppercase()),
"lld-link",
);
setup_clang_symlink(&compiler_env.cache_dir)?;
setup_llvm_tools(&compiler_env.env_path, &compiler_env.cache_dir)?;
setup_target_env(cmd, &env_target, "clang-cl")?;

let user_set_cl_flags = env::var("CL_FLAGS").unwrap_or_default();
let user_set_c_flags = env::var("CFLAGS").unwrap_or_default();
Expand Down Expand Up @@ -181,27 +137,12 @@ impl<'a> ClangCl<'a> {
));
cmd.env("CARGO_ENCODED_RUSTFLAGS", rustflags.encode()?);

#[cfg(target_os = "macos")]
{
let usr_llvm = "/usr/local/opt/llvm/bin".into();
let opt_llvm = "/opt/homebrew/opt/llvm/bin".into();
if cfg!(target_arch = "x86_64") && !env_paths.contains(&usr_llvm) {
env_paths.push(usr_llvm);
} else if cfg!(target_arch = "aarch64") && !env_paths.contains(&opt_llvm) {
env_paths.push(opt_llvm);
}
}

cmd.env("PATH", env::join_paths(env_paths.clone())?);
setup_macos_llvm_paths(&mut compiler_env.env_paths);
cmd.env("PATH", env::join_paths(compiler_env.env_paths.clone())?);

// CMake support
let cmake_toolchain = self.setup_cmake_toolchain(target, &xwin_cache_dir)?;
cmd.env("CMAKE_GENERATOR", "Ninja")
.env("CMAKE_SYSTEM_NAME", "Windows")
.env(
format!("CMAKE_TOOLCHAIN_FILE_{}", env_target),
cmake_toolchain,
);
setup_cmake_env(cmd, target, cmake_toolchain)?;
}
}
Ok(())
Expand Down Expand Up @@ -379,7 +320,6 @@ impl<'a> ClangCl<'a> {
.clone()
.unwrap_or_else(|| {
dirs::cache_dir()
// If the really is no cache dir, cwd will also do
.unwrap_or_else(|| env::current_dir().expect("Failed to get current dir"))
.join(env!("CARGO_PKG_NAME"))
})
Expand Down
Loading

0 comments on commit d67035d

Please sign in to comment.