From 0303e644ff09069ce873035218d859f98611d293 Mon Sep 17 00:00:00 2001 From: Travers Biddle Date: Sat, 18 Apr 2026 14:26:17 +1000 Subject: [PATCH 1/3] fix: Iterate all libs in order of definition --- src/generator/msvc.rs | 31 ++--- src/generator/ninja.rs | 38 +++--- src/generator/xcode.rs | 181 +++++++++++++++-------------- src/object_library.rs | 1 + src/project.rs | 2 + src/starlark_api.rs | 6 +- src/starlark_link_target.rs | 2 +- src/starlark_project.rs | 38 ++++++ src/static_library.rs | 1 + test_data/test_01/build.catapult | 7 +- test_data/test_01/mylib_helper.cpp | 7 ++ test_data/test_01/mylib_helper.hpp | 3 + tests/test.rs | 2 +- 13 files changed, 198 insertions(+), 121 deletions(-) create mode 100644 test_data/test_01/mylib_helper.cpp create mode 100644 test_data/test_01/mylib_helper.hpp diff --git a/src/generator/msvc.rs b/src/generator/msvc.rs index 9c53f64..b6b939c 100644 --- a/src/generator/msvc.rs +++ b/src/generator/msvc.rs @@ -468,19 +468,24 @@ impl Msvc { Self::generate_inner(subproject, proj_opts, targets)?; } - for lib in &project.static_libraries { - if !targets.contains_key(&as_key(lib)) { - add_static_lib(lib, proj_opts, targets)?; - } - } - for lib in &project.object_libraries { - if !targets.contains_key(&as_key(lib)) { - add_object_lib(lib, proj_opts, targets)?; - } - } - for lib in &project.shared_libraries { - if !targets.contains_key(&as_key(lib)) { - add_shared_lib(lib, proj_opts, targets)?; + for lib in &project.link_targets { + match lib { + LinkPtr::Static(lib) => { + if !targets.contains_key(&as_key(lib)) { + add_static_lib(lib, proj_opts, targets)?; + } + } + LinkPtr::Object(lib) => { + if !targets.contains_key(&as_key(lib)) { + add_object_lib(lib, proj_opts, targets)?; + } + } + LinkPtr::Interface(_) => {} + LinkPtr::Shared(lib) => { + if !targets.contains_key(&as_key(lib)) { + add_shared_lib(lib, proj_opts, targets)?; + } + } } } for exe in &project.executables { diff --git a/src/generator/ninja.rs b/src/generator/ninja.rs index 72b560b..5dd67a5 100644 --- a/src/generator/ninja.rs +++ b/src/generator/ninja.rs @@ -385,27 +385,28 @@ impl Ninja { Ninja::generate_inner(subproject, generator_opts, rules, build_lines, link_targets)?; } - for lib in &project.static_libraries { - if !link_targets.contains_key(&LinkPtr::Static(lib.clone())) { - add_static_lib_target(lib, generator_opts, rules, build_lines, link_targets)?; - } - } - - for lib in &project.object_libraries { - if !link_targets.contains_key(&LinkPtr::Object(lib.clone())) { - add_object_lib_target(lib, generator_opts, rules, build_lines, link_targets)?; + for lib in &project.link_targets { + match lib { + LinkPtr::Static(lib) => { + if !link_targets.contains_key(&LinkPtr::Static(lib.clone())) { + add_static_lib_target(lib, generator_opts, rules, build_lines, link_targets)?; + } + } + LinkPtr::Object(lib) => { + if !link_targets.contains_key(&LinkPtr::Object(lib.clone())) { + add_object_lib_target(lib, generator_opts, rules, build_lines, link_targets)?; + } + } + LinkPtr::Interface(lib) => { + let key = LinkPtr::Interface(lib.clone()); + link_targets.entry(key).or_default(); + } + LinkPtr::Shared(lib) => { + add_shared_lib_target(lib, generator_opts, rules, build_lines, link_targets)?; + } } } - for lib in &project.interface_libraries { - let key = LinkPtr::Interface(lib.clone()); - link_targets.entry(key).or_default(); - } - - for lib in &project.shared_libraries { - add_shared_lib_target(lib, generator_opts, rules, build_lines, link_targets)?; - } - for exe in &project.executables { add_executable_target(exe, generator_opts, rules, build_lines, link_targets)?; } @@ -1271,6 +1272,7 @@ fn test_position_independent_code() { generator_vars: None, output_name: None, })], + link_targets: vec![LinkPtr::Static(create_lib(weak_parent))], static_libraries: vec![create_lib(weak_parent)], object_libraries: Vec::new(), interface_libraries: Vec::new(), diff --git a/src/generator/xcode.rs b/src/generator/xcode.rs index f06b361..74c288b 100644 --- a/src/generator/xcode.rs +++ b/src/generator/xcode.rs @@ -1115,92 +1115,95 @@ fn project_targets( let mut native_target_keys = Vec::new(); let mut external_projects = HashMap::::new(); - for lib in &project.object_libraries { - let key = new_native_target_archive( - lib.as_ref(), - &lib.sources, - &lib.generator_vars, - native_target_build_configs, - toolchain, - graph, - id_gen, - global_targets, - &mut external_projects, - build_dir, - )?; - let nt = graph.native_targets.get(&key).unwrap(); - let prod_ref = graph.file_references.get(&nt.product_reference).unwrap(); - global_targets.insert( - as_key(lib), - GlobalTargetMeta { - project_info: project.info.clone(), - native_target_id: nt.id.clone(), - product_reference_id: prod_ref.id.clone(), - target_name: nt.name.clone(), - product_name: nt.product_name.clone(), - local_key: key, - product_kind: XcodeProductKind::StaticArchive, - }, - ); - native_target_keys.push(key); - } - - for lib in &project.static_libraries { - let key = new_native_target_archive( - lib.as_ref(), - &lib.sources, - &lib.generator_vars, - native_target_build_configs, - toolchain, - graph, - id_gen, - global_targets, - &mut external_projects, - build_dir, - )?; - let nt = graph.native_targets.get(&key).unwrap(); - let prod_ref = graph.file_references.get(&nt.product_reference).unwrap(); - global_targets.insert( - as_key(lib), - GlobalTargetMeta { - project_info: project.info.clone(), - native_target_id: nt.id.clone(), - product_reference_id: prod_ref.id.clone(), - target_name: nt.name.clone(), - product_name: nt.product_name.clone(), - local_key: key, - product_kind: XcodeProductKind::StaticArchive, - }, - ); - native_target_keys.push(key); - } - - for lib in &project.shared_libraries { - let key = new_native_target_shared( - lib, - native_target_build_configs, - toolchain, - graph, - id_gen, - global_targets, - &mut external_projects, - build_dir, - )?; - let nt = graph.native_targets.get(&key).unwrap(); - let prod_ref = graph.file_references.get(&nt.product_reference).unwrap(); - global_targets.insert( - as_key(lib), - GlobalTargetMeta { - project_info: project.info.clone(), - native_target_id: nt.id.clone(), - product_reference_id: prod_ref.id.clone(), - target_name: nt.name.clone(), - product_name: nt.product_name.clone(), - local_key: key, - product_kind: XcodeProductKind::DynamicLibrary, - }, - ); - native_target_keys.push(key); + for lib in &project.link_targets { + match lib { + LinkPtr::Static(lib) => { + let key = new_native_target_archive( + lib.as_ref(), + &lib.sources, + &lib.generator_vars, + native_target_build_configs, + toolchain, + graph, + id_gen, + global_targets, + &mut external_projects, + build_dir, + )?; + let nt = graph.native_targets.get(&key).unwrap(); + let prod_ref = graph.file_references.get(&nt.product_reference).unwrap(); + global_targets.insert( + as_key(lib), + GlobalTargetMeta { + project_info: project.info.clone(), + native_target_id: nt.id.clone(), + product_reference_id: prod_ref.id.clone(), + target_name: nt.name.clone(), + product_name: nt.product_name.clone(), + local_key: key, + product_kind: XcodeProductKind::StaticArchive, + }, + ); + native_target_keys.push(key); + } + LinkPtr::Object(lib) => { + let key = new_native_target_archive( + lib.as_ref(), + &lib.sources, + &lib.generator_vars, + native_target_build_configs, + toolchain, + graph, + id_gen, + global_targets, + &mut external_projects, + build_dir, + )?; + let nt = graph.native_targets.get(&key).unwrap(); + let prod_ref = graph.file_references.get(&nt.product_reference).unwrap(); + global_targets.insert( + as_key(lib), + GlobalTargetMeta { + project_info: project.info.clone(), + native_target_id: nt.id.clone(), + product_reference_id: prod_ref.id.clone(), + target_name: nt.name.clone(), + product_name: nt.product_name.clone(), + local_key: key, + product_kind: XcodeProductKind::StaticArchive, + }, + ); + native_target_keys.push(key); + } + LinkPtr::Shared(lib) => { + let key = new_native_target_shared( + lib, + native_target_build_configs, + toolchain, + graph, + id_gen, + global_targets, + &mut external_projects, + build_dir, + )?; + let nt = graph.native_targets.get(&key).unwrap(); + let prod_ref = graph.file_references.get(&nt.product_reference).unwrap(); + global_targets.insert( + as_key(lib), + GlobalTargetMeta { + project_info: project.info.clone(), + native_target_id: nt.id.clone(), + product_reference_id: prod_ref.id.clone(), + target_name: nt.name.clone(), + product_name: nt.product_name.clone(), + local_key: key, + product_kind: XcodeProductKind::DynamicLibrary, + }, + ); + native_target_keys.push(key); + } + LinkPtr::Interface(_) => {} + } } for exe in &project.executables { @@ -2443,6 +2446,11 @@ fn test_pbxproj_generation() { }), dependencies: Vec::new(), executables: vec![exe], + link_targets: vec![ + LinkPtr::Object(subtracter.clone()), + LinkPtr::Static(adder.clone()), + LinkPtr::Interface(arithmetic.clone()), + ], static_libraries: vec![adder], object_libraries: vec![subtracter], interface_libraries: vec![arithmetic], @@ -2552,6 +2560,7 @@ fn test_xcode_transform() { }), dependencies: Vec::new(), executables: vec![exe], + link_targets: vec![LinkPtr::Static(adder.clone()), LinkPtr::Interface(iface.clone())], static_libraries: vec![adder], object_libraries: Vec::new(), interface_libraries: vec![iface], diff --git a/src/object_library.rs b/src/object_library.rs index 6f6f1f6..da2e1f2 100644 --- a/src/object_library.rs +++ b/src/object_library.rs @@ -233,6 +233,7 @@ mod tests { info: Arc::new(crate::project::ProjectInfo { name: "test".to_owned(), path: PathBuf::from(".") }), dependencies: Vec::new(), executables: Vec::new(), + link_targets: Vec::new(), static_libraries: vec![ leaf_shared, leaf_pub_pub, diff --git a/src/project.rs b/src/project.rs index a45049f..bc7b282 100644 --- a/src/project.rs +++ b/src/project.rs @@ -6,6 +6,7 @@ use std::{ use crate::{ executable::Executable, // interface_library::InterfaceLibrary, + link_type::LinkPtr, object_library::ObjectLibrary, shared_library::SharedLibrary, static_library::StaticLibrary, @@ -22,6 +23,7 @@ pub struct Project { pub info: Arc, pub dependencies: Vec>, pub executables: Vec>, + pub link_targets: Vec, pub static_libraries: Vec>, pub object_libraries: Vec>, pub interface_libraries: Vec>, diff --git a/src/starlark_api.rs b/src/starlark_api.rs index 22964e5..47bc354 100644 --- a/src/starlark_api.rs +++ b/src/starlark_api.rs @@ -19,7 +19,7 @@ use starlark::{ use crate::{ starlark_executable::{StarExecutable, StarExecutableWrapper}, starlark_interface_library::{StarIfaceLibWrapper, StarIfaceLibrary}, - starlark_link_target::StarLinkTarget, + starlark_link_target::{PtrLinkTarget, StarLinkTarget}, starlark_object_library::{StarGeneratorVars, StarObjLibWrapper, StarObjectLibrary}, starlark_project::StarProject, starlark_shared_library::{StarSharedLibWrapper, StarSharedLibrary}, @@ -131,6 +131,7 @@ pub(crate) fn build_api(builder: &mut GlobalsBuilder) { output_name: None, // TODO(Travers) }); let mut project = state.project.lock().map_err(|e| anyhow::anyhow!(e.to_string()))?; + project.link_targets.push(PtrLinkTarget(lib.clone())); project.static_libraries.push(lib.clone()); Ok(StarStaticLibWrapper(lib)) } @@ -168,6 +169,7 @@ pub(crate) fn build_api(builder: &mut GlobalsBuilder) { output_name: None, // TODO(Travers) }); let mut project = state.project.lock().map_err(|e| anyhow::anyhow!(e.to_string()))?; + project.link_targets.push(PtrLinkTarget(lib.clone())); project.object_libraries.push(lib.clone()); Ok(StarObjLibWrapper(lib)) } @@ -196,6 +198,7 @@ pub(crate) fn build_api(builder: &mut GlobalsBuilder) { // generator_vars: generator_func(generator_vars, eval)?, }); let mut project = state.project.lock().map_err(|e| anyhow::anyhow!(e.to_string()))?; + project.link_targets.push(PtrLinkTarget(lib.clone())); project.interface_libraries.push(lib.clone()); Ok(StarIfaceLibWrapper(lib)) } @@ -233,6 +236,7 @@ pub(crate) fn build_api(builder: &mut GlobalsBuilder) { output_name: None, // TODO(Travers) }); let mut project = state.project.lock().map_err(|e| anyhow::anyhow!(e.to_string()))?; + project.link_targets.push(PtrLinkTarget(lib.clone())); project.shared_libraries.push(lib.clone()); Ok(StarSharedLibWrapper(lib)) } diff --git a/src/starlark_link_target.rs b/src/starlark_link_target.rs index 280967f..d4296b5 100644 --- a/src/starlark_link_target.rs +++ b/src/starlark_link_target.rs @@ -28,7 +28,7 @@ pub(super) trait StarLinkTarget: Send + Sync + fmt::Debug + Allocative { fn public_includes_recursive(&self) -> Vec; } -#[derive(Clone)] +#[derive(Allocative, Clone, Debug)] pub(super) struct PtrLinkTarget(pub Arc); impl cmp::PartialEq for PtrLinkTarget { diff --git a/src/starlark_project.rs b/src/starlark_project.rs index afb5296..0ac0210 100644 --- a/src/starlark_project.rs +++ b/src/starlark_project.rs @@ -38,6 +38,7 @@ use crate::{ starlark_shared_library::{StarSharedLibWrapper, StarSharedLibrary}, starlark_static_library::{StarStaticLibWrapper, StarStaticLibrary}, static_library::StaticLibrary, + target::Target, }; #[derive(Clone, Debug, ProvidesStaticType, NoSerialize, Allocative)] @@ -46,6 +47,7 @@ pub(super) struct StarProject { pub path: PathBuf, pub dependencies: Vec>, pub executables: Vec>, + pub link_targets: Vec, pub static_libraries: Vec>, pub object_libraries: Vec>, pub interface_libraries: Vec>, @@ -218,6 +220,7 @@ impl StarProject { path, dependencies, executables: Vec::new(), + link_targets: Vec::new(), static_libraries: Vec::new(), object_libraries: Vec::new(), interface_libraries: Vec::new(), @@ -248,6 +251,7 @@ impl StarProject { } ) .collect::>()?, + link_targets: Vec::new(), static_libraries: self .static_libraries .iter() @@ -309,6 +313,16 @@ impl StarProject { }) .collect::>()?, }; //); + project.link_targets = self + .link_targets + .iter() + .map(|x| { + link_map + .get(x) + .ok_or_else(|| format!("Could not find target \"{}\" in link map", x.0.name())) + }) + .collect::>()?; + validate_library_dependency_order(&project)?; let ret = Arc::::new_cyclic(move |weak_parent: &Weak| -> Project { // We need one of the following to set the Weak parent without using unsafe: @@ -339,3 +353,27 @@ impl StarProject { Ok(ret) } } + +fn validate_library_dependency_order(project: &Project) -> Result<(), String> { + let mut all_targets = HashSet::new(); + let mut seen_targets = HashSet::new(); + for target in &project.link_targets { + all_targets.insert(target.clone()); + } + for target in &project.link_targets { + for dependency in target.internal_links() { + if all_targets.contains(&dependency) && !seen_targets.contains(&dependency) { + return Err(format!( + "Library order violation in project \"{}\": target \"{}\" depends on \"{}\" which is declared later. Declare \"{}\" before \"{}\".", + project.info.name, + target.name(), + dependency.name(), + dependency.name(), + target.name() + )); + } + } + seen_targets.insert(target.clone()); + } + Ok(()) +} diff --git a/src/static_library.rs b/src/static_library.rs index 8dbf356..f1b3ca4 100644 --- a/src/static_library.rs +++ b/src/static_library.rs @@ -233,6 +233,7 @@ mod tests { info: Arc::new(crate::project::ProjectInfo { name: "test".to_owned(), path: PathBuf::from(".") }), dependencies: Vec::new(), executables: Vec::new(), + link_targets: Vec::new(), static_libraries: vec![ leaf_shared, leaf_pub_pub, diff --git a/test_data/test_01/build.catapult b/test_data/test_01/build.catapult index 59ee5e0..df40541 100644 --- a/test_data/test_01/build.catapult +++ b/test_data/test_01/build.catapult @@ -1,10 +1,15 @@ +mylib_helper = add_static_library( + name = "mylib_helper", + include_dirs_public = ["."], + sources = ["mylib_helper.cpp"], +) mylib = add_shared_library( name = "mylib", sources = ["mylib.cpp"], defines_private = ["MYLIB_EXPORT"], include_dirs_public = ["."], - link_private = [my_depend.my_depend_lib], + link_private = [mylib_helper, my_depend.my_depend_lib], ) print('--- ' + str(mylib)) diff --git a/test_data/test_01/mylib_helper.cpp b/test_data/test_01/mylib_helper.cpp new file mode 100644 index 0000000..f1b6626 --- /dev/null +++ b/test_data/test_01/mylib_helper.cpp @@ -0,0 +1,7 @@ +#include "mylib_helper.hpp" + +#include + +void add_two_helper() { + std::cout << "add_two_helper()\n"; +} diff --git a/test_data/test_01/mylib_helper.hpp b/test_data/test_01/mylib_helper.hpp new file mode 100644 index 0000000..369f69f --- /dev/null +++ b/test_data/test_01/mylib_helper.hpp @@ -0,0 +1,3 @@ +#pragma once + +void add_two_helper(); diff --git a/tests/test.rs b/tests/test.rs index b5d3517..3643166 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -54,7 +54,7 @@ fn test_01() { let test_one = project; println!("test_one: {:?}", *test_one); assert_eq!(test_one.executables.len(), 1); - assert_eq!(test_one.static_libraries.len(), 0); + assert_eq!(test_one.static_libraries.len(), 1); assert_eq!(test_one.shared_libraries.len(), 1); let exe = test_one.executables.first().unwrap(); From d5fb7b0f6fe59b6a72ccb8c16951b973d1afab70 Mon Sep 17 00:00:00 2001 From: Travers Biddle Date: Sat, 18 Apr 2026 14:54:14 +1000 Subject: [PATCH 2/3] refactor: Implement get_attr, has_attr in terms of link_targets --- src/starlark_api.rs | 10 +++--- src/starlark_link_target.rs | 32 ++++++++++++++++++ src/starlark_project.rs | 65 +++++++++---------------------------- 3 files changed, 53 insertions(+), 54 deletions(-) diff --git a/src/starlark_api.rs b/src/starlark_api.rs index 47bc354..7b98478 100644 --- a/src/starlark_api.rs +++ b/src/starlark_api.rs @@ -19,7 +19,7 @@ use starlark::{ use crate::{ starlark_executable::{StarExecutable, StarExecutableWrapper}, starlark_interface_library::{StarIfaceLibWrapper, StarIfaceLibrary}, - starlark_link_target::{PtrLinkTarget, StarLinkTarget}, + starlark_link_target::{StarLinkTarget, StarLinkTargetRef}, starlark_object_library::{StarGeneratorVars, StarObjLibWrapper, StarObjectLibrary}, starlark_project::StarProject, starlark_shared_library::{StarSharedLibWrapper, StarSharedLibrary}, @@ -131,7 +131,7 @@ pub(crate) fn build_api(builder: &mut GlobalsBuilder) { output_name: None, // TODO(Travers) }); let mut project = state.project.lock().map_err(|e| anyhow::anyhow!(e.to_string()))?; - project.link_targets.push(PtrLinkTarget(lib.clone())); + project.link_targets.push(StarLinkTargetRef::Static(lib.clone())); project.static_libraries.push(lib.clone()); Ok(StarStaticLibWrapper(lib)) } @@ -169,7 +169,7 @@ pub(crate) fn build_api(builder: &mut GlobalsBuilder) { output_name: None, // TODO(Travers) }); let mut project = state.project.lock().map_err(|e| anyhow::anyhow!(e.to_string()))?; - project.link_targets.push(PtrLinkTarget(lib.clone())); + project.link_targets.push(StarLinkTargetRef::Object(lib.clone())); project.object_libraries.push(lib.clone()); Ok(StarObjLibWrapper(lib)) } @@ -198,7 +198,7 @@ pub(crate) fn build_api(builder: &mut GlobalsBuilder) { // generator_vars: generator_func(generator_vars, eval)?, }); let mut project = state.project.lock().map_err(|e| anyhow::anyhow!(e.to_string()))?; - project.link_targets.push(PtrLinkTarget(lib.clone())); + project.link_targets.push(StarLinkTargetRef::Interface(lib.clone())); project.interface_libraries.push(lib.clone()); Ok(StarIfaceLibWrapper(lib)) } @@ -236,7 +236,7 @@ pub(crate) fn build_api(builder: &mut GlobalsBuilder) { output_name: None, // TODO(Travers) }); let mut project = state.project.lock().map_err(|e| anyhow::anyhow!(e.to_string()))?; - project.link_targets.push(PtrLinkTarget(lib.clone())); + project.link_targets.push(StarLinkTargetRef::Shared(lib.clone())); project.shared_libraries.push(lib.clone()); Ok(StarSharedLibWrapper(lib)) } diff --git a/src/starlark_link_target.rs b/src/starlark_link_target.rs index d4296b5..7fad5e2 100644 --- a/src/starlark_link_target.rs +++ b/src/starlark_link_target.rs @@ -11,7 +11,11 @@ use starlark::values::OwnedFrozenValue; use super::{ link_type::LinkPtr, project::Project, // + starlark_interface_library::StarIfaceLibrary, + starlark_object_library::StarObjectLibrary, starlark_project::StarLinkTargetCache, + starlark_shared_library::StarSharedLibrary, + starlark_static_library::StarStaticLibrary, }; pub(super) trait StarLinkTarget: Send + Sync + fmt::Debug + Allocative { @@ -45,3 +49,31 @@ impl hash::Hash for PtrLinkTarget { (Arc::as_ptr(&self.0) as *const ()).hash(hasher) } } + +#[derive(Clone, Debug, Allocative)] +pub(super) enum StarLinkTargetRef { + Static(Arc), + Object(Arc), + Interface(Arc), + Shared(Arc), +} + +impl StarLinkTargetRef { + pub(super) fn name(&self) -> &str { + match self { + Self::Static(x) => &x.name, + Self::Object(x) => &x.name, + Self::Interface(x) => &x.name, + Self::Shared(x) => &x.name, + } + } + + pub(super) fn as_ptr_link_target(&self) -> PtrLinkTarget { + match self { + Self::Static(x) => PtrLinkTarget(x.clone()), + Self::Object(x) => PtrLinkTarget(x.clone()), + Self::Interface(x) => PtrLinkTarget(x.clone()), + Self::Shared(x) => PtrLinkTarget(x.clone()), + } + } +} diff --git a/src/starlark_project.rs b/src/starlark_project.rs index 0ac0210..ac4126e 100644 --- a/src/starlark_project.rs +++ b/src/starlark_project.rs @@ -33,7 +33,7 @@ use crate::{ shared_library::SharedLibrary, starlark_executable::StarExecutable, // starlark_interface_library::{StarIfaceLibWrapper, StarIfaceLibrary}, - starlark_link_target::PtrLinkTarget, + starlark_link_target::{PtrLinkTarget, StarLinkTargetRef}, starlark_object_library::{StarObjLibWrapper, StarObjectLibrary}, starlark_shared_library::{StarSharedLibWrapper, StarSharedLibrary}, starlark_static_library::{StarStaticLibWrapper, StarStaticLibrary}, @@ -47,7 +47,7 @@ pub(super) struct StarProject { pub path: PathBuf, pub dependencies: Vec>, pub executables: Vec>, - pub link_targets: Vec, + pub link_targets: Vec, pub static_libraries: Vec>, pub object_libraries: Vec>, pub interface_libraries: Vec>, @@ -76,59 +76,25 @@ impl<'v> StarlarkValue<'v> for StarProject { project_methods() } fn get_attr(&self, attribute: &str, heap: &'v Heap) -> Option> { - for lib in &self.static_libraries { - if lib.name == attribute { - return Some(heap.alloc(StarStaticLibWrapper(lib.clone()))); - } - } - for lib in &self.object_libraries { - if lib.name == attribute { - return Some(heap.alloc(StarObjLibWrapper(lib.clone()))); - } - } - for lib in &self.interface_libraries { - if lib.name == attribute { - return Some(heap.alloc(StarIfaceLibWrapper(lib.clone()))); - } - } - for lib in &self.shared_libraries { - if lib.name == attribute { - return Some(heap.alloc(StarSharedLibWrapper(lib.clone()))); + for link_target in &self.link_targets { + if link_target.name() == attribute { + let value = match link_target { + StarLinkTargetRef::Static(lib) => heap.alloc(StarStaticLibWrapper(lib.clone())), + StarLinkTargetRef::Object(lib) => heap.alloc(StarObjLibWrapper(lib.clone())), + StarLinkTargetRef::Interface(lib) => heap.alloc(StarIfaceLibWrapper(lib.clone())), + StarLinkTargetRef::Shared(lib) => heap.alloc(StarSharedLibWrapper(lib.clone())), + }; + return Some(value); } } None } fn has_attr(&self, attribute: &str, _: &'v Heap) -> bool { - for lib in &self.static_libraries { - if lib.name == attribute { - return true; - } - } - for lib in &self.object_libraries { - if lib.name == attribute { - return true; - } - } - for lib in &self.interface_libraries { - if lib.name == attribute { - return true; - } - } - false + self.link_targets.iter().any(|x| x.name() == attribute) } fn dir_attr(&self) -> Vec { - let mut attrs = Vec::new(); - for lib in &self.static_libraries { - attrs.push(lib.name.to_owned()); - } - for lib in &self.object_libraries { - attrs.push(lib.name.to_owned()); - } - for lib in &self.interface_libraries { - attrs.push(lib.name.to_owned()); - } - attrs + self.link_targets.iter().map(|x| x.name().to_owned()).collect() } } @@ -317,9 +283,10 @@ impl StarProject { .link_targets .iter() .map(|x| { + let ptr = x.as_ptr_link_target(); link_map - .get(x) - .ok_or_else(|| format!("Could not find target \"{}\" in link map", x.0.name())) + .get(&ptr) + .ok_or_else(|| format!("Could not find target \"{}\" in link map", x.name())) }) .collect::>()?; validate_library_dependency_order(&project)?; From 967661d55852ce7a25abd3873e88a5e95bb2fe4d Mon Sep 17 00:00:00 2001 From: Travers Biddle Date: Sat, 18 Apr 2026 15:44:39 +1000 Subject: [PATCH 3/3] refactor: Store only link_targets instead of separate lib types --- src/generator/ninja.rs | 4 - src/generator/xcode.rs | 8 -- src/lib.rs | 5 +- src/object_library.rs | 23 ++-- src/project.rs | 8 -- src/starlark_api.rs | 4 - src/starlark_interface_library.rs | 3 +- src/starlark_object_library.rs | 2 +- src/starlark_project.rs | 216 ++++++------------------------ src/starlark_shared_library.rs | 3 +- src/starlark_static_library.rs | 3 +- src/static_library.rs | 24 ++-- tests/test.rs | 70 ++++++++-- 13 files changed, 131 insertions(+), 242 deletions(-) diff --git a/src/generator/ninja.rs b/src/generator/ninja.rs index 5dd67a5..9afa7cf 100644 --- a/src/generator/ninja.rs +++ b/src/generator/ninja.rs @@ -1273,10 +1273,6 @@ fn test_position_independent_code() { output_name: None, })], link_targets: vec![LinkPtr::Static(create_lib(weak_parent))], - static_libraries: vec![create_lib(weak_parent)], - object_libraries: Vec::new(), - interface_libraries: Vec::new(), - shared_libraries: Vec::new(), }); let toolchain = Toolchain { msvc_platforms: vec!["x64".to_owned(), "Win32".to_owned(), "ARM64".to_owned()], diff --git a/src/generator/xcode.rs b/src/generator/xcode.rs index 74c288b..86b34dc 100644 --- a/src/generator/xcode.rs +++ b/src/generator/xcode.rs @@ -2451,10 +2451,6 @@ fn test_pbxproj_generation() { LinkPtr::Static(adder.clone()), LinkPtr::Interface(arithmetic.clone()), ], - static_libraries: vec![adder], - object_libraries: vec![subtracter], - interface_libraries: vec![arithmetic], - shared_libraries: Vec::new(), } }); @@ -2561,10 +2557,6 @@ fn test_xcode_transform() { dependencies: Vec::new(), executables: vec![exe], link_targets: vec![LinkPtr::Static(adder.clone()), LinkPtr::Interface(iface.clone())], - static_libraries: vec![adder], - object_libraries: Vec::new(), - interface_libraries: vec![iface], - shared_libraries: Vec::new(), } }); diff --git a/src/lib.rs b/src/lib.rs index c90f298..1d3e0be 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,7 @@ mod executable; pub mod generator; mod interface_library; -mod link_type; +pub mod link_type; mod misc; mod object_library; pub mod project; @@ -37,8 +37,7 @@ use reqwest::StatusCode; use serde::Deserialize; use starlark::{ environment::{ - Globals, // - GlobalsBuilder, + GlobalsBuilder, // Module, }, eval::Evaluator, diff --git a/src/object_library.rs b/src/object_library.rs index da2e1f2..35e3337 100644 --- a/src/object_library.rs +++ b/src/object_library.rs @@ -233,23 +233,20 @@ mod tests { info: Arc::new(crate::project::ProjectInfo { name: "test".to_owned(), path: PathBuf::from(".") }), dependencies: Vec::new(), executables: Vec::new(), - link_targets: Vec::new(), - static_libraries: vec![ - leaf_shared, - leaf_pub_pub, - leaf_pub_priv, - leaf_priv_pub, - leaf_priv_priv, - mid_pub, - mid_priv, + link_targets: vec![ + LinkPtr::Object(main_lib.clone()), + LinkPtr::Static(leaf_shared.clone()), + LinkPtr::Static(leaf_pub_pub.clone()), + LinkPtr::Static(leaf_pub_priv.clone()), + LinkPtr::Static(leaf_priv_pub.clone()), + LinkPtr::Static(leaf_priv_priv.clone()), + LinkPtr::Static(mid_pub.clone()), + LinkPtr::Static(mid_priv.clone()), ], - object_libraries: vec![main_lib], - interface_libraries: Vec::new(), - shared_libraries: Vec::new(), } }); - let main_lib = project.object_libraries.iter().find(|x| x.name == "main_lib").unwrap(); + let main_lib = project.link_targets.iter().find(|x| x.name() == "main_lib").unwrap(); let internal_includes = main_lib.internal_includes(); diff --git a/src/project.rs b/src/project.rs index bc7b282..cbb51f9 100644 --- a/src/project.rs +++ b/src/project.rs @@ -5,11 +5,7 @@ use std::{ use crate::{ executable::Executable, // - interface_library::InterfaceLibrary, link_type::LinkPtr, - object_library::ObjectLibrary, - shared_library::SharedLibrary, - static_library::StaticLibrary, }; #[derive(Debug)] @@ -24,8 +20,4 @@ pub struct Project { pub dependencies: Vec>, pub executables: Vec>, pub link_targets: Vec, - pub static_libraries: Vec>, - pub object_libraries: Vec>, - pub interface_libraries: Vec>, - pub shared_libraries: Vec>, } diff --git a/src/starlark_api.rs b/src/starlark_api.rs index 7b98478..dba0579 100644 --- a/src/starlark_api.rs +++ b/src/starlark_api.rs @@ -132,7 +132,6 @@ pub(crate) fn build_api(builder: &mut GlobalsBuilder) { }); let mut project = state.project.lock().map_err(|e| anyhow::anyhow!(e.to_string()))?; project.link_targets.push(StarLinkTargetRef::Static(lib.clone())); - project.static_libraries.push(lib.clone()); Ok(StarStaticLibWrapper(lib)) } @@ -170,7 +169,6 @@ pub(crate) fn build_api(builder: &mut GlobalsBuilder) { }); let mut project = state.project.lock().map_err(|e| anyhow::anyhow!(e.to_string()))?; project.link_targets.push(StarLinkTargetRef::Object(lib.clone())); - project.object_libraries.push(lib.clone()); Ok(StarObjLibWrapper(lib)) } @@ -199,7 +197,6 @@ pub(crate) fn build_api(builder: &mut GlobalsBuilder) { }); let mut project = state.project.lock().map_err(|e| anyhow::anyhow!(e.to_string()))?; project.link_targets.push(StarLinkTargetRef::Interface(lib.clone())); - project.interface_libraries.push(lib.clone()); Ok(StarIfaceLibWrapper(lib)) } @@ -237,7 +234,6 @@ pub(crate) fn build_api(builder: &mut GlobalsBuilder) { }); let mut project = state.project.lock().map_err(|e| anyhow::anyhow!(e.to_string()))?; project.link_targets.push(StarLinkTargetRef::Shared(lib.clone())); - project.shared_libraries.push(lib.clone()); Ok(StarSharedLibWrapper(lib)) } diff --git a/src/starlark_interface_library.rs b/src/starlark_interface_library.rs index 94d370f..f987fc3 100644 --- a/src/starlark_interface_library.rs +++ b/src/starlark_interface_library.rs @@ -76,8 +76,7 @@ impl StarLinkTarget for StarIfaceLibrary { ) -> Result { let data = self.as_library(parent, parent_path, link_map, gen_name_map)?; let arc = Arc::new(data); - // let ptr = PtrLinkTarget(arc.clone()); - link_map.insert_interface(ptr, arc.clone()); + link_map.insert(ptr, LinkPtr::Interface(arc.clone())); Ok(LinkPtr::Interface(arc)) } diff --git a/src/starlark_object_library.rs b/src/starlark_object_library.rs index 6adc403..188e7df 100644 --- a/src/starlark_object_library.rs +++ b/src/starlark_object_library.rs @@ -98,7 +98,7 @@ impl StarLinkTarget for StarObjectLibrary { gen_name_map: &HashMap, ) -> Result { let arc = Arc::new(self.as_library(parent, parent_path, link_map, gen_name_map)?); - link_map.insert_object(ptr, arc.clone()); + link_map.insert(ptr, LinkPtr::Object(arc.clone())); Ok(LinkPtr::Object(arc)) } diff --git a/src/starlark_project.rs b/src/starlark_project.rs index ac4126e..d9f03e9 100644 --- a/src/starlark_project.rs +++ b/src/starlark_project.rs @@ -12,8 +12,7 @@ use starlark::{ MethodsBuilder, MethodsStatic, }, - // starlark_complex_value, - starlark_module, + starlark_module, // starlark_simple_value, values::{ Heap, // @@ -26,18 +25,14 @@ use starlark::{ }; use crate::{ - interface_library::InterfaceLibrary, link_type::LinkPtr, - object_library::ObjectLibrary, project::{Project, ProjectInfo}, - shared_library::SharedLibrary, starlark_executable::StarExecutable, // - starlark_interface_library::{StarIfaceLibWrapper, StarIfaceLibrary}, + starlark_interface_library::StarIfaceLibWrapper, starlark_link_target::{PtrLinkTarget, StarLinkTargetRef}, - starlark_object_library::{StarObjLibWrapper, StarObjectLibrary}, - starlark_shared_library::{StarSharedLibWrapper, StarSharedLibrary}, - starlark_static_library::{StarStaticLibWrapper, StarStaticLibrary}, - static_library::StaticLibrary, + starlark_object_library::StarObjLibWrapper, + starlark_shared_library::StarSharedLibWrapper, + starlark_static_library::StarStaticLibWrapper, target::Target, }; @@ -48,11 +43,6 @@ pub(super) struct StarProject { pub dependencies: Vec>, pub executables: Vec>, pub link_targets: Vec, - pub static_libraries: Vec>, - pub object_libraries: Vec>, - pub interface_libraries: Vec>, - pub shared_libraries: Vec>, - pub generator_names: HashMap, } @@ -100,82 +90,17 @@ impl<'v> StarlarkValue<'v> for StarProject { starlark_simple_value!(StarProject); -pub(super) struct StarLinkTargetCache { - all_targets: HashSet, - static_libs: HashMap>, - object_libs: HashMap>, - interface_libs: HashMap>, - shared_libs: HashMap>, -} +pub(super) struct StarLinkTargetCache(HashMap); impl StarLinkTargetCache { fn new() -> StarLinkTargetCache { - StarLinkTargetCache { - all_targets: HashSet::new(), - static_libs: HashMap::new(), - object_libs: HashMap::new(), - interface_libs: HashMap::new(), - shared_libs: HashMap::new(), - } - } - pub fn get_static(&self, key: &PtrLinkTarget) -> Option<&Arc> { - if self.all_targets.contains(key) { - self.static_libs.get(key) - } else { - None - } - } - pub fn get_object(&self, key: &PtrLinkTarget) -> Option<&Arc> { - if self.all_targets.contains(key) { - self.object_libs.get(key) - } else { - None - } - } - pub fn get_interface(&self, key: &PtrLinkTarget) -> Option<&Arc> { - if self.all_targets.contains(key) { - self.interface_libs.get(key) - } else { - None - } - } - pub fn get_shared(&self, key: &PtrLinkTarget) -> Option<&Arc> { - if self.all_targets.contains(key) { - self.shared_libs.get(key) - } else { - None - } + StarLinkTargetCache(HashMap::new()) } pub fn get(&self, key: &PtrLinkTarget) -> Option { - if let Some(x) = self.get_static(key) { - return Some(LinkPtr::Static(x.clone())); - } - if let Some(x) = self.get_object(key) { - return Some(LinkPtr::Object(x.clone())); - } - if let Some(x) = self.get_interface(key) { - return Some(LinkPtr::Interface(x.clone())); - } - if let Some(x) = self.get_shared(key) { - return Some(LinkPtr::Shared(x.clone())); - } - None - } - pub fn insert_static(&mut self, key: PtrLinkTarget, value: Arc) { - self.static_libs.insert(key.clone(), value); - self.all_targets.insert(key); + self.0.get(key).cloned() } - pub fn insert_object(&mut self, key: PtrLinkTarget, value: Arc) { - self.object_libs.insert(key.clone(), value); - self.all_targets.insert(key); - } - pub fn insert_interface(&mut self, key: PtrLinkTarget, value: Arc) { - self.interface_libs.insert(key.clone(), value); - self.all_targets.insert(key); - } - pub fn insert_shared(&mut self, key: PtrLinkTarget, value: Arc) { - self.shared_libs.insert(key.clone(), value); - self.all_targets.insert(key); + pub fn insert(&mut self, key: PtrLinkTarget, value: LinkPtr) { + self.0.insert(key, value); } } @@ -187,11 +112,6 @@ impl StarProject { dependencies, executables: Vec::new(), link_targets: Vec::new(), - static_libraries: Vec::new(), - object_libraries: Vec::new(), - interface_libraries: Vec::new(), - shared_libraries: Vec::new(), - generator_names: HashMap::new(), } } @@ -217,78 +137,23 @@ impl StarProject { } ) .collect::>()?, - link_targets: Vec::new(), - static_libraries: self - .static_libraries - .iter() - .map(|x| -> Result,String>{ - let ptr = PtrLinkTarget(x.clone()); - if let Some(lib) = link_map.get_static(&ptr) { - Ok(lib.clone()) - } else { - let data = x.as_library(Weak::new(), &self.path, link_map, &self.generator_names)?; - let arc = Arc::new(data); - link_map.insert_static(ptr, arc.clone()); - Ok(arc) - } - }) - .collect::>()?, - object_libraries: self - .object_libraries - .iter() - .map(|x| -> Result,String>{ - let ptr = PtrLinkTarget(x.clone()); - if let Some(lib) = link_map.get_object(&ptr) { - Ok(lib.clone()) - } else { - let data = x.as_library(Weak::new(), &self.path, link_map, &self.generator_names)?; - let arc = Arc::new(data); - link_map.insert_object(ptr, arc.clone()); - Ok(arc) - } - }) - .collect::>()?, - interface_libraries: self - .interface_libraries - .iter() - .map(|x| -> Result<_,String>{ - let ptr = PtrLinkTarget(x.clone()); - if let Some(lib) = link_map.get_interface(&ptr) { - Ok(lib.clone()) - } else { - let data = x.as_library(Weak::new(), &self.path, link_map, &self.generator_names)?; - let arc = Arc::new(data); - link_map.insert_interface(ptr, arc.clone()); - Ok(arc) - } - }) - .collect::>()?, - shared_libraries: self - .shared_libraries - .iter() - .map(|x| -> Result,String>{ - let ptr = PtrLinkTarget(x.clone()); - if let Some(lib) = link_map.get_shared(&ptr) { - Ok(lib.clone()) - } else { - let data = x.as_library(Weak::new(), &self.path, link_map, &self.generator_names)?; - let arc = Arc::new(data); - link_map.insert_shared(ptr, arc.clone()); - Ok(arc) - } - }) - .collect::>()?, - }; //); - project.link_targets = self + link_targets: self .link_targets .iter() - .map(|x| { + .map(|x| -> Result { let ptr = x.as_ptr_link_target(); - link_map - .get(&ptr) - .ok_or_else(|| format!("Could not find target \"{}\" in link map", x.name())) + if let Some(lib) = link_map.get(&ptr) { + Ok(lib) + } else { + let data = ptr.0.as_link_target(Weak::new(), &self.path, ptr.clone(), link_map, &self.generator_names)?; + // let arc = Arc::new(data); + link_map.insert(ptr, data.clone()); + Ok(data) + } }) - .collect::>()?; + .collect::>()?, + }; + validate_library_dependency_order(&project)?; let ret = Arc::::new_cyclic(move |weak_parent: &Weak| -> Project { @@ -298,21 +163,26 @@ impl StarProject { for exe in &mut project.executables { Arc::get_mut(exe).unwrap().set_parent(weak_parent.clone()); } - for lib in &mut project.static_libraries { - let lib_mut = unsafe { &mut (*Arc::as_ptr(lib).cast_mut()) }; - lib_mut.set_parent(weak_parent.clone()); - } - for lib in &mut project.object_libraries { - let lib_mut = unsafe { &mut (*Arc::as_ptr(lib).cast_mut()) }; - lib_mut.set_parent(weak_parent.clone()); - } - for lib in &mut project.interface_libraries { - let lib_mut = unsafe { &mut (*Arc::as_ptr(lib).cast_mut()) }; - lib_mut.set_parent(weak_parent.clone()); - } - for lib in &mut project.shared_libraries { - let lib_mut = unsafe { &mut (*Arc::as_ptr(lib).cast_mut()) }; - lib_mut.set_parent(weak_parent.clone()); + + for lib in &mut project.link_targets { + match lib { + LinkPtr::Static(lib) => { + let lib_mut = unsafe { &mut (*Arc::as_ptr(lib).cast_mut()) }; + lib_mut.set_parent(weak_parent.clone()); + } + LinkPtr::Object(lib) => { + let lib_mut = unsafe { &mut (*Arc::as_ptr(lib).cast_mut()) }; + lib_mut.set_parent(weak_parent.clone()); + } + LinkPtr::Interface(lib) => { + let lib_mut = unsafe { &mut (*Arc::as_ptr(lib).cast_mut()) }; + lib_mut.set_parent(weak_parent.clone()); + } + LinkPtr::Shared(lib) => { + let lib_mut = unsafe { &mut (*Arc::as_ptr(lib).cast_mut()) }; + lib_mut.set_parent(weak_parent.clone()); + } + } } project }); diff --git a/src/starlark_shared_library.rs b/src/starlark_shared_library.rs index 6aff519..9ad3bf8 100644 --- a/src/starlark_shared_library.rs +++ b/src/starlark_shared_library.rs @@ -97,8 +97,7 @@ impl StarLinkTarget for StarSharedLibrary { gen_name_map: &HashMap, ) -> Result { let arc = Arc::new(self.as_library(parent, parent_path, link_map, gen_name_map)?); - // let ptr = PtrLinkTarget(arc.clone()); - link_map.insert_shared(ptr, arc.clone()); + link_map.insert(ptr, LinkPtr::Shared(arc.clone())); Ok(LinkPtr::Shared(arc)) } diff --git a/src/starlark_static_library.rs b/src/starlark_static_library.rs index 9405e5a..fe7b83f 100644 --- a/src/starlark_static_library.rs +++ b/src/starlark_static_library.rs @@ -97,8 +97,7 @@ impl StarLinkTarget for StarStaticLibrary { gen_name_map: &HashMap, ) -> Result { let arc = Arc::new(self.as_library(parent, parent_path, link_map, gen_name_map)?); - // let ptr = PtrLinkTarget(arc.clone()); - link_map.insert_static(ptr, arc.clone()); + link_map.insert(ptr, LinkPtr::Static(arc.clone())); Ok(LinkPtr::Static(arc)) } diff --git a/src/static_library.rs b/src/static_library.rs index f1b3ca4..444d03f 100644 --- a/src/static_library.rs +++ b/src/static_library.rs @@ -233,24 +233,20 @@ mod tests { info: Arc::new(crate::project::ProjectInfo { name: "test".to_owned(), path: PathBuf::from(".") }), dependencies: Vec::new(), executables: Vec::new(), - link_targets: Vec::new(), - static_libraries: vec![ - leaf_shared, - leaf_pub_pub, - leaf_pub_priv, - leaf_priv_pub, - leaf_priv_priv, - mid_pub, - mid_priv, - main_lib, + link_targets: vec![ + LinkPtr::Static(leaf_shared.clone()), + LinkPtr::Static(leaf_pub_pub.clone()), + LinkPtr::Static(leaf_pub_priv.clone()), + LinkPtr::Static(leaf_priv_pub.clone()), + LinkPtr::Static(leaf_priv_priv.clone()), + LinkPtr::Static(mid_pub.clone()), + LinkPtr::Static(mid_priv.clone()), + LinkPtr::Static(main_lib.clone()), ], - object_libraries: Vec::new(), - interface_libraries: Vec::new(), - shared_libraries: Vec::new(), } }); - let main_lib = project.static_libraries.iter().find(|x| x.name == "main_lib").unwrap(); + let main_lib = project.link_targets.iter().find(|x| x.name() == "main_lib").unwrap(); let internal_includes = main_lib.internal_includes(); diff --git a/tests/test.rs b/tests/test.rs index 3643166..f6e3f1c 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -3,7 +3,11 @@ use std::{ env, }; -use catapult::{target::Target, toolchain::Toolchain}; +use catapult::{ + link_type::LinkPtr, // + target::Target, + toolchain::Toolchain, +}; #[test] fn test_01() { @@ -28,9 +32,18 @@ fn test_01() { assert_eq!(my_depends.len(), 1); let my_depend = my_depends.first().unwrap(); assert_eq!(my_depend.executables.len(), 1); - assert_eq!(my_depend.static_libraries.len(), 1); - let static_lib = my_depend.static_libraries.first().unwrap(); + let my_depend_static_libs = my_depend + .link_targets + .iter() + .filter_map(|x| match x { + LinkPtr::Static(lib) => Some(lib.clone()), + _ => None, + }) + .collect::>(); + assert_eq!(my_depend_static_libs.len(), 1); + + let static_lib = my_depend_static_libs.first().unwrap(); assert_eq!(static_lib.name, "my_depend_lib"); assert_eq!(static_lib.sources.cpp.len(), 1); assert_eq!(static_lib.sources.cpp[0].full, cwd.join("submodules").join("my_depend").join("my_depend.cpp")); @@ -41,9 +54,19 @@ fn test_01() { .filter(|x| x.info.name == "blobject") .collect::>(); assert_eq!(blobjects.len(), 1); + let blobject = blobjects.first().unwrap(); - assert_eq!(blobject.object_libraries.len(), 1); - let obj_lib = blobject.object_libraries.first().unwrap(); + let blobject_obj_libs = blobject + .link_targets + .iter() + .filter_map(|x| match x { + LinkPtr::Object(lib) => Some(lib.clone()), + _ => None, + }) + .collect::>(); + assert_eq!(blobject_obj_libs.len(), 1); + + let obj_lib = blobject_obj_libs.first().unwrap(); assert_eq!(obj_lib.name, "blobject"); assert_eq!(obj_lib.sources.c.len(), 1); assert_eq!(obj_lib.sources.c[0].full, cwd.join("submodules").join("blobject").join("blobject2.c")); @@ -51,11 +74,32 @@ fn test_01() { assert_eq!(obj_lib.sources.cpp[0].full, cwd.join("submodules").join("blobject").join("blobject1.cpp")); assert_eq!(project.info.name, "test_one"); + let test_one = project; println!("test_one: {:?}", *test_one); assert_eq!(test_one.executables.len(), 1); - assert_eq!(test_one.static_libraries.len(), 1); - assert_eq!(test_one.shared_libraries.len(), 1); + assert_eq!( + test_one + .link_targets + .iter() + .filter_map(|x| match x { + LinkPtr::Static(lib) => Some(lib.clone()), + _ => None, + }) + .count(), + 1 + ); + assert_eq!( + test_one + .link_targets + .iter() + .filter_map(|x| match x { + LinkPtr::Shared(lib) => Some(lib.clone()), + _ => None, + }) + .count(), + 1 + ); let exe = test_one.executables.first().unwrap(); assert_eq!(exe.name, "myexe"); @@ -68,7 +112,17 @@ fn test_01() { assert_eq!(exe.links[3].name(), "nasmobjs"); assert_eq!(exe.links[4].name(), "zstd"); - let lib = test_one.shared_libraries.first().unwrap(); + let test_one_shared_libs = test_one + .link_targets + .iter() + .filter_map(|x| match x { + LinkPtr::Shared(lib) => Some(lib.clone()), + _ => None, + }) + .collect::>(); + assert_eq!(test_one_shared_libs.len(), 1); + + let lib = test_one_shared_libs.first().unwrap(); assert_eq!(lib.name, "mylib"); assert_eq!(lib.sources.cpp.len(), 1); assert_eq!(lib.sources.cpp[0].full, cwd.join("mylib.cpp"));