diff --git a/pkgs/misc/urbit/ca-bundle.nix b/pkgs/misc/urbit/ca-bundle.nix new file mode 100644 index 0000000000000..01b65077beb58 --- /dev/null +++ b/pkgs/misc/urbit/ca-bundle.nix @@ -0,0 +1,12 @@ +{ runCommandLocal, xxd, cacert }: + +runCommandLocal "ca-bundle" {} '' + mkdir include + + cat ${cacert}/etc/ssl/certs/ca-bundle.crt > include/ca-bundle.crt + ${xxd}/bin/xxd -i include/ca-bundle.crt > ca-bundle.h + + mkdir -p $out/include + + mv ca-bundle.h $out/include + '' diff --git a/pkgs/misc/urbit/default.nix b/pkgs/misc/urbit/default.nix index 9ea1fc64c3f37..c5609646b4412 100644 --- a/pkgs/misc/urbit/default.nix +++ b/pkgs/misc/urbit/default.nix @@ -1,31 +1,77 @@ -{ lib, stdenv, fetchFromGitHub, curl, git, gmp, libsigsegv, meson, ncurses, ninja -, openssl, pkg-config, re2c, zlib -}: +{ lib +, pkgs +, fetchFromGitHub +, curlMinimal +, openssl +, h2o +, libsigsegv +, lmdb +, zlib +, stdenv +}: let -stdenv.mkDerivation rec { - pname = "urbit"; - version = "0.7.3"; - - src = fetchFromGitHub { + urbit-src = fetchFromGitHub { owner = "urbit"; repo = "urbit"; - rev = "v${version}"; - sha256 = "192843pjzh8z55fd0x70m3l1vncmixljia3nphgn7j7x4976xkp2"; - fetchSubmodules = true; + rev = "urbit-v1.15"; + hash = "sha256-YHl4aPJglUIQ6mrLWSUU7gNJn9DjeCwNBCCUkDfX2iw="; }; - nativeBuildInputs = [ pkg-config ninja meson ]; - buildInputs = [ curl git gmp libsigsegv ncurses openssl re2c zlib ]; + callPackage = lib.callPackageWith ( pkgs // urbitPackages); + + urbitPackages = { + + fetchGitHubLFS = callPackage ./fetch-github-lfs.nix {}; + + ca-bundle = callPackage ./ca-bundle.nix {}; + + ent = callPackage ./ent.nix { + inherit urbit-src; + }; + + libaes_siv = callPackage ./libaes_siv {}; + + murmur3 = callPackage ./murmur3.nix {}; - postPatch = '' - patchShebangs . - ''; + ivory-header = callPackage ./ivory-header.nix { + inherit urbit-src; + }; - meta = with lib; { - description = "An operating function"; - homepage = "https://urbit.org"; - license = licenses.mit; - maintainers = with maintainers; [ mudri ]; - platforms = with platforms; linux; + softfloat3 = callPackage ./softfloat3.nix {}; + + h2o-stable = h2o.overrideAttrs (_attrs: { + version = "v2.2.6"; + src = fetchFromGitHub { + owner = "h2o"; + repo = "h2o"; + rev = "v2.2.6"; + sha256 = "0qni676wqvxx0sl0pw9j0ph7zf2krrzqc1zwj73mgpdnsr8rsib7"; + }; + outputs = [ "out" "dev" "lib" ]; + meta.platforms = lib.platforms.unix; + }); + + libsigsegv_patched = libsigsegv.overrideAttrs (oldAttrs: { + patches = (lib.lists.optionals (oldAttrs.patches != null) oldAttrs.patches) ++ [ + ./libsigsegv/disable-stackvma_fault-linux-arm.patch + ./libsigsegv/disable-stackvma_fault-linux-i386.patch + ]; + }); + + lmdb_patched = lmdb.overrideAttrs (oldAttrs: { + patches = + oldAttrs.patches or [] ++ lib.optionals stdenv.isDarwin [ + ./lmdb/darwin-fsync.patch + ]; + }); + + urbit = callPackage ./urbit.nix { + inherit urbit-src; + }; + + urcrypt = callPackage ./urcrypt.nix { + inherit urbit-src; + }; }; -} + +in urbitPackages.urbit diff --git a/pkgs/misc/urbit/ent.nix b/pkgs/misc/urbit/ent.nix new file mode 100644 index 0000000000000..adfb38f8fc3f4 --- /dev/null +++ b/pkgs/misc/urbit/ent.nix @@ -0,0 +1,23 @@ +{ urbit-src, lib, stdenv }: + +stdenv.mkDerivation { + pname = "ent"; + version = urbit-src.rev; + src = lib.cleanSource "${urbit-src}/pkg/ent"; + + postPatch = '' + patchShebangs ./configure + ''; + + installFlags = [ "PREFIX=$(out)" ]; + + enableParallelBuilding = true; + + meta = { + description = "Cross-platform wrapper around getentropy"; + homepage = "https://github.com/urbit/urbit"; + license = lib.licenses.free; + maintainers = [ lib.maintainers.uningan ]; + platforms = lib.platforms.unix; + }; +} diff --git a/pkgs/misc/urbit/fetch-github-lfs.nix b/pkgs/misc/urbit/fetch-github-lfs.nix new file mode 100644 index 0000000000000..2e39e327d0513 --- /dev/null +++ b/pkgs/misc/urbit/fetch-github-lfs.nix @@ -0,0 +1,104 @@ +{ lib, stdenvNoCC, runCommandLocal, cacert, curl, jq }: + +{ src +# `name` shouldn't use `baseNameOf` otherwise we'll +# get `is not allowed to refer to a store path` errors. +, name ? baseNameOf src, owner ? "urbit", repo ? "urbit" +, preferLocalBuild ? true }: +let + + # Parse the first 7 characters of the supplied `src` path for the required + # `version` key as defined by the lfs specification: + # https://github.com/git-lfs/git-lfs/blob/master/docs/spec.md + # + # If `version` exists we assume we're dealing with a lfs pointer and parse + # the `oid` and `size` from the pointer and write these into a JSON object. + # + # If the first 7 characters are unrecognised we assume the path is a binary + # file and set both `oid` and `size` to `null`. + # + # The `oid` and `size` are then JSON decoded into an expression to use + # as the fixed-output derivation's `sha256 = oid`, and to form a download + # operation payload to request the actual lfs blob's real url. + pointer = builtins.fromJSON (builtins.readFile + (runCommandLocal "lfs-pointer-${name}" { } '' + oid="null" + size="null" + + if [[ "$(head -c 7 "${src}")" != "version" ]]; then + header "lfs ${src} is a binary blob, skipping" + else + header "reading lfs pointer from ${src}" + + contents=($(awk '{print $2}' "${src}")) + oid="''${contents[1]#sha256:}" + size="''${contents[2]}" + fi + + cat < "$out" + {"oid": "$oid", "size": $size} + EOF + '')); + + downloadUrl = + "https://github.com/${owner}/${repo}.git/info/lfs/objects/batch"; + + # Encode `oid` and `size` into a download operation per: + # https://github.com/git-lfs/git-lfs/blob/master/docs/api/batch.md + # + # This is done using toJSON to avoid bash quotation issues. + downloadPayload = builtins.toJSON { + operation = "download"; + objects = [ pointer ]; + }; + + # Define a fixed-output derivation using the lfs pointer's `oid` as the + # expected sha256 output hash, if `oid` is not null. + # + + # 1. Request the actual url of the binary file from the lfs batch api. + # 2. Download the binary file contents to `$out`. + download = stdenvNoCC.mkDerivation { + name = "lfs-blob-${name}"; + nativeBuildInputs = [ curl jq ]; + phases = [ "installPhase" ]; + installPhase = '' + curl=( + curl + --location + --max-redirs 20 + --retry 3 + --disable-epsv + --cookie-jar cookies + $NIX_CURL_FLAGS + ) + + header "reading lfs metadata from ${downloadUrl}" + + href=$("''${curl[@]}" \ + -d '${downloadPayload}' \ + -H 'Accept: application/vnd.git-lfs+json' \ + '${downloadUrl}' \ + | jq -r '.objects[0].actions.download.href') + + header "download lfs data from remote" + + # Pozor/Achtung: the href contains credential and signature information, + # so we avoid echoing it to stdout/err. + "''${curl[@]}" -s --output "$out" "$href" + ''; + + impureEnvVars = lib.fetchers.proxyImpureEnvVars; + + SSL_CERT_FILE = "${cacert}/etc/ssl/certs/ca-bundle.crt"; + + outputHashAlgo = "sha256"; + outputHashMode = "flat"; + outputHash = pointer.oid; + + inherit preferLocalBuild; + }; + + # If `pointer.oid` is null then supplied the `src` must be a binary + # blob and can be returned directly. +in if pointer.oid == null || pointer.size == null then src else download diff --git a/pkgs/misc/urbit/ivory-header.nix b/pkgs/misc/urbit/ivory-header.nix new file mode 100644 index 0000000000000..4e0ff24783c20 --- /dev/null +++ b/pkgs/misc/urbit/ivory-header.nix @@ -0,0 +1,13 @@ +{ urbit-src +, runCommandLocal +, fetchGitHubLFS +, xxd +}: let + lfs = fetchGitHubLFS { + src = "${urbit-src}/bin/ivory.pill"; + }; +in runCommandLocal "ivory-header" {} '' + mkdir -p $out/include + cat ${lfs} > u3_Ivory.pill + ${xxd}/bin/xxd -i u3_Ivory.pill > $out/include/ivory_impl.h + '' diff --git a/pkgs/misc/urbit/libaes_siv/cmakefiles_static.patch b/pkgs/misc/urbit/libaes_siv/cmakefiles_static.patch new file mode 100644 index 0000000000000..7b7c71b25ea39 --- /dev/null +++ b/pkgs/misc/urbit/libaes_siv/cmakefiles_static.patch @@ -0,0 +1,34 @@ +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -5,6 +5,8 @@ if("${CMAKE_BUILD_TYPE}" STREQUAL "") + set(CMAKE_BUILD_TYPE Release) + endif("${CMAKE_BUILD_TYPE}" STREQUAL "") + ++option(BUILD_SHARED_LIBS "Build shared libraries" ON) ++ + include(GNUInstallDirs) + + # Warning: don't use the UB sanitizer in production builds. It can introduce timing side-channels +@@ -31,10 +33,12 @@ endif(NOT DISABLE_DOCS) + configure_file(config.h.in config.h) + include_directories(${CMAKE_CURRENT_BINARY_DIR}) + ++if(BUILD_SHARED_LIBS) + add_library(aes_siv SHARED aes_siv.c) + target_include_directories(aes_siv PUBLIC ${OPENSSL_INCLUDE_DIR}) + target_link_libraries(aes_siv ${OPENSSL_CRYPTO_LIBRARY}) + set_target_properties(aes_siv PROPERTIES VERSION "1.0.1" SOVERSION 1) ++endif() + + add_library(aes_siv_static STATIC aes_siv.c) + target_include_directories(aes_siv_static PUBLIC ${OPENSSL_INCLUDE_DIR}) +@@ -63,7 +67,9 @@ endif(ENABLE_SANITIZER) + add_executable(bench EXCLUDE_FROM_ALL bench.c) + target_link_libraries(bench aes_siv_static) + ++if(BUILD_SHARED_LIBS) + install(TARGETS aes_siv LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) ++endif() + install(TARGETS aes_siv_static ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) + install(FILES aes_siv.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + diff --git a/pkgs/misc/urbit/libaes_siv/default.nix b/pkgs/misc/urbit/libaes_siv/default.nix new file mode 100644 index 0000000000000..c34575d9eca84 --- /dev/null +++ b/pkgs/misc/urbit/libaes_siv/default.nix @@ -0,0 +1,33 @@ +{ stdenv +, lib +, cmake +, openssl +, fetchFromGitHub +}: +stdenv.mkDerivation { + pname = "libaes_siv"; + version = "9681279cfaa6e6399bb7ca3afbbc27fc2e19df4b"; + src = fetchFromGitHub { + owner = "dfoxfranke"; + repo = "libaes_siv"; + rev = "9681279cfaa6e6399bb7ca3afbbc27fc2e19df4b"; + sha256 = "1g4wy0m5wpqx7z6nillppkh5zki9fkx9rdw149qcxh7mc5vlszzi"; + }; + + patches = [ ./cmakefiles_static.patch ]; + + nativeBuildInputs = [ cmake ]; + buildInputs = [ openssl ]; + + cmakeFlags = [ + "-DBUILD_SHARED_LIBS=OFF" + ]; + + meta = { + description = "An RFC5297-compliant C implementation of AES-SIV"; + homepage = "https://github.com/dfoxfranke/libaes_siv"; + license = lib.licenses.asl20; + maintainers = [ lib.maintainers.uningan ]; + platforms = lib.platforms.unix; + }; +} diff --git a/pkgs/misc/urbit/libsigsegv/disable-stackvma_fault-linux-arm.patch b/pkgs/misc/urbit/libsigsegv/disable-stackvma_fault-linux-arm.patch new file mode 100644 index 0000000000000..56d2b4b757078 --- /dev/null +++ b/pkgs/misc/urbit/libsigsegv/disable-stackvma_fault-linux-arm.patch @@ -0,0 +1,11 @@ +--- a/src/fault-linux-arm.h ++++ b/src/fault-linux-arm.h +@@ -17,6 +17,8 @@ + + #include "fault-posix-ucontext.h" + ++#define HAVE_STACKVMA 0 ++ + #if defined(__aarch64__) || defined(__ARM_64BIT_STATE) || defined(__ARM_PCS_AAPCS64) /* 64-bit */ + + /* See glibc/sysdeps/unix/sysv/linux/aarch64/sys/ucontext.h. diff --git a/pkgs/misc/urbit/libsigsegv/disable-stackvma_fault-linux-i386.patch b/pkgs/misc/urbit/libsigsegv/disable-stackvma_fault-linux-i386.patch new file mode 100644 index 0000000000000..9d7d03bd16011 --- /dev/null +++ b/pkgs/misc/urbit/libsigsegv/disable-stackvma_fault-linux-i386.patch @@ -0,0 +1,11 @@ +--- a/src/fault-linux-i386.h ++++ b/src/fault-linux-i386.h +@@ -18,6 +18,8 @@ + + #include "fault-posix-ucontext.h" + ++#define HAVE_STACKVMA 0 ++ + #if defined __x86_64__ + /* 64 bit registers */ + diff --git a/pkgs/misc/urbit/lmdb/darwin-fsync.patch b/pkgs/misc/urbit/lmdb/darwin-fsync.patch new file mode 100644 index 0000000000000..961b8a1ffd878 --- /dev/null +++ b/pkgs/misc/urbit/lmdb/darwin-fsync.patch @@ -0,0 +1,13 @@ +diff --git a/libraries/liblmdb/mdb.c b/libraries/liblmdb/mdb.c +index fe65e30..0070215 100644 +--- a/libraries/liblmdb/mdb.c ++++ b/libraries/liblmdb/mdb.c +@@ -2526,7 +2526,7 @@ mdb_env_sync(MDB_env *env, int force) + rc = ErrCode(); + } else + #endif +- if (MDB_FDATASYNC(env->me_fd)) ++ if (fcntl(env->me_fd, F_FULLFSYNC, 0)) + rc = ErrCode(); + } + } diff --git a/pkgs/misc/urbit/murmur3.nix b/pkgs/misc/urbit/murmur3.nix new file mode 100644 index 0000000000000..cd18664d31a0d --- /dev/null +++ b/pkgs/misc/urbit/murmur3.nix @@ -0,0 +1,32 @@ +{ lib +, stdenv +, fetchFromGitHub +}: +stdenv.mkDerivation { + pname = "murmur3"; + version = "71a75d57ca4e7ca0f7fc2fd84abd93595b0624ca"; + src = fetchFromGitHub { + owner = "urbit"; + repo = "murmur3"; + rev = "71a75d57ca4e7ca0f7fc2fd84abd93595b0624ca"; + sha256 = "0k7jq2nb4ad9ajkr6wc4w2yy2f2hkwm3nkbj2pklqgwsg6flxzwg"; + }; + + buildPhase = '' + $CC -fPIC -O3 -o murmur3.o -c $src/murmur3.c + ''; + + installPhase = '' + mkdir -p $out/{lib,include} + $AR rcs $out/lib/libmurmur3.a murmur3.o + cp $src/*.h $out/include/ + ''; + + meta = { + description = "C port of Murmur3 hash"; + homepage = "https://github.com/urbit/murmur3"; + license = lib.licenses.mit; + maintainers = [ lib.maintainers.uningan ]; + platforms = lib.platforms.unix; + }; +} diff --git a/pkgs/misc/urbit/softfloat3.nix b/pkgs/misc/urbit/softfloat3.nix new file mode 100644 index 0000000000000..ef35332957763 --- /dev/null +++ b/pkgs/misc/urbit/softfloat3.nix @@ -0,0 +1,41 @@ +{ stdenv +, lib +, fetchFromGitHub +}: + +stdenv.mkDerivation { + pname = "softfloat3"; + version = "ec4c7e31b32e07aad80e52f65ff46ac6d6aad986"; + src = fetchFromGitHub { + owner = "urbit"; + repo = "berkeley-softfloat-3"; + rev = "ec4c7e31b32e07aad80e52f65ff46ac6d6aad986"; + sha256 = "1lz4bazbf7lns1xh8aam19c814a4n4czq5xsq5rmi9sgqw910339"; + }; + + postPatch = '' + for f in $(find build -type f -name 'Makefile'); do + substituteInPlace $f \ + --replace 'gcc' '$(CC)' \ + --replace 'ar crs' '$(AR) crs' + done + ''; + + preBuild = '' + cd build/Linux-x86_64-GCC + ''; + + installPhase = '' + mkdir -p $out/{lib,include} + cp $src/source/include/*.h $out/include/ + cp softfloat.a $out/lib/libsoftfloat3.a + ''; + + meta = { + description = "C implementation of binary floating-point"; + homepage = "https://github.com/urbit/berkeley-softfloat-3"; + license = lib.licenses.free; + maintainers = [ lib.maintainers.uningan ]; + platforms = lib.platforms.unix; + }; +} diff --git a/pkgs/misc/urbit/urbit.nix b/pkgs/misc/urbit/urbit.nix new file mode 100644 index 0000000000000..318b04b6d1a93 --- /dev/null +++ b/pkgs/misc/urbit/urbit.nix @@ -0,0 +1,89 @@ +{ lib +, stdenv +, coreutils +, pkg-config +, cacert +, ca-bundle +, ivory-header +, curlMinimal +, ent +, gmp +, h2o-stable +, libsigsegv_patched +, libuv +, lmdb_patched +, murmur3 +, openssl +, softfloat3 +, urcrypt +, zlib +, urbit-src +}:let + + src = lib.cleanSource "${urbit-src}/pkg/urbit"; + + version = builtins.readFile "${src}/version"; + + # See https://github.com/urbit/urbit/issues/5561 + oFlags = + if stdenv.isDarwin + then [ "-O3" ] + else [ "-O3" "-g" ]; + +in stdenv.mkDerivation { + inherit src version; + + pname = "urbit"; + + nativeBuildInputs = [ pkg-config ]; + + buildInputs = [ + cacert + ca-bundle + curlMinimal + ent + gmp + h2o-stable + ivory-header + libsigsegv_patched + libuv + lmdb_patched + murmur3 + openssl + softfloat3 + urcrypt + zlib + ]; + + checkTarget = "test"; + + installPhase = '' + mkdir -p $out/bin + cp ./build/urbit $out/bin/urbit + ''; + + dontDisableStatic = false; + + # CFLAGS = oFlags ++ [ "-Werror" ]; + CFLAGS = oFlags ++ [ "" ]; + + MEMORY_DEBUG = false; + CPU_DEBUG = false; + EVENT_TIME_DEBUG = false; + + enableParallelBuilding = true; + doCheck = true; + + # Ensure any `/usr/bin/env bash` shebang is patched. + postPatch = '' + patchShebangs ./configure + ''; + + meta = { + description = "An operating function"; + homepage = "https://urbit.org"; + license = lib.licenses.mit; + maintainers = [ lib.maintainers.uningan ]; + platforms = lib.platforms.unix; + }; +} diff --git a/pkgs/misc/urbit/urcrypt.nix b/pkgs/misc/urbit/urcrypt.nix new file mode 100644 index 0000000000000..a4e7d6143ce50 --- /dev/null +++ b/pkgs/misc/urbit/urcrypt.nix @@ -0,0 +1,32 @@ +{ lib +, urbit-src +, stdenv +, autoreconfHook +, pkgconfig +, libaes_siv +, openssl +, secp256k1 +}: + +stdenv.mkDerivation rec { + pname = "urcrypt"; + version = urbit-src.rev; + src = "${urbit-src}/pkg/urcrypt"; + + # XX why are these required for darwin? + dontDisableStatic = false; + + nativeBuildInputs = + [ autoreconfHook pkgconfig ]; + + buildInputs = + [ openssl secp256k1 libaes_siv ]; + + meta = { + description = "A library of cryptography routines used by urbit jets"; + homepage = "https://github.com/urbit/urbit"; + license = lib.licenses.mit; + maintainers = [ lib.maintainers.uningan ]; + platforms = lib.platforms.unix; + }; +}