. "$BST_LIB" # BST-TIMEOUT: 300 # one probe run plus ~150 shell extractions; the 60s default # is for suites that fork far less than this one does. # fltk 1.3.8 -- a GUI toolkit on an image with no display. # # --------------------------------------------------------------------------- # WHAT THIS PORT SHIPS, AND WHY THE SUITE IS NOT A FILE LISTING # # The image takes fltk-dev and fltk-staticdev: the FL/ headers, libfltk.a, # libfltk_images.a, libfltk_forms.a and fltk-config. No window will ever open # here -- XOpenDisplay has nothing to connect to and every FLTK route to a # display ends in Fl::fatal() and exit(1) -- so the honest statement of what was # ported is NOT "a working toolkit" and is also not "some files arrived". # # It is this: the parts of FLTK that are pure computation cross-compiled # correctly. That is a large and useful part of the library -- the UTF-8 codec, # the filename and glob machinery, Fl_Text_Buffer, Fl_Preferences, the image # decoders and the widget tree -- and every one of it can be complete, # installed and WRONG on a new architecture with nothing else going red. So the # recipe builds fltk-probe against the very archives it ships and this suite # drives it. # # WHY THE EXPECTATIONS ARE WRITTEN OUT HERE rather than diffed against a # build-host reference, which is what 57-libx11.test does. libx11's question -- # what a code generator emitted under cross -- has no absolute answer, so only a # reference can state it. This one mostly does: the codec cases are fixed by # Unicode, the glob cases by fl_filename_match's documented syntax, the geometry # and colour cases by integer arithmetic, and the image cases by a fixture # generated with four solid quadrants for exactly this reason. Where a value is # FLTK's own answer rather than a standard's -- fl_filename_relative's output, # Fl_Text_Buffer's undo arithmetic, the desaturation weight -- it was measured # on an x86-64 control built from the same tarball with the same switches, and # the design doc records that run. An absolute expectation does not rot when the # build host moves. # # --------------------------------------------------------------------------- # READ A RED IN SECTION ORDER; THE FIRST SECTION TO GO RED LOCALISES THE DEFECT # # 1 the payload arrived packaging only # 2 fltk-config answers what a consumer on this image is told # 3 the probe runs to its end libfltk.a executes on this arm # 4 identity -dev and -staticdev came from one build # 5 the UTF-8 codec the arch-sensitive core # 6 filenames and the glob matcher pure string work # 7 Fl_Text_Buffer the editing engine # 8 Fl_Preferences FLTK's own I/O, end to end # 9 the image decoders libpng and libjpeg-turbo through FLTK # 10 the widget tree, and the C++ arm vtables and RTTI, measured # 11 the display that is not there the limitation, as a measurement # # A build where 3 passes and 5 does not has a word-size fault in the toolchain # rather than anything wrong with this recipe. One where 9 goes red without 5 # is a decoder dependency, not FLTK. One where 10's RTTI cases go red is the # exceptions-off libc++ arm having produced something that links and is not a # polymorphic library -- which is the failure this port was written to rule out. require fltk-config fltk/present INC=/usr/include/FL LIB=/usr/lib PROBE=/usr/libexec/fltk-tests/fltk-probe # --- 1. the payload ------------------------------------------------------- check fltk/hdr-fl test -f "$INC/Fl.H" check fltk/hdr-window test -f "$INC/Fl_Window.H" check fltk/hdr-x test -f "$INC/x.H" check fltk/hdr-utf8 test -f "$INC/fl_utf8.h" check fltk/hdr-enum test -f "$INC/Enumerations.H" check fltk/lib-fltk test -f "$LIB/libfltk.a" check fltk/lib-images test -f "$LIB/libfltk_images.a" check fltk/lib-forms test -f "$LIB/libfltk_forms.a" # Whatever shared objects this recipe ships must be usable: no .so at all means # unconverted, and a dangling or empty one is the packaging split that leaves the # symlink in the runtime package and its target in -dev. bst_lib_shape fltk/no-shared "$LIB/libfltk*.so*" # --- 2. fltk-config, the consumer-facing half of a -dev package ----------- check_out fltk/config-version "1.3.8" fltk-config --version check_out fltk/config-api "1.3" fltk-config --api-version check_out fltk/config-includedir "/usr/include" fltk-config --includedir # --cxxflags does NOT carry -I/usr/include, and that is correct rather than a # gap: fltk-config.in:219 emits the -I only when includedir differs from # /usr/include. What it must carry is the large-file dialect the archive was # compiled with, since a consumer that disagrees gets a different off_t. check_out fltk/config-cxxflags "_FILE_OFFSET_BITS=64" fltk-config --cxxflags # --ldstaticflags must name the archive that actually shipped, by its installed # path -- this is the line a consumer on this image would paste into a link check_out fltk/config-ldstatic "/usr/lib/libfltk.a" fltk-config --ldstaticflags # and it must name the WHOLE static X11 chain. libX11.a calls into libxcb and # libxcb into libXau and libXdmcp; a consumer who pastes a line naming only # -lX11 -lXext gets `wasmld: phantom import: env.xcb_disconnect' rather than a # missing-symbol diagnostic. The recipe adds the three; this is the check that # they are still there. check_out fltk/config-ldstatic-xcb "-lxcb" fltk-config --ldstaticflags # and none of it may still point into the build host's sysroot. binconfig # rewrites those paths at packaging time, and a leaked build path is the classic # way a -dev package is unusable while every file is present. if fltk-config --cxxflags --ldstaticflags 2>&1 | grep -q 'tmp-glibc\|recipe-sysroot\|/build/'; then bst_notok fltk/config-no-buildpaths "fltk-config still names a build-tree path" else bst_ok fltk/config-no-buildpaths fi # --- 3. the probe --------------------------------------------------------- check fltk/probe-shipped test -f "$PROBE" W=${TMPDIR:-/tmp}/bst-fltk.$$ mkdir -p "$W" P="$W/fltk-probe" FACTS="$W/facts" if cp "$PROBE" "$P" 2>/dev/null && chmod +x "$P" 2>/dev/null; then "$P" > "$FACTS" 2>"$W/err"; prc=$? bst_ok fltk/probe-staged else bst_notok fltk/probe-staged "cannot copy $PROBE to $P" : > "$FACTS"; prc=127 fi check_eq fltk/probe-rc 0 "$prc" # PROBE-END is the terminator: a probe that stopped half way through prints a # prefix of the facts below, and every one of those cases would then read # MISSING rather than wrong. This case is what separates the two readings. check_out fltk/probe-end "PROBE-END" cat "$FACTS" # One awk per case, against the file the probe already wrote -- the probe is # NOT re-run per case. MISSING is printed for an absent key so a case that lost # its line is a red with a legible cause rather than an empty comparison. fact() { awk -v k="$1" '$1==k { $1=""; sub(/^ /,""); print; f=1 } END { if (!f) print "MISSING" }' "$FACTS" } # --- 4. identity ---------------------------------------------------------- # The header's constant and the archive's function, compared on the target. # They come from different packages, so a mismatch is fltk-dev and # fltk-staticdev built at different times -- which no file listing can see. check_eq fltk/ver-hdr-api 10308 "$(fact VER-HDR-API)" check_eq fltk/ver-lib-api 10308 "$(fact VER-LIB-API)" check_eq fltk/ver-match 1 "$(fact VER-MATCH)" check_eq fltk/ver-lib-abi 10300 "$(fact VER-LIB-ABI)" # --- 5. the UTF-8 codec --------------------------------------------------- # FLTK's own codec, not the C library's. wchar_t is 4 bytes on this arm, which # is why the wide-character cases are here rather than assumed: on a 2-byte # wchar_t host UTF8-TOWC-N would be 5, not 4. check_eq fltk/utf8-wchar-size 4 "$(fact UTF8-WCHAR-SIZE)" check_eq fltk/utf8-bytes-ascii 1 "$(fact UTF8-BYTES-ASCII)" check_eq fltk/utf8-bytes-eacute 2 "$(fact UTF8-BYTES-EACUTE)" check_eq fltk/utf8-bytes-euro 3 "$(fact UTF8-BYTES-EURO)" check_eq fltk/utf8-bytes-emoji 4 "$(fact UTF8-BYTES-EMOJI)" check_eq fltk/utf8-roundtrip 1 "$(fact UTF8-ROUNDTRIP)" check_eq fltk/utf8-encoded-bytes 10 "$(fact UTF8-ENCODED-BYTES)" check_eq fltk/utf8-strlen 10 "$(fact UTF8-STRLEN)" check_eq fltk/utf8-nbchar 4 "$(fact UTF8-NBCHAR)" check_eq fltk/utf8-test 4 "$(fact UTF8-TEST)" check_eq fltk/utf8-test-bad 0 "$(fact UTF8-TEST-BAD)" check_eq fltk/utf8-len1-lead 2 "$(fact UTF8-LEN1-LEAD)" check_eq fltk/utf8-towc-n 4 "$(fact UTF8-TOWC-N)" check_eq fltk/utf8-towc-last 128512 "$(fact UTF8-TOWC-LAST)" check_eq fltk/utf8-fromwc-n 10 "$(fact UTF8-FROMWC-N)" check_eq fltk/utf8-fromwc-eq 1 "$(fact UTF8-FROMWC-EQ)" # UTF-16 is where the surrogate pair appears whatever wchar_t is check_eq fltk/utf8-utf16-n 5 "$(fact UTF8-TOUTF16-N)" check_eq fltk/utf8-utf16-hi 55357 "$(fact UTF8-TOUTF16-HI)" check_eq fltk/utf8-utf16-lo 56832 "$(fact UTF8-TOUTF16-LO)" check_eq fltk/utf8-tolower 233 "$(fact UTF8-TOLOWER-C9)" check_eq fltk/utf8-toupper 201 "$(fact UTF8-TOUPPER-E9)" check_eq fltk/utf8-strcasecmp 0 "$(fact UTF8-STRCASECMP)" check_eq fltk/utf8-strncasecmp 0 "$(fact UTF8-STRNCASECMP)" check_eq fltk/utf8-fwd 3 "$(fact UTF8-FWD-OFF)" check_eq fltk/utf8-back 3 "$(fact UTF8-BACK-OFF)" check_eq fltk/utf8-nonspacing 1 "$(fact UTF8-NONSPACING-COMBINING)" check_eq fltk/utf8-spacing 0 "$(fact UTF8-NONSPACING-A)" # --- 6. filenames and the glob matcher ----------------------------------- # fl_filename_match is FLTK's own matcher, not fnmatch(3): brace alternation # and negated classes are part of its documented syntax. check_eq fltk/fn-name "a.test" "$(fact FN-NAME)" check_eq fltk/fn-name-bare "a.test" "$(fact FN-NAME-BARE)" check_eq fltk/fn-ext ".gz" "$(fact FN-EXT)" check_eq fltk/fn-setext "/tmp/report.json" "$(fact FN-SETEXT)" check_eq fltk/fn-match-star 1 "$(fact FN-MATCH-STAR)" check_eq fltk/fn-match-qmark 1 "$(fact FN-MATCH-QMARK)" check_eq fltk/fn-match-class 1 "$(fact FN-MATCH-CLASS)" check_eq fltk/fn-match-negclass 0 "$(fact FN-MATCH-NEGCLASS)" check_eq fltk/fn-match-brace 1 "$(fact FN-MATCH-BRACE)" check_eq fltk/fn-match-no 0 "$(fact FN-MATCH-NO)" # asked about paths the probe made itself: an ABSENT path also answers 0, so a # case pointed at something that might not be on the image would pass for the # wrong reason. The subdir case is what makes the file case mean anything. check_eq fltk/fn-isdir-root 1 "$(fact FN-ISDIR-ROOT)" check_eq fltk/fn-isdir-subdir 1 "$(fact FN-ISDIR-SUBDIR)" check_eq fltk/fn-isdir-file 0 "$(fact FN-ISDIR-FILE)" check_eq fltk/fn-isdir-absent 0 "$(fact FN-ISDIR-ABSENT)" check_eq fltk/fn-absolute "/a/b/../c.txt" "$(fact FN-ABSOLUTE)" check_eq fltk/fn-relative "b/c.txt" "$(fact FN-RELATIVE)" check_eq fltk/fn-relative-up "../../x/y.txt" "$(fact FN-RELATIVE-ELSEWHERE)" check_eq fltk/fn-expand "/root/prefs.ini" "$(fact FN-EXPAND-TILDE)" # the dirent-backed half, over a tree the probe built itself check_eq fltk/fn-list-n 6 "$(fact FN-LIST-N)" check_eq fltk/fn-list-subdir 1 "$(fact FN-LIST-SUBDIR-SLASH)" check_eq fltk/fn-list-file 1 "$(fact FN-LIST-FILE)" # --- 7. Fl_Text_Buffer ---------------------------------------------------- # The engine under Fl_Text_Editor, and the largest piece of FLTK a headless # consumer on this image could actually use. check_eq fltk/tb-length 17 "$(fact TB-LENGTH)" check_eq fltk/tb-lines 3 "$(fact TB-LINES)" check_eq fltk/tb-line-start 6 "$(fact TB-LINE-START)" check_eq fltk/tb-line-end 10 "$(fact TB-LINE-END)" check_eq fltk/tb-line-text "beta" "$(fact TB-LINE-TEXT)" check_eq fltk/tb-search-fwd 1 "$(fact TB-SEARCH-FWD-RC)" check_eq fltk/tb-search-fwd-pos 11 "$(fact TB-SEARCH-FWD-POS)" check_eq fltk/tb-search-back 1 "$(fact TB-SEARCH-BACK-RC)" check_eq fltk/tb-search-back-pos 6 "$(fact TB-SEARCH-BACK-POS)" check_eq fltk/tb-search-case 0 "$(fact TB-SEARCH-CASE)" check_eq fltk/tb-search-nocase 1 "$(fact TB-SEARCH-NOCASE)" check_eq fltk/tb-after-insert 20 "$(fact TB-AFTER-INSERT)" check_eq fltk/tb-after-replace 20 "$(fact TB-AFTER-REPLACE)" check_eq fltk/tb-byte-at 35 "$(fact TB-BYTE-AT-0)" check_eq fltk/tb-selected 1 "$(fact TB-SELECTED)" check_eq fltk/tb-selection "alpha" "$(fact TB-SELECTION)" check_eq fltk/tb-after-remove 17 "$(fact TB-AFTER-REMOVE)" check_eq fltk/tb-undo-rc 1 "$(fact TB-UNDO-RC)" check_eq fltk/tb-after-undo 20 "$(fact TB-AFTER-UNDO)" check_eq fltk/tb-tab-distance 4 "$(fact TB-TAB-DISTANCE)" # UTF-8 awareness: the cursor steps characters, not bytes check_eq fltk/tb-utf8-length 6 "$(fact TB-UTF8-LENGTH)" check_eq fltk/tb-utf8-next1 1 "$(fact TB-UTF8-NEXT1)" check_eq fltk/tb-utf8-next2 3 "$(fact TB-UTF8-NEXT2)" check_eq fltk/tb-utf8-next3 6 "$(fact TB-UTF8-NEXT3)" check_eq fltk/tb-utf8-prev 3 "$(fact TB-UTF8-PREV)" check_eq fltk/tb-utf8-align 3 "$(fact TB-UTF8-ALIGN)" check_eq fltk/tb-utf8-dispchars 3 "$(fact TB-UTF8-DISPCHARS)" # --- 8. Fl_Preferences ---------------------------------------------------- # Write, flush, destroy, reopen, read back -- the only section that puts FLTK's # own file I/O on the virtiofs root under test end to end. check_eq fltk/pref-int 424242 "$(fact PREF-INT)" check_eq fltk/pref-double 35 "$(fact PREF-DOUBLE-X10)" check_eq fltk/pref-str "yes" "$(fact PREF-STR-OK)" # size() reports the ENCODED length: a binary entry is two hex characters per # byte, so five bytes measure ten. Both are asserted because a caller reading # size() as a byte count is the mistake this pair exists to document. check_eq fltk/pref-blob-enc 10 "$(fact PREF-BLOB-ENCODED-SIZE)" check_eq fltk/pref-blob-dec 5 "$(fact PREF-BLOB-DECODED-SIZE)" check_eq fltk/pref-blob-ok 1 "$(fact PREF-BLOB-OK)" check_eq fltk/pref-exists 1 "$(fact PREF-ENTRY-EXISTS)" check_eq fltk/pref-absent 0 "$(fact PREF-ENTRY-ABSENT)" check_eq fltk/pref-groups 1 "$(fact PREF-GROUPS)" check_eq fltk/pref-group-exists 1 "$(fact PREF-GROUP-EXISTS)" check_eq fltk/pref-nested 2 "$(fact PREF-NESTED-DEPTH)" check_eq fltk/pref-entries 4 "$(fact PREF-ENTRIES)" check_eq fltk/pref-default 777 "$(fact PREF-DEFAULT)" check_eq fltk/pref-after-delete 0 "$(fact PREF-AFTER-DELETE)" # --- 9. the image decoders ------------------------------------------------ # libpng and libjpeg-turbo reached through FLTK, with no display in the path. # The fixture is four solid quadrants, so the PNG assertions are exact; JPEG is # lossy and gets the coarse one. The broken-input case is the one that needs # libpng's longjmp to arrive rather than merely its setjmp to return 0. check_eq fltk/img-png-fail 0 "$(fact IMG-PNG-FAIL)" check_eq fltk/img-png-w 8 "$(fact IMG-PNG-W)" check_eq fltk/img-png-h 6 "$(fact IMG-PNG-H)" check_eq fltk/img-png-d 3 "$(fact IMG-PNG-D)" check_eq fltk/img-png-tl-r 255 "$(fact IMG-PNG-TL-R)" check_eq fltk/img-png-tl-g 0 "$(fact IMG-PNG-TL-G)" check_eq fltk/img-png-tl-b 0 "$(fact IMG-PNG-TL-B)" check_eq fltk/img-png-tr-g 255 "$(fact IMG-PNG-TR-G)" check_eq fltk/img-png-bl-b 255 "$(fact IMG-PNG-BL-B)" check_eq fltk/img-pnga-fail 0 "$(fact IMG-PNGA-FAIL)" check_eq fltk/img-pnga-d 4 "$(fact IMG-PNGA-D)" check_eq fltk/img-jpg-fail 0 "$(fact IMG-JPG-FAIL)" check_eq fltk/img-jpg-w 8 "$(fact IMG-JPG-W)" check_eq fltk/img-jpg-h 6 "$(fact IMG-JPG-H)" check_eq fltk/img-jpg-d 3 "$(fact IMG-JPG-D)" check_eq fltk/img-jpg-redish 1 "$(fact IMG-JPG-TL-REDISH)" check_eq fltk/img-copy-w 16 "$(fact IMG-COPY-W)" check_eq fltk/img-copy-h 12 "$(fact IMG-COPY-H)" check_eq fltk/img-copy-d 3 "$(fact IMG-COPY-D)" check_eq fltk/img-desat-d 1 "$(fact IMG-DESAT-D)" # 79 = 255*31/100, FLTK's own luminance weight for pure red check_eq fltk/img-desat-tl 79 "$(fact IMG-DESAT-TL)" check_eq fltk/img-broken 1 "$(fact IMG-BROKEN-FAILS)" check_eq fltk/img-broken-w 0 "$(fact IMG-BROKEN-W)" check_eq fltk/img-xpm-w 4 "$(fact IMG-XPM-W)" check_eq fltk/img-xpm-h 2 "$(fact IMG-XPM-H)" # --- 10. the widget tree, and the C++ arm --------------------------------- # A widget tree is memory, not pixels. The RTTI and vtable cases are this # port's evidence that the exceptions-off libc++ arm produced a real # polymorphic library: a dynamic_cast and a virtual call through a base pointer # each need a typeinfo record and a vtable that a wrongly built C++ arm loses # while still linking. check_eq fltk/wid-win-w 320 "$(fact WID-WIN-W)" check_eq fltk/wid-win-h 240 "$(fact WID-WIN-H)" check_eq fltk/wid-win-label "probe" "$(fact WID-WIN-LABEL)" check_eq fltk/wid-win-children 1 "$(fact WID-WIN-CHILDREN)" check_eq fltk/wid-grp-children 2 "$(fact WID-GRP-CHILDREN)" check_eq fltk/wid-grp-find-box 0 "$(fact WID-GRP-FIND-BOX)" check_eq fltk/wid-grp-find-btn 1 "$(fact WID-GRP-FIND-BTN)" check_eq fltk/wid-parent 1 "$(fact WID-BOX-PARENT-IS-GRP)" # never shown, so no display was touched to get this far check_eq fltk/wid-win-shown 0 "$(fact WID-WIN-SHOWN)" check_eq fltk/wid-win-visible 0 "$(fact WID-WIN-VISIBLE)" check_eq fltk/wid-box-x 30 "$(fact WID-BOX-X)" check_eq fltk/wid-box-y 40 "$(fact WID-BOX-Y)" check_eq fltk/wid-box-w 120 "$(fact WID-BOX-W)" check_eq fltk/wid-box-h 50 "$(fact WID-BOX-H)" check_eq fltk/wid-boxtype 2 "$(fact WID-BOX-BOXTYPE)" check_eq fltk/wid-labelsize 17 "$(fact WID-BOX-LABELSIZE)" check_eq fltk/wid-color 88 "$(fact WID-BOX-COLOR)" # 0x11223300 -- fl_rgb_color packs the three bytes and leaves the index zero check_eq fltk/wid-rgb-color 287453952 "$(fact WID-RGB-COLOR)" check_eq fltk/wid-getcolor-r 255 "$(fact WID-GETCOLOR-RED-R)" check_eq fltk/wid-getcolor-g 0 "$(fact WID-GETCOLOR-RED-G)" check_eq fltk/wid-getcolor-b 0 "$(fact WID-GETCOLOR-RED-B)" check_eq fltk/wid-callbacks 2 "$(fact WID-CALLBACK-HITS)" check_eq fltk/wid-after-remove 1 "$(fact WID-GRP-AFTER-REMOVE)" check_eq fltk/rtti-dyncast-btn 1 "$(fact RTTI-DYNCAST-BUTTON)" check_eq fltk/rtti-dyncast-neg 1 "$(fact RTTI-DYNCAST-GROUP)" check_eq fltk/rtti-dyncast-up 1 "$(fact RTTI-DYNCAST-UPCAST)" check_eq fltk/rtti-typeid "yes" "$(fact RTTI-TYPEID-HAS-BUTTON)" check_eq fltk/vtable-as-window 1 "$(fact VTABLE-AS-WINDOW)" check_eq fltk/vtable-as-window-neg 1 "$(fact VTABLE-AS-WINDOW-NEG)" check_eq fltk/vtable-as-group 1 "$(fact VTABLE-AS-GROUP)" # --- 11. the display that is not there ------------------------------------ # The limitation, measured rather than asserted. XOpenDisplay returning NULL is # the CORRECT behaviour of a correctly built X client with no server, and it is # what makes "builds, links, cannot open a window" a measurement instead of a # claim. The probe calls Xlib directly: every FLTK route to a display ends in # Fl::fatal() and exit(1), so the toolkit cannot be asked this and survive to # answer. check_eq fltk/dpy-open-null 1 "$(fact DPY-OPEN-NULL-ENV)" check_eq fltk/dpy-open-colon0 1 "$(fact DPY-OPEN-COLON0)" check_eq fltk/dpy-fl-null 1 "$(fact DPY-FL-DISPLAY-NULL)" rm -rf "$W"