Building OpenSSH using Android's NDK

Geoff Taylor openssh-unix-dev at opinionatedgeek.com
Thu Jun 18 00:08:22 AEST 2015


Hi,

(I hope this is the right list for this problem. My apologies if it's
not - can you please send me details of where I should post this
instead?)

tl;dr: I'd appreciate some help getting OpenSSH 6.8p1 to build using
Android's Native Development Kit. I've put together a Docker container
with the build environment if you want to try building it yourself
without changing your existing build setup.

I wanted to get an OpenSSH binary for an app I'm playing around with,
so I thought I'd try building OpenSSH6.8 using the Android NDK. It
didn't go well, and I'm hoping someone can point me in the right
direction. (I couldn't find any documents detailing how to build on
Android so if they exist please do let me know.) The problems and
error messages are detailed below.

To avoid any environmental differences, I've created a basic Docker
image for cross compilation. If you use Docker, you should be able to
grab it, start it, and have the latest NDK set up for cross-compiling
Android binaries. The Docker image is called
'opinionatedgeek/android-ndk-10e' on the Hub, and /src is available
for mapping so you don't lose changes when you stop the image.
Alternatively you can just view/copy the Dockerfile from:
    https://registry.hub.docker.com/u/opinionatedgeek/android-ndk-10e/dockerfile/

Once the Docker image is running, here are all the commands I used to
build OpenSSH:

----****----****----

# Some environment variables for building OpenSSL.
export FIPS_SIG=$PWD/openssl-fips-2.0.2/util/incore
export MACHINE=armv7l
export RELEASE=2.6.37
export SYSTEM=android
export ARCH=arm
export ANDROID_DEV="$ANDROID_NDK/platforms/android-21/arch-arm/usr"
export HOSTCC=gcc

# Get OpenSSL source code.
cd /src
wget https://www.openssl.org/source/openssl-1.0.2c.tar.gz
tar zxvf openssl-1.0.2c.tar.gz

# Build OpenSSL - this seems to go OK.
cd /src/openssl-1.0.2c
./config shared no-ssl2 no-ssl3 no-comp no-hw no-engine
--openssldir=/usr/local/ssl/$ANDROID_API
make depend
make all

# Get OpenSSH source code.
cd /src
wget http://mirror.ox.ac.uk/pub/OpenBSD/OpenSSH/portable/openssh-6.8p1.tar.gz
tar zxvf openssh-6.8p1.tar.gz

# Build OpenSSH.
cd /src/openssh-6.8p1
./configure --host=arm-linux-androideabi --with-ssl-dir=/src/openssl-1.0.2c
make all

----****----****----

The final line fails. It's a known problem, but when I fix that
another problem appears, and then another, and it got to the stage
that I wasn't comfortable with the horrible changes I was making to
work around the errors.

