Skip to content

Commit d38a5f0

Browse files
authored
Merge pull request #4362 from tgross35/ctest-ci
Add `ctest` to the root workspace and enable CI
2 parents 6da1998 + 20cca22 commit d38a5f0

File tree

24 files changed

+144
-358
lines changed

24 files changed

+144
-358
lines changed

.github/workflows/ci.yaml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,23 @@ jobs:
213213
export PATH=$HOME/.rust_solaris/bin:$PATH
214214
./ci/run.sh ${{ matrix.target }}
215215
216+
ctest_msrv:
217+
name: Check MSRV
218+
runs-on: ubuntu-24.04
219+
timeout-minutes: 10
220+
env:
221+
RUSTFLAGS: # No need to check warnings on old MSRV, unset `-Dwarnings`
222+
steps:
223+
- uses: actions/checkout@master
224+
- run: |
225+
msrv="$(perl -ne 'print if s/rust-version\s*=\s*"(.*)"/\1/g' ctest/Cargo.toml)"
226+
echo "MSRV: $msrv"
227+
echo "MSRV=$msrv" >> "$GITHUB_ENV"
228+
- name: Install Rust
229+
run: rustup update "$MSRV" --no-self-update && rustup default "$MSRV"
230+
- uses: Swatinem/rust-cache@v2
231+
- run: cargo build -p ctest
232+
216233
# One job that "summarizes" the success state of this pipeline. This can then be added to branch
217234
# protection, rather than having to add each job separately.
218235
success:
@@ -224,6 +241,7 @@ jobs:
224241
- test_tier2
225242
- test_tier2_vm
226243
- verify_build
244+
- ctest_msrv
227245
# Github branch protection is exceedingly silly and treats "jobs skipped because a dependency
228246
# failed" as success. So we have to do some contortions to ensure the job fails if any of its
229247
# dependencies fails.

Cargo.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,4 +140,8 @@ rustc-dep-of-std = ["rustc-std-workspace-core"]
140140
extra_traits = []
141141

142142
[workspace]
143-
members = ["libc-test"]
143+
members = [
144+
"ctest",
145+
"ctest-test",
146+
"libc-test",
147+
]

ci/docker/x86_64-unknown-linux-gnu/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ FROM ubuntu:24.10
22

33
RUN apt-get update
44
RUN apt-get install -y --no-install-recommends \
5-
gcc libc6-dev ca-certificates linux-headers-generic
5+
gcc g++ libc6-dev ca-certificates linux-headers-generic
66

77
RUN apt search linux-headers
88
RUN ls /usr/src

ci/run.sh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,19 @@ case "$target" in
9393
*) cmd="$cmd --workspace"
9494
esac
9595

96+
# garando_errors only compiles on `cfg(any(unix, windows))`
97+
case "$target" in
98+
*wasm*) cmd="$cmd --exclude ctest --exclude ctest-test"
99+
esac
100+
101+
# # FIXME(ctest): duplicate symbol errors for statics, e.g. T1_static_mut_u8, on Unix-
102+
# # like platforms.
103+
# cast "$(uname -s)" in
104+
# *windows*msvc) ;;
105+
# *apple*) ;;
106+
# *) cmd="$cmd --exclude ctest-test" ;;
107+
# esca
108+
96109
if [ "$target" = "s390x-unknown-linux-gnu" ]; then
97110
# FIXME: s390x-unknown-linux-gnu often fails to test due to timeout,
98111
# so we retry this N times.

ctest-test/Cargo.toml

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[package]
2-
name = "testcrate"
2+
name = "ctest-test"
33
version = "0.1.0"
44
authors = ["Alex Crichton <[email protected]>"]
55
build = "build.rs"
@@ -11,12 +11,8 @@ ctest = { path = "../ctest" }
1111
cc = "1.0"
1212

1313
[dependencies]
14-
libc = "0.2"
15-
16-
[lib]
17-
name = "testcrate"
18-
test = false
19-
doctest = false
14+
cfg-if = "1.0.0"
15+
libc = { path = ".." }
2016

2117
[[bin]]
2218
name = "t1"

ctest-test/build.rs

