Skip to content

Commit 328f419

Browse files
committed
individualized target build non-working
1 parent 2c798e4 commit 328f419

File tree

4 files changed

+141
-80
lines changed

4 files changed

+141
-80
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[package]
2+
name = "core_ffi_typcheck"
3+
version = "0.1.0"
4+
edition = "2021"
5+
build = "build.rs"
6+
7+
[workspace]
8+
9+
[lib]
10+
path = "mod.rs"
11+
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
use std::fs::File;
2+
use std::io::Write;
3+
use std::process::Command;
4+
5+
//acquires all c types using grep command
6+
// TODO: add different system support (e.g. Windows)
7+
fn get_c_types() -> Vec<String> {
8+
let output = Command::new("sh")
9+
.arg("-c")
10+
.arg("grep 'type c_[^ ]*' mod.rs -o | cut -d' ' -f2 | sort -u")
11+
.output()
12+
.expect("Failed, please run on UNIX system");
13+
14+
String::from_utf8(output.stdout)
15+
.expect("please use unix system")
16+
.lines()
17+
.map(|s| s.to_string())
18+
.collect()
19+
}
20+
21+
fn main() {
22+
let dest_path = "type_sizes.rs";
23+
println!("cargo:warning=Writing to: {}", dest_path);
24+
25+
let mut f = File::create(dest_path).unwrap();
26+
27+
let c_types = get_c_types();
28+
println!("cargo:warning=Found C types: {:?}", c_types);
29+
30+
writeln!(f, "pub fn create_type_sizes() -> std::collections::HashMap<String, String> {{")
31+
.unwrap();
32+
writeln!(f, " let mut sizes = std::collections::HashMap::new();").unwrap();
33+
34+
for type_name in c_types {
35+
writeln!(
36+
f,
37+
" sizes.insert(\"{0}\".to_string(), std::mem::size_of::<core::ffi::{0}>().to_string());",
38+
type_name
39+
).unwrap();
40+
}
41+
42+
writeln!(f, " sizes").unwrap();
43+
writeln!(f, "}}").unwrap();
44+
45+
println!("cargo:rerun-if-changed=mod.rs");
46+
println!("cargo:rerun-if-changed=build.rs");
47+
}
Lines changed: 68 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,8 @@
11
use std::collections::HashMap;
22

3-
use run_make_support::{clang, rfs, rustc, serde_json};
4-
5-
const C_TYPES: &[(&str, &str)] = &[
6-
("c_char", "__CHAR_BIT__"), // Character width
7-
("char_signedness", "__CHAR_UNSIGNED__"),
8-
("c_double", "__SIZEOF_DOUBLE__"), // Double precision floating-point
9-
("c_float", "__SIZEOF_FLOAT__"), // Single precision floating-point
10-
("c_int", "__SIZEOF_INT__"), // Signed integer
11-
("c_long", "__SIZEOF_LONG__"), // Signed long integer
12-
("c_longlong", "__SIZEOF_LONG_LONG__"), // Signed long long integer
13-
("c_schar", "__SIZEOF_CHAR__"), // Signed char
14-
("c_short", "__SIZEOF_SHORT__"), // Signed short integer
15-
("c_uchar", "__SIZEOF_CHAR__"), // Unsigned char
16-
("c_uint", "__SIZEOF_INT__"), // Unsigned integer
17-
("c_ulong", "__SIZEOF_LONG__"), // Unsigned long integer
18-
("c_ulonglong", "__SIZEOF_LONG_LONG__"), // Unsigned long long integer
19-
("c_ushort", "__SIZEOF_SHORT__"), // Unsigned short integer
20-
("c_size_t", "__SIZEOF_SIZE_T__"), // Size type
21-
("c_ptrdiff_t", "__SIZEOF_PTRDIFF_T__"), // Pointer difference type];
22-
];
23-
24-
// #define __CHAR_BIT__ 8 // c_char
25-
// #define __CHAR_UNSIGNED__ 1 // char signedness
26-
27-
// #define __SIZEOF_DOUBLE__ 8 // c_double
28-
// #define __SIZEOF_FLOAT__ 4 // c_float
29-
// #define __SIZEOF_INT__ 4 // c_int
30-
// #define __SIZEOF_LONG_DOUBLE__ 16 // c_longdouble
31-
// #define __SIZEOF_LONG_LONG__ 8 // c_longlong
32-
// #define __SIZEOF_LONG__ 4 // c_long
33-
// #define __SIZEOF_POINTER__ 4 // *const c_void
34-
// #define __SIZEOF_PTRDIFF_T__ 4 // c_ptrdiff_t
35-
// #define __SIZEOF_SHORT__ 2 // c_short
36-
// #define __SIZEOF_SIZE_T__ 4 // c_size_t
37-
38-
// const ADDITIONAL_CHECKS: &[(&str, &str)] = &[
39-
// ("bool", "__BOOL_WIDTH__"),
40-
// ("isize", "__INTPTR_WIDTH__"),
41-
// ("usize", "__UINTPTR_WIDTH__"),
42-
// ("c_int_width", "__INT_WIDTH__"),
43-
// ("c_long_width", "__LONG_WIDTH__"),
44-
// ("c_longlong_width", "__LLONG_WIDTH__"),
45-
// ("c_short_width", "__SHRT_WIDTH__"),
46-
// ("c_size_t_width", "__SIZE_WIDTH__"),
47-
// ];
3+
include!("type_sizes.rs");
4+
5+
use run_make_support::{cargo, clang, rustc, serde_json};
486

