diff --git a/docs/en/api-guides/build-system.rst b/docs/en/api-guides/build-system.rst index bec630be8b0..738fe2f02a6 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 2f41f4d8971..e09eacff7e3 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 24c26d9d740..08a83b25bfa 100644 --- a/tools/idf_py_actions/core_ext.py +++ b/tools/idf_py_actions/core_ext.py @@ -537,6 +537,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..3dcf2894566 100644 --- a/tools/idf_py_actions/global_options.py +++ b/tools/idf_py_actions/global_options.py @@ -1,4 +1,4 @@ -# 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'], diff --git a/tools/idf_py_actions/tools.py b/tools/idf_py_actions/tools.py index 015f536973f..7bda66f1bdd 100644 --- a/tools/idf_py_actions/tools.py +++ b/tools/idf_py_actions/tools.py @@ -667,18 +667,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']]