1. 60
    1. 31

      As some of you noticed I disabled my account and disappeared for a bit. This was mostly ‘externalising’ a self imposed constraint to stop finding excuses and push this one through (also finishing a contract for a client and to start looking for new things).

      For reasons covered in the post, it was an emotionally difficult hurdle. I have quite a few battle scars worn with some pride. It is one thing to tune out the general ‘Web 2.blergh’ attenuated negativity from the various forums and contain the own anger that it feeds. It is quite another to try and do so when parts of the work you represent and >chose to expose< is grounded in the last memories you have of someone that lost the fight; the risk of those frozen moments thawing into oblivion. I think I cleared this obstacle. I am anything but certain.

      1. 32

        I came to ask if anyone knew why you’d disabled your account, glad you’re back!

        I’d be careful in the xmake transition. I’m looking to move CHERIoT RTOS away from xmake (thanks to @borisk for working on a potential replacement). I liked the idea of xmake a lot, it the more I use it, the more I learn both that it’s highly opinionated (with bizarre opinions) and that it has no underlying model. For example:

        • If you specify compiler flags, xmake will silently drop them unless it knows that the compiler supports them. This isn’t done by querying the compiler, xmake just has a hard-coded list, so if someone else uses a newer xmake they may be passed through (conversely, someone using an older xmake may find critical build flags are silently removed and the build fails). I cannot comprehend the mindset that believes this is a good idea. The only way to avoid it is to pass an undocumented { force = true } extra parameter all over the place. This works for flags but not for things like the default language (want C23? You must set it by forcing a flag, not by setting the language).
        • It hides all warnings by default. If you do not pass -w on the command, any compiler step that emits warnings will produce no output. The rationale for this is that most users don’t want to see warnings, only developers. I have no idea who the author thinks users of a build system are. Oh, and although error messages are output, they’re arbitrarily truncated. You can see the full version only by passing -v, but that emits a load of other output as well (xmake internal tracing things)
        • It’s strongly typed. Targets have target kinds that define special rules, but these are just strings. If you make a typo, your target type becomes none. Oh, and there’s no way of adding new types.
        • When you build, xmake finds the xmake.lua furthest from you up the source tree. This impacts tree organisation. You can’t, for example, put tests or examples under your main project. If you clone your repo inside another, you must remember the -P option to build. This is made worse by the fact that xmake encourages building from the source, rather than driving the build from the build directory (welcome to 1990).
        • There is no modularity. Target names must be globally unique. If you include another project’s xmake.lua, you don’t see the targets that it exports in a namespace for that project, you see them all in the global namespace.
        • The way that dependencies are tracked is opaque. If you have custom build steps that produce intermediate files, expect to have to do clean builds periodically because you’ll probably get dependency tracking wrong.
        • Oh, you thought you did a clean build? Think again, it does some internal caching of things that are not invalidated on clean builds. It also has its own ccache analogue, which doesn’t always get invalidation right. You will find rm -rf build .xmake appear a lot in your command history after builds fail for random reasons.
        • The core abstractions simply don’t exist. I’ve tried asking the author what the key parts of the abstract model are and got nothing. It’s just a pile of Lua that does stuff. Sometimes that stuff changes between minor versions.

        I don’t agree with all of the decisions in build2 (especially some of the defaults) but at least the defaults can be fairly easily overridden and they’ve thought about the hard problems.

        1. 1

          Thanks for the wb!, I had to bite my tongue a few times as the /comments RSS is still in my CLI- built-ins but the restraints were enough of ‘keep the faith’ that I got things done - I was about to /mail the @cam one before getting to the point where I can stomach more Wayland me-too hellthreads derailing all things interesting (that my highest ‘upvoted comment’ here covering … 5% of grievances being plastered across 4chan didn’t exactly help motivation). I will hide in Tokyos various cigar and cocktail bars for a bit to escape the Swedish winter, but I still intend to take you up on that beer when the weather isn’t sheit.

          Added thanks for the breakdown - practical CM experience pitfalls is rare dissemination and an important part mostly absent from the seemingly infinite PL/formal methods/langsec/memsafe tirades. I’d pay premium for horror stories from both android and chrome’s build systems, as I’ve been spoiled by having CM teams to lean on in the past.

          There are indeed a few dealbreakers for me there (not worse than what CMake has to offer but…). Although I’d love to send the ‘Lua at every layer’ message to show that the ‘BASIC of the 90ies’ could be used to provide agency for every substantial part of someone’s early steps into computing and instead focus on the dynamics that makes all this more interesting than mere unrequited love for mathematics, not syntax/semantics – build systems into packaging into execution is a ruly beast indeed, with the interesting property in that they can seemingly get away with endless abuse, whether that is LLM training tuning, bitstream compilation or ’rational clearcase massaging IAR to get objects verified through Excel just to get NCed to 3rd party servers for patching (true story).

          1. 5

            I’d pay premium for horror stories from both android and chrome’s build systems, as I’ve been spoiled by having CM teams to lean on in the past.

            Hm not sure exactly what you mean with Android and Chrome, but they both use a language that generates Ninja. (And this wasn’t either of their first build system – Android used plain GNU Make, and Chrome used Scons - https://neugierig.org/software/chromium/notes/2011/02/ninja.html )

            Now Chrome uses “GN” generating Ninja - https://chromium.googlesource.com/chromium/src/tools/gn/+/48062805e19b4697c5fbd926dc649c78b6aaa138/README.md

            Android uses “Blueprint” generating Ninja - https://android.googlesource.com/platform/build/bazel/+/7d96ed30359f12311dd7a78c399e29eb695b2012/docs/concepts.md

            If you look at the syntax, they are both similar to and influenced by Google’s earlier Bazel build system

            https://gn.googlesource.com/gn/+/refs/heads/main/examples/simple_build/BUILD.gn

            The Android page has a direct mapping to Bazel concepts – Blueprint is Starlark, and Ninja is Bazel’s execution phase.


            I use the same pattern in Oils, but with plain Python, and it works well:

            https://lobste.rs/s/qnb7xt/ninja_is_enough_build_system#c_tutskb

            https://www.oilshell.org/blog/2022/10/garbage-collector.html#declarative-ninja-mini-bazel – it’s a “mini-Bazel” on top of Ninja.

            And I’m not the only one using it – contributors seem to have good results with it, and a few have updated the build configs.

            The pattern is to have a high-level application dep graph lowered to a low-level Ninja dep graph.


            So you can almost certainly do the same thing in Lua if you like. It’s not trivial but it’s around 1000 lines of code.

            I simplified the pattern so you have a .py file in each directory, and then a main file that imports all of them and threads as Rules ru object through. And then the build config is simply calling high level functions on ru objects, like ru.cc_binary() and ru.cc_library().

            This makes a big graph data structure in memory, and then I do some checks on it, with transitive dependencies for cc_binary, and then write out a huge Ninja file.

            Like I said it’s not trivial, but once you get the hang of it, the build system is entirely under your control, which is nice. It’s also very fast due to Ninja. This build config stage all happens in like 100 ms.

            And you can probably just port it directly from Python to Lua. I think it should work exactly the same way. There is a fair bit of shell, which is fine for us, because we’re not supporting Windows.

            The build variant support (ASAN, dbg, opt, -D FOO, etc.) is the best I’ve used. That part wasn’t trivial either and evolved a bit, but now it works very well.

            Main thing I would like is some help on missing deps, e.g. sandboxing of build actions, but most build systems don’t do that because it requires OS-specific techniques.

            1. 1

              Sorry, for some reason I didn’t see the alert on your reply. I worked on ‘everything is on fire and we release tomorrow’ debugging Android for an ODM for many years. The biggest(?) enabler I had was the team of CMs that could go navigate the absolute cesspit of DIY tools / patches and scripts to pull something in and get the miraculous ‘flashable and bootable and observable’ images of (revisions start..suspect..current) needed for triage.

              The choice in ‘discrete’ tools like Make et al. is a minor one and not what interests me, but the actual ‘system’ that emerges does because that is where so many of the bodies are buried and where dark secrets can be uncovered.

              Android is especially burdened here as the ‘fantastic’ choice of ‘repo/lunch/m/mm/mmm’ coupled with 3rd party repositories (get fscked QCM) that gung-ho decides to force-push things into oblivion because they leaked ‘secrets’ (or just bad/vulnerable code) for the n:th time, or switches authentication primitives so you need one set for the one checkout and another for repeating it 10 minutes later.

            2. 3

              We would have used CMake (and did for the first version) if not for the fact that CMake makes it very hard to add new abstractions. We have shared libraries and compartments that need a little bit of different linking and we need to propagate build setting back from the firmware image target to the things that it depends on. Both of these are possible (though clunky) in xmake, they’re just very painful (and break encapsulation) in CMake. If you don’t have those requirements, I’d definitely avoid it.

              Both xmake and build2 try to provide a layered system, where there are a set of core tools for building a dependency graph and assigning actions that run when traversing it, but build2 has a more principled design. I’m quite curious to see how much of the core machinery of build2 could be wired up to sol3 and exposed in Lua.

              1. 1

                My biggest gripe with CMake is the evolution of the thing and how the 2-3 major ‘style revisions’ clash and how that led to many conflicting recipes and style guides, just to then fight their many deprecations; spammy output and so on. Otherwise I like the toolchains, the relative robustness of rebuild and reactions to triggering on changes to Cache.txt and so on.

                The whole build system for Arcan could be much simplified these days - especially if I drop the requirement that the full architecture should work on OSX; be reasonable re-portable back into Windows (we used to NSIS/CPack up until 0.4 with MinGW - oh the compiler bugs ..); to be able to ‘cuckoo’ the role of SurfaceFlinger in Android (one of my bigger regrets not doubling down on that instead of trying to work with the kms/gbm stack).

                With the network protocol providing a sufficient compatibility boundary for allowing at least access, and permit development of bridging tools, into Win/OSX/Android/iOS for “sharing” (hey, the counter to what WSL2 is doing to Linux via Wayland, isn’t that interesting?) – all those requirements can be dropped.

                With SHMIF having a stable enough IPC system these days (albeit in need of a complete refactor regarding atomics etc. as it’s not 2008 anymore) and no breaking changes planned, much of the project can be split out into otherwise independent binaries and the main dependency graph shrinks considerably.

                If so the choice in build system more boils down to the recurring point of lowering the barrier to entry for budding developers (the Lua at every layer thing again). In the ‘As OS implementation’ sense I’d very much like to get to the point (and am fairly close) that a single 80ies style home computer era ‘bootrom’ (albeit on an SD card) for RPi 400 level hardware (preferably also weaker embedded with FPGA-GPU graphics sufficient for ‘SCADA systems in your home’ level so the big gaping HW vuln. hole everywhere can be closed) landing at a REPL form of writing CLIs/TUIs/“other Web” apps with ‘a safe share and collaborate with friends’ being close at hand.

                1. 3

                  we used to NSIS/CPack up until 0.4 with MinGW - oh the compiler bugs

                  My experience with MinGW is that it causes more problems than it solves. The MinGW ABI is a weird hybrid of ELF conventions and the Windows ABI. You can kind-of use Windows DLLs, but things don’t quite work. I gave up trying to support it for libobjc2. It was less effort to do a native Windows port than to work with all of the subtle ways in which MinGW wasn’t a *NIX and also didn’t behave like Windows.

                  With the network protocol providing a sufficient compatibility boundary for allowing at least access, and permit development of bridging tools, into Win/OSX/Android/iOS for “sharing” (hey, the counter to what WSL2 is doing to Linux via Wayland, isn’t that interesting?) – all those requirements can be dropped.

                  WSL2 does this a very weird way. They run a MS-provided Linux VM that has GPU passthrough and PipeWire, so your random distro just needs a pipewire client and can push things to the server. That runs a custom Wayland compositor that renders to texture, which is exposed to the Windows host. All of this works about as well as X11 over the loopback did, though with the addition of audio working.

                  SHMIF over VirtIO (or VMBus on Windows) would be a huge win relative to the PipeWire things for VM use cases.

                  If so the choice in build system more boils down to the recurring point of lowering the barrier to entry for budding developers (the Lua at every layer thing again).

                  I’d love to see a well-designed Lua-based build system, with clear layers of abstraction, a module system, and so on. I suspect Lua bindings to Build2 are a better path than xmake. A lot of xmake tries to hide that it’s Lua and so you have a mix of a declarative DSL and Lua, with certain things not exposed properly in one or the other direction.

                  1. 1

                    SHMIF over VirtIO (or VMBus on Windows) would be a huge win relative to the PipeWire things for VM use cases. The blocker for that now is the current reliance on posix semaphores (OSX .. /sigh) otherwise we’d switch to futexes yesterday as that means the privileged path can move away from named/filesystem objects completely.

                    Otherwise the Qemu side is still fairly in synch and can lift guest- side of the equation from LookingGlass.

                    WSL2 does this a very weird way. They run a MS-provided Linux VM that has GPU passthrough and PipeWire, so your random distro just needs a pipewire client and can push things to the server. That runs a custom Wayland compositor that renders to texture, which is exposed to the Windows host. All of this works about as well as X11 over the loopback did, though with the addition of audio working.

                    XWin is fairly interesting among the Xorg DDXes and the one I got the most out of reading the code for in all of Xorg, perhaps due to to some win32 malware reversing in my baggage as Windows UI programming was more Delphi VCL or MFC or mIRC et al “CreateWindowEx”. Microsoft were quite elaborate and timely in covering their bases should X ever become more than a legacy nuisance. Now why the Wayland angle was pushed in spite of this is, I’m guessing (given the available talent pool and no-one giving two tugs of a dead dog’s cock of the technical merits of a first-year student level of failed linear algebra trying their hand at an IDL and wire packing format), is that the risk of Mesa/GTK ‘gently pushing’ (with a hollerith guided hand) X11 into non-working status was high enough to warrant paying a few useful idiots a pittance to do the heavy lifting.

                    My cynical side “might” be shining through here but I put the long term prospects of using ‘whole system virtualization’ as a viable compatibility strategy moving forwards asymptotic a flatline - barrier to entry and legally questionable ‘one-click installer’ will just keep things out of reach the second you need it. In the other side of the equation, and this is from the grapevine (just as it was a secret to nobody about Mali/Adreno’s “qualities” as the actually ‘central’ processing unit very early on), the massive ‘just try to get it working’ codebase copied verbatim between all the Linuxes and BSDs render any other security layering moot (/dev/dri/renderDXXX will be descriptor 5 or 6 or so). I’m banking on hardware compartmentalisation for now. For that one needs bridging tools and a protocol - and here we are.

                    I’d love to see a well-designed Lua-based build system, with clear layers of abstraction, a module system, and so on. I suspect Lua bindings to Build2 are a better path than xmake. A lot of xmake tries to hide that it’s Lua and so you have a mix of a declarative DSL and Lua, with certain things not exposed properly in one or the other direction.

                    I haven’t given it more than a cursory glance, and there seem to be infinitely many ’oh here is another build system with a huge glaring but! that is about to bite your own at some point in the future” but given https://gittup.org/tup a serious look? I only gotten far enough that a printout of the ‘Build system rules and Algorithms’ paper now rests in the armchair pile.

                    1. 1

                      I haven’t had a detailed look at tup. I think it solves only half the problem. The thing I want from a build system is:

                      • A way of specifying a dependency graph (possibly with some dynamic edges that are discovered only during the build), and
                      • A way of building composable abstractions.

                      From what I’ve read of tup, it looks as if they have some great solutions to the first and view the second as out of scope. If anything. I think the second is the harder problem. We were trying to build something nicer there with Fabrique, but got distracted with other projects.

              2. 1

                We would have used CMake (and did for the first version) if not for the fact that CMake makes it very hard to add new abstractions. We have shared libraries and compartments that need a little bit of different linking and we need to propagate build setting back from the firmware image target to the things that it depends on. Both of these are possible (though clunky) in xmake, they’re just very painful (and break encapsulation) in CMake. If you don’t have those requirements, I’d definitely avoid it.

                Both xmake and build2 try to provide a layered system, where there are a set of core tools for building a dependency graph and assigning actions that run when traversing it, but build2 has a more principled design. I’m quite curious to see how much of the core machinery of build2 could be wired up to sol3 and exposed in Lua.

            3. 7

              I love this work and look forward greatly to using it one day.

              1. 6

                I am teribly sorry to hear what a hurdle it was. When I finally dragged myself into opening my Mastodon account months ago and started building my follow list I realised you hadn’t posted here in a long time but I figured it was just more renovation work :-). It’s the sort of obstacle you clear everyday for a while. I’m happy to see a new Arcan release but really most of all I’m just happy you’re doing better!

                1. 2

                  Thanks for the concern, there is more health hazards around but mostly tied to the renovation work – near heart attack inducing panic-pumping sewage in the basement from clogged old pipes hidden deep in the 70ies concrete seeing the muddy stew rise towards towards the transformers and filtration for the galvo-fiber lasers, the Co2 ones, the CnCs, inching towards the inball machines etc, married well with many many various power tool love-bites. Upon finishing my latest contract I was given a pro-grade emergency kit as a present. No more deliberate soldering iron cauterisations planned nosire!

                  Did you land the 3D (game?) dev gig?

                  1. 3

                    Upon finishing my latest contract I was given a pro-grade emergency kit as a present.

                    Pro-grade as in it has one of those large flame-heated soldering irons for cauterising large wounds, right :-D?

                    Did you land the 3D (game?) dev gig?

                    I did! It’s been floating for a long time now, we actually started talking about it like two years ago but it kept getting derailed by other projects. It’s both tooling and game development work, since there’s not much of the former that you can do without knowing a bit about what’s itching people who do the latter.

                    I’m pretty happy about it. I haven’t even considered writing games professionally in a very long time – actually I don’t think I ever considered it as an actual programmer, only back when I was a snotty kid who’d copy-pasted all the examples in Smashing the Stack for Fun and Profit and thus felt entitled to opinions about everything. When I figured I would have to leave embedded development behind, and that I’d have to be open-minded and just not say no to things I can do well until something sticks, I wasn’t thinking as far away from an oscilloscope as this. I probably would’ve still said no to anyone else; but this is a small studio that I’ve worked with before, they make nice things, not DLC funnels, the people I know there are easy to work with and professional, and they have a culture of software quality that I’ve really missed lately.

                    So worst-case scenario is it turns out I really suck at this and get an year’s enrollment in an ad-hoc professional exchange program before they graciously tell me the renewal option was just standard legalese and we’re not taking it. That’s actually better than the last seven or so years’ best-case scenarios. Even if I hadn’t been so enthusiastic about it (modulo always expect the worst, this is the software industry after all), I’d have taken it just because I can’t see a losing path.

                    I hope you have a good Christmas in Tokyo! Here’s hoping the next one’s gonna find us in better shape :-).

                    (Someone’s flagging this as off-topic in 3, 2, 1…)

                    1. 1

                      I can pre-emptively flag it to discourage others or something then DM you. Maybe only the latter.

              2. 8

                Congrats on the funding!

                1. 5

                  Does anyone have a comparison matrix of what is supported between X11, Wayland, & Arcan?

                  Also congrats on both the funding & deciding to migrate off Microsoft & Discord.

                  1. 5

                    I don’t think so although I’d love to see one too.

                    It’s a difficult task. My impression is that comparing X and Arcan is a bit like comparing the wheel-and-axle and the inclined plane (being two of the classical simple machines)… this is meaningful and useful, because when you strip these things down to essentials like that, you could usefully do a big-picture, list-of-tick-boxes comparison like that.

                    But comparing with Wayland is like trying to compare “the wheel” with the forged wheel of a SF90 Spider. It’s one specific tool for one specific role. It’s not one of the simple machines. It’s one particular implementation of one particular type of wheel. You can compare it to other implementations but it’s not comparing like with like.

                    Compare Arcan with Rio and maybe that would be meaningful, but Wayland, I can’t quite see it. It’s a protocol that enables a window manager to become a display server, by specifying how that display server talks to apps and talks to graphical displays.

                    You can’t really compare the wheel with a wheel nut any more than you can compare Leonardo da Vinci with “a Liverpudlian”. They are both entities of class “human being” but one is a long-dead artist and designer, and the other is not a person, it’s a type of person. You can’t compare dissimilar entities like this.

                    Meaningful: Q: How can a wheel store energy? A: (an undergrad essay.)

                    Not meaningful: “How does the SF90 forged wheel store energy?” A: It doesn’t.

                    For comparison:

                    Q: Compare how Wayland and Arcan interact with the command line? A: You can’t, because Wayland doesn’t.

                    Q: Compare Wayland’s and Rio’s interaction models with the file system? A: You can’t. Wayland doesn’t interact with the filesystem.

                    Q: How does Wayland abstract the concept of “a window” and communicate that, compared to other window systems? A: You can’t, because Wayland doesn’t have that concept.

                    Q: How does Wayland communicate over the network with other instances compared to X and Arcan? A: It doesn’t.

                    1. 18

                      Wayland is in more pressing need of a matrix that shows:

                      1. Which of the umpteen different protocols actually make something into “wayland” because right now, nobody knows, Just look at this thing: https://wayland.app/protocols – there are even more out there. Guess how many of them have anything even resembling tests.
                      2. Which of the different ‘compositors’ implement which of the protocols.
                      3. Which of the many client side applications explicitly (if not then exit) expects, implicitly expects (registry lookup fail leading to null-deref) expects or optionally (if not then change behaviour) depend on which of the protocols. There are close to no actual guarantees.

                      This combined with a big disclaimer as to which expected features are snuck in through one of the ‘d-bus’, ‘portals’, ‘pipewire’ backdoors used to cover things that were solvable in X11, deemed ‘out of scope’ and subsequently breaks what little actual ‘network transparency’ they pretend to have.

                      There are enough clues given by now to put another card on the table. The last ‘second order form’ article on Arcan design will be titled ‘A browser for different webs’ - because that is what this is. Visit the linked article on A12: Visions of the Networked Desktop for more examples to the effect. See this slide from close to 10 years ago: https://speakerdeck.com/letoram/arcan?slide=2 … That’s a browser.

                      The distance from say, adding a way for Chrome to “embed” another process versus a ‘window manager’ that maps a DOM as X11 ‘Windows’ with script triggers stored in per window ATOMs is quite short. This shouldn’t come as a surprise, Heck, Microsoft understood this strongly way back in the 90ies. Compare NeWS to the emergent first era browsers. Electron proved beyond doubt that the ‘toolkit’ part was covered. The wrong tech choices won and we got a torrent of hacks.

                      Just as Nelson tried to communicate, repeatedly (hence why his ‘computing for cynics’ is used as the example video playback in the clip) - there are more and in my opinion, infinitely more interesting, models for most ‘dynamic, linked’ networked documents than the one we ended up with.

                      What’s interesting in this space is that the cost for putting a feature wrong in the architecture is absolutely murderous. The layering of ‘secure transport’ first solving authentication but then having to re-implement authentication on the app level “register and login” just because authenticated identity wasn’t preserved is one that alone has cost humanity dearly, though there are others as well.

                      Instead of cooperating with local processes (the display server part) browsers emphasised assimilation through virtualisation again and again – but of course this time yet another ‘universal’ ISA will get it right and turn out better than Java Applets or Flash. For window management we basically got clunky tabs and called it a day (RiP Old MDI Opera).

                      Instead of decoupling the networked document part into a ‘retrieve, compile and sign’ pass (in other places we did figure out ‘build systems’) into a viewer that would have opened up for many other models, it all just merged into a monolith and through that, stuck infinitely making a document that bootsraps an application that generate documents that ..

                      1. 4

                        TBH I wish I understood it better myself, because I’d like to try to write a simple explanation of this stuff for non-specialist audiences, but I have only a dim partial understanding of X11 and Wayland as it is, and less than that of Arcan.

                        Delighted to hear you have some funding, though!