Androidコマンドラインでcmakeを使用してceresライブラリをクロスコンパイル

11765 ワード

前言
最近ceresライブラリを使うと、ネット上の資料が少ないことに気づき、自分で何日か研究して、やっとコンパイルに成功しました.今記録して、同じ問題に遭遇した開発者に参考にしてほしいです.
ステップ
  • ceres,eigenライブラリ
  • をダウンロード
  • CMakeListsを修正する.txtコンパイル構成
  • コンパイルスクリプト作成
  • Android studio統合ダイナミックライブラリ
  • ライブラリファイルのダウンロード
    Ceres公式サイトダウンロード
    eigenの公式サイトのダウンロード
    コンパイルの準備
    ceres、eigen解凍パッケージを格納するフォルダを作成し、コンパイル結果を格納するbuildフォルダを作成します.ディレクトリは次のとおりです.
    ----source
        |
        +---ceres-solver-1.14.0
        |
        +---eigen-3.3.7
        |
        +---build
    

    クロスコンパイルスクリプトの作成
    buildフォルダに入りconfigを作成する.shスクリプト、公式ドキュメントを参考にスクリプトを作成します
  • 最初の行は自分のコンピュータのcmakeパス
  • に記入します
  • DCMAKE_TOOLCHAIN_FILE:NDK独自のツールチェーンコンパイルを使用して、ツールチェーンアドレス
  • に記入する
  • DEIGEN_INCLUDE_DIR:eigenプロジェクトアドレス
  • を入力
  • は、構成の最後にceresプロジェクトアドレス
  • に記入する.
    /Users/qiuyongheng/Library/Android/sdk/cmake/3.10.2.4988404/bin/cmake \
    -DCMAKE_TOOLCHAIN_FILE=/Users/qiuyongheng/Library/Android/sdk/ndk-bundle/build/cmake/android.toolchain.cmake \
    -DEIGEN_INCLUDE_DIR=/Users/qiuyongheng/Downloads/eigen-3.3.7 \
    -DANDROID_ABI=armeabi-v7a \
    -DANDROID_STL=c++_shared \
    -DANDROID_NATIVE_API_LEVEL=android-24 \
    -DBUILD_SHARED_LIBS=ON \
    -DMINIGLOG=ON \
    -DCMAKE_BUILD_TYPE=Release \
    -DCMAKE_C_FLAGS="-s" \
    /Users/qiuyongheng/Downloads/ceres-solver-1.14.0
    
    make clean
    make
    make install
    

    コンパイル開始
    buildフォルダに入り、次のコマンドを実行し、コンパイルスクリプトを実行します.
    sh config.sh
    

    途中で以下のエラーを報告します
    error: 
    miniglog/glog/logging.h:201: error: undefined reference to '__android_log_wr
        : 
    find_libary     ,            ,    log   ...
    
    error: 
    java.lang.UnsatisfiedLinkError: dlopen failed: library "libc++_shared.so" no found
        :
     ndk-bundle         libc++_shared.so      .
         /Users/qiuyongheng/Library/Android/sdk/ndk-bundle/sources/cxx-stl/llvm-libc++/libs
    

    プロジェクトに統合
  • ダイナミックライブラリとヘッダファイルをプロジェクトに追加
  •              
    /usr/local/lib/libceres.so
    /usr/local/include/ceres
    
  • CMakeListsを修正する.txt
  • cmake_minimum_required(VERSION 3.4.1)
    
    set(jniLibs_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../jniLibs)
    message(STATUS "jniLibs_DIR: ${jniLibs_DIR}")
    
    set(lib_build_DIR $ENV{HOME}/tmp)
    message(STATUS "tmp_dir: ${lib_build_DIR}")
    
    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).
            native-lib.cpp)
    
    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)
    
    #   ceres 
    add_library(ceres SHARED IMPORTED)
    set_target_properties(ceres PROPERTIES IMPORTED_LOCATION
            ${jniLibs_DIR}/${ANDROID_ABI}/libceres.so)
    
    
    include_directories(
            ${CMAKE_CURRENT_SOURCE_DIR}/eigen3
            ${CMAKE_CURRENT_SOURCE_DIR}/include
            ${CMAKE_CURRENT_SOURCE_DIR}/include/ceres/internal/miniglog
    )
    
    # target_link_libraries( # Specifies the target library.
            native-lib
            ceres
            ${log-lib})
    
  • テスト
  • extern "C"
    JNIEXPORT jstring JNICALL
    Java_com_qyh_cerestest_MainActivity_testCeres(JNIEnv *env, jobject instance) {
        std::string hello = "Hello Ceres";
    
        //     x    , 5
        double initial_x = 5.0;
        double x = initial_x;
    
        //     :      
        Problem problem;
        CostFunction* cost_function =
                new AutoDiffCostFunction<CostFunctor, 1, 1>(new CostFunctor); //      ,             ,   1     ,      ,   1     ,      x   。
        problem.AddResidualBlock(cost_function, NULL, &x); //         ,       ,      。
    
        //    :         
        Solver::Options options;
        options.linear_solver_type = ceres::DENSE_QR; //         
        options.minimizer_progress_to_stdout = true;//   cout
        Solver::Summary summary;//    
        ceres::Solve(options, &problem, &summary);//  !!!
    
        std::cout << summary.BriefReport() << "
    "
    ;// // std::cout << "x : " << initial_x << " -> " << x << "
    "
    ; return env->NewStringUTF(summary.BriefReport().c_str()); }

    demoアドレス
    github cerestest