From ea04b0afbf3e5346c2df015b9c59ff1b0b3bc270 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Tue, 30 Jul 2024 13:07:49 -0400 Subject: [PATCH] use llvm-nm in symbol-visibility rmake test --- .../src/external_deps/llvm.rs | 30 +++++++++++++++++++ src/tools/run-make-support/src/lib.rs | 4 +-- tests/run-make/symbol-visibility/rmake.rs | 29 ++++++++++++------ 3 files changed, 52 insertions(+), 11 deletions(-) diff --git a/src/tools/run-make-support/src/external_deps/llvm.rs b/src/tools/run-make-support/src/external_deps/llvm.rs index b116bd08e3a6c..259bb6159461b 100644 --- a/src/tools/run-make-support/src/external_deps/llvm.rs +++ b/src/tools/run-make-support/src/external_deps/llvm.rs @@ -36,6 +36,12 @@ pub fn llvm_ar() -> LlvmAr { LlvmAr::new() } +/// Construct a new `llvm-nm` invocation. This assumes that `llvm-nm` is available +/// at `$LLVM_BIN_DIR/llvm-nm`. +pub fn llvm_nm() -> LlvmNm { + LlvmNm::new() +} + /// A `llvm-readobj` invocation builder. #[derive(Debug)] #[must_use] @@ -71,11 +77,19 @@ pub struct LlvmAr { cmd: Command, } +/// A `llvm-nm` invocation builder. +#[derive(Debug)] +#[must_use] +pub struct LlvmNm { + cmd: Command, +} + crate::macros::impl_common_helpers!(LlvmReadobj); crate::macros::impl_common_helpers!(LlvmProfdata); crate::macros::impl_common_helpers!(LlvmFilecheck); crate::macros::impl_common_helpers!(LlvmObjdump); crate::macros::impl_common_helpers!(LlvmAr); +crate::macros::impl_common_helpers!(LlvmNm); /// Generate the path to the bin directory of LLVM. #[must_use] @@ -244,3 +258,19 @@ impl LlvmAr { self } } + +impl LlvmNm { + /// Construct a new `llvm-nm` invocation. This assumes that `llvm-nm` is available + /// at `$LLVM_BIN_DIR/llvm-nm`. + pub fn new() -> Self { + let llvm_nm = llvm_bin_dir().join("llvm-nm"); + let cmd = Command::new(llvm_nm); + Self { cmd } + } + + /// Provide an input file. + pub fn input>(&mut self, path: P) -> &mut Self { + self.cmd.arg(path.as_ref()); + self + } +} diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index 085120764b463..9ced61932585c 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -48,8 +48,8 @@ pub use cc::{cc, cxx, extra_c_flags, extra_cxx_flags, Cc}; pub use clang::{clang, Clang}; pub use htmldocck::htmldocck; pub use llvm::{ - llvm_ar, llvm_filecheck, llvm_objdump, llvm_profdata, llvm_readobj, LlvmAr, LlvmFilecheck, - LlvmObjdump, LlvmProfdata, LlvmReadobj, + llvm_ar, llvm_filecheck, llvm_nm, llvm_objdump, llvm_profdata, llvm_readobj, LlvmAr, + LlvmFilecheck, LlvmNm, LlvmObjdump, LlvmProfdata, LlvmReadobj, }; pub use python::python_command; pub use rustc::{aux_build, bare_rustc, rustc, Rustc}; diff --git a/tests/run-make/symbol-visibility/rmake.rs b/tests/run-make/symbol-visibility/rmake.rs index cd085cf05d0ed..b37ff44f4ead6 100644 --- a/tests/run-make/symbol-visibility/rmake.rs +++ b/tests/run-make/symbol-visibility/rmake.rs @@ -6,13 +6,16 @@ //@ ignore-windows-msvc -use run_make_support::{bin_name, dynamic_lib_name, is_windows, llvm_readobj, regex, rustc}; +//FIXME(Oneirical): This currently uses llvm-nm for symbol detection. However, +// the custom Rust-based solution of #128314 may prove to be an interesting alternative. + +use run_make_support::{bin_name, dynamic_lib_name, is_darwin, is_windows, llvm_nm, regex, rustc}; fn main() { - let mut cdylib_name = dynamic_lib_name("a_cdylib"); - let mut rdylib_name = dynamic_lib_name("a_rust_dylib"); + let cdylib_name = dynamic_lib_name("a_cdylib"); + let rdylib_name = dynamic_lib_name("a_rust_dylib"); let exe_name = bin_name("an_executable"); - let mut combined_cdylib_name = dynamic_lib_name("combined_rlib_dylib"); + let combined_cdylib_name = dynamic_lib_name("combined_rlib_dylib"); rustc().arg("-Zshare-generics=no").input("an_rlib.rs").run(); rustc().arg("-Zshare-generics=no").input("a_cdylib.rs").run(); rustc().arg("-Zshare-generics=no").input("a_rust_dylib.rs").run(); @@ -74,13 +77,13 @@ fn main() { // Check the combined case, where we generate a cdylib and an rlib in the same // compilation session: - // Check that a cdylib exports its public //[no_mangle] functions + // Check that a cdylib exports its public #[no_mangle] functions symbols_check( &combined_cdylib_name, SymbolCheckType::StrSymbol("public_c_function_from_cdylib"), true, ); - // Check that a cdylib exports the public //[no_mangle] functions of dependencies + // Check that a cdylib exports the public #[no_mangle] functions of dependencies symbols_check( &combined_cdylib_name, SymbolCheckType::StrSymbol("public_c_function_from_rlib"), @@ -94,9 +97,9 @@ fn main() { rustc().arg("-Zshare-generics=yes").input("a_rust_dylib.rs").run(); rustc().arg("-Zshare-generics=yes").input("an_executable.rs").run(); - // Check that a cdylib exports its public //[no_mangle] functions + // Check that a cdylib exports its public #[no_mangle] functions symbols_check(&cdylib_name, SymbolCheckType::StrSymbol("public_c_function_from_cdylib"), true); - // Check that a cdylib exports the public //[no_mangle] functions of dependencies + // Check that a cdylib exports the public #[no_mangle] functions of dependencies symbols_check(&cdylib_name, SymbolCheckType::StrSymbol("public_c_function_from_rlib"), true); // Check that a cdylib DOES NOT export any public Rust functions symbols_check(&cdylib_name, SymbolCheckType::AnyRustSymbol, false); @@ -142,7 +145,15 @@ fn main() { #[track_caller] fn symbols_check(path: &str, symbol_check_type: SymbolCheckType, exists_once: bool) { - let out = llvm_readobj().arg("--dyn-symbols").input(path).run().invalid_stdout_utf8(); + let mut nm = llvm_nm(); + if is_windows() { + nm.arg("--extern-only"); + } else if is_darwin() { + nm.arg("--extern-only").arg("--defined-only"); + } else { + nm.arg("--dynamic"); + } + let out = nm.input(path).run().stdout_utf8(); assert_eq!( out.lines() .filter(|&line| !line.contains("__imp_") && has_symbol(line, symbol_check_type))