tests: port extern-fn-reachable
to rmake.rs
Co-authored-by: binarycat <binarycat@envs.net>
This commit is contained in:
parent
c074d8eee7
commit
98f673e93a
4 changed files with 61 additions and 27 deletions
|
@ -1,5 +1,4 @@
|
|||
run-make/cat-and-grep-sanity-check/Makefile
|
||||
run-make/extern-fn-reachable/Makefile
|
||||
run-make/jobserver-error/Makefile
|
||||
run-make/split-debuginfo/Makefile
|
||||
run-make/symbol-mangling-hashed/Makefile
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
# ignore-cross-compile
|
||||
include ../tools.mk
|
||||
|
||||
# ignore-windows-msvc
|
||||
|
||||
NM=nm -D
|
||||
|
||||
ifeq ($(UNAME),Darwin)
|
||||
NM=nm -gU
|
||||
endif
|
||||
|
||||
ifdef IS_WINDOWS
|
||||
NM=nm -g
|
||||
endif
|
||||
|
||||
# This overrides the LD_LIBRARY_PATH for RUN
|
||||
TARGET_RPATH_DIR:=$(TARGET_RPATH_DIR):$(TMPDIR)
|
||||
|
||||
all:
|
||||
$(RUSTC) dylib.rs -o $(TMPDIR)/libdylib.so -C prefer-dynamic
|
||||
|
||||
[ "$$($(NM) $(TMPDIR)/libdylib.so | grep -v __imp_ | grep -c fun1)" -eq "1" ]
|
||||
[ "$$($(NM) $(TMPDIR)/libdylib.so | grep -v __imp_ | grep -c fun2)" -eq "1" ]
|
||||
[ "$$($(NM) $(TMPDIR)/libdylib.so | grep -v __imp_ | grep -c fun3)" -eq "1" ]
|
||||
[ "$$($(NM) $(TMPDIR)/libdylib.so | grep -v __imp_ | grep -c fun4)" -eq "1" ]
|
||||
[ "$$($(NM) $(TMPDIR)/libdylib.so | grep -v __imp_ | grep -c fun5)" -eq "1" ]
|
|
@ -1,19 +1,34 @@
|
|||
#![crate_type = "dylib"]
|
||||
#![allow(dead_code)]
|
||||
|
||||
// `pub` extern fn here is a Rust nameres visibility concept, and should not affect symbol
|
||||
// visibility in the dylib.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn fun1() {}
|
||||
|
||||
// (Lack of) `pub` for the extern fn here is a Rust nameres visibility concept, and should not
|
||||
// affect symbol visibility in the dylib.
|
||||
#[no_mangle]
|
||||
extern "C" fn fun2() {}
|
||||
|
||||
// Modules are a Rust nameres concept, and should not affect symbol visibility in the dylib if the
|
||||
// extern fn is nested inside a module.
|
||||
mod foo {
|
||||
#[no_mangle]
|
||||
pub extern "C" fn fun3() {}
|
||||
}
|
||||
|
||||
// Similarly, the Rust visibility of the containing module is a Rust nameres concept, and should not
|
||||
// affect symbol visibility in the dylib.
|
||||
pub mod bar {
|
||||
#[no_mangle]
|
||||
pub extern "C" fn fun4() {}
|
||||
}
|
||||
|
||||
// Non-extern `#[no_mangle]` fn should induce a symbol visible in the dylib.
|
||||
#[no_mangle]
|
||||
pub fn fun5() {}
|
||||
|
||||
// The Rust visibility of the fn should not affect is symbol visibility in the dylib.
|
||||
#[no_mangle]
|
||||
fn fun6() {}
|
||||
|
|
46
tests/run-make/extern-fn-reachable/rmake.rs
Normal file
46
tests/run-make/extern-fn-reachable/rmake.rs
Normal file
|
@ -0,0 +1,46 @@
|
|||
//! Smoke test to check that that symbols of `extern "C"` functions and `#[no_mangle]` rust
|
||||
//! functions:
|
||||
//!
|
||||
//! 1. Are externally visible in the dylib produced.
|
||||
//! 2. That the symbol visibility is orthogonal to the Rust nameres visibility of the functions
|
||||
//! involved.
|
||||
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
use run_make_support::object::{self, Object};
|
||||
use run_make_support::{dynamic_lib_name, is_darwin, path, rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
let dylib = dynamic_lib_name("dylib");
|
||||
rustc().input("dylib.rs").output(&dylib).arg("-Cprefer-dynamic").run();
|
||||
|
||||
let expected_symbols = if is_darwin() {
|
||||
// Mach-O states that all exported symbols should have an underscore as prefix. At the
|
||||
// same time dlsym will implicitly add it, so outside of compilers, linkers and people
|
||||
// writing assembly, nobody needs to be aware of this.
|
||||
BTreeSet::from(["_fun1", "_fun2", "_fun3", "_fun4", "_fun5", "_fun6"])
|
||||
} else {
|
||||
BTreeSet::from(["fun1", "fun2", "fun3", "fun4", "fun5", "fun6"])
|
||||
};
|
||||
|
||||
let mut found_symbols = BTreeSet::new();
|
||||
|
||||
let blob = rfs::read(path(dylib));
|
||||
let file = object::File::parse(&*blob).unwrap();
|
||||
for export in file.exports().unwrap() {
|
||||
let sym_name = export.name();
|
||||
let sym_name = std::str::from_utf8(sym_name).unwrap();
|
||||
found_symbols.insert(sym_name);
|
||||
}
|
||||
|
||||
println!("expected_symbols = {:?}", expected_symbols);
|
||||
println!("found_symbols = {:?}", found_symbols);
|
||||
if !found_symbols.is_superset(&expected_symbols) {
|
||||
for diff in expected_symbols.difference(&found_symbols) {
|
||||
eprintln!("missing symbol: {}", diff);
|
||||
}
|
||||
panic!("missing expected symbols");
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue