Skip to content

Commit d305cf9

Browse files
committed
✨ - Improve build
1 parent 9dd6c6d commit d305cf9

File tree

3 files changed

+194
-99
lines changed

3 files changed

+194
-99
lines changed

src/build.rs

Lines changed: 80 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ fn generate_asts(version: &str, build_state: &mut BuildState, pb: &ProgressBar)
379379
SourceType::SourceFile(source_file) => {
380380
let root_package = build_state.get_package(&build_state.root_config_name).unwrap();
381381

382-
let (ast_path, iast_path) = if source_file.implementation.dirty
382+
let (ast_path, iast_path, dirty) = if source_file.implementation.dirty
383383
|| source_file.interface.as_ref().map(|i| i.dirty).unwrap_or(false)
384384
{
385385
pb.inc(1);
@@ -403,7 +403,7 @@ fn generate_asts(version: &str, build_state: &mut BuildState, pb: &ProgressBar)
403403
_ => Ok(None),
404404
};
405405

406-
(ast_result, iast_result)
406+
(ast_result, iast_result, true)
407407
} else {
408408
(
409409
Ok((
@@ -414,10 +414,11 @@ fn generate_asts(version: &str, build_state: &mut BuildState, pb: &ProgressBar)
414414
.interface
415415
.as_ref()
416416
.map(|i| (helpers::get_basename(&i.path).to_string() + ".iast", None))),
417+
false,
417418
)
418419
};
419420

420-
(module_name.to_owned(), ast_path, iast_path, true)
421+
(module_name.to_owned(), ast_path, iast_path, dirty)
421422
}
422423
}
423424
})
@@ -441,6 +442,7 @@ fn generate_asts(version: &str, build_state: &mut BuildState, pb: &ProgressBar)
441442
SourceType::MlMap(_) => module.compile_dirty = true,
442443
_ => (),
443444
}
445+
module.compile_dirty = true
444446
}
445447
match ast_path {
446448
Ok((_path, err)) => {
@@ -671,6 +673,8 @@ pub fn parse_packages(build_state: &mut BuildState) {
671673
dependents: AHashSet::new(),
672674
package_name: package.name.to_owned(),
673675
compile_dirty: false,
676+
last_compiled_cmt: None,
677+
last_compiled_cmi: None,
674678
},
675679
);
676680
});
@@ -719,6 +723,8 @@ pub fn parse_packages(build_state: &mut BuildState) {
719723
dependents: AHashSet::new(),
720724
package_name: package.name.to_owned(),
721725
compile_dirty: true,
726+
last_compiled_cmt: None,
727+
last_compiled_cmi: None,
722728
});
723729
} else {
724730
// remove last character of string: resi -> res, rei -> re, mli -> ml
@@ -769,6 +775,8 @@ pub fn parse_packages(build_state: &mut BuildState) {
769775
dependents: AHashSet::new(),
770776
package_name: package.name.to_owned(),
771777
compile_dirty: true,
778+
last_compiled_cmt: None,
779+
last_compiled_cmi: None,
772780
});
773781
}
774782
}
@@ -1223,6 +1231,60 @@ fn format_dependency_cycle(cycle: &Vec<String>) -> String {
12231231
.join(" -> ")
12241232
}
12251233

