Skip to content

Commit 90c8cd0

Browse files
committed
link clang_rt profile
1 parent b92a41c commit 90c8cd0

File tree

3 files changed

+42
-10
lines changed

3 files changed

+42
-10
lines changed

src/bootstrap/compile.rs

+33-5
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use crate::config::{LlvmLibunwind, RustcLto, TargetSelection};
2727
use crate::dist;
2828
use crate::llvm;
2929
use crate::tool::SourceType;
30-
use crate::util::get_clang_cl_resource_dir;
30+
use crate::util::get_clang_rt_dir;
3131
use crate::util::{exe, is_debug_info, is_dylib, output, symlink_dir, t, up_to_date};
3232
use crate::LLVM_TOOLS;
3333
use crate::{CLang, Compiler, DependencyType, GitRepo, Mode};
@@ -923,10 +923,38 @@ fn rustc_llvm_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetSelect
923923
// found. This is to avoid the linker errors about undefined references to
924924
// `__llvm_profile_instrument_memop` when linking `rustc_driver`.
925925
let mut llvm_linker_flags = String::new();
926-
if builder.config.llvm_profile_generate && target.contains("msvc") {
927-
if let Some(ref clang_cl_path) = builder.config.llvm_clang_cl {
928-
// Add clang's runtime library directory to the search path
929-
let clang_rt_dir = get_clang_cl_resource_dir(clang_cl_path);
926+
if builder.config.llvm_profile_generate {
927+
if target.contains("msvc") {
928+
if let Some(ref clang_cl_path) = builder.config.llvm_clang_cl {
929+
// Add clang's runtime library directory to the search path
930+
let clang_rt_dir = get_clang_rt_dir(clang_cl_path, true);
931+
llvm_linker_flags.push_str(&format!("-L{}", clang_rt_dir.display()));
932+
}
933+
}
934+
935+
if target.contains("apple") {
936+
let clang_rt_profile_lib_suffix = if target.ends_with("ios-sim") {
937+
"iossim"
938+
} else if target.ends_with("ios") {
939+
"ios"
940+
} else if target.ends_with("tvos-sim") {
941+
"tvossim"
942+
} else if target.ends_with("tvos") {
943+
"tvos"
944+
} else if target.ends_with("darwin") {
945+
"osx"
946+
} else if target.ends_with("watchos-sim") {
947+
"watchossim"
948+
} else if target.ends_with("watchos") {
949+
"watchos"
950+
} else {
951+
panic!("clang has no clang_rt.profile library for {target}");
952+
};
953+
let clang = builder.cc(target);
954+
let clang_rt_dir = get_clang_rt_dir(clang, false);
955+
let clang_rt_profile_lib = format!("libclang_rt.profile_{clang_rt_profile_lib_suffix}");
956+
llvm_linker_flags.push_str(&format!("-l{clang_rt_profile_lib}"));
957+
llvm_linker_flags.push_str(" ");
930958
llvm_linker_flags.push_str(&format!("-L{}", clang_rt_dir.display()));
931959
}
932960
}

src/bootstrap/llvm.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use std::process::Command;
1919
use crate::builder::{Builder, RunConfig, ShouldRun, Step};
2020
use crate::channel;
2121
use crate::config::{Config, TargetSelection};
22-
use crate::util::get_clang_cl_resource_dir;
22+
use crate::util::get_clang_rt_dir;
2323
use crate::util::{self, exe, output, t, up_to_date};
2424
use crate::{CLang, GitRepo};
2525

@@ -828,7 +828,7 @@ impl Step for Lld {
828828
if let Some(clang_cl_path) = builder.config.llvm_clang_cl.as_ref() {
829829
// Find clang's runtime library directory and push that as a search path to the
830830
// cmake linker flags.
831-
let clang_rt_dir = get_clang_cl_resource_dir(clang_cl_path);
831+
let clang_rt_dir = get_clang_rt_dir(clang_cl_path);
832832
ldflags.push_all(&format!("/libpath:{}", clang_rt_dir.display()));
833833
}
834834
}

src/bootstrap/util.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -493,11 +493,15 @@ fn absolute_windows(path: &std::path::Path) -> std::io::Result<std::path::PathBu
493493
/// When `clang-cl` is used with instrumentation, we need to add clang's runtime library resource
494494
/// directory to the linker flags, otherwise there will be linker errors about the profiler runtime
495495
/// missing. This function returns the path to that directory.
496-
pub fn get_clang_cl_resource_dir(clang_cl_path: &str) -> PathBuf {
496+
pub fn get_clang_rt_dir(clang: impl AsRef<Path>, is_msvc: bool) -> PathBuf {
497497
// Similar to how LLVM does it, to find clang's library runtime directory:
498498
// - we ask `clang-cl` to locate the `clang_rt.builtins` lib.
499-
let mut builtins_locator = Command::new(clang_cl_path);
500-
builtins_locator.args(&["/clang:-print-libgcc-file-name", "/clang:--rtlib=compiler-rt"]);
499+
let mut builtins_locator = Command::new(clang.as_ref());
500+
if is_msvc {
501+
builtins_locator.args(&["/clang:-print-libgcc-file-name", "/clang:--rtlib=compiler-rt"]);
502+
} else {
503+
builtins_locator.args(&["-print-libgcc-file-name", "-rtlib=compiler-rt"]);
504+
};
501505

502506
let clang_rt_builtins = output(&mut builtins_locator);
503507
let clang_rt_builtins = Path::new(clang_rt_builtins.trim());

0 commit comments

Comments
 (0)