497
type ClangDefinitions = HashMap<String, String>;
508
type TargetDefinitions = HashMap<String, ClangDefinitions>;
@@ -82,16 +40,13 @@ fn get_clang_definitions(llvm_target: &str) -> HashMap<String, String> {
8240

8341
//extract only the relevant defines
8442
let mut definitions = HashMap::new();
85-
let relevant_defines: Vec<&str> = C_TYPES.iter().map(|(_, define)| *define).collect();
8643

8744
for line in output.lines() {
8845
if let Some((key, value)) = line.strip_prefix("#define ").and_then(|l| {
8946
let mut parts = l.split_whitespace();
9047
Some((parts.next()?, parts.next()?))
9148
}) {
92-
if relevant_defines.contains(&key) {
93-
definitions.insert(key.to_string(), value.to_string());
94-
}
49+
definitions.insert(key.to_string(), value.to_string());
9550
}
9651
}
9752

@@ -112,32 +67,33 @@ fn collect_clang_definitions(target: &HashMap<String, String>) -> TargetDefiniti
11267
all_definitions
11368
}
11469

115-
fn generate_rust_test(definitions: HashMap<String, String>) -> String {
116-
//clang definition | int
117-
let mut test_code = String::new();
118-
test_code.push_str("use std::ffi::c_char;\n");
119-
test_code.push_str("fn main() {");
120-
121-
if let Some(is_unsigned) = definitions.get("__CHAR_UNSIGNED__") {
122-
let char_type = if is_unsigned == "1" { "u8" } else { "i8" };
123-
test_code.push_str(&format!(" const _CHAR: c_char = 0_{char_type};\n"));
124-
}
125-
126-
test_code.push_str("}\n");
127-
128-
test_code
70+
//i need to rebuild every single time to get the new types.
71+
fn get_core_ffi_types() -> HashMap<String, String> {
72+
create_type_sizes()
12973
}
130-
131-
// DEBUGGING PURPOSES
132-
// fn print_definitions(all_definitions: &TargetDefinitions) {
133-
// let mut file = File::create("debug_output.txt").expect("Unable to create file");
134-
// for (target, definitions) in all_definitions {
135-
// writeln!(file, "Target: {}", target).expect("Write failed");
136-
// for (define, val) in definitions {
137-
// writeln!(file, " {} = {}", define, val).expect("Write failed");
138-
// }
139-
// }
140-
// }
74+
//c_char -> size
75+
//c_int -> size
76+
// c_long -> size
77+
// c_ptrdiff_t
78+
// c_size_t
79+
// c_ssize_t
80+
// c_uint
81+
// c_ulong
82+
83+
// __CHAR_BIT__ = 8
84+
// __CHAR_UNSIGNED__ = 1
85+
// __SIZEOF_DOUBLE__ = 8
86+
// __SIZEOF_INT__ = 4
87+
// __SIZEOF_LONG__ = 8
88+
// __SIZEOF_PTRDIFF_T__ = 8
89+
// __SIZEOF_SIZE_T__ = 8
90+
// __SIZEOF_FLOAT__ = 4
91+
// __SIZEOF_LONG_LONG__ = 8
92+
// __SIZEOF_SHORT__ = 2
93+
94+
//fn check_type_allignment(core_types: &HashMap<String, String>, llvm_target: String, llvm_target_defines: &HashMap<String, String>) {
95+
//
96+
//}
14197

14298
fn main() {
14399
let output = get_target_list();
@@ -153,16 +109,48 @@ fn main() {
153109
}
154110
}
155111

112+
let core_ffi_types = get_core_ffi_types();
113+
println!("Core FFI types: {:?}", core_ffi_types);
114+
156115
let all_definitions = collect_clang_definitions(&target_map);
157116

117+
//now need to compare the types to the definition sizes.
118+
158119
//print_definitions(&all_definitions);
159120

160121
//all_definitions Hash<TARGET, HASH<DEFINE, VAL>>
161122

162-
rfs::create_file("test.rs");
163-
for defines in all_definitions.values() {
164-
let test = generate_rust_test(defines.clone());
165-
rfs::write("test.rs", test);
166-
rustc().arg("-Z").arg("no-codegen").arg("test.rs").run();
167-
}
123+
//do not think this is right.
124+
// rfs::create_file("test.rs");
125+
// for defines in all_definitions.values() {
126+
// let test = generate_rust_test(defines.clone(), core_ffi_types);
127+
// rfs::write("test.rs", test);
128+
// rustc().arg("-Z").arg("no-codegen").arg("test.rs").run();
129+
// }
130+
}
131+
132+
// //check char_bit
133+
// // this can be checked, specifically c_char
134+
// //llvm_target_defines.find(__CHAR_BIT__) != llvm_target_defines.end()
135+
// // then can compare to c_char and make sure sizes allign
136+
// // if sizes dont allign print("error sizes do not allign for {llvm_target})
137+
// if let (Some(char_bit), Some(c_char)) = (
138+
// llvm_target_defines.get("__CHAR_BIT__").and_then(|v| v.parse::<usize>().ok()),
139+
// core_types.get("c_char").and_then(|v| v.parse::<usize>().ok())
140+
// ) {
141+
// if char_bit != c_char {
142+
// println!("error: sizes do not align for {}: CHAR_BIT is {} but c_char is {} bits",
143+
// llvm_target, char_bit, c_char);
144+
// }
145+
// }
146+
// //this needs to be worked on, cannot really do this.
147+
148+
//check unsigned
149+
// im not too sure if this needs to be checked for core::ffi will look into this.
150+
// check unsigned with system
151+
/*
152+
if let Some(is_unsigned) = definitions.get("__CHAR_UNSIGNED__") {
153+
let char_type = if is_unsigned == "1" { "u8" } else { "i8" };
154+
test_code.push_str(&format!(" const _CHAR: c_char = 0_{char_type};\n"));
168155
}
156+
*/
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
pub fn create_type_sizes() -> std::collections::HashMap<String, String> {
2+
let mut sizes = std::collections::HashMap::new();
3+
sizes.insert("c_char".to_string(), std::mem::size_of::<core::ffi::c_char>().to_string());
4+
sizes.insert("c_int".to_string(), std::mem::size_of::<core::ffi::c_int>().to_string());
5+
sizes.insert("c_long".to_string(), std::mem::size_of::<core::ffi::c_long>().to_string());
6+
sizes.insert(
7+
"c_ptrdiff_t".to_string(),
8+
std::mem::size_of::<core::ffi::c_ptrdiff_t>().to_string(),
9+
);
10+
sizes.insert("c_size_t".to_string(), std::mem::size_of::<core::ffi::c_size_t>().to_string());
11+
sizes.insert("c_ssize_t".to_string(), std::mem::size_of::<core::ffi::c_ssize_t>().to_string());
12+
sizes.insert("c_uint".to_string(), std::mem::size_of::<core::ffi::c_uint>().to_string());
13+
sizes.insert("c_ulong".to_string(), std::mem::size_of::<core::ffi::c_ulong>().to_string());
14+
sizes
15+
}

0 commit comments

Comments
 (0)