I'm new to both OpenSSH and Android NDK but, either:
* The environment is bad in some way.
* The configure command is wrong. (I've tried variants without success.)
* The 6.8p1 release isn't expected to build using the standard Android
NDK version 10e.
* There's an actual problem with building the source code.

(I'm hoping it's one of the first two options.)

Here are some of the errors I get:

----****----****----

(cd openbsd-compat && make)
make[1]: Entering directory '/src/openssh-6.8p1/openbsd-compat'
/android-ndk-r10e/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc
--sysroot=/android-ndk-r10e/platforms/android-21/arch-arm/ -Wall
-Wpointer-arith -Wuninitialized -Wsign-compare -Wformat-security
-Wsizeof-pointer-memaccess -Wno-pointer-sign -Wno-unused-result
-fno-strict-aliasing -D_FORTIFY_SOURCE=2 -ftrapv -fno-builtin-memset
-fstack-protector-strong  -I. -I.. -I. -I./..
-I/src/openssl-1.0.2c/include
--sysroot=/android-ndk-r10e/platforms/android-21/arch-arm/
-DHAVE_CONFIG_H -c arc4random.c
In file included from ../includes.h:177:0,
                 from arc4random.c:27:
../openbsd-compat/openbsd-compat.h:224:22: error: expected identifier
or '(' before numeric constant
 # define mblen(x, y) 1
                      ^
Makefile:26: recipe for target 'arc4random.o' failed
make[1]: *** [arc4random.o] Error 1
make[1]: Leaving directory '/src/openssh-6.8p1/openbsd-compat'
Makefile:156: recipe for target 'openbsd-compat/libopenbsd-compat.a' failed
make: *** [openbsd-compat/libopenbsd-compat.a] Error 2

----****----****----

Changing:

# define mblen(x, y)  1

to:

# define mblen(x, y)  (1)

(as per Bugzilla) didn't fix this for me, but this allowed the build
to continue:

#define mblen innocuous_mblen

The next problem:

----****----****----

/android-ndk-r10e/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc
--sysroot=/android-ndk-r10e/platforms/android-21/arch-arm/ -Wall
-Wpointer-arith -Wuninitialized -Wsign-compare -Wformat-security
-Wsizeof-pointer-memaccess -Wno-pointer-sign -Wno-unused-result
-fno-strict-aliasing -D_FORTIFY_SOURCE=2 -ftrapv -fno-builtin-memset
-fstack-protector-strong  -I. -I.. -I. -I./..
-I/src/openssl-1.0.2c/include
--sysroot=/android-ndk-r10e/platforms/android-21/arch-arm/
-DHAVE_CONFIG_H -c getrrsetbyname.c
getrrsetbyname.c: In function 'getrrsetbyname':
getrrsetbyname.c:190:59: error: dereferencing pointer to incomplete type
  struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
                                                           ^
getrrsetbyname.c:68:33: note: in definition of macro '_THREAD_PRIVATE'
 #define _THREAD_PRIVATE(a,b,c) (c)
                                 ^
getrrsetbyname.c:219:12: error: dereferencing pointer to incomplete type
  if ((_resp->options & RES_INIT) == 0 && res_init() == -1) {
            ^
getrrsetbyname.c:219:24: error: 'RES_INIT' undeclared (first use in
this function)
  if ((_resp->options & RES_INIT) == 0 && res_init() == -1) {
                        ^
getrrsetbyname.c:219:24: note: each undeclared identifier is reported
only once for each function it appears in
getrrsetbyname.c:219:2: warning: implicit declaration of function
'res_init' [-Wimplicit-function-declaration]
  if ((_resp->options & RES_INIT) == 0 && res_init() == -1) {
  ^
getrrsetbyname.c:235:2: warning: implicit declaration of function
'res_query' [-Wimplicit-function-declaration]
  length = res_query(hostname, (signed int) rdclass, (signed int) rdtype,
  ^
Makefile:26: recipe for target 'getrrsetbyname.o' failed
make[1]: *** [getrrsetbyname.o] Error 1
make[1]: Leaving directory '/src/openssh-6.8p1/openbsd-compat'
Makefile:156: recipe for target 'openbsd-compat/libopenbsd-compat.a' failed
make: *** [openbsd-compat/libopenbsd-compat.a] Error 2

----****----****----

looked more serious. When I worked around this problem, more problems
appeared and really, the workaround itself was just plain wrong. (The
workaround that allowed me to continue building involved copying in
structs, enums and defines from the regular resolv.h on Ubuntu.) It
was then I figured I should ask for help.

For the record, the next build error was:

----****----****----

/android-ndk-r10e/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc
--sysroot=/android-ndk-r10e/platforms/android-21/arch-arm/ -Wall
-Wpointer-arith -Wuninitialized -Wsign-compare -Wformat-security
-Wsizeof-pointer-memaccess -Wno-pointer-sign -Wno-unused-result
-fno-strict-aliasing -D_FORTIFY_SOURCE=2 -ftrapv -fno-builtin-memset
-fstack-protector-strong  -I. -I.. -I. -I./..
-I/src/openssl-1.0.2c/include
--sysroot=/android-ndk-r10e/platforms/android-21/arch-arm/
-DHAVE_CONFIG_H -c pwcache.c
In file included from pwcache.c:37:0:
/android-ndk-r10e/platforms/android-21/arch-arm/usr/include/grp.h:59:21:
error: macro "endgrent" passed 1 arguments, but takes just 0
 void   endgrent(void);
                     ^
Makefile:26: recipe for target 'pwcache.o' failed
make[1]: *** [pwcache.o] Error 1
make[1]: Leaving directory '/src/openssh-6.8p1/openbsd-compat'
Makefile:156: recipe for target 'openbsd-compat/libopenbsd-compat.a' failed
make: *** [openbsd-compat/libopenbsd-compat.a] Error 2

----****----****----

So, should it build or am I doing something wrong? I tried pulling the
latest code from git too, but didn't have any more success getting it
to build.

Any help would be appreciated.

Many thanks,

    Geoff


More information about the openssh-unix-dev mailing list