Lines changed: 39 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::process::Command;
2+
13
fn main() {
24
use std::env;
35
let opt_level = env::var("OPT_LEVEL")
@@ -48,34 +50,43 @@ fn main() {
4850
.skip_roundtrip(|_| true)
4951
.generate("src/t2.rs", "t2gen.rs");
5052

51-
ctest::TestGenerator::new()
52-
.header("t1.h")
53-
.language(ctest::Lang::CXX)
54-
.include("src")
55-
.fn_cname(|a, b| b.unwrap_or(a).to_string())
56-
.type_name(move |ty, is_struct, is_union| match ty {
57-
"T1Union" => ty.to_string(),
58-
"Transparent" => ty.to_string(),
59-
t if is_struct => format!("struct {}", t),
60-
t if is_union => format!("union {}", t),
61-
t => t.to_string(),
62-
})
63-
.volatile_item(t1_volatile)
64-
.array_arg(t1_arrays)
65-
.skip_roundtrip(|n| n == "Arr")
66-
.generate("src/t1.rs", "t1gen_cxx.rs");
67-
ctest::TestGenerator::new()
68-
.header("t2.h")
69-
.language(ctest::Lang::CXX)
70-
.include("src")
71-
.type_name(move |ty, is_struct, is_union| match ty {
72-
"T2Union" => ty.to_string(),
73-
t if is_struct => format!("struct {}", t),
74-
t if is_union => format!("union {}", t),
75-
t => t.to_string(),
76-
})
77-
.skip_roundtrip(|_| true)
78-
.generate("src/t2.rs", "t2gen_cxx.rs");
53+
println!("cargo::rustc-check-cfg=cfg(has_cxx)");
54+
if !cfg!(unix) || Command::new("c++").arg("v").output().is_ok() {
55+
// A C compiler is always available, but these are only run if a C++ compiler is
56+
// also available.
57+
println!("cargo::rustc-cfg=has_cxx");
58+
59+
ctest::TestGenerator::new()
60+
.header("t1.h")
61+
.language(ctest::Lang::CXX)
62+
.include("src")
63+
.fn_cname(|a, b| b.unwrap_or(a).to_string())
64+
.type_name(move |ty, is_struct, is_union| match ty {
65+
"T1Union" => ty.to_string(),
66+
"Transparent" => ty.to_string(),
67+
t if is_struct => format!("struct {}", t),
68+
t if is_union => format!("union {}", t),
69+
t => t.to_string(),
70+
})
71+
.volatile_item(t1_volatile)
72+
.array_arg(t1_arrays)
73+
.skip_roundtrip(|n| n == "Arr")
74+
.generate("src/t1.rs", "t1gen_cxx.rs");
75+
ctest::TestGenerator::new()
76+
.header("t2.h")
77+
.language(ctest::Lang::CXX)
78+
.include("src")
79+
.type_name(move |ty, is_struct, is_union| match ty {
80+
"T2Union" => ty.to_string(),
81+
t if is_struct => format!("struct {}", t),
82+
t if is_union => format!("union {}", t),
83+
t => t.to_string(),
84+
})
85+
.skip_roundtrip(|_| true)
86+
.generate("src/t2.rs", "t2gen_cxx.rs");
87+
} else {
88+
println!("cargo::warning=skipping C++ tests");
89+
}
7990
}
8091

8192
fn t1_volatile(i: ctest::VolatileItemKind) -> bool {

ctest-test/src/bin/t1.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#![cfg(not(test))]
22
#![deny(warnings)]
33

4+
use ctest_test::t1::*;
45
use libc::*;
5-
use testcrate::t1::*;
66

77
include!(concat!(env!("OUT_DIR"), "/t1gen.rs"));

ctest-test/src/bin/t1_cxx.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
#![cfg(not(test))]
2-
#![deny(warnings)]
32

4-
use libc::*;
5-
use testcrate::t1::*;
3+
cfg_if::cfg_if! {
4+
if #[cfg(has_cxx)] {
5+
use ctest_test::t1::*;
6+
use libc::*;
67

7-
include!(concat!(env!("OUT_DIR"), "/t1gen_cxx.rs"));
8+
include!(concat!(env!("OUT_DIR"), "/t1gen_cxx.rs"));
9+
} else {
10+
fn main() {}
11+
}
12+
}

ctest-test/src/bin/t2.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#![cfg(not(test))]
22
#![deny(warnings)]
33

4-
use testcrate::t2::*;
4+
use ctest_test::t2::*;
55

66
include!(concat!(env!("OUT_DIR"), "/t2gen.rs"));

ctest-test/src/bin/t2_cxx.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
#![cfg(not(test))]
2-
#![deny(warnings)]
32

4-
use testcrate::t2::*;
3+
cfg_if::cfg_if! {
4+
if #[cfg(has_cxx)] {
5+
use ctest_test::t2::*;
56

6-
include!(concat!(env!("OUT_DIR"), "/t2gen_cxx.rs"));
7+
include!(concat!(env!("OUT_DIR"), "/t2gen_cxx.rs"));
8+
} else {
9+
fn main() {}
10+
}
11+
}

