一 过程

过程参考:https://wiki.strongswan.org/projects/strongswan/wiki/AndroidVPNClientBuild

1 准备工作:

安装所需要的软件包:参考:https://wiki.strongswan.org/projects/strongswan/repository/entry/HACKING

For interested developers, we have a public repository. To check out and compile
the code, you need the following tools:
    - Git
    - a recent GNU C compiler (>= 3.x)
    - automake
    - autoconf
    - libtool
    - pkg-config
    - gettext
    - perl
    - python
    - lex/flex
    - yacc/bison
    - gperf

注意:缺少一个软件包都不能编译成功

2 下载

1)下载strongswan:

路径下面两个都可以:

git://git.strongswan.org/strongswan.git

https://github.com/strongswan/strongswan/tree/master

git clone git://git.strongswan.org/strongswan.git

2)下载openssl:

我直接从其他地方下载的,复制到/strongswan/src/frontends/android/app/src/main/jni目录下

也可以按照文档中说的:

git clone git://git.strongswan.org/android-ndk-openssl.git -b ndk-static jni/openssl



3) 开始编译

cd strongswan
./autogen.sh
./configure
make dist

编译成功后导入android studio中编译运行,在这个过程,我遇到了好多问题,主要原因都是第一步准备工作中的软件包没有下载完全。



二 问题

1 在android studio编译的时候报错:

1)缺少oid.h文件

Error:make: *** No rule to make target `/strongswan/src/frontends/android/app/src/main/jni/../../../../../../..//src/libstrongswan/asn1/oid.c', needed by `/strongswan/src/frontends/android/app/src/main/obj/local/arm64-v8a/objs/strongswan/asn1/oid.o'.  Stop.
make: *** Waiting for unfinished jobs....
/strongswan/src/frontends/android/app/src/main/jni/../../../../../../..//src/libstrongswan/asn1/asn1.c:24:10: fatal error: 'oid.h' file not found
#include "oid.h"
         ^~~~~~~
1 error generated.
make: *** [/strongswan/src/frontends/android/app/src/main/obj/local/arm64-v8a/objs/strongswan/asn1/asn1.o] Error 1
FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:buildNative'.
> Process 'command '/ndk-bundle/ndk-build'' finished with non-zero exit value 2

原因:这是直接在android studio中编译的,由于类似oid.h这种文件都需要先使用make dist来生成。虽然下载的release版本的包中有这些文件,但是并没有安卓源码,但是从git中下载的版本并没有这些文件,需要自己一步一步下载配置编译strongswan源码,参照上面的过程。

解决方法:按照上面的过程从头来。


2)直接报如下错误

Error:Execution failed for task ':app:buildNative'.
> Process 'command '/ndk-bundle/ndk-build'' finished with non-zero exit value 2

原因:我在强行将release版本中的头文件复制到从git上下载的对应目录中,就报错如上,猜测不知道哪些文件缺失,但是又找不到实在的问题。

解决方法:按照上面的过程从头来。并没有尝试将安卓平台源码放入release版本中,可以试试。。



2 命令行运行autogen.sh报错

1) 缺少automake库

$ ./autogen.sh
Can't exec "aclocal": No such file or directory at /usr/local/Cellar/autoconf/2.69/share/autoconf/Autom4te/FileUtils.pm line 326.
autoreconf: failed to run aclocal: No such file or directory

原因:缺少automake库

解决方法:安装automake

brew install automake



2)需要aclocal做配置

$ ./autogen.sh
configure.ac:37: error: possibly undefined macro: AC_DEFINE
      If this token and others are legitimate, please use m4_pattern_allow.
      See the Autoconf documentation.
configure.ac:38: error: possibly undefined macro: AC_DISABLE_STATIC
configure.ac:78: error: possibly undefined macro: AC_SUBST
configure.ac:362: error: possibly undefined macro: AC_LIB_PREFIX
autoreconf: /usr/local/Cellar/autoconf/2.69/bin/autoconf failed with exit status: 1

原因:

解决方法:先运行下面命令,再重新执行,我在之后的编译过程中总是遇到这个错误,都是直接先运行下面命令,再执行autogen.sh即可。

aclocal -I m4


3)缺少库libtool

src/libimcv/plugins/imv_hcd/Makefile.am:10:   If 'LT_INIT' is in 'configure.ac', make sure
src/libimcv/plugins/imv_hcd/Makefile.am:10:   its definition is in aclocal's search path.
src/libimcv/plugins/imv_os/Makefile.am:10: error: Libtool library used but 'LIBTOOL' is undefined

原因:

解决方法:安装libtool,自此我发现我有很多软件包都没有安装,防止还出现这种缺失某个库的问题,安装上面准备工作中所有列出来的库。

brew install libtool



3 执行命令 ./configure 报错

./configure: line 19880: syntax error near unexpected token `soup,'
./configure: line 19880: `	PKG_CHECK_MODULES(soup, libsoup-2.4)'

原因:此时就算安装libsoup库都没有用,原因是宏未定义


把安装目录下的m4宏文件复制到项目的m4文件夹中,重新执行autoreconf命令。 


使用autoreconf -I /usr/share/aclocal同样可以解决问题,不过,对于有些开源项目自带m4宏文件,而这些宏文件和系统安装的版本不一致时,同样会出现问题,所以最好的方式是把需要的宏文件复制到m4文件夹中更好。


