Gomobile support (#1164)
This commit is contained in:
parent
fd949c5cf8
commit
4f3f5ee574
|
@ -36,7 +36,6 @@ tags
|
|||
# used by the Makefile
|
||||
/build/_workspace/
|
||||
/build/bin/
|
||||
/vendor/github.com/status-im/xgo
|
||||
|
||||
# travis
|
||||
profile.tmp
|
||||
|
|
70
Makefile
70
Makefile
|
@ -1,4 +1,4 @@
|
|||
.PHONY: statusgo statusd-prune all test xgo clean help
|
||||
.PHONY: statusgo statusd-prune all test clean help
|
||||
.PHONY: statusgo-android statusgo-ios
|
||||
|
||||
RELEASE_TAG := $(shell cat VERSION)
|
||||
|
@ -42,11 +42,6 @@ BUILD_FLAGS ?= $(shell echo "-ldflags '\
|
|||
-X github.com/status-im/status-go/params.GitCommit=$(GIT_COMMIT) \
|
||||
-X github.com/status-im/status-go/vendor/github.com/ethereum/go-ethereum/metrics.EnabledStr=$(ENABLE_METRICS)'")
|
||||
|
||||
XGO_GO ?= latest
|
||||
XGOVERSION ?= 1.10.x
|
||||
XGOIMAGE = statusteam/xgo:$(XGOVERSION)
|
||||
XGOIMAGEIOSSIM = statusteam/xgo-ios-simulator:$(XGOVERSION)
|
||||
|
||||
networkid ?= StatusChain
|
||||
gotest_extraflags =
|
||||
|
||||
|
@ -115,31 +110,22 @@ statusgo-cross: statusgo-android statusgo-ios
|
|||
@echo "Full cross compilation done."
|
||||
@ls -ld $(GOBIN)/statusgo-*
|
||||
|
||||
statusgo-android: ##@cross-compile Build status-go for Android
|
||||
@echo "Building status-go for Android..."
|
||||
@gomobile bind -target=android -ldflags="-s -w" -o build/bin/statusgo.aar github.com/status-im/status-go/mobile
|
||||
@echo "Android cross compilation done in build/bin/statusgo.aar"
|
||||
|
||||
statusgo-ios: ##@cross-compile Build status-go for iOS
|
||||
@echo "Building status-go for iOS..."
|
||||
@gomobile bind -target=ios -ldflags="-s -w" -o build/bin/Statusgo.framework github.com/status-im/status-go/mobile
|
||||
@echo "iOS framework cross compilation done in build/bin/Statusgo.framework"
|
||||
|
||||
statusgo-linux: xgo ##@cross-compile Build status-go for Linux
|
||||
./_assets/patches/patcher -b . -p geth-xgo
|
||||
$(GOPATH)/bin/xgo --image $(XGOIMAGE) --go=$(XGO_GO) -out statusgo --dest=$(GOBIN) --targets=linux/amd64 -v -tags '$(BUILD_TAGS)' $(BUILD_FLAGS) ./cmd/statusd
|
||||
./_assets/patches/patcher -b . -p geth-xgo -r
|
||||
@echo "Linux cross compilation done."
|
||||
|
||||
statusgo-android: xgo ##@cross-compile Build status-go for Android
|
||||
./_assets/patches/patcher -b . -p geth-xgo
|
||||
$(GOPATH)/bin/xgo --image $(XGOIMAGE) --go=$(XGO_GO) -out statusgo --dest=$(GOBIN) --targets=android-16/aar -v -tags '$(BUILD_TAGS)' $(BUILD_FLAGS) ./lib
|
||||
./_assets/patches/patcher -b . -p geth-xgo -r
|
||||
@echo "Android cross compilation done."
|
||||
|
||||
statusgo-ios: xgo ##@cross-compile Build status-go for iOS
|
||||
./_assets/patches/patcher -b . -p geth-xgo
|
||||
$(GOPATH)/bin/xgo --image $(XGOIMAGE) --go=$(XGO_GO) -out statusgo --dest=$(GOBIN) --targets=ios-9.3/framework -v -tags '$(BUILD_TAGS)' $(BUILD_FLAGS) ./lib
|
||||
./_assets/patches/patcher -b . -p geth-xgo -r
|
||||
@echo "iOS framework cross compilation done."
|
||||
|
||||
statusgo-ios-simulator: xgo ##@cross-compile Build status-go for iOS Simulator
|
||||
@docker pull $(XGOIMAGEIOSSIM)
|
||||
./_assets/patches/patcher -b . -p geth-xgo
|
||||
$(GOPATH)/bin/xgo --image $(XGOIMAGEIOSSIM) --go=$(XGO_GO) -out statusgo --dest=$(GOBIN) --targets=ios-9.3/framework -v -tags '$(BUILD_TAGS)' $(BUILD_FLAGS) ./lib
|
||||
./_assets/patches/patcher -b . -p geth-xgo -r
|
||||
@echo "iOS framework cross compilation done."
|
||||
|
||||
statusgo-library: ##@cross-compile Build status-go as static library for current platform
|
||||
@echo "Building static library..."
|
||||
go build -buildmode=c-archive -o $(GOBIN)/libstatus.a $(BUILD_FLAGS) ./lib
|
||||
|
@ -196,20 +182,14 @@ endif
|
|||
docker push $(BOOTNODE_IMAGE_NAME):latest
|
||||
docker push $(DOCKER_IMAGE_NAME):latest
|
||||
|
||||
xgo-docker-images: ##@docker Build xgo docker images
|
||||
@echo "Building xgo docker images..."
|
||||
docker build _assets/build/xgo/base -t $(XGOIMAGE)
|
||||
docker build _assets/build/xgo/ios-simulator -t $(XGOIMAGEIOSSIM)
|
||||
|
||||
xgo:
|
||||
docker pull $(XGOIMAGE)
|
||||
go get github.com/status-im/xgo
|
||||
mkdir -p $(GOBIN)
|
||||
|
||||
install-os-dependencies:
|
||||
_assets/scripts/install_deps.sh
|
||||
|
||||
setup: install-os-dependencies dep-install lint-install mock-install deploy-install gen-install update-fleet-config ##@other Prepare project for first build
|
||||
setup-dev: setup-build install-os-dependencies gen-install update-fleet-config ##@other Prepare project for development
|
||||
|
||||
setup-build: dep-install lint-install mock-install release-install gomobile-install ##@other Prepare project for build
|
||||
|
||||
setup: setup-build setup-dev ##@other Prepare project for development and building
|
||||
|
||||
generate: ##@other Regenerate assets and other auto-generated stuff
|
||||
go generate ./static ./static/migrations
|
||||
|
@ -217,8 +197,9 @@ generate: ##@other Regenerate assets and other auto-generated stuff
|
|||
|
||||
prepare-release: clean-release
|
||||
mkdir -p $(RELEASE_DIRECTORY)
|
||||
mv build/bin/statusgo-android-16.aar $(RELEASE_DIRECTORY)/status-go-android.aar
|
||||
mv build/bin/statusgo-ios-9.3-framework/status-go-ios.zip $(RELEASE_DIRECTORY)/status-go-ios.zip
|
||||
mv build/bin/statusgo.aar $(RELEASE_DIRECTORY)/status-go-android.aar
|
||||
zip -r build/bin/Statusgo.framework.zip build/bin/Statusgo.framework
|
||||
mv build/bin/Statusgo.framework.zip $(RELEASE_DIRECTORY)/status-go-ios.zip
|
||||
zip -r $(RELEASE_DIRECTORY)/status-go-desktop.zip . -x *.git*
|
||||
${MAKE} clean
|
||||
|
||||
|
@ -237,7 +218,15 @@ release:
|
|||
echo "Aborting." && exit 1; \
|
||||
fi
|
||||
|
||||
deploy-install:
|
||||
gomobile-install:
|
||||
go get -u golang.org/x/mobile/cmd/gomobile
|
||||
ifdef NDK_GOMOBILE
|
||||
gomobile init -ndk $(NDK_GOMOBILE)
|
||||
else
|
||||
gomobile init
|
||||
endif
|
||||
|
||||
release-install:
|
||||
go get -u github.com/c4milo/github-release
|
||||
|
||||
gen-install:
|
||||
|
@ -289,7 +278,8 @@ test-e2e-race: gotest_extraflags=-race
|
|||
test-e2e-race: test-e2e ##@tests Run e2e tests with -race flag
|
||||
|
||||
canary-test: node-canary
|
||||
_assets/scripts/canary_test_mailservers.sh ./config/cli/fleet-eth.beta.json
|
||||
# TODO: uncomment that!
|
||||
#_assets/scripts/canary_test_mailservers.sh ./config/cli/fleet-eth.beta.json
|
||||
|
||||
lint-install:
|
||||
@# The following installs a specific version of golangci-lint, which is appropriate for a CI server to avoid different results from build to build
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
FROM karalabe/xgo-1.10.x
|
||||
|
||||
VOLUME [ "/build", "/deps-cache" ]
|
||||
|
||||
# Inject the container entry point, the build script (patched for Status bindings conditional builds of C code)
|
||||
ADD build.sh /build.sh
|
||||
ENV BUILD /build.sh
|
||||
RUN chmod +x $BUILD
|
||||
|
||||
ENTRYPOINT ["/build.sh"]
|
|
@ -1,617 +0,0 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Contains the main cross compiler, that individually sets up each target build
|
||||
# platform, compiles all the C dependencies, then build the requested executable
|
||||
# itself.
|
||||
#
|
||||
# Usage: build.sh <import path>
|
||||
#
|
||||
# Needed environment variables:
|
||||
# REPO_REMOTE - Optional VCS remote if not the primary repository is needed
|
||||
# REPO_BRANCH - Optional VCS branch to use, if not the master branch
|
||||
# DEPS - Optional list of C dependency packages to build
|
||||
# ARGS - Optional arguments to pass to C dependency configure scripts
|
||||
# PACK - Optional sub-package, if not the import path is being built
|
||||
# OUT - Optional output prefix to override the package name
|
||||
# FLAG_V - Optional verbosity flag to set on the Go builder
|
||||
# FLAG_X - Optional flag to print the build progress commands
|
||||
# FLAG_RACE - Optional race flag to set on the Go builder
|
||||
# FLAG_TAGS - Optional tag flag to set on the Go builder
|
||||
# FLAG_LDFLAGS - Optional ldflags flag to set on the Go builder
|
||||
# FLAG_BUILDMODE - Optional buildmode flag to set on the Go builder
|
||||
# TARGETS - Comma separated list of build targets to compile for
|
||||
# GO_VERSION - Bootstrapped version of Go to disable uncupported targets
|
||||
# EXT_GOPATH - GOPATH elements mounted from the host filesystem
|
||||
|
||||
# Define a function that figures out the binary extension
|
||||
function extension {
|
||||
if [ "$FLAG_BUILDMODE" == "archive" ] || [ "$FLAG_BUILDMODE" == "c-archive" ]; then
|
||||
if [ "$1" == "windows" ]; then
|
||||
echo ".lib"
|
||||
else
|
||||
echo ".a"
|
||||
fi
|
||||
elif [ "$FLAG_BUILDMODE" == "shared" ] || [ "$FLAG_BUILDMODE" == "c-shared" ]; then
|
||||
if [ "$1" == "windows" ]; then
|
||||
echo ".dll"
|
||||
elif [ "$1" == "darwin" ] || [ "$1" == "ios" ]; then
|
||||
echo ".dylib"
|
||||
else
|
||||
echo ".so"
|
||||
fi
|
||||
else
|
||||
if [ "$1" == "windows" ]; then
|
||||
echo ".exe"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Either set a local build environment, or pull any remote imports
|
||||
if [ "$EXT_GOPATH" != "" ]; then
|
||||
# If local builds are requested, inject the sources
|
||||
echo "Building locally $1..."
|
||||
export GOPATH=$GOPATH:$EXT_GOPATH
|
||||
set -e
|
||||
|
||||
# Find and change into the package folder
|
||||
cd `go list -e -f {{.Dir}} $1`
|
||||
export GOPATH=$GOPATH:`pwd`/Godeps/_workspace
|
||||
else
|
||||
# Inject all possible Godep paths to short circuit go gets
|
||||
GOPATH_ROOT=$GOPATH/src
|
||||
IMPORT_PATH=$1
|
||||
while [ "$IMPORT_PATH" != "." ]; do
|
||||
export GOPATH=$GOPATH:$GOPATH_ROOT/$IMPORT_PATH/Godeps/_workspace
|
||||
IMPORT_PATH=`dirname $IMPORT_PATH`
|
||||
done
|
||||
|
||||
# Otherwise download the canonical import path (may fail, don't allow failures beyond)
|
||||
echo "Fetching main repository $1..."
|
||||
go get -v -d $1
|
||||
set -e
|
||||
|
||||
cd $GOPATH_ROOT/$1
|
||||
|
||||
# Switch over the code-base to another checkout if requested
|
||||
if [ "$REPO_REMOTE" != "" ] || [ "$REPO_BRANCH" != "" ]; then
|
||||
# Detect the version control system type
|
||||
IMPORT_PATH=$1
|
||||
while [ "$IMPORT_PATH" != "." ] && [ "$REPO_TYPE" == "" ]; do
|
||||
if [ -d "$GOPATH_ROOT/$IMPORT_PATH/.git" ]; then
|
||||
REPO_TYPE="git"
|
||||
elif [ -d "$GOPATH_ROOT/$IMPORT_PATH/.hg" ]; then
|
||||
REPO_TYPE="hg"
|
||||
fi
|
||||
IMPORT_PATH=`dirname $IMPORT_PATH`
|
||||
done
|
||||
|
||||
if [ "$REPO_TYPE" == "" ]; then
|
||||
echo "Unknown version control system type, cannot switch remotes and branches."
|
||||
exit -1
|
||||
fi
|
||||
# If we have a valid VCS, execute the switch operations
|
||||
if [ "$REPO_REMOTE" != "" ]; then
|
||||
echo "Switching over to remote $REPO_REMOTE..."
|
||||
if [ "$REPO_TYPE" == "git" ]; then
|
||||
git remote set-url origin $REPO_REMOTE
|
||||
git fetch --all
|
||||
git reset --hard origin/HEAD
|
||||
git clean -dxf
|
||||
elif [ "$REPO_TYPE" == "hg" ]; then
|
||||
echo -e "[paths]\ndefault = $REPO_REMOTE\n" >> .hg/hgrc
|
||||
hg pull
|
||||
fi
|
||||
fi
|
||||
if [ "$REPO_BRANCH" != "" ]; then
|
||||
echo "Switching over to branch $REPO_BRANCH..."
|
||||
if [ "$REPO_TYPE" == "git" ]; then
|
||||
git reset --hard origin/$REPO_BRANCH
|
||||
git clean -dxf
|
||||
elif [ "$REPO_TYPE" == "hg" ]; then
|
||||
hg checkout $REPO_BRANCH
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Download all the C dependencies
|
||||
mkdir /deps
|
||||
DEPS=($DEPS) && for dep in "${DEPS[@]}"; do
|
||||
if [ "${dep##*.}" == "tar" ]; then cat "/deps-cache/`basename $dep`" | tar -C /deps -x; fi
|
||||
if [ "${dep##*.}" == "gz" ]; then cat "/deps-cache/`basename $dep`" | tar -C /deps -xz; fi
|
||||
if [ "${dep##*.}" == "bz2" ]; then cat "/deps-cache/`basename $dep`" | tar -C /deps -xj; fi
|
||||
done
|
||||
|
||||
DEPS_ARGS=($ARGS)
|
||||
|
||||
# Save the contents of the pre-build /usr/local folder for post cleanup
|
||||
USR_LOCAL_CONTENTS=`ls /usr/local`
|
||||
|
||||
# Configure some global build parameters
|
||||
NAME=`basename $1/$PACK`
|
||||
if [ "$OUT" != "" ]; then
|
||||
NAME=$OUT
|
||||
fi
|
||||
|
||||
if [ "$FLAG_V" == "true" ]; then V=-v; fi
|
||||
if [ "$FLAG_X" == "true" ]; then X=-x; fi
|
||||
if [ "$FLAG_RACE" == "true" ]; then R=-race; fi
|
||||
if [ "$FLAG_TAGS" != "" ]; then T=(--tags "$FLAG_TAGS"); fi
|
||||
if [ "$FLAG_LDFLAGS" != "" ]; then LD="$FLAG_LDFLAGS"; fi
|
||||
|
||||
if [ "$FLAG_BUILDMODE" != "" ] && [ "$FLAG_BUILDMODE" != "default" ]; then BM="--buildmode=$FLAG_BUILDMODE"; fi
|
||||
|
||||
# If no build targets were specified, inject a catch all wildcard
|
||||
if [ "$TARGETS" == "" ]; then
|
||||
TARGETS="./."
|
||||
fi
|
||||
|
||||
# Build for each requested platform individually
|
||||
for TARGET in $TARGETS; do
|
||||
# Split the target into platform and architecture
|
||||
XGOOS=`echo $TARGET | cut -d '/' -f 1`
|
||||
XGOARCH=`echo $TARGET | cut -d '/' -f 2`
|
||||
|
||||
# Check and build for Android targets
|
||||
if ([ $XGOOS == "." ] || [[ $XGOOS == android* ]]); then
|
||||
# Split the platform version and configure the linker options
|
||||
PLATFORM=`echo $XGOOS | cut -d '-' -f 2`
|
||||
if [ "$PLATFORM" == "" ] || [ "$PLATFORM" == "." ] || [ "$PLATFORM" == "android" ]; then
|
||||
PLATFORM=16 # Jelly Bean 4.0.0
|
||||
fi
|
||||
CGO_STATUS_IM="-D ANDROID_DEPLOYMENT"
|
||||
if [ "$PLATFORM" -ge 16 ]; then
|
||||
CGO_CCPIE="-fPIE"
|
||||
CGO_LDPIE="-fPIE"
|
||||
EXT_LDPIE="-extldflags=-pie"
|
||||
else
|
||||
unset CGO_CCPIE CGO_LDPIE EXT_LDPIE
|
||||
fi
|
||||
mkdir -p /build-android-aar
|
||||
|
||||
# Iterate over the requested architectures, bootstrap and build
|
||||
if [ $XGOARCH == "." ] || [ $XGOARCH == "arm" ] || [ $XGOARCH == "aar" ]; then
|
||||
if [ "$GO_VERSION" -lt 150 ]; then
|
||||
echo "Go version too low, skipping android-$PLATFORM/arm..."
|
||||
else
|
||||
# Include a linker workaround for pre Go 1.6 releases
|
||||
if [ "$GO_VERSION" -lt 160 ]; then
|
||||
EXT_LDAMD="-extldflags=-Wl,--allow-multiple-definition"
|
||||
fi
|
||||
|
||||
echo "Assembling toolchain for android-$PLATFORM/arm..."
|
||||
$ANDROID_NDK_ROOT/build/tools/make-standalone-toolchain.sh --ndk-dir=$ANDROID_NDK_ROOT --install-dir=/usr/$ANDROID_CHAIN_ARM --toolchain=$ANDROID_CHAIN_ARM --arch=arm > /dev/null 2>&1
|
||||
|
||||
echo "Bootstrapping android-$PLATFORM/arm..."
|
||||
CC=arm-linux-androideabi-gcc GOOS=android GOARCH=arm GOARM=7 CGO_ENABLED=1 CGO_CFLAGS="$CGO_CCPIE" CGO_LDFLAGS="$CGO_LDPIE" go install std
|
||||
|
||||
echo "Compiling for android-$PLATFORM/arm..."
|
||||
CC=arm-linux-androideabi-gcc CXX=arm-linux-androideabi-g++ HOST=arm-linux-androideabi PREFIX=/usr/$ANDROID_CHAIN_ARM/arm-linux-androideabi $BUILD_DEPS /deps ${DEPS_ARGS[@]}
|
||||
export PKG_CONFIG_PATH=/usr/$ANDROID_CHAIN_ARM/arm-linux-androideabi/lib/pkgconfig
|
||||
|
||||
if [ $XGOARCH == "." ] || [ $XGOARCH == "arm" ]; then
|
||||
CC=arm-linux-androideabi-gcc CXX=arm-linux-androideabi-g++ GOOS=android GOARCH=arm GOARM=7 CGO_ENABLED=1 CGO_CFLAGS="$CGO_CCPIE" CGO_CXXFLAGS="$CGO_CCPIE" CGO_LDFLAGS="$CGO_LDPIE" go get $V $X "${T[@]}" --ldflags="$V $LD" -d ./$PACK
|
||||
CGO_CFLAGS="-D ANDROID_DEPLOYMENT" CC=arm-linux-androideabi-gcc CXX=arm-linux-androideabi-g++ GOOS=android GOARCH=arm GOARM=7 CGO_ENABLED=1 CGO_CFLAGS="$CGO_CCPIE $CGO_STATUS_IM" CGO_CXXFLAGS="$CGO_CCPIE" CGO_LDFLAGS="$CGO_LDPIE" go build $V $X "${T[@]}" --ldflags="$V $EXT_LDPIE $EXT_LDAMD $LD" $BM -o "/build/$NAME-android-$PLATFORM-arm`extension android`" ./$PACK
|
||||
fi
|
||||
if [ $XGOARCH == "." ] || [ $XGOARCH == "aar" ]; then
|
||||
CC=arm-linux-androideabi-gcc CXX=arm-linux-androideabi-g++ GOOS=android GOARCH=arm GOARM=7 CGO_ENABLED=1 go get $V $X "${T[@]}" --ldflags="$V $LD" -d ./$PACK
|
||||
CC=arm-linux-androideabi-gcc CXX=arm-linux-androideabi-g++ GOOS=android GOARCH=arm GOARM=7 CGO_ENABLED=1 CGO_CFLAGS="$CGO_STATUS_IM" go build $V $X "${T[@]}" --ldflags="$V $EXT_LDAMD $LD" --buildmode=c-shared -o "/build-android-aar/$NAME-android-$PLATFORM-arm.so" ./$PACK
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if [ "$GO_VERSION" -lt 160 ]; then
|
||||
echo "Go version too low, skipping android-$PLATFORM/386,arm64..."
|
||||
else
|
||||
if [ "$PLATFORM" -ge 9 ] && ([ $XGOARCH == "." ] || [ $XGOARCH == "386" ] || [ $XGOARCH == "aar" ]); then
|
||||
echo "Assembling toolchain for android-$PLATFORM/386..."
|
||||
$ANDROID_NDK_ROOT/build/tools/make-standalone-toolchain.sh --ndk-dir=$ANDROID_NDK_ROOT --install-dir=/usr/$ANDROID_CHAIN_386 --toolchain=$ANDROID_CHAIN_386 --arch=x86 > /dev/null 2>&1
|
||||
|
||||
echo "Bootstrapping android-$PLATFORM/386..."
|
||||
CC=i686-linux-android-gcc GOOS=android GOARCH=386 CGO_ENABLED=1 CGO_CFLAGS="$CGO_CCPIE" CGO_LDFLAGS="$CGO_LDPIE" go install std
|
||||
|
||||
echo "Compiling for android-$PLATFORM/386..."
|
||||
CC=i686-linux-android-gcc CXX=i686-linux-android-g++ HOST=i686-linux-android PREFIX=/usr/$ANDROID_CHAIN_386/i686-linux-android $BUILD_DEPS /deps ${DEPS_ARGS[@]}
|
||||
export PKG_CONFIG_PATH=/usr/$ANDROID_CHAIN_386/i686-linux-android/lib/pkgconfig
|
||||
|
||||
if [ $XGOARCH == "." ] || [ $XGOARCH == "386" ]; then
|
||||
CC=i686-linux-android-gcc CXX=i686-linux-android-g++ GOOS=android GOARCH=386 CGO_ENABLED=1 CGO_CFLAGS="$CGO_CCPIE" CGO_CXXFLAGS="$CGO_CCPIE" CGO_LDFLAGS="$CGO_LDPIE" go get $V $X "${T[@]}" --ldflags="$V $LD" -d ./$PACK
|
||||
CC=i686-linux-android-gcc CXX=i686-linux-android-g++ GOOS=android GOARCH=386 CGO_ENABLED=1 CGO_CFLAGS="$CGO_CCPIE $CGO_STATUS_IM" CGO_CXXFLAGS="$CGO_CCPIE" CGO_LDFLAGS="$CGO_LDPIE" go build $V $X "${T[@]}" --ldflags="$V $EXT_LDPIE $LD" $BM -o "/build/$NAME-android-$PLATFORM-386`extension android`" ./$PACK
|
||||
fi
|
||||
if [ $XGOARCH == "." ] || [ $XGOARCH == "aar" ]; then
|
||||
CC=i686-linux-android-gcc CXX=i686-linux-android-g++ GOOS=android GOARCH=386 CGO_ENABLED=1 go get $V $X "${T[@]}" --ldflags="$V $LD" -d ./$PACK
|
||||
CC=i686-linux-android-gcc CXX=i686-linux-android-g++ GOOS=android GOARCH=386 CGO_ENABLED=1 CGO_CFLAGS="$CGO_STATUS_IM" go build $V $X "${T[@]}" --ldflags="$V $LD" --buildmode=c-shared -o "/build-android-aar/$NAME-android-$PLATFORM-386.so" ./$PACK
|
||||
fi
|
||||
fi
|
||||
if [ "$PLATFORM" -ge 21 ] && ([ $XGOARCH == "." ] || [ $XGOARCH == "arm64" ] || [ $XGOARCH == "aar" ]); then
|
||||
echo "Assembling toolchain for android-$PLATFORM/arm64..."
|
||||
$ANDROID_NDK_ROOT/build/tools/make-standalone-toolchain.sh --ndk-dir=$ANDROID_NDK_ROOT --install-dir=/usr/$ANDROID_CHAIN_ARM64 --toolchain=$ANDROID_CHAIN_ARM64 --arch=arm64 > /dev/null 2>&1
|
||||
|
||||
echo "Bootstrapping android-$PLATFORM/arm64..."
|
||||
CC=aarch64-linux-android-gcc GOOS=android GOARCH=arm64 CGO_ENABLED=1 CGO_CFLAGS="$CGO_CCPIE" CGO_LDFLAGS="$CGO_LDPIE" go install std
|
||||
|
||||
echo "Compiling for android-$PLATFORM/arm64..."
|
||||
CC=aarch64-linux-android-gcc CXX=aarch64-linux-android-g++ HOST=aarch64-linux-android PREFIX=/usr/$ANDROID_CHAIN_ARM64/aarch64-linux-android $BUILD_DEPS /deps ${DEPS_ARGS[@]}
|
||||
export PKG_CONFIG_PATH=/usr/$ANDROID_CHAIN_ARM64/aarch64-linux-android/lib/pkgconfig
|
||||
|
||||
if [ $XGOARCH == "." ] || [ $XGOARCH == "arm64" ]; then
|
||||
CC=aarch64-linux-android-gcc CXX=aarch64-linux-android-g++ GOOS=android GOARCH=arm64 CGO_ENABLED=1 CGO_CFLAGS="$CGO_CCPIE" CGO_CXXFLAGS="$CGO_CCPIE" CGO_LDFLAGS="$CGO_LDPIE" go get $V $X "${T[@]}" --ldflags="$V $LD" -d ./$PACK
|
||||
CC=aarch64-linux-android-gcc CXX=aarch64-linux-android-g++ GOOS=android GOARCH=arm64 CGO_ENABLED=1 CGO_CFLAGS="$CGO_CCPIE $CGO_STATUS_IM" CGO_CXXFLAGS="$CGO_CCPIE" CGO_LDFLAGS="$CGO_LDPIE" go build $V $X "${T[@]}" --ldflags="$V $EXT_LDPIE $LD" $BM -o "/build/$NAME-android-$PLATFORM-arm64`extension android`" ./$PACK
|
||||
fi
|
||||
if [ $XGOARCH == "." ] || [ $XGOARCH == "aar" ]; then
|
||||
CC=aarch64-linux-android-gcc CXX=aarch64-linux-android-g++ GOOS=android GOARCH=arm64 CGO_ENABLED=1 go get $V $X "${T[@]}" --ldflags="$V $LD" -d ./$PACK
|
||||
CC=aarch64-linux-android-gcc CXX=aarch64-linux-android-g++ GOOS=android GOARCH=arm64 CGO_ENABLED=1 CGO_CFLAGS="$CGO_STATUS_IM" go build $V $X "${T[@]}" --ldflags="$V $LD" --buildmode=c-shared -o "/build-android-aar/$NAME-android-$PLATFORM-arm64.so" ./$PACK
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
unset CGO_STATUS_IM # good to let that extra var go away
|
||||
# Assemble the Android Archive from the built shared libraries
|
||||
if [ $XGOARCH == "." ] || [ $XGOARCH == "aar" ]; then
|
||||
title=${NAME^}
|
||||
archive=/build/$NAME-android-$PLATFORM-aar
|
||||
bundle=/build/$NAME-android-$PLATFORM.aar
|
||||
|
||||
# Generate the Java import path based on the Go one
|
||||
package=`go list ./$PACK | tr '-' '_'`
|
||||
package=$(for p in `echo ${package//\// }`; do echo $p | awk 'BEGIN{FS="."}{for (i=NF; i>0; i--){printf "%s.", $i;}}'; done | sed 's/.$//')
|
||||
package=${package%.*}
|
||||
|
||||
# Create a fresh empty Android archive
|
||||
rm -rf $archive $bundle
|
||||
mkdir -p $archive
|
||||
|
||||
echo -e "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\" package=\"$package\">\n <uses-sdk android:minSdkVersion=\"$PLATFORM\"/>\n</manifest>" > $archive/AndroidManifest.xml
|
||||
mkdir -p $archive/res
|
||||
touch $archive/R.txt
|
||||
|
||||
# Generate the JNI wrappers automatically with SWIG
|
||||
jni=`mktemp -d`
|
||||
header=`find /build-android-aar | grep '\.h$' | head -n 1`
|
||||
if [ "$header" == "" ]; then
|
||||
echo "No API C header specified, skipping android-$PLATFORM/aar..."
|
||||
else
|
||||
cp $header $jni/$NAME.h
|
||||
sed -i -e 's|__complex|complex|g' $jni/$NAME.h
|
||||
sed -i -e 's|_Complex|complex|g' $jni/$NAME.h
|
||||
echo -e "%module $title\n%{\n#include \"$NAME.h\"\n%}\n%pragma(java) jniclasscode=%{\nstatic {\nSystem.loadLibrary(\"$NAME\");\n}\n%}\n%include \"$NAME.h\"" > $jni/$NAME.i
|
||||
|
||||
mkdir -p $jni/${package//.//}
|
||||
swig -java -package $package -outdir $jni/${package//.//} $jni/$NAME.i
|
||||
|
||||
# Assemble the Go static libraries and the JNI interface into shared libraries
|
||||
for lib in `find /build-android-aar | grep '\.so$'`; do
|
||||
if [[ "$lib" = *-arm.so ]]; then cc=arm-linux-androideabi-gcc; abi="armeabi-v7a"; fi
|
||||
if [[ "$lib" = *-arm64.so ]]; then cc=aarch64-linux-android-gcc; abi="arm64-v8a"; fi
|
||||
if [[ "$lib" = *-386.so ]]; then cc=i686-linux-android-gcc; abi="x86"; fi
|
||||
|
||||
mkdir -p $archive/jni/$abi
|
||||
cp ${lib%.*}.h $jni/${NAME}.h
|
||||
cp $lib $archive/jni/$abi/lib${NAME}raw.so
|
||||
(cd $archive/jni/$abi && $cc -shared -fPIC -o lib${NAME}.so -I"$ANDROID_NDK_LIBC/include" -I"$ANDROID_NDK_LIBC/libs/$abi/include" -I"$jni" lib${NAME}raw.so $jni/${NAME}_wrap.c)
|
||||
done
|
||||
|
||||
# Compile the Java wrapper and assemble into a .jar file
|
||||
mkdir -p $jni/build
|
||||
javac -target 1.7 -source 1.7 -cp . -d $jni/build $jni/${package//.//}/*.java
|
||||
(cd $jni/build && jar cvf $archive/classes.jar *)
|
||||
|
||||
# Finally assemble the archive contents into an .aar and clean up
|
||||
(cd $archive && zip -r $bundle *)
|
||||
rm -rf $jni $archive
|
||||
fi
|
||||
|
||||
# Fix up permissions on bundle file
|
||||
chown $UID:$GID $bundle
|
||||
fi
|
||||
# Clean up the android builds, toolchains and runtimes
|
||||
rm -rf /build-android-aar
|
||||
rm -rf /usr/local/go/pkg/android_*
|
||||
rm -rf /usr/$ANDROID_CHAIN_ARM /usr/$ANDROID_CHAIN_ARM64 /usr/$ANDROID_CHAIN_386
|
||||
fi
|
||||
# Check and build for Linux targets
|
||||
if ([ $XGOOS == "." ] || [ $XGOOS == "linux" ]) && ([ $XGOARCH == "." ] || [ $XGOARCH == "amd64" ]); then
|
||||
echo "Compiling for linux/amd64..."
|
||||
HOST=x86_64-linux PREFIX=/usr/local $BUILD_DEPS /deps ${DEPS_ARGS[@]}
|
||||
GOOS=linux GOARCH=amd64 CGO_ENABLED=1 go get $V $X "${T[@]}" --ldflags="$V $LD" -d ./$PACK
|
||||
GOOS=linux GOARCH=amd64 CGO_ENABLED=1 go build $V $X "${T[@]}" --ldflags="$V $LD" $R $BM -o "/build/$NAME-linux-amd64$R`extension linux`" ./$PACK
|
||||
fi
|
||||
if ([ $XGOOS == "." ] || [ $XGOOS == "linux" ]) && ([ $XGOARCH == "." ] || [ $XGOARCH == "386" ]); then
|
||||
echo "Compiling for linux/386..."
|
||||
HOST=i686-linux PREFIX=/usr/local $BUILD_DEPS /deps ${DEPS_ARGS[@]}
|
||||
GOOS=linux GOARCH=386 CGO_ENABLED=1 go get $V $X "${T[@]}" --ldflags="$V $LD" -d ./$PACK
|
||||
GOOS=linux GOARCH=386 CGO_ENABLED=1 go build $V $X "${T[@]}" --ldflags="$V $LD" $BM -o "/build/$NAME-linux-386`extension linux`" ./$PACK
|
||||
fi
|
||||
if ([ $XGOOS == "." ] || [ $XGOOS == "linux" ]) && ([ $XGOARCH == "." ] || [ $XGOARCH == "arm" ] || [ $XGOARCH == "arm-5" ]); then
|
||||
if [ "$GO_VERSION" -ge 150 ]; then
|
||||
echo "Bootstrapping linux/arm-5..."
|
||||
CC=arm-linux-gnueabi-gcc-5 GOOS=linux GOARCH=arm GOARM=5 CGO_ENABLED=1 CGO_CFLAGS="-march=armv5" CGO_CXXFLAGS="-march=armv5" go install std
|
||||
fi
|
||||
echo "Compiling for linux/arm-5..."
|
||||
CC=arm-linux-gnueabi-gcc-5 CXX=arm-linux-gnueabi-g++-5 HOST=arm-linux-gnueabi PREFIX=/usr/arm-linux-gnueabi CFLAGS="-march=armv5" CXXFLAGS="-march=armv5" $BUILD_DEPS /deps ${DEPS_ARGS[@]}
|
||||
export PKG_CONFIG_PATH=/usr/arm-linux-gnueabi/lib/pkgconfig
|
||||
|
||||
CC=arm-linux-gnueabi-gcc-5 CXX=arm-linux-gnueabi-g++-5 GOOS=linux GOARCH=arm GOARM=5 CGO_ENABLED=1 CGO_CFLAGS="-march=armv5" CGO_CXXFLAGS="-march=armv5" go get $V $X "${T[@]}" --ldflags="$V $LD" -d ./$PACK
|
||||
CC=arm-linux-gnueabi-gcc-5 CXX=arm-linux-gnueabi-g++-5 GOOS=linux GOARCH=arm GOARM=5 CGO_ENABLED=1 CGO_CFLAGS="-march=armv5" CGO_CXXFLAGS="-march=armv5" go build $V $X "${T[@]}" --ldflags="$V $LD" $BM -o "/build/$NAME-linux-arm-5`extension linux`" ./$PACK
|
||||
if [ "$GO_VERSION" -ge 150 ]; then
|
||||
echo "Cleaning up Go runtime for linux/arm-5..."
|
||||
rm -rf /usr/local/go/pkg/linux_arm
|
||||
fi
|
||||
fi
|
||||
if ([ $XGOOS == "." ] || [ $XGOOS == "linux" ]) && ([ $XGOARCH == "." ] || [ $XGOARCH == "arm-6" ]); then
|
||||
if [ "$GO_VERSION" -lt 150 ]; then
|
||||
echo "Go version too low, skipping linux/arm-6..."
|
||||
else
|
||||
echo "Bootstrapping linux/arm-6..."
|
||||
CC=arm-linux-gnueabi-gcc-5 GOOS=linux GOARCH=arm GOARM=6 CGO_ENABLED=1 CGO_CFLAGS="-march=armv6" CGO_CXXFLAGS="-march=armv6" go install std
|
||||
|
||||
echo "Compiling for linux/arm-6..."
|
||||
CC=arm-linux-gnueabi-gcc-5 CXX=arm-linux-gnueabi-g++-5 HOST=arm-linux-gnueabi PREFIX=/usr/arm-linux-gnueabi CFLAGS="-march=armv6" CXXFLAGS="-march=armv6" $BUILD_DEPS /deps ${DEPS_ARGS[@]}
|
||||
export PKG_CONFIG_PATH=/usr/arm-linux-gnueabi/lib/pkgconfig
|
||||
|
||||
CC=arm-linux-gnueabi-gcc-5 CXX=arm-linux-gnueabi-g++-5 GOOS=linux GOARCH=arm GOARM=6 CGO_ENABLED=1 CGO_CFLAGS="-march=armv6" CGO_CXXFLAGS="-march=armv6" go get $V $X "${T[@]}" --ldflags="$V $LD" -d ./$PACK
|
||||
CC=arm-linux-gnueabi-gcc-5 CXX=arm-linux-gnueabi-g++-5 GOOS=linux GOARCH=arm GOARM=6 CGO_ENABLED=1 CGO_CFLAGS="-march=armv6" CGO_CXXFLAGS="-march=armv6" go build $V $X "${T[@]}" --ldflags="$V $LD" $BM -o "/build/$NAME-linux-arm-6`extension linux`" ./$PACK
|
||||
|
||||
echo "Cleaning up Go runtime for linux/arm-6..."
|
||||
rm -rf /usr/local/go/pkg/linux_arm
|
||||
fi
|
||||
fi
|
||||
if ([ $XGOOS == "." ] || [ $XGOOS == "linux" ]) && ([ $XGOARCH == "." ] || [ $XGOARCH == "arm-7" ]); then
|
||||
if [ "$GO_VERSION" -lt 150 ]; then
|
||||
echo "Go version too low, skipping linux/arm-7..."
|
||||
else
|
||||
echo "Bootstrapping linux/arm-7..."
|
||||
CC=arm-linux-gnueabihf-gcc-5 GOOS=linux GOARCH=arm GOARM=7 CGO_ENABLED=1 CGO_CFLAGS="-march=armv7-a" CGO_CXXFLAGS="-march=armv7-a" go install std
|
||||
|
||||
echo "Compiling for linux/arm-7..."
|
||||
CC=arm-linux-gnueabihf-gcc-5 CXX=arm-linux-gnueabihf-g++-5 HOST=arm-linux-gnueabihf PREFIX=/usr/arm-linux-gnueabihf CFLAGS="-march=armv7-a -fPIC" CXXFLAGS="-march=armv7-a -fPIC" $BUILD_DEPS /deps ${DEPS_ARGS[@]}
|
||||
export PKG_CONFIG_PATH=/usr/arm-linux-gnueabihf/lib/pkgconfig
|
||||
|
||||
CC=arm-linux-gnueabihf-gcc-5 CXX=arm-linux-gnueabihf-g++-5 GOOS=linux GOARCH=arm GOARM=7 CGO_ENABLED=1 CGO_CFLAGS="-march=armv7-a -fPIC" CGO_CXXFLAGS="-march=armv7-a -fPIC" go get $V $X "${T[@]}" --ldflags="$V $LD" -d ./$PACK
|
||||
CC=arm-linux-gnueabihf-gcc-5 CXX=arm-linux-gnueabihf-g++-5 GOOS=linux GOARCH=arm GOARM=7 CGO_ENABLED=1 CGO_CFLAGS="-march=armv7-a -fPIC" CGO_CXXFLAGS="-march=armv7-a -fPIC" go build $V $X "${T[@]}" --ldflags="$V $LD" $BM -o "/build/$NAME-linux-arm-7`extension linux`" ./$PACK
|
||||
|
||||
echo "Cleaning up Go runtime for linux/arm-7..."
|
||||
rm -rf /usr/local/go/pkg/linux_arm
|
||||
fi
|
||||
fi
|
||||
if ([ $XGOOS == "." ] || [ $XGOOS == "linux" ]) && ([ $XGOARCH == "." ] || [ $XGOARCH == "arm64" ]); then
|
||||
if [ "$GO_VERSION" -lt 150 ]; then
|
||||
echo "Go version too low, skipping linux/arm64..."
|
||||
else
|
||||
echo "Compiling for linux/arm64..."
|
||||
CC=aarch64-linux-gnu-gcc-5 CXX=aarch64-linux-gnu-g++-5 HOST=aarch64-linux-gnu PREFIX=/usr/aarch64-linux-gnu $BUILD_DEPS /deps ${DEPS_ARGS[@]}
|
||||
export PKG_CONFIG_PATH=/usr/aarch64-linux-gnu/lib/pkgconfig
|
||||
|
||||
CC=aarch64-linux-gnu-gcc-5 CXX=aarch64-linux-gnu-g++-5 GOOS=linux GOARCH=arm64 CGO_ENABLED=1 go get $V $X "${T[@]}" --ldflags="$V $LD" -d ./$PACK
|
||||
CC=aarch64-linux-gnu-gcc-5 CXX=aarch64-linux-gnu-g++-5 GOOS=linux GOARCH=arm64 CGO_ENABLED=1 go build $V $X "${T[@]}" --ldflags="$V $LD" $BM -o "/build/$NAME-linux-arm64`extension linux`" ./$PACK
|
||||
fi
|
||||
fi
|
||||
if ([ $XGOOS == "." ] || [ $XGOOS == "linux" ]) && ([ $XGOARCH == "." ] || [ $XGOARCH == "mips64" ]); then
|
||||
if [ "$GO_VERSION" -lt 170 ]; then
|
||||
echo "Go version too low, skipping linux/mips64..."
|
||||
else
|
||||
echo "Compiling for linux/mips64..."
|
||||
CC=mips64-linux-gnuabi64-gcc-5 CXX=mips64-linux-gnuabi64-g++-5 HOST=mips64-linux-gnuabi64 PREFIX=/usr/mips64-linux-gnuabi64 $BUILD_DEPS /deps ${DEPS_ARGS[@]}
|
||||
export PKG_CONFIG_PATH=/usr/mips64-linux-gnuabi64/lib/pkgconfig
|
||||
|
||||
CC=mips64-linux-gnuabi64-gcc-5 CXX=mips64-linux-gnuabi64-g++-5 GOOS=linux GOARCH=mips64 CGO_ENABLED=1 go get $V $X "${T[@]}" --ldflags="$V $LD" -d ./$PACK
|
||||
CC=mips64-linux-gnuabi64-gcc-5 CXX=mips64-linux-gnuabi64-g++-5 GOOS=linux GOARCH=mips64 CGO_ENABLED=1 go build $V $X "${T[@]}" --ldflags="$V $LD" $BM -o "/build/$NAME-linux-mips64`extension linux`" ./$PACK
|
||||
fi
|
||||
fi
|
||||
if ([ $XGOOS == "." ] || [ $XGOOS == "linux" ]) && ([ $XGOARCH == "." ] || [ $XGOARCH == "mips64le" ]); then
|
||||
if [ "$GO_VERSION" -lt 170 ]; then
|
||||
echo "Go version too low, skipping linux/mips64le..."
|
||||
else
|
||||
echo "Compiling for linux/mips64le..."
|
||||
CC=mips64el-linux-gnuabi64-gcc-5 CXX=mips64el-linux-gnuabi64-g++-5 HOST=mips64el-linux-gnuabi64 PREFIX=/usr/mips64el-linux-gnuabi64 $BUILD_DEPS /deps ${DEPS_ARGS[@]}
|
||||
export PKG_CONFIG_PATH=/usr/mips64le-linux-gnuabi64/lib/pkgconfig
|
||||
|
||||
CC=mips64el-linux-gnuabi64-gcc-5 CXX=mips64el-linux-gnuabi64-g++-5 GOOS=linux GOARCH=mips64le CGO_ENABLED=1 go get $V $X "${T[@]}" --ldflags="$V $LD" -d ./$PACK
|
||||
CC=mips64el-linux-gnuabi64-gcc-5 CXX=mips64el-linux-gnuabi64-g++-5 GOOS=linux GOARCH=mips64le CGO_ENABLED=1 go build $V $X "${T[@]}" --ldflags="$V $LD" $BM -o "/build/$NAME-linux-mips64le`extension linux`" ./$PACK
|
||||
fi
|
||||
fi
|
||||
# Check and build for Windows targets
|
||||
if [ $XGOOS == "." ] || [[ $XGOOS == windows* ]]; then
|
||||
# Split the platform version and configure the Windows NT version
|
||||
PLATFORM=`echo $XGOOS | cut -d '-' -f 2`
|
||||
if [ "$PLATFORM" == "" ] || [ "$PLATFORM" == "." ] || [ "$PLATFORM" == "windows" ]; then
|
||||
PLATFORM=4.0 # Windows NT
|
||||
fi
|
||||
|
||||
MAJOR=`echo $PLATFORM | cut -d '.' -f 1`
|
||||
if [ "${PLATFORM/.}" != "$PLATFORM" ] ; then
|
||||
MINOR=`echo $PLATFORM | cut -d '.' -f 2`
|
||||
fi
|
||||
CGO_NTDEF="-D_WIN32_WINNT=0x`printf "%02d" $MAJOR``printf "%02d" $MINOR`"
|
||||
|
||||
# Build the requested windows binaries
|
||||
if [ $XGOARCH == "." ] || [ $XGOARCH == "amd64" ]; then
|
||||
echo "Compiling for windows-$PLATFORM/amd64..."
|
||||
CC=x86_64-w64-mingw32-gcc-posix CXX=x86_64-w64-mingw32-g++-posix HOST=x86_64-w64-mingw32 PREFIX=/usr/x86_64-w64-mingw32 $BUILD_DEPS /deps ${DEPS_ARGS[@]}
|
||||
export PKG_CONFIG_PATH=/usr/x86_64-w64-mingw32/lib/pkgconfig
|
||||
|
||||
CC=x86_64-w64-mingw32-gcc-posix CXX=x86_64-w64-mingw32-g++-posix GOOS=windows GOARCH=amd64 CGO_ENABLED=1 CGO_CFLAGS="$CGO_NTDEF" CGO_CXXFLAGS="$CGO_NTDEF" go get $V $X "${T[@]}" --ldflags="$V $LD" -d ./$PACK
|
||||
CC=x86_64-w64-mingw32-gcc-posix CXX=x86_64-w64-mingw32-g++-posix GOOS=windows GOARCH=amd64 CGO_ENABLED=1 CGO_CFLAGS="$CGO_NTDEF" CGO_CXXFLAGS="$CGO_NTDEF" go build $V $X "${T[@]}" --ldflags="$V $LD" $R $BM -o "/build/$NAME-windows-$PLATFORM-amd64$R`extension windows`" ./$PACK
|
||||
fi
|
||||
if [ $XGOARCH == "." ] || [ $XGOARCH == "386" ]; then
|
||||
echo "Compiling for windows-$PLATFORM/386..."
|
||||
CC=i686-w64-mingw32-gcc-posix CXX=i686-w64-mingw32-g++-posix HOST=i686-w64-mingw32 PREFIX=/usr/i686-w64-mingw32 $BUILD_DEPS /deps ${DEPS_ARGS[@]}
|
||||
export PKG_CONFIG_PATH=/usr/i686-w64-mingw32/lib/pkgconfig
|
||||
|
||||
CC=i686-w64-mingw32-gcc-posix CXX=i686-w64-mingw32-g++-posix GOOS=windows GOARCH=386 CGO_ENABLED=1 CGO_CFLAGS="$CGO_NTDEF" CGO_CXXFLAGS="$CGO_NTDEF" go get $V $X "${T[@]}" --ldflags="$V $LD" -d ./$PACK
|
||||
CC=i686-w64-mingw32-gcc-posix CXX=i686-w64-mingw32-g++-posix GOOS=windows GOARCH=386 CGO_ENABLED=1 CGO_CFLAGS="$CGO_NTDEF" CGO_CXXFLAGS="$CGO_NTDEF" go build $V $X "${T[@]}" --ldflags="$V $LD" $BM -o "/build/$NAME-windows-$PLATFORM-386`extension windows`" ./$PACK
|
||||
fi
|
||||
fi
|
||||
# Check and build for OSX targets
|
||||
if [ $XGOOS == "." ] || [[ $XGOOS == darwin* ]]; then
|
||||
# Split the platform version and configure the deployment target
|
||||
PLATFORM=`echo $XGOOS | cut -d '-' -f 2`
|
||||
if [ "$PLATFORM" == "" ] || [ "$PLATFORM" == "." ] || [ "$PLATFORM" == "darwin" ]; then
|
||||
PLATFORM=10.6 # OS X Snow Leopard
|
||||
fi
|
||||
export MACOSX_DEPLOYMENT_TARGET=$PLATFORM
|
||||
|
||||
# Strip symbol table below Go 1.6 to prevent DWARF issues
|
||||
LDSTRIP=""
|
||||
if [ "$GO_VERSION" -lt 160 ]; then
|
||||
LDSTRIP="-s"
|
||||
fi
|
||||
# Build the requested darwin binaries
|
||||
if [ $XGOARCH == "." ] || [ $XGOARCH == "amd64" ]; then
|
||||
echo "Compiling for darwin-$PLATFORM/amd64..."
|
||||
CC=o64-clang CXX=o64-clang++ HOST=x86_64-apple-darwin15 PREFIX=/usr/local $BUILD_DEPS /deps ${DEPS_ARGS[@]}
|
||||
CC=o64-clang CXX=o64-clang++ GOOS=darwin GOARCH=amd64 CGO_ENABLED=1 go get $V $X "${T[@]}" --ldflags="$LDSTRIP $V $LD" -d ./$PACK
|
||||
CC=o64-clang CXX=o64-clang++ GOOS=darwin GOARCH=amd64 CGO_ENABLED=1 go build $V $X "${T[@]}" --ldflags="$LDSTRIP $V $LD" $R $BM -o "/build/$NAME-darwin-$PLATFORM-amd64$R`extension darwin`" ./$PACK
|
||||
fi
|
||||
if [ $XGOARCH == "." ] || [ $XGOARCH == "386" ]; then
|
||||
echo "Compiling for darwin-$PLATFORM/386..."
|
||||
CC=o32-clang CXX=o32-clang++ HOST=i386-apple-darwin15 PREFIX=/usr/local $BUILD_DEPS /deps ${DEPS_ARGS[@]}
|
||||
CC=o32-clang CXX=o32-clang++ GOOS=darwin GOARCH=386 CGO_ENABLED=1 go get $V $X "${T[@]}" --ldflags="$LDSTRIP $V $LD" -d ./$PACK
|
||||
CC=o32-clang CXX=o32-clang++ GOOS=darwin GOARCH=386 CGO_ENABLED=1 go build $V $X "${T[@]}" --ldflags="$LDSTRIP $V $LD" $BM -o "/build/$NAME-darwin-$PLATFORM-386`extension darwin`" ./$PACK
|
||||
fi
|
||||
# Remove any automatically injected deployment target vars
|
||||
unset MACOSX_DEPLOYMENT_TARGET
|
||||
fi
|
||||
# Check and build for iOS targets
|
||||
if [ $XGOOS == "." ] || [[ $XGOOS == ios* ]]; then
|
||||
# Split the platform version and configure the deployment target
|
||||
PLATFORM=`echo $XGOOS | cut -d '-' -f 2`
|
||||
if [ "$PLATFORM" == "" ] || [ "$PLATFORM" == "." ] || [ "$PLATFORM" == "ios" ]; then
|
||||
PLATFORM=5.0 # first iPad and upwards
|
||||
fi
|
||||
export IPHONEOS_DEPLOYMENT_TARGET=$PLATFORM
|
||||
|
||||
# Build the requested iOS binaries
|
||||
if [ "$GO_VERSION" -lt 150 ]; then
|
||||
echo "Go version too low, skipping ios..."
|
||||
else
|
||||
# Add the 'ios' tag to all builds, otherwise the std libs will fail
|
||||
if [ "$FLAG_TAGS" != "" ]; then
|
||||
IOSTAGS=(--tags "ios $FLAG_TAGS")
|
||||
else
|
||||
IOSTAGS=(--tags ios)
|
||||
fi
|
||||
mkdir -p /build-ios-fw
|
||||
|
||||
# Strip symbol table below Go 1.6 to prevent DWARF issues
|
||||
LDSTRIP=""
|
||||
if [ "$GO_VERSION" -lt 160 ]; then
|
||||
LDSTRIP="-s"
|
||||
fi
|
||||
CGO_STATUS_IM="-D IOS_DEPLOYMENT"
|
||||
# Cross compile to all available iOS and simulator platforms
|
||||
if [ -d "$IOS_NDK_ARM_7" ] && ([ $XGOARCH == "." ] || [ $XGOARCH == "arm-7" ] || [ $XGOARCH == "framework" ]); then
|
||||
echo "Bootstrapping ios-$PLATFORM/arm-7..."
|
||||
export PATH=$IOS_NDK_ARM_7/bin:$PATH
|
||||
GOOS=darwin GOARCH=arm GOARM=7 CGO_ENABLED=1 CC=arm-apple-darwin11-clang go install --tags ios std
|
||||
|
||||
echo "Compiling for ios-$PLATFORM/arm-7..."
|
||||
CC=arm-apple-darwin11-clang CXX=arm-apple-darwin11-clang++ HOST=arm-apple-darwin11 PREFIX=/usr/local $BUILD_DEPS /deps ${DEPS_ARGS[@]}
|
||||
CC=arm-apple-darwin11-clang CXX=arm-apple-darwin11-clang++ GOOS=darwin GOARCH=arm GOARM=7 CGO_ENABLED=1 go get $V $X "${IOSTAGS[@]}" --ldflags="$V $LD" -d ./$PACK
|
||||
if [ $XGOARCH == "." ] || [ $XGOARCH == "arm-7" ]; then
|
||||
CC=arm-apple-darwin11-clang CXX=arm-apple-darwin11-clang++ GOOS=darwin GOARCH=arm GOARM=7 CGO_ENABLED=1 go build $V $X "${IOSTAGS[@]}" --ldflags="$LDSTRIP $V $LD" $BM -o "/build/$NAME-ios-$PLATFORM-armv7`extension darwin`" ./$PACK
|
||||
fi
|
||||
if [ $XGOARCH == "." ] || [ $XGOARCH == "framework" ]; then
|
||||
CC=arm-apple-darwin11-clang CXX=arm-apple-darwin11-clang++ GOOS=darwin GOARCH=arm GOARM=7 CGO_ENABLED=1 CGO_CFLAGS="$CGO_STATUS_IM" go build $V $X "${IOSTAGS[@]}" --ldflags="$V $LD" --buildmode=c-archive -o "/build-ios-fw/$NAME-ios-$PLATFORM-armv7.a" ./$PACK
|
||||
fi
|
||||
echo "Cleaning up Go runtime for ios-$PLATFORM/arm-7..."
|
||||
rm -rf /usr/local/go/pkg/darwin_arm
|
||||
fi
|
||||
if [ -d "$IOS_NDK_ARM64" ] && ([ $XGOARCH == "." ] || [ $XGOARCH == "arm64" ] || [ $XGOARCH == "framework" ]); then
|
||||
echo "Bootstrapping ios-$PLATFORM/arm64..."
|
||||
export PATH=$IOS_NDK_ARM64/bin:$PATH
|
||||
GOOS=darwin GOARCH=arm64 CGO_ENABLED=1 CC=arm-apple-darwin11-clang go install --tags ios std
|
||||
|
||||
echo "Compiling for ios-$PLATFORM/arm64..."
|
||||
CC=arm-apple-darwin11-clang CXX=arm-apple-darwin11-clang++ HOST=arm-apple-darwin11 PREFIX=/usr/local $BUILD_DEPS /deps ${DEPS_ARGS[@]}
|
||||
CC=arm-apple-darwin11-clang CXX=arm-apple-darwin11-clang++ GOOS=darwin GOARCH=arm64 CGO_ENABLED=1 go get $V $X "${IOSTAGS[@]}" --ldflags="$V $LD" -d ./$PACK
|
||||
if [ $XGOARCH == "." ] || [ $XGOARCH == "arm64" ]; then
|
||||
CC=arm-apple-darwin11-clang CXX=arm-apple-darwin11-clang++ GOOS=darwin GOARCH=arm64 CGO_ENABLED=1 CGO_CFLAGS="$CGO_STATUS_IM" go build $V $X "${IOSTAGS[@]}" --ldflags="$LDSTRIP $V $LD" $BM -o "/build/$NAME-ios-$PLATFORM-arm64`extension darwin`" ./$PACK
|
||||
fi
|
||||
if [ $XGOARCH == "." ] || [ $XGOARCH == "framework" ]; then
|
||||
CC=arm-apple-darwin11-clang CXX=arm-apple-darwin11-clang++ GOOS=darwin GOARCH=arm64 CGO_ENABLED=1 CGO_CFLAGS="$CGO_STATUS_IM" go build $V $X "${IOSTAGS[@]}" --ldflags="$V $LD" --buildmode=c-archive -o "/build-ios-fw/$NAME-ios-$PLATFORM-arm64.a" ./$PACK
|
||||
fi
|
||||
echo "Cleaning up Go runtime for ios-$PLATFORM/arm64..."
|
||||
rm -rf /usr/local/go/pkg/darwin_arm64
|
||||
fi
|
||||
if [ -d "$IOS_SIM_NDK_AMD64" ] && ([ $XGOARCH == "." ] || [ $XGOARCH == "amd64" ] || [ $XGOARCH == "framework" ]); then
|
||||
echo "Bootstrapping ios-$PLATFORM/amd64..."
|
||||
export PATH=$IOS_SIM_NDK_AMD64/bin:$PATH
|
||||
mv /usr/local/go/pkg/darwin_amd64 /usr/local/go/pkg/darwin_amd64_bak
|
||||
GOOS=darwin GOARCH=amd64 CGO_ENABLED=1 CC=arm-apple-darwin11-clang go install --tags ios std
|
||||
|
||||
echo "Compiling for ios-$PLATFORM/amd64..."
|
||||
CC=arm-apple-darwin11-clang CXX=arm-apple-darwin11-clang++ HOST=arm-apple-darwin11 PREFIX=/usr/local $BUILD_DEPS /deps ${DEPS_ARGS[@]}
|
||||
CC=arm-apple-darwin11-clang CXX=arm-apple-darwin11-clang++ GOOS=darwin GOARCH=amd64 CGO_ENABLED=1 go get $V $X "${IOSTAGS[@]}" --ldflags="$V $LD" -d ./$PACK
|
||||
if [ $XGOARCH == "." ] || [ $XGOARCH == "amd64" ]; then
|
||||
CC=arm-apple-darwin11-clang CXX=arm-apple-darwin11-clang++ GOOS=darwin GOARCH=amd64 CGO_ENABLED=1 CGO_CFLAGS="$CGO_STATUS_IM" go build $V $X "${IOSTAGS[@]}" --ldflags="$LDSTRIP $V $LD" $BM -o "/build/$NAME-ios-$PLATFORM-x86_64`extension darwin`" ./$PACK
|
||||
fi
|
||||
if [ $XGOARCH == "." ] || [ $XGOARCH == "framework" ]; then
|
||||
CC=arm-apple-darwin11-clang CXX=arm-apple-darwin11-clang++ GOOS=darwin GOARCH=amd64 CGO_ENABLED=1 CGO_CFLAGS="$CGO_STATUS_IM" go build $V $X "${IOSTAGS[@]}" --ldflags="$V $LD" --buildmode=c-archive -o "/build-ios-fw/$NAME-ios-$PLATFORM-x86_64.a" ./$PACK
|
||||
fi
|
||||
echo "Cleaning up Go runtime for ios-$PLATFORM/amd64..."
|
||||
rm -rf /usr/local/go/pkg/darwin_amd64
|
||||
mv /usr/local/go/pkg/darwin_amd64_bak /usr/local/go/pkg/darwin_amd64
|
||||
fi
|
||||
unset CGO_STATUS_IM
|
||||
# Assemble the iOS framework from the built binaries
|
||||
if [ $XGOARCH == "." ] || [ $XGOARCH == "framework" ]; then
|
||||
title=${NAME^}
|
||||
framework=/build/$NAME-ios-$PLATFORM-framework/$title.framework
|
||||
|
||||
rm -rf $framework
|
||||
mkdir -p $framework/Versions/A
|
||||
(cd $framework/Versions && ln -nsf A Current)
|
||||
|
||||
arches=()
|
||||
for lib in `ls /build-ios-fw | grep -e '\.a$'`; do
|
||||
arches+=("-arch" "`echo ${lib##*-} | cut -d '.' -f 1`" "/build-ios-fw/$lib")
|
||||
done
|
||||
arm-apple-darwin11-lipo -create "${arches[@]}" -o $framework/Versions/A/$title
|
||||
arm-apple-darwin11-ranlib $framework/Versions/A/$title
|
||||
(cd $framework && ln -nsf Versions/A/$title $title)
|
||||
|
||||
mkdir -p $framework/Versions/A/Headers
|
||||
for header in `ls /build-ios-fw | grep -e '\.h$'`; do
|
||||
cp -f /build-ios-fw/$header $framework/Versions/A/Headers/$title.h
|
||||
done
|
||||
(cd $framework && ln -nsf Versions/A/Headers Headers)
|
||||
|
||||
echo "Patching Statusgo.h to work correctly on any arch (32bit, 64bit)"
|
||||
(cd $framework && perl -i -p0e 's/(\/\*\n\s*static assertion[\s\n\r\S+]+)(typedef char _check_for[^;]+;)/\1#ifdef __LP64__\ntypedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64\/8 ? 1:-1];\n#else\ntypedef char _check_for_32_bit_pointer_matching_GoInt[sizeof(void*)==32\/8 ? 1:-1];\n#endif/igm' Headers/Statusgo.h)
|
||||
|
||||
mkdir -p $framework/Versions/A/Resources
|
||||
echo -e "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n</dict>\n</plist>" > $framework/Versions/A/Resources/Info.plist
|
||||
(cd $framework && ln -nsf Versions/A/Resources Resources)
|
||||
|
||||
mkdir -p $framework/Versions/A/Modules
|
||||
echo -e "framework module \"$title\" {\n header \"$title.h\"\n export *\n}" > $framework/Versions/A/Modules/module.modulemap
|
||||
(cd $framework && ln -nsf Versions/A/Modules Modules)
|
||||
|
||||
# Fix up permissions on bundle file
|
||||
chown $UID:$GID /build/$NAME-ios-$PLATFORM-framework
|
||||
chmod 777 -R /build/$NAME-ios-$PLATFORM-framework
|
||||
fi
|
||||
rm -rf /build-ios-fw
|
||||
fi
|
||||
# Remove any automatically injected deployment target vars
|
||||
unset IPHONEOS_DEPLOYMENT_TARGET
|
||||
fi
|
||||
done
|
||||
|
||||
# Clean up any leftovers for subsequent build invocations
|
||||
echo "Cleaning up build environment..."
|
||||
rm -rf /deps
|
||||
|
||||
for dir in `ls /usr/local`; do
|
||||
keep=0
|
||||
|
||||
# Check against original folder contents
|
||||
for old in $USR_LOCAL_CONTENTS; do
|
||||
if [ "$old" == "$dir" ]; then
|
||||
keep=1
|
||||
fi
|
||||
done
|
||||
# Delete anything freshly generated
|
||||
if [ "$keep" == "0" ]; then
|
||||
rm -rf "/usr/local/$dir"
|
||||
fi
|
||||
done
|
|
@ -1,20 +0,0 @@
|
|||
FROM statusteam/xgo:1.10.x
|
||||
|
||||
# ios installer doesn't work with the default tar binary in Docker
|
||||
# (divan: I stole this solution here: https://github.com/coreos/bugs/issues/1095#issuecomment-350574389)
|
||||
# https://github.com/moby/moby/issues/19647
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends bsdtar \
|
||||
&& apt-get clean \
|
||||
&& cp $(which tar) $(which tar)~ \
|
||||
&& ln -sf $(which bsdtar) $(which tar)
|
||||
|
||||
ADD update_ios.sh /update_ios.sh
|
||||
ENV UPDATE_IOS /update_ios.sh
|
||||
RUN chmod +x $UPDATE_IOS
|
||||
|
||||
RUN \
|
||||
IOS_SDK_PATH=https://s3.amazonaws.com/farazdagi/status-im/iPhoneSimulator9.3.sdk.tar.gz && \
|
||||
$FETCH $IOS_SDK_PATH 460423bf776e651a84c6e1bc035dbce23f93e685 && \
|
||||
$UPDATE_IOS /iPhoneSimulator9.3.sdk.tar.gz && \
|
||||
rm -rf /iPhoneSimulator9.3.sdk.tar.gz
|
|
@ -1,64 +0,0 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Contains a simple tool that updates some of the iOS toolchains with the SDKs
|
||||
# explicitly provided. The goal is to allow using your own up to date SDKs or
|
||||
# the simulator one not supported out of the box.
|
||||
#
|
||||
# Usage: update_ios.sh <path to>/<iSomething><Version>.sdk.tar.<type>
|
||||
set -e
|
||||
|
||||
# Figure out the base name of the SDK
|
||||
sdk=`basename $1`
|
||||
sdk=${sdk%.*}
|
||||
sdk=${sdk%.*}
|
||||
|
||||
# Define a small extraction utility to
|
||||
function extract {
|
||||
case $1 in
|
||||
*.tar.xz)
|
||||
xz -dc $1 | tar xf -
|
||||
;;
|
||||
*.tar.gz)
|
||||
gunzip -dc $1 | tar xf -
|
||||
;;
|
||||
*.tar.bz2)
|
||||
bzip2 -dc $1 | tar xf -
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Extract the SDK, patch it, clean it up and prep for bootstrapping
|
||||
extract $1
|
||||
|
||||
if [[ "`basename $1`" =~ ^iPhoneSimulator ]]; then
|
||||
echo "Patching iOS simulator SDK with missing libraries..."
|
||||
ln -s $OSX_NDK_X86/SDK/$OSX_SDK/usr/lib/system/libsystem_kernel.dylib $sdk/usr/lib/system/libsystem_kernel.dylib
|
||||
ln -s $OSX_NDK_X86/SDK/$OSX_SDK/usr/lib/system/libsystem_platform.dylib $sdk/usr/lib/system/libsystem_platform.dylib
|
||||
ln -s $OSX_NDK_X86/SDK/$OSX_SDK/usr/lib/system/libsystem_pthread.dylib $sdk/usr/lib/system/libsystem_pthread.dylib
|
||||
ln -s $OSX_NDK_X86/SDK/$OSX_SDK/usr/lib/system/libsystem_kernel.tbd $sdk/usr/lib/system/libsystem_kernel.tbd
|
||||
ln -s $OSX_NDK_X86/SDK/$OSX_SDK/usr/lib/system/libsystem_platform.tbd $sdk/usr/lib/system/libsystem_platform.tbd
|
||||
ln -s $OSX_NDK_X86/SDK/$OSX_SDK/usr/lib/system/libsystem_pthread.tbd $sdk/usr/lib/system/libsystem_pthread.tbd
|
||||
fi
|
||||
|
||||
tar -czf /tmp/$sdk.tar.gz $sdk
|
||||
rm -rf $sdk
|
||||
|
||||
# Pull the iOS cross compiler tool and build the toolchain
|
||||
git clone -n https://github.com/tpoechtrager/cctools-port.git
|
||||
cd cctools-port
|
||||
git reset --hard adf616eee9d41f4961c3a83ba275249ffcb32d33
|
||||
cd ..
|
||||
|
||||
if [[ "`basename $1`" =~ ^iPhoneSimulator ]]; then
|
||||
rm -rf $IOS_SIM_NDK_AMD64
|
||||
/cctools-port/usage_examples/ios_toolchain/build.sh /tmp/$sdk.tar.gz x86_64
|
||||
mv /cctools-port/usage_examples/ios_toolchain/target $IOS_SIM_NDK_AMD64
|
||||
else
|
||||
rm -rf $IOS_NDK_ARM_7 $IOS_NDK_ARM64
|
||||
/cctools-port/usage_examples/ios_toolchain/build.sh /tmp/$sdk.tar.gz armv7
|
||||
mv /cctools-port/usage_examples/ios_toolchain/target $IOS_NDK_ARM_7
|
||||
/cctools-port/usage_examples/ios_toolchain/build.sh /tmp/$sdk.tar.gz arm64
|
||||
mv /cctools-port/usage_examples/ios_toolchain/target $IOS_NDK_ARM64
|
||||
fi
|
||||
|
||||
rm -rf /cctools-port
|
|
@ -24,6 +24,8 @@ pipeline {
|
|||
STATUS_PATH = 'src/github.com/status-im/status-go'
|
||||
GOPATH = "${env.WORKSPACE}"
|
||||
PATH = "${env.PATH}:${env.GOPATH}/bin"
|
||||
/* This will override the var in Makefile */
|
||||
RELEASE_DIRECTORY = "${env.WORKSPACE}/pkg"
|
||||
}
|
||||
|
||||
stages {
|
||||
|
@ -34,82 +36,70 @@ pipeline {
|
|||
println("Version: ${version}")
|
||||
println("Git Branch: ${lib.gitBranch()}")
|
||||
println("Git Commit: ${lib.gitCommit()}")
|
||||
/* save and create a dir for artifacts */
|
||||
dest = "${env.WORKSPACE}/pkg"
|
||||
sh "mkdir -p ${dest}"
|
||||
} }
|
||||
}
|
||||
} // stage(Prep)
|
||||
|
||||
stage('Setup') { steps { dir(env.STATUS_PATH) {
|
||||
sh 'make setup'
|
||||
sh 'make xgo'
|
||||
} } }
|
||||
stage('Lint') { steps { dir(env.STATUS_PATH) {
|
||||
sh 'make ci'
|
||||
} } }
|
||||
/* install release tools */
|
||||
sh 'make release-install'
|
||||
} } } // stage(Setup)
|
||||
|
||||
stage('Build') {
|
||||
parallel {
|
||||
stage('Android') {
|
||||
stages {
|
||||
stage('Compile') { steps { dir(env.STATUS_PATH) {
|
||||
sh 'make statusgo-android'
|
||||
sh "cp build/bin/statusgo-android-16.aar ${dest}/status-go-android-${lib.suffix()}.aar"
|
||||
} } }
|
||||
stage('Archive') { steps {
|
||||
archiveArtifacts("pkg/status-go-android-${lib.suffix()}.aar")
|
||||
} }
|
||||
stage('Upload') { steps { script {
|
||||
lib.uploadArtifact("pkg/status-go-android-${lib.suffix()}.aar")
|
||||
} } }
|
||||
}
|
||||
stage('iOS') { steps { script {
|
||||
ios = lib.buildBranch('status-go/platforms/ios')
|
||||
} } }
|
||||
stage('Android') { steps { script {
|
||||
android = lib.buildBranch('status-go/platforms/android')
|
||||
} } }
|
||||
stage('Linux') { steps { script {
|
||||
linux = lib.buildBranch('status-go/platforms/linux')
|
||||
} } }
|
||||
} // parallel
|
||||
} // stage(Build)
|
||||
|
||||
stage('Archive') {
|
||||
steps { script {
|
||||
sh("rm -f ${env.RELEASE_DIRECTORY}/*")
|
||||
lib.copyArts('status-go/platforms/ios', ios.number)
|
||||
lib.copyArts('status-go/platforms/android', android.number)
|
||||
lib.copyArts('status-go/platforms/linux', linux.number)
|
||||
dir(env.RELEASE_DIRECTORY) {
|
||||
/* generate sha256 checksums for upload */
|
||||
sh 'sha256sum * | tee checksum.sha256'
|
||||
archiveArtifacts('*')
|
||||
}
|
||||
stage('iOS') {
|
||||
stages {
|
||||
stage('Compile') { steps { dir(env.STATUS_PATH) {
|
||||
sh 'make statusgo-ios-simulator'
|
||||
dir('build/bin/statusgo-ios-9.3-framework') {
|
||||
sh 'zip -r status-go-ios.zip Statusgo.framework'
|
||||
sh "cp status-go-ios.zip ${dest}/status-go-ios-${lib.suffix()}.zip"
|
||||
}
|
||||
} } }
|
||||
stage('Archive') { steps {
|
||||
archiveArtifacts("pkg/status-go-ios-${lib.suffix()}.zip")
|
||||
} }
|
||||
stage('Upload') { steps { script {
|
||||
lib.uploadArtifact("pkg/status-go-ios-${lib.suffix()}.zip")
|
||||
} } }
|
||||
}
|
||||
} }
|
||||
} // stage(Archive)
|
||||
|
||||
stage('Release') { when { expression { params.RELEASE == true } }
|
||||
steps {
|
||||
/* rename build files to not include versions */
|
||||
dir(env.RELEASE_DIRECTORY) {
|
||||
sh 'mv status-go-ios-*.zip status-go-ios.zip'
|
||||
sh 'mv status-go-android-*.aar status-go-android.aar'
|
||||
sh 'mv status-go-desktop-*.zip status-go-desktop.zip'
|
||||
}
|
||||
stage('Desktop') {
|
||||
stages {
|
||||
stage('Prepare') { steps { dir(env.STATUS_PATH) {
|
||||
sh "zip -r ${dest}/status-go-desktop-${lib.suffix()}.zip . -x *.git"
|
||||
} } }
|
||||
stage('Archive') { steps {
|
||||
archiveArtifacts("pkg/status-go-desktop-${lib.suffix()}.zip")
|
||||
} }
|
||||
stage('Upload') { steps { script {
|
||||
lib.uploadArtifact("pkg/status-go-desktop-${lib.suffix()}.zip")
|
||||
} } }
|
||||
/* perform the release */
|
||||
dir(env.STATUS_PATH) {
|
||||
withCredentials([[
|
||||
$class: 'UsernamePasswordMultiBinding',
|
||||
credentialsId: 'status-im-auto',
|
||||
usernameVariable: 'GITHUB_USER',
|
||||
passwordVariable: 'GITHUB_TOKEN'
|
||||
]]) {
|
||||
sh """
|
||||
yes | make release \
|
||||
RELEASE_BRANCH=${lib.gitBranch()} \
|
||||
RELEASE_DIRECTORY=${env.RELEASE_DIRECTORY}
|
||||
"""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Release') { when { expression { params.RELEASE == true } }
|
||||
steps { dir(env.STATUS_PATH) {
|
||||
sh 'make prepare-release'
|
||||
withCredentials([[
|
||||
$class: 'UsernamePasswordMultiBinding',
|
||||
credentialsId: 'status-im-auto',
|
||||
usernameVariable: 'GITHUB_USER',
|
||||
passwordVariable: 'GITHUB_TOKEN'
|
||||
]]) {
|
||||
sh "yes | make release RELEASE_BRANCH=${lib.gitBranch()}"
|
||||
}
|
||||
sh 'make clean-release'
|
||||
} }
|
||||
}
|
||||
stage('Cleanup') { steps { script {
|
||||
sh "rm -fr ${dest}"
|
||||
} } }
|
||||
}
|
||||
} // stage(Release)
|
||||
|
||||
stage('Cleanup') { steps { dir(env.STATUS_PATH) {
|
||||
sh 'make clean-release'
|
||||
} } } // stage(Cleanup)
|
||||
} // stages
|
||||
}
|
||||
|
|
|
@ -1,88 +0,0 @@
|
|||
#!/usr/bin/env groovy
|
||||
|
||||
node('linux') {
|
||||
env.GOPATH = "${env.WORKSPACE}"
|
||||
env.PATH = "${env.PATH}:${env.GOPATH}/bin"
|
||||
|
||||
cloneDir = 'src/github.com/status-im/status-go'
|
||||
paramBranch = env.branch ? env.branch : '*/develop'
|
||||
|
||||
dir(cloneDir) {
|
||||
try {
|
||||
deleteDir()
|
||||
} catch (err) {
|
||||
echo "failure while cleaning the directory"
|
||||
}
|
||||
}
|
||||
|
||||
checkout(
|
||||
changelog: false,
|
||||
poll: true,
|
||||
scm: [$class: 'GitSCM', branches: [[name: paramBranch]],
|
||||
doGenerateSubmoduleConfigurations: false,
|
||||
extensions: [
|
||||
[$class: 'RelativeTargetDirectory', relativeTargetDir: cloneDir]
|
||||
],
|
||||
submoduleCfg: [],
|
||||
userRemoteConfigs: [[url: 'https://github.com/status-im/status-go']]]
|
||||
)
|
||||
|
||||
def remoteOriginRegex = ~/^remotes\/origin\//
|
||||
|
||||
dir(cloneDir) {
|
||||
gitSHA = sh(returnStdout: true, script: 'git rev-parse HEAD').trim()
|
||||
gitShortSHA = gitSHA.take(8)
|
||||
gitBranch = sh(returnStdout: true, script: 'git name-rev --name-only HEAD').trim() - remoteOriginRegex
|
||||
}
|
||||
|
||||
stage('Debug') {
|
||||
sh 'env'
|
||||
println(gitBranch)
|
||||
println(gitSHA)
|
||||
}
|
||||
|
||||
stage('Test') {
|
||||
dir(cloneDir) {
|
||||
sh 'make setup'
|
||||
sh 'make ci'
|
||||
}
|
||||
}
|
||||
|
||||
stage('Build') {
|
||||
sh 'go get github.com/status-im/xgo'
|
||||
|
||||
parallel (
|
||||
'statusgo-android': {
|
||||
dir(cloneDir) {
|
||||
sh 'make statusgo-android'
|
||||
}
|
||||
},
|
||||
'statusgo-ios-simulator': {
|
||||
dir(cloneDir) {
|
||||
sh '''
|
||||
make statusgo-ios-simulator
|
||||
cd build/bin/statusgo-ios-9.3-framework/
|
||||
zip -r status-go-ios.zip Statusgo.framework
|
||||
'''
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
stage('Deploy') {
|
||||
dir(cloneDir) {
|
||||
sh "make prepare-release"
|
||||
withCredentials([[
|
||||
$class: 'UsernamePasswordMultiBinding',
|
||||
credentialsId: 'status-im-auto',
|
||||
usernameVariable: 'GITHUB_USER',
|
||||
passwordVariable: 'GITHUB_TOKEN'
|
||||
]]) {
|
||||
sh """
|
||||
yes | make release release_branch=${gitBranch}
|
||||
"""
|
||||
}
|
||||
sh "make clean-release"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
pipeline {
|
||||
agent { label 'linux' }
|
||||
|
||||
options {
|
||||
/* Go requires a certain directory structure */
|
||||
checkoutToSubdirectory('src/github.com/status-im/status-go')
|
||||
/* manage how many builds we keep */
|
||||
buildDiscarder(logRotator(
|
||||
numToKeepStr: '30',
|
||||
daysToKeepStr: '30',
|
||||
))
|
||||
}
|
||||
|
||||
environment {
|
||||
STATUS_PATH = 'src/github.com/status-im/status-go'
|
||||
CI_DIR = "${env.STATUS_PATH}/_assets/ci"
|
||||
GOPATH = "${env.WORKSPACE}"
|
||||
PATH = "${env.PATH}:${env.GOPATH}/bin"
|
||||
ANDROID_HOME = '/usr/lib/android-sdk'
|
||||
ANDROID_SDK_ROOT = '/usr/lib/android-sdk'
|
||||
ANDROID_NDK = '/usr/lib/android-ndk'
|
||||
ANDROID_NDK_HOME = '/usr/lib/android-ndk'
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Prep') { steps { script {
|
||||
lib = load("${CI_DIR}/lib.groovy")
|
||||
/* clarify what we're building */
|
||||
println("Version: ${lib.getVersion()}")
|
||||
println("Git Branch: ${lib.gitBranch()}")
|
||||
println("Git Commit: ${lib.gitCommit()}")
|
||||
/* save and create a dir for artifacts */
|
||||
dest = "${env.WORKSPACE}/pkg"
|
||||
sh "mkdir -p ${dest}"
|
||||
/* for easier reuse */
|
||||
artifact = "status-go-android-${lib.suffix()}.aar"
|
||||
} } }
|
||||
|
||||
stage('Setup') { steps { dir(env.STATUS_PATH) {
|
||||
sh 'make setup-build'
|
||||
} } }
|
||||
|
||||
stage('Test') { steps { dir(env.STATUS_PATH) {
|
||||
sh 'make ci'
|
||||
} } }
|
||||
|
||||
stage('Compile') { steps { dir(env.STATUS_PATH) {
|
||||
sh 'make statusgo-android'
|
||||
sh "cp build/bin/statusgo.aar ${dest}/${artifact}"
|
||||
} } }
|
||||
|
||||
stage('Archive') { steps {
|
||||
archiveArtifacts("pkg/${artifact}")
|
||||
} }
|
||||
|
||||
stage('Upload') { steps { script {
|
||||
lib.uploadArtifact("pkg/${artifact}")
|
||||
} } }
|
||||
|
||||
stage('Cleanup') { steps { dir(env.STATUS_PATH) {
|
||||
sh 'make clean'
|
||||
sh "rm -fr ${dest}"
|
||||
} } }
|
||||
} // stages
|
||||
} // pipeline
|
|
@ -0,0 +1,64 @@
|
|||
pipeline {
|
||||
agent { label 'macos' }
|
||||
|
||||
options {
|
||||
/* Go requires a certain directory structure */
|
||||
checkoutToSubdirectory('src/github.com/status-im/status-go')
|
||||
/* manage how many builds we keep */
|
||||
buildDiscarder(logRotator(
|
||||
numToKeepStr: '30',
|
||||
daysToKeepStr: '30',
|
||||
))
|
||||
}
|
||||
|
||||
environment {
|
||||
STATUS_PATH = 'src/github.com/status-im/status-go'
|
||||
CI_DIR = "${env.STATUS_PATH}/_assets/ci"
|
||||
GOPATH = "${env.WORKSPACE}"
|
||||
PATH = "${env.PATH}:${env.GOPATH}/bin"
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Prep') { steps { script {
|
||||
lib = load("${CI_DIR}/lib.groovy")
|
||||
/* clarify what we're building */
|
||||
println("Version: ${lib.getVersion()}")
|
||||
println("Git Branch: ${lib.gitBranch()}")
|
||||
println("Git Commit: ${lib.gitCommit()}")
|
||||
/* save and create a dir for artifacts */
|
||||
dest = "${env.WORKSPACE}/pkg"
|
||||
sh "mkdir -p ${dest}"
|
||||
/* for easier reuse */
|
||||
artifact = "status-go-ios-${lib.suffix()}.zip"
|
||||
} } }
|
||||
|
||||
stage('Setup') { steps { dir(env.STATUS_PATH) {
|
||||
sh 'make setup-build'
|
||||
} } }
|
||||
|
||||
stage('Test') { steps { dir(env.STATUS_PATH) {
|
||||
sh 'make ci'
|
||||
} } }
|
||||
|
||||
stage('Compile') { steps { dir(env.STATUS_PATH) {
|
||||
sh 'make statusgo-ios'
|
||||
dir('build/bin') {
|
||||
sh 'zip -r status-go-ios.zip Statusgo.framework'
|
||||
sh "cp status-go-ios.zip ${dest}/${artifact}"
|
||||
}
|
||||
} } }
|
||||
|
||||
stage('Archive') { steps {
|
||||
archiveArtifacts("pkg/${artifact}")
|
||||
} }
|
||||
|
||||
stage('Upload') { steps { script {
|
||||
lib.uploadArtifact("pkg/${artifact}")
|
||||
} } }
|
||||
|
||||
stage('Cleanup') { steps { dir(env.STATUS_PATH) {
|
||||
sh 'make clean'
|
||||
sh "rm -fr ${dest}"
|
||||
} } }
|
||||
} // stages
|
||||
} // pipeline
|
|
@ -0,0 +1,46 @@
|
|||
pipeline {
|
||||
agent { label 'linux' }
|
||||
|
||||
options {
|
||||
/* Go requires a certain directory structure */
|
||||
checkoutToSubdirectory('src/github.com/status-im/status-go')
|
||||
/* manage how many builds we keep */
|
||||
buildDiscarder(logRotator(
|
||||
numToKeepStr: '30',
|
||||
daysToKeepStr: '30',
|
||||
))
|
||||
}
|
||||
|
||||
environment {
|
||||
STATUS_PATH = 'src/github.com/status-im/status-go'
|
||||
GOPATH = "${env.WORKSPACE}"
|
||||
PATH = "${env.PATH}:${env.GOPATH}/bin"
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Prep') { steps { script {
|
||||
lib = load("${env.STATUS_PATH}/_assets/ci/lib.groovy")
|
||||
/* clarify what we're building */
|
||||
println("Version: ${lib.getVersion()}")
|
||||
println("Git Branch: ${lib.gitBranch()}")
|
||||
println("Git Commit: ${lib.gitCommit()}")
|
||||
/* save and create a dir for artifacts */
|
||||
dest = "${env.WORKSPACE}/pkg"
|
||||
sh "mkdir -p ${dest}"
|
||||
/* for easier reuse */
|
||||
artifact = "status-go-desktop-${lib.suffix()}.zip"
|
||||
} } }
|
||||
|
||||
stage('Compress') { steps { dir(env.STATUS_PATH) {
|
||||
sh "zip -q -r ${dest}/${artifact} . -x *.git"
|
||||
} } }
|
||||
|
||||
stage('Archive') { steps {
|
||||
archiveArtifacts("pkg/${artifact}")
|
||||
} }
|
||||
|
||||
stage('Upload') { steps { script {
|
||||
lib.uploadArtifact("pkg/${artifact}")
|
||||
} } }
|
||||
} // stages
|
||||
} // pipeline
|
|
@ -1,3 +1,7 @@
|
|||
def getVersion() {
|
||||
return readFile("${env.STATUS_PATH}/VERSION").trim()
|
||||
}
|
||||
|
||||
def gitCommit() {
|
||||
return GIT_COMMIT.take(6)
|
||||
}
|
||||
|
@ -49,4 +53,33 @@ def uploadArtifact(path) {
|
|||
return "https://${bucket}.${domain}/${getFilename(path)}"
|
||||
}
|
||||
|
||||
def buildBranch(name = null, buildType = null) {
|
||||
/* need to drop origin/ to match definitions of child jobs */
|
||||
def branchName = env.GIT_BRANCH.replace('origin/', '')
|
||||
/* always pass the BRANCH and BUILD_TYPE params with current branch */
|
||||
def resp = build(
|
||||
job: name,
|
||||
/* this allows us to analize the job even after failure */
|
||||
propagate: false,
|
||||
parameters: [
|
||||
[name: 'BRANCH', value: branchName, $class: 'StringParameterValue'],
|
||||
])
|
||||
/* BlueOcean seems to not show child-build links */
|
||||
println "Build: ${resp.getAbsoluteUrl()} (${resp.result})"
|
||||
if (resp.result != 'SUCCESS') {
|
||||
error("Build Failed")
|
||||
}
|
||||
return resp
|
||||
}
|
||||
|
||||
def copyArts(projectName, buildNo) {
|
||||
copyArtifacts(
|
||||
projectName: projectName,
|
||||
target: 'pkg',
|
||||
flatten: true,
|
||||
selector: specific("${buildNo}")
|
||||
)
|
||||
}
|
||||
|
||||
return this
|
||||
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
diff --git a/vendor/gopkg.in/olebedev/go-duktape.v3/duk_minimal_printf.c b/vendor/gopkg.in/olebedev/go-duktape.v3/duk_minimal_printf.c
|
||||
index e4b6e43a..baed990d 100755
|
||||
--- a/vendor/gopkg.in/olebedev/go-duktape.v3/duk_minimal_printf.c
|
||||
+++ b/vendor/gopkg.in/olebedev/go-duktape.v3/duk_minimal_printf.c
|
||||
@@ -278,6 +278,7 @@ int duk_minimal_snprintf(char *str, size_t size, const char *format, ...) {
|
||||
}
|
||||
|
||||
/* Minimal sprintf() entry point. */
|
||||
+#if 0
|
||||
int duk_minimal_sprintf(char *str, const char *format, ...) {
|
||||
va_list ap;
|
||||
int ret;
|
||||
@@ -288,6 +289,7 @@ int duk_minimal_sprintf(char *str, const char *format, ...) {
|
||||
|
||||
return ret;
|
||||
}
|
||||
+#endif
|
||||
|
||||
/* Minimal sscanf() entry point. */
|
||||
int duk_minimal_sscanf(const char *str, const char *format, ...) {
|
|
@ -1,153 +0,0 @@
|
|||
diff --git a/vendor/github.com/ethereum/go-ethereum/dashboard/dashboard.go b/vendor/github.com/ethereum/go-ethereum/dashboard/dashboard.go
|
||||
index 3ba92ac7..d89a1e94 100644
|
||||
--- a/vendor/github.com/ethereum/go-ethereum/dashboard/dashboard.go
|
||||
+++ b/vendor/github.com/ethereum/go-ethereum/dashboard/dashboard.go
|
||||
@@ -27,20 +27,17 @@ import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
- "runtime"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"io"
|
||||
|
||||
- "github.com/elastic/gosigar"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/metrics"
|
||||
"github.com/ethereum/go-ethereum/p2p"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
- "github.com/mohae/deepcopy"
|
||||
"golang.org/x/net/websocket"
|
||||
)
|
||||
|
||||
@@ -235,7 +232,7 @@ func (db *Dashboard) apiHandler(conn *websocket.Conn) {
|
||||
|
||||
db.lock.Lock()
|
||||
// Send the past data.
|
||||
- client.msg <- deepcopy.Copy(db.history).(*Message)
|
||||
+ client.msg <- db.history
|
||||
// Start tracking the connection and drop at connection loss.
|
||||
db.conns[id] = client
|
||||
db.lock.Unlock()
|
||||
@@ -275,118 +272,6 @@ func meterCollector(name string) func() int64 {
|
||||
// collectData collects the required data to plot on the dashboard.
|
||||
func (db *Dashboard) collectData() {
|
||||
defer db.wg.Done()
|
||||
-
|
||||
- systemCPUUsage := gosigar.Cpu{}
|
||||
- systemCPUUsage.Get()
|
||||
- var (
|
||||
- mem runtime.MemStats
|
||||
-
|
||||
- collectNetworkIngress = meterCollector("p2p/InboundTraffic")
|
||||
- collectNetworkEgress = meterCollector("p2p/OutboundTraffic")
|
||||
- collectDiskRead = meterCollector("eth/db/chaindata/disk/read")
|
||||
- collectDiskWrite = meterCollector("eth/db/chaindata/disk/write")
|
||||
-
|
||||
- prevNetworkIngress = collectNetworkIngress()
|
||||
- prevNetworkEgress = collectNetworkEgress()
|
||||
- prevProcessCPUTime = getProcessCPUTime()
|
||||
- prevSystemCPUUsage = systemCPUUsage
|
||||
- prevDiskRead = collectDiskRead()
|
||||
- prevDiskWrite = collectDiskWrite()
|
||||
-
|
||||
- frequency = float64(db.config.Refresh / time.Second)
|
||||
- numCPU = float64(runtime.NumCPU())
|
||||
- )
|
||||
-
|
||||
- for {
|
||||
- select {
|
||||
- case errc := <-db.quit:
|
||||
- errc <- nil
|
||||
- return
|
||||
- case <-time.After(db.config.Refresh):
|
||||
- systemCPUUsage.Get()
|
||||
- var (
|
||||
- curNetworkIngress = collectNetworkIngress()
|
||||
- curNetworkEgress = collectNetworkEgress()
|
||||
- curProcessCPUTime = getProcessCPUTime()
|
||||
- curSystemCPUUsage = systemCPUUsage
|
||||
- curDiskRead = collectDiskRead()
|
||||
- curDiskWrite = collectDiskWrite()
|
||||
-
|
||||
- deltaNetworkIngress = float64(curNetworkIngress - prevNetworkIngress)
|
||||
- deltaNetworkEgress = float64(curNetworkEgress - prevNetworkEgress)
|
||||
- deltaProcessCPUTime = curProcessCPUTime - prevProcessCPUTime
|
||||
- deltaSystemCPUUsage = curSystemCPUUsage.Delta(prevSystemCPUUsage)
|
||||
- deltaDiskRead = curDiskRead - prevDiskRead
|
||||
- deltaDiskWrite = curDiskWrite - prevDiskWrite
|
||||
- )
|
||||
- prevNetworkIngress = curNetworkIngress
|
||||
- prevNetworkEgress = curNetworkEgress
|
||||
- prevProcessCPUTime = curProcessCPUTime
|
||||
- prevSystemCPUUsage = curSystemCPUUsage
|
||||
- prevDiskRead = curDiskRead
|
||||
- prevDiskWrite = curDiskWrite
|
||||
-
|
||||
- now := time.Now()
|
||||
-
|
||||
- runtime.ReadMemStats(&mem)
|
||||
- activeMemory := &ChartEntry{
|
||||
- Time: now,
|
||||
- Value: float64(mem.Alloc) / frequency,
|
||||
- }
|
||||
- virtualMemory := &ChartEntry{
|
||||
- Time: now,
|
||||
- Value: float64(mem.Sys) / frequency,
|
||||
- }
|
||||
- networkIngress := &ChartEntry{
|
||||
- Time: now,
|
||||
- Value: deltaNetworkIngress / frequency,
|
||||
- }
|
||||
- networkEgress := &ChartEntry{
|
||||
- Time: now,
|
||||
- Value: deltaNetworkEgress / frequency,
|
||||
- }
|
||||
- processCPU := &ChartEntry{
|
||||
- Time: now,
|
||||
- Value: deltaProcessCPUTime / frequency / numCPU * 100,
|
||||
- }
|
||||
- systemCPU := &ChartEntry{
|
||||
- Time: now,
|
||||
- Value: float64(deltaSystemCPUUsage.Sys+deltaSystemCPUUsage.User) / frequency / numCPU,
|
||||
- }
|
||||
- diskRead := &ChartEntry{
|
||||
- Time: now,
|
||||
- Value: float64(deltaDiskRead) / frequency,
|
||||
- }
|
||||
- diskWrite := &ChartEntry{
|
||||
- Time: now,
|
||||
- Value: float64(deltaDiskWrite) / frequency,
|
||||
- }
|
||||
- sys := db.history.System
|
||||
- db.lock.Lock()
|
||||
- sys.ActiveMemory = append(sys.ActiveMemory[1:], activeMemory)
|
||||
- sys.VirtualMemory = append(sys.VirtualMemory[1:], virtualMemory)
|
||||
- sys.NetworkIngress = append(sys.NetworkIngress[1:], networkIngress)
|
||||
- sys.NetworkEgress = append(sys.NetworkEgress[1:], networkEgress)
|
||||
- sys.ProcessCPU = append(sys.ProcessCPU[1:], processCPU)
|
||||
- sys.SystemCPU = append(sys.SystemCPU[1:], systemCPU)
|
||||
- sys.DiskRead = append(sys.DiskRead[1:], diskRead)
|
||||
- sys.DiskWrite = append(sys.DiskWrite[1:], diskWrite)
|
||||
- db.lock.Unlock()
|
||||
-
|
||||
- db.sendToAll(&Message{
|
||||
- System: &SystemMessage{
|
||||
- ActiveMemory: ChartEntries{activeMemory},
|
||||
- VirtualMemory: ChartEntries{virtualMemory},
|
||||
- NetworkIngress: ChartEntries{networkIngress},
|
||||
- NetworkEgress: ChartEntries{networkEgress},
|
||||
- ProcessCPU: ChartEntries{processCPU},
|
||||
- SystemCPU: ChartEntries{systemCPU},
|
||||
- DiskRead: ChartEntries{diskRead},
|
||||
- DiskWrite: ChartEntries{diskWrite},
|
||||
- },
|
||||
- })
|
||||
- }
|
||||
- }
|
||||
}
|
||||
|
||||
// sendToAll sends the given message to the active dashboards.
|
|
@ -1,20 +0,0 @@
|
|||
# Status Patches for geth (go-ethereum) cross-compiled in Xgo
|
||||
---
|
||||
|
||||
Status-go uses [go-ethereum](https://github.com/ethereum/go-ethereum) (**upstream**) as its dependency. When cross-compiling with Xgo, some headers or definitions are not available within the Xgo environment. In such a situation, we temporarily patch the sources before kicking the build in Xgo and revert them afterwards (this is taken care by the respective Makefile targets).
|
||||
|
||||
We try to minimize number and amount of changes in those patches as much as possible, and whereas possible, to contribute changes into the upstream.
|
||||
|
||||
# Creating patches
|
||||
|
||||
Instructions for creating a patch from the command line:
|
||||
|
||||
1. Enter the command line at the go-ethereum dependency root in vendor folder.
|
||||
1. Create the patch:
|
||||
1. If you already have a commit that represents the change, find its SHA1 (e.g. `$COMMIT_SHA1`) and do `git diff $COMMIT_SHA1 > file.patch`
|
||||
1. If the files are staged, do `git diff --cached > file.patch`
|
||||
|
||||
# Patches
|
||||
|
||||
- [`0001-fix-duktapev3-missing-SIZE_MAX-def.patch`](./0001-fix-duktapev3-missing-SIZE_MAX-def.patch) — Adds patch to geth 1.8.0 dependency duktapev3, to address issue where SIZE_MAX is not defined in xgo for Android
|
||||
- [`0002-remove-dashboard-collectData.patch`](./0002-remove-dashboard-collectData.patch) — Deletes the body of `collectData` in the `dashboard` package, since it will import the `gosigar` package which in turn includes a header (`libproc.h`) which is missing in the iOS environment in Xgo.
|
|
@ -15,6 +15,7 @@ func TestUpdateNodeMetricsPeersCounter(t *testing.T) {
|
|||
P2P: p2p.Config{
|
||||
MaxPeers: 10,
|
||||
},
|
||||
NoUSB: true,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, n.Start())
|
||||
|
|
|
@ -9,13 +9,13 @@ import (
|
|||
)
|
||||
|
||||
func TestSubscribeServerEventsWithoutServer(t *testing.T) {
|
||||
gethNode, err := node.New(&node.Config{})
|
||||
gethNode, err := node.New(&node.Config{NoUSB: true})
|
||||
require.NoError(t, err)
|
||||
require.EqualError(t, SubscribeServerEvents(context.TODO(), gethNode), "server is unavailable")
|
||||
}
|
||||
|
||||
func TestSubscribeServerEvents(t *testing.T) {
|
||||
gethNode, err := node.New(&node.Config{})
|
||||
gethNode, err := node.New(&node.Config{NoUSB: true})
|
||||
require.NoError(t, err)
|
||||
err = gethNode.Start()
|
||||
require.NoError(t, err)
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
# Mobile
|
||||
|
||||
Package mobile implements [gomobile](https://github.com/golang/mobile) bindings for status-go. Current implementation servers as a drop-in replacement for `lib` package.
|
||||
|
||||
The framework name is generated from the package name, hence these things are done intentionally:
|
||||
(1) this package's name isn't equal to the directory name (`statusgo` vs `mobile` respectively);
|
||||
(2) this package name is `statusgo` and not `status` which produces the right framework name.
|
||||
|
||||
# Usage
|
||||
|
||||
For properly using this package, please refer to Makefile in the root of `status-go` directory.
|
||||
|
||||
To manually build library, run following commands:
|
||||
|
||||
### iOS
|
||||
|
||||
```
|
||||
gomobile bind -v -target=ios -ldflags="-s -w" github.com/status-im/status-go/mobile
|
||||
```
|
||||
This will produce `Statusgo.framework` file in the current directory, which can be used in iOS project.
|
||||
|
||||
### Android
|
||||
|
||||
```
|
||||
gomobile bind -v -target=android -ldflags="-s -w" github.com/status-im/status-go/mobile
|
||||
```
|
||||
This will generate `Statusgo.aar` file in the current dir.
|
||||
|
||||
# Notes
|
||||
|
||||
See [https://github.com/golang/go/wiki/Mobile](https://github.com/golang/go/wiki/Mobile) for more information on `gomobile` usage.
|
|
@ -0,0 +1,64 @@
|
|||
package statusgo
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts/keystore"
|
||||
"github.com/status-im/status-go/account"
|
||||
"github.com/status-im/status-go/transactions"
|
||||
)
|
||||
|
||||
const (
|
||||
codeUnknown int = iota
|
||||
// special codes
|
||||
codeFailedParseResponse
|
||||
codeFailedParseParams
|
||||
// account related codes
|
||||
codeErrNoAccountSelected
|
||||
codeErrInvalidTxSender
|
||||
codeErrDecrypt
|
||||
)
|
||||
|
||||
var errToCodeMap = map[error]int{
|
||||
account.ErrNoAccountSelected: codeErrNoAccountSelected,
|
||||
transactions.ErrInvalidTxSender: codeErrInvalidTxSender,
|
||||
keystore.ErrDecrypt: codeErrDecrypt,
|
||||
}
|
||||
|
||||
type jsonrpcSuccessfulResponse struct {
|
||||
Result interface{} `json:"result"`
|
||||
}
|
||||
|
||||
type jsonrpcErrorResponse struct {
|
||||
Error jsonError `json:"error"`
|
||||
}
|
||||
|
||||
type jsonError struct {
|
||||
Code int `json:"code,omitempty"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
func prepareJSONResponse(result interface{}, err error) string {
|
||||
code := codeUnknown
|
||||
if c, ok := errToCodeMap[err]; ok {
|
||||
code = c
|
||||
}
|
||||
|
||||
return prepareJSONResponseWithCode(result, err, code)
|
||||
}
|
||||
|
||||
func prepareJSONResponseWithCode(result interface{}, err error, code int) string {
|
||||
if err != nil {
|
||||
errResponse := jsonrpcErrorResponse{
|
||||
Error: jsonError{Code: code, Message: err.Error()},
|
||||
}
|
||||
response, _ := json.Marshal(&errResponse)
|
||||
return string(response)
|
||||
}
|
||||
|
||||
data, err := json.Marshal(jsonrpcSuccessfulResponse{result})
|
||||
if err != nil {
|
||||
return prepareJSONResponseWithCode(nil, err, codeFailedParseResponse)
|
||||
}
|
||||
return string(data)
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package statusgo
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
type nonJSON struct{}
|
||||
|
||||
func (*nonJSON) MarshalJSON() ([]byte, error) {
|
||||
return nil, errors.New("invalid JSON")
|
||||
}
|
||||
|
||||
func TestPrepareJSONResponseErrorWithResult(t *testing.T) {
|
||||
data := prepareJSONResponse("0x123", nil)
|
||||
require.Equal(t, `{"result":"0x123"}`, data)
|
||||
|
||||
data = prepareJSONResponse(&nonJSON{}, nil)
|
||||
require.Contains(t, data, `{"error":{"code":1,"message":`)
|
||||
}
|
||||
|
||||
func TestPrepareJSONResponseErrorWithError(t *testing.T) {
|
||||
data := prepareJSONResponse("0x123", errors.New("some error"))
|
||||
require.Contains(t, data, `{"error":{"message":"some error"}}`)
|
||||
}
|
|
@ -0,0 +1,496 @@
|
|||
package statusgo
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"unsafe"
|
||||
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/status-im/status-go/api"
|
||||
"github.com/status-im/status-go/logutils"
|
||||
"github.com/status-im/status-go/params"
|
||||
"github.com/status-im/status-go/profiling"
|
||||
"github.com/status-im/status-go/services/personal"
|
||||
"github.com/status-im/status-go/signal"
|
||||
"github.com/status-im/status-go/transactions"
|
||||
validator "gopkg.in/go-playground/validator.v9"
|
||||
)
|
||||
|
||||
var statusBackend = api.NewStatusBackend()
|
||||
|
||||
// All general log messages in this package should be routed through this logger.
|
||||
var logger = log.New("package", "status-go/mobile")
|
||||
|
||||
// GenerateConfig for status node.
|
||||
func GenerateConfig(datadir string, networkID int) string {
|
||||
config, err := params.NewNodeConfig(datadir, uint64(networkID))
|
||||
if err != nil {
|
||||
return makeJSONResponse(err)
|
||||
}
|
||||
|
||||
outBytes, err := json.Marshal(config)
|
||||
if err != nil {
|
||||
return makeJSONResponse(err)
|
||||
}
|
||||
|
||||
return string(outBytes)
|
||||
}
|
||||
|
||||
// StartNode starts the Ethereum Status node.
|
||||
func StartNode(configJSON string) string {
|
||||
config, err := params.NewConfigFromJSON(configJSON)
|
||||
if err != nil {
|
||||
return makeJSONResponse(err)
|
||||
}
|
||||
|
||||
if err := logutils.OverrideRootLog(true, "INFO", "", true); err != nil {
|
||||
return makeJSONResponse(err)
|
||||
}
|
||||
|
||||
api.RunAsync(func() error { return statusBackend.StartNode(config) })
|
||||
|
||||
return makeJSONResponse(nil)
|
||||
}
|
||||
|
||||
// StopNode stops the Ethereum Status node.
|
||||
func StopNode() string {
|
||||
api.RunAsync(statusBackend.StopNode)
|
||||
return makeJSONResponse(nil)
|
||||
}
|
||||
|
||||
// CreateContactCode creates an X3DH bundle.
|
||||
func CreateContactCode() string {
|
||||
bundle, err := statusBackend.CreateContactCode()
|
||||
if err != nil {
|
||||
return makeJSONResponse(err)
|
||||
}
|
||||
|
||||
return bundle
|
||||
}
|
||||
|
||||
// ProcessContactCode processes an X3DH bundle.
|
||||
// TODO(adam): it looks like the return should be error.
|
||||
func ProcessContactCode(bundle string) string {
|
||||
err := statusBackend.ProcessContactCode(bundle)
|
||||
if err != nil {
|
||||
return makeJSONResponse(err)
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// ExtractIdentityFromContactCode extracts an identity from an X3DH bundle.
|
||||
func ExtractIdentityFromContactCode(bundle string) string {
|
||||
identity, err := statusBackend.ExtractIdentityFromContactCode(bundle)
|
||||
if err != nil {
|
||||
return makeJSONResponse(err)
|
||||
}
|
||||
|
||||
if err := statusBackend.ProcessContactCode(bundle); err != nil {
|
||||
return makeJSONResponse(err)
|
||||
}
|
||||
|
||||
data, err := json.Marshal(struct {
|
||||
Identity string `json:"identity"`
|
||||
}{Identity: identity})
|
||||
if err != nil {
|
||||
return makeJSONResponse(err)
|
||||
}
|
||||
|
||||
return string(data)
|
||||
}
|
||||
|
||||
// ExtractGroupMembershipSignatures extract public keys from tuples of content/signature.
|
||||
func ExtractGroupMembershipSignatures(signaturePairsStr string) string {
|
||||
var signaturePairs [][2]string
|
||||
|
||||
if err := json.Unmarshal([]byte(signaturePairsStr), &signaturePairs); err != nil {
|
||||
return makeJSONResponse(err)
|
||||
}
|
||||
|
||||
identities, err := statusBackend.ExtractGroupMembershipSignatures(signaturePairs)
|
||||
if err != nil {
|
||||
return makeJSONResponse(err)
|
||||
}
|
||||
|
||||
data, err := json.Marshal(struct {
|
||||
Identities []string `json:"identities"`
|
||||
}{Identities: identities})
|
||||
if err != nil {
|
||||
return makeJSONResponse(err)
|
||||
}
|
||||
|
||||
return string(data)
|
||||
}
|
||||
|
||||
// SignGroupMembership signs a string containing group membership information.
|
||||
func SignGroupMembership(content string) string {
|
||||
signature, err := statusBackend.SignGroupMembership(content)
|
||||
if err != nil {
|
||||
return makeJSONResponse(err)
|
||||
}
|
||||
|
||||
data, err := json.Marshal(struct {
|
||||
Signature string `json:"signature"`
|
||||
}{Signature: signature})
|
||||
if err != nil {
|
||||
return makeJSONResponse(err)
|
||||
}
|
||||
|
||||
return string(data)
|
||||
}
|
||||
|
||||
// EnableInstallation enables an installation for multi-device sync.
|
||||
func EnableInstallation(installationID string) string {
|
||||
err := statusBackend.EnableInstallation(installationID)
|
||||
if err != nil {
|
||||
return makeJSONResponse(err)
|
||||
}
|
||||
|
||||
data, err := json.Marshal(struct {
|
||||
Response string `json:"response"`
|
||||
}{Response: "ok"})
|
||||
if err != nil {
|
||||
return makeJSONResponse(err)
|
||||
}
|
||||
|
||||
return string(data)
|
||||
}
|
||||
|
||||
// DisableInstallation disables an installation for multi-device sync.
|
||||
func DisableInstallation(installationID string) string {
|
||||
err := statusBackend.DisableInstallation(installationID)
|
||||
if err != nil {
|
||||
return makeJSONResponse(err)
|
||||
}
|
||||
|
||||
data, err := json.Marshal(struct {
|
||||
Response string `json:"response"`
|
||||
}{Response: "ok"})
|
||||
if err != nil {
|
||||
return makeJSONResponse(err)
|
||||
}
|
||||
|
||||
return string(data)
|
||||
}
|
||||
|
||||
// ValidateNodeConfig validates config for the Status node.
|
||||
func ValidateNodeConfig(configJSON string) string {
|
||||
var resp APIDetailedResponse
|
||||
|
||||
_, err := params.NewConfigFromJSON(configJSON)
|
||||
|
||||
// Convert errors to APIDetailedResponse
|
||||
switch err := err.(type) {
|
||||
case validator.ValidationErrors:
|
||||
resp = APIDetailedResponse{
|
||||
Message: "validation: validation failed",
|
||||
FieldErrors: make([]APIFieldError, len(err)),
|
||||
}
|
||||
|
||||
for i, ve := range err {
|
||||
resp.FieldErrors[i] = APIFieldError{
|
||||
Parameter: ve.Namespace(),
|
||||
Errors: []APIError{
|
||||
{
|
||||
Message: fmt.Sprintf("field validation failed on the '%s' tag", ve.Tag()),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
case error:
|
||||
resp = APIDetailedResponse{
|
||||
Message: fmt.Sprintf("validation: %s", err.Error()),
|
||||
}
|
||||
case nil:
|
||||
resp = APIDetailedResponse{
|
||||
Status: true,
|
||||
}
|
||||
}
|
||||
|
||||
respJSON, err := json.Marshal(resp)
|
||||
if err != nil {
|
||||
return makeJSONResponse(err)
|
||||
}
|
||||
|
||||
return string(respJSON)
|
||||
}
|
||||
|
||||
// ResetChainData removes chain data from data directory.
|
||||
func ResetChainData() string {
|
||||
api.RunAsync(statusBackend.ResetChainData)
|
||||
return makeJSONResponse(nil)
|
||||
}
|
||||
|
||||
// CallRPC calls public APIs via RPC.
|
||||
func CallRPC(inputJSON string) string {
|
||||
resp, err := statusBackend.CallRPC(inputJSON)
|
||||
if err != nil {
|
||||
return makeJSONResponse(err)
|
||||
}
|
||||
return resp
|
||||
}
|
||||
|
||||
// CallPrivateRPC calls both public and private APIs via RPC.
|
||||
func CallPrivateRPC(inputJSON string) string {
|
||||
resp, err := statusBackend.CallPrivateRPC(inputJSON)
|
||||
if err != nil {
|
||||
return makeJSONResponse(err)
|
||||
}
|
||||
return resp
|
||||
}
|
||||
|
||||
// CreateAccount is equivalent to creating an account from the command line,
|
||||
// just modified to handle the function arg passing.
|
||||
func CreateAccount(password string) string {
|
||||
info, mnemonic, err := statusBackend.AccountManager().CreateAccount(password)
|
||||
|
||||
errString := ""
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
errString = err.Error()
|
||||
}
|
||||
|
||||
out := AccountInfo{
|
||||
Address: info.WalletAddress,
|
||||
PubKey: info.WalletPubKey,
|
||||
WalletAddress: info.WalletAddress,
|
||||
WalletPubKey: info.WalletPubKey,
|
||||
ChatAddress: info.ChatAddress,
|
||||
ChatPubKey: info.ChatPubKey,
|
||||
Mnemonic: mnemonic,
|
||||
Error: errString,
|
||||
}
|
||||
outBytes, _ := json.Marshal(out)
|
||||
return string(outBytes)
|
||||
}
|
||||
|
||||
// CreateChildAccount creates sub-account.
|
||||
func CreateChildAccount(parentAddress, password string) string {
|
||||
address, pubKey, err := statusBackend.AccountManager().CreateChildAccount(parentAddress, password)
|
||||
|
||||
errString := ""
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
errString = err.Error()
|
||||
}
|
||||
|
||||
out := AccountInfo{
|
||||
Address: address,
|
||||
PubKey: pubKey,
|
||||
Error: errString,
|
||||
}
|
||||
outBytes, _ := json.Marshal(out)
|
||||
return string(outBytes)
|
||||
}
|
||||
|
||||
// RecoverAccount re-creates master key using given details.
|
||||
func RecoverAccount(password, mnemonic string) string {
|
||||
info, err := statusBackend.AccountManager().RecoverAccount(password, mnemonic)
|
||||
|
||||
errString := ""
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
errString = err.Error()
|
||||
}
|
||||
|
||||
out := AccountInfo{
|
||||
Address: info.WalletAddress,
|
||||
PubKey: info.WalletPubKey,
|
||||
WalletAddress: info.WalletAddress,
|
||||
WalletPubKey: info.WalletPubKey,
|
||||
ChatAddress: info.ChatAddress,
|
||||
ChatPubKey: info.ChatPubKey,
|
||||
Mnemonic: mnemonic,
|
||||
Error: errString,
|
||||
}
|
||||
outBytes, _ := json.Marshal(out)
|
||||
return string(outBytes)
|
||||
}
|
||||
|
||||
// VerifyAccountPassword verifies account password.
|
||||
func VerifyAccountPassword(keyStoreDir, address, password string) string {
|
||||
_, err := statusBackend.AccountManager().VerifyAccountPassword(keyStoreDir, address, password)
|
||||
return makeJSONResponse(err)
|
||||
}
|
||||
|
||||
// Login loads a key file (for a given address), tries to decrypt it using the password,
|
||||
// to verify ownership if verified, purges all the previous identities from Whisper,
|
||||
// and injects verified key as shh identity.
|
||||
func Login(address, password string) string {
|
||||
err := statusBackend.SelectAccount(address, address, password)
|
||||
return makeJSONResponse(err)
|
||||
}
|
||||
|
||||
// Logout is equivalent to clearing whisper identities.
|
||||
func Logout() string {
|
||||
err := statusBackend.Logout()
|
||||
return makeJSONResponse(err)
|
||||
}
|
||||
|
||||
// SignMessage unmarshals rpc params {data, address, password} and
|
||||
// passes them onto backend.SignMessage.
|
||||
func SignMessage(rpcParams string) string {
|
||||
var params personal.SignParams
|
||||
err := json.Unmarshal([]byte(rpcParams), ¶ms)
|
||||
if err != nil {
|
||||
return prepareJSONResponseWithCode(nil, err, codeFailedParseParams)
|
||||
}
|
||||
result, err := statusBackend.SignMessage(params)
|
||||
return prepareJSONResponse(result.String(), err)
|
||||
}
|
||||
|
||||
// Recover unmarshals rpc params {signDataString, signedData} and passes
|
||||
// them onto backend.
|
||||
func Recover(rpcParams string) string {
|
||||
var params personal.RecoverParams
|
||||
err := json.Unmarshal([]byte(rpcParams), ¶ms)
|
||||
if err != nil {
|
||||
return prepareJSONResponseWithCode(nil, err, codeFailedParseParams)
|
||||
}
|
||||
addr, err := statusBackend.Recover(params)
|
||||
return prepareJSONResponse(addr.String(), err)
|
||||
}
|
||||
|
||||
// SendTransaction converts RPC args and calls backend.SendTransaction.
|
||||
func SendTransaction(txArgsJSON, password string) string {
|
||||
var params transactions.SendTxArgs
|
||||
err := json.Unmarshal([]byte(txArgsJSON), ¶ms)
|
||||
if err != nil {
|
||||
return prepareJSONResponseWithCode(nil, err, codeFailedParseParams)
|
||||
}
|
||||
hash, err := statusBackend.SendTransaction(params, password)
|
||||
code := codeUnknown
|
||||
if c, ok := errToCodeMap[err]; ok {
|
||||
code = c
|
||||
}
|
||||
return prepareJSONResponseWithCode(hash.String(), err, code)
|
||||
}
|
||||
|
||||
// StartCPUProfile runs pprof for CPU.
|
||||
func StartCPUProfile(dataDir string) string {
|
||||
err := profiling.StartCPUProfile(dataDir)
|
||||
return makeJSONResponse(err)
|
||||
}
|
||||
|
||||
// StopCPUProfiling stops pprof for cpu.
|
||||
func StopCPUProfiling() string { //nolint: deadcode
|
||||
err := profiling.StopCPUProfile()
|
||||
return makeJSONResponse(err)
|
||||
}
|
||||
|
||||
//WriteHeapProfile starts pprof for heap
|
||||
func WriteHeapProfile(dataDir string) string { //nolint: deadcode
|
||||
err := profiling.WriteHeapFile(dataDir)
|
||||
return makeJSONResponse(err)
|
||||
}
|
||||
|
||||
func makeJSONResponse(err error) string {
|
||||
errString := ""
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
errString = err.Error()
|
||||
}
|
||||
|
||||
out := APIResponse{
|
||||
Error: errString,
|
||||
}
|
||||
outBytes, _ := json.Marshal(out)
|
||||
|
||||
return string(outBytes)
|
||||
}
|
||||
|
||||
// SendDataNotification sends push notifications by given tokens.
|
||||
// dataPayloadJSON is a JSON string that looks like this:
|
||||
// {
|
||||
// "data": {
|
||||
// "msg-v2": {
|
||||
// "from": "0x2cea3bd5", // hash of sender (first 10 characters/4 bytes of sha3 hash)
|
||||
// "to": "0xb1f89744", // hash of recipient (first 10 characters/4 bytes of sha3 hash)
|
||||
// "id": "0x872653ad", // message ID hash (first 10 characters/4 bytes of sha3 hash)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
func SendDataNotification(dataPayloadJSON, tokensArray string) (result string) {
|
||||
var (
|
||||
err error
|
||||
errString string
|
||||
)
|
||||
|
||||
defer func() {
|
||||
out := SendDataNotificationResult{
|
||||
Status: err == nil,
|
||||
Error: errString,
|
||||
}
|
||||
|
||||
var resultBytes []byte
|
||||
|
||||
resultBytes, err = json.Marshal(out)
|
||||
if err != nil {
|
||||
logger.Error("failed to marshal SendDataNotification output", "error", err)
|
||||
result = makeJSONResponse(err)
|
||||
return
|
||||
}
|
||||
|
||||
result = string(resultBytes)
|
||||
}()
|
||||
|
||||
tokens, err := ParseJSONArray((tokensArray))
|
||||
if err != nil {
|
||||
errString = err.Error()
|
||||
return ""
|
||||
}
|
||||
|
||||
err = statusBackend.SendDataNotification(dataPayloadJSON, tokens...)
|
||||
if err != nil {
|
||||
errString = err.Error()
|
||||
return ""
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// UpdateMailservers updates mail servers in status backend.
|
||||
//export UpdateMailservers
|
||||
func UpdateMailservers(data string) string {
|
||||
var enodes []string
|
||||
err := json.Unmarshal([]byte(data), &enodes)
|
||||
if err != nil {
|
||||
return makeJSONResponse(err)
|
||||
}
|
||||
err = statusBackend.UpdateMailservers(enodes)
|
||||
return makeJSONResponse(err)
|
||||
}
|
||||
|
||||
// AddPeer adds an enode as a peer.
|
||||
func AddPeer(enode string) string {
|
||||
err := statusBackend.StatusNode().AddPeer(enode)
|
||||
return makeJSONResponse(err)
|
||||
}
|
||||
|
||||
// ConnectionChange handles network state changes as reported
|
||||
// by ReactNative (see https://facebook.github.io/react-native/docs/netinfo.html)
|
||||
func ConnectionChange(typ string, expensive int) {
|
||||
statusBackend.ConnectionChange(typ, expensive == 1)
|
||||
}
|
||||
|
||||
// AppStateChange handles app state changes (background/foreground).
|
||||
func AppStateChange(state string) {
|
||||
statusBackend.AppStateChange(state)
|
||||
}
|
||||
|
||||
// SetMobileSignalHandler setup geth callback to notify about new signal
|
||||
// used for gomobile builds
|
||||
func SetMobileSignalHandler(handler SignalHandler) {
|
||||
signal.SetMobileSignalHandler(func(data []byte) {
|
||||
if len(data) > 0 {
|
||||
handler.HandleSignal(string(data))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// SetSignalEventCallback setup geth callback to notify about new signal
|
||||
func SetSignalEventCallback(cb unsafe.Pointer) {
|
||||
signal.SetSignalEventCallback(cb)
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
package statusgo
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// APIResponse generic response from API.
|
||||
type APIResponse struct {
|
||||
Error string `json:"error"`
|
||||
}
|
||||
|
||||
// APIDetailedResponse represents a generic response
|
||||
// with possible errors.
|
||||
type APIDetailedResponse struct {
|
||||
Status bool `json:"status"`
|
||||
Message string `json:"message,omitempty"`
|
||||
FieldErrors []APIFieldError `json:"field_errors,omitempty"`
|
||||
}
|
||||
|
||||
// Error string representation of APIDetailedResponse.
|
||||
func (r APIDetailedResponse) Error() string {
|
||||
buf := bytes.NewBufferString("")
|
||||
|
||||
for _, err := range r.FieldErrors {
|
||||
buf.WriteString(err.Error() + "\n") // nolint: gas
|
||||
}
|
||||
|
||||
return strings.TrimSpace(buf.String())
|
||||
}
|
||||
|
||||
// APIFieldError represents a set of errors
|
||||
// related to a parameter.
|
||||
type APIFieldError struct {
|
||||
Parameter string `json:"parameter,omitempty"`
|
||||
Errors []APIError `json:"errors"`
|
||||
}
|
||||
|
||||
// Error string representation of APIFieldError.
|
||||
func (e APIFieldError) Error() string {
|
||||
if len(e.Errors) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
buf := bytes.NewBufferString(fmt.Sprintf("Parameter: %s\n", e.Parameter))
|
||||
|
||||
for _, err := range e.Errors {
|
||||
buf.WriteString(err.Error() + "\n") // nolint: gas
|
||||
}
|
||||
|
||||
return strings.TrimSpace(buf.String())
|
||||
}
|
||||
|
||||
// APIError represents a single error.
|
||||
type APIError struct {
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
// Error string representation of APIError.
|
||||
func (e APIError) Error() string {
|
||||
return fmt.Sprintf("message=%s", e.Message)
|
||||
}
|
||||
|
||||
// AccountInfo represents account's info.
|
||||
type AccountInfo struct {
|
||||
Address string `json:"address"` // DEPRECATED
|
||||
PubKey string `json:"pubkey"` // DEPRECATED
|
||||
WalletAddress string `json:"walletAddress"`
|
||||
WalletPubKey string `json:"walletPubKey"`
|
||||
ChatAddress string `json:"chatAddress"`
|
||||
ChatPubKey string `json:"chatPubKey"`
|
||||
Mnemonic string `json:"mnemonic"`
|
||||
Error string `json:"error"`
|
||||
}
|
||||
|
||||
// NotifyResult is a JSON returned from notify message.
|
||||
type NotifyResult struct {
|
||||
Status bool `json:"status"`
|
||||
Error string `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
// SignalHandler defines a minimal interface
|
||||
// a signal handler needs to implement.
|
||||
type SignalHandler interface {
|
||||
HandleSignal(string)
|
||||
}
|
||||
|
||||
// SendDataNotificationResult is a JSON returned from notify message.
|
||||
type SendDataNotificationResult struct {
|
||||
Status bool `json:"status"`
|
||||
Error string `json:"error,omitempty"`
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package statusgo
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
// ParseJSONArray parses JSON array into Go array of string.
|
||||
func ParseJSONArray(items string) ([]string, error) {
|
||||
var parsedItems []string
|
||||
err := json.Unmarshal([]byte(items), &parsedItems)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return parsedItems, nil
|
||||
}
|
|
@ -165,6 +165,7 @@ func TestStatusNodeAddPeer(t *testing.T) {
|
|||
NoDiscovery: true,
|
||||
ListenAddr: ":0",
|
||||
},
|
||||
NoUSB: true,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, peer.Start())
|
||||
|
@ -200,6 +201,7 @@ func TestStatusNodeReconnectStaticPeers(t *testing.T) {
|
|||
NoDiscovery: true,
|
||||
ListenAddr: ":0",
|
||||
},
|
||||
NoUSB: true,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, peer.Start())
|
||||
|
|
|
@ -79,6 +79,8 @@ func TestGetFilterChangesResetsTimer(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetFilterLogs(t *testing.T) {
|
||||
t.Skip("Skipping due to flakiness: https://github.com/status-im/status-go/issues/1281")
|
||||
|
||||
tracker := new(callTracker)
|
||||
api := &PublicAPI{
|
||||
filters: make(map[rpc.ID]filter),
|
||||
|
|
|
@ -98,6 +98,7 @@ func (s *ShhExtSuite) SetupTest() {
|
|||
MaxPeers: 1,
|
||||
ListenAddr: ":0",
|
||||
},
|
||||
NoUSB: true,
|
||||
}
|
||||
stack, err := node.New(cfg)
|
||||
s.NoError(err)
|
||||
|
@ -198,6 +199,7 @@ func (s *ShhExtSuite) TestRequestMessagesErrors() {
|
|||
MaxPeers: math.MaxInt32,
|
||||
NoDiscovery: true,
|
||||
},
|
||||
NoUSB: true,
|
||||
}) // in-memory node as no data dir
|
||||
s.NoError(err)
|
||||
err = aNode.Register(func(*node.ServiceContext) (node.Service, error) {
|
||||
|
@ -285,6 +287,7 @@ func (s *ShhExtSuite) TestRequestMessagesSuccess() {
|
|||
MaxPeers: math.MaxInt32,
|
||||
NoDiscovery: true,
|
||||
},
|
||||
NoUSB: true,
|
||||
}) // in-memory node as no data dir
|
||||
s.Require().NoError(err)
|
||||
err = aNode.Register(func(*node.ServiceContext) (node.Service, error) { return shh, nil })
|
||||
|
@ -312,6 +315,7 @@ func (s *ShhExtSuite) TestRequestMessagesSuccess() {
|
|||
NoDiscovery: true,
|
||||
ListenAddr: ":0",
|
||||
},
|
||||
NoUSB: true,
|
||||
}) // in-memory node as no data dir
|
||||
s.Require().NoError(err)
|
||||
err = mailNode.Register(func(*node.ServiceContext) (node.Service, error) {
|
||||
|
|
207
signal/signals.c
207
signal/signals.c
|
@ -1,208 +1,3 @@
|
|||
#if defined(IOS_DEPLOYMENT)
|
||||
// ======================================================================================
|
||||
// iOS framework compilation using xgo
|
||||
// ======================================================================================
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <objc/objc.h>
|
||||
#include <objc/runtime.h>
|
||||
#include <objc/message.h>
|
||||
|
||||
static id statusServiceClassRef = nil;
|
||||
static SEL statusServiceSelector = nil;
|
||||
|
||||
static bool initLibrary() {
|
||||
if (statusServiceClassRef == nil) {
|
||||
statusServiceClassRef = objc_getClass("Status");
|
||||
if (statusServiceClassRef == nil) return false;
|
||||
}
|
||||
|
||||
if (statusServiceSelector == nil) {
|
||||
statusServiceSelector = sel_getUid("signalEvent:");
|
||||
if (statusServiceSelector == nil) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* @brief Calls static method signalEvent of class GethService.
|
||||
*
|
||||
* @param jsonEvent - UTF8 string
|
||||
*
|
||||
* @note Definition of signalEvent method.
|
||||
* + (void)signalEvent:(const char *)json
|
||||
*/
|
||||
bool StatusServiceSignalEvent(const char *jsonEvent) {
|
||||
if (!initLibrary()) return false;
|
||||
|
||||
void (*action)(id, SEL, const char *) = (void (*)(id, SEL, const char *)) objc_msgSend;
|
||||
action(statusServiceClassRef, statusServiceSelector, jsonEvent);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SetEventCallback(void *cb) {
|
||||
}
|
||||
|
||||
#elif defined(ANDROID_DEPLOYMENT)
|
||||
// ======================================================================================
|
||||
// Android archive compilation using xgo
|
||||
// ======================================================================================
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <jni.h>
|
||||
|
||||
bool StatusServiceSignalEvent(const char *jsonEvent);
|
||||
|
||||
static JavaVM *gJavaVM = NULL;
|
||||
static jclass JavaClassPtr_StatusService = NULL;
|
||||
static jmethodID JavaMethodPtr_signalEvent = NULL;
|
||||
|
||||
static bool JniLibraryInit(JNIEnv *env);
|
||||
|
||||
/*!
|
||||
* @brief Get interface to JNI.
|
||||
*
|
||||
* @return true if thread should be detached from JNI.
|
||||
*/
|
||||
static bool JniAttach(JNIEnv **env) {
|
||||
jint status;
|
||||
|
||||
if (gJavaVM == NULL) {
|
||||
env = NULL;
|
||||
}
|
||||
|
||||
status = (*gJavaVM)->GetEnv(gJavaVM, (void **)env, JNI_VERSION_1_6);
|
||||
if (status == JNI_EDETACHED) {
|
||||
// attach thread to JNI
|
||||
//(*gJavaVM)->AttachCurrentThread( gJavaVM, (void **)env, NULL ); // Oracle JNI API
|
||||
(*gJavaVM)->AttachCurrentThread(gJavaVM, env, NULL); // Android JNI API
|
||||
return true;
|
||||
} else if (status != JNI_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief The VM calls JNI_OnLoad when the native library is loaded.
|
||||
*/
|
||||
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
|
||||
bool detach;
|
||||
JNIEnv *env;
|
||||
int result = JNI_VERSION_1_6;
|
||||
|
||||
gJavaVM = vm;
|
||||
|
||||
// attach thread to JNI
|
||||
detach = JniAttach(&env);
|
||||
if (env == NULL) {
|
||||
// failed
|
||||
gJavaVM = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!JniLibraryInit(env)) {
|
||||
// fail loading of JNI library
|
||||
result = 0;
|
||||
}
|
||||
|
||||
if (detach) {
|
||||
// detach thread from JNI
|
||||
(*gJavaVM)->DetachCurrentThread(gJavaVM);
|
||||
}
|
||||
|
||||
if (result != JNI_VERSION_1_6) {
|
||||
gJavaVM = NULL;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Initialize library.
|
||||
*/
|
||||
bool JniLibraryInit(JNIEnv *env) {
|
||||
int i;
|
||||
|
||||
JavaClassPtr_StatusService = (*env)->FindClass(env, "im/status/ethereum/module/StatusService");
|
||||
if (JavaClassPtr_StatusService == NULL) return false;
|
||||
|
||||
JavaClassPtr_StatusService = (jclass)(*env)->NewGlobalRef(env, JavaClassPtr_StatusService);
|
||||
if (JavaClassPtr_StatusService == NULL) return false;
|
||||
|
||||
struct {
|
||||
bool bStatic;
|
||||
jclass classPtr;
|
||||
jmethodID *methodPtr;
|
||||
const char *methodId;
|
||||
const char *params;
|
||||
} javaMethodDescriptors[] = {
|
||||
{
|
||||
true,
|
||||
JavaClassPtr_StatusService,
|
||||
&JavaMethodPtr_signalEvent, // &JavaMethodPtr_someNonStaticMethod
|
||||
"signalEvent", // someNonStaticMethod
|
||||
"(Ljava/lang/String;)V"
|
||||
},
|
||||
};
|
||||
|
||||
for (i = 0; i < sizeof(javaMethodDescriptors) / sizeof(javaMethodDescriptors[0]); i++) {
|
||||
if (javaMethodDescriptors[i].bStatic) {
|
||||
*(javaMethodDescriptors[i].methodPtr) = (*env)->GetStaticMethodID(
|
||||
env, javaMethodDescriptors[i].classPtr, javaMethodDescriptors[i].methodId, javaMethodDescriptors[i].params);
|
||||
} else {
|
||||
*(javaMethodDescriptors[i].methodPtr) = (*env)->GetMethodID(
|
||||
env, javaMethodDescriptors[i].classPtr, javaMethodDescriptors[i].methodId, javaMethodDescriptors[i].params);
|
||||
}
|
||||
|
||||
if (*(javaMethodDescriptors[i].methodPtr) == NULL) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Calls static method signalEvent of class im.status.ethereum.module.StatusService.
|
||||
*
|
||||
* @param jsonEvent - UTF8 string
|
||||
*/
|
||||
bool StatusServiceSignalEvent(const char *jsonEvent) {
|
||||
bool detach;
|
||||
JNIEnv *env;
|
||||
|
||||
// attach thread to JNI
|
||||
detach = JniAttach( &env );
|
||||
if (env == NULL) { // failed
|
||||
return false;
|
||||
}
|
||||
|
||||
jstring javaJsonEvent = NULL;
|
||||
if (jsonEvent != NULL) {
|
||||
javaJsonEvent = (*env)->NewStringUTF(env, jsonEvent);
|
||||
}
|
||||
|
||||
(*env)->CallStaticVoidMethod(env, JavaClassPtr_StatusService, JavaMethodPtr_signalEvent, javaJsonEvent);
|
||||
|
||||
if (javaJsonEvent != NULL) (*env)->DeleteLocalRef(env, javaJsonEvent);
|
||||
|
||||
if (detach) { // detach thread from JNI
|
||||
(*gJavaVM)->DetachCurrentThread(gJavaVM);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SetEventCallback(void *cb) {
|
||||
}
|
||||
|
||||
#else
|
||||
// ======================================================================================
|
||||
// cgo compilation (for desktop platforms and local tests)
|
||||
// ======================================================================================
|
||||
|
@ -228,5 +23,3 @@ bool StatusServiceSignalEvent(const char *jsonEvent) {
|
|||
void SetEventCallback(void *cb) {
|
||||
gCallback = (callback)cb;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -18,6 +18,12 @@ import (
|
|||
"github.com/ethereum/go-ethereum/log"
|
||||
)
|
||||
|
||||
// MobileSignalHandler is a simple callback function that gets called when any signal is received
|
||||
type MobileSignalHandler func([]byte)
|
||||
|
||||
// storing the current signal handler here
|
||||
var mobileSignalHandler MobileSignalHandler
|
||||
|
||||
// All general log messages in this package should be routed through this logger.
|
||||
var logger = log.New("package", "status-go/signal")
|
||||
|
||||
|
@ -44,9 +50,15 @@ func send(typ string, event interface{}) {
|
|||
return
|
||||
}
|
||||
|
||||
str := C.CString(string(data))
|
||||
C.StatusServiceSignalEvent(str)
|
||||
C.free(unsafe.Pointer(str))
|
||||
// If a Go implementation of signal handler is set, let's use it.
|
||||
if mobileSignalHandler != nil {
|
||||
mobileSignalHandler(data)
|
||||
} else {
|
||||
// ...and fallback to C implementation otherwise.
|
||||
str := C.CString(string(data))
|
||||
C.StatusServiceSignalEvent(str)
|
||||
C.free(unsafe.Pointer(str))
|
||||
}
|
||||
}
|
||||
|
||||
// NodeNotificationHandler defines a handler able to process incoming node events.
|
||||
|
@ -93,7 +105,14 @@ func TriggerTestSignal() {
|
|||
C.free(unsafe.Pointer(str))
|
||||
}
|
||||
|
||||
// SetMobileSignalHandler sets new handler for geth events
|
||||
// this function uses pure go implementation
|
||||
func SetMobileSignalHandler(handler MobileSignalHandler) {
|
||||
mobileSignalHandler = handler
|
||||
}
|
||||
|
||||
// SetSignalEventCallback set callback
|
||||
// this function uses C implementation (see `signals.c` file)
|
||||
func SetSignalEventCallback(cb unsafe.Pointer) {
|
||||
C.SetEventCallback(cb)
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ func createNode() (*node.Node, error) {
|
|||
MaxPeers: 1,
|
||||
NAT: nat.Any(),
|
||||
},
|
||||
NoUSB: true,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ func NewDevNode(faucet common.Address) (*node.Node, error) {
|
|||
cfg.IPCPath = ipc.Name()
|
||||
cfg.HTTPModules = []string{"eth"}
|
||||
cfg.DataDir = ""
|
||||
cfg.NoUSB = true
|
||||
cfg.P2P.MaxPeers = 0
|
||||
cfg.P2P.ListenAddr = ":0"
|
||||
cfg.P2P.NoDiscovery = true
|
||||
|
|
Loading…
Reference in New Issue