Skip to content

Commit 41e9c03

Browse files
committed
Refactor build rules
Remove include_dir from artifacts
1 parent 534bfed commit 41e9c03

File tree

4 files changed

+121
-175
lines changed

4 files changed

+121
-175
lines changed

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,4 @@ ucid = [] # accept UniCode IDentifiers
1818
members = ["testcrate"]
1919

2020
[dependencies]
21-
cc = "1.0.54"
21+
cc = { version = "1.2", features = ["parallel"] }

src/lib.rs

+58-120
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,26 @@ pub use self::Version::*;
1414
pub struct Build {
1515
out_dir: Option<PathBuf>,
1616
target: Option<String>,
17-
host: Option<String>,
1817
}
1918

2019
pub struct Artifacts {
21-
include_dir: PathBuf,
2220
lib_dir: PathBuf,
2321
libs: Vec<String>,
2422
}
2523

26-
impl Build {
27-
#[allow(clippy::new_without_default)]
28-
pub fn new() -> Build {
24+
impl Default for Build {
25+
fn default() -> Build {
2926
Build {
30-
out_dir: env::var_os("OUT_DIR").map(|s| PathBuf::from(s).join("lua-build")),
27+
out_dir: env::var_os("OUT_DIR").map(PathBuf::from),
3128
target: env::var("TARGET").ok(),
32-
host: env::var("HOST").ok(),
3329
}
3430
}
31+
}
32+
33+
impl Build {
34+
pub fn new() -> Build {
35+
Build::default()
36+
}
3537

3638
pub fn out_dir<P: AsRef<Path>>(&mut self, path: P) -> &mut Build {
3739
self.out_dir = Some(path.as_ref().to_path_buf());
@@ -43,43 +45,15 @@ impl Build {
4345
self
4446
}
4547

46-
pub fn host(&mut self, host: &str) -> &mut Build {
47-
self.host = Some(host.to_string());
48-
self
49-
}
50-
5148
pub fn build(&mut self, version: Version) -> Artifacts {
52-
let target = &self.target.as_ref().expect("TARGET not set")[..];
53-
let host = &self.host.as_ref().expect("HOST not set")[..];
54-
let out_dir = self.out_dir.as_ref().expect("OUT_DIR not set");
55-
let lib_dir = out_dir.join("lib");
56-
let include_dir = out_dir.join("include");
57-
58-
let source_dir_base = Path::new(env!("CARGO_MANIFEST_DIR"));
59-
let mut source_dir = match version {
60-
Lua51 => source_dir_base.join("lua-5.1.5"),
61-
Lua52 => source_dir_base.join("lua-5.2.4"),
62-
Lua53 => source_dir_base.join("lua-5.3.6"),
63-
Lua54 => source_dir_base.join("lua-5.4.7"),
64-
};
65-
66-
if lib_dir.exists() {
67-
fs::remove_dir_all(&lib_dir).unwrap();
68-
}
69-
fs::create_dir_all(&lib_dir).unwrap();
70-
71-
if include_dir.exists() {
72-
fs::remove_dir_all(&include_dir).unwrap();
73-
}
74-
fs::create_dir_all(&include_dir).unwrap();
49+
let target = &self.target.as_ref().expect("TARGET is not set")[..];
50+
let out_dir = self.out_dir.as_ref().expect("OUT_DIR is not set");
51+
let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
52+
let mut source_dir = manifest_dir.join(version.source_dir());
53+
let build_dir = out_dir.join("lua-build");
7554

7655
let mut config = cc::Build::new();
77-
config
78-
.target(target)
79-
.host(host)
80-
.warnings(false)
81-
.opt_level(2)
82-
.cargo_metadata(false);
56+
config.warnings(false).cargo_metadata(false);
8357

8458
match target {
8559
_ if target.contains("linux") => {
@@ -132,8 +106,8 @@ impl Build {
132106
}
133107
source_dir = cpp_source_dir
134108
}
135-
_ => panic!("don't know how to build Lua for {}", target),
136-
};
109+
_ => panic!("don't know how to build Lua for {target}"),
110+
}
137111

138112
if let Lua54 = version {
139113
config.define("LUA_COMPAT_5_3", None);
@@ -145,93 +119,42 @@ impl Build {
145119
config.define("LUA_USE_APICHECK", None);
146120
}
147121

148-
let lib_name = match version {
149-
Lua51 => "lua5.1",
150-
Lua52 => "lua5.2",
151-
Lua53 => "lua5.3",
152-
Lua54 => "lua5.4",
153-
};
154-
155122
config
156123
.include(&source_dir)
157124
.flag("-w") // Suppress all warnings
158125
.flag_if_supported("-fno-common") // Compile common globals like normal definitions
159-
.file(source_dir.join("lapi.c"))
160-
.file(source_dir.join("lauxlib.c"))
161-
.file(source_dir.join("lbaselib.c"))
162-
// skipped: lbitlib.c (>= 5.2, <= 5.3)
163-
.file(source_dir.join("lcode.c"))
164-
// skipped: lcorolib.c (>= 5.2)
165-
// skipped: lctype.c (>= 5.2)
166-
.file(source_dir.join("ldblib.c"))
167-
.file(source_dir.join("ldebug.c"))
168-
.file(source_dir.join("ldo.c"))
169-
.file(source_dir.join("ldump.c"))
170-
.file(source_dir.join("lfunc.c"))
171-
.file(source_dir.join("lgc.c"))
172-
.file(source_dir.join("linit.c"))
173-
.file(source_dir.join("liolib.c"))
174-
.file(source_dir.join("llex.c"))
175-
.file(source_dir.join("lmathlib.c"))
176-
.file(source_dir.join("lmem.c"))
177-
.file(source_dir.join("loadlib.c"))
178-
.file(source_dir.join("lobject.c"))
179-
.file(source_dir.join("lopcodes.c"))
180-
.file(source_dir.join("loslib.c"))
181-
.file(source_dir.join("lparser.c"))
182-
.file(source_dir.join("lstate.c"))
183-
.file(source_dir.join("lstring.c"))
184-
.file(source_dir.join("lstrlib.c"))
185-
.file(source_dir.join("ltable.c"))
186-
.file(source_dir.join("ltablib.c"))
187-
.file(source_dir.join("ltm.c"))
188-
.file(source_dir.join("lundump.c"))
189-
// skipped: lutf8lib.c (>= 5.3)
190-
.file(source_dir.join("lvm.c"))
191-
.file(source_dir.join("lzio.c"));
192-
193-
match version {
194-
Lua51 => {}
195-
Lua52 => {
196-
config
197-
.file(source_dir.join("lbitlib.c"))
198-
.file(source_dir.join("lcorolib.c"))
199-
.file(source_dir.join("lctype.c"));
200-
}
201-
Lua53 => {
202-
config
203-
.file(source_dir.join("lbitlib.c"))
204-
.file(source_dir.join("lcorolib.c"))
205-
.file(source_dir.join("lctype.c"))
206-
.file(source_dir.join("lutf8lib.c"));
207-
}
208-
Lua54 => {
209-
config
210-
.file(source_dir.join("lcorolib.c"))
211-
.file(source_dir.join("lctype.c"))
212-
.file(source_dir.join("lutf8lib.c"));
213-
}
214-
}
126+
.add_files_by_ext(&source_dir, "c")
127+
.out_dir(&build_dir)
128+
.compile(version.lib_name());
215129

216-
config.out_dir(&lib_dir).compile(lib_name);
130+
Artifacts {
131+
lib_dir: build_dir,
132+
libs: vec![version.lib_name().to_string()],
133+
}
134+
}
135+
}
217136

218-
for f in &["lauxlib.h", "lua.h", "luaconf.h", "lualib.h"] {
219-
fs::copy(source_dir.join(f), include_dir.join(f)).unwrap();
137+
impl Version {
138+
fn source_dir(&self) -> &str {
139+
match self {
140+
Lua51 => "lua-5.1.5",
141+
Lua52 => "lua-5.2.4",
142+
Lua53 => "lua-5.3.6",
143+
Lua54 => "lua-5.4.7",
220144
}
145+
}
221146

222-
Artifacts {
223-
lib_dir,
224-
include_dir,
225-
libs: vec![lib_name.to_string()],
147+
fn lib_name(&self) -> &str {
148+
match self {
149+
Lua51 => "lua5.1",
150+
Lua52 => "lua5.2",
151+
Lua53 => "lua5.3",
152+
Lua54 => "lua5.4",
226153
}
227154
}
228155
}
229156

230157
impl Artifacts {
231-
pub fn include_dir(&self) -> &Path {
232-
&self.include_dir
233-
}
234-
235158
pub fn lib_dir(&self) -> &Path {
236159
&self.lib_dir
237160
}
@@ -243,9 +166,24 @@ impl Artifacts {
243166
pub fn print_cargo_metadata(&self) {
244167
println!("cargo:rustc-link-search=native={}", self.lib_dir.display());
245168
for lib in self.libs.iter() {
246-
println!("cargo:rustc-link-lib=static={}", lib);
169+
println!("cargo:rustc-link-lib=static={lib}");
247170
}
248-
println!("cargo:include={}", self.include_dir.display());
249-
println!("cargo:lib={}", self.lib_dir.display());
171+
}
172+
}
173+
174+
trait AddFilesByExt {
175+
fn add_files_by_ext(&mut self, dir: &Path, ext: &str) -> &mut Self;
176+
}
177+
178+
impl AddFilesByExt for cc::Build {
179+
fn add_files_by_ext(&mut self, dir: &Path, ext: &str) -> &mut Self {
180+
for entry in fs::read_dir(dir)
181+
.unwrap()
182+
.filter_map(|e| e.ok())
183+
.filter(|e| e.path().extension() == Some(ext.as_ref()))
184+
{
185+
self.file(entry.path());
186+
}
187+
self
250188
}
251189
}

testcrate/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
name = "testcrate"
33
version = "0.1.0"
44
authors = ["Aleksandr Orlenko <[email protected]>"]
5+
edition = "2021"
6+
publish = false
57

68
[features]
79
lua54 = []

testcrate/src/lib.rs

+60-54
Original file line numberDiff line numberDiff line change
@@ -56,66 +56,72 @@ pub unsafe fn lua_pcall(
5656
lua_pcallk(state, nargs, nresults, errfunc, 0, std::ptr::null())
5757
}
5858

59-
#[test]
60-
fn test_lua() {
61-
use std::{ptr, slice};
62-
unsafe {
63-
let state = luaL_newstate();
64-
assert!(state != ptr::null_mut());
65-
66-
luaL_openlibs(state);
67-
68-
let version = {
69-
lua_getglobal(state, "_VERSION\0".as_ptr().cast());
70-
let mut len: c_long = 0;
71-
let version_ptr = lua_tolstring(state, -1, &mut len);
72-
slice::from_raw_parts(version_ptr as *const u8, len as usize)
73-
};
74-
75-
#[cfg(feature = "lua51")]
76-
assert_eq!(version, "Lua 5.1".as_bytes());
77-
#[cfg(feature = "lua52")]
78-
assert_eq!(version, "Lua 5.2".as_bytes());
79-
#[cfg(feature = "lua53")]
80-
assert_eq!(version, "Lua 5.3".as_bytes());
81-
#[cfg(feature = "lua54")]
82-
assert_eq!(version, "Lua 5.4".as_bytes());
83-
}
59+
pub unsafe fn to_string<'a>(state: *mut c_void, index: c_int) -> &'a str {
60+
let mut len: c_long = 0;
61+
let ptr = lua_tolstring(state, index, &mut len);
62+
let bytes = std::slice::from_raw_parts(ptr as *const u8, len as usize);
63+
std::str::from_utf8(bytes).unwrap()
8464
}
8565

86-
#[test]
87-
fn test_unicode_identifiers() {
88-
unsafe {
89-
let state = luaL_newstate();
90-
let code = "local 😀 = 0\0";
91-
let ret = luaL_loadstring(state, code.as_ptr().cast());
92-
#[cfg(feature = "lua54")]
93-
assert_eq!(0, ret);
94-
#[cfg(not(feature = "lua54"))]
95-
assert_ne!(0, ret);
66+
#[cfg(test)]
67+
mod tests {
68+
use super::*;
69+
70+
#[test]
71+
fn test_lua_version() {
72+
unsafe {
73+
let state = luaL_newstate();
74+
assert!(!state.is_null());
75+
76+
luaL_openlibs(state);
77+
78+
lua_getglobal(state, c"_VERSION".as_ptr());
79+
let version = to_string(state, -1);
80+
81+
#[cfg(feature = "lua51")]
82+
assert_eq!(version, "Lua 5.1");
83+
#[cfg(feature = "lua52")]
84+
assert_eq!(version, "Lua 5.2");
85+
#[cfg(feature = "lua53")]
86+
assert_eq!(version, "Lua 5.3");
87+
#[cfg(feature = "lua54")]
88+
assert_eq!(version, "Lua 5.4");
89+
}
9690
}
97-
}
9891

99-
#[test]
100-
fn test_exceptions() {
101-
use std::{ptr, slice, str};
102-
unsafe {
103-
let state = luaL_newstate();
104-
assert!(state != ptr::null_mut());
92+
#[test]
93+
fn test_unicode_identifiers() {
94+
unsafe {
95+
let state = luaL_newstate();
96+
let ret = luaL_loadstring(state, c"😀 = '🌚︎'".as_ptr());
97+
98+
#[cfg(feature = "lua54")]
99+
{
100+
assert_eq!(ret, 0);
101+
assert_eq!(lua_pcall(state, 0, 0, 0), 0);
102+
lua_getglobal(state, c"😀".as_ptr());
103+
assert_eq!(to_string(state, -1), "🌚︎");
104+
}
105105

106-
unsafe extern "C-unwind" fn it_panics(state: *mut c_void) -> c_int {
107-
luaL_error(state, "exception!\0".as_ptr().cast())
106+
#[cfg(not(feature = "lua54"))]
107+
assert_ne!(ret, 0);
108108
}
109+
}
109110

110-
lua_pushcclosure(state, it_panics, 0);
111-
let result = lua_pcall(state, 0, 0, 0);
112-
assert_eq!(result, 2); // LUA_ERRRUN
113-
let s = {
114-
let mut len: c_long = 0;
115-
let version_ptr = lua_tolstring(state, -1, &mut len);
116-
let s = slice::from_raw_parts(version_ptr as *const u8, len as usize);
117-
str::from_utf8(s).unwrap()
118-
};
119-
assert_eq!(s, "exception!");
111+
#[test]
112+
fn test_exceptions() {
113+
unsafe {
114+
let state = luaL_newstate();
115+
assert!(!state.is_null());
116+
117+
unsafe extern "C-unwind" fn it_panics(state: *mut c_void) -> c_int {
118+
luaL_error(state, c"exception!".as_ptr())
119+
}
120+
121+
lua_pushcclosure(state, it_panics, 0);
122+
let result = lua_pcall(state, 0, 0, 0);
123+
assert_eq!(result, 2); // LUA_ERRRUN
124+
assert_eq!(to_string(state, -1), "exception!");
125+
}
120126
}
121127
}

0 commit comments

Comments
 (0)