diff --git a/flake.lock b/flake.lock new file mode 100644 index 000000000..b7c18b53f --- /dev/null +++ b/flake.lock @@ -0,0 +1,163 @@ +{ + "nodes": { + "fenix": { + "inputs": { + "nixpkgs": "nixpkgs", + "rust-analyzer-src": "rust-analyzer-src" + }, + "locked": { + "lastModified": 1707891749, + "narHash": "sha256-SeikNYElHgv8uVMbiA9/pU3Cce7ssIsiM8CnEiwd1Nc=", + "owner": "nix-community", + "repo": "fenix", + "rev": "3115aab064ef38cccd792c45429af8df43d6d277", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "fenix", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1705309234, + "narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "naersk": { + "inputs": { + "nixpkgs": "nixpkgs_2" + }, + "locked": { + "lastModified": 1698420672, + "narHash": "sha256-/TdeHMPRjjdJub7p7+w55vyABrsJlt5QkznPYy55vKA=", + "owner": "nix-community", + "repo": "naersk", + "rev": "aeb58d5e8faead8980a807c840232697982d47b9", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "naersk", + "type": "github" + } + }, + "nix-filter": { + "locked": { + "lastModified": 1705332318, + "narHash": "sha256-kcw1yFeJe9N4PjQji9ZeX47jg0p9A0DuU4djKvg1a7I=", + "owner": "numtide", + "repo": "nix-filter", + "rev": "3449dc925982ad46246cfc36469baf66e1b64f17", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "nix-filter", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1707689078, + "narHash": "sha256-UUGmRa84ZJHpGZ1WZEBEUOzaPOWG8LZ0yPg1pdDF/yM=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "f9d39fb9aff0efee4a3d5f4a6d7c17701d38a1d8", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1707743206, + "narHash": "sha256-AehgH64b28yKobC/DAWYZWkJBxL/vP83vkY+ag2Hhy4=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "2d627a2a704708673e56346fcb13d25344b8eaf3", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "type": "indirect" + } + }, + "nixpkgs_3": { + "locked": { + "lastModified": 1707689078, + "narHash": "sha256-UUGmRa84ZJHpGZ1WZEBEUOzaPOWG8LZ0yPg1pdDF/yM=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "f9d39fb9aff0efee4a3d5f4a6d7c17701d38a1d8", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "fenix": "fenix", + "flake-utils": "flake-utils", + "naersk": "naersk", + "nix-filter": "nix-filter", + "nixpkgs": "nixpkgs_3" + } + }, + "rust-analyzer-src": { + "flake": false, + "locked": { + "lastModified": 1707849817, + "narHash": "sha256-If6T0MDErp3/z7DBlpG4bV46IPP+7BWSlgTI88cmbw0=", + "owner": "rust-lang", + "repo": "rust-analyzer", + "rev": "a02a219773629686bd8ff123ca1aa995fa50d976", + "type": "github" + }, + "original": { + "owner": "rust-lang", + "ref": "nightly", + "repo": "rust-analyzer", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 000000000..ce31f09bf --- /dev/null +++ b/flake.nix @@ -0,0 +1,330 @@ +{ + description = "Delta Chat core"; + inputs = { + fenix.url = "github:nix-community/fenix"; + flake-utils.url = "github:numtide/flake-utils"; + naersk.url = "github:nix-community/naersk"; + nix-filter.url = "github:numtide/nix-filter"; + nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + }; + outputs = { self, nixpkgs, flake-utils, nix-filter, naersk, fenix }: + flake-utils.lib.eachDefaultSystem (system: + let + pkgs = nixpkgs.legacyPackages.${system}; + fenixPkgs = fenix.packages.${system}; + naersk' = pkgs.callPackage naersk { }; + manifest = (pkgs.lib.importTOML ./Cargo.toml).package; + cargoLock = { + lockFile = ./Cargo.lock; + outputHashes = { + "email-0.0.20" = "sha256-rV4Uzqt2Qdrfi5Ti1r+Si1c2iW1kKyWLwOgLkQ5JGGw="; + "encoded-words-0.2.0" = "sha256-KK9st0hLFh4dsrnLd6D8lC6pRFFs8W+WpZSGMGJcosk="; + "lettre-0.9.2" = "sha256-+hU1cFacyyeC9UGVBpS14BWlJjHy90i/3ynMkKAzclk="; + }; + }; + mkRustPackage = packageName: + naersk'.buildPackage { + pname = packageName; + cargoBuildOptions = x: x ++ [ "--package" packageName ]; + version = manifest.version; + src = pkgs.lib.cleanSource ./.; + nativeBuildInputs = [ + pkgs.perl # Needed to build vendored OpenSSL. + ]; + auditable = false; # Avoid cargo-auditable failures. + doCheck = false; # Disable test as it requires network access. + }; + pkgsWin64 = pkgs.pkgsCross.mingwW64; + mkWin64RustPackage = packageName: + let + rustTarget = "x86_64-pc-windows-gnu"; + in + let + toolchainWin = fenixPkgs.combine [ + fenixPkgs.stable.rustc + fenixPkgs.stable.cargo + fenixPkgs.targets.${rustTarget}.stable.rust-std + ]; + naerskWin = pkgs.callPackage naersk { + cargo = toolchainWin; + rustc = toolchainWin; + }; + in + naerskWin.buildPackage rec { + pname = packageName; + cargoBuildOptions = x: x ++ [ "--package" packageName ]; + version = manifest.version; + strictDeps = true; + src = pkgs.lib.cleanSource ./.; + nativeBuildInputs = [ + pkgs.perl # Needed to build vendored OpenSSL. + ]; + depsBuildBuild = [ + pkgsWin64.stdenv.cc + pkgsWin64.windows.pthreads + ]; + auditable = false; # Avoid cargo-auditable failures. + doCheck = false; # Disable test as it requires network access. + + CARGO_BUILD_TARGET = rustTarget; + TARGET_CC = "${pkgsWin64.stdenv.cc}/bin/${pkgsWin64.stdenv.cc.targetPrefix}cc"; + CARGO_BUILD_RUSTFLAGS = [ + "-C" + "linker=${TARGET_CC}" + ]; + + CC = "${pkgsWin64.stdenv.cc}/bin/${pkgsWin64.stdenv.cc.targetPrefix}cc"; + LD = "${pkgsWin64.stdenv.cc}/bin/${pkgsWin64.stdenv.cc.targetPrefix}cc"; + }; + + pkgsWin32 = pkgs.pkgsCross.mingw32; + mkWin32RustPackage = packageName: + let + rustTarget = "i686-pc-windows-gnu"; + in + let + toolchainWin = fenixPkgs.combine [ + fenixPkgs.stable.rustc + fenixPkgs.stable.cargo + fenixPkgs.targets.${rustTarget}.stable.rust-std + ]; + naerskWin = pkgs.callPackage naersk { + cargo = toolchainWin; + rustc = toolchainWin; + }; + + # Get rid of MCF Gthread library. + # See + # and + # for details. + # + # Use DWARF-2 instead of SJLJ for exception handling. + winCC = pkgsWin32.buildPackages.wrapCC ( + (pkgsWin32.buildPackages.gcc-unwrapped.override + ({ + threadsCross = { + model = "win32"; + package = null; + }; + })).overrideAttrs (oldAttr: rec{ + configureFlags = oldAttr.configureFlags ++ [ + "--disable-sjlj-exceptions --with-dwarf2" + ]; + }) + ); + winStdenv = pkgsWin32.buildPackages.overrideCC pkgsWin32.stdenv winCC; + in + naerskWin.buildPackage rec { + pname = packageName; + cargoBuildOptions = x: x ++ [ "--package" packageName ]; + version = manifest.version; + strictDeps = true; + src = pkgs.lib.cleanSource ./.; + nativeBuildInputs = [ + pkgs.perl # Needed to build vendored OpenSSL. + ]; + depsBuildBuild = [ + winCC + pkgsWin32.windows.pthreads + ]; + auditable = false; # Avoid cargo-auditable failures. + doCheck = false; # Disable test as it requires network access. + + CARGO_BUILD_TARGET = rustTarget; + TARGET_CC = "${winCC}/bin/${winCC.targetPrefix}cc"; + CARGO_BUILD_RUSTFLAGS = [ + "-C" + "linker=${TARGET_CC}" + ]; + + CC = "${winCC}/bin/${winCC.targetPrefix}cc"; + LD = "${winCC}/bin/${winCC.targetPrefix}cc"; + }; + + mkCrossRustPackage = rustTarget: crossTarget: packageName: + let + pkgsCross = import nixpkgs { + system = system; + crossSystem.config = crossTarget; + }; + in + let + toolchain = fenixPkgs.combine [ + fenixPkgs.stable.rustc + fenixPkgs.stable.cargo + fenixPkgs.targets.${rustTarget}.stable.rust-std + ]; + naersk-lib = pkgs.callPackage naersk { + cargo = toolchain; + rustc = toolchain; + }; + in + naersk-lib.buildPackage rec { + pname = packageName; + cargoBuildOptions = x: x ++ [ "--package" packageName ]; + version = manifest.version; + strictDeps = true; + src = pkgs.lib.cleanSource ./.; + nativeBuildInputs = [ + pkgs.perl # Needed to build vendored OpenSSL. + ]; + auditable = false; # Avoid cargo-auditable failures. + doCheck = false; # Disable test as it requires network access. + + CARGO_BUILD_TARGET = rustTarget; + TARGET_CC = "${pkgsCross.stdenv.cc}/bin/${pkgsCross.stdenv.cc.targetPrefix}cc"; + CARGO_BUILD_RUSTFLAGS = [ + "-C" + "linker=${TARGET_CC}" + ]; + + CC = "${pkgsCross.stdenv.cc}/bin/${pkgsCross.stdenv.cc.targetPrefix}cc"; + LD = "${pkgsCross.stdenv.cc}/bin/${pkgsCross.stdenv.cc.targetPrefix}cc"; + }; + + mk-aarch64-RustPackage = mkCrossRustPackage "aarch64-unknown-linux-musl" "aarch64-unknown-linux-musl"; + mk-i686-RustPackage = mkCrossRustPackage "i686-unknown-linux-musl" "i686-unknown-linux-musl"; + mk-x86_64-RustPackage = mkCrossRustPackage "x86_64-unknown-linux-musl" "x86_64-unknown-linux-musl"; + mk-armv7l-RustPackage = mkCrossRustPackage "armv7-unknown-linux-musleabihf" "armv7l-unknown-linux-musleabihf"; + mk-armv6l-RustPackage = mkCrossRustPackage "arm-unknown-linux-musleabihf" "armv6l-unknown-linux-musleabihf"; + in + { + formatter = pkgs.nixpkgs-fmt; + + packages = rec { + # Run with `nix run .#deltachat-repl foo.db`. + deltachat-repl = mkRustPackage "deltachat-repl"; + deltachat-rpc-server = mkRustPackage "deltachat-rpc-server"; + + deltachat-repl-win64 = mkWin64RustPackage "deltachat-repl"; + deltachat-rpc-server-win64 = mkWin64RustPackage "deltachat-rpc-server"; + + deltachat-repl-win32 = mkWin32RustPackage "deltachat-repl"; + deltachat-rpc-server-win32 = mkWin32RustPackage "deltachat-rpc-server"; + + deltachat-repl-aarch64-linux = mk-aarch64-RustPackage "deltachat-repl"; + deltachat-rpc-server-aarch64-linux = mk-aarch64-RustPackage "deltachat-rpc-server"; + + deltachat-repl-i686-linux = mk-i686-RustPackage "deltachat-repl"; + deltachat-rpc-server-i686-linux = mk-i686-RustPackage "deltachat-rpc-server"; + + deltachat-repl-x86_64-linux = mk-x86_64-RustPackage "deltachat-repl"; + deltachat-rpc-server-x86_64-linux = mk-x86_64-RustPackage "deltachat-rpc-server"; + + deltachat-repl-armv7l-linux = mk-armv7l-RustPackage "deltachat-repl"; + deltachat-rpc-server-armv7l-linux = mk-armv7l-RustPackage "deltachat-rpc-server"; + + deltachat-repl-armv6l-linux = mk-armv6l-RustPackage "deltachat-repl"; + deltachat-rpc-server-armv6l-linux = mk-armv6l-RustPackage "deltachat-rpc-server"; + + # Run `nix build .#docs` to get C docs generated in `./result/`. + docs = + pkgs.stdenv.mkDerivation { + pname = "docs"; + version = manifest.version; + src = pkgs.lib.cleanSource ./.; + nativeBuildInputs = [ pkgs.doxygen ]; + buildPhase = ''scripts/run-doxygen.sh''; + installPhase = ''mkdir -p $out; cp -av deltachat-ffi/html deltachat-ffi/xml $out''; + }; + + libdeltachat = + pkgs.stdenv.mkDerivation rec { + pname = "libdeltachat"; + version = manifest.version; + src = nix-filter.lib { + root = ./.; + + # Include only necessary files + # to avoid rebuilds e.g. when README.md or flake.nix changes. + include = [ + ./benches + ./assets + ./Cargo.lock + ./Cargo.toml + ./CMakeLists.txt + ./CONTRIBUTING.md + ./deltachat_derive + ./deltachat-ffi + ./deltachat-jsonrpc + ./deltachat-ratelimit + ./deltachat-repl + ./deltachat-rpc-client + ./deltachat-rpc-server + ./format-flowed + ./release-date.in + ./src + ]; + exclude = [ + (nix-filter.lib.matchExt "nix") + "flake.lock" + ]; + }; + cargoDeps = pkgs.rustPlatform.importCargoLock cargoLock; + + nativeBuildInputs = [ + pkgs.perl # Needed to build vendored OpenSSL. + pkgs.cmake + pkgs.rustPlatform.cargoSetupHook + pkgs.cargo + ]; + + postInstall = '' + substituteInPlace $out/include/deltachat.h \ + --replace __FILE__ '"${placeholder "out"}/include/deltachat.h"' + ''; + }; + + deltachat-rpc-client = + pkgs.python3Packages.buildPythonPackage rec { + pname = "deltachat-rpc-client"; + version = manifest.version; + src = pkgs.lib.cleanSource ./deltachat-rpc-client; + format = "pyproject"; + propagatedBuildInputs = [ + pkgs.python3Packages.setuptools + pkgs.python3Packages.setuptools_scm + ]; + }; + + deltachat-python = + pkgs.python3Packages.buildPythonPackage rec { + pname = "deltachat-python"; + version = manifest.version; + src = pkgs.lib.cleanSource ./python; + format = "pyproject"; + buildInputs = [ + libdeltachat + ]; + nativeBuildInputs = [ + pkgs.pkg-config + ]; + propagatedBuildInputs = [ + pkgs.python3Packages.setuptools + pkgs.python3Packages.setuptools_scm + pkgs.python3Packages.pkgconfig + pkgs.python3Packages.cffi + pkgs.python3Packages.imap-tools + pkgs.python3Packages.pluggy + pkgs.python3Packages.requests + ]; + }; + python-docs = + pkgs.stdenv.mkDerivation { + pname = "docs"; + version = manifest.version; + src = pkgs.lib.cleanSource ./.; + buildInputs = [ + deltachat-python + deltachat-rpc-client + pkgs.python3Packages.breathe + pkgs.python3Packages.sphinx_rtd_theme + ]; + nativeBuildInputs = [ pkgs.sphinx ]; + buildPhase = ''sphinx-build -b html -a python/doc/ dist/html''; + installPhase = ''mkdir -p $out; cp -av dist/html $out''; + }; + }; + } + ); +}