title: Android: Linking to prebuilt static libraries
body: <p>I have compiled some static and shared libraries for Android. Specifically, I have the libraries </p>
  
  <pre><code>libcoinblas.a   libcoinlapack.a   libcoinmetis.a   libcoinmumps.a   libipopt.a
  libcoinblas.so  libcoinlapack.so  libcoinmetis.so  libcoinmumps.so  libipopt.so
  </code></pre>
  
  <p>Furthermore, these libraries are inter-dependent, that is, </p>
  
  <pre><code>Lapack requires Blas
  Mumps  requires Blas and Metis
  Ipopt  requires Mumps, Metis, and Lapack
  </code></pre>
  
  <p>The Android project correctly links and runs when using the shared libraries, but fails to build with the static libraries. </p>
  
  <p>In the shared case, I am using the cmake file</p>
  
  <pre><code>cmake_minimum_required(VERSION 3.4.1)
  
  add_library( native-lib
               SHARED
               src/main/cpp/cpp_example.cpp
               src/main/cpp/MyNLP.cpp)
  
  # Add dependent libraries
  add_library(blas SHARED IMPORTED)
  set_property(TARGET blas PROPERTY IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libcoinblas.so)
  
  add_library(lapack SHARED IMPORTED)
  set_property(TARGET lapack PROPERTY IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libcoinlapack.so)
  
  add_library(metis SHARED IMPORTED)
  set_property(TARGET metis PROPERTY IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libcoinmetis.so)
  
  add_library(mumps SHARED IMPORTED)
  set_property(TARGET mumps PROPERTY IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libcoinmumps.so)
  
  add_library(ipopt SHARED IMPORTED)
  set_property(TARGET ipopt PROPERTY IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libipopt.so)
  
  # Location of header files
  include_directories(${CMAKE_SOURCE_DIR}/libs/include
                      ${CMAKE_SOURCE_DIR}/libs/include/ThirdParty)
  
  target_link_libraries( native-lib
  
                         blas
                         lapack
                         metis
                         mumps
                         ipopt
                         )
  </code></pre>
  
  <p>and in the static case </p>
  
  <pre><code>cmake_minimum_required(VERSION 3.4.1)
  
  add_library( native-lib
               SHARED
               src/main/cpp/cpp_example.cpp
               src/main/cpp/MyNLP.cpp)
  
  # Add dependent libraries
  add_library(blas STATIC IMPORTED)
  set_property(TARGET blas PROPERTY IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libcoinblas.a)
  
  add_library(lapack STATIC IMPORTED)
  set_property(TARGET lapack PROPERTY IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libcoinlapack.a)
  
  add_library(metis STATIC IMPORTED)
  set_property(TARGET metis PROPERTY IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libcoinmetis.a)
  
  add_library(mumps STATIC IMPORTED)
  set_property(TARGET mumps PROPERTY IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libcoinmumps.a)
  
  add_library(ipopt STATIC IMPORTED)
  set_property(TARGET ipopt PROPERTY IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libipopt.a)
  
  # Location of header files
  include_directories(${CMAKE_SOURCE_DIR}/libs/include
                      ${CMAKE_SOURCE_DIR}/libs/include/ThirdParty)
  
  target_link_libraries( native-lib
  
                         blas
                         lapack
                         metis
                         mumps
                         ipopt
                         )
  </code></pre>
  
  <p>I presumed that I simply need to change how the libraries are added from </p>
  
  <pre><code>add_library(libxxx SHARED IMPORTED)
  set_property(TARGET libxxx PROPERTY ... libxxx.so)
  </code></pre>
  
  <p>to </p>
  
  <pre><code>add_library(libxxx STATIC IMPORTED)
  set_property(TARGET libxxx PROPERTY ... libxxx.a)
  </code></pre>
  
  <p>But that does not work. Specifically, in the static case, I get a bunch (hundreds) of </p>
  
  <pre><code>undefined reference to xxx 
  </code></pre>
  
  <p>errors. For example, </p>
  
  <pre><code>../../../../libs/arm64-v8a/libipopt.a(IpLapack.o): In function `Ipopt::IpLapackDppsv(int, int, double const*, double*, int, int&amp;)':
  IpLapack.cpp:(.text+0x3d4): undefined reference to `dppsv_'
  </code></pre>
  
  <p>Although the errors are not just due to missing Lapack functions, but also Mumps and others. </p>
  
  <hr>
  
  <h2>EDIT</h2>
  
  <p>Looking at the specific failed command, I believe that the libraries were specified in the correct order: </p>
  
  <blockquote>
    <p>FAILED: cmd.exe /C "cd . &amp;&amp; clang++.exe 
    --target=aarch64-none-linux-android --gcc-toolchain=C:/Android/android-sdk/ndk-bundle/toolchains/aarch64-linux-android-4.9/prebuilt/windows-x86_64
    --sysroot=sysroot -fPIC -isystem C:/Android/android-sdk/ndk-bundle/sysroot/usr/include/aarch64-linux-android
    -D__ANDROID_API__=23 -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -Wa,--noexecstack -Wformat -Werror=format-security   -O0 -fno-limit-debug-info  -Wl,--exclude-libs,libgcc.a -Wl,--exclude-libs,libatomic.a --sysroot C:/Android/android-sdk/ndk-bundle/platforms/android-23/arch-arm64
    -Wl,--build-id -Wl,--warn-shared-textrel -Wl,--fatal-warnings -Wl,--no-undefined -Wl,-z,noexecstack -Qunused-arguments -Wl,-z,relro -Wl,-z,now -shared -Wl,-soname,libnative-lib.so -o ........\build\intermediates\cmake\debug\obj\arm64-v8a\libnative-lib.so
    CMakeFiles/native-lib.dir/src/main/cpp/cpp_example.cpp.o
    CMakeFiles/native-lib.dir/src/main/cpp/MyNLP.cpp.o  libcoinblas.a
    libcoinlapack.a libcoinmetis.a libcoinmumps.a libipopt.a -latomic -lm
    "C:/Android/android-sdk/ndk-bundle/sources/cxx-stl/gnu-libstdc++/4.9/libs/arm64-v8a/libgnustl_static.a"
    &amp;&amp; cd ."</p>
  </blockquote>
  
  <p>Note that I sanitized the paths a little bit above so that they are slightly readable, but towards the end you can see that the libraries are listed in the order </p>
  
  <pre><code>libcoinblas.a libcoinlapack.a libcoinmetis.a libcoinmumps.a libipopt.a
  </code></pre>
  
  <hr>
  
  <h2>EDIT</h2>
  
  <p>I also tried changing the link command from <code>target_link_library</code> to <code>link_library</code>:</p>
  
  <pre><code>link_libraries(native-lib blas lapack metis mumps ipopt)
  </code></pre>
  
  <p>but this also fails. For some reason, in this case, the link command doesn't even include the libraries that it is supposed to link: </p>
  
  <blockquote>
    <p>FAILED: cmd.exe /C "cd . &amp;&amp;
    C:\Android\android-sdk\ndk-bundle\toolchains\llvm\prebuilt\windows-x86_64\bin\clang++.exe
    --target=aarch64-none-linux-android --gcc-toolchain=C:/Android/android-sdk/ndk-bundle/toolchains/aarch64-linux-android-4.9/prebuilt/windows-x86_64
    --sysroot=C:/Android/android-sdk/ndk-bundle/sysroot -fPIC -isystem C:/Android/android-sdk/ndk-bundle/sysroot/usr/include/aarch64-linux-android
    -D__ANDROID_API__=23 -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -Wa,--noexecstack -Wformat -Werror=format-security   -O0 -fno-limit-debug-info  -Wl,--exclude-libs,libgcc.a -Wl,--exclude-libs,libatomic.a --sysroot C:/Android/android-sdk/ndk-bundle/platforms/android-23/arch-arm64
    -Wl,--build-id -Wl,--warn-shared-textrel -Wl,--fatal-warnings -Wl,--no-undefined -Wl,-z,noexecstack -Qunused-arguments -Wl,-z,relro -Wl,-z,now -shared -Wl,-soname,libnative-lib.so -o ........\build\intermediates\cmake\debug\obj\arm64-v8a\libnative-lib.so
    CMakeFiles/native-lib.dir/src/main/cpp/cpp_example.cpp.o
    CMakeFiles/native-lib.dir/src/main/cpp/MyNLP.cpp.o  -latomic -lm
    "C:/Android/android-sdk/ndk-bundle/sources/cxx-stl/gnu-libstdc++/4.9/libs/arm64-v8a/libgnustl_static.a"
    &amp;&amp; cd ." CMakeFiles/native-lib.dir/src/main/cpp/cpp_example.cpp.o: In
    function `Java_io_jeti_ipopt_1static_MainActivity_stringFromJNI':</p>
  </blockquote>