ctest-test/src/t1.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,4 +72,6 @@ void* T1_vol0(volatile void* x, void* a) { return a? a: (void*)x; }
7272
volatile void* T1_vol1(void* x, void* b) { return b? (volatile void*)x : (volatile void*)x; }
7373
volatile void* T1_vol2(void* c, volatile void* x) { return c? x : x; }
7474

75+
/* FIXME(#4365): duplicate symbol errors when enabled
7576
uint8_t (* volatile T1_fn_ptr_vol)(uint8_t, uint8_t) = foo;
77+
*/

ctest-test/src/t1.h

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,17 @@ void T1v(const Arr* a);
6262

6363
extern uint32_t T1static;
6464
extern const uint8_t T1_static_u8;
65-
uint8_t T1_static_mut_u8;
66-
uint8_t (*T1_static_mut_fn_ptr)(uint8_t, uint8_t);
65+
/* FIXME(#4365): duplicate symbol errors when enabled
66+
// uint8_t T1_static_mut_u8;
67+
// uint8_t (*T1_static_mut_fn_ptr)(uint8_t, uint8_t);
6768
extern uint8_t (*const T1_static_const_fn_ptr_unsafe)(uint8_t, uint8_t);
69+
*/
6870
extern void (*const T1_static_const_fn_ptr_unsafe2)(uint8_t);
6971
extern void (*const T1_static_const_fn_ptr_unsafe3)(void);
7072

7173
extern const uint8_t T1_static_right;
72-
uint8_t (*T1_static_right2)(uint8_t, uint8_t);
74+
/* FIXME(#4365): duplicate symbol errors when enabled
75+
// uint8_t (*T1_static_right2)(uint8_t, uint8_t);
7376
7477
// T1_fn_ptr_nested: function pointer to a function, taking a uint8_t, and
7578
// returning a function pointer to a function taking a uint16_t and returning a
@@ -80,6 +83,7 @@ uint32_t (*(*T1_fn_ptr_s)(uint8_t))(uint16_t);
8083
// uint8_t -> uint8_t, and returning a function pointer to a function taking a
8184
// uint16_t and returning a uint32_t
8285
uint32_t (*(*T1_fn_ptr_s2)(uint8_t(*)(uint8_t), uint16_t(*)(uint16_t)))(uint16_t);
86+
*/
8387

8488
extern const int32_t T1_arr0[2];
8589
extern const int32_t T1_arr1[2][3];
@@ -98,8 +102,10 @@ extern int32_t* T1_mut_opt_mut_ref;
98102
extern const int32_t* T1_const_opt_const_ref;
99103

100104
extern void (*const T1_opt_fn1)(void);
101-
uint32_t (*(*T1_opt_fn2)(uint8_t))(uint16_t);
102-
uint32_t (*(*T1_opt_fn3)(uint8_t(*)(uint8_t), uint16_t(*)(uint16_t)))(uint16_t);
105+
/* FIXME(#4365): duplicate symbol errors when enabled
106+
// uint32_t (*(*T1_opt_fn2)(uint8_t))(uint16_t);
107+
// uint32_t (*(*T1_opt_fn3)(uint8_t(*)(uint8_t), uint16_t(*)(uint16_t)))(uint16_t);
108+
*/
103109

