Skip to content

An artifacts dependency and its consumer that deploy the same runtime file from different outputs collide at planning #723

Description

@speak-agent

Observation

The first real consumer of the artifacts edge (#711, mcpp 2026.9.27.1) fails planning. GalTranslPP's GUI ships its updater beside itself; with

# GPPGUI/mcpp.toml
[dependencies]
"gpp.updater" = { path = "../Updater", artifacts = ["Updater"] }

mcpp emit build-database (and mcpp build) on Windows reports

GPPGUI: runtime deploy collision: '<cache>\target\.build-mcpp\out\qt\translations\qt_zh_CN.qm' and
'<cache>\target\.build-mcpp\deps\updater@3.1.1\out\qt\translations\qt_zh_CN.qm' both target 'bin\translations\qt_zh_CN.qm'

(Sunrisepeak/GalTranslPP run 36312954298, mcpp 2026.9.27.1, mcpp:plugins 0.16.0.)

Both programs are Qt programs whose build programs ask rules-qt for Qt's own Chinese strings (i18n.qt_languages = {"zh_CN"}). Each writes qt_zh_CN.qm into its own out directory and deploys it to translations/. The artifact program runs from the consumer's directory, so its deploy set joins the consumer's, and add_deploy (src/build/plan.cppm) refuses two different source paths for one destination.

The two files are byte-for-byte the same: for these modules (Core, Gui, Network, Widgets on one side, Core, Gui, Widgets on the other) rules-qt combines the one catalog qtbase_zh_CN.qm of the same SDK with the same lconvert command; only the output path differs. At planning time neither file exists, so the check cannot compare contents. The Qt runtime libraries and plugins of the two programs do not collide, because they are deployed from the same payload paths and deduplicated.

Question for the design

What should a program shipped through artifacts do with a runtime file its consumer also deploys under the same name? Some options:

  1. The consumer's own deploy set takes precedence over what an artifacts edge brings, with a note naming the file that was not placed; a program placed in the consumer's directory already shares that directory's files.
  2. Two deploys whose sources are outputs of actions with the same command and the same inputs (differing only in the output path) are the same file, and one is placed.
  3. The edge accepts a list of deploy entries to leave out.

Until one of these is decided, GalTranslPP's validation keeps the updater on a tools edge.

Activity

  1. added a commit that references this issue on Sep 27, 2026
  2. added a commit that references this issue on Sep 27, 2026
  3. speak-agent commented on Sep 27, 2026

    @speak-agent
    MemberAuthor

    Implemented in 2026.9.28.1 (#727). The rule is SPEC-007 R4.2 and R4.3: one destination, one content, one writer.

    • Planning no longer refuses. Several sources for one deploy destination become one staging edge with every source as an input.
    • Staging compares bytes. mcpp stage places identical bytes once. Different bytes fail the edge, naming every source and the destination. A missing source is named as missing.
    • Declared files win. The post-link DLL placement never writes a name the deploy list places. A DLL that a runtime search directory offers under a declared name yields to the declared file, and a difference is warned. On a PE target, destinations compare without case.

    Verification of the published release. A fresh SubOS sandbox (xlings subos use <name> --sandbox) with the CN mirror configured for both xlings and mcpp installed mcpp@2026.9.28.1 through the index and ran one script over the published binary: 13 ok, 0 failed (the Windows-only items are reported as not run). The same script in a second sandbox against mcpp@2026.9.27.1 reads 5 ok, 8 failed, so each assertion below measures this change rather than the setup it runs in.

    criterion 2026.9.28.1 2026.9.27.1
    an artifacts-style dependency and its consumer each deploy identical generated bytes to bin/shared/shared.bin; the build places one file ok runtime deploy collision at planning
    different bytes are refused, naming the destination ok ok (refused, at planning)

    e2e 810, 811 (Windows) and 818 carry the properties in the suite.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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