nix: reafactoring of status-go builds

Changes:
- Fixed `nix/status-go/desktop` builds
- Dropped nimbus wrapper for `status-go` for now
- Split `status-go` builds into subfolders: `mobile`, `desktop`
- Fixed shells for desktop builds: `linux`,`macos`,`windows`
- Added `make status-go-*` targets for building them
- Moved source management to `nix/status-go/source.nix`
- Moved `nix/status-go/build.nix` into `nix/status-go/mobile`
- Moved `nix/desktop/cmake/qtkeychain` to `nix/pkgs/qtkeychain-src`
- Moved `nix/desktop/linux/linuxdeployqt` to `nix/pkgs`
- Moved `nix/desktop/linux/appimagekit` to `nix/pkgs`
- Dropped `nix/tools/mkShell.nix` since it did almost nothing
- Dropped `nix/desktop/cmake/snorenotify` since it's broken
- Moved setup from `nix/tools/mkShell.nix` to `nix/shells.nix`
- Simplified `nix/mobile/ios/status-go-shell.nix`
- Simplified `nix/status-go/default.nix`
- Updated the `nix/DETAILS.md` and `nix/README.md`
- Moved known issues to `nix/KNOWN_ISSUES.md`
- Improved output of `nix/scripts/build.sh`

Signed-off-by: Jakub Sokołowski <jakub@status.im>
This commit is contained in:
Jakub Sokołowski 2020-04-23 20:19:12 +02:00
parent 3116b04a34
commit 42fb40476c
No known key found for this signature in database
GPG Key ID: 4EF064D0E6D63020
43 changed files with 615 additions and 782 deletions

View File

@ -201,6 +201,22 @@ jsbundle-ios: export BUILD_ENV ?= prod
jsbundle-ios: ##@jsbundle Compile JavaScript and Clojure into index.ios.js
yarn shadow-cljs release ios
#--------------
# status-go lib
# -------------
status-go-desktop: SHELL := /bin/sh
status-go-desktop: ##@status-go Compile status-go for desktop app
nix/scripts/build.sh targets.status-go.desktop
status-go-android: SHELL := /bin/sh
status-go-android: ##@status-go Compile status-go for Android app
nix/scripts/build.sh targets.status-go.mobile.android
status-go-ios: SHELL := /bin/sh
status-go-ios: ##@status-go Compile status-go for iOS app
nix/scripts/build.sh targets.status-go.mobile.ios
#--------------
# Clojure REPL
# -------------
@ -259,16 +275,15 @@ endif
lint: export TARGET := clojure
lint: ##@test Run code style checks
# yarn clj-kondo --confg .clj-kondo/config.edn --lint src
clojure -Sdeps '{:deps {cljfmt {:mvn/version "0.6.7"}}}' \
-m cljfmt.main check src \
--indents indentation.edn
-m cljfmt.main check src \
--indents indentation.edn
lint-fix: export TARGET := clojure
lint-fix: ##@test Run code style checks and fix issues
clojure -Sdeps '{:deps {cljfmt {:mvn/version "0.6.7"}}}' \
-m cljfmt.main fix src \
--indents indentation.edn
-m cljfmt.main fix src \
--indents indentation.edn
test: export TARGET := clojure
test: ##@test Run tests once in NodeJS

View File

@ -1,9 +1,10 @@
# for passing build options, see nix/README.md
{ config ? { status-im = { build-type = ""; }; } }:
{ config ? { status-im = { }; } }:
let
main = import ./nix/default.nix { inherit config; };
in {
# this is where the --attr argument selects the shell or target
inherit (main) pkgs targets shells;
inherit config;
}

View File

@ -9,6 +9,7 @@ There are four main folders in the `nix` directory:
* `nix/scripts` - Bash scripts for easier usage of Nix
* `nix/pkgs` - Packages we add to or modify in `nixpkgs`
* `nix/deps` - Project dependencies managed by Nix
* `nix/lib` - Our tools we merge into `pkgs.lib`
* `nix/tools` - Various tools used by our derivations and shells
* `nix/status-go` - Derivations for building [`status-go`](https://github.com/status-im/status-go) repo
@ -16,12 +17,15 @@ There are four main folders in the `nix` directory:
There are a few main files that define the whole build environment:
* `nix/nix.conf` - Binary cache configuration
* `nix/default.nix` - Entrypoint for both shells and targets
* `nix/shells.nix` - Definition of Nix shells used in builds
* `nix/targets.nix` - Hierarchy of main build targets
* `nix/pkgs.nix` - Definition of a custom `nixpkgs` repo
* `nix/overlay.nix` - Overrides for `nixpkgs`, custom packages
The `default.nix` and `shell.nix` files at th repo root are just a gateway into the `nix` subfolder.
# Start
The starting point for using our Nix shells and targets is the [`default.nix`](/default.nix) file.
@ -49,11 +53,11 @@ nix-build \
--show-trace \
--attr targets.mobile.android.release \
--argstr secrets-file '/tmp/tmp-status-react-559a3a441/tmp.xAnrPuNtAP' \
--option extra-sandbox-paths '/home/sochan/.gradle/status-im.keystore /tmp/tmp-status-react-559a3a441/tmp.xAnrPuNtAP' \
--option extra-sandbox-paths '/home/joe/.gradle/status-im.keystore /tmp/tmp-status-react-559a3a441/tmp.xAnrPuNtAP' \
--arg config '{ \
status-im.build-type="nightly";
status-im.build-number="2020022418";
status-im.android.keystore-file="/home/sochan/.gradle/status-im.keystore";
status-im.android.keystore-path="/home/joe/.gradle/status-im.keystore";
status-im.android.abi-split="false";
status-im.android.abi-include="armeabi-v7a;arm64-v8a;x86";
}' \

47
nix/KNOWN_ISSUES.md Normal file
View File