104110

105111
struct Q {
@@ -153,8 +159,10 @@ void* T1_vol0(volatile void*, void*);
153159
volatile void* T1_vol1(void*, void*);
154160
volatile void* T1_vol2(void*, volatile void*);
155161

162+
/* FIXME(#4365): duplicate symbol errors when enabled
156163
// volatile function pointers:
157164
uint8_t (*volatile T1_fn_ptr_vol)(uint8_t, uint8_t);
165+
*/
158166

159167
#define LOG_MAX_LINE_LENGTH (1400)
160168

ctest-test/src/t1.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,22 +93,26 @@ pub fn foo() {
9393

9494
extern "C" {
9595
pub static T1_static_u8: u8;
96-
pub static mut T1_static_mut_u8: u8;
97-
pub static mut T1_static_mut_fn_ptr: extern "C" fn(u8, u8) -> u8;
96+
/* FIXME(#4365): duplicate symbol errors when enabled
97+
// pub static mut T1_static_mut_u8: u8;
98+
// pub static mut T1_static_mut_fn_ptr: extern "C" fn(u8, u8) -> u8;
9899
pub static T1_static_const_fn_ptr_unsafe: unsafe extern "C" fn(u8, u8) -> u8;
100+
*/
99101
pub static T1_static_const_fn_ptr_unsafe2: unsafe extern "C" fn(u8) -> ();
100102
pub static T1_static_const_fn_ptr_unsafe3: unsafe extern "C" fn() -> ();
101103

102104
#[link_name = "T1_static_right"]
103105
pub static T1_static_wrong: u8;
104-
#[link_name = "T1_static_right2"]
105-
pub static mut T1_static_wrong2: extern "C" fn(u8, u8) -> u8;
106+
/* FIXME(#4365): duplicate symbol errors when enabled
107+
// #[link_name = "T1_static_right2"]
108+
// pub static mut T1_static_wrong2: extern "C" fn(u8, u8) -> u8;
106109
107110
pub static T1_fn_ptr_s: unsafe extern "C" fn(u8) -> extern "C" fn(u16) -> u32;
108111
pub static T1_fn_ptr_s2: unsafe extern "C" fn(
109112
extern "C" fn(u8) -> u8,
110113
extern "C" fn(u16) -> u16,
111114
) -> extern "C" fn(u16) -> u32;
115+
*/
112116

113117
pub static T1_arr0: [i32; 2];
114118
pub static T1_arr1: [[i32; 3]; 2];
@@ -128,13 +132,15 @@ extern "C" {
128132
pub static T1_const_opt_const_ref: Option<&'static i32>;
129133

130134
pub static T1_opt_fn1: Option<unsafe extern "C" fn() -> ()>;
135+
/* FIXME(#4365): duplicate symbol errors when enabled
131136
pub static T1_opt_fn2: Option<unsafe extern "C" fn(u8) -> extern "C" fn(u16) -> u32>;
132137
pub static T1_opt_fn3: Option<
133138
unsafe extern "C" fn(
134139
extern "C" fn(u8) -> u8,
135140
extern "C" fn(u16) -> u16,
136141
) -> extern "C" fn(u16) -> u32,
137142
>;
143+
*/
138144
}
139145

140146
#[repr(C)]
@@ -176,7 +182,9 @@ extern "C" {
176182
pub fn T1_vol0(arg0: *mut c_void, arg1: *mut c_void) -> *mut c_void;
177183
pub fn T1_vol1(arg0: *mut c_void, arg1: *mut c_void) -> *mut c_void;
178184
pub fn T1_vol2(arg0: *mut c_void, arg1: *mut c_void) -> *mut c_void;
185+
/* FIXME(#4365): duplicate symbol errors when enabled
179186
pub static T1_fn_ptr_vol: Option<unsafe extern "C" fn(u8, u8) -> u8>;
187+
*/
180188
}
181189

182190
pub const LOG_MAX_LINE_LENGTH: usize = 1400;

0 commit comments

Comments
 (0)