Android: 在项目中编译tunsocks和libevent的方法

最近被宽带运营商在网页中添加的广告烦的实在是没办法了,决定自己去写一个广告过滤的软件。找到了一个tunsocks的软件,这个软件可以与tun网络设备进行数据交换:

tunsocks is a user-level SOCKS and port forwarding proxy for use with VPNs that typically interact with tun devices. Rather than passing bytes to and from the tun device, they can pass the data to and from this user-level program. tunsocks is implemented using lwIP.

其他相关的信息请看这里:https://github.com/russdill/tunsocks

编译tunsocks需要用到libevent,  并且代码中也没有提及所使用的版本号,下载libevent的最新代码:

https://github.com/libevent/libevent

  • 相关版本信息

1. Android 项目:这里使用的是android-6.0.1_r65

2. tunsocks版本:

commit 2a85b5ffda7adfeabaa2369a02acbfc4e085b30d
Author: Russ Dill <Russ.Dill@gmail.com>
Date:   Wed Mar 1 00:39:22 2017 -0800

    Fix bind ip/port parsing
    
    This cleans up and fixes a bug in ip/port parsing where the two
    would get switched on -D 0.0.0.0:8080
    
    Signed-off-by: Russ Dill <Russ.Dill@gmail.com>

3. libevent版本:

