From a6d4da44543b802456daa06162b7686466e38da5 Mon Sep 17 00:00:00 2001 From: Laurence Tratt Date: Thu, 11 May 2023 16:26:37 +0100 Subject: [PATCH] Build ykllvm in `target//ykllvm`. Previously we tried building ykllvm in `OUT_DIR` but, unfortunately, that means when testing we can't access the Cargo variable we defined in https://github.com/rust-lang/cargo/issues/10927. Previously, things accidentally worked because we also required PATH to be set to `/path/to/ykllvm/bin`, but that means you could pick up unexpected versions of clang/clang++, for example. This commit rethinks things. It builds a copy of ykllvm in `target//ykllvm`. [Technically this breaks Cargo's rules, but since we're having to worm around a Cargo restriction, I think we can deal with this: if Cargo's rules change in the future, we can change the location easily enough.] `yk-config` gains `--cc` and `--cxx` flags which give the user the path to the C/C++ compiler. I've tried to keep this commit as minimal as possible: it would certainly be possible to do various bits of cleaning-up at the same time, but I think that would obscure what we're most interested in. --- .buildbot.sh | 60 +++++++++++++++++++-------------- docs/src/dev/env.md | 19 +++++++---- hwtracer/build.rs | 6 +++- tests/benches/bench.rs | 3 +- tests/langtest_c.rs | 11 ++++-- tests/langtest_hwtracer_ykpt.rs | 7 ++-- tests/src/bin/gdb_c_test.rs | 10 +++++- tests/src/lib.rs | 26 +++++++++----- ykbuild/build.rs | 38 ++++++++++++++------- ykbuild/src/ccgen.rs | 2 +- ykbuild/src/lib.rs | 58 +++++++++++++++++++++++++++---- ykbuild/wrap-clang++.sh | 7 ++-- ykbuild/wrap-clang.sh | 5 ++- ykcapi/scripts/yk-config | 13 +++++-- ykllvmwrap/build.rs | 26 +++++++++++--- yksmp/tests/Makefile | 9 ++--- 16 files changed, 212 insertions(+), 88 deletions(-) diff --git a/.buildbot.sh b/.buildbot.sh index 3af8c7685..346678fa3 100644 --- a/.buildbot.sh +++ b/.buildbot.sh @@ -16,14 +16,6 @@ export PATH=${CARGO_HOME}/bin/:$PATH rustup toolchain install nightly --allow-downgrade --component rustfmt -# There are some feature-gated testing/debugging switches which slow the JIT -# down a bit. Check that if we build the system without tests, those features -# are not enabled. -for mode in "" "--release"; do \ - cargo -Z unstable-options build ${mode} --build-plan -p ykcapi | \ - awk '/yk_testing/ { ec=1 } /yk_jitstate_debug/ { ec=1 } END {exit ec}'; \ -done - cargo fmt --all -- --check # Check licenses. @@ -37,11 +29,13 @@ mdbook build test -d book cd .. -# Build LLVM for the C tests. -cd ykllvm -mkdir build -cd build - +# We could let yk build two copies of LLVM, but we also want to: check that +# YKB_YKLLVM_BIN_DIR works; and we want access to clang-format from a build +# of LLVM. So we first build our own LLVM-with-assertions, use the +# YKB_YKLLVM_BIN_DIR variable to have yk use that, and use its +# clang-format. +mkdir -p ykllvm/build +cd ykllvm/build # Due to an LLVM bug, PIE breaks our mapper, and it's not enough to pass # `-fno-pie` to clang for some reason: # https://github.com/llvm/llvm-project/issues/57085 @@ -56,33 +50,47 @@ cmake -DCMAKE_INSTALL_PREFIX=`pwd`/../inst \ ../llvm cmake --build . cmake --install . -export PATH=`pwd`/../inst/bin:${PATH} +export YKB_YKLLVM_BIN_DIR=`pwd`/../inst/bin cd ../../ # Check that clang-format is installed. -clang-format --version +PATH=${YKB_YKLLVM_BIN_DIR}:${PATH} clang-format --version # Check C/C++ formatting using xtask. -cargo xtask cfmt - +PATH=${YKB_YKLLVM_BIN_DIR}:${PATH} cargo xtask cfmt # This is used to check clang-tidy output, but the dirty submodule from building # ykllvm is also shown. # FIXME: Add build/ to .gitignore in ykllvm git diff --exit-code --ignore-submodules -# Check that building `ykcapi` in isolation works. This is what we'd be doing -# if we were building release binaries, as it would mean we get a system -# without the (slower) `yk_testing` and `yk_jitstate_debug` features enabled. -for mode in "" "--release"; do - cargo build ${mode} -p ykcapi; -done +# There are some feature-gated testing/debugging switches which slow the JIT +# down a bit. Check that if we build the system without tests, those features +# are not enabled. +cargo -Z unstable-options build --build-plan -p ykcapi | \ + awk '/yk_testing/ { ec=1 } /yk_jitstate_debug/ { ec=1 } END {exit ec}' for i in $(seq 10); do cargo test - cargo test --release done -cargo bench - # Run examples. cargo run --example hwtracer_example + + +# We now want to test building with `--release`, which we also take as an +# opportunity to check that yk can build ykllvm, which requires unsetting +# YKB_YKLLVM_BIN_DIR. In essence, we now repeat much of what we did above but +# with `--release`. +unset YKB_YKLLVM_BIN_DIR + +cargo -Z unstable-options build --release --build-plan -p ykcapi | \ + awk '/yk_testing/ { ec=1 } /yk_jitstate_debug/ { ec=1 } END {exit ec}' + +cargo build --release -p ykcapi + +for i in $(seq 10); do + cargo test --release +done + cargo run --release --example hwtracer_example + +cargo bench diff --git a/docs/src/dev/env.md b/docs/src/dev/env.md index a00236fcb..d64debd8b 100644 --- a/docs/src/dev/env.md +++ b/docs/src/dev/env.md @@ -17,12 +17,19 @@ build *without* the feature enabled, do `cargo build -p ykcapi`). ### `YKB_YKLLVM_BIN_DIR` -Under normal circumstances, yk builds a copy of its LLVM fork "ykllvm" and uses -it to build interpreters. You can use your own ykllvm build by specifying the -directory where the executables (e.g. `clang`, `llvm-config`, and so on) are -stored with `YKB_YKLLVM_BIN_DIR`. yk does not check your installation for -compatibility: it is your responsibility to ensure that your ykllvm build -matches that expected by yk. +Under normal circumstances, yk builds a copy of its LLVM fork "ykllvm", which +it also uses it to build interpreters (via the compiler's use of `yk-config`). +You can use your own ykllvm build by specifying the directory where the +executables (e.g. `clang`, `llvm-config`, and so on) are stored with +`YKB_YKLLVM_BIN_DIR`. + +yk does not check your installation for compatibility: it is your +responsibility to ensure that your ykllvm build matches that expected by yk. + +It is also undefined behaviour to move between defining this variable and not +within a repository using `yk` (including the `yk` repository itself). If you +want to set/unset `YKB_YKLLVM_BIN_DIR` then `cargo clean` any repositories +using `yk` before rebuilding them. ## Run-time Variables diff --git a/hwtracer/build.rs b/hwtracer/build.rs index 5dde0c47a..966817a00 100644 --- a/hwtracer/build.rs +++ b/hwtracer/build.rs @@ -7,7 +7,10 @@ use std::fs; use std::os::unix::fs as unix_fs; use std::path::{Path, PathBuf}; use std::process::Command; -use ykbuild::ccgen::{CCGenerator, CCLang}; +use ykbuild::{ + ccgen::{CCGenerator, CCLang}, + ykllvm_bin, +}; const FEATURE_CHECKS_PATH: &str = "feature_checks"; @@ -101,6 +104,7 @@ fn main() { // Generate a `compile_commands.json` database for clangd. let ccg = CCGenerator::new("hwtracer", &env::var("CARGO_MANIFEST_DIR").unwrap()); env::set_var.call(ccg.build_env()); + env::set_var("YK_COMPILER_PATH", ykllvm_bin("clang")); c_build.compiler(CCLang::C.compiler_wrapper()); let c_deps_dir = make_c_deps_dir(); diff --git a/tests/benches/bench.rs b/tests/benches/bench.rs index fd41874ea..93b9a47ce 100644 --- a/tests/benches/bench.rs +++ b/tests/benches/bench.rs @@ -13,6 +13,7 @@ use std::{ }; use tempfile::TempDir; use tests::mk_compiler; +use ykbuild::ykllvm_bin; const SAMPLE_SIZE: usize = 50; const MEASUREMENT_TIME: Duration = Duration::from_secs(30); @@ -27,7 +28,7 @@ fn compile_runner(tempdir: &TempDir) -> PathBuf { exe.push(tempdir); exe.push(src.file_stem().unwrap()); - let mut compiler = mk_compiler("clang", &exe, &src, "-O0", &[], false); + let mut compiler = mk_compiler(ykllvm_bin("clang"), &exe, &src, "-O0", &[], false); compiler.arg("-ltests"); let out = compiler.output().unwrap(); check_output(&out); diff --git a/tests/langtest_c.rs b/tests/langtest_c.rs index c449b34fc..7bc00462d 100644 --- a/tests/langtest_c.rs +++ b/tests/langtest_c.rs @@ -11,7 +11,10 @@ use std::{ }; use tempfile::TempDir; use tests::{mk_compiler, EXTRA_LINK}; -use ykbuild::ccgen::{CCGenerator, CCLang}; +use ykbuild::{ + ccgen::{CCGenerator, CCLang}, + ykllvm_bin, +}; const COMMENT: &str = "//"; @@ -50,6 +53,7 @@ fn run_suite(opt: &'static str, force_decoder: &'static str) { // Generate a `compile_commands.json` database for clangd. let ccg = CCGenerator::new("c_tests", &env::var("CARGO_MANIFEST_DIR").unwrap()); env::set_var.call(ccg.build_env()); + env::set_var("YK_COMPILER_PATH", ykllvm_bin("clang")); LangTester::new() .test_dir("c") @@ -80,14 +84,15 @@ fn run_suite(opt: &'static str, force_decoder: &'static str) { .map(|l| l.generate_obj(tempdir.path())) .collect::>(); - let compiler = mk_compiler( - CCLang::C.compiler_wrapper().to_str().unwrap(), + let mut compiler = mk_compiler( + CCLang::C.compiler_wrapper().as_path(), &exe, p, opt, &extra_objs, true, ); + compiler.env("YK_COMPILER_PATH", ykllvm_bin("clang")); let mut runtime = Command::new(exe.clone()); runtime.env("YKD_FORCE_TRACE_DECODER", force_decoder); vec![("Compiler", compiler), ("Run-time", runtime)] diff --git a/tests/langtest_hwtracer_ykpt.rs b/tests/langtest_hwtracer_ykpt.rs index 1fc9cb373..6b6133f73 100644 --- a/tests/langtest_hwtracer_ykpt.rs +++ b/tests/langtest_hwtracer_ykpt.rs @@ -12,6 +12,7 @@ use std::{ use tempfile::TempDir; use tests::mk_compiler; use tests::ExtraLinkage; +use ykbuild::ykllvm_bin; const COMMENT: &str = "//"; @@ -24,8 +25,8 @@ pub static EXTRA_LINK_HWTRACER_YKPT: LazyLock>(); - let mut compiler = mk_compiler("clang", &exe, p, opt, &extra_objs, false); + let mut compiler = mk_compiler(ykllvm_bin("clang"), &exe, p, opt, &extra_objs, false); compiler.arg("-ltests"); let runtime = Command::new(exe.clone()); vec![("Compiler", compiler), ("Run-time", runtime)] diff --git a/tests/src/bin/gdb_c_test.rs b/tests/src/bin/gdb_c_test.rs index cccb750a0..7c1dcd0a4 100644 --- a/tests/src/bin/gdb_c_test.rs +++ b/tests/src/bin/gdb_c_test.rs @@ -4,6 +4,7 @@ use clap::Parser; use std::{env, path::PathBuf, process::Command}; use tempfile::TempDir; use tests::{mk_compiler, EXTRA_LINK}; +use ykbuild::ykllvm_bin; /// Run a C test under gdb. #[derive(Parser, Debug)] @@ -54,7 +55,14 @@ fn main() { let binstem = PathBuf::from(args.test_file.file_stem().unwrap()); let binpath = [tempdir.path(), &binstem].iter().collect::(); - let mut cmd = mk_compiler("clang", &binpath, &test_path, "-O0", &extra_objs, true); + let mut cmd = mk_compiler( + ykllvm_bin("clang").as_path(), + &binpath, + &test_path, + "-O0", + &extra_objs, + true, + ); if !cmd.spawn().unwrap().wait().unwrap().success() { panic!("compilation failed"); } diff --git a/tests/src/lib.rs b/tests/src/lib.rs index 300236889..a3e321b66 100644 --- a/tests/src/lib.rs +++ b/tests/src/lib.rs @@ -10,6 +10,7 @@ use std::{ process::Command, sync::LazyLock, }; +use ykbuild::ykllvm_bin; const TEMPDIR_SUBST: &str = "%%TEMPDIR%%"; pub static EXTRA_LINK: LazyLock>> = LazyLock::new(|| { @@ -30,8 +31,8 @@ pub static EXTRA_LINK: LazyLock>> = Lazy *test_file, vec![ExtraLinkage::new( "%%TEMPDIR%%/call_me.o", + ykllvm_bin("clang").to_owned(), &[ - "clang", "-I../ykcapi", "-c", "-O0", @@ -49,27 +50,33 @@ pub static EXTRA_LINK: LazyLock>> = Lazy pub struct ExtraLinkage<'a> { /// The name of the object file to be generated. output_file: &'a str, - /// The command that generates the object file. - gen_cmd: &'a [&'a str], + /// The path to the binary we want to run. + gen_bin: PathBuf, + /// Arguments to the binary. + gen_args: &'a [&'a str], } impl<'a> ExtraLinkage<'a> { - pub fn new(output_file: &'a str, gen_cmd: &'a [&'a str]) -> Self { + pub fn new(output_file: &'a str, gen_bin: PathBuf, gen_args: &'a [&'a str]) -> Self { Self { output_file, - gen_cmd, + gen_bin, + gen_args, } } /// Run the command to generate the object in `tempdir` and return the absolute path to the /// generated object. pub fn generate_obj(&self, tempdir: &Path) -> PathBuf { - let mut cmd = Command::new(self.gen_cmd[0]); + let mut cmd = Command::new(&self.gen_bin); let tempdir_s = tempdir.to_str().unwrap(); - for arg in self.gen_cmd[1..].iter() { + for arg in self.gen_args.iter() { cmd.arg(arg.replace(TEMPDIR_SUBST, tempdir_s)); } - let out = cmd.output().unwrap(); + let out = match cmd.output() { + Ok(x) => x, + Err(e) => panic!("Error when running {:?} {:?}", cmd, e), + }; assert!(tempdir.exists()); if !out.status.success() { io::stdout().write_all(&out.stdout).unwrap(); @@ -87,7 +94,7 @@ impl<'a> ExtraLinkage<'a> { /// /// If `patch_cp` is `false` then the argument to patch the control point is omitted. pub fn mk_compiler( - compiler: &str, + compiler: &Path, exe: &Path, src: &Path, opt: &str, @@ -117,6 +124,7 @@ pub fn mk_compiler( .output() .expect("failed to execute yk-config"); if !yk_config_out.status.success() { + io::stderr().write_all(&yk_config_out.stderr).ok(); panic!("yk-config exited with non-zero status"); } let mut yk_flags = String::from_utf8(yk_config_out.stdout).unwrap(); diff --git a/ykbuild/build.rs b/ykbuild/build.rs index 6f5f30c0d..9a8da7dbd 100644 --- a/ykbuild/build.rs +++ b/ykbuild/build.rs @@ -1,23 +1,42 @@ -use std::env; +use std::{env, fs::create_dir_all, path::Path}; use which::which; -const YKLLVM: &str = "../ykllvm/llvm"; -const PROFILE: &str = "Release"; +/// Where is ykllvm's source code relative to this crate? +const YKLLVM_SUBMODULE_PATH: &str = "../ykllvm/llvm"; fn main() { + // If the user defines YKB_YKLLVM_BIN_DIR then we don't try to build ykllvm ourselves. if env::var("YKB_YKLLVM_BIN_DIR").is_ok() { - println!("cargo:ykllvm={}", env::var("YKB_YKLLVM_BIN_DIR").unwrap()); return; } + // Build ykllvm in "target/[debug|release]". Note that the directory used here *must* + // be exactly the same as that produced by `ykbuild/src/lib.rs:llvm_bin_dir` and + // yk-config. + let mut ykllvm_dir = Path::new(&env::var("OUT_DIR").unwrap()) + .parent() + .unwrap() + .parent() + .unwrap() + .parent() + .unwrap() + .to_owned(); + { + let leaf = ykllvm_dir.file_name().unwrap().to_str().unwrap(); + assert!(leaf == "debug" || leaf == "release"); + } + ykllvm_dir.push("ykllvm"); + create_dir_all(&ykllvm_dir).unwrap(); + // Ninja builds are faster, so use this if it's available. let use_ninja = which("ninja").is_ok(); let is_debug = env::var("PROFILE").unwrap() == "debug"; let nprocs = format!("-j {}", num_cpus::get()); - let mut ykllvm = cmake::Config::new(YKLLVM); + let mut ykllvm = cmake::Config::new(YKLLVM_SUBMODULE_PATH); ykllvm - .profile(PROFILE) + .profile("Release") + .out_dir(ykllvm_dir) .generator(if use_ninja { "Ninja" } else { "Unix Makefiles" }) .define("LLVM_INSTALL_UTILS", "ON") .define("BUILD_SHARED_LIBS", "ON") @@ -52,10 +71,5 @@ fn main() { } } - let dsp = ykllvm.build(); - - // We need to be able to locate the ykllvm install llvm bins from other - // crates, so this sets a `DEP_YKBUILD_YKLLVM` env var which can be accessed - // from any other crate in the yk workspace. - println!("cargo:ykllvm={}/bin/", dsp.display()) + ykllvm.build(); } diff --git a/ykbuild/src/ccgen.rs b/ykbuild/src/ccgen.rs index 1abac3e65..37bb25a8b 100644 --- a/ykbuild/src/ccgen.rs +++ b/ykbuild/src/ccgen.rs @@ -87,7 +87,7 @@ impl CCGenerator { /// Returns the key and value that must be applied to the wrapped compiler's environment. pub fn build_env(&self) -> (&str, &str) { - ("YK_CC_TEMPDIR", self.tmpdir.path().to_str().unwrap()) + ("YK_COMPILER_TEMPDIR", self.tmpdir.path().to_str().unwrap()) } /// Call when the build is done to generate the `build_commands.json` file. diff --git a/ykbuild/src/lib.rs b/ykbuild/src/lib.rs index d4e163f44..1eff7d311 100644 --- a/ykbuild/src/lib.rs +++ b/ykbuild/src/lib.rs @@ -1,6 +1,10 @@ //! Utilities for the yk build system. -use std::{env, process::Command}; +use std::{ + env, + path::{Path, PathBuf}, + process::Command, +}; pub mod ccgen; @@ -8,10 +12,47 @@ fn manifest_dir() -> String { env::var("CARGO_MANIFEST_DIR").unwrap() } -pub fn llvm_config() -> Command { - let mut c = Command::new("llvm-config"); - c.arg("--link-shared"); - c +/// Return a [Path] to the directory containing a ykllvm installation. +pub fn ykllvm_bin_dir() -> PathBuf { + match env::var("YKB_YKLLVM_BIN_DIR") { + Ok(x) => Path::new(&x).to_owned(), + Err(_) => { + // The directory returned here *must* be exactly the same as that produced by + // `ykbuild/build.rs`. + let mut ykllvm_dir = Path::new(env!("OUT_DIR")) + .parent() + .unwrap() + .parent() + .unwrap() + .parent() + .unwrap() + .to_owned(); + { + let leaf = ykllvm_dir.file_name().unwrap().to_str().unwrap(); + assert!(leaf == "debug" || leaf == "release"); + } + ykllvm_dir.push("ykllvm"); + ykllvm_dir.push("bin"); + ykllvm_dir + } + } +} + +/// Return the location of the ykllvm binary `bin_name`. +/// +/// # Panics +/// +/// If `bin_name` is not found. +pub fn ykllvm_bin(bin_name: &str) -> PathBuf { + let mut p = ykllvm_bin_dir(); + p.push(bin_name); + if p.exists() { + return p; + } + panic!( + "ykllvm binary {} not found", + p.to_str().unwrap_or_else(|| bin_name) + ) } /// Call from a build script to ensure that the LLVM libraries are in the loader path. @@ -19,7 +60,12 @@ pub fn llvm_config() -> Command { /// This is preferred to adding an rpath, as we wouldn't want to distribute binaries with /// system-local rpaths inside. pub fn apply_llvm_ld_library_path() { - let lib_dir = llvm_config().arg("--libdir").output().unwrap().stdout; + let lib_dir = Command::new(&ykllvm_bin("llvm-config")) + .arg("--link-shared") + .arg("--libdir") + .output() + .unwrap() + .stdout; let lib_dir = std::str::from_utf8(&lib_dir).unwrap(); println!("cargo:rustc-env=LD_LIBRARY_PATH={}", lib_dir); } diff --git a/ykbuild/wrap-clang++.sh b/ykbuild/wrap-clang++.sh index e4567dc25..a917f69b9 100755 --- a/ykbuild/wrap-clang++.sh +++ b/ykbuild/wrap-clang++.sh @@ -6,8 +6,5 @@ set -e -export PATH=${DEP_YKBUILD_YKLLVM}:${PATH} - -echo "clang++ $@" > $(mktemp -p ${YK_CC_TEMPDIR}) - -clang++ $@ +echo "${YK_COMPILER_PATH} $@" > $(mktemp -p ${YK_COMPILER_TEMPDIR}) +${YK_COMPILER_PATH} $@ diff --git a/ykbuild/wrap-clang.sh b/ykbuild/wrap-clang.sh index c4e3a33a3..af3671619 100755 --- a/ykbuild/wrap-clang.sh +++ b/ykbuild/wrap-clang.sh @@ -4,6 +4,5 @@ set -e -echo "clang $@" > $(mktemp -p ${YK_CC_TEMPDIR}) - -clang $@ +echo "${YK_COMPILER_PATH} $@" > $(mktemp -p ${YK_COMPILER_TEMPDIR}) +${YK_COMPILER_PATH} $@ diff --git a/ykcapi/scripts/yk-config b/ykcapi/scripts/yk-config index da295baa2..de6e15a70 100755 --- a/ykcapi/scripts/yk-config +++ b/ykcapi/scripts/yk-config @@ -15,7 +15,7 @@ OUTPUT="" usage() { echo "Generate C compiler flags for building against the Yk JIT.\n" echo "Usage:" - echo " yk-config [--cppflags] [--cflags] [--ldflags]\n" + echo " yk-config <--cc|--cxx|--cppflags|--cflags|--ldflags>\n" echo " Where is either 'debug' or 'release'." } @@ -23,7 +23,16 @@ handle_arg() { mode=$1 shift + if [ "x${YKB_YKLLVM_BIN_DIR}" != "x" ]; then + ykllvm_bin_dir=`realpath ${YKB_YKLLVM_BIN_DIR}` + else + # The way this path is calculated must match that in ykbuild/build.rs. + ykllvm_bin_dir=`realpath ${DIR}/../../target/${mode}/ykllvm/bin/` + fi + case $1 in + --cc) OUTPUT="${ykllvm_bin_dir}/clang" ;; + --cxx) OUTPUT="${ykllvm_bin_dir}/clang++" ;; --cflags) # Enable LTO. OUTPUT="${OUTPUT} -flto" @@ -107,7 +116,7 @@ handle_arg() { # of rude to add local rpaths to interpreter binaries that # downstreams may want to distribute. OUTPUT="${OUTPUT} -Wl,-rpath=${DIR}/../../target/${mode}/deps" - OUTPUT="${OUTPUT} -Wl,-rpath=$(llvm-config --link-shared --libdir)" + OUTPUT="${OUTPUT} -Wl,-rpath=$(${ykllvm_bin_dir}/llvm-config --link-shared --libdir)" # Add a proper RPATH, not a RUNPATH: # https://bugs.launchpad.net/ubuntu/+source/glibc/+bug/1737608 OUTPUT="${OUTPUT} -Wl,--disable-new-dtags" diff --git a/ykllvmwrap/build.rs b/ykllvmwrap/build.rs index a23437644..a5a18353e 100644 --- a/ykllvmwrap/build.rs +++ b/ykllvmwrap/build.rs @@ -1,11 +1,11 @@ #![feature(fn_traits)] use rerun_except::rerun_except; -use std::env; +use std::{env, process::Command}; use ykbuild::{ apply_llvm_ld_library_path, ccgen::{CCGenerator, CCLang}, - llvm_config, + ykllvm_bin, }; fn main() { @@ -13,7 +13,12 @@ fn main() { rerun_except(&[]).unwrap(); // Compile our wrappers with the right LLVM C++ flags. - let cxxflags_out = llvm_config().arg("--cxxflags").output().unwrap().stdout; + let cxxflags_out = Command::new(&ykllvm_bin("llvm-config")) + .arg("--link-shared") + .arg("--cxxflags") + .output() + .unwrap() + .stdout; let cxxflags_str = std::str::from_utf8(&cxxflags_out).unwrap(); let cxxflags = cxxflags_str.split_whitespace().collect::>(); @@ -49,6 +54,7 @@ fn main() { // Generate a `compile_commands.json` database for clangd. let ccg = CCGenerator::new("ykllvmwrap", &env::var("CARGO_MANIFEST_DIR").unwrap()); env::set_var.call(ccg.build_env()); + env::set_var("YK_COMPILER_PATH", ykllvm_bin("clang++")); comp.compiler(CCLang::CPP.compiler_wrapper()); // Actually do the compilation. @@ -58,12 +64,22 @@ fn main() { ccg.generate(); // Ensure that downstream crates performing linkage use the right -L and -l flags. - let lib_dir = llvm_config().arg("--libdir").output().unwrap().stdout; + let lib_dir = Command::new(&ykllvm_bin("llvm-config")) + .arg("--link-shared") + .arg("--libdir") + .output() + .unwrap() + .stdout; let lib_dir = std::str::from_utf8(&lib_dir).unwrap(); println!("cargo:rustc-link-search={}", lib_dir); apply_llvm_ld_library_path(); - let libs = llvm_config().arg("--libs").output().unwrap().stdout; + let libs = Command::new(&ykllvm_bin("llvm-config")) + .arg("--link-shared") + .arg("--libs") + .output() + .unwrap() + .stdout; let libs = std::str::from_utf8(&libs).unwrap(); for lib in libs.split_whitespace() { assert!(lib.starts_with("-l")); diff --git a/yksmp/tests/Makefile b/yksmp/tests/Makefile index bdf59a0bb..31c13e400 100644 --- a/yksmp/tests/Makefile +++ b/yksmp/tests/Makefile @@ -1,16 +1,17 @@ TARGET_DIR = $(shell readlink -f $(shell pwd)/../../target/) +CC = $(shell $(shell readlink -f $(shell pwd)/../../ykcapi/scripts/yk-config) debug --cc) simple.o: - clang simple.ll -o ${TARGET_DIR}/simple.o + ${CC} simple.ll -o ${TARGET_DIR}/simple.o deopt.o: - clang deopt.ll -o ${TARGET_DIR}/deopt.o + ${CC} deopt.ll -o ${TARGET_DIR}/deopt.o simple.ll: - clang -emit-llvm -S -o simple.ll -c simple.c + ${CC} -emit-llvm -S -o simple.ll -c simple.c deopt.ll: - clang -emit-llvm -S -o deopt.ll -c deopt.c + ${CC} -emit-llvm -S -o deopt.ll -c deopt.c clean: rm simple.o