From bed331d803ebac373663983b944de22b254e48c3 Mon Sep 17 00:00:00 2001 From: tensor-tang Date: Tue, 18 Jun 2019 11:52:54 +0000 Subject: [PATCH] support clang compile on arm --- CMakeLists.txt | 15 +++- cmake/cross_compiling/android.cmake | 25 +++++- cmake/cross_compiling/findar.cmake | 33 ++++++++ cmake/external/gflags.cmake | 3 +- cmake/external/glog.cmake | 3 +- cmake/external/gtest.cmake | 4 +- cmake/external/protobuf.cmake | 1 + paddle/fluid/lite/core/CMakeLists.txt | 2 +- paddle/fluid/lite/tools/build.sh | 96 +++++++++++++----------- paddle/fluid/lite/tools/mobile_readme.md | 1 + 10 files changed, 133 insertions(+), 50 deletions(-) create mode 100644 cmake/cross_compiling/findar.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index bd25403836e..5ac1f7d7698 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,7 +42,17 @@ if(LITE_WITH_LIGHT_WEIGHT_FRAMEWORK) message(FATAL_ERROR "ARM_TARGET_ARCH_ABI must be in one of ${ARM_TARGET_ARCH_ABI_LIST}") endif() - message(STATUS "Lite ARM Compile ${ARM_TARGET_OS} with ${ARM_TARGET_ARCH_ABI}") + # check arch abi + if(NOT DEFINED ARM_TARGET_LANG) + set(ARM_TARGET_LANG "clang" CACHE STRING "Choose ARM Target Language") + endif() + set(ARM_TARGET_LANG_LIST "gcc" "clang") + set_property(CACHE ARM_TARGET_LANG PROPERTY STRINGS ${ARM_TARGET_LANG_LIST}) + if (NOT ARM_TARGET_LANG IN_LIST ARM_TARGET_LANG_LIST) + message(FATAL_ERROR "ARM_TARGET_LANG must be in one of ${ARM_TARGET_LANG_LIST}") + endif() + + message(STATUS "Lite ARM Compile ${ARM_TARGET_OS} with ${ARM_TARGET_ARCH_ABI} ${ARM_TARGET_LANG}") include(cross_compiling/host) include(cross_compiling/armlinux) include(cross_compiling/android) @@ -158,6 +168,9 @@ include_directories("${PADDLE_SOURCE_DIR}") # for mobile if (WITH_LITE AND LITE_WITH_LIGHT_WEIGHT_FRAMEWORK) message(STATUS "Building the mobile framework") + if (ANDROID) + include(cross_compiling/findar) + endif() # include the necessary thirdparty dependencies include(external/gflags) # download, build, install gflags include(external/glog) # download, build, install glog diff --git a/cmake/cross_compiling/android.cmake b/cmake/cross_compiling/android.cmake index 24f2bf676d3..c3bdbe202f7 100644 --- a/cmake/cross_compiling/android.cmake +++ b/cmake/cross_compiling/android.cmake @@ -31,7 +31,7 @@ if(NOT DEFINED ANDROID_API_LEVEL) endif() if(NOT DEFINED ANDROID_STL_TYPE) - set(ANDROID_STL_TYPE "c++_static" CACHE STRING "stl type") + set(ANDROID_STL_TYPE "c++_static" CACHE STRING "stl type") # can also use shared endif() if(ARM_TARGET_ARCH_ABI STREQUAL "armv7hf") @@ -71,8 +71,31 @@ if (NOT ANDROID_STL_TYPE IN_LIST ANDROID_STL_TYPE_LITS) message(FATAL_ERROR "ANDROID_STL_TYPE must be in one of ${ANDROID_STL_TYPE_LITS}") endif() +if(ARM_TARGET_LANG STREQUAL "gcc") + # gcc do not need set lang + set(ARM_TARGET_LANG "") +endif() + set(CMAKE_SYSTEM_NAME Android) set(CMAKE_SYSTEM_VERSION ${ANDROID_API_LEVEL}) set(CMAKE_ANDROID_ARCH_ABI ${ANDROID_ARCH_ABI}) set(CMAKE_ANDROID_NDK ${ANDROID_NDK}) +set(CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION ${ARM_TARGET_LANG}) set(CMAKE_ANDROID_STL_TYPE ${ANDROID_STL_TYPE}) + +if (ARM_TARGET_LANG STREQUAL "clang") + if(ARM_TARGET_ARCH_ABI STREQUAL "armv8") + set(triple aarch64-v8a-linux-android) + elseif(ARM_TARGET_ARCH_ABI STREQUAL "armv7") + set(triple arm-v7a-linux-android) + else() + message(FATAL_ERROR "Clang do not support this ${ARM_TARGET_ARCH_ABI}, use armv8 or armv7") + endif() + + set(CMAKE_C_COMPILER clang) + set(CMAKE_C_COMPILER_TARGET ${triple}) + set(CMAKE_CXX_COMPILER clang++) + set(CMAKE_CXX_COMPILER_TARGET ${triple}) + + message(STATUS "CMAKE_CXX_COMPILER_TARGET: ${CMAKE_CXX_COMPILER_TARGET}") +endif() diff --git a/cmake/cross_compiling/findar.cmake b/cmake/cross_compiling/findar.cmake new file mode 100644 index 00000000000..bcb0dc70fd8 --- /dev/null +++ b/cmake/cross_compiling/findar.cmake @@ -0,0 +1,33 @@ +# Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +if(NOT ARM_TARGET_LANG STREQUAL "clang") + # only clang need find ar tool + return() +endif() + +if(NOT EXISTS "${CMAKE_CXX_COMPILER}") + message(ERROR "Can not find CMAKE_CXX_COMPILER ${CMAKE_CXX_COMPILER}") +endif() + +get_filename_component(AR_PATH ${CMAKE_CXX_COMPILER} PATH) + +find_file(AR_TOOL NAMES llvm-ar PATHS ${AR_PATH}) + +if(NOT AR_TOOL) + message(ERROR "Failed to find AR_TOOL in ${AR_PATH}") +else() + set(CMAKE_AR ${AR_TOOL}) + message(STATUS "Found CMAKE_AR : " ${CMAKE_AR}) +endif() diff --git a/cmake/external/gflags.cmake b/cmake/external/gflags.cmake index 42ce7c644f3..256e1bbebf0 100644 --- a/cmake/external/gflags.cmake +++ b/cmake/external/gflags.cmake @@ -40,7 +40,8 @@ if(ANDROID) "-DCMAKE_SYSTEM_VERSION=${CMAKE_SYSTEM_VERSION}" "-DCMAKE_ANDROID_ARCH_ABI=${CMAKE_ANDROID_ARCH_ABI}" "-DCMAKE_ANDROID_NDK=${CMAKE_ANDROID_NDK}" - "-DCMAKE_ANDROID_STL_TYPE=${CMAKE_ANDROID_STL_TYPE}") + "-DCMAKE_ANDROID_STL_TYPE=${CMAKE_ANDROID_STL_TYPE}" + "-DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=${CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION}" ) endif() ExternalProject_Add( diff --git a/cmake/external/glog.cmake b/cmake/external/glog.cmake index 9ac9b832643..80abc2350ca 100644 --- a/cmake/external/glog.cmake +++ b/cmake/external/glog.cmake @@ -46,7 +46,8 @@ if(ANDROID) "-DCMAKE_SYSTEM_VERSION=${CMAKE_SYSTEM_VERSION}" "-DCMAKE_ANDROID_ARCH_ABI=${CMAKE_ANDROID_ARCH_ABI}" "-DCMAKE_ANDROID_NDK=${CMAKE_ANDROID_NDK}" - "-DCMAKE_ANDROID_STL_TYPE=${CMAKE_ANDROID_STL_TYPE}") + "-DCMAKE_ANDROID_STL_TYPE=${CMAKE_ANDROID_STL_TYPE}" + "-DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=${CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION}") endif() ExternalProject_Add( diff --git a/cmake/external/gtest.cmake b/cmake/external/gtest.cmake index de44719803f..57fd6812879 100644 --- a/cmake/external/gtest.cmake +++ b/cmake/external/gtest.cmake @@ -58,7 +58,9 @@ IF(WITH_TESTING OR (WITH_DISTRIBUTE AND NOT WITH_GRPC)) "-DCMAKE_SYSTEM_VERSION=${CMAKE_SYSTEM_VERSION}" "-DCMAKE_ANDROID_ARCH_ABI=${CMAKE_ANDROID_ARCH_ABI}" "-DCMAKE_ANDROID_NDK=${CMAKE_ANDROID_NDK}" - "-DCMAKE_ANDROID_STL_TYPE=${CMAKE_ANDROID_STL_TYPE}") + "-DCMAKE_ANDROID_STL_TYPE=${CMAKE_ANDROID_STL_TYPE}" + "-DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=${CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION}" + ) endif() ExternalProject_Add( diff --git a/cmake/external/protobuf.cmake b/cmake/external/protobuf.cmake index 41cd1ebaf33..6d2136223d3 100644 --- a/cmake/external/protobuf.cmake +++ b/cmake/external/protobuf.cmake @@ -199,6 +199,7 @@ FUNCTION(build_protobuf TARGET_NAME BUILD_FOR_HOST) "-DCMAKE_ANDROID_ARCH_ABI=${CMAKE_ANDROID_ARCH_ABI}" "-DCMAKE_ANDROID_NDK=${CMAKE_ANDROID_NDK}" "-DCMAKE_ANDROID_STL_TYPE=${CMAKE_ANDROID_STL_TYPE}" + "-DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=${CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION}" "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}" "-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}" "-DCMAKE_C_FLAGS=${CMAKE_C_FLAGS}" diff --git a/paddle/fluid/lite/core/CMakeLists.txt b/paddle/fluid/lite/core/CMakeLists.txt index 89101aa0327..665d7555e37 100644 --- a/paddle/fluid/lite/core/CMakeLists.txt +++ b/paddle/fluid/lite/core/CMakeLists.txt @@ -1,5 +1,5 @@ if (WITH_TESTING) - cc_library(lite_gtest_main SRCS lite_gtest_main.cc DEPS gtest) + cc_library(lite_gtest_main SRCS lite_gtest_main.cc DEPS gtest gflags) endif() lite_cc_library(target_wrapper_lite SRCS target_wrapper.cc DEPS target_wrapper_host diff --git a/paddle/fluid/lite/tools/build.sh b/paddle/fluid/lite/tools/build.sh index f1c58489ce6..44c546e1de3 100755 --- a/paddle/fluid/lite/tools/build.sh +++ b/paddle/fluid/lite/tools/build.sh @@ -57,6 +57,7 @@ function check_style { function cmake_arm { # $1: ARM_TARGET_OS in "android" , "armlinux" # $2: ARM_TARGET_ARCH_ABI in "armv8", "armv7" ,"armv7hf" + # $3: ARM_TARGET_LANG in "gcc" "clang" cmake .. \ -DWITH_GPU=OFF \ -DWITH_MKL=OFF \ @@ -66,7 +67,7 @@ function cmake_arm { -DLITE_WITH_ARM=ON \ -DLITE_WITH_LIGHT_WEIGHT_FRAMEWORK=ON \ -DWITH_TESTING=ON \ - -DARM_TARGET_OS=$1 -DARM_TARGET_ARCH_ABI=$2 + -DARM_TARGET_OS=$1 -DARM_TARGET_ARCH_ABI=$2 -DARM_TARGET_LANG=$3 } function build_single { @@ -125,31 +126,36 @@ function test_arm_android { function build_test_arm { # 1. Build goes first cur_dir=$(pwd) - for os in "android" "armlinux" ; do - for abi in "armv8" "armv7" "armv7hf"; do - # TODO(hongming): enable compile armv7 and armv7hf on armlinux - if [[ ${abi} == "armv7hf" ]]; then - echo "armv7hf is not supported on both android and armlinux yet" + for lang in "gcc" "clang"; do + for os in "android" "armlinux" ; do + if [[ ${os} == "armlinux" && ${lang} == "clang" ]]; then continue fi - - # TODO(hongming): enable armv7 on armlinux - if [[ ${os} == "armlinux" && ${abi} == "armv7" ]]; then - echo "armv7 is not supported on armlinux yet" - continue - fi - - if [[ ${os} == "android" && ${abi} == "armv7hf" ]]; then - echo "android do not need armv7hf" - continue - fi - - build_dir=$cur_dir/build.lite.${os}.${abi} - mkdir -p $build_dir - cd $build_dir - - cmake_arm ${os} ${abi} - build $TESTS_FILE + for abi in "armv8" "armv7" "armv7hf"; do + # TODO(hongming): enable compile armv7 and armv7hf on armlinux + if [[ ${abi} == "armv7hf" ]]; then + echo "armv7hf is not supported on both android and armlinux yet" + continue + fi + + # TODO(hongming): enable armv7 on armlinux + if [[ ${os} == "armlinux" && ${abi} == "armv7" ]]; then + echo "armv7 is not supported on armlinux yet" + continue + fi + + if [[ ${os} == "android" && ${abi} == "armv7hf" ]]; then + echo "android do not need armv7hf" + continue + fi + + build_dir=$cur_dir/build.lite.${os}.${abi}.${lang} + mkdir -p $build_dir + cd $build_dir + + cmake_arm ${os} ${abi} ${lang} + build $TESTS_FILE + done done done @@ -168,26 +174,28 @@ function build_test_arm { sleep 1m # now can only test android. - for abi in "armv8" "armv7" ; do - # TODO(yuanshuai): enable armv7 on android - if [[ ${abi} == "armv7" ]]; then - continue - fi - - build_dir=$cur_dir/build.lite.android.${abi} - cd $build_dir - - local port= - if [[ ${abi} == "armv7" ]]; then - port=${port_armv7} - fi - - if [[ ${abi} == "armv8" ]]; then - port=${port_armv8} - fi - echo "test file: ${TESTS_FILE}" - for _test in $(cat $TESTS_FILE); do - test_arm_android $_test $port + for lang in "gcc" "clang"; do + for abi in "armv8" "armv7" ; do + # TODO(yuanshuai): enable armv7 on android + if [[ ${abi} == "armv7" ]]; then + continue + fi + + build_dir=$cur_dir/build.lite.android.${abi}.${lang} + cd $build_dir + + local port= + if [[ ${abi} == "armv7" ]]; then + port=${port_armv7} + fi + + if [[ ${abi} == "armv8" ]]; then + port=${port_armv8} + fi + echo "test file: ${TESTS_FILE}" + for _test in $(cat $TESTS_FILE); do + test_arm_android $_test $port + done done done diff --git a/paddle/fluid/lite/tools/mobile_readme.md b/paddle/fluid/lite/tools/mobile_readme.md index 1d866cbb822..08bd7b0f5d6 100644 --- a/paddle/fluid/lite/tools/mobile_readme.md +++ b/paddle/fluid/lite/tools/mobile_readme.md @@ -26,6 +26,7 @@ $ git checkout incubate/lite - "armv8", 等效于 "arm64"。 default值为这个。 - "armv7hf", 等效于使用`eabihf`且`-march=armv7-a -mfloat-abi=hard -mfpu=neon-vfpv4 `。 - "armv7", 等效于使用`eabi`且`-march=armv7-a -mfloat-abi=softfp -mfpu=neon-vfpv4`。 +- `ARM_TARGET_LANG` 代表目标编译的语言, 默认为gcc,支持 gcc和clang两种。 ### 编译 -- GitLab