@ -0,0 +1,47 @@
# Known Issues
## MacOS 10.15 "Catalina"
There is an unsolved issue with the root(`/`) file system in `10.15` being read-only:
https://github.com/NixOS/nix/issues/2925
Our current recommended workaround is putting `/nix` under `/opt/nix` and symlinking it via `/etc/synthetic.conf`:
```bash
sudo mkdir /opt/nix
sudo chown ${USER} /opt/nix
sudo sh -c "echo 'nix\t/opt/nix' >> /etc/synthetic.conf"
reboot
```
After the system reboots you should see the `/nix` symlink in place:
```bash
% ls -l /nix
lrwxr-xr-x 1 root wheel 8 Oct 11 13:53 /nix -> /opt/nix
```
In order to be able to use Nix with a symlinked `/nix` you need to include this in your shell:
```bash
export NIX_IGNORE_SYMLINK_STORE=1
```
Add it to your `.bashrc` or any other shell config file.
__NOTE__: Your old `/nix` directory will end up in `/Users/Shared/Relocated Items/Security/nix` after OS upgrade.
## Cache Downloads Timing Out
If copying from Nix Cache times out you can adjust the timeout by changing [`nix/nix.conf`](/nix/nix.conf):
```conf
stalled-download-timeout = 9001
```
## `extra-sandbox-paths` Is a Restricted Setting
When building Android on NixOS you might encounter the following error:
```
ignoring the user-specified setting 'extra-sandbox-paths', because it is a restricted setting and you are not a trusted user
```
You can mitigate this by setting the [`nix.trustedUsers`](https://nixos.org/nixos/options.html#nix.trustedusers) property.

View File

@ -10,19 +10,23 @@ __NOTE:__ If you are in Asia you might want to add the `https://nix-cache-cn.sta
## Build arguments
We leverage the standard nixpkgs `config` argument for our own parameterization of the builds (e.g. to pass a build number or build type). Here is a sample structure of the `config` attribute set:
We leverage the standard nixpkgs `config` argument for our own parameterization of the builds (e.g. to pass a build number or build type).
Here is a sample structure of the `config` attribute set:
```nix
config = {
status-im = {
ci = "1"; # This flag is present when running in a CI environment
build-type = "pr"; # Build type (influences which .env file gets used for feature flags)
status-go = {
src-override = "$GOPATH/src/github.com/status-im/status-go";
build-type = "pr"; # Build type (influences which .env file gets used for feature flags)
build-number = 9999; # Used for versionCode and CFBundleVersion in Android and iOS respectively
android = {
gradle-opts = ""; # Gradle options passed for Android builds
keystore-path = ""; # Path to keystore for signing the APK
abi-split = false; # If APKs should be split based on architectures
abi-include = "x86"; # Android architectures to build for
};
status-react = {
build-number = "9999"; # Build number to be assigned to the app bundle
gradle-opts = ""; # Gradle options passed for Android builds
status-go = {
src-override = "$HOME/my/source/status-go"; # local source override
};
};
};
@ -46,71 +50,14 @@ For valid values you can check the [`nix/shells.nix`](/nix/shells.nix) file.
## Using a local status-go repository
If you need to use a locally checked-out status-go repository as a dependency of status-react, you can achieve that by defining the `STATUS_GO_SRC_OVERRIDE`
environment variable.
If you need to use a locally checked-out status-go repository, you can achieve that by defining the `STATUS_GO_SRC_OVERRIDE`
environment variable:
```sh
export STATUS_GO_SRC_OVERRIDE=$GOPATH/src/github.com/status-im/status-go
# Any command that you run from now on
# will use the specified status-go location
make release-android
```
or for a one-off build:
```sh
make release-android STATUS_GO_SRC_OVERRIDE=$GOPATH/src/github.com/status-im/status-go
```
## Using a local Nimbus repository
If you need to use a locally checked-out Nimbus repository as a dependency of status-go, you can achieve that by defining the `NIMBUS_SRC_OVERRIDE`
environment variable, in the same way as the previous point for local status-go repositories.
## Known Issues
### MacOS 10.15 "Catalina"
There is an unsolved issue with the root(`/`) file system in `10.15` being read-only:
https://github.com/NixOS/nix/issues/2925
Our current recommended workaround is putting `/nix` under `/opt/nix` and symlinking it via `/etc/synthetic.conf`:
```bash
sudo mkdir /opt/nix
sudo chown ${USER} /opt/nix
sudo sh -c "echo 'nix\t/opt/nix' >> /etc/synthetic.conf"
reboot
```
After the system reboots you should see the `/nix` symlink in place:
```bash
% ls -l /nix
lrwxr-xr-x 1 root wheel 8 Oct 11 13:53 /nix -> /opt/nix
```
In order to be able to use Nix with a symlinked `/nix` you need to include this in your shell:
```bash
export NIX_IGNORE_SYMLINK_STORE=1
```
Add it to your `.bashrc` or any other shell config file.
__NOTE__: Your old `/nix` directory will end up in `/Users/Shared/Relocated Items/Security/nix` after OS upgrade.
### Cache Downloads Timing Out
If copying from Nix Cache times out you can adjust the timeout by changing [`nix/nix.conf`](/nix/nix.conf):
```conf
stalled-download-timeout = 9001
```
### `extra-sandbox-paths` Is a Restricted Setting
When building Android on NixOS you might encounter the following error:
```
ignoring the user-specified setting 'extra-sandbox-paths', because it is a restricted setting and you are not a trusted user
```
You can mitigate this by setting the [`nix.trustedUsers`](https://nixos.org/nixos/options.html#nix.trustedusers) property.
See [`KNOWN_ISSUES.md`](./KNOWN_ISSUES.md).

View File

@ -1,43 +0,0 @@
{ pkgs, stdenv, fetchFromGitHub }:
let
version = "0.8.90";
rev = "d3c606c55adf8c2c2747556055652b3469f6c4c2"; # This revision will get used in https://github.com/status-im/react-native-keychain/blob/master/desktop/CMakeLists.txt#L45
sha256 = "1gqw3g0j46aswncm8fgy419lp1fp2y2nild82hs18xra5albvf3i";
package = stdenv.mkDerivation {
name = "qtkeychain-patched-source";
version = "${version}-${stdenv.lib.strings.substring 0 7 rev}";
src = fetchFromGitHub {
inherit rev sha256;
owner = "status-im";
repo = "qtkeychain";
name = "qtkeychain-source-${version}";
};
phases = [ "unpackPhase" ];
unpackPhase = ''
mkdir -p $out/src
cp -r $src/* $out/src/
substituteInPlace $out/src/CMakeLists.txt \
--replace "cmake_minimum_required(VERSION 2.8.11)" "cmake_minimum_required(VERSION 3.12.1)" \
--replace "project(qtkeychain)" "project(qtkeychain VERSION ${version})" \
--replace "set(QTKEYCHAIN_VERSION 0.8.90)" "set(QTKEYCHAIN_VERSION ${version})" \
--replace "{QTKEYCHAIN_VERSION}\" VARIABLE_PREFIX SNORE" "QTKEYCHAIN_VERSION VARIABLE_PREFIX SNORE" \
--replace "\"\$QTKEYCHAIN_VERSION" qtkeychain
'';
meta = with stdenv.lib; {
description = "Patched sources for qtkeychain, a platform-independent Qt API for storing passwords securely";
homepage = https://github.com/status-im/qtkeychain;
license = licenses.bsd3;
maintainers = [ maintainers.pombeirp ];
platforms = with platforms; darwin ++ linux;
};
};
in package // {
shellHook = (package.shellHook or "") + ''
export QTKEYCHAIN_SOURCES="${package}/src"
'';
}

View File

@ -1,52 +0,0 @@
{ pkgs, stdenv, fetchFromGitHub }:
let
version = "0.7.1";
rev = "9d54904e4896ab6c3c3a52f97381e5948b455970"; # This revision will get used in modules/react-native-desktop-notification/desktop/CMakeLists.txt#L71
sha256 = "0ix1qgx877nw9mlbbqsgkis4phkkf4ax2ambziy2w48hg6ai0x4d";
package = stdenv.mkDerivation {
name = "snorenotify-patched-source";
version = "${version}-${stdenv.lib.strings.substring 0 7 rev}";
src = fetchFromGitHub {
inherit rev sha256;
owner = "status-im";
repo = "snorenotify";
name = "snorenotify-source-${version}";
};
phases = [ "unpackPhase" ];
unpackPhase =
let
inherit (stdenv.lib) versions;
in ''
mkdir -p $out/src
cp -r $src/* $out/src/
substituteInPlace $out/src/CMakeLists.txt \
--replace "cmake_minimum_required( VERSION 2.8.12 )" "" \
--replace "project( SnoreNotify )" "cmake_minimum_required( VERSION 3.12.1 )
project( SnoreNotify VERSION ${version} )" \
--replace "set(SNORE_VERSION_MAJOR 0)" "set(SNORE_VERSION_MAJOR ${versions.major version} )" \
--replace "set(SNORE_VERSION_MINOR 7)" "set(SNORE_VERSION_MINOR ${versions.minor version} )" \
--replace "set(SNORE_VERSION_PATCH 1)" "set(SNORE_VERSION_PATCH ${versions.patch version} )"
substituteInPlace $out/src/src/libsnore/CMakeLists.txt \
--replace "{SNORE_VERSION_MAJOR}" "SNORE_VERSION_MAJOR" \
--replace "{SNORE_VERSION_MINOR}" "SNORE_VERSION_MINOR" \
--replace "{SNORE_VERSION_PATCH}" "SNORE_VERSION_PATCH" \
--replace "ecm_setup_version(\"\$SNORE_VERSION_MAJOR.\$SNORE_VERSION_MINOR.\$SNORE_VERSION_PATCH\"" "ecm_setup_version(SnoreNotify"
'';
meta = {
description = "Patched sources for Snorenotify, a multi platform Qt notification framework. Using a plugin system it is possible to create notifications with many different notification systems on Windows, Mac OS and Unix and mobile Devices";
homepage = https://github.com/status-im/snorenotify;
license = stdenv.lib.licenses.lgpl3;
maintainers = with stdenv.lib.maintainers; [ pombeirp ];
platforms = with stdenv.lib.platforms; darwin ++ linux;
};
};
in package // {
shellHook = (package.shellHook or "") + ''
export SNORENOTIFY_SOURCES="${package}/src"
'';
}

View File

@ -1,39 +1,49 @@
{ stdenv, mkShell, callPackage, status-go,
cmake, extra-cmake-modules, file, moreutils, go, darwin, nodejs }:
{ stdenv, lib, pkgs, mkShell, callPackage
, status-go, qtkeychain-src }:
let
inherit (stdenv.lib) catAttrs concatStrings optional unique;
inherit (stdenv) isLinux isDarwin;
inherit (lib) mapAttrs catAttrs optional unique mergeSh;
baseImageFactory = callPackage ./base-image { inherit stdenv; };
snoreNotifySources = callPackage ./cmake/snorenotify { };
qtkeychainSources = callPackage ./cmake/qtkeychain { };
# utilities
baseImageFactory = callPackage ./base-image { };
# main targets
linux = callPackage ./linux { inherit stdenv status-go baseImageFactory; };
macos = callPackage ./macos { inherit stdenv status-go darwin baseImageFactory; };
windows = callPackage ./windows { inherit stdenv go baseImageFactory; };
linux = callPackage ./linux { inherit status-go baseImageFactory; };
macos = callPackage ./macos { inherit status-go baseImageFactory; };
windows = callPackage ./windows { inherit baseImageFactory; };
selectedSources =
optional stdenv.isLinux linux ++
optional stdenv.isLinux windows ++
optional stdenv.isDarwin macos;
optional isLinux linux ++
optional isLinux windows ++
optional isDarwin macos;
in rec {
inherit linux macos windows;
# default shell for desktop builds
default = mkShell {
buildInputs = with pkgs; unique ([
file moreutils cmake
extra-cmake-modules
qtkeychain-src
] ++ (catAttrs "buildInputs" selectedSources));
buildInputs = unique ([
cmake
extra-cmake-modules
file
moreutils
snoreNotifySources
qtkeychainSources
] ++ catAttrs "buildInputs" selectedSources);
inputsFrom = [ status-go.desktop ]
++ (catAttrs "shell" selectedSources);
shell = mkShell {
inherit buildInputs;
shellHook = concatStrings (catAttrs "shellHook" (
selectedSources ++ [ snoreNotifySources qtkeychainSources ]
));
# These variables are used by the Status Desktop CMake build script in:
# - modules/react-native-status/desktop/CMakeLists.txt
shellHook = ''
export STATUS_GO_DESKTOP_INCLUDEDIR=${status-go.desktop}/include
export STATUS_GO_DESKTOP_LIBDIR=${status-go.desktop}/lib
# QT Keychain library sources
export QTKEYCHAIN_SOURCES="${qtkeychain-src}/src"
'';
};
# for merging default shell
mergeDefaultShell = (key: val: { shell = mergeSh default [ val.shell ]; });
in {
shell = default;
}
# merge default shell with platform sub-shells
// mapAttrs mergeDefaultShell { inherit linux windows macos; }

View File

@ -1,30 +1,30 @@
{ stdenv, mkShell, callPackage,
appimagekit, patchelf, qt5, status-go, baseImageFactory }:
{ lib, stdenv, mkShell, callPackage
# pkgs
, appimagekit, linuxdeployqt, patchelf, qt5custom
# custom arguments
, status-go, baseImageFactory }:
with stdenv;
assert isLinux;
assert lib.assertMsg stdenv.isLinux "Building Linux app can work only on Linux!";
let
inherit (lib) concatStrings catAttrs;
baseImage = baseImageFactory "linux";
appimagekit = callPackage ./appimagekit { };
linuxdeployqt = callPackage ./linuxdeployqt { inherit appimagekit; };
in rec {
buildInputs = [
appimagekit
linuxdeployqt
patchelf
qt5.full
] ++ status-go.buildInputs;
qt5custom
];
shell = mkShell {
inherit buildInputs;
shellHook = concatStrings (catAttrs "shellHook" [ baseImage status-go ]) + ''
export QT_PATH="${qt5.full}"
export QT_BASEBIN_PATH="${qt5.qtbase.bin}"
export PATH="${qt5.full}/bin:$PATH"
inputsFrom = [ baseImage status-go ];
shellHook = ''
export QT_PATH="${qt5custom}"
export QT_BASEBIN_PATH="${qt5custom}/bin"
export PATH="$QT_BASEBIN_PATH:$PATH"
'';
};
}

View File

@ -1,32 +1,32 @@
{ stdenv, lib, callPackage, mkShell,
gnupg22, darwin, qt5, status-go, baseImageFactory }:
gnupg22, darwin, qt5custom, status-go, baseImageFactory }:
with darwin.apple_sdk.frameworks;
assert lib.assertMsg stdenv.isDarwin "Building MacOS app can work only on MacOS!";
assert stdenv.isDarwin;
let
inherit (lib) concatStrings catAttrs;
inherit (darwin.apple_sdk.frameworks)
AppKit Cocoa Foundation OpenGL CoreFoundation;
baseImage = baseImageFactory "macos";
in rec {
buildInputs = [
gnupg22
baseImage
qt5.full
AppKit
Cocoa
darwin.cf-private
Foundation
OpenGL
] ++ status-go.buildInputs;
in {
shell = mkShell {
inherit buildInputs;
shellHook = baseImage.shellHook + ''
buildInputs = [
gnupg22 baseImage qt5custom
darwin.cf-private
AppKit Cocoa Foundation OpenGL
];
inputsFrom = [
status-go baseImage
];
shellHook = ''
export NIX_TARGET_LDFLAGS="-F${CoreFoundation}/Library/Frameworks -framework CoreFoundation $NIX_TARGET_LDFLAGS"
export QT_PATH="${qt5.full}"
export QT_BASEBIN_PATH="${qt5.qtbase.bin}"
export PATH="${qt5.full}/bin:$PATH"
export QT_PATH="${qt5custom}"
export QT_BASEBIN_PATH="${qt5custom}/bin"
export PATH="$QT_BASEBIN_PATH/bin:$PATH"
'';
};
}

View File

@ -1,12 +1,12 @@
{ stdenv, mkShell, conan, nsis, go, baseImageFactory }:
{ stdenv, lib, mkShell, conan, nsis, go, baseImageFactory }:
assert stdenv.isLinux;
assert lib.assertMsg stdenv.isLinux "Building Windows app can work only on Linux!";
let
baseImage = baseImageFactory "windows";
in rec {
buildInputs = stdenv.lib.optionals stdenv.isLinux [
buildInputs = lib.optionals stdenv.isLinux [
conan
nsis
baseImage

7
nix/lib/default.nix Normal file
View File

@ -0,0 +1,7 @@
{ lib, config }:
{
getConfig = import ./getConfig.nix { inherit lib config; };
mkFilter = import ./mkFilter.nix { inherit lib; };
mergeSh = import ./mergeSh.nix { inherit lib; };
}

12
nix/lib/getConfig.nix Normal file
View File

@ -0,0 +1,12 @@
#
# helper for getting status-im config values in a safe way
#
{ lib, config }:
let
inherit (lib) splitString attrByPath;
in
name: default:
let path = [ "status-im" ] ++ (splitString "." name);
in attrByPath path default config

View File

@ -1,10 +1,10 @@
{ lib }:
# This Nix expression allows filtering a local directory by
# specifying dirRootsToInclude, dirsToExclude and filesToInclude.
# It also filters out symlinks to result folders created by nix-build,
# as well as backup/swap/generated files.
{ lib }:
let
inherit (lib)
any range flatten length sublist cleanSourceFilter

View File

@ -50,9 +50,5 @@ in {
"${mavenAndNpmDeps.drv}/project"
'';
})
[ status-go.shell mavenAndNpmDeps.shell androidShell ];
env = {
shell = androidShell;
};
[ mavenAndNpmDeps.shell androidShell ];
}

View File

@ -1,5 +1,7 @@
{ stdenv, lib, config, callPackage, bash, file, gnumake, watchmanFactory, gradle
, androidPkgs, mavenAndNpmDeps, nodejs, openjdk, jsbundle, status-go, unzip, zlib }:
{ stdenv, lib, config, callPackage,
bash, file, gnumake, watchmanFactory, gradle,
androidPkgs, mavenAndNpmDeps,
nodejs, openjdk, jsbundle, status-go, unzip, zlib }:
{
buildEnv ? "prod", # Value for BUILD_ENV checked by Clojure code at compile time
@ -10,26 +12,20 @@
assert (lib.stringLength watchmanSockPath) > 0 -> stdenv.isDarwin;
let
inherit (lib)
toLower splitString optionalString
attrByPath hasAttrByPath optionalAttrs;
# helper for getting config values
safeGetConfig = name: default:
let path = [ "status-im" ] ++ (splitString "." name);
in attrByPath path default config;
inherit (lib) toLower optionalString getConfig;
# custom env variables derived from config
env = {
ANDROID_ABI_SPLIT = safeGetConfig "android.abi-split" false;
ANDROID_ABI_INCLUDE = safeGetConfig "android.abi-include" "armeabi-v7a;arm64-v8a;x86";
STATUS_GO_SRC_OVERRIDE = safeGetConfig "nimbus.src-override" null;
ANDROID_ABI_SPLIT = getConfig "android.abi-split" "false";
ANDROID_ABI_INCLUDE = getConfig "android.abi-include" "armeabi-v7a;arm64-v8a;x86";
STATUS_GO_SRC_OVERRIDE = getConfig "nimbus.src-override" null;
};
buildType = safeGetConfig "build-type" "prod";
buildNumber = safeGetConfig "build-number" "9999";
gradleOpts = safeGetConfig "android.gradle-opts" "";
keystorePath = safeGetConfig "android.keystore-path" "";
buildType = getConfig "build-type" "prod";
buildNumber = getConfig "build-number" 9999;
gradleOpts = getConfig "android.gradle-opts" null;
keystorePath = getConfig "android.keystore-path" null;
# Keep the same keystore path for determinism
keystoreLocal = "${gradleHome}/status-im.keystore";
@ -90,7 +86,7 @@ in stdenv.mkDerivation rec {
runHook postUnpack
'';
postUnpack = assert lib.assertMsg (keystorePath != "") "keystore-file has to be set!"; ''
postUnpack = assert lib.assertMsg (keystorePath != null) "keystore-file has to be set!"; ''
mkdir -p ${gradleHome}
# WARNING: Renaming the keystore will cause 'Keystore was tampered with' error
@ -123,14 +119,14 @@ in stdenv.mkDerivation rec {
substituteInPlace $sourceRoot/android/gradlew \
--replace \
'exec gradle' \
"exec gradle -Dmaven.repo.local='${localMavenRepo}' --offline ${gradleOpts}"
"exec gradle -Dmaven.repo.local='${localMavenRepo}' --offline ${toString gradleOpts}"
set $prevSet
'';
buildPhase = let
inherit (lib)
stringLength optionalString substring
concatStrings concatStringsSep
toInt concatStrings concatStringsSep
catAttrs mapAttrsToList makeLibraryPath;
# Take the env attribute set and build a couple of scripts
@ -140,7 +136,7 @@ in stdenv.mkDerivation rec {
adhocEnvVars = optionalString stdenv.isLinux
"LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${makeLibraryPath [ zlib ]}";
in
assert stringLength env.ANDROID_ABI_SPLIT > 0;
assert env.ANDROID_ABI_SPLIT != null && env.ANDROID_ABI_SPLIT != "";
assert stringLength env.ANDROID_ABI_INCLUDE > 0;
''
export ANDROID_SDK_ROOT="${androidPkgs}"
@ -151,16 +147,19 @@ in stdenv.mkDerivation rec {
export STATUS_REACT_HOME=$PWD
export HOME=$sourceRoot
# Used by the Android Gradle build script in android/build.gradle
export STATUS_GO_ANDROID_LIBDIR=${status-go}
${exportEnvVars}
${optionalString (secretsFile != "") "source ${secretsFile}"}
${concatStrings (catAttrs "shellHook" [ mavenAndNpmDeps.shell status-go.shell ])}
${concatStrings (catAttrs "shellHook" [ mavenAndNpmDeps.shell ])}
# fix permissions so gradle can create directories
chmod -R +w $sourceRoot/android
pushd $sourceRoot/android
${adhocEnvVars} ./gradlew -PversionCode=${buildNumber} assemble${gradleBuildType} || exit
${adhocEnvVars} ./gradlew -PversionCode=${toString buildNumber} assemble${gradleBuildType} || exit
popd > /dev/null
'';
doCheck = true;

View File

@ -12,17 +12,17 @@ let
android = callPackage ./android {
inherit localMavenRepoBuilder projectNodePackage;
status-go = status-go.android;
status-go = status-go.mobile.android;
};
ios = callPackage ./ios {
inherit xcodeWrapper projectNodePackage fastlane;
status-go = status-go.ios;
status-go = status-go.mobile.ios;
};
selectedSources = [
status-go.android
status-go.ios
status-go.mobile.android
status-go.mobile.ios
fastlane
android
ios

View File

@ -33,7 +33,7 @@ let
};
in {
inherit buildInputs pod-shell;
inherit buildInputs pod-shell status-go-shell;
shell = lib.mergeSh localShell [
fastlane.shell status-go-shell pod-shell

View File

@ -1,31 +1,30 @@
#
# This prepares status-go build file called Statusgo.framework for XCode.
# It copies the status-go build result to 'modules/react-native-status/ios/RCTStatus'.
#
{ lib, mkShell, status-go }:
let
shell = mkShell {
shellHook = ''
if [ -z "$STATUS_GO_IOS_LIBDIR" ]; then
echo "STATUS_GO_IOS_LIBDIR is not defined! Aborting."
exit 1
fi
mkShell {
shellHook = ''
export STATUS_GO_IOS_LIBDIR=${status-go}/Statusgo.framework
RCTSTATUS_DIR="$STATUS_REACT_HOME/modules/react-native-status/ios/RCTStatus"
targetBasename='Statusgo.framework'
RCTSTATUS_DIR="$STATUS_REACT_HOME/modules/react-native-status/ios/RCTStatus"
targetBasename='Statusgo.framework'
# Compare target folder with source to see if copying is required
if [ -d "$RCTSTATUS_DIR/$targetBasename" ] && [ -d $STATUS_REACT_HOME/ios/Pods/ ] && \
diff -q --no-dereference --recursive $RCTSTATUS_DIR/$targetBasename/ $STATUS_GO_IOS_LIBDIR/ > /dev/null; then
echo "$RCTSTATUS_DIR/$targetBasename already in place"
else
sourceBasename="$(basename $STATUS_GO_IOS_LIBDIR)"
echo "Copying $sourceBasename from Nix store to $RCTSTATUS_DIR"
rm -rf "$RCTSTATUS_DIR/$targetBasename/"
cp -a $STATUS_GO_IOS_LIBDIR $RCTSTATUS_DIR
chmod -R 755 "$RCTSTATUS_DIR/$targetBasename"
if [ "$sourceBasename" != "$targetBasename" ]; then
mv "$RCTSTATUS_DIR/$sourceBasename" "$RCTSTATUS_DIR/$targetBasename"
fi
# Compare target folder with source to see if copying is required
if [ -d "$RCTSTATUS_DIR/$targetBasename" ] && [ -d $STATUS_REACT_HOME/ios/Pods/ ] && \
diff -qr --no-dereference $RCTSTATUS_DIR/$targetBasename/ $STATUS_GO_IOS_LIBDIR/ > /dev/null; then
echo "$RCTSTATUS_DIR/$targetBasename already in place"
else
sourceBasename="$(basename $STATUS_GO_IOS_LIBDIR)"
echo "Copying $sourceBasename from Nix store to $RCTSTATUS_DIR"
rm -rf "$RCTSTATUS_DIR/$targetBasename/"
cp -a $STATUS_GO_IOS_LIBDIR $RCTSTATUS_DIR
chmod -R 755 "$RCTSTATUS_DIR/$targetBasename"
if [ "$sourceBasename" != "$targetBasename" ]; then
mv "$RCTSTATUS_DIR/$sourceBasename" "$RCTSTATUS_DIR/$targetBasename"
fi
'';
};
in
lib.mergeSh status-go.shell [ shell ]
fi
'';
}

View File

@ -1,4 +1,3 @@
#
# Override some packages and utilities in 'pkgs'
# and make them available globally via callPackage.
#
@ -9,18 +8,17 @@
self: super:
let
inherit (super) stdenv stdenvNoCC callPackage;
let inherit (super) stdenv stdenvNoCC callPackage;
in {
# Fix for MacOS
mkShell = super.mkShell.override { stdenv = stdenvNoCC; };
# Various utilities
utils = callPackage ./tools/utils.nix { };
lib = (super.lib or {}) // {
mkFilter = callPackage ./tools/mkFilter.nix { };
mergeSh = callPackage ./tools/mergeSh.nix { };
};
lib = (super.lib or { }) // (import ./lib {
inherit (super) lib;
inherit (self) config;
});
# Android environement
androidEnvCustom = callPackage ./mobile/android/sdk { };
@ -34,4 +32,8 @@ in {
# Custom packages
gomobile = callPackage ./pkgs/gomobile { };
qt5custom = callPackage ./pkgs/qt5custom { };
qtkeychain-src = callPackage ./pkgs/qtkeychain-src { };
appimagekit = callPackage ./pkgs/appimagekit { };
linuxdeployqt = callPackage ./pkgs/linuxdeployqt { inherit (self) appimagekit; };
}

View File

@ -0,0 +1,11 @@
{ qt5 }:
# Custom collection of QT libraries for Status desktop App
qt5.env "qt-status-${qt5.qtbase.version}" (with qt5; [
qtbase
qtsvg
qtwebengine
qtwebview
qtdeclarative
qtquickcontrols2
])

View File

@ -0,0 +1,40 @@
{ pkgs, stdenv, fetchFromGitHub }:
let
version = "0.8.90";
# This revision will get used in:
# https://github.com/status-im/react-native-keychain/blob/master/desktop/CMakeLists.txt#L45
rev = "d3c606c55adf8c2c2747556055652b3469f6c4c2";
sha256 = "1gqw3g0j46aswncm8fgy419lp1fp2y2nild82hs18xra5albvf3i";
in stdenv.mkDerivation {
name = "qtkeychain-patched-source";
version = "${version}-${stdenv.lib.strings.substring 0 7 rev}";
src = fetchFromGitHub {
inherit rev sha256;
owner = "status-im";
repo = "qtkeychain";
name = "qtkeychain-source-${version}";
};
phases = [ "unpackPhase" ];
unpackPhase = ''
mkdir -p $out/src
cp -r $src/* $out/src/
substituteInPlace $out/src/CMakeLists.txt \
--replace "cmake_minimum_required(VERSION 2.8.11)" "cmake_minimum_required(VERSION 3.12.1)" \
--replace "project(qtkeychain)" "project(qtkeychain VERSION ${version})" \
--replace "set(QTKEYCHAIN_VERSION 0.8.90)" "set(QTKEYCHAIN_VERSION ${version})" \
--replace "{QTKEYCHAIN_VERSION}\" VARIABLE_PREFIX SNORE" "QTKEYCHAIN_VERSION VARIABLE_PREFIX SNORE" \
--replace "\"\$QTKEYCHAIN_VERSION" qtkeychain
'';
meta = with stdenv.lib; {
description = "Patched sources for qtkeychain, a platform-independent Qt API for storing passwords securely";
homepage = https://github.com/status-im/qtkeychain;
license = licenses.bsd3;
maintainers = [ maintainers.pombeirp ];
platforms = with platforms; darwin ++ linux;
};
}

View File

@ -23,7 +23,8 @@ function cleanup() {
fi
}
if [[ -z "${_NIX_NO_CLEAN}" ]]; then
# If you want to clean after every build set _NIX_CLEAN=true
if [[ -n "${_NIX_CLEAN}" ]]; then
trap cleanup EXIT ERR INT QUIT
fi
@ -31,9 +32,8 @@ fi
function extractResults() {
local nixResultPath="$1"
mkdir -p "${resultPath}"
cp -vfr ${nixResultPath}/* "${resultPath}"
cp -vfr ${nixResultPath}/* "${resultPath}" | sed 's#'${PWD}'#.#'
chmod -R u+w "${resultPath}"
ls -l "${resultPath}"
}
targetAttr="${1}"
@ -58,7 +58,8 @@ nixOpts=(
echo "Running: nix-build "${nixOpts[@]}" "${@}" default.nix"
nixResultPath=$(nix-build "${nixOpts[@]}" "${@}" default.nix)
echo "Extracting result: ${nixResultPath}"
echo -e "\n${YLW}Extracting result${RST}: ${BLD}${nixResultPath}${RST}"
extractResults "${nixResultPath}"
echo -e "${GRN}SUCCESS${RST}"
echo -e "\n${GRN}SUCCESS${RST}"

View File

@ -26,12 +26,12 @@ fi
entryPoint="default.nix"
nixArgs+=("--attr shells.${TARGET}")
if [[ "$TARGET" =~ (linux|windows|darwin|macos) ]]; then
# This is a dirty workaround because 'yarn install' is an impure operation,
# so we need to call it from an impure shell.
# Hopefully we'll be able to fix this later on with something like yarn2nix
nix-shell ${nixArgs[@]} --run "scripts/prepare-for-desktop-platform.sh" || exit
# TODO: Manage node dependencies for desktop with yarn2nix
nix-shell ${nixArgs[@]} --run "scripts/prepare-for-desktop-platform.sh" default.nix || exit
fi
config=''

View File

@ -65,19 +65,20 @@ let
buildInputs = [ pkgs.openjdk8 ];
};
# for targets that need 'adb'
android-env = targets.mobile.android.env.shell;
# for targets that need 'adb' and other SDK/NDK tools
android-env = pkgs.androidShell;
# helpers for use with target argument
ios = targets.mobile.ios.shell;
android = targets.mobile.android.shell;
desktop = targets.desktop.shell;
linux = targets.desktop.linux.shell;
macos = targets.desktop.macos.shell;
windows = targets.desktop.windows.shell;
android = targets.mobile.android.shell;
ios = targets.mobile.ios.shell;
windows = targets.desktop.macos.shell;
};
# for merging the default shell with others
mergeDefaultShell = (name: value: lib.mergeSh default [ value ]);
mergeDefaultShell = (key: val: lib.mergeSh default [ val ]);
# values here can be selected using `nix-shell --attr shells.$TARGET default.nix`
# the nix/scripts/shell.sh wrapper does this for us and expects TARGET to be set

View File

@ -1,76 +0,0 @@
{ buildGoPackage, go, xcodeWrapper, stdenv, utils }:
{ owner, repo, rev, cleanVersion, goPackagePath, src, host,
nativeBuildInputs ? [],
buildInputs ? [],
buildPhase, buildMessage,
installPhase ? "",
postInstall ? "",
preFixup ? "",
outputs, meta } @ args':
with stdenv;
let
inherit (stdenv.lib) strings;
removeReferences = [ go ];
removeExpr = refs: ''remove-references-to ${lib.concatMapStrings (ref: " -t ${ref}") refs}'';
args = removeAttrs args' [ "buildMessage" ]; # Remove our arguments from args before passing them on to buildGoPackage
buildStatusGo = buildGoPackage (args // {
pname = repo;
version = "${cleanVersion}-${strings.substring 0 7 rev}-${host}";
nativeBuildInputs =
nativeBuildInputs ++
lib.optional isDarwin xcodeWrapper;
inherit buildInputs;
# Fixes Cgo related build failures (see https://github.com/NixOS/nixpkgs/issues/25959 )
hardeningDisable = [ "fortify" ];
# Ensure XCode is present, instead of failing at the end of the build
preConfigure = lib.optionalString isDarwin utils.enforceXCodeAvailable;
buildPhase = ''
runHook preBuild
runHook renameImports
echo
echo "${buildMessage}"
echo
${buildPhase}
runHook postBuild
'';
installPhase = ''
runHook preInstall
${installPhase}
runHook postInstall
'';
# replace hardcoded paths to go package in /nix/store, otherwise Nix will fail the build
preFixup = preFixup + ''
find $out -type f -exec ${removeExpr removeReferences} '{}' + || true
return # make sure we stop fixup so as to not allow the host preFixup script to proceed
'';
passthru = { inherit owner repo version rev; };
meta = {
# Add default meta information
inherit (meta) platforms;
description = meta.description or "The Status module that consumes go-ethereum.";
license = lib.licenses.mpl20;
} // meta // {
# add an extra maintainer to every package
maintainers = (meta.maintainers or [ ]) ++ [ lib.maintainers.pombeirp ];
};
});
in buildStatusGo

View File

@ -1,128 +1,26 @@
{ config, lib, utils, stdenv, callPackage, mkShell,
fetchFromGitHub, openjdk, androidPkgs }:
{ lib, callPackage, mkShell, openjdk, androidPkgs }:
let
inherit (stdenv.lib)
catAttrs concatStrings concatStringsSep fileContents importJSON makeBinPath
optional optionalString strings attrValues mapAttrs attrByPath
traceValFn;
inherit (lib)
catAttrs concatStrings concatStringsSep fileContents makeBinPath
getConfig optional attrValues mapAttrs attrByPath;
envFlags = callPackage ../tools/envParser.nix { };
enableNimbus = (attrByPath ["STATUS_GO_ENABLE_NIMBUS"] "0" envFlags) != "0";
nimbus =
if enableNimbus then callPackage ./nimbus { }
else { wrappers-android = { }; };
buildStatusGoDesktopLib = callPackage ./desktop { };
buildStatusGoMobileLib = callPackage ./mobile { };
srcData =
# If config.status-im.status-go.src-override is defined, instruct Nix to use that path to build status-go
if (attrByPath ["status-im" "status-go" "src-override"] "" config) != "" then rec {
owner = "status-im";
repo = "status-go";
rev = "unknown";
shortRev = "unknown";
rawVersion = "develop";
cleanVersion = rawVersion;
goPackagePath = "github.com/${owner}/${repo}";
src =
let path = traceValFn (path: "Using local ${repo} sources from ${path}\n") config.status-im.status-go.src-override;
in builtins.path { # We use builtins.path so that we can name the resulting derivation, otherwise the name would be taken from the checkout directory, which is outside of our control
inherit path;
name = "${repo}-source-${shortRev}";
filter =
# Keep this filter as restrictive as possible in order to avoid unnecessary rebuilds and limit closure size
lib.mkFilter {
root = path;
include = [ ".*" ];
exclude = [
".*/[.]git.*" ".*[.]md" ".*[.]yml"
".*/.*_test.go$" "_assets/.*" "build/.*"
".*/.*LICENSE.*" ".*/CONTRIB.*" ".*/AUTHOR.*"
];
};
};
} else
# Otherwise grab it from the location defined by status-go-version.json
let
versionJSON = importJSON ../../status-go-version.json; # TODO: Simplify this path search with lib.locateDominatingFile
sha256 = versionJSON.src-sha256;
in rec {
inherit (versionJSON) owner repo version;
rev = versionJSON.commit-sha1;
shortRev = strings.substring 0 7 rev;
rawVersion = versionJSON.version;
cleanVersion = utils.sanitizeVersion versionJSON.version;
goPackagePath = "github.com/${owner}/${repo}";
src = fetchFromGitHub { inherit rev owner repo sha256; name = "${repo}-${srcData.shortRev}-source"; };
};
mobileConfigs = {
android = rec {
name = "android";
envVars = [
"ANDROID_HOME=${androidPkgs}"
"ANDROID_NDK_HOME=${androidPkgs}/ndk-bundle"
"PATH=${makeBinPath [ openjdk ]}:$PATH"
];
gomobileExtraFlags = [ "-androidapi 23" ];
outputFileName = "status-go-${srcData.shortRev}.aar";
platforms = {
arm64 = {
linkNimbus = enableNimbus;
nimbus = assert enableNimbus; nimbus.wrappers-android.arm64;
gomobileTarget = "${name}/arm64";
outputFileName = "status-go-${srcData.shortRev}-arm64.aar";
};
arm = {
linkNimbus = enableNimbus;
nimbus = assert enableNimbus; nimbus.wrappers-android.arm;
gomobileTarget = "${name}/arm";
outputFileName = "status-go-${srcData.shortRev}-arm.aar";
};
x86 = {
linkNimbus = enableNimbus;
nimbus = assert enableNimbus; nimbus.wrappers-android.x86;
gomobileTarget = "${name}/386";
outputFileName = "status-go-${srcData.shortRev}-386.aar";
};
};
};
ios = rec {
name = "ios";
envVars = [];
gomobileExtraFlags = [ "-iosversion=8.0" ];
outputFileName = "Statusgo.framework";
platforms = {
ios = {
linkNimbus = enableNimbus;
nimbus = assert false; null; # TODO: Currently we don't support Nimbus on iOS
gomobileTarget = name;
inherit outputFileName;
};
};
};
# Metadata common to all builds of status-go
meta = {
description = "The Status Go module that consumes go-ethereum.";
license = lib.licenses.mpl20;
platforms = with lib.platforms; linux ++ darwin;
};
hostConfigs = {
darwin = {
name = "macos";
allTargets = [ status-go-packages.desktop status-go-packages.ios status-go-packages.android ];
};
linux = {
name = "linux";
allTargets = [ status-go-packages.desktop status-go-packages.android ];
};
};
currentHostConfig = if stdenv.isDarwin then hostConfigs.darwin else hostConfigs.linux;
goBuildFlags = concatStringsSep " " [ "-v" (optionalString enableNimbus "-tags='nimbus'") ];
# status-go params to be set at build time, important for About section and metrics
# Source can be changed with a local override from config
source = callPackage ./source.nix { };
# Params to be set at build time, important for About section and metrics
goBuildParams = {
GitCommit = srcData.rev;
Version = srcData.cleanVersion;
GitCommit = source.rev;
Version = source.cleanVersion;
};
# These are necessary for status-go to show correct version
paramsLdFlags = attrValues (mapAttrs (name: value:
"-X github.com/status-im/status-go/params.${name}=${value}"
@ -133,61 +31,14 @@ let
"-w" # -w disables DWARF debugging information
];
statusGoArgs = { inherit (srcData) src owner repo rev cleanVersion goPackagePath; inherit goBuildFlags goBuildLdFlags; };
status-go-packages = {
desktop = buildStatusGoDesktopLib (statusGoArgs // {
outputFileName = "libstatus.a";
hostSystem = stdenv.hostPlatform.system;
host = currentHostConfig.name;
});
goBuildFlags = [ "-v" ];
android = buildStatusGoMobileLib (statusGoArgs // {
host = mobileConfigs.android.name;
targetConfig = mobileConfigs.android;
});
ios = buildStatusGoMobileLib (statusGoArgs // {
host = mobileConfigs.ios.name;
targetConfig = mobileConfigs.ios;
});
in rec {
mobile = callPackage ./mobile {
inherit meta source goBuildFlags goBuildLdFlags;
};
android = rec {
buildInputs = [ status-go-packages.android ];
shell = mkShell {
inherit buildInputs;
shellHook = ''
# These variables are used by the Status Android Gradle build script in android/build.gradle
export STATUS_GO_ANDROID_LIBDIR=${status-go-packages.android}/lib
'';
};
desktop = callPackage ./desktop {
inherit meta source goBuildFlags goBuildLdFlags;
};
ios = rec {
buildInputs = [ status-go-packages.ios ];
shell = mkShell {
inherit buildInputs;
shellHook = ''
# These variables are used by the iOS build preparation section in nix/mobile/ios/default.nix
export STATUS_GO_IOS_LIBDIR=${status-go-packages.ios}/lib/Statusgo.framework
'';
};
};
desktop = rec {
buildInputs = [ status-go-packages.desktop ];
shell = mkShell {
inherit buildInputs;
shellHook = ''
# These variables are used by the Status Desktop CMake build script in modules/react-native-status/desktop/CMakeLists.txt
export STATUS_GO_DESKTOP_INCLUDEDIR=${status-go-packages.desktop}/include
export STATUS_GO_DESKTOP_LIBDIR=${status-go-packages.desktop}/lib
'';
};
};
platforms = [ android ios desktop ];
in {
shell = lib.mergeSh mkShell {} (catAttrs "shell" platforms);
# CHILD DERIVATIONS
inherit android ios desktop;
}

View File

@ -1,50 +1,60 @@
{ stdenv, utils, callPackage, buildGoPackage, go, xcodeWrapper }:
{ owner, repo, rev, cleanVersion, goPackagePath, src, host,
# desktop-only arguments
goBuildFlags, goBuildLdFlags,
outputFileName,
hostSystem } @ args':
{ lib, stdenv, utils, go, buildGoPackage
# object with source attributes
, meta , source
, goBuildFlags
, goBuildLdFlags
, outputFileName ? "libstatus.a" }:
let
buildStatusGo = callPackage ../build.nix {
inherit buildGoPackage go xcodeWrapper utils;
};
inherit (lib) concatStringsSep optionalString concatMapStrings;
# Remove desktop-only arguments from args
args = removeAttrs args' [
"goBuildFlags" "goBuildLdFlags" "outputFileName" "hostSystem"
];
removeReferences = [ go ];
removeExpr = refs: ''remove-references-to ${concatMapStrings (ref: " -t ${ref}") refs}'';
buildStatusGoDesktopLib = buildStatusGo (args // {
buildMessage = "Building desktop library";
#GOOS=windows GOARCH=amd64 CGO_ENABLED=1 go build ${goBuildFlags} -buildmode=c-archive -o $out/${outputFileName} ./lib
buildPhase =
let
CGO_LDFLAGS = stdenv.lib.concatStringsSep " " goBuildLdFlags;
in ''
pushd "$NIX_BUILD_TOP/go/src/${goPackagePath}" >/dev/null
hostSystem = stdenv.hostPlatform.system;
export GO111MODULE=off
in buildGoPackage {
pname = source.repo;
version = "${source.cleanVersion}-${source.shortRev}";
go build -o $out/${outputFileName} \
${goBuildFlags} \
-buildmode=c-archive \
-ldflags='${CGO_LDFLAGS}' \
./lib
inherit meta;
inherit (source) src goPackagePath;
popd >/dev/null
'';
# Fixes Cgo related build failures (see https://github.com/NixOS/nixpkgs/issues/25959 )
hardeningDisable = [ "fortify" ];
installPhase = ''
mkdir -p $out/lib/${hostSystem} $out/include
mv $out/${outputFileName} $out/lib/${hostSystem}
mv $out/libstatus.h $out/include
'';
# Ensure XCode is present, instead of failing at the end of the build
preConfigure = optionalString stdenv.isDarwin utils.enforceXCodeAvailable;
outputs = [ "out" ];
buildMessage = "Building desktop library";
meta = { platforms = with stdenv.lib.platforms; linux ++ darwin; };
});
#GOOS=windows GOARCH=amd64 CGO_ENABLED=1 go build ${goBuildFlags} -buildmode=c-archive -o $out/${outputFileName} ./lib
buildPhase = let
CGO_LDFLAGS = concatStringsSep " " goBuildLdFlags;
in ''
pushd "$NIX_BUILD_TOP/go/src/${source.goPackagePath}" >/dev/null
in buildStatusGoDesktopLib
export GO111MODULE=off
go build -o $out/${outputFileName} \
${concatStringsSep " " goBuildFlags} \
-buildmode=c-archive \
-ldflags='${CGO_LDFLAGS}' \
./lib
popd >/dev/null
'';
# replace hardcoded paths to go package in /nix/store, otherwise Nix will fail the build
fixupPhase = ''
find $out -type f -exec ${removeExpr removeReferences} '{}' + || true
'';
installPhase = ''
mkdir -p $out/lib/${hostSystem} $out/include
mv $out/${outputFileName} $out/lib/${hostSystem}
mv $out/libstatus.h $out/include
'';
outputs = [ "out" ];
}

View File

@ -0,0 +1,15 @@
#
# This is currently unused but is a reminder of how we used to build desktop app
#
{ mkShell, status-go-desktop }:
mkShell {
buildInputs = [ status-go-desktop ];
# These variables are used by the Status Desktop CMake build script in:
# - modules/react-native-status/desktop/CMakeLists.txt
shellHook = ''
export STATUS_GO_DESKTOP_INCLUDEDIR=${status-go-desktop}/include
export STATUS_GO_DESKTOP_LIBDIR=${status-go-desktop}/lib
'';
}

View File

@ -0,0 +1,91 @@
{ lib, stdenv, utils, callPackage, buildGoPackage
, go, androidPkgs, openjdk, gomobile, xcodeWrapper
# object with source attributes
, meta, source
, platform ? "android"
, architectures ? [ "arm64" "arm" "x86" ]
, goBuildFlags ? [ ]
, goBuildLdFlags ? [ ]
, outputFileName ? "status-go-${source.shortRev}-${platform}.aar" }:
let
inherit (lib)
concatStrings concatStringsSep concatMapStrings optionalString
getAttr attrValues makeBinPath optional;
removeReferences = [ go ];
removeExpr = refs: ''remove-references-to ${concatMapStrings (ref: " -t ${ref}") refs}'';
# formatted for use with -target
targetArchs = map (a: "${platform}/${a}") architectures;
in buildGoPackage {
pname = source.repo;
version = "${source.cleanVersion}-${source.shortRev}-${platform}";
inherit meta;
inherit (source) src goPackagePath;
nativeBuildInputs = [ gomobile ]
++ optional (platform == "android") openjdk
++ optional stdenv.isDarwin xcodeWrapper;
# Fixes Cgo related build failures (see https://github.com/NixOS/nixpkgs/issues/25959 )
hardeningDisable = [ "fortify" ];
# Ensure XCode is present, instead of failing at the end of the build
preConfigure = optionalString stdenv.isDarwin utils.enforceXCodeAvailable;
# Build mobile libraries
preBuild = let
NIX_GOWORKDIR = "$NIX_BUILD_TOP/go-build";
in ''
mkdir ${NIX_GOWORKDIR}
export GO111MODULE=off
export GOPATH=${gomobile.dev}:$GOPATH
export NIX_GOWORKDIR=${NIX_GOWORKDIR}
'' + optionalString (platform == "android") ''
export ANDROID_HOME=${androidPkgs}
export ANDROID_NDK_HOME=${androidPkgs}/ndk-bundle
export PATH="${makeBinPath [ openjdk ]}:$PATH"
'';
# Build the Go library using gomobile for each of the configured platforms
buildPhase = let
ldFlags = [ "-extldflags=-Wl,--allow-multiple-definition" ] ++ goBuildLdFlags;
CGO_LDFLAGS = concatStringsSep " " ldFlags;
in ''
runHook preBuild
runHook renameImports
echo -e "\nBuilding for targets: ${concatStringsSep "," targetArchs}\n"
${gomobile}/bin/gomobile bind \
-target=${concatStringsSep "," targetArchs} \
-ldflags="${CGO_LDFLAGS}" \
${optionalString (platform == "android") "-androidapi 23"} \
${optionalString (platform == "ios") "-iosversion=8.0"} \
${concatStringsSep " " goBuildFlags} \
-o ${outputFileName} \
${source.goPackagePath}/mobile
rm -rf $NIX_GOWORKDIR
runHook postBuild
'';
# replace hardcoded paths to go package in /nix/store, otherwise Nix will fail the build
fixupPhase = ''
find $out -type f -exec ${removeExpr removeReferences} '{}' + || true
'';
installPhase = ''
mkdir -p $out
mv ${outputFileName} $out/
'';
outputs = [ "out" ];
}

View File

@ -1,102 +1,20 @@
{ stdenv, utils, callPackage,
buildGoPackage, go, gomobile, androidPkgs,
openjdk, unzip, zip, xcodeWrapper }:
{ callPackage
, meta, source
, goBuildFlags
, goBuildLdFlags }:
{ owner, repo, rev, cleanVersion, goPackagePath, src, host,
# mobile-only arguments
goBuildFlags, goBuildLdFlags,
targetConfig } @ args':
let
inherit (stdenv.lib) concatStringsSep makeBinPath optional optionals;
buildStatusGo = callPackage ../build.nix {
inherit buildGoPackage go xcodeWrapper utils;
{
android = callPackage ./build.nix {
platform = "android";
architectures = [ "arm" "arm64" "386" ];
outputFileName = "status-go-${source.shortRev}.aar";
inherit meta source goBuildFlags goBuildLdFlags;
};
# Remove mobile-only arguments from args
args = removeAttrs args' [
"targetConfig" "goBuildFlags" "goBuildLdFlags"
];
buildStatusGoMobileLib =
let
inherit (stdenv.lib) concatStrings mapAttrsToList optionalString;
in buildStatusGo (args // {
nativeBuildInputs = [ gomobile unzip zip ] ++ optional (targetConfig.name == "android") openjdk;
buildMessage = "Building mobile library for ${targetConfig.name}";
# Build mobile libraries
buildPhase =
let
NIX_GOWORKDIR = "$NIX_BUILD_TOP/go-build";
CGO_LDFLAGS = concatStringsSep " " (goBuildLdFlags ++ [ "-extldflags=-Wl,--allow-multiple-definition" ]);
nimbusBridgeVendorDir = "$NIX_BUILD_TOP/go/src/${goPackagePath}/vendor/${goPackagePath}/eth-node/bridge/nimbus";
in ''
mkdir ${NIX_GOWORKDIR}
export GO111MODULE=off
export GOPATH=${gomobile.dev}:$GOPATH
export PATH=${makeBinPath [ gomobile.bin ]}:$PATH
export NIX_GOWORKDIR=${NIX_GOWORKDIR}
export ${concatStringsSep " " targetConfig.envVars}
# Build the Go library using gomobile for each of the configured platforms
${concatStrings (mapAttrsToList (_: platformConfig: ''
${optionalString platformConfig.linkNimbus ''
# Copy the Nimbus API artifacts to the expected vendor location
cp ${platformConfig.nimbus}/{include/*,lib/libnimbus.a} ${nimbusBridgeVendorDir}
chmod +w ${nimbusBridgeVendorDir}/libnimbus.{a,h}
''}
echo
echo "Building for target ${platformConfig.gomobileTarget}"
gomobile bind \
-target=${platformConfig.gomobileTarget} \
-ldflags="${CGO_LDFLAGS}" \
${concatStringsSep " " targetConfig.gomobileExtraFlags} \
${goBuildFlags} \
-o ${platformConfig.outputFileName} \
${goPackagePath}/mobile
${optionalString platformConfig.linkNimbus ''
rm ${nimbusBridgeVendorDir}/libnimbus.{a,h}
''}
'') targetConfig.platforms)
}
if [ "${targetConfig.name}" = 'android' ]; then
# Merge the platform-specific .aar files into a single one
local mergeDir='.aar'
mkdir $mergeDir
${concatStrings (mapAttrsToList (_: platformConfig: ''
unzip -d $mergeDir -q -n -u ${platformConfig.outputFileName}
rm ${platformConfig.outputFileName}
'') targetConfig.platforms)}
pushd $mergeDir > /dev/null
zip -r -o ../${targetConfig.outputFileName} *
popd > /dev/null
rm -rf $mergeDir
unzip -l ${targetConfig.outputFileName}
fi
# TODO: Merge iOS packages when linking with libnimbus.a
rm -rf ${NIX_GOWORKDIR}
'';
installPhase = ''
mkdir -p $out/lib
mv ${targetConfig.outputFileName} $out/lib/
'';
outputs = [ "out" ];
meta = {
platforms = with stdenv.lib.platforms; linux ++ darwin;
};
});
in buildStatusGoMobileLib
ios = callPackage ./build.nix {
platform = "ios";
architectures = [ "arm" "arm64" "386" ];
outputFileName = "Statusgo.framework";
inherit meta source goBuildFlags goBuildLdFlags;
};
}

View File

@ -1,34 +1,47 @@
{ config, stdenv, callPackage, fetchFromGitHub, mkFilter }:
#
# This fetches nimbus source from local folder or GitHub and
# loads the derivation defined in the `nix/default.nix` in the repo.
#
{ config, lib, stdenv, callPackage, fetchFromGitHub }:
let
inherit (stdenv.lib) attrByPath strings traceValFn;
inherit (lib) getConfig attrByPath strings traceValFn;
repo = "nimbus";
localPath = attrByPath ["status-im" "nimbus" "src-override"] "" config;
localSrc = builtins.path rec { # We use builtins.path so that we can name the resulting derivation, otherwise the name would be taken from the checkout directory, which is outside of our control
path = traceValFn (path: "Using local ${repo} sources from ${path}\n") localPath;
name = "${repo}-source-local";
filter =
# Keep this filter as restrictive as possible in order to avoid unnecessary rebuilds and limit closure size
mkFilter {
root = path;
include = [
"nix.*" "wrappers.*" "vendor.*"
"Makefile" "nim.cfg" "nimbus.nimble" "default.nix"
];
};
localPath = getConfig "nimbus.src-override" "";
localSrc =
# We use builtins.path so that we can name the resulting derivation.
# Name would be taken from the checkout directory, and wouldn't be deterministic.
builtins.path rec {
path = traceValFn (path: ''
Using local ${repo} sources from ${path}
'') localPath;
name = "${repo}-source-local";
filter =
# Keep this filter as restrictive as possible in order to
# avoid unnecessary rebuilds and limit closure size
lib.mkFilter {
root = path;
include = [
"nix.*" "wrappers.*" "vendor.*"
"Makefile" "nim.cfg" "nimbus.nimble" "default.nix"
];
};
};
ghSrc = fetchFromGitHub rec {
inherit repo;
name = "${repo}-source-${strings.substring 0 7 rev}";
rev = "73278f20d0bf27fb7c6c331b515abb765814f1cc";
owner = "status-im";
sha256 = "0myq234zqnpmqsc2452xygnyc6sjs8x1blyrpa4bi9v2cwbyap5c";
fetchSubmodules = true;
};
src = if localPath != "" then localSrc
else fetchFromGitHub rec {
inherit repo;
name = "${repo}-source-${strings.substring 0 7 rev}";
rev = "73278f20d0bf27fb7c6c331b515abb765814f1cc";
owner = "status-im";
sha256 = "0myq234zqnpmqsc2452xygnyc6sjs8x1blyrpa4bi9v2cwbyap5c";
fetchSubmodules = true;
};
src = if localPath != "" then localSrc else ghSrc;
nimbusDeriv = import "${src}/nix/default.nix";
in nimbusDeriv

59
nix/status-go/source.nix Normal file
View File

@ -0,0 +1,59 @@
{ config, utils, lib, callPackage, fetchFromGitHub }:
let
inherit (lib) strings traceValFn attrByPath importJSON;
srcOverride = attrByPath [ "status-im" "status-go" "src-override" ] null config;
# Warning message about using local sources
localSrcWarn = (path: "Using local status-go sources from ${path}");
localSrc = rec {
owner = "status-im";
repo = "status-go";
rev = "unknown";
shortRev = rev;
rawVersion = "develop";
cleanVersion = rawVersion;
goPackagePath = "github.com/${owner}/${repo}";
# We use builtins.path so that we can name the resulting derivation,
# Normally the name would not be deterministic, taken from the checkout directory.
src = builtins.path rec {
path = traceValFn localSrcWarn srcOverride;
name = "${repo}-source-${shortRev}";
# Keep this filter as restrictive as possible in order
# to avoid unnecessary rebuilds and limit closure size
filter = lib.mkFilter {
root = path;
include = [ ".*" ];
exclude = [
".*/[.]git.*" ".*[.]md" ".*[.]yml" ".*/.*_test.go$"
"_assets/.*" "build/.*"
".*/.*LICENSE.*" ".*/CONTRIB.*" ".*/AUTHOR.*"
];
};
};
};
githubSrc = let
# TODO: Simplify this path search with lib.locateDominatingFile
versionJSON = importJSON ../../status-go-version.json;
sha256 = versionJSON.src-sha256;
in rec {
inherit (versionJSON) owner repo version;
rev = versionJSON.commit-sha1;
shortRev = strings.substring 0 7 rev;
rawVersion = versionJSON.version;
cleanVersion = utils.sanitizeVersion versionJSON.version;
goPackagePath = "github.com/${owner}/${repo}";
src = fetchFromGitHub {
inherit rev owner repo sha256;
name = "${repo}-${shortRev}-source";
};
};
in
if srcOverride != null
# If config.status-im.status-go.src-override is defined,
# instruct Nix to use that path to build status-go
then localSrc
# Otherwise grab it from the location defined by status-go-version.json
else githubSrc

View File

@ -7,14 +7,8 @@ let
inherit (pkgs) stdenv callPackage;
status-go = callPackage ./status-go { };
desktop = callPackage ./desktop {
status-go = status-go.desktop;
};
mobile = callPackage ./mobile {
inherit status-go;
};
desktop = callPackage ./desktop { inherit status-go; };
mobile = callPackage ./mobile { inherit status-go; };
in {
inherit mobile desktop status-go;
}

View File

@ -1,40 +0,0 @@
# This Nix expression appends/modifies an existing attribute set
# in order to define STATUS_REACT_HOME for use multiple derivations and scripts
{ pkgs, stdenv ? pkgs.stdenv }:
# Declare a specialized mkShell function which adds some bootstrapping
# so that e.g. STATUS_REACT_HOME is automatically available in the shell
attrs:
(pkgs.mkShell.override({ inherit stdenv; }) attrs)
.overrideAttrs(super: rec {
nativeBuildInputs = (super.nativeBuildInputs or [ ]) ++ [ pkgs.git ];
# avoid terinal issues
TERM="xterm";
# default locale
LANG="en_US.UTF-8";
LANGUAGE="en_US.UTF-8";
shellSetup = ''
set -e
if [ -z "$STATUS_REACT_HOME" ]; then
export STATUS_REACT_HOME=$(git rev-parse --show-toplevel)
fi
export SHELL_SETUP=done
set +e
'';
shellHook = ''
if [ -z "$SHELL_SETUP" ]; then
${shellSetup}
fi
${super.shellHook or ""}
'';
}
)

View File

@ -1,9 +1,14 @@
{ xcodeWrapper, lib }:
#
# This is a collection of various utilities used throught this repo.
#
let
RED = "\\033[0;31m";
GREEN = "\\033[0;32m";
NC = "\\033[0m";
_xcodeToolsTest = ''
xcode=0
iPhoneSDK=0
@ -18,6 +23,7 @@ let
export SELECTED=$iPhoneSDK; ${_xcodeToolReportScript "iPhone SDK"}
'';
_xcodeVersion = builtins.replaceStrings ["xcode-wrapper-"] [""] xcodeWrapper.name;
enforceXCodeAvailable = ''
${_xcodeToolsTest}
if [ $xcode -eq 0 ]; then
@ -26,6 +32,7 @@ let
exit 1
fi
'';
enforceiPhoneSDKAvailable = ''
${_xcodeToolsTest}
if [ $iPhoneSDK -eq 0 ]; then

View File

@ -1,19 +1,13 @@
#!/usr/bin/env bash
###################################################################################################
#
# Impure setup (any setup here should be minimized and instead be moved to Nix for a pure setup)
#
###################################################################################################
# WARNING: Impure setup, should be minimized.
# TODO: Replace this with yarn2nix.
set -e
GIT_ROOT=$(cd "${BASH_SOURCE%/*}" && git rev-parse --show-toplevel)
source "${GIT_ROOT}/scripts/colors.sh"
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
PLATFORM_FOLDER="desktop/js_files"
if [ ! -f package.json ] || [ $(readlink package.json) != "${PLATFORM_FOLDER}/package.json" ]; then
@ -33,4 +27,4 @@ mkdir -p "$GIT_ROOT/node_modules/"
# Leverage flock (file lock) utility to create an exclusive lock on node_modules/ while running 'yarn install'
flock "$GIT_ROOT/node_modules/" yarn install --frozen-lockfile
echo -e "${GREEN}Finished!${NC}"
echo -e "${GRN}Finished!${RST}"