preWarmMetaCache computes GenPortTomlString, GetBuildConfig, and CheckHostSupported for all transitive dependencies in parallel, filling the sync.Map caches before the serial install pipeline begins. Must be called AFTER cloneAllRepos (so repos are cloned and GetCommitHash won't hit ErrRepoNotExit)
()
| 926 | // won't hit ErrRepoNotExit) and AFTER checkAllTools (so exprVars is final and |
| 927 | // Port.Init's ExprVars().Clone() has no writer race). |
| 928 | func (p *Port) preWarmMetaCache() error { |
| 929 | nameVersions, err := p.collectAllDeps() |
| 930 | if err != nil { |
| 931 | return err |
| 932 | } |
| 933 | if len(nameVersions) == 0 { |
| 934 | return nil |
| 935 | } |
| 936 | |
| 937 | // Meta pre-warm is IO-bound (read port.toml + git log), not CPU-bound like compilation. |
| 938 | jobs := p.ctx.Jobs() * 4 |
| 939 | if jobs <= 0 { |
| 940 | jobs = 4 |
| 941 | } |
| 942 | |
| 943 | var group errgroup.Group |
| 944 | group.SetLimit(jobs) |
| 945 | |
| 946 | for _, item := range nameVersions { |
| 947 | nameVersion := item |
| 948 | group.Go(func() error { |
| 949 | // ErrRepoNotExit is expected for ports with a checksum: they are |
| 950 | // skipped by cloneAllRepos (they will be restored from pkgcache instead), |
| 951 | // so their repo dir doesn't exist and GetCommitHash returns this error, |
| 952 | // It's not a real failure. |
| 953 | if _, err := p.GenPortTomlString(nameVersion, false); err != nil { |
| 954 | if !errors.Is(err, errors.ErrRepoNotExit) { |
| 955 | return fmt.Errorf("failed to generate port toml string for %s as target -> %w", nameVersion, err) |
| 956 | } |
| 957 | } |
| 958 | |
| 959 | // Some port defined in port.toml can only be build cross-compile toolchian, |
| 960 | // for example: system_processor = "aarch64", and no host buildConfig can be matched when |
| 961 | // init it with devDep, so we there is no need to pre warn meta cache for it. |
| 962 | if p.CheckHostSupported(nameVersion) { |
| 963 | if _, err := p.GenPortTomlString(nameVersion, true); err != nil { |
| 964 | if !errors.Is(err, errors.ErrRepoNotExit) { |
| 965 | return fmt.Errorf("failed to generate port toml string for %s as dev/host -> %w", nameVersion, err) |
| 966 | } |
| 967 | } |
| 968 | |
| 969 | if _, err := p.GetBuildConfig(nameVersion, true); err != nil { |
| 970 | return fmt.Errorf("cannot find matched build config for %s as dev/host -> %w", nameVersion, err) |
| 971 | } |
| 972 | } |
| 973 | |
| 974 | // Pre-warm buildConfigCache. |
| 975 | if _, err := p.GetBuildConfig(nameVersion, false); err != nil { |
| 976 | return fmt.Errorf("cannot find matched build_config for %s as target -> %w", nameVersion, err) |
| 977 | } |
| 978 | |
| 979 | // Pre-warm hostSupportedCache. |
| 980 | p.CheckHostSupported(nameVersion) |
| 981 | return nil |
| 982 | }) |
| 983 | } |
| 984 | |
| 985 | return group.Wait() |
no test coverage detected