Search code examples
androidandroid-studiocmakeandroid-ndkndk-build

Making CMake native library on another ndkbuild library


I have two Android libraries which need to be built for my application. The dependency graph is as follows:

Myapp --> ProjectA --> ProjectF

Myapp depends on ProjectA (which is a library project), and ProjectA depends on ProjectF (also a library project).

ProjectA and ProjectF both contain native code.

ProjectA is built using CMake (which I wrote), and ProjectF is a project I downloaded from Github, and uses ndkbuild (contains Android.mk). It builds fine from the command line. I created a build.gradle for ProjectF so as to include it in my Android Studio project for the application. This build.gradle looks like below.

apply plugin: 'com.android.library'
apply plugin: 'com.github.dcendents.android-maven'

android {
    compileSdkVersion 29

    defaultConfig {
        minSdkVersion 16
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles.add(file("proguard-rules.pro"))
        }
    }

    externalNativeBuild {
        ndkBuild {
            path 'jni/Android.mk'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
}

I have set up the dependency in the project structure as above.

My CMakeLists.txt file for ProjectA looks like this:

cmake_minimum_required(VERSION 3.4.1)

add_library(
             my-native-lib
             SHARED
             [List of .c/.cpp source files for ProjectA]
            )

include_directories(
        [list of include directories for ProjectA and API headers from ProjectF]
        )

add_library(
        ProjectF   #[this is the library which should be linked when building ProjectA]

        STATIC
        IMPORTED
        )

find_library(
        log-lib

        log )


target_link_libraries(
        my-native-lib

        ${log-lib} )

However, I am getting linker errors when building ProjectA, for symbols referenced from ProjectF. The linker command shows that the library from ProjectF was not linked at all.

I am sure I am missing something really stupid. I would really appreciate any help.


Solution

  • The ProjectF target library was not linked because it was not included in your target_link_libraries() call. CMake will not link this library to other libraries automatically; you have to explicitly tell CMake which libraries to link. You likely need to tell CMake where your imported ProjectF library resides on your machine as well, using the IMPORTED_LOCATION property.

    Also, find_library() is often called with the PATHS argument to tell CMake where to look for a specific library. If your log library is not found, consider adding some search paths.

    The updated portion of your CMake code could look something like this:

    add_library(
            ProjectF   #[this is the library which should be linked when building ProjectA]
            STATIC
            IMPORTED
            )
    
    # Tell CMake where ProjectF library exists.
    set_target_properties(ProjectF PROPERTIES
            IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/path/to/libs/ProjectFLib.a
            )
    
    find_library(
            log-lib
            PATHS /path/containing/your/log/lib
            log )
    
    # Don't forget to link ProjectF here!
    target_link_libraries(
            my-native-lib PUBLIC
            ProjectF
            ${log-lib} )