diff --git a/pkgs/applications/networking/instant-messengers/fluffychat/default.nix b/pkgs/applications/networking/instant-messengers/fluffychat/default.nix new file mode 100644 index 0000000000000..e567f18fe7b1e --- /dev/null +++ b/pkgs/applications/networking/instant-messengers/fluffychat/default.nix @@ -0,0 +1,31 @@ +{ lib +, fetchFromGitLab +, flutter +, olm +}: + +flutter.mkFlutterApp rec { + pname = "fluffychat"; + version = "1.2.0"; + + vendorHash = "sha256-Qg0IlajbIl8e3BkKgn4O+mbZGvhfqr7XwllBLJQAA/I="; + + src = fetchFromGitLab { + owner = "famedly"; + repo = "fluffychat"; + rev = "v${version}"; + hash = "sha256-PJH3jMQc6u9R6Snn+9rNN8t+8kt6l3Xt7zKPbpqj13E="; + }; + + buildInputs = [ + olm + ]; + + meta = with lib; { + description = "Chat with your friends (matrix client)"; + homepage = "https://fluffychat.im/"; + license = licenses.agpl3Plus; + maintainers = with maintainers; [ mkg20001 ]; + platforms = platforms.linux; + }; +} diff --git a/pkgs/build-support/fetchgit/deterministic-git b/pkgs/build-support/fetchgit/deterministic-git new file mode 100755 index 0000000000000..67f5855591167 --- /dev/null +++ b/pkgs/build-support/fetchgit/deterministic-git @@ -0,0 +1,45 @@ +#!/bin/sh + +# some git commands print to stdout, which would contaminate our JSON output +clean_git(){ + git "$@" >&2 +} + +# Remove all remote branches, remove tags not reachable from HEAD, do a full +# repack and then garbage collect unreferenced objects. +make_deterministic_repo(){ + local repo="$1" + + # run in sub-shell to not touch current working directory + ( + cd "$repo" + # Remove files that contain timestamps or otherwise have non-deterministic + # properties. + rm -rf .git/logs/ .git/hooks/ .git/index .git/FETCH_HEAD .git/ORIG_HEAD \ + .git/refs/remotes/origin/HEAD .git/config + + # Remove all remote branches. + git branch -r | while read -r branch; do + clean_git branch -rD "$branch" + done + + # Remove tags not reachable from HEAD. If we're exactly on a tag, don't + # delete it. + maybe_tag=$(git tag --points-at HEAD) + git tag --contains HEAD | while read -r tag; do + if [ "$tag" != "$maybe_tag" ]; then + clean_git tag -d "$tag" + fi + done + + # Do a full repack. Must run single-threaded, or else we lose determinism. + clean_git config pack.threads 1 + clean_git repack -A -d -f + rm -f .git/config + + # Garbage collect unreferenced objects. + # Note: --keep-largest-pack prevents non-deterministic ordering of packs + # listed in .git/objects/info/packs by only using a single pack + clean_git gc --prune=all --keep-largest-pack + ) +} diff --git a/pkgs/build-support/flutter/default.nix b/pkgs/build-support/flutter/default.nix new file mode 100644 index 0000000000000..5208dbc7d05dc --- /dev/null +++ b/pkgs/build-support/flutter/default.nix @@ -0,0 +1,277 @@ +{ flutter +, lib +, llvmPackages_13 +, cmake +, ninja +, pkg-config +, wrapGAppsHook +, autoPatchelfHook +, util-linux +, libselinux +, libsepol +, libthai +, libdatrie +, libxkbcommon +, at-spi2-core +, libsecret +, jsoncpp +, xorg +, dbus +, gtk3 +, glib +, pcre +, libepoxy +, stdenvNoCC +, cacert +, git +, dart +, nukeReferences +, targetPlatform +, bash +, curl +, unzip +, which +, xz +}: + +# absolutely no mac support for now + +args: +let + pl = n: "##FLUTTER_${n}_PLACEHOLDER_MARKER##"; + placeholder_deps = pl "DEPS"; + placeholder_flutter = pl "FLUTTER"; + fetchAttrs = [ "src" "sourceRoot" "setSourceRoot" "unpackPhase" "patches" ]; + getAttrsOrNull = names: attrs: lib.genAttrs names (name: if attrs ? ${name} then attrs.${name} else null); + flutterDeps = [ + # flutter deps + flutter.unwrapped + bash + curl + flutter.dart + git + unzip + which + xz + ]; + self = +(self: llvmPackages_13.stdenv.mkDerivation (args // { + deps = stdenvNoCC.mkDerivation (lib.recursiveUpdate (getAttrsOrNull fetchAttrs args) { + name = "${self.name}-deps-flutter-v${flutter.unwrapped.version}-${targetPlatform.system}.tar.gz"; + + nativeBuildInputs = flutterDeps ++ [ + nukeReferences + ]; + + installPhase = '' + . ${../fetchgit/deterministic-git} + + TMP=$(mktemp -d) + + export HOME="$TMP" + export PUB_CACHE=''${PUB_CACHE:-"$HOME/.pub-cache"} + export ANDROID_EMULATOR_USE_SYSTEM_LIBS=1 + + flutter config --no-analytics &>/dev/null # mute first-run + flutter config --enable-linux-desktop + flutter packages get + flutter build linux || true # so it downloads tools + + RES="$TMP" + + mkdir -p "$RES/f" + + # so we can use lock, diff yaml + cp "pubspec.yaml" "$RES" + cp "pubspec.lock" "$RES" + mv .dart_tool .flutter-plugins .flutter-plugins-dependencies .packages "$RES/f" + + # replace paths with placeholders + find "$RES" -type f -exec sed -i \ + -e s,$TMP,${placeholder_deps},g \ + -e s,${flutter.unwrapped},${placeholder_flutter},g \ + {} + + + remove_line_matching() { + replace_line_matching "$1" "$2" "" + } + + replace_line_matching() { + sed "s|.*$2.*|$3|g" -r -i "$1" + } + + # nuke nondeterminism + + # clientId is random + remove_line_matching "$RES/.flutter" clientId + + # deterministic git repos + find "$RES" -iname .git -type d | while read -r repoGit; do + make_deterministic_repo "$(dirname "$repoGit")" + done + + # dart _fetchedAt, etc + DART_DATE=$(date --date="@$SOURCE_DATE_EPOCH" -In | sed "s|,|.|g" | sed "s|+.*||g") + find "$RES/.pub-cache" -iname "*.json" -exec sed -r 's|.*_fetchedAt.*| "_fetchedAt": "'"$DART_DATE"'",|g' -i {} + + replace_line_matching "$RES/f/.dart_tool/package_config.json" '"generated"' '"generated": "'"$DART_DATE"'",' + replace_line_matching "$RES/f/.flutter-plugins-dependencies" '"date_created"' '"date_created": "'"$DART_DATE"'",' + remove_line_matching "$RES/f/.packages" "Generated by pub" + + # nuke refs + find "$RES" -type f -exec nuke-refs {} + + + # Build a reproducible tar, per instructions at https://reproducible-builds.org/docs/archives/ + tar --owner=0 --group=0 --numeric-owner --format=gnu \ + --sort=name --mtime="@$SOURCE_DATE_EPOCH" \ + -czf "$out" -C "$RES" . + ''; + + GIT_SSL_CAINFO = "${cacert}/etc/ssl/certs/ca-bundle.crt"; + + impureEnvVars = lib.fetchers.proxyImpureEnvVars ++ [ + "GIT_PROXY_COMMAND" "NIX_GIT_SSL_CAINFO" "SOCKS_SERVER" + ]; + + # unnecesarry + dontFixup = true; + + outputHashAlgo = if self ? vendorHash then null else "sha256"; + # outputHashMode = "recursive"; + outputHash = if self ? vendorHash then + self.vendorHash + else if self ? vendorSha256 then + self.vendorSha256 + else + lib.fakeSha256; + + }); + + nativeBuildInputs = flutterDeps ++ [ + # flutter dev tools + cmake + ninja + pkg-config + wrapGAppsHook + # flutter likes dynamic linking + autoPatchelfHook + ] ++ lib.optionals (args ? nativeBuildInputs) args.nativeBuildInputs; + + buildInputs = [ + # cmake deps + gtk3 + glib + pcre + util-linux + # also required by cmake, not sure if really needed or dep of all packages + libselinux + libsepol + libthai + libdatrie + xorg.libXdmcp + xorg.libXtst + libxkbcommon + dbus + at-spi2-core + libsecret + jsoncpp + # build deps + xorg.libX11 + # directly required by build + libepoxy + ] ++ lib.optionals (args ? buildInputs) args.buildInputs; + + # TODO: do we need this? + NIX_LDFLAGS = "-rpath ${lib.makeLibraryPath self.buildInputs}"; + NIX_CFLAGS_COMPILE = "-I${xorg.libX11}/include"; + LD_LIBRARY_PATH = lib.makeLibraryPath self.buildInputs; + + configurePhase = '' + runHook preConfigure + + # for some reason fluffychat build breaks without this - seems file gets overriden by some tool + cp pubspec.yaml pubspec-backup + + # we get this from $depsFolder so disabled for now, but we might need it again once deps are fetched properly + # flutter config --no-analytics >/dev/null 2>/dev/null # mute first-run + # flutter config --enable-linux-desktop + + # extract deps + depsFolder=$(mktemp -d) + tar xzf "$deps" -C "$depsFolder" + + # after extracting update paths to point to real paths + find "$depsFolder" -type f -exec sed -i \ + -e s,${placeholder_deps},$depsFolder,g \ + -e s,${placeholder_flutter},${flutter.unwrapped},g \ + {} + + + # ensure we're using a lockfile for the right package version + if [ -e pubspec.lock ]; then + # diff -u pubspec.lock $depsFolder/pubspec.lock + true + else + cp -v "$depsFolder/pubspec.lock" . + fi + diff -u pubspec.yaml $depsFolder/pubspec.yaml + + mv -v $(find $depsFolder/f -type f) . + + # prepare + export HOME=$depsFolder + export PUB_CACHE=''${PUB_CACHE:-"$HOME/.pub-cache"} + export ANDROID_EMULATOR_USE_SYSTEM_LIBS=1 + + # binaries need to be patched + autoPatchelf -- "$depsFolder" + + runHook postConfigure + ''; + + buildPhase = '' + runHook preBuild + + # for some reason fluffychat build breaks without this - seems file gets overriden by some tool + mv pubspec-backup pubspec.yaml + mkdir -p build/flutter_assets/fonts + + flutter packages get --offline -v + flutter build linux --release -v + + runHook postBuild + ''; + + installPhase = '' + runHook preInstall + + built=build/linux/*/release/bundle + + mkdir -p $out/bin + mv $built $out/app + + for f in $built/data/flutter_assets/assets/*.desktop; do + install -D $f $out/share/applications/$(basename $f) + done + for f in $(find $out/app -maxdepth 1 -type f); do + ln -s $f $out/bin/$(basename $f) + done + + # this confuses autopatchelf hook otherwise + rm -rf "$depsFolder" + + # make *.so executable + find $out/app -iname "*.so" -type f -exec chmod +x {} + + + # remove stuff like /build/source/packages/ubuntu_desktop_installer/linux/flutter/ephemeral + for f in $(find $out/app -executable -type f); do + if patchelf --print-rpath "$f" | grep /build; then # this ignores static libs (e,g. libapp.so) also + echo "strip RPath of $f" + newrp=$(patchelf --print-rpath $f | sed -r "s|/build.*ephemeral:||g" | sed -r "s|/build.*profile:||g") + patchelf --set-rpath "$newrp" "$f" + fi + done + + runHook postInstall + ''; +})) self; +in + self diff --git a/pkgs/development/compilers/flutter/flutter.nix b/pkgs/development/compilers/flutter/flutter.nix index 4b0789e35eb80..43538ede339ed 100644 --- a/pkgs/development/compilers/flutter/flutter.nix +++ b/pkgs/development/compilers/flutter/flutter.nix @@ -32,6 +32,7 @@ , nss , systemd , which +, callPackage }: let drvName = "flutter-${version}"; @@ -146,6 +147,8 @@ let }; in +let +self = (self: runCommand drvName { startScript = '' @@ -159,6 +162,9 @@ runCommand drvName passthru = { unwrapped = flutter; inherit dart; + mkFlutterApp = callPackage ../../../build-support/flutter { + flutter = self; + }; }; meta = with lib; { description = "Flutter is Google's SDK for building mobile, web and desktop with Dart"; @@ -179,4 +185,6 @@ runCommand drvName echo -n "$startScript" > $out/bin/${pname} chmod +x $out/bin/${pname} -'' +'') self; +in +self diff --git a/pkgs/os-specific/linux/firmware/firmware-updater/default.nix b/pkgs/os-specific/linux/firmware/firmware-updater/default.nix new file mode 100644 index 0000000000000..69cd829049cac --- /dev/null +++ b/pkgs/os-specific/linux/firmware/firmware-updater/default.nix @@ -0,0 +1,27 @@ +{ lib +, flutter +, fetchFromGitHub +}: + +flutter.mkFlutterApp { + pname = "firmware-updater"; + version = "unstable"; + + vendorHash = "sha256-QgeRCFbd3AcFekJunFTwu2nDOQpAOMJUxZhgY4stJJc="; + + src = fetchFromGitHub { + owner = "canonical"; + repo = "firmware-updater"; + rev = "a51817a2551e29895352618a91df9cf93d944af1"; + sha256 = "6uhks6a9JcyIC5o0VssqfBlE4pqKiQ7d3KOb6feNTvU="; + fetchSubmodules = true; + }; + + meta = with lib; { + description = "Firmware Updater for Linux"; + homepage = "https://github.com/canonical/firmware-updater"; + license = licenses.free; + maintainers = with maintainers; [ mkg20001 ]; + platforms = platforms.linux; + }; +} diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index f7db2a982089b..787ea39ae4944 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -1792,6 +1792,8 @@ with pkgs; fspy = callPackage ../applications/misc/fspy { }; + fluffychat = callPackage ../applications/networking/instant-messengers/fluffychat { }; + fxlinuxprintutil = callPackage ../tools/misc/fxlinuxprintutil { }; genann = callPackage ../development/libraries/genann { }; @@ -22301,6 +22303,8 @@ with pkgs; firmware-manager = callPackage ../os-specific/linux/firmware/firmware-manager { }; + firmware-updater = callPackage ../os-specific/linux/firmware/firmware-updater { }; + fwts = callPackage ../os-specific/linux/fwts { }; gobi_loader = callPackage ../os-specific/linux/gobi_loader { };