Skip to content

Link step should always consume .a archives #1520

@cpunion

Description

@cpunion

Summary

linkMainPkg feeds the linker the raw .o files when a package was just built, but after that package hits the compiler cache we link the cached .a instead. The link step should always consume the archive so cache hits and misses behave identically.

Steps to Reproduce

  1. Ensure LLGO_BUILD_CACHE=on and run any build (llgo build ./demo/hello works) with verbose logging.
  2. On the first build (cache miss) observe that the linker command receives every package's .o files (see linkMainPkg -> objFiles in internal/build/build.go:823-907).
  3. Run the same build again. Because tryLoadFromCache sets pkg.LLFiles = []string{paths.Archive} (internal/build/collect.go:306-349), the linker now receives .a archives stored by saveToCache (internal/build/collect.go:440-493).

Analysis

  • Fresh builds call buildPkg, which only appends .o outputs (concatPkgLinkFiles, exportObject, etc.) to aPkg.LLFiles (internal/build/build.go:1064-1089).
  • saveToCache already creates an archive from those .o files, but the archive is ignored until the next build when tryLoadFromCache rewrites pkg.LLFiles to the .a (internal/build/collect.go:342-349).
  • Because linkMainPkg blindly appends aPkg.LLFiles, the first build links .o while the next links .a. This means the linker input and ordering changes depending on whether the cache was warm, which is exactly the inconsistency reported in the bug description.

Expected Behavior

Every package should always be linked via its .a archive so cache state does not change the linker inputs.

Actual Behavior

Cache misses link .o files, cache hits link .a. The transition happens purely based on whether pkg.CacheHit was true.

Proposed Fix

Normalize aPkg.LLFiles to the .a archive right after a package is built (or teach linkMainPkg/linkObjFiles to treat .o and .a uniformly) so the linker command line never depends on cache state.

Environment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions