Cross compile Python for Android

前置作業 & 注意事項

  1. 產生要移植平台相對應的 standalone toolchain ,參考 Android API level (系統版本) 傳送門
  2. cross compile relative libs. link
  3. 修正 cross compile 與 auto conf 期間產生的錯誤
  4. 注意編譯需將 libs 都編譯成 static mode. (non-dynamic mode) 目的是可以方便使用,缺點是檔案大小會較大,不過動態連結,缺點是在入時會呼叫外部的 *.so 檔,Linux 底下的動態連函式庫(Dynamic link library)。(DLL) 但是手機的路徑與 Linux 預設路徑是不同的,所以使用 static mode 不外部呼叫 DLL 是最保險,不然還要去處理載入外部的路徑問題。
  5. 下載 Python source code,也可以使用 MEGA 載點的,已經修正錯誤。
  6. 如果使用自行下載的 source 編譯與 auto conf 發生錯誤,可以自行參考MEGA 載點中的 source 裡的檔案,看是如何修改的。

Python-2.7.1

  1. MEGA 載點或 Python 官網下載 source code
  2. 若從MEGA上下載,可以跳過這一點。這一點是上 patch ,MEGA 載點裡有這個檔案可以使用:python-2.7.1-cross-compile.patch
  3. 編譯 host 版本的 Python
  4. 把產生執行檔改成:
    mv python hostpython
    mv Parser/pgen Parser/hostpgen
  5. 按照下面的 android-configure bash script file

#上 patch,第 2 點

patch -p1 < /path/to/python-2.7.1-cross-compile.patch


#android-configure

#!/bin/bash

export TOOLCHAIN=/home/lab501/android-toolchain-16
export PATH=$TOOLCHAIN/bin:$PATH
export CC=$TOOLCHAIN/bin/arm-linux-androideabi-gcc
export CXX=$TOOLCHAIN/bin/arm-linux-androideabi-g++
export RANLIB=$TOOLCHAIN/bin/arm-linux-androideabi-ranlib
export AR=$TOOLCHAIN/bin/arm-linux-androideabi-ar
export LD=$TOOLCHAIN/bin/arm-linux-androideabi-ld
export STRIP=$TOOLCHAIN/bin/arm-linux-androideabi-strip
export ARCH="arm-linux-androideabi"
#export LD_LIBRARY_PATH="/data/local/tmp/_install_python/lib"
#change your shared libs'(libpython.so) path (LDFLAGS= --rpath)

./configure \
     LDFLAGS="-static -static-libgcc -fPIE -pie" \
    CFLAGS="-static -fPIE -pie" \
    --host=arm-linux-androideabi \
    --target=arm-linux-androideabi \
    --disable-shared \
    --prefix="/home/lab501/android-cross-compile-16/Python-2.7.1/_install"

make \
    HOSTPYTHON=/home/lab501/Python-2.7.1/hostpython \
    HOSTPGEN=/home/lab501/Python-2.7.1/Parser/hostpgen \
    CROSS_COMPILE=androideabi \
    CROSS_COMPILE_TARGET=yes \
    BLDSHARED="arm-linux-androideabi-gcc -shared" \

#make install...
#make -i install \
    #HOSTPYTHON=/home/lab501/Python-2.7.1/hostpython \
    #BLDSHARED="arm-linux-androideabi-gcc -shared" \
    #CROSS_COMPILE=androideabi \
    #CROSS_COMPILE_TARGET=yes

修改:setup.py 檔,設定如何 build modules

#for example, build hashlib modules
#只加入下面這兩行
#find_library_file(self.compiler, 'Modules',lib_dirs,
#       ['/home/lab501/Python-2.7.1/Modules'] )

if have_any_openssl:
#if have_usable_openssl:
# The _hashlib module wraps optimized implementations
# of hash functions from the OpenSSL library.
#comment this code. In order to cross compile hashlib.
#exts.append( Extension('_hashlib', ['_hashopenssl.c'],
# include_dirs = ssl_incs,
# library_dirs = ssl_libs,
# libraries = ['ssl', 'crypto']) )

#add this code. In order to cross compile hashlib. Important
find_library_file(self.compiler, 'Modules',lib_dirs,
['/home/lab501/Python-2.7.1/Modules'] )
#else:
# print ("warning: openssl 0x%08x is too old for _hashlib" %
# openssl_ver)
# missing.append('_hashlib')
#if COMPILED_WITH_PYDEBUG or not have_usable_openssl:
# The _sha module implements the SHA1 hash algorithm.
#comment this code. In order to cross compile hashlib.
#exts.append( Extension('_hashlib', ['shamodule.c']) )
# The _md5 module implements the RSA Data Security, Inc. MD5

參考資料

How-to-Cross-Compile-Python-and-Run-in-Embedded-System

howto-cross-compile-python-25

後記

build modules :要自己去調整 setup.py 要試試看,有可能會調整失敗,try and error.

 

Cross compile MySQL for Android

