diff --git a/docs/en/api-guides/build-system.rst b/docs/en/api-guides/build-system.rst index 4b6b91044db..a9079826b8f 100644 --- a/docs/en/api-guides/build-system.rst +++ b/docs/en/api-guides/build-system.rst @@ -77,7 +77,13 @@ In the above list, the ``cmake`` command configures the project and generates bu It's not necessary to run ``cmake`` more than once. After the first build, you only need to run ``ninja`` each time. ``ninja`` will automatically re-invoke ``cmake`` if the project needs reconfiguration. -When using ``idf.py`` with the Ninja generator, you can cap the number of parallel build jobs by setting the ``IDF_PY_BUILD_JOBS`` environment variable. For example: +You can control the number of parallel build jobs passed to the underlying build tool (Ninja or Make) with the ``-j``/``--jobs`` option of ``idf.py``. For example: + +.. code-block:: bash + + idf.py -j 6 build + +The same value can be set with the ``IDF_PY_BUILD_JOBS`` environment variable, which is used as the default when ``-j``/``--jobs`` is not given: .. code-block:: bash diff --git a/docs/zh_CN/api-guides/build-system.rst b/docs/zh_CN/api-guides/build-system.rst index 0b80ff0d863..2cf38e8b825 100644 --- a/docs/zh_CN/api-guides/build-system.rst +++ b/docs/zh_CN/api-guides/build-system.rst @@ -77,7 +77,13 @@ idf.py 没有必要多次运行 ``cmake``。第一次构建后,往后每次只需运行 ``ninja`` 即可。如果项目需要重新配置,``ninja`` 会自动重新调用 ``cmake``。 -使用 Ninja 生成器配合 ``idf.py`` 时,可以通过设置环境变量 ``IDF_PY_BUILD_JOBS`` 来限制并行构建任务数。例如: +使用 ``idf.py`` 时,可以通过 ``-j``/``--jobs`` 选项来控制传递给底层构建工具(Ninja 或 Make)的并行构建任务数。例如: + +.. code-block:: bash + + idf.py -j 6 build + +也可以通过设置环境变量 ``IDF_PY_BUILD_JOBS`` 来指定该值,当未提供 ``-j``/``--jobs`` 时,该环境变量将作为默认值使用: .. code-block:: bash diff --git a/tools/idf_py_actions/constants.py b/tools/idf_py_actions/constants.py index 3c97b50affe..b21b5a4aba0 100644 --- a/tools/idf_py_actions/constants.py +++ b/tools/idf_py_actions/constants.py @@ -29,7 +29,9 @@ GENERATORS: dict[str, str | dict | list] = collections.OrderedDict( if os.name != 'nt': MAKE_CMD = 'gmake' if platform.system() == 'FreeBSD' else 'make' GENERATORS['Unix Makefiles'] = { - 'command': [MAKE_CMD, '-j', str(multiprocessing.cpu_count() + 2)], + # Make, unlike Ninja, does not parallelize by default; run_target() applies this as -j. + 'default_jobs': multiprocessing.cpu_count() + 2, + 'command': [MAKE_CMD], 'version': [MAKE_CMD, '--version'], 'dry_run': [MAKE_CMD, '-n'], 'verbose_flag': 'VERBOSE=1', diff --git a/tools/idf_py_actions/core_ext.py b/tools/idf_py_actions/core_ext.py index b9a6aabe165..8c01fb5c545 100644 --- a/tools/idf_py_actions/core_ext.py +++ b/tools/idf_py_actions/core_ext.py @@ -536,6 +536,13 @@ def action_extensions(base_actions: dict, project_path: str) -> Any: 'help': 'CMake generator.', 'type': click.Choice(GENERATORS.keys()), }, + { + 'names': ['-j', '--jobs'], + 'help': 'Number of parallel build jobs passed to the build tool (Ninja or Make).', + 'envvar': 'IDF_PY_BUILD_JOBS', + 'type': click.IntRange(min=1), + 'default': None, + }, { 'names': ['--dry-run'], 'help': "Only process arguments, but don't execute actions.", diff --git a/tools/idf_py_actions/global_options.py b/tools/idf_py_actions/global_options.py index fecc40042e9..8d1ca5a6a8c 100644 --- a/tools/idf_py_actions/global_options.py +++ b/tools/idf_py_actions/global_options.py @@ -1,8 +1,10 @@ -# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Apache-2.0 -global_options = [{ - 'names': ['-D', '--define-cache-entry'], - 'help': 'Create a cmake cache entry.', - 'scope': 'global', - 'multiple': True, -}] +global_options = [ + { + 'names': ['-D', '--define-cache-entry'], + 'help': 'Create a cmake cache entry.', + 'scope': 'global', + 'multiple': True, + } +] diff --git a/tools/idf_py_actions/tools.py b/tools/idf_py_actions/tools.py index 33db67ae0b6..e741769e1db 100644 --- a/tools/idf_py_actions/tools.py +++ b/tools/idf_py_actions/tools.py @@ -646,18 +646,13 @@ def run_target( generator_cmd = list(GENERATORS[args.generator]['command']) - if args.generator == 'Ninja': - parallel_level = os.environ.get('IDF_PY_BUILD_JOBS') - if parallel_level: - try: - jobs = int(parallel_level) - except ValueError as e: - raise FatalError('Environment variable IDF_PY_BUILD_JOBS must be a positive integer') from e + # Parallel jobs from -j/--jobs (or IDF_PY_BUILD_JOBS), falling back to the generator's default. + jobs = getattr(args, 'jobs', None) + if jobs is None: + jobs = GENERATORS[args.generator].get('default_jobs') - if jobs <= 0: - raise FatalError('Environment variable IDF_PY_BUILD_JOBS must be a positive integer') - - generator_cmd += ['-j', str(jobs)] + if jobs is not None: + generator_cmd += ['-j', str(jobs)] if args.verbose: generator_cmd += [GENERATORS[args.generator]['verbose_flag']]