【问题标题】:Change ndk-build output locations更改 ndk-build 输出位置
【发布时间】:2015-09-01 03:01:09
【问题描述】:

我的应用具有以下结构

Android
|
|-> app
|    |
|    |-> build [1]
|    |-> src
|    |    |-> main
|    |    |     |-> assets
|    |    |     |-> java
|    |    |     |-> jni 
|    |    |     |     |-> Android.mk
|    |    |     |     |-> Application.mk
|    |    |     |
|    |    |     |-> jniLibs
|    |    |     |      |-> armeabi
|    |    |     |      |-> armeabi-v7a
|    |    |     |
|    |    |     |-> res
|    |    |     |-> AndroidManifest.xml
|
|-> build [2]

我正在 Linux 机器中使用 ndk-build 命令构建我的 .so 库。我像这样使用它:

<my_ndk_path>/ndk-build -C <my_project_path>/Android/app/src/main/

构建过程运行良好,生成的输出文件没有错误。

我的问题是结果文件没有“定向到正确的位置”

libs 生成于:

.app/src/main/libs/armeabi-v7a/libMyGeneratedLibrary.so
.app/src/main/libs/armeabi/libMyGeneratedLibrary.so

以及obj 文件:

.app/src/main/obj/local/armeabi-v7a/libMyGeneratedLibrary.so
.app/src/main/obj/local/armeabi/libMyGeneratedLibrary.so

我希望输出在不同的位置产生:

  1. libsjniLibs。 IE。 ./app/src/main/<em>jniLibs</em>/armeabi*
  2. 构建文件夹之一下的obj。 IE。 build[1] 或 build[2]。

是否有任何可能的方法通过将某些参数更改为.mk 文件或构建命令来实现?


编辑

TARGET_OUT 似乎在 NDK r6b 中不起作用

执行命令ndk-build -C Android/app/src/main/ TARGET_OUT='Android/app/src/main/jniLibs/$(TARGET_ARCH_ABI)'

每个生成的文件都会出现如下警告。

android-ndk-r6b/build/core/build-binary.mk:217: warning: overriding commands for target 'Android/app/src/main/jniLibs//objs/***/****.o'
android-ndk-r6b/build/core/build-binary.mk:217: warning: ignoring old commands for target 'Android/app/src/main/jniLibs//objs/***/****.o'

【问题讨论】:

    标签: android android-gradle-plugin ndk-build


    【解决方案1】:

    您可以使用NDK_LIBS_OUT 更改libs 输出和NDK_OUT 更改obj 输出。 就像这样:ndk-build NDK_LIBS_OUT=./jniLibs NDK_OUT=./obj

    【讨论】:

    • 这对我来说真的不起作用。看起来这些被 NDK 忽略了。也许它是后来版本的一部分,因为我有一个相当旧的 r6b 版本。
    • NDK_OUT 在修订版 7c 中添加; NDK_LIBS_OUT 在修订版 9 中添加。
    • NDK_LIBS_OUT应该添加到哪里,Android.mk还是Application.mk?
    • NDK_LIBS_OUT 应作为参数添加到 ndk-build 调用
    • 那么如何在 ndk-build 调用中添加参数呢? Gradle 3.2.1 一直告诉我arguments 无效。
    【解决方案2】:

    如果您需要为所有可用架构构建,请使用参数:

        TARGET_OUT='<your_build_dir>/$(TARGET_ARCH_ABI)'
    

    如果只有一个目标架构就足够了,那么使用参数:

        TARGET_OUT=<your_build_dir>
    

    【讨论】:

    • 这对我不起作用,我需要的 $(TARGET_ARCH_ABI) 没有任何效果,lib 是在 jniLibs 文件夹中生成的,而不是在 armeabiarmeabi-v7a 中生成的/跨度>
    • 在使用上述参数时,您能否在此处复制并粘贴您的确切命令行?我很好奇,因为我在几个小时前成功地使用了它。另外,您的 NDK 版本是多少?
    • 遗憾的是,它是一个相当旧的 r6b 版本。我尝试了很多不同的方法,还尝试将TARGET_OUT := ... 添加到Application.mk,当它通过并且没有失败时,我收到了我添加到原始帖子中的警告。
    【解决方案3】:

    指定输出位置的更好、更简单的方法是链接Gradle to your native library。 之后,使用ndkBuild 块中的buildStagingDirectory 选项指定输出位置:

    android {
        externalNativeBuild {
            ndkBuild {
                // Tells Gradle to put outputs from external native
                // builds in the path specified below.
                buildStagingDirectory  "src/main/libs"
            }
        }
    }
    

    然后只需 Sync Gradle 并构建,完成。

    【讨论】:

    • buildStagingDirectory 指定外部原生构建输出目录的路径,以替换默认的&lt;project_dir&gt;/.cxx/。我同意上面的官方解释可能会造成混淆,但是这个目录包含中间构建文件(日志、对象等)。 .so 文件通常会转到 &lt;project_dir&gt;/build 目录。请参阅discussion
    • cmakendkBuild 部分似乎都允许 buildStagingDirectory 选项,谢谢!
    【解决方案4】:

    最简单的方法是linkingAndroid.mk 文件到Gradle,像这样:

    android {
        ...
        externalNativeBuild {
            ndkBuild {
                path file('src/main/jni/Android.mk')
            }
        }
    }
    

    然后只需点击立即同步并构建项目

    【讨论】:

      【解决方案5】:

      编辑(适用于使用较新 NDK 版本涉足此主题的任何人):

      • 使用NDK_LIBS_OUT 更改库输出(需要NDK r9 及更高版本)
      • 使用NDK_OUT改变obj输出(需要NDK r7c及以上版本)

      构建命令是:

      ndk-build NDK_LIBS_OUT=./jniLibs NDK_OUT=./obj
      

      上一个答案(适用于任何情况):

      我如何解决它。不是很优雅,但至少它有效。

      因为我的构建机制非常复杂,所以我也有几个自定义的 gradle 任务和脚本,对我来说构建的单个命令并不重要。

      所以我保持原样构建命令

      <my_ndk_path>/ndk-build -C <my_project_path>/Android/app/src/main/
      

      添加文件夹创建(-p 如果存在则不生成错误)

      mkdir -p <my_project_path>/Android/app/src/main/jniLibs/
      

      然后我使用同步命令将 .so 文件移动到最终位置。

      rsync -avh --remove-source-files                        \
            <my_project_path>/Android/app/src/main/libs/*     \
            <my_project_path>/Android/app/src/main/jniLibs/
      

      您可以对obj 文件夹执行类似的操作。我刚刚修改了我的 .gitignore,所以我保持原样。

      【讨论】:

        猜你喜欢
        • 2016-05-27
        • 1970-01-01
        • 2016-05-22
        • 2014-04-22
        • 2013-04-05
        • 2018-08-01
        • 2014-06-29
        • 2022-06-22
        • 1970-01-01
        相关资源
        最近更新 更多