前置作業 & 注意事項

  1. 產生要移植平台相對應的 standalone toolchain ,參考 Android API level (系統版本) 傳送門
  2. cross compile relative libs. link
  3. 修正 cross compile 與 auto conf 期間產生的錯誤
  4. 注意編譯需將 libs 都編譯成 static mode. (non-dynamic mode) 目的是可以方便使用,缺點是檔案大小會較大,不過動態連結,缺點是在入時會呼叫外部的 *.so 檔,Linux 底下的動態連函式庫。(DLL) 但是手機的路徑與 Linux 預設路徑是不同的,所以使用 static mode 不外部呼叫 DLL 是最保險,不然還要去處理載入外部的路徑問題。
  5. 下載 lighttpd 與  PHP source code,也可以使用 MEGA 載點的,已經修正錯誤。
  6. 如果使用自行下載的 source 編譯與 auto conf 發生錯誤,可以自行參考MEGA 載點中的 source 裡的檔案,看是如何修改的。
  7. MySQL source 下載點:http://downloads.mysql.com/archives/community/

version:5.0.22

bash-script for auto conf.


#!/bin/bash

export TOOLCHAIN=/home/lab501/android-toolchain-16
export PATH=$TOOLCHAIN/bin:$PATH
export CC=$TOOLCHAIN/bin/arm-linux-androideabi-gcc
export CXX=$TOOLCHAIN/bin/arm-linux-androideabi-g++
export AR=$TOOLCHAIN/bin/arm-linux-androideabi-ar
export RANLIB=$TOOLCHAIN/bin/arm-linux-androideabi-ranlib
export STRIP=$TOOLCHAIN/bin/arm-linux-androideabi-strip
export CFLAGS="-I$TOOLCHAIN/sysroot/usr/include -fPIE -pie"
export LDFLAGS="-static -L$TOOLCHAIN/sysroot/usr/lib -L$TOOLCHAIN/sysroot/usr/include -fPIE -pie"
export ac_cv_sys_restartable_syscalls="no"

./configure \
--host=arm-linux-androideabi \
--enable-static \
--enable-local-infile \
--with-named-curses-libs=/home/lab501/android-cross-compile-16/ncurses-5.9/_install/lib/libncurses.a \
--with-named-thread-libs=/home/lab501/android-toolchain-16/sysroot/usr/include/pthread.h \
--prefix=/home/lab501/android-cross-compile-16/mysql-5.0.22/_install \
--without-debug \
--without-docs \
--without-plugin-innodb_plugin \
--without-plugin-innobase \
--without-libedit \
--with-readline \
--with-mysqld-user=root \
--with-charset=utf8 \
--with-extra-charsets=big5,gbk,gb2312,utf8,ascii \
--without-man

#make and make install

 

[參考資料]

auto conf 與 make 時期遇到的錯誤:

mysql数据库在arm+linux平台上的移植

setpwent 未定義參考解決方式 (參考文章下方的評論)

