Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

gradle NDK cmake build fails during linking

I'm building a non-trivial android library, using gradle android build tools v2.2.0, that links to a dozen prebuilt .a files, the output should is a .so file. In attempting to convert from ndk-build to cmake I'm unable to correctly link the .so file because the resulting ninja build seems unable to find the static libraries' headers.

CMakeLists.txt

cmake_minimum_required(VERSION 3.4.1)

set(CMAKE_VERBOSE_MAKEFILE on)

include_directories(${CMAKE_SOURCE_DIR}
    ${CMAKE_SOURCE_DIR}/prebuilt/include )

add_library(precompiledA STATIC IMPORTED)
set_target_properties(precompiledA PROPERTIES 
    IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/prebuilt/dcmtk/lib/libprecompiledA.a)

add_library(precompiledB STATIC IMPORTED)
set_target_properties(precompiledB PROPERTIES 
    IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/prebuilt/dcmtk/lib/libprecompiledB.a)

add_library(precompiledC STATIC IMPORTED)
set_target_properties(precompiledC PROPERTIES 
    IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/prebuilt/dcmtk/lib/libprecompiledC.a)



add_library( jni-library

             SHARED

             hello.cpp )

find_library( log-lib
              log )

target_link_libraries( jni-library 

                       precompiledA
                       precompiledB
                       precompiledC

                       ${log-lib} )

build.gradle

apply plugin: 'com.android.library'

android {
    compileSdkVersion 24
    buildToolsVersion "24.0.2"

    defaultConfig {
        minSdkVersion 19
        targetSdkVersion 24

        ndk {
            abiFilters 'armeabi-v7a'
        }

        externalNativeBuild {
            cmake {
                arguments '-DANDROID_STL=gnustl_static',
                          '-DANDROID_CPP_FEATURES=exceptions'
            }
        }
    }

    externalNativeBuild {
        cmake {
            path 'src/main/cpp/CMakeLists.txt'
        }
    }
}

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

The error - abbreviated

ld: error: cannot find -lprecompiledA
undefined references galore...

When it comes to calling gradle the .o files are generated, but at link time the headers associated with the static libraries seem to be missing and the linking fails. Is there an option to tell cmake where the static library headers are for link-time?

like image 803
Cameron Lowell Palmer Avatar asked Oct 30 '22 19:10

Cameron Lowell Palmer


1 Answers

Correcting undefined references

The mistakes I made were not using target_include_directories, failing to give an absolute path to the library and forgetting the ${ANDROID_ABI} variable for getting the correct version of the binary.

cmake_minimum_required( VERSION 3.4.1 )

set( CMAKE_VERBOSE_MAKEFILE on )

add_library( precompiledA STATIC IMPORTED )
set_target_properties( precompiledA 
                       PROPERTIES 
                       IMPORTED_LOCATION
                       ${CMAKE_SOURCE_DIR}/prebuilt_libs/mylib/lib/${ANDROID_ABI}/libprecompiledA.a )

add_library( precompiledB STATIC IMPORTED )
set_target_properties( precompiledB 
                       PROPERTIES 
                       IMPORTED_LOCATION
                       ${CMAKE_SOURCE_DIR}/prebuilt_libs/mylib/lib/${ANDROID_ABI}/libprecompiledB.a )

add_library( precompiledC STATIC IMPORTED )
set_target_properties( precompiledC 
                       PROPERTIES 
                       IMPORTED_LOCATION
                       ${CMAKE_SOURCE_DIR}/prebuilt_libs/mylib/lib/${ANDROID_ABI}/libprecompiledC.a )

find_library( log-lib
              log )


target_include_directories( dicom-jni PRIVATE
                            prebuilt_libs/mylib/${ANDROID_ABI}/include )

add_library( jni-library
             SHARED
             hello.cpp )

target_link_libraries( jni-library 

                       precompiledA
                       precompiledB
                       precompiledC

                       ${log-lib} )
like image 128
Cameron Lowell Palmer Avatar answered Nov 09 '22 13:11

Cameron Lowell Palmer