fn build()

in tools/hakari/src/hakari.rs [622:729]


    fn build(builder: HakariBuilder<'g>) -> Self {
        let graph = *builder.graph;
        let mut computed_map_build = ComputedMapBuild::new(&builder);
        let platform_specs: Vec<_> = builder
            .platforms
            .iter()
            .map(|platform| PlatformSpec::Platform(platform.clone()))
            .collect();

        let unify_target_host = builder.unify_target_host.to_impl(graph);

        // Collect all the dependencies that need to be unified, by platform and build type.
        let mut map_build: OutputMapBuild<'g> = OutputMapBuild::new(graph);
        map_build.insert_all(
            computed_map_build.iter(),
            builder.output_single_feature,
            unify_target_host,
        );

        if !builder.output_single_feature {
            // Adding packages might cause different feature sets for some dependencies. Simulate
            // further builds with the given target and host features, and use that to add in any
            // extra features that need to be considered.
            loop {
                let mut add_extra = HashSet::new();
                for (output_key, features) in map_build.iter_feature_sets() {
                    let initials_platform = match output_key.build_platform {
                        BuildPlatform::Target => InitialsPlatform::Standard,
                        BuildPlatform::Host => InitialsPlatform::Host,
                    };

                    let mut cargo_opts = CargoOptions::new();
                    let platform_spec = match output_key.platform_idx {
                        Some(idx) => platform_specs[idx].clone(),
                        None => PlatformSpec::Always,
                    };
                    // Third-party dependencies are built without including dev.
                    cargo_opts
                        .set_include_dev(false)
                        .set_initials_platform(initials_platform)
                        .set_platform(platform_spec)
                        .set_resolver(builder.resolver)
                        .add_omitted_packages(computed_map_build.excludes.iter());
                    let cargo_set = features
                        .into_cargo_set(&cargo_opts)
                        .expect("into_cargo_set processed successfully");

                    // Check the features for the cargo set to see if any further dependencies were
                    // built with a different result and weren't included in the hakari map
                    // originally.
                    for &(build_platform, feature_set) in cargo_set.all_features().iter() {
                        for feature_list in
                            feature_set.packages_with_features(DependencyDirection::Forward)
                        {
                            let dep = feature_list.package();
                            let dep_id = dep.id();
                            let v_mut = computed_map_build
                                .get_mut(output_key.platform_idx, dep_id)
                                .expect("full value should be present");

                            // Is it already present in the output?
                            let new_key = OutputKey {
                                platform_idx: output_key.platform_idx,
                                build_platform,
                            };

                            if map_build.is_inserted(new_key, dep_id) {
                                continue;
                            }

                            let this_list: BTreeSet<_> = feature_list.named_features().collect();

                            let already_present = v_mut.contains(build_platform, &this_list);
                            if !already_present {
                                // The feature list added by this dependency is non-unique.
                                v_mut.mark_fixed_up(build_platform, this_list);
                                add_extra.insert((output_key.platform_idx, dep_id));
                            }
                        }
                    }
                }

                if add_extra.is_empty() {
                    break;
                }

                map_build.insert_all(
                    add_extra.iter().map(|&(platform_idx, dep_id)| {
                        let v = computed_map_build
                            .get(platform_idx, dep_id)
                            .expect("full value should be present");
                        (platform_idx, dep_id, v)
                    }),
                    builder.output_single_feature,
                    unify_target_host,
                );
            }
        }

        let computed_map = computed_map_build.computed_map;
        let output_map = map_build.finish(&builder.final_excludes);

        Self {
            builder,
            output_map,
            computed_map,
        }
    }