mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
Auto merge of #128793 - matthiaskrgr:rollup-ork16t0, r=matthiaskrgr
Rollup of 4 pull requests Successful merges: - #128363 (Migrate `pdb-buildinfo-cl-cmd` and `pgo-indirect-call-promotion` `run-make` tests to rmake) - #128384 (Add tests to ensure MTE tags are preserved across FFI boundaries) - #128636 (migrate `thumb-none-cortex-m` to rmake) - #128696 (Migrate `staticlib-dylib-linkage` `run-make` test to rmake) Failed merges: - #128407 (Migrate `min-global-align` and `no-alloc-shim` `run-make` tests to rmake) - #128639 (migrate `thumb-none-qemu` to rmake) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
86e7875c13
@ -170,6 +170,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
|
||||
"only-32bit",
|
||||
"only-64bit",
|
||||
"only-aarch64",
|
||||
"only-aarch64-unknown-linux-gnu",
|
||||
"only-apple",
|
||||
"only-arm",
|
||||
"only-avr",
|
||||
@ -204,6 +205,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
|
||||
"only-watchos",
|
||||
"only-windows",
|
||||
"only-windows-gnu",
|
||||
"only-windows-msvc",
|
||||
"only-x86",
|
||||
"only-x86_64",
|
||||
"only-x86_64-fortanix-unknown-sgx",
|
||||
|
@ -16,16 +16,12 @@ run-make/macos-deployment-target/Makefile
|
||||
run-make/min-global-align/Makefile
|
||||
run-make/native-link-modifier-bundle/Makefile
|
||||
run-make/no-alloc-shim/Makefile
|
||||
run-make/pdb-buildinfo-cl-cmd/Makefile
|
||||
run-make/pgo-indirect-call-promotion/Makefile
|
||||
run-make/remap-path-prefix-dwarf/Makefile
|
||||
run-make/reproducible-build/Makefile
|
||||
run-make/rlib-format-packed-bundled-libs/Makefile
|
||||
run-make/split-debuginfo/Makefile
|
||||
run-make/staticlib-dylib-linkage/Makefile
|
||||
run-make/symbol-mangling-hashed/Makefile
|
||||
run-make/sysroot-crates-are-unstable/Makefile
|
||||
run-make/thumb-none-cortex-m/Makefile
|
||||
run-make/thumb-none-qemu/Makefile
|
||||
run-make/translation/Makefile
|
||||
run-make/x86_64-fortanix-unknown-sgx-lvi/Makefile
|
||||
|
43
tests/run-make/mte-ffi/bar.h
Normal file
43
tests/run-make/mte-ffi/bar.h
Normal file
@ -0,0 +1,43 @@
|
||||
#ifndef __BAR_H
|
||||
#define __BAR_H
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <sys/auxv.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// Set the allocation tag on the destination address using the STG instruction.
|
||||
#define set_tag(tagged_addr) do { \
|
||||
asm volatile("stg %0, [%0]" : : "r" (tagged_addr) : "memory"); \
|
||||
} while (0)
|
||||
|
||||
int mte_enabled() {
|
||||
return (getauxval(AT_HWCAP2)) & HWCAP2_MTE;
|
||||
}
|
||||
|
||||
void *alloc_page() {
|
||||
// Enable MTE with synchronous checking
|
||||
if (prctl(PR_SET_TAGGED_ADDR_CTRL,
|
||||
PR_TAGGED_ADDR_ENABLE | PR_MTE_TCF_SYNC | (0xfffe << PR_MTE_TAG_SHIFT),
|
||||
0, 0, 0))
|
||||
{
|
||||
perror("prctl() failed");
|
||||
}
|
||||
|
||||
// Using `mmap` allows us to ensure that, on systems which support MTE, the allocated
|
||||
// memory is 16-byte aligned for MTE.
|
||||
// This also allows us to explicitly specify whether the region should be protected by
|
||||
// MTE or not.
|
||||
if (mte_enabled()) {
|
||||
void *ptr = mmap(NULL, sysconf(_SC_PAGESIZE),
|
||||
PROT_READ | PROT_WRITE | PROT_MTE, MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
-1, 0);
|
||||
} else {
|
||||
void *ptr = mmap(NULL, sysconf(_SC_PAGESIZE),
|
||||
PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
-1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // __BAR_H
|
44
tests/run-make/mte-ffi/bar_float.c
Normal file
44
tests/run-make/mte-ffi/bar_float.c
Normal file
@ -0,0 +1,44 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include "bar.h"
|
||||
|
||||
extern void foo(char*);
|
||||
|
||||
void bar(char *ptr) {
|
||||
if (((uintptr_t)ptr >> 56) != 0x1f) {
|
||||
fprintf(stderr, "Top byte corrupted on Rust -> C FFI boundary!\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
float *ptr = alloc_page();
|
||||
if (ptr == MAP_FAILED)
|
||||
{
|
||||
perror("mmap() failed");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Store an arbitrary tag in bits 56-59 of the pointer (where an MTE tag may be),
|
||||
// and a different value in the ignored top 4 bits.
|
||||
ptr = (float *)((uintptr_t)ptr | 0x1fl << 56);
|
||||
|
||||
if (mte_enabled()) {
|
||||
set_tag(ptr);
|
||||
}
|
||||
|
||||
ptr[0] = 2.0f;
|
||||
ptr[1] = 1.5f;
|
||||
|
||||
foo(ptr); // should change the contents of the page and call `bar`
|
||||
|
||||
if (ptr[0] != 0.5f || ptr[1] != 0.2f) {
|
||||
fprintf(stderr, "invalid data in memory; expected '0.5 0.2', got '%f %f'\n",
|
||||
ptr[0], ptr[1]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
39
tests/run-make/mte-ffi/bar_function.c
Normal file
39
tests/run-make/mte-ffi/bar_function.c
Normal file
@ -0,0 +1,39 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include "bar.h"
|
||||
|
||||
typedef void (*fp)(int (*)());
|
||||
|
||||
extern void foo(fp);
|
||||
|
||||
void bar(int (*ptr)()) {
|
||||
if (((uintptr_t)ptr >> 56) != 0x2f) {
|
||||
fprintf(stderr, "Top byte corrupted on Rust -> C FFI boundary!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int r = (*ptr)();
|
||||
if (r != 32) {
|
||||
fprintf(stderr, "invalid return value; expected 32, got '%d'\n", r);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
fp ptr = alloc_page();
|
||||
if (ptr == MAP_FAILED)
|
||||
{
|
||||
perror("mmap() failed");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Store an arbitrary tag in bits 56-59 of the pointer (where an MTE tag may be),
|
||||
// and a different value in the ignored top 4 bits.
|
||||
ptr = (fp)((uintptr_t)&bar | 0x1fl << 56);
|
||||
|
||||
foo(ptr);
|
||||
|
||||
return 0;
|
||||
}
|
47
tests/run-make/mte-ffi/bar_int.c
Normal file
47
tests/run-make/mte-ffi/bar_int.c
Normal file
@ -0,0 +1,47 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include "bar.h"
|
||||
|
||||
extern void foo(unsigned int *);
|
||||
|
||||
void bar(char *ptr) {
|
||||
if (((uintptr_t)ptr >> 56) != 0x1f) {
|
||||
fprintf(stderr, "Top byte corrupted on Rust -> C FFI boundary!\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// Construct a pointer with an arbitrary tag in bits 56-59, simulating an MTE tag.
|
||||
// It's only necessary that the tag is preserved across FFI bounds for this test.
|
||||
unsigned int *ptr;
|
||||
|
||||
ptr = alloc_page();
|
||||
if (ptr == MAP_FAILED)
|
||||
{
|
||||
perror("mmap() failed");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Store an arbitrary tag in bits 56-59 of the pointer (where an MTE tag may be),
|
||||
// and a different value in the ignored top 4 bits.
|
||||
ptr = (unsigned int *)((uintptr_t)ptr | 0x1fl << 56);
|
||||
|
||||
if (mte_enabled()) {
|
||||
set_tag(ptr);
|
||||
}
|
||||
|
||||
ptr[0] = 61;
|
||||
ptr[1] = 62;
|
||||
|
||||
foo(ptr); // should change the contents of the page to start with 0x63 0x64 and call `bar`
|
||||
|
||||
if (ptr[0] != 0x63 || ptr[1] != 0x64) {
|
||||
fprintf(stderr, "invalid data in memory; expected '63 64', got '%d %d'\n", ptr[0], ptr[1]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
48
tests/run-make/mte-ffi/bar_string.c
Normal file
48
tests/run-make/mte-ffi/bar_string.c
Normal file
@ -0,0 +1,48 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include "bar.h"
|
||||
|
||||
extern void foo(char*);
|
||||
|
||||
void bar(char *ptr) {
|
||||
if (((uintptr_t)ptr >> 56) != 0x2f) {
|
||||
fprintf(stderr, "Top byte corrupted on Rust -> C FFI boundary!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (strcmp(ptr, "cd")) {
|
||||
fprintf(stderr, "invalid data in memory; expected 'cd', got '%s'\n", ptr);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// Construct a pointer with an arbitrary tag in bits 56-59, simulating an MTE tag.
|
||||
// It's only necessary that the tag is preserved across FFI bounds for this test.
|
||||
char *ptr;
|
||||
|
||||
ptr = alloc_page();
|
||||
if (ptr == MAP_FAILED)
|
||||
{
|
||||
perror("mmap() failed");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Store an arbitrary tag in bits 56-59 of the pointer (where an MTE tag may be),
|
||||
// and a different value in the ignored top 4 bits.
|
||||
ptr = (unsigned int *)((uintptr_t)ptr | 0x1fl << 56);
|
||||
|
||||
if (mte_enabled()) {
|
||||
set_tag(ptr);
|
||||
}
|
||||
|
||||
ptr[0] = 'a';
|
||||
ptr[1] = 'b';
|
||||
ptr[2] = '\0';
|
||||
|
||||
foo(ptr);
|
||||
|
||||
return 0;
|
||||
}
|
19
tests/run-make/mte-ffi/foo_float.rs
Normal file
19
tests/run-make/mte-ffi/foo_float.rs
Normal file
@ -0,0 +1,19 @@
|
||||
#![crate_type = "cdylib"]
|
||||
#![crate_name = "foo"]
|
||||
|
||||
use std::os::raw::c_float;
|
||||
|
||||
extern "C" {
|
||||
fn bar(ptr: *const c_float);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn foo(ptr: *mut c_float) {
|
||||
assert_eq!((ptr as usize) >> 56, 0x1f);
|
||||
|
||||
unsafe {
|
||||
*ptr = 0.5;
|
||||
*ptr.wrapping_add(1) = 0.2;
|
||||
bar(ptr);
|
||||
}
|
||||
}
|
17
tests/run-make/mte-ffi/foo_function.rs
Normal file
17
tests/run-make/mte-ffi/foo_function.rs
Normal file
@ -0,0 +1,17 @@
|
||||
#![crate_type = "cdylib"]
|
||||
#![crate_name = "foo"]
|
||||
|
||||
extern "C" fn ret32() -> i32 {
|
||||
32
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn foo(ptr: extern "C" fn(extern "C" fn() -> i32)) {
|
||||
assert_eq!((ptr as usize) >> 56, 0x1f);
|
||||
|
||||
// Store an arbitrary tag in the tag bits, and convert back to the correct pointer type.
|
||||
let p = ((ret32 as usize) | (0x2f << 56)) as *const ();
|
||||
let p: extern "C" fn() -> i32 = unsafe { std::mem::transmute(p) };
|
||||
|
||||
unsafe { ptr(p) }
|
||||
}
|
19
tests/run-make/mte-ffi/foo_int.rs
Normal file
19
tests/run-make/mte-ffi/foo_int.rs
Normal file
@ -0,0 +1,19 @@
|
||||
#![crate_type = "cdylib"]
|
||||
#![crate_name = "foo"]
|
||||
|
||||
use std::os::raw::c_uint;
|
||||
|
||||
extern "C" {
|
||||
fn bar(ptr: *const c_uint);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn foo(ptr: *mut c_uint) {
|
||||
assert_eq!((ptr as usize) >> 56, 0x1f);
|
||||
|
||||
unsafe {
|
||||
*ptr = 0x63;
|
||||
*ptr.wrapping_add(1) = 0x64;
|
||||
bar(ptr);
|
||||
}
|
||||
}
|
27
tests/run-make/mte-ffi/foo_string.rs
Normal file
27
tests/run-make/mte-ffi/foo_string.rs
Normal file
@ -0,0 +1,27 @@
|
||||
#![crate_type = "cdylib"]
|
||||
#![crate_name = "foo"]
|
||||
|
||||
use std::arch::asm;
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::os::raw::c_char;
|
||||
|
||||
extern "C" {
|
||||
fn bar(ptr: *const c_char);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn foo(ptr: *const c_char) {
|
||||
assert_eq!((ptr as usize) >> 56, 0x1f);
|
||||
|
||||
let s = unsafe { CStr::from_ptr(ptr) };
|
||||
assert_eq!(s.to_str().unwrap(), "ab");
|
||||
|
||||
let s = CString::from_vec_with_nul("cd\0".into()).unwrap();
|
||||
let mut p = ((s.as_ptr() as usize) | (0x2f << 56)) as *const c_char;
|
||||
unsafe {
|
||||
#[cfg(target_feature = "mte")]
|
||||
asm!("stg {p}, [{p}]", p = inout(reg) p);
|
||||
|
||||
bar(p);
|
||||
}
|
||||
}
|
38
tests/run-make/mte-ffi/rmake.rs
Normal file
38
tests/run-make/mte-ffi/rmake.rs
Normal file
@ -0,0 +1,38 @@
|
||||
// Tests that MTE tags and values stored in the top byte of a pointer (TBI) are
|
||||
// preserved across FFI boundaries (C <-> Rust).
|
||||
// This test does not require MTE: whilst the test will use MTE if available, if it is not,
|
||||
// arbitrary tag bits are set using TBI.
|
||||
|
||||
// This test is only valid for AArch64.
|
||||
// The linker must be explicitly specified when cross-compiling, so it is limited to
|
||||
// `aarch64-unknown-linux-gnu`.
|
||||
//@ only-aarch64-unknown-linux-gnu
|
||||
|
||||
use run_make_support::{cc, dynamic_lib_name, extra_c_flags, run, rustc, target};
|
||||
|
||||
fn main() {
|
||||
run_test("int");
|
||||
run_test("float");
|
||||
run_test("string");
|
||||
run_test("function");
|
||||
}
|
||||
|
||||
fn run_test(variant: &str) {
|
||||
let flags = {
|
||||
let mut flags = extra_c_flags();
|
||||
flags.push("-march=armv8.5-a+memtag");
|
||||
flags
|
||||
};
|
||||
println!("{variant} test...");
|
||||
rustc()
|
||||
.input(format!("foo_{variant}.rs"))
|
||||
.target(target())
|
||||
.linker("aarch64-linux-gnu-gcc")
|
||||
.run();
|
||||
cc().input(format!("bar_{variant}.c"))
|
||||
.input(dynamic_lib_name("foo"))
|
||||
.out_exe("test")
|
||||
.args(&flags)
|
||||
.run();
|
||||
run("test");
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
include ../tools.mk
|
||||
|
||||
# only-windows-msvc
|
||||
|
||||
# tests if the pdb contains the following information in the LF_BUILDINFO:
|
||||
# 1. the commandline args to compile it (cmd)
|
||||
# 2. full path to the compiler (cl)
|
||||
|
||||
# we just do a stringsearch on the pdb, as these need to show up at least once, as the LF_BUILDINFO is created for each cgu
|
||||
# actual parsing would be better, but this is a simple and good enough solution for now
|
||||
|
||||
all:
|
||||
$(RUSTC_ORIGINAL) main.rs -g --crate-name my_crate_name --crate-type bin -C metadata=dc9ef878b0a48666 --out-dir $(TMPDIR)
|
||||
cat '$(TMPDIR)/my_crate_name.pdb' | grep -F '$(RUSTC_ORIGINAL)'
|
||||
# using a file containing the string so I don't have problems with escaping quotes and spaces
|
||||
cat '$(TMPDIR)/my_crate_name.pdb' | grep -f 'stringlist.txt'
|
39
tests/run-make/pdb-buildinfo-cl-cmd/rmake.rs
Normal file
39
tests/run-make/pdb-buildinfo-cl-cmd/rmake.rs
Normal file
@ -0,0 +1,39 @@
|
||||
// Check if the pdb file contains the following information in the LF_BUILDINFO:
|
||||
// 1. full path to the compiler (cl)
|
||||
// 2. the commandline args to compile it (cmd)
|
||||
// This is because these used to be missing in #96475.
|
||||
// See https://github.com/rust-lang/rust/pull/113492
|
||||
|
||||
//@ only-windows-msvc
|
||||
// Reason: pdb files are unique to this architecture
|
||||
|
||||
use run_make_support::{assert_contains, bstr, env_var, rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
rustc()
|
||||
.input("main.rs")
|
||||
.arg("-g")
|
||||
.crate_name("my_crate_name")
|
||||
.crate_type("bin")
|
||||
.metadata("dc9ef878b0a48666")
|
||||
.run();
|
||||
let tests = [
|
||||
&env_var("RUSTC"),
|
||||
r#""main.rs""#,
|
||||
r#""-g""#,
|
||||
r#""--crate-name""#,
|
||||
r#""my_crate_name""#,
|
||||
r#""--crate-type""#,
|
||||
r#""bin""#,
|
||||
r#""-Cmetadata=dc9ef878b0a48666""#,
|
||||
];
|
||||
for test in tests {
|
||||
assert_pdb_contains(test);
|
||||
}
|
||||
}
|
||||
|
||||
fn assert_pdb_contains(needle: &str) {
|
||||
let needle = needle.as_bytes();
|
||||
use bstr::ByteSlice;
|
||||
assert!(&rfs::read("my_crate_name.pdb").find(needle).is_some());
|
||||
}
|
@ -1 +0,0 @@
|
||||
"main.rs" "-g" "--crate-name" "my_crate_name" "--crate-type" "bin" "-C" "metadata=dc9ef878b0a48666" "--out-dir"
|
@ -1,23 +0,0 @@
|
||||
# needs-profiler-support
|
||||
# ignore-cross-compile
|
||||
|
||||
include ../tools.mk
|
||||
|
||||
all:
|
||||
# We don't compile `opaque` with either optimizations or instrumentation.
|
||||
# We don't compile `opaque` with either optimizations or instrumentation.
|
||||
$(RUSTC) $(COMMON_FLAGS) opaque.rs
|
||||
# Compile the test program with instrumentation
|
||||
mkdir -p "$(TMPDIR)"/prof_data_dir
|
||||
$(RUSTC) $(COMMON_FLAGS) interesting.rs \
|
||||
-Cprofile-generate="$(TMPDIR)"/prof_data_dir -O -Ccodegen-units=1
|
||||
$(RUSTC) $(COMMON_FLAGS) main.rs -Cprofile-generate="$(TMPDIR)"/prof_data_dir -O
|
||||
# The argument below generates to the expected branch weights
|
||||
$(call RUN,main) || exit 1
|
||||
"$(LLVM_BIN_DIR)"/llvm-profdata merge \
|
||||
-o "$(TMPDIR)"/prof_data_dir/merged.profdata \
|
||||
"$(TMPDIR)"/prof_data_dir
|
||||
$(RUSTC) $(COMMON_FLAGS) interesting.rs \
|
||||
-Cprofile-use="$(TMPDIR)"/prof_data_dir/merged.profdata -O \
|
||||
-Ccodegen-units=1 --emit=llvm-ir
|
||||
cat "$(TMPDIR)"/interesting.ll | "$(LLVM_FILECHECK)" filecheck-patterns.txt
|
33
tests/run-make/pgo-indirect-call-promotion/rmake.rs
Normal file
33
tests/run-make/pgo-indirect-call-promotion/rmake.rs
Normal file
@ -0,0 +1,33 @@
|
||||
// This test checks that indirect call promotion is performed. The test
|
||||
// programs calls the same function a thousand times through a function pointer.
|
||||
// Only PGO data provides the information that it actually always is the same
|
||||
// function. We verify that the indirect call promotion pass inserts a check
|
||||
// whether it can make a direct call instead of the indirect call.
|
||||
// See https://github.com/rust-lang/rust/pull/66631
|
||||
|
||||
//@ needs-profiler-support
|
||||
// Reason: llvm_profdata is used
|
||||
//@ ignore-cross-compile
|
||||
// Reason: the compiled binary is executed
|
||||
|
||||
use run_make_support::{llvm_filecheck, llvm_profdata, rfs, run, rustc};
|
||||
|
||||
fn main() {
|
||||
// We don't compile `opaque` with either optimizations or instrumentation.
|
||||
rustc().input("opaque.rs").run();
|
||||
// Compile the test program with instrumentation
|
||||
rfs::create_dir("prof_data_dir");
|
||||
rustc().input("interesting.rs").profile_generate("prof_data_dir").opt().codegen_units(1).run();
|
||||
rustc().input("main.rs").profile_generate("prof_data_dir").opt().run();
|
||||
// The argument below generates to the expected branch weights
|
||||
run("main");
|
||||
llvm_profdata().merge().output("prof_data_dir/merged.profdata").input("prof_data_dir").run();
|
||||
rustc()
|
||||
.input("interesting.rs")
|
||||
.profile_use("prof_data_dir/merged.profdata")
|
||||
.opt()
|
||||
.codegen_units(1)
|
||||
.emit("llvm-ir")
|
||||
.run();
|
||||
llvm_filecheck().patterns("filecheck-patterns.txt").stdin(rfs::read("interesting.ll")).run();
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
include ../tools.mk
|
||||
|
||||
# ignore-cross-compile
|
||||
# ignore-msvc FIXME(bjorn3) can't figure out how to link with the MSVC toolchain
|
||||
# ignore-wasm wasm doesn't support dynamic libraries
|
||||
|
||||
all:
|
||||
$(RUSTC) -C prefer-dynamic bar.rs
|
||||
$(RUSTC) foo.rs --crate-type staticlib --print native-static-libs \
|
||||
-Z staticlib-allow-rdylib-deps 2>&1 | grep 'note: native-static-libs: ' \
|
||||
| sed 's/note: native-static-libs: \(.*\)/\1/' > $(TMPDIR)/libs.txt
|
||||
cat $(TMPDIR)/libs.txt
|
||||
|
||||
ifdef IS_MSVC
|
||||
$(CC) $(CFLAGS) /c foo.c /Fo:$(TMPDIR)/foo.o
|
||||
$(RUSTC_LINKER) $(TMPDIR)/foo.o $(TMPDIR)/foo.lib $$(cat $(TMPDIR)/libs.txt) $(call OUT_EXE,foo)
|
||||
else
|
||||
$(CC) $(CFLAGS) foo.c -L $(TMPDIR) -lfoo $$(cat $(TMPDIR)/libs.txt) -o $(call RUN_BINFILE,foo)
|
||||
endif
|
||||
|
||||
$(call RUN,foo)
|
37
tests/run-make/staticlib-dylib-linkage/rmake.rs
Normal file
37
tests/run-make/staticlib-dylib-linkage/rmake.rs
Normal file
@ -0,0 +1,37 @@
|
||||
// A basic smoke test to check that rustc supports linking to a rust dylib with
|
||||
// --crate-type staticlib. bar is a dylib, on which foo is dependent - the native
|
||||
// static lib search paths are collected and used to compile foo.c, the final executable
|
||||
// which depends on both foo and bar.
|
||||
// See https://github.com/rust-lang/rust/pull/106560
|
||||
|
||||
//@ ignore-cross-compile
|
||||
// Reason: the compiled binary is executed.
|
||||
//@ ignore-wasm
|
||||
// Reason: WASM does not support dynamic libraries
|
||||
//@ ignore-msvc
|
||||
//FIXME(Oneirical): Getting this to work on MSVC requires passing libcmt.lib to CC,
|
||||
// which is not trivial to do.
|
||||
// Tracking issue: https://github.com/rust-lang/rust/issues/128602
|
||||
// Discussion: https://github.com/rust-lang/rust/pull/128407#discussion_r1702439172
|
||||
|
||||
use run_make_support::{cc, regex, run, rustc};
|
||||
|
||||
fn main() {
|
||||
rustc().arg("-Cprefer-dynamic").input("bar.rs").run();
|
||||
let libs = rustc()
|
||||
.input("foo.rs")
|
||||
.crate_type("staticlib")
|
||||
.print("native-static-libs")
|
||||
.arg("-Zstaticlib-allow-rdylib-deps")
|
||||
.run()
|
||||
.assert_stderr_contains("note: native-static-libs: ")
|
||||
.stderr_utf8();
|
||||
let re = regex::Regex::new(r#"note: native-static-libs:\s*(.+)"#).unwrap();
|
||||
let libs = re.find(&libs).unwrap().as_str().trim();
|
||||
// remove the note
|
||||
let (_, library_search_paths) = libs.split_once("note: native-static-libs: ").unwrap();
|
||||
// divide the command-line arguments in a vec
|
||||
let library_search_paths = library_search_paths.split(' ').collect::<Vec<&str>>();
|
||||
cc().input("foo.c").arg("-lfoo").args(library_search_paths).out_exe("foo").run();
|
||||
run("foo");
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
include ../tools.mk
|
||||
|
||||
# How to run this
|
||||
# $ ./x.py clean
|
||||
# $ ./x.py test --target thumbv6m-none-eabi,thumbv7m-none-eabi tests/run-make
|
||||
|
||||
# Supported targets:
|
||||
# - thumbv6m-none-eabi (Bare Cortex-M0, M0+, M1)
|
||||
# - thumbv7em-none-eabi (Bare Cortex-M4, M7)
|
||||
# - thumbv7em-none-eabihf (Bare Cortex-M4F, M7F, FPU, hardfloat)
|
||||
# - thumbv7m-none-eabi (Bare Cortex-M3)
|
||||
|
||||
# only-thumb
|
||||
|
||||
# For cargo setting
|
||||
RUSTC := $(RUSTC_ORIGINAL)
|
||||
LD_LIBRARY_PATH := $(HOST_RPATH_DIR)
|
||||
# We need to be outside of 'src' dir in order to run cargo
|
||||
WORK_DIR := $(TMPDIR)
|
||||
|
||||
HERE := $(shell pwd)
|
||||
|
||||
CRATE := cortex-m
|
||||
CRATE_URL := https://github.com/rust-embedded/cortex-m
|
||||
CRATE_SHA1 := a448e9156e2cb1e556e5441fd65426952ef4b927 # 0.5.0
|
||||
|
||||
# Don't make lints fatal, but they need to at least warn or they break Cargo's target info parsing.
|
||||
export RUSTFLAGS := --cap-lints=warn
|
||||
|
||||
all:
|
||||
env
|
||||
mkdir -p $(WORK_DIR)
|
||||
-cd $(WORK_DIR) && rm -rf $(CRATE)
|
||||
cd $(WORK_DIR) && bash -x $(HERE)/../git_clone_sha1.sh $(CRATE) $(CRATE_URL) $(CRATE_SHA1)
|
||||
# HACK(eddyb) sets `RUSTC_BOOTSTRAP=1` so Cargo can accept nightly features.
|
||||
# These come from the top-level Rust workspace, that this crate is not a
|
||||
# member of, but Cargo tries to load the workspace `Cargo.toml` anyway.
|
||||
cd $(WORK_DIR) && cd $(CRATE) && env RUSTC_BOOTSTRAP=1 $(BOOTSTRAP_CARGO) build --target $(TARGET) -v
|
59
tests/run-make/thumb-none-cortex-m/rmake.rs
Normal file
59
tests/run-make/thumb-none-cortex-m/rmake.rs
Normal file
@ -0,0 +1,59 @@
|
||||
//! Test building of the `cortex-m` crate, a foundational crate in the embedded ecosystem
|
||||
//! for a collection of thumb targets. This is a smoke test that verifies that both cargo
|
||||
//! and rustc work in this case.
|
||||
//!
|
||||
//! How to run this
|
||||
//! $ ./x.py clean
|
||||
//! $ ./x.py test --target thumbv6m-none-eabi,thumbv7m-none-eabi tests/run-make
|
||||
//!
|
||||
//! Supported targets:
|
||||
//! - thumbv6m-none-eabi (Bare Cortex-M0, M0+, M1)
|
||||
//! - thumbv7em-none-eabi (Bare Cortex-M4, M7)
|
||||
//! - thumbv7em-none-eabihf (Bare Cortex-M4F, M7F, FPU, hardfloat)
|
||||
//! - thumbv7m-none-eabi (Bare Cortex-M3)
|
||||
|
||||
//@ only-thumb
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
use run_make_support::rfs::create_dir;
|
||||
use run_make_support::{cmd, env_var, target};
|
||||
|
||||
const CRATE: &str = "cortex-m";
|
||||
const CRATE_URL: &str = "https://github.com/rust-embedded/cortex-m";
|
||||
const CRATE_SHA1: &str = "a448e9156e2cb1e556e5441fd65426952ef4b927"; // v0.5.0
|
||||
|
||||
fn main() {
|
||||
// FIXME: requires an internet connection https://github.com/rust-lang/rust/issues/128733
|
||||
// See below link for git usage:
|
||||
// https://stackoverflow.com/questions/3489173#14091182
|
||||
cmd("git").args(["clone", CRATE_URL, CRATE]).run();
|
||||
std::env::set_current_dir(CRATE).unwrap();
|
||||
cmd("git").args(["reset", "--hard", CRATE_SHA1]).run();
|
||||
|
||||
let target_dir = PathBuf::from("target");
|
||||
let manifest_path = PathBuf::from("Cargo.toml");
|
||||
|
||||
let path = env_var("PATH");
|
||||
let rustc = env_var("RUSTC");
|
||||
let bootstrap_cargo = env_var("BOOTSTRAP_CARGO");
|
||||
// FIXME: extract bootstrap cargo invocations to a proper command
|
||||
// https://github.com/rust-lang/rust/issues/128734
|
||||
let mut cmd = cmd(bootstrap_cargo);
|
||||
cmd.args(&[
|
||||
"build",
|
||||
"--manifest-path",
|
||||
manifest_path.to_str().unwrap(),
|
||||
"-Zbuild-std=core",
|
||||
"--target",
|
||||
&target(),
|
||||
])
|
||||
.env("PATH", path)
|
||||
.env("RUSTC", rustc)
|
||||
.env("CARGO_TARGET_DIR", &target_dir)
|
||||
// Don't make lints fatal, but they need to at least warn
|
||||
// or they break Cargo's target info parsing.
|
||||
.env("RUSTFLAGS", "-Copt-level=0 -Cdebug-assertions=yes --cap-lints=warn");
|
||||
|
||||
cmd.run();
|
||||
}
|
Loading…
Reference in New Issue
Block a user