Skip to content

Instantly share code, notes, and snippets.

@egasimus
Last active May 17, 2021 09:39
Show Gist options
  • Save egasimus/0254dcd67f95f262aa6e133794738392 to your computer and use it in GitHub Desktop.
Save egasimus/0254dcd67f95f262aa6e133794738392 to your computer and use it in GitHub Desktop.
Building Arcan on NixOS, 2020 version
See also:
* https://github.com/NixOS/nixpkgs/issues/49626
* https://gist.github.com/telent/4a92294a767656759959006fe8440122
({ lib, newScope, stdenv, pkgs }: let
# nicer aliases
derive = stdenv.mkDerivation;
concat = builtins.concatStringsSep " ";
# vendored libuvc: don't build, just make sources available
libuvc-src = derive {
name = "libuvc-src";
# using fetchgit instead fetchFromGitHub because
# the .git directory is needed by arcan's cmake scripts
src = pkgs.fetchgit {
leaveDotGit = true;
url = "https://github.com/letoram/libuvc.git";
rev = "v0.0.6";
sha256 = "1jdmiinsd91nnli5hgcn9c6ifj0s6ngbyjwm0z6fim4f8krnh0sf";
};
nativeBuildInputs = with pkgs; [ git ];
# fetchgit strips all refs, leaving just a fetchgit branch
# but cmake needs to check out the ref called 'master':
installPhase = ''
git tag master
cp -r . $out/
cd $out
'';
};
# cmake flags pointing to locations of arcan headers
arcanIncludeDirs = arcan: [
"-DARCAN_SHMIF_INCLUDE_DIR=${arcan}/include/arcan/shmif"
"-DARCAN_TUI_INCLUDE_DIR=${arcan}/include/arcan"
];
# cmake flags pointing to locations of libusb1 headers and binaries
libusbDirs = libusb1: [
"-DLIBUSB_1_INCLUDE_DIRS=${libusb1.dev}/include/libusb-1.0"
"-DLIBUSB_1_LIBRARIES=${libusb1}/lib/libusb-1.0.so"
];
in lib.makeScope newScope (self: with self; let
mkArcanAppl = { name, src, applRoot }: callPackage ({ pkgs }: derive {
name = name;
src = src;
nativeBuildInputs = with pkgs; [ envsubst ];
buildInputs = [ arcan ];
installPhase = ''
mkdir -p $out/${name} $out/bin
cp -r ./${applRoot}/* $out/${name}/
Arcan=${arcan} Appls=$out Appl=${name} envsubst \
< ${./Arcan.wrapper} \
> $out/bin/arcan.${name}
chmod +x $out/bin/arcan.${name}
'';
}) {};
arcanRev = "280bb2f1b39da4465e391158d7debba4a8c168c6";
arcanCoreSrc = pkgs.fetchgit {
leaveDotGit = true;
url = "https://github.com/letoram/arcan.git";
rev = arcanRev;
sha256 = "0pzgb8s74na9wr8dy3bgvv23fry2zny4w6kzjyq1q5lnsgma0zqn";
};
in {
# arcan core:
arcan = callPackage ({ pkgs }: derive {
name = "arcan";
src = arcanCoreSrc;
patches = [ ./Arcan.nosuid.patch ]; # nix refuses to build suid binaries
postUnpack = '' # add vendored libuvc
mkdir -p ./arcan/external/git/libuvc
pushd ./arcan/external/git/
shopt -s dotglob nullglob # bashism: * now also matches dotfiles
cp -r ${libuvc-src}/* libuvc/
shopt -u dotglob nullglob # phases are stateful
popd
'';
nativeBuildInputs = with pkgs; [ cmake gcc git ];
buildInputs = with pkgs; [
apr
espeak-classic
file
ffmpeg-full
freetype
harfbuzzFull
leptonica
libGL
libdrm
libjpeg
libusb1
libvncserver
libxkbcommon
luajit
lzma
mesa
openal
SDL2
sqlite
tesseract
vlc
wayland
wayland-protocols
xorg.libxcb
xorg.xcbutil
xorg.xcbutilwm
];
PKG_CONFIG_PATH = concat [ # make wayland protocols available
"${pkgs.wayland-protocols}/share/pkgconfig"
"${pkgs.libusb1.dev}/lib/pkgconfig"
];
CFLAGS = concat [ # don't warn on read()/write() without a format
"-Wno-format" # (Arcan code uses them on SHMIFs)
"-Wno-format-security"
];
cmakeFlags = concat (
# cmake won't be able to find these paths on its own:
(libusbDirs pkgs.libusb) ++ [
"-DDRM_INCLUDE_DIR=${pkgs.libdrm.dev}/include/libdrm"
"-DGBM_INCLUDE_DIR=${pkgs.libGL.dev}/include"
"-DWAYLANDPROTOCOLS_PATH=${pkgs.wayland-protocols}/share/wayland-protocols"
# enable features:
"-DVIDEO_PLATFORM=egl-dri"
"-DSHMIF_TUI_ACCEL=ON"
"-DENABLE_LWA=ON"
"-DNO_BUILTIN_OPENHMD=ON"
"-DHYBRID_SDL=On"
"-DHYBRID_HEADLESS=On"
"-DFSRV_DECODE_UVC=Off"
# optional
"-DVERBOSE=ON"
#"--debug-output"
#"--trace"
"../src"
]);
}) {};
# arcan utilities:
acfgfs = callPackage ({ pkgs }: derive {
name = "acfgfs";
src = arcanCoreSrc;
nativeBuildInputs = with pkgs; [ cmake gcc git ];
buildInputs = [ arcan ] ++ (with pkgs; [ fuse3 ]);
cmakeFlags = concat ((arcanIncludeDirs arcan) ++ [ "../src/tools/acfgfs" ]);
}) {};
aclip = callPackage ({ pkgs }: derive {
name = "aclip";
src = arcanCoreSrc;
nativeBuildInputs = with pkgs; [ cmake gcc git pkg-config ];
buildInputs = [ arcan ];
PKG_CONFIG_PATH = concat [ "${arcan}/lib/pkgconfig" ];
cmakeFlags = concat ((arcanIncludeDirs arcan) ++ [ "../src/tools/aclip" ]);
}) {};
aloadimage = callPackage ({ pkgs }: derive {
name = "aloadimage";
src = arcanCoreSrc;
nativeBuildInputs = with pkgs; [ cmake gcc git ];
buildInputs = [ arcan ];
cmakeFlags = concat ((arcanIncludeDirs arcan) ++ [ "../src/tools/aloadimage" ]);
}) {};
shmmon = callPackage ({ pkgs }: derive {
name = "shmmon";
src = arcanCoreSrc;
nativeBuildInputs = with pkgs; [ cmake gcc git ];
buildInputs = [ arcan ];
cmakeFlags = concat ((arcanIncludeDirs arcan) ++ [ "../src/tools/shmmon" ]);
}) {};
# TODO: provide <hidapi/hidapi.h> include path
#vrbridge = callPackage ({ pkgs }: derive {
#name = "vrbridge";
#src = ./arcan;
#nativeBuildInputs = with pkgs; [ cmake gcc git pkg-config ];
#buildInputs = [ arcan ] ++ (with pkgs; [ libusb1 ]);
#cmakeFlags = concat (
#(arcanIncludeDirs arcan) ++
#(libusbDirs pkgs.libusb1) ++
#[ "../src/tools/vrbridge" ]
#);
#}) {};
# arcan appls
awb = mkArcanAppl {
name = "awb";
src = pkgs.fetchgit {
leaveDotGit = true;
url = "https://github.com/letoram/awb.git";
rev = "271ef7ffd7f24569d2f836198e4c96b8c617e372";
sha256 = "1jdmiinsd91nnli5hgcn9c6ifj0s6ngbyjwm0z6fim4f8krnh0s8";
};
applRoot = "";
};
prio = mkArcanAppl {
name = "prio";
src = pkgs.fetchgit {
leaveDotGit = true;
url = "https://github.com/letoram/prio.git";
rev = "c3f97491339d15f063d6937d5f89bcfaea774dd1";
sha256 = "0igsbzp0df24f856sfwzcgcfanxlvxmw5v94gqq2p42kwardfmm9";
};
applRoot = "";
};
durden = mkArcanAppl {
name = "durden";
src = pkgs.fetchgit {
leaveDotGit = true;
url = "https://github.com/letoram/durden.git";
rev = "bfbfe68bc325a5fb06ea1869a99404e277291a89";
sha256 = "11zfd1cf0sh63a9wrm5n129jmb5m0ibfh51ryjjjgxgx901k2qhi";
};
applRoot = "durden";
};
safespaces = mkArcanAppl {
name = "safespaces";
src = pkgs.fetchgit {
leaveDotGit = true;
url = "https://github.com/letoram/safespaces.git";
rev = "https://github.com/letoram/safespaces/commit/58eef59afba091293cab4d2b156e725f75d92eaf";
sha256 = "1jdmiinsd91nnli5hgcn9c6ifj0s6ngbyjwm0z6fim4f8krnh0s9";
};
applRoot = "safespaces";
};
}))
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 34a0d20a..f90ce0a6 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -740,7 +740,6 @@ if (VIDEO_PLATFORM STREQUAL "egl-dri")
amsg("${CL_YEL}egl-dri+privsep${CL_RST}\t${CL_GRN}installing SUID${CL_RST}")
install(TARGETS arcan DESTINATION bin
PERMISSIONS
- SETUID
OWNER_WRITE OWNER_READ OWNER_EXECUTE
GROUP_READ GROUP_EXECUTE
WORLD_READ WORLD_EXECUTE
#!/bin/sh
pushd $Arcan/bin # otherwise `arcan doesn't find system-binaries`
trap "popd" EXIT # let's not leave the user stranded, though
./arcan \
-T ../share/arcan/scripts \
-p ../share/arcan/resources \
-t $Appls $@ $Appl
# A minimal configuration.nix containing just Arcan.
{pkgs,...}:{
environment.systemPackages = let
arcan = (pkgs.callPackage (import ./Arcan.nix) {});
in [
arcan.arcan
arcan.acfgfs
arcan.aloadimage
arcan.aclip
arcan.shmmon
arcan.prio
arcan.durden
];
users.groups.input.members = ["user"];
}
@egasimus
Copy link
Author

@colemickens P.S. It would be great to see some buy-in from Arcan authors - I don't think @letoram even knows about this effort? The whole reason I'm giving this a is because I believe the NixOS community is an adequate audience for the Arcan project.

@letoram
Copy link

letoram commented Dec 15, 2020

There are a few users on IRC that has built on nixos in some capacity ( @akavel at least, others -e.g. I don't have a GH repo for ) - I'm stretched thin dist-as it is (home-lab is running FBSD/OBSD void/alpine/osx/ubuntu each needing manual verification because GPUs are terrible).

@akavel
Copy link

akavel commented Dec 15, 2020

I have some nix I'm currently using personally for slowly experimenting with arcan, at:

it's based on some other nix I googled up. I'm not sure I'll be able to contribute anything more comprehensive or collaborate more systematically, but if anything of this is useful, I'm happy. I tried to pick a simplest nix expression I could find at the time as a basis for modifications, so that I could grasp it and in general try to keep minimal. I don't however use other apps yet (I'm a super noob with arcan), so I don't have a mkArcanAppl for example. It would be super cool if something like mkArcanAppl (?) was externally available from Nix expression for Arcan, so that e.g. custom lua scripts based on Arcan could be easily packaged. Also I plan to experiment writing custom "frameservers" for Arcan, so I expect to need to be able to link with Arcan libraries like SHMIF, so they should be available from a Nix expression for Arcan.

@egasimus
Copy link
Author

I see @jnetod has made some nice progress in their fork of the gist by updating Arcan to 0.6.0, adding pkgconfig to the nativeBuildInputs (does that fix the missing hidapi include path?), and adding a patches argument to mkArcanAppl.

I think the final missing piece is adding the option to launch appls from the display manager. That goes hand in hand with making sure appl crashes/errors are handled gracefully by the surrounding environment. Then we're ready for primetime on nixpkgs :-)

I looked into how a list of possible sessions is given to the display manager and I think Arcan wrappers can just go in ${pkg}/share/wayland-sessions? (On a side note, renaming ${pkg}/share/wayland-sessions to ${pkg}/share/sessions, and putting Arcan launchers there, would be a small step in the right direction of migrating away from X11 and... not necessarily onto Wayland)

Linking to that other thread for future reference: NixOS/nixpkgs#49626 ;-)

@ChrisOboe
Copy link

Hi, i just found out about your arcan nixpkg. I also created a nixpkg for arcan. i'm pretty new to nix, so my one is definetly not as good as yours, but nevertheless it may be interesting for someone.

Also i'm not sure if removing suid from arcan and adding the users to the input group is the best way for getting input working as this could compromise some security of arcan.
With suid, only arcan can access the input, and all the other software, need to receive the input from arcan (so we only need to trust arcan not to do bad stuff like keylogging).
With users in the input group, every program running under the user can access all the input devices.

@egasimus
Copy link
Author

egasimus commented Jan 3, 2021

@ChrisOboe nice work! There's something to be said about the discoverability of cool Nix features like wrapProgram (which I didn't know about... and I see you've disabled it since :-)). I'm still not sure how to handle suid binaries correctly under NixOS.

More importantly, though, I think that adding Arcan to the list of sessions in the display manager remains the main obstacle to getting these efforts in the hands of more people. Would you be interested in giving it a shot?

@ChrisOboe
Copy link

@egasimus as far as i understand suid isn't possible in pkgs itself, but its possible to to in the system config like

security.wrappers = {
  arcan = {
    source = "${pkgs.nur.repos.chrisoboe.arcan}/bin/arcan";
    owner = "root";
    setuid = true;
  };
};

with that i could execute arcan with my user not in the input group (and still got input working since arcan is run as root).
That's also the reason why i disabled the wrapProgram and now patch the source for the paths directly, since suid only works on native-binaries and not scripts like wrappers.

I'll try to get arcan running as a session working.

@ChrisOboe
Copy link

@egasimus
i've got durden running through a session. It seems the only thing that's necessary for a pkg to be used for a session is the line passthru.providedSessions = [ "durden" ]; and a .desktop file like

Name=durden
Comment=Next Generation Window Manager
Exec=/nix/store/arl8n5a7yasvaxlw4bv5dcj8d6jdwqnf-durden-0.6.1/bin/durden
Type=Application

i've added them in my durden pkg. Now this pkg can be added to the session list services.xserver.displayManager.sessionPackages = [ pkgs.nur.repos.chrisoboe.durden ];

@egasimus
Copy link
Author

egasimus commented Jan 5, 2021

@ChrisOboe nice work! Will test ASAP

@egasimus
Copy link
Author

@ChrisOboe
2021-01-18-001456_1600x900_scrot

Just built your pkg. Display manager integration works like a charm, that's really awesome! It's interesting to see how durden preserves the session after killing arcan and logging back into i3. One weird problem though... durden is upside-down when running windowed?!

I hadn't built my my pkg again and found it broken, something weird had happened where most source checksums wouldn't match, Guess I need to sort that out and compare if my version is also upside down...

Looks like soon we are going to have everything we need to prepare a PR for nixpkgs.

@letoram
Copy link

letoram commented Jan 18, 2021

Upside down when running windowed - there is an issue on it already. The SDL2 platform layer generates the wrong texture coordinates on window-resize (and correct the first time but more often than not i3 and friends storm resize events). https://github.com/letoram/durden/issues/61

Quick workaround is "arcan_db add_appl_kv durden display_simple true" but that will break multi-displays when running native.

A FYI - you don't have to kill arcan to trick the clients into crash-recovery. Durden "/global/system/shutdown/silent" will do the same. Be warned that wayland/xwayland clients don't rebuild correctly.

@ChrisOboe
Copy link

@egasimus I think there are still some points before we do a PR for arcan.
The most important points are these:

I'm not sure whats the proper way is to manage the paths of appls. Currently we patch arcan to find the default appls. And for durden we use a script so arcan executes durden with it's absolute path. But this approach won't work for 3rdParty appls we may want to launch inside durden, since arcan wouldn't know the paths.

I also couldn't get wayland/xwayland clients to work in arcan yet. I'm not sure why. I think this is a big showstopper since most people wouldn't use arcan/durden if they can't run most gui software.

and propably we will need a nixos module so the security wrappers settings can be a simple programs.arcan.enable = true. Also for security it would be better, if we run arcan under an own arcan user, which only has the permissions for drm and input instead of root. But i'm not sure if the nixos module should be a seperate PR.

@letoram
Copy link

letoram commented Jan 19, 2021

  1. Most likely reason why wayland/xwayland fails are missing XDG_RUNTIME_DIR or a different XDG_RUNTIME_DIR when starting Arcan versus one set by whatever terminal you are running in. Arcan/SHMIF will use XDG_vars if set, but doesn't rely on them if not.

  2. There are a few options and it is complicated as the different resource namespaces were based on replacing Android while avoiding some of the mistakes therein (substituting for some of our own...). See the NAMESPACES section in the manpage. The normal 'tactic' is to have a read-only shared applbase where each appl gets its own subdirectory, then a user-rw appltemppath that act as an overlay and scratch store for the appls.

  3. While it will work without the watchdog/device-process being root, some features will fail-silent. The main culprit right now is LED devices, mainly backlights for laptops that require poking around in /sys. In coming releases some input device drivers (PS5 controller and UVC webcams) also use Arcan for USB/HID arbitration.

@ChrisOboe
Copy link

@letoram

  1. Yes, you were right. With the XDG_RUNTIME_DIR variable set wayland clients started working. I'm currently even writing this with wayland firefox in durden :D

  2. Yes i think i understand how arcan expects the folder layout. This is more a nixos problem, since on nixos each package i in an own folder. That's why global directories used by several packages are a bit tricky.

  3. ahh okay. Then i will keep arcan running as root.

@letoram
Copy link

letoram commented Feb 15, 2021

@ChrisOboe: I'm looking into a fallback plan for doing the XDG runtime dance in an env where it is not inherited, but it is somewhat lower priority - my current contract is focused on improving the QEmu backend (updated to that repository coming) and to the network transparency layer.

Be careful with firefox in single -exec mode and not just arcan-wayland as a protocol service. Firefox expects to be able to make multiple connections, and -exec removes the socket after a client has appeared.

@bhankas
Copy link

bhankas commented Feb 28, 2021

I'm thinking of giving this a shot on my own primary machine.
But @jnetod's fork seems to be updated latest. Which one do I go for?

@egasimus
Copy link
Author

egasimus commented Mar 1, 2021

@payasrelekar Whichever one feels more sound to you - here's my latest take, which runs Prio and Durden.

@abathur
Copy link

abathur commented Apr 12, 2021

I found this while looking into a new project (pipeworld, https://github.com/letoram/pipeworld) posted to lobste.rs today. (By same developers as arcan, and uses arcan, so I was curious if we had it packaged.) Just cross-referencing on the off-chance it helps anyone here.

@egasimus
Copy link
Author

@abathur Wow! This is extremely relevant to my interests.

Sadly, I haven't had much time to play with Arcan on NixOS lately, however adding another mkArcanAppl invocation should be a good starting point and hopefully enough to try this out.

@cipharius
Copy link

@abathur I forked this gist, fixed it up and added pipeworld appl. Test it out here: https://gist.github.com/cipharius/829fb6baacfcbc668af23488db95fe11

@bhankas
Copy link

bhankas commented Apr 28, 2021

@cipharius thanks, I'll check it out over weekend.

I'm wondering, how far along are we to submitting this work to Nixpkgs?

@egasimus
Copy link
Author

@payasrelekar Feel free to fork my nixpkgs PR or start a new one. I realized I need to be way more organized in order to productively contribute to nixpkgs. I don't have that kind of mental clarity right now.

To be perfectly honest, my failure to even find the entrypoint of the most basic Arcan appl so I can start putting things on the screen dissuaded me somewhat from pursuing this further. I wish I had something more to contribute than initiative, but right now that's in everyone else's hands too.

@cipharius
Copy link

@egasimus Have you joined arcan's IRC channel or discord server? Discord server is a pretty new addition, but the IRC channel is decently active.

As for the entrypoint, I'd recommend checking the small tutorial series found under arcan's wiki page. It mentions there, that all Lua appls have entry point in script [APPL_NAME].lua in function matching the appl's name. So for durden you'll find durden.lua with function durden() defined somewhere within it.

@letoram
Copy link

letoram commented Apr 28, 2021

That structure is slightly more thought out than it might initially seem. With the forced prefix for all engine->script calls and applnames being unique means that you can embed an appl in an appl. Durden or Safespaces can pull in Pipeworld and have it structurally work without any namespace collisions.

@egasimus
Copy link
Author

egasimus commented Apr 29, 2021

Sure, I got that far. Another project I find inspirational is Deno, which has similar "non-standard" entry points (#! doesnt work with deno run unless using non-POSIX /usr/bin/env -S deno run) - in both cases I've tried to make my Nix builds include a single-command invocation with no parameters that covers the default case (e.g. arcan.durden, etc).

But my problem lies elsewhere - last time I tried writing an appl I started from the simplest "bouncing logo" example included, and still couldn't figure out what the main function is/does. Like I said, maybe I just haven't approached this with sufficient clarity of mind - I find myself lacking the time to achieve it these days :-(

Lua is kinda new to me but it supports a traditional imperative style, right? Guess I sorta expected a main loop with a draw function; if there's one in there I must've missed it by a long shot. As a contrived example, Processing gets this "right" (as far as my intuition is concerned anyway).

I understand the two projects differ vastly in scope, but I'm just looking for a way to put things on a screen (first and foremost for my own personal use) that has better semantics than a canvas or a X11 WM, and better performance than a browser. If I ever manage to do that, I'd be happy to write a tutorial on how to get the whole stack running and how to start developing with it - unless someone already beat me to it?

When I first encountered Arcan, I hoped it would be easy to write bindings to it for another language (JS, Rust - the usual suspects; Arcan+Deno+some form of hot module reloading sounds like a blissful way to build a personal GUI from scratch) and have that structurally work with no collisions.

Is there something about Lua's namespacing that necessitates a more thought out naming scheme than just slapping things together? I'm accustomed to expect composability at the function level, not the module level though I understand different languages come with different approaches.

As it stands, I'm quite sad to admit that I found the code that I'm supposed to interface with in order to build something on Arcan nearly impenetrable. (And that's from someone who enjoys writing Nix builds!)

I'll try to find some time to check out the community - I've stood by the sidelines long enough, and Pipeworld really blew my mind, so guess it's about time I saw what y'all are really up to :-)

@letoram
Copy link

letoram commented May 3, 2021

First - a problem with the NixOS module itself:

It does not build arcan_lwa (which is used under the hood to run arcan applications inside of other arcan applications). The reason for that is, most likely, that the in-source version of OpenAL is ignored (external/clone.sh). That one has patches which adds an 'arcan' audio backend that should not be upstreamed or be integrated with system OpenAL (which normal arcan uses). The dependency will eventually be refactored out and swapped for something slimmer, but not today.

Second, as to your general remarks:

The development style in Lua is very much up to the engine integration, hence why it is rarely a standalone language itself and does not fit very well with such a mold. Arcan forces a more functional/event-driven nature rather than giving you control over an imperative main loop - you are almost guaranteed to screw up something like a while(true){ process_input(); move_things_around(); if (time_to_draw) draw_frame(); }. Regular game developers do so repeatedly (locking animations and logic to %30Hz or so and breaking spectacularly on variable frame rate displays and so on). On a system graphics level, this problem is much more complex with many soft failure modes.

The applname() entry point is a substitution for the '.html' file in your normal web application -- any up-front loading of resources and necessary allocations should be done there. Before that point none of the actual APIs are exposed - leaving much less room for obfuscation and funny tricks for concealing intent. As a side note, that is also one of the reasons why normal "loadstring(str)()" kind of functions are not exposed. If you harden the setup a bit (separate appl, appl-out namespaces, block the .so form of system_load()) dynamic coding tricks for packers/unpackers and other shady tactics are closed off.

The Lua part isn't simply a language that is substitutable by anything else, in reality it is treated as a 'safe' keyword for C. Lua itself (as in arcan_lua.c) is a bit of a misnomer as quite a few functions in that behemoth do provide additional abstractions and encode idioms that evolved over time. There is a lot of work behind how its specific VM interface interacts with the rest of the engine when it comes to error and crash recovery, as well as GC cadence and so on.

If anything, other language support should be done as part of the scripting space and keep actual execution out of process more akin to how WMs work in X11. A single appl or hookscript that uses open_nonblock to create an socket, then generate bindings from doc/*.lua. Unfortunately those files were not written with the intent of being used as an IDL, and it is a slow burn task reworking that format in this direction where the overloaded arguments each have their expected types explicitly written out and so on. What helps is that the macro in the arcan_lua.c that marks every entry-point also has a #define hack at the top of the source unit to emit a trace, so running that against something like durden/pipeworld would give decent statistics of the more useful functions versus the edge case ones.

function myapp()
    logo = load_image("logo.png")
    blend_image(logo, 1.0, 50)
    move_image(logo, VRESW, 0, 100, INTERP_SMOOTHSTEP)
    move_image(logo, 0, 0, 100, INTERP_SINE)
    image_transform_cycle(logo, true)
end

store as myapp/myapp.lua, shove logo.png into the myapp folder or somewhere accessible with arcan -p /path/to/resource/base myapp and done.

This would have your logo move from the left edge to the right edge indefinitely (though missing a myapp_display_state handler to deal with window resizes changing the VRESW/VRESH constants). It was never a strong intent that the Lua API would be used directly (albeit that's basically what I do), but rather emitted by a translator from something else. I have reconsidered somewhat since then, and a 'REPL-' style wrapper for easier experimentation is on the todo along with something that targets pine* and RPI400 etc. specifically to get back to a sort of "power on" 10 print "hello world" kind of computing.

@a12l
Copy link

a12l commented May 3, 2021

Hi! @letoram linked this gist in Discord. I've just pushed a commit with a Nix expression what enables building arcan. I haven't tested it out yet, so I don't know if there's any bugs. :)

It's very a WIP, so I just wanted to commit and push as a backup.

EDIT: And it builds arcan_lwa.

https://github.com/a12l/nixpkgs/tree/arcan

@a12l
Copy link

a12l commented May 17, 2021

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