undefined reference to `setpwent’

 

Cross compile Lighttpd and PHP for Android

前置作業 & 注意事項

  1. 產生要移植平台相對應的 standalone toolchain ,參考 Android API level (系統版本) 傳送門
  2. cross compile relative libs. link
  3. 修正 cross compile 與 auto conf 期間產生的錯誤
  4. 注意編譯需將 libs 都編譯成 static mode. (non-dynamic mode) 目的是可以方便使用,缺點是檔案大小會較大,不過動態連結,缺點是在入時會呼叫外部的 *.so 檔,Linux 底下的動態連函式庫。(DLL) 但是手機的路徑與 Linux 預設路徑是不同的,所以使用 static mode 不外部呼叫 DLL 是最保險,不然還要去處理載入外部的路徑問題。
  5. 下載 lighttpd 與  PHP source code,也可以使用 MEGA 載點的,已經修正錯誤。
  6. 如果使用自行下載的 source 編譯與 auto conf 發生錯誤,可以自行參考MEGA 載點中的 source 裡的檔案,看是如何修改的。

Lighttpd-1.4.33–a lighweight http server

完成前置作業後,開始使用下面的 android-configure 檔,做 auto conf 產生要編譯 Lighttpd 的 Makefile


#!/bin/bash

export TOOLCHAIN=/home/lab501/android-toolchain
export PATH=$TOOLCHAIN/bin:$PATH
export CC=$TOOLCHAIN/bin/arm-linux-androideabi-gcc
export RANLIB=$TOOLCHAIN/bin/arm-linux-androideabi-ranlib
export STRIP=$TOOLCHAIN/bin/arm-linux-androideabi-strip
export CROSS_COMPILING=yes
export AR=$TOOLCHAIN/bin/arm-linux-androideabi-ar
export LDFLAGS="-L/home/lab501/pcre-8.34/_install/lib -fPIE -pie"
export CFLAGS='-fPIE'

#manual copy pcre.h to /path/to/lighttpd-1.4.33/src/pcre.h

./configure \
 --prefix=/home/lab501/lighttpd-1.4.33/_install \
 --disable-shared \
 --enable-static \
 --with-openssl=/home/lab501/openssl-1.0.1f/_install \
 --with-pcre=/home/lab501/pcre-8.34/_install \
 --with-zlib=/home/lab501/zlib-1.2.8/_install \
 --without-bzip2 \
 --without-lua \
 --host=arm-linux-androideabi

#make and make install

PHP-5.6.17– a hypertext preprocessor


#!/bin/bash

export TOOLCHAIN=/home/lab501/android-toolchain
export PATH=$TOOLCHAIN/bin:$PATH
export CC=$TOOLCHAIN/bin/arm-linux-androideabi-gcc
export CXX=$TOOLCHAIN/bin/arm-linux-androideabi-g++
export AR=$TOOLCHAIN/bin/arm-linux-androideabi-ar
export LD=$TOOLCHAIN/bin/arm-linux-androideabi-ld
export RANLIB=$TOOLCHAIN/bin/arm-linux-androideabi-ranlib
export CFLAGS='-fPIE -pie'
export LDFLAGS='-fPIE -pie'

./configure \
 --prefix=/home/lab501/php-5.6.17/_install \
 --enable-static \
 --disable-shared \
 --disable-all \
 --enable-filter \
 --enable-calendar \
 --enable-ctype \
 --enable-dom \
 --enable-exif \
 --enable-fileinfo \
 --enable-ftp \
 --with-mhash="/home/lab501/mhash-0.9.9.9/_install" \
 --disable-intl \
 --disable-phar \
 --enable-posix \
 --enable-shmop \
 --enable-simplexml \
 --disable-sysvmsg \
 --enable-sysvsem \
 --disable-sysvshm \
 --enable-tokenizer \
 --disable-wddx \
 --enable-xmlreader \
 --enable-xmlwriter \
 --enable-pcntl \
 --enable-soap \
 --enable-cgi \
 --enable-json \
 --with-zlib \
 --enable-zip \
 --with-mysql=mysqlnd \
 --enable-mysqlnd \
 --with-mysqli=mysqlnd \
 --enable-pdo \
 --with-pdo-mysql=mysqlnd \
 --enable-libxml \
 --with-pdo-sqlite \
 --with-sqlite3 \
 --enable-sockets \
 --enable-bcmath \
 --enable-mbstring \
 --enable-mbregex \
 --enable-session \
 --disable-ipv6 \
 --enable-opcache=no \
 --disable-cli \
 --without-pear \
 --enable-fpm \
 --enable-hash \
 --with-bz2="/home/lab501/bzip2-1.0.6/_install" \
 --with-zlib-dir="/home/lab501/zlib-1.2.8/_install" \
 --with-libxml-dir="/home/lab501/libxml2-2.7.6/_install" \
 --with-curl="/home/lab501/curl-7.35.0/_install" \
 --with-openssl="/home/lab501/openssl-1.0.1f/_install" \
 --with-jpeg-dir="/home/lab501/jpeg-9/_install" \
 --with-png-dir="/home/lab501/libpng-1.6.9/_install" \
 --with-freetype-dir="/home/lab501/freetype-2.5.3/_install" \
 --with-iconv-dir="/home/lab501/libiconv-1.14/_install" \
 --with-mcrypt="/home/lab501/libmcrypt-2.5.8/_install" \
 --with-pcre-dir="/home/lab501/pcre-8.34/_install" \
 --host=arm-linux-androideabi

#make and make install

[參考文章]

編輯 android-configure bash script file 參考:

Cross Compile lighttpd & PHP for ARM based embdedded device

編譯時遇到錯誤解決方法參考:

(OK)port_php-5.6.14_to_Android-(和lighttpd的集成成功) -沒有基於Android 4.4系統的源碼

[ 額外 PHP 的錯誤 ]

因為有一些 source 裡面,Android toolchain 本身並沒有定義,所以導致會出現 XXX undelclared . 類似錯誤如下:


/home/lab501/android-cross-compile-16/php-5.6.17/ext/mysql/php_mysql.c: In function 'php_mysql_do_connect':
/home/lab501/android-cross-compile-16/php-5.6.17/ext/mysql/php_mysql.c:757:39: error: 'ushort' undeclared (first use in this function)
MySG(default_port) = (uint) ntohs((ushort) serv_ptr->s_port);

解決方法:

修改 /path/to/android-toolchain-standalone/sysroot/usr/include/sys 底下的 types.h

最下面新增:

/* Old compatibility names for C types. */
typedef unsigned short int ushort;

這兩行

錯誤:’S_IREAD’ undeclared

因為缺少 S_IREAD 與 S_WRITE 定義,因此在路徑:/home/lab501/android-toolchain-16/sysroot/usr/include/linux/stat.h 這個的 header 檔加入:

 
#define S_IRWXU 00700 
#define S_IRUSR 00400 
#define S_IREAD 00400 
#define S_IWUSR 00200 
#define S_IWRITE 00200 
#define S_IXUSR 00100 
#define S_IEXEC 00100 
#define S_IRWXG 00070 
#define S_IRGRP 00040
#define S_IWGRP 00020 
#define S_IXGRP 00010 
#define S_IRWXO 00007 
#define S_IROTH 00004 
#define S_IWOTH 00002 
#define S_IXOTH 00001 

因為還有一些錯誤,經修正過了,所以 將 MEGA 載點中的 android-toolchain-9.tar.bz2 裡的 android-toolchain下的 sysroot 整個目錄 對應 /path/to/your-android-toolchain/sysroot 做覆蓋,修正其他已經修改過的錯誤。

若是只想更動修改的檔案,善用 grep 指令,把有修正過的檔案做 copy 即可。例如:


grep you-find-key-words *.h

[ 後記 ]

  1. 網路上很多文章也是沒有提到錯誤如何修正,就只有參數如何編寫得比較多,遇到錯誤還是需要上網找解法。
  2. 這篇文章最主要是補上了 MEGA 下載點可以供其他人在編譯 source code 時遇到錯誤可以參考。
  3. 我是依照網路上文章的版本做編譯的,並非使用最新的版本,如果要使用最新的版本做編譯,則可以到每個官網去做下載。

Cross compile libraries for Android

前置作業:產生 standalone toolchain

cross compile 需要用到的 libraries.

dependencies:mhash,bz2,zlib,libxml,and more.

下載點:提供修改過後的版本,官方下載點也可,不過有些地方需要自己自行修改,會寫在每個 libs 裡的 bash script file for auto conf. 做註解

bash script file 若是自己編輯的,需要把權限改為可執行檔。(executable) 即:chmod 700 /path/to/android-configure

也可以自行下載其他版本的 libraries 做編譯,如果有遇到錯誤,則可以去 MEGA 載點參考 libraries 中的檔案或是 android-toolchain 裡的檔標頭案。裡面的標頭檔都附已修正過的。

就試著 try and error 吧,改成正確的。

下載點記得把裡面的目錄:_install 刪除並做:make distclean (OpenSSL 是 make dist 與 make clean。 ) 才可以清掉之前編譯的內容與 Makefile。

(也有 Android toolchain 可以參考)

環境變數 TOOLCHAIN 需改成自己正確的路徑與安裝路徑 (–prefix)。

下面各個 source 的 MEGA 載點

souce 目錄裡面的 android-configure 檔案即為下面的各個 libs 的 bash script file

mhash


#!/bin/bash

export TOOLCHAIN=/home/lab501/android-toolchain
export PATH=$TOOLCHAIN/bin:$PATH
export CC=$TOOLCHAIN/bin/arm-linux-androideabi-gcc
export CXX=$TOOLCHAIN/bin/arm-linux-androideabi-g++
export LD=$TOOLCHAIN/bin/arm-linux-androideabi-ld
export AR=$TOOLCHAIN/bin/arm-linux-androideabi-ar
export RANLIB=$TOOLCHAIN/bin/arm-linux-androideabi-ranlib
export ac_cv_func_malloc_0_nonnull=yes

./configure \
 --host=arm-linux-androideabi \
 --disable-shared \
 --enable-static \
 --prefix=/home/lab501/mhash-0.9.9.9/_install

#make and make install

 

bz2

#source code 沒有 configure 直接給 Makefile
#!/bin/bash

TOOLCHAIN=/home/lab501/android-toolchain
PATH=$TOOLCHAIN/bin:$PATH

make install \
 PREFIX=/home/lab501/bzip2-1.0.6/_install \
 CC=$TOOLCHAIN/bin/arm-linux-androideabi-gcc \
 AR=$TOOLCHAIN/bin/arm-linux-androideabi-ar \
 RANLIB=$TOOLCHAIN/bin/arm-linux-androideabi-ranlib

zlib

#!/bin/bash

export TOOLCHAIN=/home/lab501/android-toolchain
export PATH=$TOOLCHAIN/bin:$PATH
export CC=$TOOLCHAIN/bin/arm-linux-androideabi-gcc
export RANLIB=$TOOLCHAIN/bin/arm-linux-androideabi-ranlib

./configure \
 --prefix="/home/lab501/zlib-1.1.3/_install" \
 --static
#make and make install

libxml


#!/bin/bash

export TOOLCHAIN=/home/lab501/android-toolchain
export PATH=$TOOLCHAIN/bin:$PATH
export CC=$TOOLCHAIN/bin/arm-linux-androideabi-gcc
export RANLIB=$TOOLCHAIN/bin/arm-linux-androideabi-ranlib
export AR=$TOOLCHAIN/bin/arm-linux-androideabi-ar
export LD=$TOOLCHAIN/bin/arm-linux-androideabi-ld
export ARCH=arm

~/android-toolchain/bin/arm-linux-androideabi-gcc -c -I/home/lab501/android-toolchain/sysroot/usr/include -I. glob.c \

chmod +x glob.o

export LIBS=$PWD/glob.o

./configure \
 --enable-static \
 --disable-shared \
 --host=arm-linux-androideabi \
 --prefix=/home/lab501/libxml2-2.7.6/_install \
 --without-python \
 --with-iconv=/home/lab501/libiconv-1.14/_install \
 --with-zlib=/home/lab501/zlib-1.2.8/_install \
 --with-readline=/home/lab501/readline-6.2/_install

#make and make install

cURL

 #!/bin/bash

export TOOLCHAIN=/home/lab501/android-toolchain
export PATH=$TOOLCHAIN/bin:$PATH
export CC=$TOOLCHAIN/bin/arm-linux-androideabi-gcc
export CXX=$TOOLCHAIN/bin/arm-linux-androideabi-g++
export RANLIB=$TOOLCHAIN/bin/arm-linux-androideabi-ranlib

./configure \
 --host=arm-linux-androideabi \
 --with-ssl=/home/lab501/openssl-1.0.1f/_install \
 --disable-shared \
 --enable-static \
 --prefix=/home/lab501/curl-7.35.0/_install \
 --with-zlib=/home/lab501/zlib-1.2.8/_install
#make and make install

OpenSSL


#!/bin/bash

export OPENSSL_TARGET=linux-armv4
export TOOLCHAIN=/home/lab501/android-toolchain-16
export PATH=$TOOLCHAIN/bin:$PATH
export CC=$TOOLCHAIN/bin/arm-linux-androideabi-gcc
export AR=$TOOLCHAIN/bin/arm-linux-androideabi-ar
export LD=$TOOLCHAIN/bin/arm-linux-androideabi-ld
export AS=$TOOLCHAIN/bin/arm-linux-androideabi-as
export RANLIB=$TOOLCHAIN/bin/arm-linux-androideabi-ranlib

./Configure $OPENSSL_TARGET no-shared \
 --prefix=/home/lab501/android-cross-compile-16/openssl-1.0.1f/_install \
 --with-zlib-lib=/home/lab501/android-cross-compile-16/zlib-1.2.8/_install/lib \
 --with-zlib-include=/home/lab501/android-cross-compile-16/zlib-1.2.8/_install/include

#make

#make install_sw

 jpeg


#!/bin/bash

export TOOLCHAIN=/home/lab501/android-toolchain
export PATH=$TOOLCHAIN/bin:$PATH
export CC=$TOOLCHAIN/bin/arm-linux-androideabi-gcc
export AR=$TOOLCHAIN/bin/arm-linux-androideabi-ar
export RANLIB=$TOOLCHAIN/bin/arm-linux-androideabi-ranlib

./configure \
 --enable-static \
 --disable-shared \
 --host=arm-linux-androideabi \
 --prefix=/home/lab501/jpeg-9/_install

#make and make install

 

libpng


#!/bin/bash

export TOOLCHAIN=/home/lab501/android-toolchain
export PATH=$TOOLCHAIN/bin:$PATH
export CC=$TOOLCHAIN/bin/arm-linux-androideabi-gcc
export CXX=$TOOLCHAIN/bin/arm-linux-androideabi-g++
export LD=$TOOLCHAIN/bin/arm-linux-androideabi-ld
export AR=$TOOLCHAIN/bin/arm-linux-androideabi-ar
export RANLIB=$TOOLCHAIN/bin/arm-linux-androideabi-ranlib

./configure \
 --enable-static \
 --disable-shared \
 --prefix=/home/lab501/libpng-1.6.9/_install \
 --host=arm-linux-androideabi

#make and make install

 

freetype


#!/bin/bash

export TOOLCHAIN=/home/lab501/android-toolchain
export PATH=$TOOLCHAIN/bin:$PATH
export CC=$TOOLCHAIN/bin/arm-linux-androideabi-gcc
export LD=$TOOLCHAIN/bin/arm-linux-androideabi-ld
export AS=$TOOLCHAIN/bin/arm-linux-androideabi-as
export AR=$TOOLCHAIN/bin/arm-linux-androideabi-ar
export CXX=$TOOLCHAIN/bin/arm-linux-androideabi-g++
export RANLIB=$TOOLCHAIN/bin/arm-linux-androideabi-ranlib

#manual copy libpng header file 手動複製 libpng 相關標頭檔 (header file)

./configure \
 --enable-static \
 --disable-shared \
 --host=arm-linux-androideabi \
 --prefix=/home/lab501/freetype-2.5.3/_install \
 --without-zlib \
 --without-png \
 --without-harfbuzz

#make and make install

 

libiconv


#!/bin/bash

export TOOLCHAIN=/home/lab501/android-toolchain
export PATH=$TOOLCHAIN/bin:$PATH
export CC=$TOOLCHAIN/bin/arm-linux-androideabi-gcc
export AR=$TOOLCHAIN/bin/arm-linux-androideabi-ar
export CXX=$TOOLCHAIN/bin/arm-linux-androideabi-g++
export RANLIB=$TOOLCHAIN/bin/arm-linux-androideabi-ranlib

./configure \
 --host=arm-linux-androideabi \
 --target=arm-linux-androideabi \
 --prefix=/home/lab501/libiconv-1.14/_install \
 --enable-static \
 --disable-shared

#make and make install

 

libmcrypt


#!/bin/bash

export TOOLCHAIN=/home/lab501/android-toolchain
export PATH=$TOOLCHAIN/bin:$PATH
export CC=$TOOLCHAIN/bin/arm-linux-androideabi-gcc
export CXX=$TOOLCHAIN/bin/arm-linux-androideabi-g++
export LD=$TOOLCHAIN/bin/arm-linux-androideabi-ld
export RANLIB=$TOOLCHAIN/bin/arm-linux-androideabi-ranlib
export STRIP=$TOOLCHAIN/bin/arm-linux-androideabi-strip
export AR=$TOOLCHAIN/bin/arm-linux-androideabi-ar
export ac_cv_type_unsigned_long_int=no
export ac_cv_sizeof_unsigned_int=no
export ac_cv_sizeof_unsigned_short_int=no
export ac_cv_sizeof_unsigned_char=no
export ac_cv_func_malloc_0_nonnull=yes
export ac_cv_func_realloc_0_nonnull=yes

./configure \
 --prefix=/home/lab501/libmcrypt-2.5.8/_install \
 --host=arm-linux-androideabi \
 --with-mhash \
 --enable-static \
 --disable-shared

#fix some erros

sed -i "s{SIZEOF_UNSIGNED_CHAR no{SIZEOF_UNSIGNED_CHAR 1{" config.h
sed -i "s{SIZEOF_UNSIGNED_INT no{SIZEOF_UNSIGNED_INT 4{" config.h
sed -i "s{SIZEOF_UNSIGNED_LONG_INT 0{SIZEOF_UNSIGNED_LONG_INT 4{" config.h
sed -i "s{SIZEOF_UNSIGNED_SHORT_INT no{SIZEOF_UNSIGNED_SHORT_INT 2{" config.h

#make and make install

 

pcre


#!/bin/bash

export TOOLCHAIN=/home/lab501/android-toolchain
export PATH=$TOOLCHAIN/bin:$PATH
export CC=$TOOLCHAIN/bin/arm-linux-androideabi-gcc
export AR=$TOOLCHAIN/bin/arm-linux-androideabi-ar
export RANLIB=$TOOLCHAIN/bin/arm-linux-androideabi-ranlib
./configure \
 --enable-static \
 --disable-shared \
 --prefix=/home/lab501/pcre-8.34/_install \
 --host=arm-linux-androideabi \
 --disable-cpp

#make and make install

ncurses


#!/bin/bash

export TOOLCHAIN=/home/lab501/android-toolchain
export PATH=$TOOLCHAIN/bin:$PATH
export CC=$TOOLCHAIN/bin/arm-linux-androideabi-gcc
export AS=$TOOLCHAIN/bin/arm-linux-androideabi-as
export AR=$TOOLCHAIN/bin/arm-linux-androideabi-ar
export LD=$TOOLCHAIN/bin/arm-linux-androideabi-ld
export RANLIB=$TOOLCHAIN/bin/arm-linux-androideabi-ranlib
export ac_cv_header_locale_h=no

./configure \
 --host=arm-linux-androideabi \
 --disable-widec \
 --disable-ext-funcs \
 --without-cxx-binding \
 --without-cxx \
 --without-shared \
 --without-ada \
 --without-tests \
 --without-debug \
 --enable-overwrite \
 --prefix=/home/lab501/ncurses-5.9/_install

#make and make install

 

readline


#!/bin/bash

export TOOLCHAIN=/home/lab501/android-toolchain
export PATH=$TOOLCHAIN/bin:$PATH
export CC=$TOOLCHAIN/bin/arm-linux-androideabi-gcc
export AR=$TOOLCHAIN/bin/arm-linux-androideabi-ar
export RANLIB=$TOOLCHAIN/bin/arm-linux-androideabi-ranlib

./configure \
 --host=arm-linux-androideabi \
 --prefix=/home/lab501/readline-6.2/_install \
 --with-curses=/home/lab501/ncurses-5.9/_install \
 --enable-static

#make and make install

 

[ 編譯 libs 常見的錯誤 ]

  1. #include <xxxx.h> no such file or directory

解法找到哪個標頭檔案出問題,接著去尋找檔案,把有問題檔案裡的 #include 到正確的位置。(通常是用到產生的 standalone Android toolchain 裡的檔案)

可以使用下面指令找到相關位置的路徑檔。只截取有 android-toolchain 相關的 ouput strings .

 locate your-file.h | grep android-toolchain 

    2. undefined reference ‘XXX’ :有標頭檔沒有對應到相對應的參數,需要自行增加。(因為有些預設 Android toolchain 本身就沒有這個參數)

    3. ….parameter ‘xxxx’ no such parameters:沒有相對應的參數,這個錯誤目前出現較少。

4. 在 autoconf 時,出現 cannot recognize stsyem name “arm-linux-androideabi” source 裡附的 config.guess 和 config.sub 版本太舊,解決方式是從附的 MEGA 載點下載一個 libs 拿裡面這兩個檔案做覆蓋。

[ OpenSSL 錯誤 ]


../libcrypto.a(eng_rsax.o): In function `e_rsax_bn_mod_exp':
eng_rsax.c:(.text+0x132f): undefined reference to `mod_exp_512'
../libcrypto.a(eng_rsax.o): In function `e_rsax_rsa_mod_exp':
eng_rsax.c:(.text+0x1c08): undefined reference to `mod_exp_512'
eng_rsax.c:(.text+0x22a8): undefined reference to `mod_exp_512'
../libcrypto.a(e_rc4_hmac_md5.o): In function `rc4_hmac_md5_cipher':
e_rc4_hmac_md5.c:(.text+0x44e): undefined reference to `rc4_md5_enc'
e_rc4_hmac_md5.c:(.text+0x4f1): undefined reference to `rc4_md5_enc'
collect2: error: ld returned 1 exit status
make[2]: *** [link_app.] Error 1
make[2]: Leaving directory `/opt/openssl-1.0.1e/apps'
make[1]: *** [openssl] Error 2
make[1]: Leaving directory `/opt/openssl-1.0.1e/apps'
make: *** [build_apps] Error 1

原因是未設定 target 作業系統,設定成:linux-armv4 即可,可以參考前面的 bash script file for OpenSSL .

[ 參考資料 ]

DroidPHP (與PHP 和 lighttpd 相關 dependencies 內容不齊全,可能是作者還正在撰寫中吧,沒有提到相關編譯的錯誤,只有列出需要編譯的 libs)

build-libxm.sh (bash script file 可以做為 auto conf libxml 的參考)

 

[後記]

網路上很多文章就只有提到參數該怎麼設定,很少提到錯誤怎麼解決,這篇文章算是整個整理過後的心得。

萬一自己編譯有問題或是遇到非上述的 general errors 時,可以從提供的 MEGA 載點下載不同版本的 Android toolchain 參考檔案要如何加註與修改 header 檔中的 preprocessor code。

Cross compile Node.js for Android

產生 toolchain 請參考先前的文章

到 Node.js 官網。如果要跨編譯最新的 preview 版,可以到 Github 網址上下載。

建議到官網下載 stable 版的 source 進行 cross compile. 到官網點選 source code.

參考官方提供的 android-configure 進行修改並 autoconf. 下面是官方預設的參數,若有參考 ./configure –help 產生出說明的文件,發現有一些參數可以加上去,像是  –fully-static 和

–enable-static 等。

不過,當加上 –fully-static ,產生執行檔沒有包含外部的動態l ibs ,使用這個參數的時候,意思是,我在 make 編譯期間會出現錯誤,會出現:/usr/bin/ld: cannot find -llog 目前在 Github 也有類似的問題

當加上 –enable-static 時,是需要 build as static library 將l ibs 函式庫做靜態連結。不過這一步也沒有成功,一開始的 autoconf 就會有問題。

目前這兩個問題沒有解決的方式。

修改如下:(toolchain 依照自己路徑進行修改)

需要:Python 2.7+ (Linux/Ubuntu 內建)pshot

若編譯進去,則在 make 期間會出現類似下列這樣的錯誤:

pi1p/out/Release/mksnapshot: 1: /home/iojs/build/workspace/node-cross-compile/nodes/cross-compiler-pi1p/out/Release/mksnapshot: Syntax error: word unexpected (expecting ")")
#!/bin/bash
 
export TOOLCHAIN=/home/lab501/android-toolchain-16
export PATH=$TOOLCHAIN/bin:$PATH
export AR=$TOOLCHAIN/bin/arm-linux-androideabi-ar
export CC=$TOOLCHAIN/bin/arm-linux-androideabi-gcc
export CXX=$TOOLCHAIN/bin/arm-linux-androideabi-g++
export LINK=$TOOLCHAIN/bin/arm-linux-androideabi-g++
 
./configure \
   --dest-cpu=arm \
   --dest-os=android \
   --without-snapshot \
   --prefix=/home/lab501/node-v4.3.0/_install

編譯 Node.js 版本:v4.3.0
需要:Python 2.7+ (Linux/Ubuntu 內建)

遇到的問題:

也可以設定一些相關的東西讓 snapshot 編進去,不過省麻煩,這裡就不編進去了。這裡編譯用全靜態連結。(static mode)

再來就是 make 和 make install 了,完成之後。會在指定目錄下產生出 node 執行檔。這樣 Node.js 編譯就完成了。

[錯誤]

使用官方參數所遇到的錯誤:在編譯時,呼叫 python 檔做執行時,會 import bz2 沒有找到相關的 module 。

這是一個普通的錯誤 (general error),所以只要:sudo apt-get install libbz2-dev 把套件安裝起來就可以。之後還需要重新編譯 Python 否則會一直出現相同錯誤導致編譯中斷。

雖然可以輸入指令:make 再繼續編譯,一樣會成功,不過這不是一個好的方式。

再來就是要注意,若是自己的電腦上在編譯時有其他 Python 需要的 module 時,也是需要查詢並做安裝。這篇文章沒有出線原因是因為可能之前我做其他事已經把相關的套件做安裝了。

所以這個錯誤是因人而異。

[參考資料]

Android編譯提示ImportError: No module named bz2的解決辦法

[後記]

編譯 Node.js 版本:v0.12.10

下載自Github

需要:Python 2.7+ (Linux/Ubuntu 內建)

./android-configure bash scrit for auto conf.

#!/bin/bash
 
export TOOLCHAIN=/home/lab501/android-toolchain-16
export PATH=$TOOLCHAIN/bin:$PATH
export AR=$TOOLCHAIN/bin/arm-linux-androideabi-ar
export CC=$TOOLCHAIN/bin/arm-linux-androideabi-gcc
export CXX=$TOOLCHAIN/bin/arm-linux-androideabi-g++
export LINK=$TOOLCHAIN/bin/arm-linux-androideabi-g++
 
./configure \
 --dest-cpu=arm \
 --dest-os=android \
 --without-snapshot \
 --prefix=/home/lab501/node/_install

結果:編譯成功,無錯誤,使用 –fully-static 參數仍會出現錯誤,懷疑是 Node.js 較高版本才出現的問題。需要再詳細測試才會知道。

[參考文章]

Building and running Node.js for Android

[後記]

PIE 問題,參考:https://github.com/nodejs/node/issues/3581

修改:/path/to/node-v4.3.0/common.gypi 下的檔案。

找到下列的片段:

'target_defaults': {
 'default_configuration': 'Release',
 'configurations': {
 'Debug': {
 'variables': {
 'v8_enable_handle_zapping': 1,
 },
 'defines': [ 'DEBUG', '_DEBUG' ],
 'cflags': [ '-g', '-O0' ],
 'conditions': [
 ['target_arch=="x64"', {
 'msvs_configuration_platform': 'x64',
 }],
 ['OS=="aix"', {
 'cflags': [ '-gxcoff' ],
 'ldflags': [ '-Wl,-bbigtoc' ],
 }],
 ['OS == "android"', {
 'cflags': [ '-fPIE' ],
 'ldflags': [ '-fPIE', '-pie' ]
 }]
 ],
 'msvs_settings': {
 'VCCLCompilerTool': {
 'RuntimeLibrary': 1, # static debug
 'Optimization': 0, # /Od, no optimization
 'MinimalRebuild': 'false',
 'OmitFramePointers': 'false',
 'BasicRuntimeChecks': 3, # /RTC1
 },
 'VCLinkerTool': {
 'LinkIncremental': 2, # enable incremental linking
 },
 },
 'xcode_settings': {
 'GCC_OPTIMIZATION_LEVEL': '0', # stop gyp from defaulting to -Os
 },
 },
 'Release': {
 'variables': {
 'v8_enable_handle_zapping': 0,
 },
 'cflags': [ '-O3', '-ffunction-sections', '-fdata-sections' ],
 'conditions': [
 ['target_arch=="x64"', {
 'msvs_configuration_platform': 'x64',
 }],
 ['OS=="solaris"', {
 `# pull in V8's postmortem metadata`
 'ldflags': [ '-Wl,-z,allextract' ]
 }],
 ['OS!="mac" and OS!="win"', {
 'cflags': [ '-fno-omit-frame-pointer' ],
 }],
 ['OS == "android"', {
 'cflags': [ '-fPIE' ],
 'ldflags': [ '-fPIE', '-pie' ]
 }]
 ],

 

