【问题标题】:gradle NDK cmake build fails during linking链接期间gradle NDK cmake构建失败
【发布时间】:2016-10-01 10:35:31
【问题描述】:

我正在使用 gradle android build tools v2.2.0 构建一个重要的 android 库,它链接到十几个预构建的 .a 文件,输出应该是一个 .so 文件。在尝试从 ndk-build 转换为 cmake 时,我无法正确链接 .so 文件,因为生成的 ninja 构建似乎无法找到静态库的标头。

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'])
}

错误 - 缩写

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

在调用 gradle 时会生成 .o 文件,但在链接时,与静态库关联的标头似乎丢失并且链接失败。是否可以选择告诉 cmake 链接时静态库头在哪里?

【问题讨论】:

  • 我不是 gradle 专家,但错误消息 cannot find -lprecompiledA 闻起来像 CMake 解释库传递给 target_link_libraries 作为通用(系统)库,并忽略以前的 add_library(IMPORTED) 调用。但是发布的 CMake 代码似乎是正确的......你说的“标题”是什么?链接器根本不适用于标头,它们在 compile 阶段完全处理。

标签: gradle android-ndk cmake


【解决方案1】:

更正未定义的引用

我犯的错误是没有使用target_include_directories,没有给出库的绝对路径,忘记了${ANDROID_ABI} 变量来获取正确版本的二进制文件。

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} )

【讨论】:

  • 谢谢,这是一个将其他预建库添加到我的 NDK 项目中的简明示例。只是给其他人的说明:它是预编译的,而不是 target_link_libraries() 中的 ${precompiledA}!我花了将近 2 个小时才发现:(
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-30
  • 2016-10-26
  • 1970-01-01
  • 2018-01-16
  • 1970-01-01
相关资源
最近更新 更多