commit b1e8a4138f0da3c8a4bc303ff72b620b41c066d6
Author: Azat Khuzhin <a3at.mail@gmail.com>
Date:   Tue Mar 14 13:33:31 2017 +0300

    cmake: use APPEND during exporting targets (for old cmake)
    
    On centos with cmake 2.8.12.2:
      CMake Error at cmake/AddEventLibrary.cmake:92 (export):
        export called with target "event_extra_shared" which requires target
        "event_core_shared" that is not in the export list.
    
        If the required target is not easy to reference in this call, consider
        using the APPEND option with multiple separate calls.
    
    But on newer cmake I guess everything is ok.
    
    Fixes: 7182c2f561570cd9ceb704623ebe9ae3608c7b43 ("cmake: build SHARED
    and STATIC libraries (like autoconf does)")

  • 配置编译环境

1. 配置Android项目编译环境

$ . build/envsetup.sh
$ lunch m_e_arm-eng
  • 编译 libevent

这里参考的是这篇文档:http://stackoverflow.com/questions/11655911/cross-compiling-libevent-for-android

a. 执行autogen.sh生成相关的配置文件

$ ./autogen.sh 
autoreconf: Entering directory `.'
autoreconf: configure.ac: not using Gettext
autoreconf: running: /opt/local/bin/aclocal --force -I m4
autoreconf: configure.ac: tracing
autoreconf: running: /opt/local/bin/glibtoolize --copy --force
glibtoolize: putting auxiliary files in '.'.
glibtoolize: copying file './ltmain.sh'
glibtoolize: putting macros in AC_CONFIG_MACRO_DIRS, 'm4'.
glibtoolize: copying file 'm4/libtool.m4'
glibtoolize: copying file 'm4/ltoptions.m4'
glibtoolize: copying file 'm4/ltsugar.m4'
glibtoolize: copying file 'm4/ltversion.m4'
glibtoolize: copying file 'm4/lt~obsolete.m4'
autoreconf: running: /opt/local/bin/autoconf --force
autoreconf: running: /opt/local/bin/autoheader --force
autoreconf: running: /opt/local/bin/automake --add-missing --copy --force-missing
configure.ac:25: installing './compile'
configure.ac:33: installing './config.guess'
configure.ac:33: installing './config.sub'
configure.ac:13: installing './install-sh'
configure.ac:13: installing './missing'
Makefile.am: installing './depcomp'
parallel-tests: installing './test-driver'
autoreconf: Leaving directory `.'

b. 执行如下命令进行配置

$ ./configure --host=arm-linux-androideabi \
    CC=arm-linux-androideabi-gcc LD=arm-linux-androideabi-ld \
    CPPFLAGS="-I$(gettop)/prebuilts/ndk/9/platforms/android-18/arch-arm/usr/include/" \
    CFLAGS="-nostdlib" \
    LDFLAGS="-Wl,-rpath-link=$(gettop)/prebuilts/ndk/9/platforms/android-18/arch-arm/usr/lib/ -L$(gettop)/prebuilts/ndk/9/platforms/android-18/arch-arm/usr/lib/" \
    LIBS="-lc" \
    --disable-openssl --disable-thread-support --disable-malloc-replacement --disable-libevent-regress --disable-samples --disable-static
#! /bin/bash
set -e -x

NDK_ROOT=${NDK_ROOT:-/Volumes/droid/ndk-dev/android-ndk-r13b}

PATH=${PATH}:${NDK_ROOT}/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin

./configure --host=arm-linux-androideabi \
    CC=arm-linux-androideabi-gcc LD=arm-linux-androideabi-ld \
    CFLAGS="--sysroot=${NDK_ROOT}/platforms/android-21/arch-arm" \
    CPPFLAGS="-I${NDK_ROOT}/platforms/android-21/arch-arm/usr/include" \
    LDFLAGS="-Wl,-rpath-link=${NDK_ROOT}/platforms/android-21/arch-arm/usr/lib -L${NDK_ROOT}/platforms/android-21/arch-arm/usr/lib" \
    --disable-openssl \
	--disable-thread-support \
	--disable-malloc-replacement \
	--disable-libevent-regress \
	--disable-samples \
	--disable-shared

c. 生成include/event2/event-config.h文件

$ make include/event2/event-config.h

d. 编写Android.mk文件

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := libevent
LOCAL_MODULE_TAGS := optional
LOCAL_UNINSTALLABLE_MODULE := true

LOCAL_SRC_FILES := \
	buffer.c \
	bufferevent.c \
	bufferevent_filter.c \
	bufferevent_pair.c \
	bufferevent_ratelim.c \
	bufferevent_sock.c \
	event.c \
	evmap.c \
	evthread.c \
	evutil.c \
	evutil_rand.c \
	evutil_time.c \
	listener.c \
	log.c

LOCAL_SRC_FILES += \
	epoll.c \
	evdns.c \
	event_tagging.c \
	evrpc.c \
	http.c \
	poll.c \
	select.c \
	signal.c

LOCAL_C_INCLUDES := \
	$(LOCAL_PATH)/include \
	$(LOCAL_PATH)/compat

include $(BUILD_SHARED_LIBRARY)

之后就可以通过mm命令编译了。

NOTE:

如果通过make命令编译代码的话,编译时会报如下错误:

 extern int fcntl(int, int, ...);
            ^
  CCLD     libevent.la
/prj/droid-6.0.1_r65/prebuilts/gcc/darwin-x86/arm/arm-linux-androideabi-4.9/bin/../lib/gcc/arm-linux-androideabi/4.9.x-google/../../../../arm-linux-androideabi/bin/ld: error: cannot open crtbegin_so.o: No such file or directory
/prj/droid-6.0.1_r65/prebuilts/gcc/darwin-x86/arm/arm-linux-androideabi-4.9/bin/../lib/gcc/arm-linux-androideabi/4.9.x-google/../../../../arm-linux-androideabi/bin/ld: error: cannot open crtend_so.o: No such file or directory
collect2: error: ld returned 1 exit status
make[1]: *** [libevent.la] Error 1
make: *** [all] Error 2

可以将crtbegin_so.o与crtend_so.o这两个文件考贝到当前目录:

$ ln -sv $(gettop)/prebuilts/ndk/9/platforms/android-18/arch-arm/usr/lib/crtbegin_so.o
$ ln -sv $(gettop)/prebuilts/ndk/9/platforms/android-18/arch-arm/usr/lib/crtend_so.o
  • 编译tunsocks代码

编写Android.mk文件:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := tunsocks
LOCAL_MODULE_TAGS := optional
LOCAL_UNINSTALLABLE_MODULE := true

LOCAL_SRC_FILES := \
	lwip/src/api/err.c \
	lwip/src/core/init.c \
	lwip/src/core/def.c \
	lwip/src/core/mem.c \
	lwip/src/core/memp.c \
	lwip/src/core/netif.c \
	lwip/src/core/pbuf.c \
	lwip/src/core/stats.c \
	lwip/src/core/dns.c \
	lwip/src/core/udp.c \
	lwip/src/core/sys.c \
	lwip/src/core/raw.c \
	lwip/src/core/tcp.c \
	lwip/src/core/tcp_in.c \
	lwip/src/core/tcp_out.c \
	lwip/src/core/inet_chksum.c \
	lwip/src/core/ipv4/icmp.c \
	lwip/src/core/ipv4/ip4.c \
	lwip/src/core/ipv4/ip4_addr.c \
	lwip/src/core/ipv4/ip_frag.c \
	src/libevent.c \
	src/socks4.c \
	src/socks5.c \
	src/socks.c \
	src/forward_local.c \
	src/forward_remote.c \
	src/tunif.c \
	src/pipe.c \
	src/host.c \

LOCAL_SRC_FILES += \
	src/main.c

LOCAL_C_INCLUDES := \
	$(LOCAL_PATH)/lwip/src/include \
	$(LOCAL_PATH)/lwip/src/include/ipv4 \
	$(LOCAL_PATH)/lwip/src/include/ipv6 \
	$(LOCAL_PATH)/include

LOCAL_C_INCLUDES += \
	$(LOCAL_PATH)/libevent/include

LOCAL_SHARED_LIBRARIES := \
	libevent

include $(BUILD_EXECUTABLE)

include $(call all-makefiles-under,$(LOCAL_PATH))

执行mm命令一次可一次编译通过!

  • 相关的参考文档
  1. http://stackoverflow.com/questions/11655911/cross-compiling-libevent-for-android
  2. https://github.com/russdill/tunsocks

发表评论

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