Ограничьте количество ядер ЦП для ndkBuild с Cmake и Ninja

Раньше, когда я использовал ndkBuld для создания собственного кода на Android, я мог передать аргумент делать, чтобы определить количество используемых ядер ЦП. Если бы я хотел использовать 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 822
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

управление параллелизмом ниндзя

Ниндзя также поддерживают тот же параметр:

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

[...]

options:
  [...]

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

  [...]

управление параллелизмом ниндзя, дифференцирующее задания compile и link

Теперь, если вы хотите большей детализации. Например, если вы хотите ограничить количество одновременных link jobs или compile 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. Бинарные файлы также доступны в связанных выпусках 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()
    }
}

Можете ли вы предложить решение в контексте файла сборки Android Gradle? Если я помещаю аргументы в раздел externalNativeBuild { cmake { arguments, я получаю следующую ошибку: Error while executing process D:\Android\sdk\cmake\3.6.4111459\bin\cmake.exe with arguments {--build D:\...\.externalNativeBuild\cmake\fullDebug\arm64-v8a --target JniInterface} ninja: error: build.ninja:113: unknown pool name 'compile' Для другого решения. Я знаю, что ниндзя может принимать параметр -j, но я не запускаю ниндзя напрямую, и добавление -Dj X в качестве аргумента для cmake ничего не делает ...

bio007 30.07.2018 15:01

Учитывая, что -jN - это опция, специфичная для средства сборки ninja, указание -Dj X (или -Dj=X) не будет работать. Ошибка unknown pool name 'compile', вероятно, указывает на то, что вы настроили проект, передав только параметр '-DCMAKE_JOB_POOLS:STRING=compile=5;link=2', и забыли передать -DCMAKE_JOB_POOL_COMPILE:STRING=compile и -DCMAKE_JOB_POOL_LINK:STRING=link.

J-Christophe 30.07.2018 22:11

Я обновил ответ, чтобы предложить возможный подход с использованием externalNativeBuild.

J-Christophe 30.07.2018 22:16

Нет, я уже приводил здесь все аргументы. В любом случае, если вы говорите так, как вы предлагаете, не работает ни Build command failed. Error while executing process D:\...\cmake.exe with arguments {-HD:\...\sdk -BD:\...\arm64-v8a -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=android-21 -DCMAKE_LIBRARY_OUTPUT_DIRECTORY=D:\...\arm64-v8a -DCMAKE_BUILD_TYPE=Debug ... -DCMAKE_MAKE_PROGRAM=D:\...\ninja.exe -GAndroid Gradle - Ninja -DANDROID_STL=c++_static -DCMAKE_JOB_POOL_COMPILE:STRING=compile -DCMAKE_JOB_POOL_LINK:STRING=link '-DCMAKE_JOB_POOLS:STRING=compile=5;link=2'}

bio007 31.07.2018 08:31

все сообщение об ошибке было слишком длинным, поэтому я удалил пути и некоторые неважные аргументы. Но я не думаю, что это должно быть проблемой для тебя

bio007 31.07.2018 08:32

Если указанные аргументы фактически являются аргументами, переданными через командную строку, наличие -GAndroid Gradle - Ninja без кавычек кажется подозрительным. Есть ли другие соответствующие сообщения?

J-Christophe 31.07.2018 09:44

Ошибка возникает уже во время синхронизации gradle. Но ничего другого, имеющего отношение к этому вопросу, нет.

bio007 31.07.2018 10:18

Вы подтверждаете, что проблема возникла с добавлением опций -DCMAKE_JOB_*? Если вы удалите их, сборка будет завершена? Или хотя бы нормально запускается? Возможно, вы могли бы попытаться удалить одинарную кавычку ', это необходимо сделать при запуске команды из командной строки, чтобы избежать интерпретации ;. В вашем случае это может быть не нужно.,

J-Christophe 31.07.2018 10:28

да, без атрибутов -DCMAKE_JOB_* сборка работает нормально, успешно создавая APK в конце. Котировки в '-DCMAKE_JOB_POOLS:STRING=compile=5;link=2' без разницы. Я пробовал без них и результат был такой же

bio007 31.07.2018 10:31

Позвольте нам продолжить обсуждение в чате.

J-Christophe 31.07.2018 17:31

Не могли бы вы сообщить нам результат обсуждения? У меня такие же проблемы.

oar.garuna 23.05.2019 11:31

Похоже, архив чата недоступен, или этого не было (это было некоторое время назад). Тем не менее, если вам не повезло с настройкой -DCMAKE_JOB_, вы можете изучить установку переменной окружения CMAKE_BUILD_PARALLEL_LEVEL [1]. Примечание: независимо от подхода, если вы используете модуль ExternalProject (IOW, если проект ниндзя заканчивается созданием другого проекта, основанного на ниндзя), вы должны использовать форк сервера заданий поддержки ниндзя [2]) [1] cmake.org/cmake/help/latest/envvar/… [2] github.com/kitware/ninja#readme

J-Christophe 24.05.2019 08:20
Ответ принят как подходящий

Хорошо, похоже, это ошибка / отсутствующая функция в NDK. Я разговаривал с некоторыми «гуглерами NDK», и они тоже не смогли мне помочь. Надеюсь, он будет поддерживаться в более поздних версиях NDK / AS.

Вот проблемы, по которым вы можете отслеживать прогресс:

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

а также

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

Я создал обходной путь: оберните исполняемый файл ninja, используемый Android Studio, скриптом, который вызывает ninja со всеми заданными параметрами плюс «-j1» в конце.

  1. Найдите исполняемый файл ниндзя, используемый Android Studio. Что-то вроде, например, somefolder/Android/Sdk/cmake/3.10.2.4988404/bin/ninja
  2. Переименуйте его во что-нибудь другое, например ninja_orig
  3. Создайте сценарий оболочки (и добавьте к нему разрешение на выполнение), чтобы заменить исходный исполняемый файл ninja на somefolder/Android/Sdk/cmake/3.10.2.4988404/bin/ninja следующим содержимым:
    #!/bin/sh
    somefolder/Android/Sdk/cmake/3.10.2.4988404/bin/ninja_orig $@ -j1
    

Я смог исправить это, добавив:

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

Другие вопросы по теме