重新生成以下configure就可以了

执行如下:

aclocal -I m4
autoreconf -I /usr/local/Cellar/automake/1.16.1/share/aclocal
aclocal -I m4
./autogen.sh

其中上面的aclocal是我的安装路径,需要换成自己的路径

autogen.sh命令执行成功结果如下:

strongSwan will be built with the following plugins
-----------------------------------------------------
libstrongswan: aes des rc2 sha2 sha1 md5 mgf1 random nonce x509 revocation constraints pubkey pkcs1 pkcs7 pkcs8 pkcs12 pgp dnskey sshkey pem fips-prf gmp curve25519 xcbc cmac hmac
libcharon:     attr kernel-netlink resolve socket-default stroke vici updown xauth-generic counters
libtnccs:     
libtpmtss:



4 执行命令make dist 报错

1)使用bison解析报错

/crypto/proposal/proposal_keywords_static.txt > crypto/proposal/proposal_keywords_static.c
/bin/sh ../../ylwrap settings/settings_parser.y y.tab.c settings/settings_parser.c y.tab.h `echo settings/settings_parser.c | sed -e s/cc$/hh/ -e s/cpp$/hpp/ -e s/cxx$/hxx/ -e s/c++$/h++/ -e s/c$/h/` y.output settings/settings_parser.output -- bison -y -v -d 
/strongswan/src/libstrongswan/settings/settings_parser.y:68.9-16: syntax error, unexpected identifier, expecting string
make[5]: *** [settings/settings_parser.c] Error 1
make[4]: *** [distdir-am] Error 1
make[3]: *** [distdir] Error 2
make[2]: *** [distdir-am] Error 1
make[1]: *** [distdir] Error 2
make: *** [dist] Error 2

执行到这一步已经产生了proposal_keywords_static.h和.c文件,这是上面问题1所缺失过的文件。

原因:由于bison版本不同,相关语法也不同,从生成的代码对比来看,release版本的strongswan-5.6.2版本使用的bison 2.3版本,而我下载的版本是3.0.4,但是不知道为什么我在使用android studio编译后,bison的环境变量就改到了2.3版本的bison路径

解决方法:不过当前的问题还是需要解决的,按照报错的位置,修改相关语法:

报错1:%define api.pure:修改为:%pure-parser,(虽然报错%define后面需要跟字符串,但是从生成的文件结果来看,修改为“%define "api.pure"”是没有用的,如果成功了生成的文件应该有“#define YYPURE 1”)
报错2:%name-prefix "settings_parser_" 函数名前缀,如果不设置默认为yy(如:yytokentype),修改为%name-prefix= "settings_parser_"

修改上面的问题的时候,可以直接直接下面命令测试,生成文件y.tab.h和y.tab.c:

$ cd /strongswan/src/libstrongswan/settings 
$ bison -y -v -d ./settings_parser.y



2)问题如上,另外一个文件

-- bison -y -v -d 
/strongswan/src/starter/parser/parser.y:62.9-16: syntax error, unexpected identifier, expecting string
make[5]: *** [parser/parser.c] Error 1
make[4]: *** [distdir-am] Error 1
make[3]: *** [distdir] Error 2
make[2]: *** [distdir-am] Error 1
make[1]: *** [distdir] Error 2
make: *** [dist] Error 2

原因:


解决方法:按上面方法将%define api.pure:修改为:%pure-parser


3)此处不报错,只有warning,但是在android studio中编译的时候会报错:Error:error: use of undeclared identifier '$NAME'; did you mean 'NAME'?这会导致后面使用android studio编译的时候,报错不识别$NAME等变量

./settings_parser.y:117.34: warning: stray `$'
./settings_parser.y:115.9-118.9: warning: unused value: $1

原因:说明$1等变量没有用到,而$NAME等用法不识别


解决方法:修改为对应的$1, $2, $3,根据不同的参数值修改,目前还没有找到方法会可以直接使用$NAME等变量,如果有方法希望可以告诉我。

%%

/**
 * strongswan.conf grammar rules
 */
statements:
	/* empty */
	| statements NEWLINE
	| statements statement
	;

statement:
	section
	{
        //add_setting(ctx, $setting);
		add_section(ctx, $1);
	}
	| setting
	{
        //add_setting(ctx, $setting);
        add_setting(ctx, $1);
	}
	;

section:
	section_start statements '}'
	{
		pop_section(ctx);
       // $$ = $section_start;
        $$ = $1;
	}
	;

section_start:
	NAME '{'
	{
        //$$ = push_section(ctx, $NAME);
        $$ = push_section(ctx, $1);
	}
	|
	NAME NEWLINE '{'
	{
        //$$ = push_section(ctx, $NAME);
        $$ = push_section(ctx, $1);
	}
	;

setting:
	NAME '=' value
	{
       // $$ = settings_kv_create($NAME, $value);
        $$ = settings_kv_create($1, $3);
	}
	|
	NAME '='
	{
       // $$ = settings_kv_create($NAME, NULL);
        $$ = settings_kv_create($1, NULL);
	}
	;

value:
	valuepart
	| value valuepart
	{	/* just put a single space between them, use strings for more */
		if (asprintf(&$$, "%s %s", $1, $2) < 0)
		{
			free($1);
			free($2);
			YYERROR;
		}
		free($1);
		free($2);
	}
	;

valuepart:
	NAME
	| STRING
	;

%%