ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [안드로이드] native c++ 컴파일 관련 정리
    Android 2019. 2. 16. 17:53

    툴체인 선택

    표 1. 다양한 명령 집합에 대한 APP_ABI 설정

    아키텍처 툴체인 이름
    ARM 기반 arm-linux-androideabi-<gcc-version>
    x86 기반 x86-<gcc-version>
    MIPS 기반 mipsel-linux-android-<gcc-version>
    ARM64 기반 aarch64-linux-android-<gcc-version>
    X86-64 기반 x86_64-<gcc-version>
    MIPS64 기반 mips64el-linux-android-<gcc-version>

    Sysroot 선택

    SYSROOT=$NDK/platforms/android-21/arch-arm 

    컴파일러 호출

    간단한 호출

    다음은 NDK 내에 미리 빌드 되어있는 arm-linux-androideabi-4.8 툴체인을 이용한 빌드 방법이다.

    export CC="$NDK/toolchains/arm-linux-androideabi-4.8/prebuilt/ \ linux-x86/bin/arm-linux-androideabi-gcc-4.8 --sysroot=$SYSROOT" $CC -o foo.o -c foo.c 

    이 방법에서는 C++ STL (STLport, libc++ 또는 GNU libstdc++)을 사용할 수 없습니다. 예외나 RTTI가 지원되지도 않는다.

    고급 방법

    NDK는 명령줄에서 사용자 지정 툴체인 설치를 수행할 수 있는 make-standalone-toolchain.sh 셸 스크립트를 제공합니다.

    $NDK/build/tools/ 디렉터리에 있으며, 여기서 $NDK는 NDK의 설치 루트 디렉터리입니다.

    $NDK/build/tools/make-standalone-toolchain.sh \ --arch=arm --platform=android-21 --install-dir=/tmp/my-android-toolchain 

    이 명령어를 실행하면 /tmp/my-android-toolchain/이라는 이름의 디렉터리가 생성되고, 이 디렉터리에는 android-21/arch-arm sysroot의 복사본과 32비트 ARM 아키텍처용 툴체인 바이너리의 복사본이 포함됩니다.

    표 3. --arch를 사용하는 툴체인과 해당 값

    툴체인
    mips64 컴파일러 --arch=mips64
    mips GCC 4.8 컴파일러 --arch=mips
    x86 GCC 4.8 컴파일러 --arch=x86
    x86_64 GCC 4.8 컴파일러 --arch=x86_64
    mips GCC 4.8 컴파일러 --arch=mips

    표 4. --toolchain을 사용하는 툴체인과 해당 값

    툴체인
    arm --toolchain=arm-linux-androideabi-4.8
    --toolchain=arm-linux-androideabi-4.9
    --toolchain=arm-linux-android-clang3.5
    --toolchain=arm-linux-android-clang3.6
    x86 --toolchain=x86-linux-android-4.8
    --toolchain=x86-linux-android-4.9
    --toolchain=x86-linux-android-clang3.5
    --toolchain=x86-linux-android-clang3.6
    mips --toolchain=mips-linux-android-4.8
    --toolchain=mips-linux-android-4.9
    --toolchain=mips-linux-android-clang3.5
    --toolchain=mips-linux-android-clang3.6
    arm64 --toolchain=aarch64-linux-android-4.9
    --toolchain=aarch64-linux-android-clang3.5
    --toolchain=aarch64-linux-android-clang3.6
    x86_64 --toolchain=x86_64-linux-android-4.9
    --toolchain=x86_64-linux-android-clang3.5
    --toolchain=x86_64-linux-android-clang3.6
    mips64 --toolchain=mips64el-linux-android-4.9
    --toolchain=mips64el-linux-android-clang3.5
    --toolchain=mips64el-linux-android-clang3.6

     

    CMakeList.txt

    # For more information about using CMake with Android Studio, read the # documentation: https://d.android.com/studio/projects/add-native-code.html  # Sets the minimum version of CMake required to build the native library.  cmake_minimum_required(VERSION 3.4.1)  # Creates and names a library, sets it as either STATIC # or SHARED, and provides the relative paths to its source code. # You can define multiple libraries, and CMake builds them for you. # Gradle automatically packages shared libraries with your APK. 

    다음은 .cpp 라이브러리 추가하는 방법이다.

    add_library( # Sets the name of the library.              native-lib               # Sets the library as a shared library.              SHARED               # Provides a relative path to your source file(s).              src/main/cpp/native-lib.cpp              ) 
    add_library( # Sets the name of the library.              blerp               # Sets the library as a shared library.              SHARED               # Provides a relative path to your source file(s).              src/main/cpp/detection/blerp.cpp              )  add_library( # Sets the name of the library.              util               # Sets the library as a shared library.              SHARED               # Provides a relative path to your source file(s).              src/main/cpp/detection/util.cpp              )   add_library( # Sets the name of the library.              input-processing               # Sets the library as a shared library.              SHARED               # Provides a relative path to your source file(s).              src/main/cpp/detection/input_processing.cpp              ) 

     

    필요한 경우에는 add_library 의 세번째 파라미터에 여러 cpp 파일을 묶어 하나의 라이브러리로 등록할 수 있다. (좋은 의견을 주신 코드몬님 감사드립니다. )
    add_library( # Sets the name of the library.
                 native-lib2
    
                 # Sets the library as a shared library.
                 SHARED
    
                 # Provides a relative path to your source file(s).
                 native-lib.cpp common/hmac.cpp common/sha1.cpp common/sha256.cpp
                )

     

    다음은 헤더 파일을 포함하고 있는 디렉토리를 선언하는 코드이다.

    # Specifies a path to native header files. include_directories( src/main/cpp/include ) 

    다음은 라이브러리를 찾아서 해당 라이브러리에 이름을 할당하는 코드이다.

    # Searches for a specified prebuilt library and stores the path as a # variable. Because CMake includes system libraries in the search path by # default, you only need to specify the name of the public NDK library # you want to add. CMake verifies that the library exists before # completing its build.  find_library( # Sets the name of the path variable.               log-lib                # Specifies the name of the NDK library that               # you want CMake to locate.               log ) 

    다음은 라이브러리의 target을 정의하는 코드이다.

    # Specifies libraries CMake should link to your target library. You # can link multiple libraries, such as libraries you define in this # build script, prebuilt third-party libraries, or system libraries.   target_link_libraries( # Specifies the target library.                        native-lib                         # Links the target library to the log library                        # included in the NDK.                        ${log-lib} ) 

    input_processing  util에 종속되어 있고, util은 blerp에 종속되어있다.

    target_link_libraries( input-processing util ) target_link_libraries( util blerp ) 

    여담

    C와 C++이 섞여 있는 코드를 이용할 때, C에서 만들어진 함수의 이름과 C++에서 선언한 함수의 이름을 비슷한 형식으로 만들어서 C++에서 컴파일된 함수를 C에서도 사용할 수 있도록 한다.

    extern "C"를 명시적으로 선언해 줌으로써 이 부분에 선언된 함수는 C 형식의 함수 실행 이름을 가지게 되고, 이를 C에서도 사용할 수 있게 된다. 이 때 함수의 선언 형식은 C의 기준을 따라야 하며, C++의 기준(클래스를 명시한다던지, template을 이용하는 등)을 따르는 함수는 오류를 발생한다.

    // blerp.h #include <stdint.h>  typedef struct {     uint32_t *pixels;     unsigned int w;     unsigned int h; } image_t; #define getByte(value, n) (value >> (n*8) & 0xFF)  #ifdef __cplusplus extern "C" { #endif  void copy_element(image_t *image, unsigned int x, unsigned int y, uint32_t color);  #ifdef __cplusplus } #endif 

     

    참고

    C 및 C++ 코드를 프로젝트에 추가

    독립 실행형 툴체인

    CMake: target_link_libraries

     

    Buy Me A Coffee

     

    반응형

    댓글

Designed by Tistory.