Fix Android build on macOS

This commit is contained in:
Pedro Pombeiro 2019-09-10 11:50:09 +02:00
parent 9feb31bd3b
commit 46e3b52809
No known key found for this signature in database
GPG Key ID: C4A24185B2AA48A1
6 changed files with 67 additions and 17 deletions

View File

@ -111,14 +111,9 @@ release-android: export BUILD_ENV ?= prod
release-android: export BUILD_TYPE ?= nightly
release-android: export BUILD_NUMBER ?= 9999
release-android: export NDK_ABI_FILTERS ?= armeabi-v7a;arm64-v8a;x86
release-android: export STORE_FILE ?= ~/.gradle/status-im.keystore
release-android: export STORE_FILE ?= $(HOME)/.gradle/status-im.keystore
release-android: ##@build build release for Android
nix/build.sh targets.mobile.$(TARGET_OS).release \
--arg env '{NDK_ABI_FILTERS="$(NDK_ABI_FILTERS)";}' \
--argstr build-type $(BUILD_TYPE) \
--argstr build-number $(BUILD_NUMBER) \
--argstr keystore-file $(STORE_FILE) \
--option extra-sandbox-paths $(STORE_FILE)
scripts/release-android.sh
release-ios: export TARGET_OS ?= ios
release-ios: export BUILD_ENV ?= prod

View File

