LoginSignup
2
1

More than 1 year has passed since last update.

Android NDK で静的ライブラリを最小構成で作成する

Last updated at Posted at 2021-10-06

ことの発端

他のプラットフォームで C++ を使って開発した機種依存しないコード(所謂共有コード)を Android で使いたい。
小規模ならば AndroidStudio で自動生成された CMakeLists.txt にソースコードを追加して終了なのだが、共有コードが巨大(またはビルドに相当な時間が掛かる)だと色々と厄介。
なので、共有コードを独立してビルドして、後でガッチャンコしたい。

共有コードのビルド

いきなり巨大な共有コードだと大変なので、まずは簡単な構成でやってみましょう。

1. ファイル・フォルダ構成

ファイル・フォルダ構成
/
  src/
    sub.cpp
    sub.h
  CMakeLists.txt
  build.sh

2. CMakeLists.txt を作る

お好きな感じで CMakeLists.txt を作ります。

CMakeLists.txt
cmake_minimum_required(VERSION 3.10.2)

project("sub")

add_library(
  sub
  src/sub.cpp
)

target_link_libraries( 
  sub
)

3. ビルドスクリプトを作る

CMake をアーキテクチャ毎に呼び出してビルドするスクリプトを書きましょう。
ANDROID_NDK_HOME はフォルダを探して適宜指定しましょう。

build.sh
# NDKのパスとAPIレベルの設定(外部で定義するも良し)
ANDROID_NDK_HOME=~/Library/Android/sdk/ndk/23.0.7599858
ANDROID_NATIVE_API_LEVEL=26

# パスの設定(libsが成果物でアーキテクチャ毎サブディレクトリが生成される)
BUILD_PATH=build
LIBS_PATH=libs
BASE_PATH=`pwd`

# CMAKEの設定
CMAKE_TOOLCHAIN_FILE=${ANDROID_NDK_HOME}/build/cmake/android.toolchain.cmake
CMAKE_BUILD_TYPE=Release

# 並列ビルド数
PARALLEL=2

# ABI のアーキテクチャを列挙(このくらいあればOK?)
TARGETS="armeabi-v7a x86 arm64-v8a"

# 作業フォルダと成果物フォルダの削除
rm -rf ${BUILD_PATH}
rm -rf ${LIBS_PATH}

# ABIでループする
for ABI in ${TARGETS}
do    
  mkdir -p ${BUILD_PATH}/${ABI}
  cd ${BUILD_PATH}/${ABI}

  cmake \
    -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} \
    -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} \
    -DANDROID_NATIVE_API_LEVEL=${ANDROID_NATIVE_API_LEVEL} \
    -DANDROID_NDK=${ANDROID_NDK_HOME} \
    -DANDROID_ABI=${ABI} \
    ${BASE_PATH}

  make -j${PARALLEL}
  cd -

  mkdir -p ${LIBS_PATH}/${ABI}
  cp ${BUILD_PATH}/${ABI}/*.a ${LIBS_PATH}/${ABI}
done

4. ビルド実行

言わずもがな、 build.sh を実行します。
実行後に libs フォルダが下記のような感じになります。

libsフォルダ
/
  libs/
    armeabi-v7a/
      libsub.a
    x86/
      libsub.a
    arm64-v8a/
      libsub.a

ガッチャンコ

アプリで使用する際にはアーキテクチャ毎にリンクするライブラリを指定する必要がりますので、下記のように設定します。

ライブラリを使うときのCMakeLists.txt
set(SUB_MODULE_PATH ....)
add_library(libsub STATIC IMPORTED)
set_target_properties(libsub PROPERTIES IMPORTED_LOCATION
        ${SUB_MODULE_PATH}/libs/${CMAKE_ANDROID_ARCH_ABI}/libsub.a)

target_link_libraries(
  ...
  libsub
)

ちなみに、 Android アプリから呼び出されることになるので、生成されるライブラリは Shared Library です。

あとがき

サンプル用のプロジェクトを作成しました。

  1. sub というフォルダで build.sh を実行してライブラリを生成します。
  2. アプリをビルドします。

build.gradle で依存関係を組んでも良いかもですね。(どうなるの?)

サンプル

参考文献

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1