Skip to content

Instantly share code, notes, and snippets.

@steve-chavez
Forked from egasimus/Arcan.nix
Created April 29, 2021 14:45
Show Gist options
  • Save steve-chavez/62ef015c30968b4561d2e45ee51a0b7e to your computer and use it in GitHub Desktop.
Save steve-chavez/62ef015c30968b4561d2e45ee51a0b7e to your computer and use it in GitHub Desktop.

Revisions

  1. @egasimus egasimus revised this gist Jul 30, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion configuration.example.nix
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    // A minimal configuration.nix containing just Arcan.
    # A minimal configuration.nix containing just Arcan.
    {pkgs,...}:{
    environment.systemPackages = let
    arcan = (pkgs.callPackage (import ./Arcan.nix) {});
  2. @egasimus egasimus created this gist Jul 30, 2020.
    235 changes: 235 additions & 0 deletions Arcan.nix
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,235 @@
    ({ 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";
    };

    }))
    12 changes: 12 additions & 0 deletions Arcan.nosuid.patch
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,12 @@
    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
    7 changes: 7 additions & 0 deletions Arcan.wrapper
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,7 @@
    #!/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
    3 changes: 3 additions & 0 deletions README.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,3 @@
    See also:
    * https://github.com/NixOS/nixpkgs/issues/49626
    * https://gist.github.com/telent/4a92294a767656759959006fe8440122
    17 changes: 17 additions & 0 deletions configuration.example.nix
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,17 @@
    // 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"];
    }