@ -8,11 +8,14 @@ let
androidEnv = callPackage ./android-env.nix { inherit target-os openjdk; };
gradle = callPackage ./gradle.nix { };
# Import a patched version of watchman (important for sandboxed builds on macOS)
watchmanFactory = callPackage ./watchman.nix { };
# Import a local patched version of node_modules, together with a local version of the Maven repo
mavenAndNpmDeps = callPackage ./maven-and-npm-deps { inherit stdenv stdenvNoCC gradle bash nodejs zlib localMavenRepoBuilder mkFilter projectNodePackage; };
# TARGETS
release = callPackage ./targets/release-android.nix { inherit target-os gradle mavenAndNpmDeps mkFilter nodejs jsbundle status-go zlib; androidEnvShellHook = androidEnv.shellHook; };
release = callPackage ./targets/release-android.nix { inherit target-os gradle mavenAndNpmDeps mkFilter nodejs jsbundle status-go zlib watchmanFactory; androidEnvShellHook = androidEnv.shellHook; };
generate-maven-and-npm-deps-shell = callPackage ./maven-and-npm-deps/maven/shell.nix { inherit mkShell gradle maven nodejs projectNodePackage status-go; androidEnvShellHook = androidEnv.shellHook; };
adb-shell = mkShell {
buildInputs = [ androidEnv.licensedAndroidEnv ];

View File

@ -1,5 +1,5 @@
{ stdenv, stdenvNoCC, lib, target-os, callPackage,
mkFilter, bash, file, gnumake, watchman, gradle,
mkFilter, bash, file, gnumake, watchmanFactory, gradle,
androidEnvShellHook, mavenAndNpmDeps,
nodejs, openjdk, jsbundle, status-go, unzip, zlib }:
@ -8,9 +8,12 @@
gradle-opts ? "",
keystore-file ? "", # Path to the .keystore file used to sign the package
secrets-file ? "", # Path to the file containing secret environment variables
watchmanSockPath ? "", # Path to the socket file exposed by an external watchman instance (workaround needed for building Android on macOS)
env ? {} # Attribute set contaning environment variables to expose to the build script
}:
assert (builtins.stringLength watchmanSockPath) > 0 -> stdenv.isDarwin;
let
baseName = "release-${target-os}";
name = "status-react-build-${baseName}";
@ -23,6 +26,7 @@ let
buildType' = if (build-type == "pr" || build-type == "e2e") then "pr" else "release"; /* PR builds shouldn't replace normal releases */
generatedApkPath = "$sourceRoot/android/app/build/outputs/apk/${buildType'}/app-${buildType'}.apk";
outApkName = "app.apk";
patchedWatchman = watchmanFactory watchmanSockPath;
in stdenv.mkDerivation {
inherit name;
@ -36,15 +40,15 @@ in stdenv.mkDerivation {
mkFilter {
dirRootsToInclude = [
"mobile_files"
"modules/react-native-status"
"modules/react-native-status/android"
"resources"
];
dirsToExclude = [ ".git" ".svn" "CVS" ".hg" ".gradle" "build" "intermediates" "libs" "obj" ];
filesToInclude = [ envFileName "status-go-version.json" "VERSION" "react-native.config.js" ];
filesToInclude = [ envFileName "status-go-version.json" "VERSION" "react-native.config.js" ".watchmanconfig" ];
root = path;
};
};
nativeBuildInputs = [ bash gradle unzip ] ++ lib.optionals stdenv.isDarwin [ file gnumake watchman ];
nativeBuildInputs = [ bash gradle unzip ] ++ lib.optionals stdenv.isDarwin [ file gnumake patchedWatchman ];
buildInputs = [ nodejs openjdk ];
phases = [ "unpackPhase" "patchPhase" "buildPhase" "checkPhase" "installPhase" ];
unpackPhase = ''

View File

@ -0,0 +1,18 @@
{ stdenv, runCommand, makeWrapper,
watchman }:
let
patchedWatchmanFactory = watchmanSockPath:
assert (builtins.stringLength watchmanSockPath) > 0 -> stdenv.isDarwin;
if stdenv.isDarwin then
assert (builtins.stringLength watchmanSockPath) > 0;
# Create a wrapper to watchman that includes the --sockname flag
runCommand "patched-watchman" { nativeBuildInputs = [ makeWrapper ]; } ''
mkdir -p $out/bin
makeWrapper ${watchman}/bin/watchman \
$out/bin/watchman \
--add-flags "--sockname=${watchmanSockPath}"
'' else watchman;
in patchedWatchmanFactory

View File

@ -22,7 +22,7 @@ if ! command -v "nix" >/dev/null 2>&1; then
if [ -f ~/.nix-profile/etc/profile.d/nix.sh ]; then
. ~/.nix-profile/etc/profile.d/nix.sh
elif [ "$IN_NIX_SHELL" != 'pure' ]; then
echo -e "${GREEN}Setting up environment...${NC}"
echo -e "${GREEN}Setting up environment...${NC}" > /dev/stderr
./scripts/setup
. ~/.nix-profile/etc/profile.d/nix.sh
@ -30,7 +30,7 @@ if ! command -v "nix" >/dev/null 2>&1; then
fi
if !command -v "nix" >/dev/null 2>&1; then
echo "Nix not available, sourcing profile failed!"
echo "Nix not available, sourcing profile failed!" > /dev/stderr
exit 1
fi
@ -41,7 +41,7 @@ shellArgs=(
if [[ -n "${TARGET_OS}" ]]; then
shellArgs+=("--argstr target-os ${TARGET_OS}")
else
echo -e "${YELLOW}Env is missing TARGET_OS, assuming no target platform.${NC} See nix/README.md for more details."
echo -e "${YELLOW}Env is missing TARGET_OS, assuming no target platform.${NC} See nix/README.md for more details." > /dev/stderr
fi
if [[ "$TARGET_OS" =~ (linux|windows|darwin|macos) ]]; then
@ -61,7 +61,7 @@ fi
# ENTER_NIX_SHELL is the fake command used when `make shell` is run.
# It is just a special string, not a variable, and a marker to not use `--run`.
if [[ $@ == "ENTER_NIX_SHELL" ]]; then
echo -e "${GREEN}Configuring ${_NIX_ATTR:-default} Nix shell for target '${TARGET_OS:-none}'...${NC}"
echo -e "${GREEN}Configuring ${_NIX_ATTR:-default} Nix shell for target '${TARGET_OS:-none}'...${NC}" > /dev/stderr
exec nix-shell ${shellArgs[@]} ${entryPoint}
else
# Not all builds are ready to be run in a pure environment
@ -74,6 +74,6 @@ else
if [[ -n "${_NIX_KEEP}" ]]; then
shellArgs+=("--keep ${_NIX_KEEP//;/ --keep }")
fi
echo -e "${GREEN}Configuring ${pureDesc}${_NIX_ATTR:-default} Nix shell for target '${TARGET_OS}'...${NC}"
echo -e "${GREEN}Configuring ${pureDesc}${_NIX_ATTR:-default} Nix shell for target '${TARGET_OS}'...${NC}" > /dev/stderr
exec nix-shell ${shellArgs[@]} --run "$@" ${entryPoint}
fi

30
scripts/release-android.sh Executable file
View File

@ -0,0 +1,30 @@
#!/usr/bin/env bash
GIT_ROOT=$(cd "${BASH_SOURCE%/*}" && git rev-parse --show-toplevel)
_current_dir=$(cd "${BASH_SOURCE%/*}" && pwd)
source "$_current_dir/lib/setup/path-support.sh"
source_lib "platform.sh"
nixOpts=(
"--arg env {NDK_ABI_FILTERS=\"${NDK_ABI_FILTERS}\";}"
"--argstr build-type ${BUILD_TYPE}"
"--argstr build-number ${BUILD_NUMBER}"
"--argstr keystore-file ${STORE_FILE}"
)
if is_macos; then
# Start a watchman instance if not started already and store its socket path.
# In order to get access to the right versions of watchman and jq, we start an ad-hoc nix-shell that imports the packages from nix/nixpkgs-bootstrap.
WATCHMAN_SOCKFILE=$(watchman get-sockname --no-pretty | jq -r .sockname)
nixOpts+=(
"--argstr watchmanSockPath ${WATCHMAN_SOCKFILE}"
"--option extra-sandbox-paths ${STORE_FILE};${WATCHMAN_SOCKFILE}"
)
else
nixOpts+=(
"--option extra-sandbox-paths ${STORE_FILE}"
)
fi
${GIT_ROOT}/nix/build.sh targets.mobile.${TARGET_OS}.release "${nixOpts[@]}"