diff --git a/CLAUDE.md b/CLAUDE.md index 6cd359844..38004bf0e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1471,6 +1471,16 @@ in the topic file. it is repeated here. *Check which `6l` answers before reading anything into it*, and see the bind rule immediately below for how a window quietly acquires the host's. +- **A command name inside `apexp-sh` is whatever the UNION resolves it + to, and Plan 9's own flags are the ones most likely to be missing.** + `cmd/php/mkfile` used `` `{basename -d $target} `` -- the Plan 9 + idiom for a dirname -- and got `basename: invalid option -- d`, + because the union puts APExp's `/bin` first and that `basename` is + **GNU coreutils'**. *mk then reported the failure of the compile, + not of the `mkdir`*, so the message named the victim again. Same + family as "check which `6l` answers". A recipe that needs a Plan 9 + flag should not assume it is reachable; the php mkfile dropped the + external command entirely and uses a static directory list. - **`rm -rf` on a directory something has BOUND does not unbind it.** The bind still names the removed directory, a recreated one has a new qid, and the union component silently falls through to whatever is diff --git a/docs/notes/php.md b/docs/notes/php.md index 2af204abe..81a9402b8 100644 --- a/docs/notes/php.md +++ b/docs/notes/php.md @@ -384,6 +384,32 @@ entry aborts the whole tree's `mk`, and a port that has never been built has not been measured in that position. `cd sys/src/ape/cmd/php && mk` is how to try it. +### What the first `mk install` said, and both answers were cheap + +**`mkfile:612: syntax error`** -- the `OFILES` list ended one line +early, leaving a tab-indented entry orphaned. `mkcont-sweep` reported +0 over it, and is widened now; see `CLAUDE.md`. + +**`basename: invalid option -- d`** -- the rule used Plan 9's idiom +for a dirname, and inside `apexp-sh` the union puts APExp's own +`/bin` first, so `basename` is **GNU coreutils'**. *A command name +here is whatever the union resolves it to.* The rule uses a static +directory list now and runs no external command at all. + +***AND `no recipe to make 'ext/json/json_parser.6'` HAD A BETTER +ANSWER THAN EXPECTED.*** `ext/json`'s parser is bison-generated and +**the generated file ships in the tarball** as `json_parser.tab.c`, +so the object upstream calls `json_parser.lo` is built from a source +whose name does not match it. One explicit rule covers it. + +The useful half is what the check found rather than what it fixed: +**all 513 objects were resolved against the vendored tree and this was +the only name that does not** -- so **no bison and no re2c are needed +anywhere in this port**. `json_scanner.c` and +`php_json_scanner_defs.h` are shipped too, alongside the four Zend +parsers and scanners and the 4.2MB `zend_vm_execute.h`. *A question +that could have cost two more build tools cost one grep.* + ## What the config.h decided, and why by hand The long reasoning is in the file itself; what matters as a summary: diff --git a/sys/src/ape/cmd/php/mkfile b/sys/src/ape/cmd/php/mkfile index 02073c71e..867ee3aa4 100644 --- a/sys/src/ape/cmd/php/mkfile +++ b/sys/src/ape/cmd/php/mkfile @@ -654,6 +654,24 @@ LD=pcc DEFS=-D__x86_64__ -DHAVE_TIMELIB_CONFIG_H=1 -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1\ -DSHADOW_STACK_SYSCALL=0 -D_POSIX_SOURCE -D_BSD_EXTENSION -D_PLAN9_SOURCE +OBJDIRS=\ + TSRM Zend Zend/Optimizer ext/date ext/date/lib ext/hash\ + ext/hash/murmur ext/hash/sha3/generic64lc ext/json ext/lexbor\ + ext/lexbor/lexbor/core ext/lexbor/lexbor/css\ + ext/lexbor/lexbor/css/at_rule ext/lexbor/lexbor/css/property\ + ext/lexbor/lexbor/css/selectors ext/lexbor/lexbor/css/syntax\ + ext/lexbor/lexbor/css/syntax/tokenizer ext/lexbor/lexbor/dom\ + ext/lexbor/lexbor/dom/interfaces ext/lexbor/lexbor/encoding\ + ext/lexbor/lexbor/html ext/lexbor/lexbor/html/interfaces\ + ext/lexbor/lexbor/html/tokenizer ext/lexbor/lexbor/html/tree\ + ext/lexbor/lexbor/html/tree/insertion_mode ext/lexbor/lexbor/ns\ + ext/lexbor/lexbor/ports/posix/lexbor/core\ + ext/lexbor/lexbor/punycode ext/lexbor/lexbor/tag\ + ext/lexbor/lexbor/unicode ext/lexbor/lexbor/url ext/opcache\ + ext/pcre ext/pcre/pcre2lib ext/random ext/reflection ext/spl\ + ext/standard ext/standard/libavifinfo ext/uri\ + ext/uri/uriparser/src main main/streams sapi/cli + INCS=-I. -I$PHPSRC -I$PHPSRC/main -I$PHPSRC/Zend -I$PHPSRC/TSRM\ -I$PHPSRC/ext/date/lib -I$PHPSRC/ext/lexbor\ -I$PHPSRC/ext/uri/uriparser/include @@ -661,14 +679,48 @@ INCS=-I. -I$PHPSRC -I$PHPSRC/main -I$PHPSRC/Zend -I$PHPSRC/TSRM\ CFLAGS=-c $DEFS $INCS # The objects live beside their sources in the build directory, so the -# directory has to exist before `pcc -o' can write into it. +# directories have to exist before `pcc -o' can write into them. +# +# ***THE FIRST VERSION SAID ``mkdir -p `{basename -d $target}'' AND +# THAT IS A PLAN 9 IDIOM THIS SHELL DOES NOT HAVE.*** Inside +# `apexp-sh' the union mount puts APExp's own `/bin' first, so +# `basename' is **GNU coreutils'**, which has no `-d': +# +# basename: invalid option -- d +# mkdir: missing operand +# +# -- and mk then reported the failure of the compile, not of the +# `mkdir'. *The same shape as "check which `6l' answers"*: a command +# name inside `apexp-sh' is whatever the union resolves it to, and +# Plan 9's own flags are the ones most likely to be missing. +# +# So no external command at all: the directory list is known +# statically, `mkdir -p' is idempotent, and one exec per compile is +# nothing beside 513 runs of pcc. %.$O: $PHPSRC/%.c - mkdir -p `{basename -d $target} + mkdir -p $OBJDIRS $CC $CFLAGS $prereq -o $target %.$O: %.c $CC $CFLAGS $stem.c +# ***ONE OBJECT IS NOT NAMED AFTER ITS SOURCE.*** `ext/json's parser +# is bison-generated, and the generated file SHIPS IN THE TARBALL as +# `json_parser.tab.c' -- so the object upstream calls +# `ext/json/json_parser.lo' is built from `json_parser.tab.c', not +# from a `json_parser.c' that does not exist. mk said so plainly: +# `no recipe to make 'ext/json/json_parser.6''. +# +# **No bison and no re2c are needed anywhere in this port**, which was +# worth checking rather than assuming: `json_scanner.c' and +# `php_json_scanner_defs.h' are in the tarball too, as are the four +# Zend parsers and scanners and the 4.2MB `zend_vm_execute.h'. A +# sweep of all 513 objects against the vendored tree found this as the +# ONLY name that does not resolve. +ext/json/json_parser.$O: $PHPSRC/ext/json/json_parser.tab.c + mkdir -p $OBJDIRS + $CC $CFLAGS -I$PHPSRC/ext/json $prereq -o $target + # mkone's `clean' is `rm -f *.[$OS] ...', which cannot see an object in # a subdirectory -- and 512 of the 513 here are in one. Overriding it # means repeating what it does, the same as `cmd/bash/mkfile'.