新增這段文字:


['OS == "android"', {
'cflags': [ '-fPIE', '-pie' ],
'ldflags': [ '-fPIE', '-pie' ]
}]

 

使用 Android NDK 產生 standalone toolchain

步驟 1:前往 Android ndk 官網:http://developer.android.com/intl/zh-tw/ndk/downloads/index.html

依照自己的作業系統下載自我解壓縮檔。下面以 Linux Ubuntu 為例,用此作業系統較易進行跨編譯,用 Windows 則需要使用 Cygwin,較複雜且使用不易。

步驟 2:下載解壓檔後,切換到檔的目錄下開啟終端機,執行下列的指令:


chmod a+x android-ndk-r10c-linux-x86_64.bin

步驟 3:依照自己需求,產生相對應 Android API level 版本,以便可以在那個版本系統上執行,否則對應錯誤會導致編譯出執行檔無法執行。(可向下相容)

 

出現類似如下的錯誤:


CANNOT LINK EXECUTABLE: cannot locate symbol "sigfillset" referenced by "./rgbimg"...

PIE 簡介:Error: only position independent executables (PIE) are supported

PIE這個安全機制從4.1引入,但是Android L之前的系統版本並不會去檢驗可執行文件是否基於PIE編譯出的。因此不會報錯。但是Android L已經開啟驗證,如果調用的可執行文件不是基於 PIE 方式編譯的,則無法運行。

