diff --git a/cabal.project b/cabal.project index 1de1eae02..39619484b 100644 --- a/cabal.project +++ b/cabal.project @@ -9,3 +9,8 @@ source-repository-package type: git location: git://github.com/simplex-chat/haskell-terminal.git tag: f708b00009b54890172068f168bf98508ffcd495 + +source-repository-package + type: git + location: git://github.com/zw3rk/android-support.git + tag: 3c3a5ab0b8b137a072c98d3d0937cbdc96918ddb diff --git a/direct-sqlite-2.3.26.patch b/direct-sqlite-2.3.26.patch new file mode 100644 index 000000000..9ac2196dd --- /dev/null +++ b/direct-sqlite-2.3.26.patch @@ -0,0 +1,15 @@ +diff --git a/direct-sqlite.cabal b/direct-sqlite.cabal +index 96f26b7..996198e 100644 +--- a/direct-sqlite.cabal ++++ b/direct-sqlite.cabal +@@ -69,7 +69,9 @@ library + install-includes: sqlite3.h, sqlite3ext.h + include-dirs: cbits + +- if !os(windows) && !os(android) ++ extra-libraries: dl ++ ++ if !os(windows) && !os(android) + extra-libraries: pthread + + if flag(fulltextsearch) diff --git a/flake.lock b/flake.lock new file mode 100644 index 000000000..8ab1093a0 --- /dev/null +++ b/flake.lock @@ -0,0 +1,341 @@ +{ + "nodes": { + "HTTP": { + "flake": false, + "locked": { + "lastModified": 1451647621, + "narHash": "sha256-oHIyw3x0iKBexEo49YeUDV1k74ZtyYKGR2gNJXXRxts=", + "owner": "phadej", + "repo": "HTTP", + "rev": "9bc0996d412fef1787449d841277ef663ad9a915", + "type": "github" + }, + "original": { + "owner": "phadej", + "repo": "HTTP", + "type": "github" + } + }, + "cabal-32": { + "flake": false, + "locked": { + "lastModified": 1603716527, + "narHash": "sha256-sDbrmur9Zfp4mPKohCD8IDZfXJ0Tjxpmr2R+kg5PpSY=", + "owner": "haskell", + "repo": "cabal", + "rev": "94aaa8e4720081f9c75497e2735b90f6a819b08e", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "3.2", + "repo": "cabal", + "type": "github" + } + }, + "cabal-34": { + "flake": false, + "locked": { + "lastModified": 1622475795, + "narHash": "sha256-chwTL304Cav+7p38d9mcb+egABWmxo2Aq+xgVBgEb/U=", + "owner": "haskell", + "repo": "cabal", + "rev": "b086c1995cdd616fc8d91f46a21e905cc50a1049", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "3.4", + "repo": "cabal", + "type": "github" + } + }, + "cabal-36": { + "flake": false, + "locked": { + "lastModified": 1640163203, + "narHash": "sha256-TwDWP2CffT0j40W6zr0J1Qbu+oh3nsF1lUx9446qxZM=", + "owner": "haskell", + "repo": "cabal", + "rev": "ecf418050c1821f25e2e218f1be94c31e0465df1", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "3.6", + "repo": "cabal", + "type": "github" + } + }, + "cardano-shell": { + "flake": false, + "locked": { + "lastModified": 1608537748, + "narHash": "sha256-PulY1GfiMgKVnBci3ex4ptk2UNYMXqGjJOxcPy2KYT4=", + "owner": "input-output-hk", + "repo": "cardano-shell", + "rev": "9392c75087cb9a3d453998f4230930dea3a95725", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "cardano-shell", + "type": "github" + } + }, + "flake-utils": { + "locked": { + "lastModified": 1638122382, + "narHash": "sha256-sQzZzAbvKEqN9s0bzWuYmRaA03v40gaJ4+iL1LXjaeI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "74f7e4319258e287b0f9cb95426c9853b282730b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { + "locked": { + "lastModified": 1623875721, + "narHash": "sha256-A8BU7bjS5GirpAUv4QA+QnJ4CceLHkcXdRp4xITDB0s=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "f7e004a55b120c02ecb6219596820fcd32ca8772", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "ghc-8.6.5-iohk": { + "flake": false, + "locked": { + "lastModified": 1600920045, + "narHash": "sha256-DO6kxJz248djebZLpSzTGD6s8WRpNI9BTwUeOf5RwY8=", + "owner": "input-output-hk", + "repo": "ghc", + "rev": "95713a6ecce4551240da7c96b6176f980af75cae", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "ref": "release/8.6.5-iohk", + "repo": "ghc", + "type": "github" + } + }, + "hackage": { + "flake": false, + "locked": { + "lastModified": 1642986764, + "narHash": "sha256-U6FPiNjz9JctwKC838LEoT/xjGfb8L18ZGIEY5YYzdU=", + "owner": "input-output-hk", + "repo": "hackage.nix", + "rev": "22406c79a506164c4e835a68e54739f63f918784", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "hackage.nix", + "type": "github" + } + }, + "haskellNix": { + "inputs": { + "HTTP": "HTTP", + "cabal-32": "cabal-32", + "cabal-34": "cabal-34", + "cabal-36": "cabal-36", + "cardano-shell": "cardano-shell", + "flake-utils": "flake-utils_2", + "ghc-8.6.5-iohk": "ghc-8.6.5-iohk", + "hackage": "hackage", + "hpc-coveralls": "hpc-coveralls", + "nix-tools": "nix-tools", + "nixpkgs": [ + "nixpkgs" + ], + "nixpkgs-2003": "nixpkgs-2003", + "nixpkgs-2105": "nixpkgs-2105", + "nixpkgs-2111": "nixpkgs-2111", + "nixpkgs-unstable": "nixpkgs-unstable", + "old-ghc-nix": "old-ghc-nix", + "stackage": "stackage" + }, + "locked": { + "lastModified": 1643019329, + "narHash": "sha256-So77czYvvD0jt4GJeypkqw3VNn20ype5tHnHri2s5lg=", + "owner": "input-output-hk", + "repo": "haskell.nix", + "rev": "ddc654e2e7e44617bfc17a5aed2a0947d3e192cc", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "ref": "angerman/android-static", + "repo": "haskell.nix", + "type": "github" + } + }, + "hpc-coveralls": { + "flake": false, + "locked": { + "lastModified": 1607498076, + "narHash": "sha256-8uqsEtivphgZWYeUo5RDUhp6bO9j2vaaProQxHBltQk=", + "owner": "sevanspowell", + "repo": "hpc-coveralls", + "rev": "14df0f7d229f4cd2e79f8eabb1a740097fdfa430", + "type": "github" + }, + "original": { + "owner": "sevanspowell", + "repo": "hpc-coveralls", + "type": "github" + } + }, + "nix-tools": { + "flake": false, + "locked": { + "lastModified": 1636018067, + "narHash": "sha256-ng306fkuwr6V/malWtt3979iAC4yMVDDH2ViwYB6sQE=", + "owner": "input-output-hk", + "repo": "nix-tools", + "rev": "ed5bd7215292deba55d6ab7a4e8c21f8b1564dda", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "nix-tools", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1641457028, + "narHash": "sha256-bA31xSpdSIo+rJMbHPurlxIsP/b6bbN+jvXOqyn2lR8=", + "owner": "angerman", + "repo": "nixpkgs", + "rev": "7b049e87e9b371f9ea6648aa8f1f2d17b2e31ae5", + "type": "github" + }, + "original": { + "owner": "angerman", + "ref": "patch-1", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2003": { + "locked": { + "lastModified": 1620055814, + "narHash": "sha256-8LEHoYSJiL901bTMVatq+rf8y7QtWuZhwwpKE2fyaRY=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "1db42b7fe3878f3f5f7a4f2dc210772fd080e205", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-20.03-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2105": { + "locked": { + "lastModified": 1640283157, + "narHash": "sha256-6Ddfop+rKE+Gl9Tjp9YIrkfoYPzb8F80ergdjcq3/MY=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "dde1557825c5644c869c5efc7448dc03722a8f09", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-21.05-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2111": { + "locked": { + "lastModified": 1640283207, + "narHash": "sha256-SCwl7ZnCfMDsuSYvwIroiAlk7n33bW8HFfY8NvKhcPA=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "64c7e3388bbd9206e437713351e814366e0c3284", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-21.11-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-unstable": { + "locked": { + "lastModified": 1641285291, + "narHash": "sha256-KYaOBNGar3XWTxTsYPr9P6u74KAqNq0wobEC236U+0c=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "0432195a4b8d68faaa7d3d4b355260a3120aeeae", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "old-ghc-nix": { + "flake": false, + "locked": { + "lastModified": 1631092763, + "narHash": "sha256-sIKgO+z7tj4lw3u6oBZxqIhDrzSkvpHtv0Kki+lh9Fg=", + "owner": "angerman", + "repo": "old-ghc-nix", + "rev": "af48a7a7353e418119b6dfe3cd1463a657f342b8", + "type": "github" + }, + "original": { + "owner": "angerman", + "ref": "master", + "repo": "old-ghc-nix", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "haskellNix": "haskellNix", + "nixpkgs": "nixpkgs" + } + }, + "stackage": { + "flake": false, + "locked": { + "lastModified": 1642986888, + "narHash": "sha256-oxG7LzlJdjKTJgSv7diKWsGTETDZMPT2mNNLbrBfiVs=", + "owner": "input-output-hk", + "repo": "stackage.nix", + "rev": "aeaf5fe21874f01702f394d01e18f472be6e3e08", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "stackage.nix", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 000000000..de81fb10d --- /dev/null +++ b/flake.nix @@ -0,0 +1,165 @@ +{ + description = "nix flake for simplex-chat"; + inputs.nixpkgs.url = "github:angerman/nixpkgs/patch-1"; # based on 21.11, still need this, until everything is merged into 21.11. + inputs.haskellNix.url = "github:input-output-hk/haskell.nix?ref=angerman/android-static"; + inputs.haskellNix.inputs.nixpkgs.follows = "nixpkgs"; + inputs.flake-utils.url = "github:numtide/flake-utils"; + outputs = { self, haskellNix, nixpkgs, flake-utils }: + let systems = [ "x86_64-linux" "x86_64-darwin" "aarch64-linux" "aarch64-darwin" ]; in + flake-utils.lib.eachSystem systems (system: + let pkgs = haskellNix.legacyPackages.${system}; in + let drv = pkgs': pkgs'.haskell-nix.project { + compiler-nix-name = "ghc8107"; + index-state = "2022-01-24T00:00:00Z"; + # We need this, to specify we want the cabal project. + # If the stack.yaml was dropped, this would not be necessary. + projectFileName = "cabal.project"; + src = pkgs.haskell-nix.haskellLib.cleanGit { + name = "simplex-chat"; + src = ./.; + }; + sha256map = import ./sha256map.nix; + modules = [{ + packages.direct-sqlite.patches = [ ./direct-sqlite-2.3.26.patch ]; + } + ({ pkgs,lib, ... }: lib.mkIf (pkgs.stdenv.hostPlatform.isAndroid) { + packages.simplex-chat.components.library.ghcOptions = [ "-pie" ]; + })]; + }; in + # This will package up all *.a in $out into a pkg.zip that can + # be downloaded from hydra. + let withHydraLibPkg = pkg: pkg.overrideAttrs (old: { + postInstall = '' + mkdir -p $out/_pkg + find $out/lib -name "*.a" -exec cp {} $out/_pkg \; + (cd $out/_pkg; ${pkgs.zip}/bin/zip -r -9 $out/pkg.zip *) + rm -fR $out/_pkg + mkdir -p $out/nix-support + echo "file binary-dist \"$(echo $out/*.zip)\"" \ + > $out/nix-support/hydra-build-products + ''; + }); in + rec { + packages = { + "lib:simplex-chat" = (drv pkgs).simplex-chat.components.library; + "exe:simplex-chat" = (drv pkgs).simplex-chat.components.exes.simplex-chat; + } // ({ + "x86_64-linux" = + let + androidPkgs = pkgs.pkgsCross.aarch64-android; + # For some reason building libiconv with nixpgks android setup produces + # LANGINFO_CODESET to be found, which is not compatible with android sdk 23; + # so we'll patch up iconv to not include that. + androidIconv = (androidPkgs.libiconv.override { enableStatic = true; }).overrideAttrs (old: { + postConfigure = '' + echo "#undef HAVE_LANGINFO_CODESET" >> libcharset/config.h + echo "#undef HAVE_LANGINFO_CODESET" >> lib/config.h + ''; + }); + # Similarly to icovn, for reasons beyond my current knowledge, nixpkgs andorid + # toolchain makes configure believe we have MEMFD_CREATE, which we don't in + # sdk 23. + androidFFI = androidPkgs.libffi.overrideAttrs (old: { + dontDisableStatic = true; + hardeningDisable = [ "fortify" ]; + postConfigure = '' + echo "#undef HAVE_MEMFD_CREATE" >> aarch64-unknown-linux-android/fficonfig.h + ''; + } + );in { + "aarch64-android:lib:support" = (drv androidPkgs).android-support.components.library.override { + smallAddressSpace = true; enableShared = false; + setupBuildFlags = map (x: "--ghc-option=${x}") [ "-shared" "-o" "libsupport.so" ]; + postInstall = '' + + mkdir -p $out/_pkg + cp libsupport.so $out/_pkg + ${pkgs.patchelf}/bin/patchelf --remove-needed libunwind.so.1 $out/_pkg/libsupport.so + (cd $out/_pkg; ${pkgs.zip}/bin/zip -r -9 $out/pkg.zip *) + rm -fR $out/_pkg + + mkdir -p $out/nix-support + echo "file binary-dist \"$(echo $out/*.zip)\"" \ + > $out/nix-support/hydra-build-products + ''; + }; + "aarch64-android:lib:simplex-chat" = (drv androidPkgs).simplex-chat.components.library.override { + smallAddressSpace = true; enableShared = false; + # for android we build a shared library, passing these arguments is a bit tricky, as + # we want only the threaded rts (HSrts_thr) and ffi to be linked, but not fed into iserv for + # template haskell cross compilation. Thus we just pass them as linker options (-optl). + setupBuildFlags = map (x: "--ghc-option=${x}") [ "-shared" "-o" "libsimplex.so" "-optl-lHSrts_thr" "-optl-lffi"]; + postInstall = '' + ${pkgs.tree}/bin/tree $out + mkdir -p $out/_pkg + # copy over includes, we might want those, but maybe not. + # cp -r $out/lib/*/*/include $out/_pkg/ + # find the libHS...ghc-X.Y.Z.a static library; this is the + # rolled up one with all dependencies included. + cp libsimplex.so $out/_pkg + # find ./dist -name "lib*.so" -exec cp {} $out/_pkg \; + # find ./dist -name "libHS*-ghc*.a" -exec cp {} $out/_pkg \; + # find ${androidFFI}/lib -name "*.a" -exec cp {} $out/_pkg \; + # find ${androidPkgs.gmp6.override { withStatic = true; }}/lib -name "*.a" -exec cp {} $out/_pkg \; + # find ${androidIconv}/lib -name "*.a" -exec cp {} $out/_pkg \; + # find ${androidPkgs.stdenv.cc.libc}/lib -name "*.a" -exec cp {} $out/_pkg \; + + ${pkgs.patchelf}/bin/patchelf --remove-needed libunwind.so.1 $out/_pkg/libsimplex.so + + ${pkgs.tree}/bin/tree $out/_pkg + (cd $out/_pkg; ${pkgs.zip}/bin/zip -r -9 $out/pkg.zip *) + rm -fR $out/_pkg + mkdir -p $out/nix-support + echo "file binary-dist \"$(echo $out/*.zip)\"" \ + > $out/nix-support/hydra-build-products + ''; + }; + }; + "aarch64-darwin" = { + "aarch64-darwin:lib:simplex-chat" = (drv pkgs).simplex-chat.components.library.override { + smallAddressSpace = true; enableShared = false; + # we need threaded here, otherwise all the queing logic doesn't work properly. + # for iOS we also use -staticlib, to get one rolled up library. + # still needs mac2ios patching of the archives. + ghcOptions = [ "-staticlib" "-threaded" ]; + postInstall = '' + ${pkgs.tree}/bin/tree $out + mkdir -p $out/_pkg + # copy over includes, we might want those, but maybe not. + # cp -r $out/lib/*/*/include $out/_pkg/ + # find the libHS...ghc-X.Y.Z.a static library; this is the + # rolled up one with all dependencies included. + find ./dist -name "libHS*.a" -exec cp {} $out/_pkg \; + find ${pkgs.libffi.overrideAttrs (old: { dontDisableStatic = true; })}/lib -name "*.a" -exec cp {} $out/_pkg \; + find ${pkgs.gmp6.override { withStatic = true; }}/lib -name "*.a" -exec cp {} $out/_pkg \; + # There is no static libc + ${pkgs.tree}/bin/tree $out/_pkg + (cd $out/_pkg; ${pkgs.zip}/bin/zip -r -9 $out/pkg.zip *) + rm -fR $out/_pkg + mkdir -p $out/nix-support + echo "file binary-dist \"$(echo $out/*.zip)\"" \ + > $out/nix-support/hydra-build-products + ''; + }; + }; + }.${system} or {}); + # build all packages in hydra. + hydraJobs = packages; + + devShell = let + updateCmd = pkgs.writeShellApplication { + name = "update-sha256map"; + runtimeInputs = [ pkgs.nix-prefetch-git pkgs.jq pkgs.gawk ]; + text = '' + gawk -f update-sha256.awk cabal.project > sha256map.nix + ''; + }; in + pkgs.mkShell { + buildInputs = [ updateCmd ]; + shellHook = '' + echo "welcome to the shell!" + ''; + }; + } + ); +} diff --git a/sha256map.nix b/sha256map.nix new file mode 100644 index 000000000..71494a7c5 --- /dev/null +++ b/sha256map.nix @@ -0,0 +1,5 @@ +{ + "git://github.com/simplex-chat/simplexmq.git"."b777a4fd93f888d549edf1877583fb7fc0e0196f" = "0cnbc9swdzb29j3pv4z64w26sq8dsp4ixnnv5bbf5k6dz9bwl9zm"; + "git://github.com/simplex-chat/haskell-terminal.git"."f708b00009b54890172068f168bf98508ffcd495" = "0zmq7lmfsk8m340g47g5963yba7i88n4afa6z93sg9px5jv1mijj"; + "git://github.com/zw3rk/android-support.git"."3c3a5ab0b8b137a072c98d3d0937cbdc96918ddb" = "1r6jyxbim3dsvrmakqfyxbd6ms6miaghpbwyl0sr6dzwpgaprz97"; +} diff --git a/update-sha256.awk b/update-sha256.awk new file mode 100644 index 000000000..e432ec32d --- /dev/null +++ b/update-sha256.awk @@ -0,0 +1,23 @@ +BEGIN { + print "{" + loc="" + ref="" + isGit=false +} +/source-repository-package/ { loc=""; ref=""; isGit=false; } + +/type: git/ { isGit=true; } +/location/ && isGit == true { loc=$2 } +/tag/ && isGit == true { ref=$2 } + +isGit == true && loc != "" && ref != "" { + cmd = "nix-prefetch-git --quiet "loc" "ref" | jq -r .sha256" + cmd | getline sha256 + close(cmd) + print " \""loc"\".\""ref"\" = \""sha256"\";"; + isGit=false; loc=""; ref=""; +} + +END { + print "}" +}