1234+
pub fn mark_modules_with_deleted_deps_dirty(
1235+
build_state: &mut BuildState,
1236+
deleted_modules: &AHashSet<String>,
1237+
) {
1238+
build_state.modules.iter_mut().for_each(|(_, module)| {
1239+
if !module.deps.is_disjoint(deleted_modules) {
1240+
module.compile_dirty = true;
1241+
}
1242+
});
1243+
}
1244+
1245+
pub fn mark_modules_with_expired_deps_dirty(build_state: &mut BuildState) {
1246+
let mut modules_with_expired_deps: AHashSet<String> = AHashSet::new();
1247+
build_state
1248+
.modules
1249+
.iter()
1250+
.filter(|m| !m.1.is_mlmap())
1251+
.for_each(|(module_name, module)| {
1252+
for dependent in module.dependents.iter() {
1253+
let dependent_module = build_state.modules.get(dependent).unwrap();
1254+
match dependent_module.source_type {
1255+
SourceType::SourceFile(_) => {
1256+
match (module.last_compiled_cmt, module.last_compiled_cmi) {
1257+
(None, None) | (Some(_), None) | (None, Some(_)) => {
1258+
modules_with_expired_deps.insert(module_name.to_string());
1259+
}
1260+
(Some(_), Some(_)) => (),
1261+
}
1262+
1263+
// we compare the last compiled time of the dependent module with the last
1264+
// compile of the interface of the module it depends on, if the interface
1265+
// didn't change it doesn't matter
1266+
match (dependent_module.last_compiled_cmt, module.last_compiled_cmi) {
1267+
(Some(last_compiled_dependent), Some(last_compiled)) => {
1268+
if last_compiled_dependent < last_compiled {
1269+
modules_with_expired_deps.insert(dependent.to_string());
1270+
}
1271+
}
1272+
_ => (),
1273+
}
1274+
}
1275+
// a namespace is never a dependent of a module (it can be a dependency, but not the other
1276+
// way around)
1277+
SourceType::MlMap(_) => (),
1278+
}
1279+
}
1280+
});
1281+
build_state.modules.iter_mut().for_each(|(module_name, module)| {
1282+
if modules_with_expired_deps.contains(module_name) {
1283+
module.compile_dirty = true;
1284+
}
1285+
});
1286+
}
1287+
12261288
pub fn build(filter: &Option<regex::Regex>, path: &str, no_timing: bool) -> Result<BuildState, ()> {
12271289
let timing_total = Instant::now();
12281290
let project_root = helpers::get_abs_path(path);
@@ -1351,21 +1413,29 @@ pub fn build(filter: &Option<regex::Regex>, path: &str, no_timing: bool) -> Resu
13511413
let start_compiling = Instant::now();
13521414

13531415
let mut compiled_modules = AHashSet::<String>::new();
1416+
1417+
mark_modules_with_deleted_deps_dirty(&mut build_state, &deleted_module_names);
1418+
mark_modules_with_expired_deps_dirty(&mut build_state);
1419+
13541420
let dirty_modules = build_state
13551421
.modules
1356-
.iter_mut()
1422+
.iter()
13571423
.filter_map(|(module_name, module)| {
13581424
if module.compile_dirty {
13591425
Some(module_name.to_owned())
1360-
} else if !module.deps.is_disjoint(&deleted_module_names) {
1361-
module.compile_dirty = true;
1362-
Some(module_name.to_owned())
13631426
} else {
13641427
None
13651428
}
13661429
})
13671430
.collect::<AHashSet<String>>();
13681431

1432+
// println!("{} dirty modules", dirty_modules.len());
1433+
// let mut sorted_dirty_modules = dirty_modules.iter().collect::<Vec<&String>>();
1434+
// sorted_dirty_modules.sort();
1435+
// sorted_dirty_modules
1436+
// .iter()
1437+
// .for_each(|m| println!("dirty module: {}", m));
1438+
13691439
// for sure clean modules -- after checking the hash of the cmi
13701440
let mut clean_modules = AHashSet::<String>::new();
13711441

@@ -1382,10 +1452,6 @@ pub fn build(filter: &Option<regex::Regex>, path: &str, no_timing: bool) -> Resu
13821452
let mut sorted_modules = build_state.module_names.iter().collect::<Vec<&String>>();
13831453
sorted_modules.sort();
13841454

1385-
// for module in dirty_modules.clone() {
1386-
// println!("dirty module: {}", module);
1387-
// }
1388-
13891455
// this is the whole "compile universe" all modules that might be dirty
13901456
// we get this by traversing from the dirty modules to all the modules that
13911457
// are dependent on them
@@ -1406,6 +1472,7 @@ pub fn build(filter: &Option<regex::Regex>, path: &str, no_timing: bool) -> Resu
14061472
break;
14071473
}
14081474
}
1475+
14091476
let pb = ProgressBar::new(compile_universe.len().try_into().unwrap());
14101477
pb.set_style(
14111478
ProgressStyle::with_template(&format!(
@@ -1591,9 +1658,10 @@ pub fn build(filter: &Option<regex::Regex>, path: &str, no_timing: bool) -> Resu
15911658

15921659
// if not clean -- compile modules that depend on this module
15931660
for dep in module_dependents.iter() {
1594-
let dep_module = build_state.modules.get_mut(dep).unwrap();
15951661
// mark the reverse dep as dirty when the source is not clean
15961662
if !*is_clean {
1663+
let dep_module = build_state.modules.get_mut(dep).unwrap();
1664+
// mark the reverse dep as dirty when the source is not clean
15971665
dep_module.compile_dirty = true;
15981666
}
15991667
if !compiled_modules.contains(dep) {

src/build_types.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,17 @@ pub struct Module {
5959
pub dependents: AHashSet<String>,
6060
pub package_name: String,
6161
pub compile_dirty: bool,
62+
pub last_compiled_cmi: Option<SystemTime>,
63+
pub last_compiled_cmt: Option<SystemTime>,
64+
}
65+
66+
impl Module {
67+
pub fn is_mlmap(&self) -> bool {
68+
match self.source_type {
69+
SourceType::MlMap(_) => true,
70+
_ => false,
71+
}
72+
}
6273
}
6374

6475
#[derive(Debug)]

0 commit comments

Comments
 (0)