Executables with PIE (Position Independent Execution) have been supported since Android 4.1. It is a security feature involving address space layout randomization(ASLR) to prevent attacks such as buffer overflow. In Android’s latest release Lollipop, PIE has been made a requirement.

Android 平台對應參考:

platforms: see http://developer.android.com/guide/topics/manifest/uses-sdk-element.html#ApiLevels

  1. Android 1.5 API level 3 (arm/neon)
  2. Android 1.6 API level 4 (arm/neon)
  3. Android 2.0 API level 5 (arm/neon)
  4. Android 2.2.x API level 8
  5. Android 2.3-2.3.2 API level 9 (arm/neon, x86, mips)
  6. Android 2.3.3-2.3.4 API level 10
  7. Android 3.0.x API level 11
  8. Android 3.1.x API level 12
  9. Android 3.2 API level 13
  10. Android 4.0-4.0.2 API level 14
  11. Android 4.0.3-4.0.4 API level 15
  12. Android 4.1 API level 16
  13. Android 4.2 API level 17
  14. Android 4.3 API level 18
  15. Android 4.4 API level 19
  16. Android 5.0 API level 21
  17. Android 5.1 API level 22

步驟 4:執行產生 standalone toolchain 指令:


cd ~/android-ndk-r10e/build/tools

./make-standalone-toolchain.sh --platform=android-16 --install-dir=/home/lab501/android-toolchain-16 --ndk-dir=/home/lab501/android-ndk-r10e --toolchain=arm-linux-androideabi-4.8 --system=linux-x86_64

–install-dir 產生的 toolchain 要安裝的目錄,–ndk-dir 是指定的 ndk 目錄。

產生工具就到這裡結束。下回開始教如何編譯一個 Node.js 在 Android 上執行。