使用Cmake和Ninja限制ndkBuild的CPU内核

时间:2018-07-27 12:04:53

标签: android cmake ndk-build ninja

之前,当我使用ndkBuld在Android上构建本机代码时,我能够将参数传递给 make 来定义要使用的多个CPU内核。如果我想利用4个核心,我可以添加类似的内容

externalNativeBuild {
    ndkBuild {
        arguments "-j4", "APP_SHORT_COMMANDS=true"
        abiFilters "armeabi-v7a"
    }
}

有人可以建议我如何使用Cmake和Ninja做类似的事情吗? cmake配置是否有一些等效参数?

externalNativeBuild {
    cmake {
        arguments "-DANDROID_STL=c++_static"
        abiFilters getAbis()
    }
}

谢谢。

4 个答案:

答案 0 :(得分:3)

控制忍者并行性

忍者也支持相同的参数:

$ ninja --help
usage: ninja [options] [targets...]

[...]

options:
  [...]

  -j N     run N jobs in parallel [default=10, derived from CPUs available]

  [...]

控制忍者并行性以区分compilelink个工作

现在,如果您想要更多的粒度。例如,如果您想限制同时link jobscompile jobs或两者的数量。

从CMake 3.11开始,现在可以限制compile和/或link作业的数量。

然后可以使用以下选项配置项目:

-DCMAKE_JOB_POOL_COMPILE:STRING=compile
-DCMAKE_JOB_POOL_LINK:STRING=link
'-DCMAKE_JOB_POOLS:STRING=compile=5;link=2'

现在,如果您的项目最终产生了其他子进程,这些子进程本身就是使用忍者来构建项目的,那么您将必须:

  • 像在make中一样,使用忍受的叉子来提供Job Server支持。二进制文件也可以在相关的GitHub版本中获得。参见https://github.com/kitware/ninja#readme

  • 确保子项目也配置了相同的-DCMAKE_JOB_选项

在externalNativeBuild上下文中

这意味着您可以尝试如下操作:

externalNativeBuild { cmake { arguments "-DANDROID_STL=c++_static -DCMAKE_JOB_POOL_COMPILE:STRING=compile -DCMAKE_JOB_POOL_LINK:STRING=link '-DCMAKE_JOB_POOLS:STRING=compile=5;link=2'" abiFilters getAbis() } }

答案 1 :(得分:1)

我能够通过添加以下内容来解决此问题:

if (PARALLEL_COMPILE_JOBS)
  set(CMAKE_JOB_POOL_COMPILE compile_job_pool${CMAKE_CURRENT_SOURCE_DIR})
  string (REGEX REPLACE "[^a-zA-Z0-9]+" "_" CMAKE_JOB_POOL_COMPILE ${CMAKE_JOB_POOL_COMPILE})
  set_property(GLOBAL APPEND PROPERTY JOB_POOLS ${CMAKE_JOB_POOL_COMPILE}=${PARALLEL_COMPILE_JOBS})
endif ()
  if (PARALLEL_COMPILE_JOBS)
    message(STATUS "${CMAKE_CURRENT_SOURCE_DIR}: Limiting compiler jobs to ${PARALLEL_COMPILE_JOBS}")
endif ()

到我的基本CMakeLists.txt,然后在我的build.gradle中添加cmake参数:“ -DPARALLEL_COMPILE_JOBS = 8”,以指定最多8个并行clang ++编译过程。这适用于当前的Android Studio cmake(3.10)和ninja(1.8.2)版本

答案 2 :(得分:0)

好吧,这似乎是NDK中的错误/缺失功能。我已经与一些“ NDK Google员工”进行了交谈,他们也无法帮助我。希望它将在更高版本的NDK / AS中受支持。

以下是您可以跟踪进度的问题:

https://github.com/android-ndk/ndk/issues/983

https://issuetracker.google.com/issues/137878831

答案 3 :(得分:0)

我创建了一种解决方法:将Android Studio使用的ninja可执行文件包装为一个脚本,该脚本以所有给定参数加最后的“ -j1”调用ninja。

  1. 找到Android Studio使用的ninja可执行文件。例如somefolder/Android/Sdk/cmake/3.10.2.4988404/bin/ninja
  2. 重命名为其他名称,例如ninja_orig
  3. 创建一个shell脚本(并为其添加执行权限),以将somefolder/Android/Sdk/cmake/3.10.2.4988404/bin/ninja上的原始ninja可执行文件替换为以下内容:
    #!/bin/sh
    somefolder/Android/Sdk/cmake/3.10.2.4988404/bin/ninja_orig $@ -j1