shadowsocks-android:源码编译打包-详细版

(Last Updated On: 2019-01-03) 之前写的有点过于简洁了,而且官方版本项目也已经更新了一些,改也不好改,这里干脆做个详细一点的版本。

0.准备

  • 项目地址:GitHub
  • JDK 1.8
  • Go 1.11+
  • Android SDK 、Android NDK r19+
本人环境为:系统macOS 10.14.2 mojave,AndroidStudio版本3.2.1,gradle版本4.10.2-all,go随便用的1.11.4,其他直接用项目默认的配置。然而最近的版本默认使用的是gradle5.0版本,与我的AndroidStudio 3.2.1 不兼容,会导致报错。

1.Android环境

JDK 单独下载安装,AndroidStudio安装好后顺便下好Android SDK。NDK r19 beta可以到这里下载,解压即可。

2.go环境

因为需要go 1.11以上,所以本人重新用brew安装/升级了一遍go,Windows系统或者Linux的也只需要按照golang官方指南,或者用相关的包管理器来安装。然后配置一下环境变量。
#1 brew 安装go
brew install go

#2 配置环境变量,用户目录下的.bash_profile,可以用vim,也可以用编辑器改
cd ~
vim .bash_profile

#3 配置类似下面的内容,根据自己的情况设置安装目录GOROOT和GOPATH
export GOROOT=/usr/local/Cellar/go/1.11.4/libexec
export GOPATH=~/go
export GOBIN=/usr/local/opt/go/libexec/bin
export PATH=$PATH:$GOBIN

#4 保存,命令行生效
source .bash_profile

#5 查看go版本和环境
go version
go env

3.go无法下载的依赖

由于限制问题,国内使用、安装 golang 官方包可能会失败,使用 golang 在 github 上建立的一个镜像库 ,这里主要将net、sys、crypto、text包clone下来到GOPATH中使用,还需要对应go版本,默认是最新版1.11,如果需要匹配不同的版本,则可以clone不同的版本分支。
#在GOPATH在创建目录
mkdir -p $GOPATH/src/golang.org/x
cd $GOPATH/src/golang.org/x

#下载依赖
git clone https://github.com/golang/net.git

git clone https://github.com/golang/sys.git

git clone https://github.com/golang/crypto.git

git clone https://github.com/golang/text.git

4.修改core的GOPATH

之前的版本还有一个自定义GOPATH字段 GOROOT_BOOTSTRAP,后面的一些提交后移除了:remove custom go
项目的默认GOPATH是core模块下,如果不改项目的GOPATH,可以将上面第三步的依赖下载到core/src/overture/src/(golang.org/x/...),这里还是改成自定义的GOPATH。

# shadowsocks-android/core/src/overture/make.bash 16行
# 改成自己的GOPATH
 # export GOPATH=$DIR        #注释或者删除这一行
 export GOPATH = ${GOROOT}   #新增自己的路径

1.下载源码

可以直接连同子模块一起clone:
git clone --recurse-submodules https://github.com/shadowsocks/shadowsocks-android.git

也可以分两步,先clone主项目,再update submodules
#1 clone主项目
git clone https://github.com/shadowsocks/shadowsocks-android.git

#输出:
Cloning into 'shadowsocks-android'...
remote: Enumerating objects: 80, done.
remote: Counting objects: 100% (80/80), done.
remote: Compressing objects: 100% (43/43), done.
remote: Total 31509 (delta 28), reused 58 (delta 20), pack-reused 31429
Receiving objects: 100% (31509/31509), 51.33 MiB | 708.00 KiB/s, done.
Resolving deltas: 100% (15110/15110), done.

#2 进入项目目录
cd shadowsocks-android

#3 更新submodule
git submodule update --init --recursive

