From 843ab66e17abd347546480df77b5140c5b7f50bd Mon Sep 17 00:00:00 2001 From: Adam Langley Date: Tue, 28 Apr 2015 17:46:58 -0700 Subject: [PATCH] Add support for building with the Android NDK. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously I've been using the Linaro toolchains and just building static binaries. However, the Linaro toolchains have a broken pthread_rwlock_wrlock—it does nothing and then unlocking corrupts the lock. Building with the Android NDK avoids this. These build instructions depend on https://github.com/taka-no-me/android-cmake which people will need to clone into util/ if they want to use the Android NDK. Change-Id: Ic64919f9399af2a57e8df4fb4b3400865ddb2427 Reviewed-on: https://boringssl-review.googlesource.com/4600 Reviewed-by: Adam Langley --- BUILDING | 26 +++++++++++++++++++++++--- CMakeLists.txt | 20 ++++++++++++++++++-- crypto/CMakeLists.txt | 2 +- crypto/cpu-arm.c | 5 ++--- tool/CMakeLists.txt | 2 +- util/aarch64-toolchain.cmake | 6 ------ util/arm-toolchain.cmake | 6 ------ 7 files changed, 45 insertions(+), 22 deletions(-) delete mode 100644 util/aarch64-toolchain.cmake delete mode 100644 util/arm-toolchain.cmake diff --git a/BUILDING b/BUILDING index 8a655282..d818f950 100644 --- a/BUILDING +++ b/BUILDING @@ -43,17 +43,37 @@ automatically. Note that the default build flags in the top-level CMakeLists.txt are for debugging - optimisation isn't enabled. -If you want to cross-compile then there are example toolchain files for 32-bit -Intel and ARM in util/. Wipe out the build directory, recreate it and run cmake +If you want to cross-compile then there is an example toolchain file for +32-bit Intel in util/. Wipe out the build directory, recreate it and run cmake like this: - cmake -DCMAKE_TOOLCHAIN_FILE=../util/arm-toolchain.cmake -GNinja .. + cmake -DCMAKE_TOOLCHAIN_FILE=../util/32-bit-toolchain.cmake -GNinja .. If you want to build as a shared library, pass -DBUILD_SHARED_LIBS=1. On Windows, where functions need to be tagged with "dllimport" when coming from a shared library, define BORINGSSL_SHARED_LIBRARY in any code which #includes the BoringSSL headers. + +Building for Android: + +It's possible to build BoringSSL with the Android NDK using CMake. This has +been tested with version 10d of the NDK. + +Unpack the Android NDK somewhere and export ANDROID_NDK to point to the +directory. Clone https://github.com/taka-no-me/android-cmake into util/. +Then make a build directory as above and run CMake *twice* like this: + + cmake -DANDROID_NATIVE_API_LEVEL=android-9 \ + -DANDROID_ABI=armeabi-v7a \ + -DCMAKE_TOOLCHAIN_FILE=../util/android-cmake/android.toolchain.cmake \ + -GNinja .. + +Once you've run that twice, ninja should produce Android-compatible binaries. +You can replace "armeabi-v7a" in the above with "arm64-v8a" to build aarch64 +binaries. + + Known Limitations on Windows: * Versions of cmake since 3.0.2 have a bug in its Ninja generator that causes diff --git a/CMakeLists.txt b/CMakeLists.txt index 75a75f57..6e41ee9f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,9 +2,16 @@ cmake_minimum_required (VERSION 2.8.10) project (BoringSSL) -find_package(Perl REQUIRED) +if(ANDROID) + # Android-NDK CMake files reconfigure the path and so Go and Perl won't be + # found. However, ninja will still find them in $PATH if we just name them. + set(PERL_EXECUTABLE "perl") + set(GO_EXECUTABLE "go") +else() + find_package(Perl REQUIRED) + find_program(GO_EXECUTABLE go) +endif() -find_program(GO_EXECUTABLE go) if (NOT GO_EXECUTABLE) message(FATAL_ERROR "Could not find Go") endif() @@ -97,12 +104,21 @@ elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "i686") set(ARCH "x86") elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "arm") set(ARCH "arm") +elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "armv7-a") + set(ARCH "arm") elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64") set(ARCH "aarch64") else() message(FATAL_ERROR "Unknown processor:" ${CMAKE_SYSTEM_PROCESSOR}) endif() +if (ANDROID AND ${ARCH} STREQUAL "arm") + # The Android-NDK CMake files somehow fail to set the -march flag for + # assembly files. Without this flag, the compiler believes that it's + # building for ARMv5. + set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -march=armv7-a") +endif() + if (${ARCH} STREQUAL "x86" AND APPLE) # With CMake 2.8.x, ${CMAKE_SYSTEM_PROCESSOR} evalutes to i386 on OS X, # but clang defaults to 64-bit builds on OS X unless otherwise told. diff --git a/crypto/CMakeLists.txt b/crypto/CMakeLists.txt index 009f0f44..3af298e9 100644 --- a/crypto/CMakeLists.txt +++ b/crypto/CMakeLists.txt @@ -191,7 +191,7 @@ add_library( $ ) -if(NOT MSVC) +if(NOT MSVC AND NOT ANDROID) target_link_libraries(crypto pthread) endif() diff --git a/crypto/cpu-arm.c b/crypto/cpu-arm.c index 27f9bf9b..e7538cbe 100644 --- a/crypto/cpu-arm.c +++ b/crypto/cpu-arm.c @@ -30,9 +30,6 @@ unsigned long getauxval(unsigned long type) __attribute__((weak)); -static const unsigned long AT_HWCAP = 16; -static const unsigned long AT_HWCAP2 = 26; - char CRYPTO_is_NEON_capable(void) { return (OPENSSL_armcap_P & ARMV7_NEON) != 0; } @@ -136,6 +133,7 @@ void OPENSSL_cpuid_setup(void) { return; } + static const unsigned long AT_HWCAP = 16; unsigned long hwcap = getauxval(AT_HWCAP); #if defined(OPENSSL_ARM) @@ -146,6 +144,7 @@ void OPENSSL_cpuid_setup(void) { /* In 32-bit mode, the ARMv8 feature bits are in a different aux vector * value. */ + static const unsigned long AT_HWCAP2 = 26; hwcap = getauxval(AT_HWCAP2); /* See /usr/include/asm/hwcap.h on an ARM installation for the source of diff --git a/tool/CMakeLists.txt b/tool/CMakeLists.txt index 67f59a77..74c1ac8f 100644 --- a/tool/CMakeLists.txt +++ b/tool/CMakeLists.txt @@ -15,7 +15,7 @@ add_executable( transport_common.cc ) -if (APPLE OR WIN32) +if (APPLE OR WIN32 OR ANDROID) target_link_libraries(bssl ssl crypto) else() target_link_libraries(bssl ssl crypto -lrt) diff --git a/util/aarch64-toolchain.cmake b/util/aarch64-toolchain.cmake deleted file mode 100644 index 77f33ab9..00000000 --- a/util/aarch64-toolchain.cmake +++ /dev/null @@ -1,6 +0,0 @@ -set(CMAKE_SYSTEM_NAME Linux) -set(CMAKE_SYSTEM_VERSION 1) -set(CMAKE_SYSTEM_PROCESSOR "aarch64") -set(CMAKE_CXX_COMPILER "/opt/gcc-linaro-4.9-2014.11-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-g++") -set(CMAKE_C_COMPILER "/opt/gcc-linaro-4.9-2014.11-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc") -set(CMAKE_EXE_LINKER_FLAGS "-static") diff --git a/util/arm-toolchain.cmake b/util/arm-toolchain.cmake deleted file mode 100644 index 2dfd2bd8..00000000 --- a/util/arm-toolchain.cmake +++ /dev/null @@ -1,6 +0,0 @@ -set(CMAKE_SYSTEM_NAME Linux) -set(CMAKE_SYSTEM_VERSION 1) -set(CMAKE_SYSTEM_PROCESSOR "arm") -set(CMAKE_CXX_COMPILER "/opt/gcc-linaro-4.9-2014.11-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++") -set(CMAKE_C_COMPILER "/opt/gcc-linaro-4.9-2014.11-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc") -set(CMAKE_EXE_LINKER_FLAGS "-static")