简体   繁体   中英

Linking static ".a" libraries to an Android Studio project using Gradle and CMake

I need to link a, prebuilt ".a" static library to an Android Studio project, using CMakeLists.txt.

The .a library was properly built to armeabi, armeabiv-7a, mips and x86 (it can even be "objdumped" for "content checking") and the ".h" files are just right as well.

The goal isn't to recompile the library sources along with my Android Studio project native sources.

Also, please do not refer to solutions using NDK + Andoid.mk (CMakeLists.txt only).

Since there is no working example on this matter on the web (including the Google NDK documentation and SO), please provide every change needed to the project files and/or project structure.

I keep the ".a" file and its "include" directory on a local folder, so as a meta reference to the this location, please consider /lib.a and /include.

Thank you.

After a long research on this subject, this is a working solution, with a couple of minor issues.

Issue #1:

This should work by placing the libxyz.a lib file and its include directory at {AndroidStudioProjects folder}/{The Project's name}/app/libs but for some (still unknown) reason, on my system it never worked like that.

I managed to make it work by placing both (lib file and include dir) at: {AndroidStudioProjects folder}/{The Project's name}/app/src/main/cpp/libs (which had to be created).

Issue #2:

I have faced some 32bit x 64bit linking issues so, at this point, I have given up on "fat APKs" and kept it 32bit only.

What did I do

On CMakeLists.txt add:

add_library(xyz STATIC IMPORTED)
set_target_properties(xyz PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libxyz.a)

And on target_link_libraries (to your shared native lib), you must add the "xyz" reference:

target_link_libraries(
    #the target shared lib:
    native-lib
    #other libs to link go here
    xyz)

Extra:

If you want to be able to include the headers to libxyz.a on your C++ code by using the default include dir, like this:

#inlcude <xyz.h>

You must add it to CMakeLists.txt :

include_directories( ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/include )

Making the output 32bit only

On build.gradle (Module:app) go to the "android defaultConfig" block, right before "externalNativeBuild" and add the ndk abiFilters:

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.your.project"
        minSdkVersion 21
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        ndk {
            abiFilters 'armeabi-v7a', 'x86'
        }
        externalNativeBuild {
            cmake {
                cppFlags ""
            }
        }
    }

Please feel free to improve this.

Create a submodule to your project.

put your *.a files in the appropriate libs/armAppropriate/nameOfLib.a

in your cmakelists.txt add the following lines

set(import-lib-location ${CMAKE_CURRENT_SOURCE_DIR}/../../../libs)

make sure this matches the location of your libs folder, do not use absolute path

put your .h files in the include directory of the submodule main.cpp.include

add the following to your CmakeLists.txt file

include_directories(include/) 
add_library(nameOfLib STATIC IMPORTED )
set_target_properties(crypto
        PROPERTIES IMPORTED_LOCATION ${import-lib-location}/${ANDROID_ABI}/nameOfLib.a)


target_link_libraries( # Specifies the target library.
        your_main_cpp_file

        nameOfLib
        )

Your static lib will be available through api written in your main cpp file and java/kotlin code written in this module

In your build.gradle of your main module write

api project(path: ':project_that_contains_a_libs')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM