Skip to content

AOT: Link multiple translation units into one binary #154

Description

@PurHur

Category

bootstrap | language (AOT link)

Problem

bin/compile.php / phpc build originally emitted one .o per entry file. Multi-file apps need:

public/index.php  → require bootstrap.php → src/Router.php

Status (May 2026)

Phase 1 shipped on master:

Capability Issue Status
Manifest includes[] #452
ProjectGraph BFS #504
Multi-.o link #752
003-MiniWebApp AOT link + execute #764
Deploy bundle #609

Phase 2 open — dynamic discovery: #1762 (PSR-4 autoload, non-literal requires). Parent umbrella #59 should narrow to phase-2 or close when static path is documented.

php-src reference

  • N/A (AOT linker) — analogous to linking multiple .o from php-src build + php CLI embedding multiple compilation units
  • Include graph: compare Zend OPcache preload / zend_compile_file per path

Repro — phase 1 (passes today)

./script/docker-exec.sh -- bash -lc 'source script/php-env.sh
  php bin/compile.php --project examples/003-MiniWebApp -o /tmp/miniwebapp
  /tmp/miniwebapp 2>&1 | head -5
'

003-MiniWebApp with explicit includes[] in phpc.json links and executes (#764 ✅).

Repro — phase 2 gap (#1762)

./script/docker-exec.sh -- bash -lc 'source script/php-env.sh
  php bin/compile.php --project test/fixtures/aot/projects/psr4_mini -o /tmp/psr4_mini
'

Expected: green link when autoload discovers src/*.php.
Actual: fixture missing / requires hand includes[].

Goal (phase 2)

phpc build --project discovers PHP files reachable from entry without hand-maintaining every path in phpc.json when uses PSR-4 or static string requires.

Scope (this repo)

Module Path
Linker lib/AOT/Linker.php — multi-.o symbol merge ✅
Graph lib/AOT/ProjectGraph.php — BFS literal includes ✅; extend #1762
Manifest lib/Web/ProjectManifest.php, phpc.json schema #1803
Compiler metadata lib/Compiler.php — record literal include targets
Tests test/fixtures/aot/cases/multi_file_include.phpt, test/fixtures/aot/projects/psr4_mini/

Discovery graph (phase 2)

Symbol table

Done when

Phase 1 (met):

Phase 2 (this issue stays open until #1762 closes):

  • phpc build --project test/fixtures/aot/projects/psr4_mini green without hand includes[]
  • phpc lint --project reports dynamic require $var with file:line
  • Document static vs dynamic policy in docs/capabilities.md / project build docs

Verification (local / Docker only)

./script/docker-exec.sh -- bash -lc 'source script/php-env.sh && ./script/ci-local.sh --filter AotTest'
./script/docker-exec.sh -- bash -lc 'source script/php-env.sh && ./script/ci-local.sh --filter ProjectGraph'

Do not use raw docker run -v "$(pwd):/compiler" on Runforge — use ./script/docker-exec.sh.

Dependencies

Related

Activity

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

    area:compilerCompiler / CFG / JITenhancementNew feature or requestimplementation-readySpec complete: repro, php-src ref, done-when — safe for workers to claimphase-3:aotPhase 3 – AOT deployment

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions