【问题标题】:How to tell CMake (invoked through externalNativeBuild) where to look for libraries?如何告诉 CMake(通过 externalNativeBuild 调用)在哪里寻找库?
【发布时间】:2021-05-26 02:52:06
【问题描述】:

我正在开发一个支持 Linux 和 Android 的多平台项目。代码多为C; Android 端口有一个用于特定平台部分的 Java 包装器,它调用本机代码部分来实现核心功能。

在 Linux 上,我们使用 CMake 构建此项目,然后使用 make。对于 Android,我们基本上使用 Gradle 并通过 externalNativeBuild 调用 CMake。 CMakeFile.txt 可以通过简单的if (ANDROID) 检测 Android 构建,让我们能够

该项目依赖于一些标准库,我们在CMakeLists.txt 中使用以下内容检测到:

find_package(PkgConfig)
if(PKG_CONFIG_FOUND)
    pkg_check_modules ( FOO foo-42.0 )
    if (FOO_FOUND)
        set(HAVE_FOO 1)
        include_directories(${FOO_INCLUDE_DIRS})
        # …

在为 Android 构建时,这不会为主机操作系统(位于 /usr/include/ 下方)而不是为 Android (位于 $NDK/sysroot 下方)选择任何内容或库。 (注意$NDK只是表示NDK路径,不一定是环境变量。)

根据this postpkg-config 依赖于一堆环境变量来确定在哪里寻找库,即CMAKE_SYSROOTPKG_CONFIG_DIRPKG_CONFIG_LIBDIRPKG_CONFIG_SYSROOT_DIR。我检查了它们,它们是空的(或未设置)。

使用 gradle/NDK/CMake 工具链,我怎样才能将正确的变量传递给 CMake,或者让它找到 NDK 为其提供标头的库?

【问题讨论】:

    标签: android gradle cmake android-ndk


    【解决方案1】:

    有两种选择:

    1. 如果预建库安装在托管操作系统上(例如,我们使用docker image,包括所有已编译和安装的预建库和其他先决条件 - SDK、NDK、AndroidStudio 等),您需要提供@987654323 @ librariesincludescmake configs 的安装位置:
    list(APPEND CMAKE_FIND_ROOT_PATH ${THIRDPARTY_DIR}/${THIRDPARTY_ANDROID_PLATFORM}/${ANDROID_ABI}/boost)
    
    1. 如果未安装预构建,您需要提供Find<module>.cmake,例如FindBoost.cmake 来服务find_package(Boost)(这里有一个example 说明它的可能方式,这个项目也使用了多平台部件)。

    【讨论】:

    • 谢谢,但问题不在于捆绑预建库,而在于使用 Android 附带的库(例如标准 C 库)并确保 CMake 找到正确的头文件。
    • 没关系,算法是一样的,所以Android(NDK)自带的库不提供*config.cmake,所以要支持find_package(),需要提供Find<>.cmake无需支持,您可以使用 find_library 与 NDK 一起使用或直接链接所需的库,例如:target_link_libraries(native-lib log)
    【解决方案2】:

    NDK 路径可用于 gradle 为 android.ndkDirectory。像这样更新build.gradle

    android {
        // ...
        defaultConfig {
            // ...
            externalNativeBuild {
                cmake {
                    // amend existing list of arguments, if you have one
                    arguments '-DCMAKE_SYSROOT='+android.ndkDirectory+'/sysroot'
                }
            }
        }
    }
    

    然后,在CMakeLists.txt,在第一次使用pf pkg-config之前,添加:

    if(ANDROID)
        set(ENV{PKG_CONFIG_DIR} "")
        set(ENV{PKG_CONFIG_LIBDIR} "${CMAKE_SYSROOT}/usr/lib/pkgconfig:${CMAKE_SYSROOT}/usr/share/pkgconfig")
        set(ENV{PKG_CONFIG_SYSROOT_DIR} ${CMAKE_SYSROOT})
    endif(ANDROID)
    

    【讨论】:

      猜你喜欢
      • 2014-12-02
      • 2018-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-14
      • 2014-03-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多