#输出
Submodule 'core/src/main/jni/badvpn' (https://github.com/shadowsocks/badvpn.git) registered for path 'core/src/main/jni/badvpn'
Submodule 'core/src/main/jni/libancillary' (https://github.com/shadowsocks/libancillary.git) registered for path 'core/src/main/jni/libancillary'
Submodule 'core/src/main/jni/libev' (https://github.com/shadowsocks/libev.git) registered for path 'core/src/main/jni/libev'
Submodule 'core/src/main/jni/libevent' (https://github.com/shadowsocks/libevent.git) registered for path 'core/src/main/jni/libevent'
Submodule 'core/src/main/jni/libsodium' (https://github.com/jedisct1/libsodium.git) registered for path 'core/src/main/jni/libsodium'
Submodule 'core/src/main/jni/mbedtls' (https://github.com/ARMmbed/mbedtls) registered for path 'core/src/main/jni/mbedtls'
Submodule 'core/src/main/jni/pcre' (https://android.googlesource.com/platform/external/pcre) registered for path 'core/src/main/jni/pcre'
Submodule 'core/src/main/jni/redsocks' (https://github.com/shadowsocks/redsocks.git) registered for path 'core/src/main/jni/redsocks'
Submodule 'core/src/main/jni/shadowsocks-libev' (https://github.com/shadowsocks/shadowsocks-libev) registered for path 'core/src/main/jni/shadowsocks-libev'
Submodule 'core/src/overture/src/github.com/shadowsocks/overture' (https://github.com/shadowsocks/overture.git) registered for path 'core/src/overture/src/github.com/shadowsocks/overture'
Cloning into '/Users/water/Desktop/git/android/shadowsocks-android-20181230/shadowsocks-android/core/src/main/jni/badvpn'...
Cloning into '/Users/water/Desktop/git/android/shadowsocks-android-20181230/shadowsocks-android/core/src/main/jni/libancillary'...
Cloning into '/Users/water/Desktop/git/android/shadowsocks-android-20181230/shadowsocks-android/core/src/main/jni/libev'...
Cloning into '/Users/water/Desktop/git/android/shadowsocks-android-20181230/shadowsocks-android/core/src/main/jni/libevent'...
Cloning into '/Users/water/Desktop/git/android/shadowsocks-android-20181230/shadowsocks-android/core/src/main/jni/libsodium'...
Cloning into '/Users/water/Desktop/git/android/shadowsocks-android-20181230/shadowsocks-android/core/src/main/jni/mbedtls'...
Cloning into '/Users/water/Desktop/git/android/shadowsocks-android-20181230/shadowsocks-android/core/src/main/jni/pcre'...
Cloning into '/Users/water/Desktop/git/android/shadowsocks-android-20181230/shadowsocks-android/core/src/main/jni/redsocks'...
Cloning into '/Users/water/Desktop/git/android/shadowsocks-android-20181230/shadowsocks-android/core/src/main/jni/shadowsocks-libev'...
Cloning into '/Users/water/Desktop/git/android/shadowsocks-android-20181230/shadowsocks-android/core/src/overture/src/github.com/shadowsocks/overture'...
Submodule path 'core/src/main/jni/badvpn': checked out '4c0050878618423da53e7e335fbb55ec2af6be06'
Submodule path 'core/src/main/jni/libancillary': checked out '311e5d14f593f16c785bc6605220517eb1f21f6b'
Submodule path 'core/src/main/jni/libev': checked out '5213419011ec5de302f8bc1716f348de1fb53b12'
Submodule path 'core/src/main/jni/libevent': checked out 'f29f07bc8c43eec96f227e6f6eede32b3af66168'
Submodule path 'core/src/main/jni/libsodium': checked out 'fec4c92d81189e0394ad94e14f238a837c81385e'
Submodule path 'core/src/main/jni/mbedtls': checked out '4f0929189ab43e020b0d441919abf6bab02baf11'
Submodule path 'core/src/main/jni/pcre': checked out '222bbf4b3fb8e13c21686803e47e31aa3e4ad130'
Submodule path 'core/src/main/jni/redsocks': checked out '274334f14839431ae003774d99c3d1de337afff4'
Submodule path 'core/src/main/jni/shadowsocks-libev': checked out '91222766e793a6d1516ac066984b63069594e0bf'
Submodule 'libbloom' (https://github.com/shadowsocks/libbloom.git) registered for path 'core/src/main/jni/shadowsocks-libev/libbloom'
Submodule 'libcork' (https://github.com/shadowsocks/libcork.git) registered for path 'core/src/main/jni/shadowsocks-libev/libcork'
Submodule 'libipset' (https://github.com/shadowsocks/ipset.git) registered for path 'core/src/main/jni/shadowsocks-libev/libipset'
Cloning into '/Users/water/Desktop/git/android/shadowsocks-android-20181230/shadowsocks-android/core/src/main/jni/shadowsocks-libev/libbloom'...
Cloning into '/Users/water/Desktop/git/android/shadowsocks-android-20181230/shadowsocks-android/core/src/main/jni/shadowsocks-libev/libcork'...
Cloning into '/Users/water/Desktop/git/android/shadowsocks-android-20181230/shadowsocks-android/core/src/main/jni/shadowsocks-libev/libipset'...
Submodule path 'core/src/main/jni/shadowsocks-libev/libbloom': checked out '7a9deb893fc1646c0b9186b50d46358379953d4b'
Submodule path 'core/src/main/jni/shadowsocks-libev/libcork': checked out '8e37949dccae43bc9045bffea97fa6ac4e0305ce'
Submodule path 'core/src/main/jni/shadowsocks-libev/libipset': checked out '3ea7fe30adf4b39b27d932e5a70a2ddce4adb508'
Submodule path 'core/src/overture/src/github.com/shadowsocks/overture': checked out 'ffc00f97fa7663a91011a10e46ae954cfda3837f'


2.编译core

编译有2种方式,本质是一样的,一种是在terminal里面执行:
#指定编译core模块
./gradlew -p core clean build

另一种则是使用AndroidStudio插件的快捷菜单:
#省略一大堆日志
10 warnings generated.
13 warnings generated.
[armeabi-v7a] Executable     : libtun2socks.so
Build redsocks armeabi-v7a
[armeabi-v7a] Compile thumb  : redsocks <= base.c
[armeabi-v7a] Compile thumb  : redsocks <= http-connect.c
[armeabi-v7a] Compile thumb  : redsocks <= log.c
[armeabi-v7a] Compile thumb  : redsocks <= md5.c
[armeabi-v7a] Compile thumb  : redsocks <= socks5.c
[armeabi-v7a] Compile thumb  : redsocks <= base64.c
[armeabi-v7a] Compile thumb  : redsocks <= http-auth.c
[armeabi-v7a] Compile thumb  : redsocks <= http-relay.c
[armeabi-v7a] Compile thumb  : redsocks <= main.c
[armeabi-v7a] Compile thumb  : redsocks <= parser.c
[armeabi-v7a] Compile thumb  : redsocks <= redsocks.c
[armeabi-v7a] Compile thumb  : redsocks <= socks4.c
[armeabi-v7a] Compile thumb  : redsocks <= utils.c
[armeabi-v7a] Compile thumb  : event <= buffer.c
[armeabi-v7a] Compile thumb  : event <= bufferevent.c
[armeabi-v7a] Compile thumb  : event <= event.c
[armeabi-v7a] Compile thumb  : event <= bufferevent_sock.c
[armeabi-v7a] Compile thumb  : event <= bufferevent_ratelim.c
[armeabi-v7a] Compile thumb  : event <= evthread.c
[armeabi-v7a] Compile thumb  : event <= log.c
[armeabi-v7a] Compile thumb  : event <= evutil.c
[armeabi-v7a] Compile thumb  : event <= evutil_time.c
[armeabi-v7a] Compile thumb  : event <= evmap.c
[armeabi-v7a] Compile thumb  : event <= epoll.c
[armeabi-v7a] Compile thumb  : event <= poll.c
[armeabi-v7a] Compile thumb  : event <= signal.c
[armeabi-v7a] Compile thumb  : event <= select.c
[armeabi-v7a] StaticLibrary  : libevent.a
[armeabi-v7a] Executable     : libredsocks.so
Build jni-helper armeabi-v7a
[armeabi-v7a] Compile thumb  : cpufeatures <= cpu-features.c
[armeabi-v7a] Compile++ thumb: jni-helper <= jni-helper.cpp
[armeabi-v7a] StaticLibrary  : libcpufeatures.a
[armeabi-v7a] SharedLibrary  : libjni-helper.so
warn: removing resource com.github.shadowsocks.core:string/night_mode without required default value.
warn: removing resource com.github.shadowsocks.core:string/night_mode_auto without required default value.
warn: removing resource com.github.shadowsocks.core:string/night_mode_off without required default value.
warn: removing resource com.github.shadowsocks.core:string/night_mode_on without required default value.
warn: removing resource com.github.shadowsocks.core:string/night_mode_system without required default value.
warn: removing resource com.github.shadowsocks.core:string/received without required default value.
warn: removing resource com.github.shadowsocks.core:string/sent without required default value.


> Task :core:lint
Ran lint on variant debug: 111 issues found
Ran lint on variant release: 111 issues found
Wrote HTML report to file:///Users/water/Desktop/git/android/shadowsocks-android-20181230/shadowsocks-android/core/build/reports/lint-results.html
Wrote XML report to file:///Users/water/Desktop/git/android/shadowsocks-android-20181230/shadowsocks-android/core/build/reports/lint-results.xml

BUILD SUCCESSFUL in 3m 6s
109 actionable tasks: 93 executed, 16 up-to-date


可以看到core模块下overture/bin目录编译出cpu架构相关的.so文件

3.运行调试

运行调试,不出意外,可以看到App运行效果。(包名冲突,需要改包名或者将官方包卸载)。Instant Run不是很支持,建议先将其关闭,菜单路径在 preference -> Build, Execution, Deployment -> Instant run

4.相关错误与处理

Failed to notify build listener

Cause: org.jetbrains.plugins.gradle.tooling.util.ModuleComponentIdentifierImpl.getModuleIdentifier()Lorg/gradle/api/artifacts/ModuleIdentifier;

原因:gradle与android.buildtool版本不兼容,项目默认的gradle 5.0 与本人使用的AndroidStudio3.2.1 以及插件com.android.tools.build:gradle:3.2.1 不兼容,将gradle改为4.10.2或者其他低一点的版本即可。
WARNING: ABIs [arm64-v8a,armeabi-v7a,armeabi] set by 'android.injected.build.abi' gradle flag contained 'ARMEABI' not targeted by this project.

原因:缺少对应的so文件,需要先成功编译core模块
Fetching https://golang.org/x/net/proxy?go-get=1
https fetch failed: Get https://golang.org/x/net/proxy?go-get=1: dial tcp 216.239.37.1:443: i/o timeout
package golang.org/x/net/proxy: unrecognized import path "golang.org/x/net/proxy" (https fetch: Get https://golang.org/x/net/proxy?go-get=1: dial tcp 216.239.37.1:443: i/o timeout)
Cross compile overture for arm
../../../Sirupsen/logrus/terminal_check_notappengine.go:9:2: cannot find package "golang.org/x/crypto/ssh/terminal" in any of:
    /usr/local/go/src/golang.org/x/crypto/ssh/terminal (from $GOROOT)
    /Users/water/Desktop/git/android/shadowsocks-android-20181230/shadowsocks-android/core/src/overture/src/golang.org/x/crypto/ssh/terminal (from $GOPATH)
../core/outbound/client.go:15:2: cannot find package "golang.org/x/net/proxy" in any of:
    /usr/local/go/src/golang.org/x/net/proxy (from $GOROOT)
    /Users/water/Desktop/git/android/shadowsocks-android-20181230/shadowsocks-android/core/src/overture/src/golang.org/x/net/proxy (from $GOPATH)

> Task :core:goBuild FAILED

原因:go部分依赖无法加载,使用前面手动的方法下载部分依赖,如果已经下载,检查$GOPATH路径是否正确。 其他的问题可以自行根据错误日志去搜索答案,或者留言讨论,欢迎指教。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

Solve : *
9 + 27 =


此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据