Repository: conan-io/conan
Pull request: set jobs parameter in cmake build presets(#15419)
Changelog: Feature: ``CMakeToolchain`` defines ``jobs`` in generated ``CMakePresets.json`` buildPresets.
Docs: Omit

this should be seen as a proof of concept for the feature request to have conan generate CMakePresets.json with jobs parameter set.

closes #15419

- [x] Refer to the issue that supports this Pull Request.
- [ ] If the issue has missing info, explain the purpose/use case/pain/need that covers this Pull Request.
- [x] I've read the [Contributing guide](https://github.com/conan-io/conan/blob/develop/.github/CONTRIBUTING.md).
- [?] I've followed the PEP8 style guides for Python code.
- [ ] I've opened another PR in the Conan docs repo to the ``develop`` branch, documenting this one.


Problem statement:
[feature] set jobs parameter in CMakePreset buildPresets to get parallel builds when invoking cmake after conan install
### What is your suggestion?

the generated CMakePresets.json does not contain the "jobs" parameter, making it default to 1 (at least sometimes).
when manually set to a higher number, the cmake build command builds in parallel as expected.
it would be good if Conan could set this parameter while generating the preset file(s).

example "buildPresets" section before this feature is implemented:
```
    "buildPresets": [
        {
            "name": "conan-relwithdebinfo",
            "configurePreset": "conan-relwithdebinfo"
        }
    ],
```

example "buildPresets" section with the proposed feature:
```
    "buildPresets": [
        {
            "name": "conan-relwithdebinfo",
            "configurePreset": "conan-relwithdebinfo",
            "jobs": 16
        }
    ],
 ```
 
 this allows cmake to be invoked as follows, `cmake --build --target all --preset conan-relwithdebinfo` and have it build in parallel (much faster).
 

 the issue was observed on Ubuntu 23.10
```
 $ lsb_release -a
Distributor ID:	Ubuntu
Description:	Ubuntu 23.10
Release:	23.10
Codename:	mantic
```

Conan version 2.0.14
cmake version 3.27.4

### Have you read the CONTRIBUTING guide?

- [X] I've read the CONTRIBUTING guide

Hints from issue discussion:
Hi @Hailios 

Thanks for your suggestion.
I think this could make sense, might be doable, I'll check with the team.

Commit message: set jobs parameter in cmake build presets(#15419)

Patch to review:
diff --git a/conan/tools/cmake/presets.py b/conan/tools/cmake/presets.py
index cb11e2174f8..1afddfae630 100644
--- a/conan/tools/cmake/presets.py
+++ b/conan/tools/cmake/presets.py
@@ -6,6 +6,7 @@
 from conan.tools.cmake.layout import get_build_folder_custom_vars
 from conan.tools.cmake.toolchain.blocks import GenericSystemBlock
 from conan.tools.cmake.utils import is_multi_configuration
+import conan.tools.build as build
 from conan.tools.microsoft import is_msvc
 from conans.client.graph.graph import RECIPE_CONSUMER
 from conan.errors import ConanException
@@ -189,6 +190,8 @@ def _common_preset_fields(conanfile, multiconfig, preset_prefix):
     @staticmethod
     def _build_preset_fields(conanfile, multiconfig, preset_prefix):
         ret = _CMakePresets._common_preset_fields(conanfile, multiconfig, preset_prefix)
+        build_preset_jobs = build.build_jobs(conanfile)
+        ret["jobs"] = build_preset_jobs
         return ret
 
     @staticmethod


Code review comments:
diff_hunk: @@ -6,6 +6,7 @@
 from conan.tools.cmake.layout import get_build_folder_custom_vars
 from conan.tools.cmake.toolchain.blocks import GenericSystemBlock
 from conan.tools.cmake.utils import is_multi_configuration
+import conan.tools.build as build
path: conan/tools/cmake/presets.py
text: @user1:
Better import directly ``build_jobs``, we are not using scoping in general.

@author:
updated

@user1:
Great, thanks.

Did you check my comment above? 
> Looks good and low risk. A small unit/integration test (not really necessary a functional one) could be enough to move this forward (I have checked with the team, good to move it)

Do you think you can add some small test, it seems in https://github.com/conan-io/conan/blob/develop2/conans/test/integration/toolchains/cmake/test_cmaketoolchain.py would be the best, some of the existing ones can help? If not let me know and I'll do it

@author:
would be great if you could do it :)

@user1:
I contributed the test, and also moved the definition to the "common" preset, so it also applies to the ``testPresets``. I understand that we also want to do it, in the same way it affects also the ``CMake.test()`` helper?

@author:
thanks for the test. very good choice of parallel jobs ;)

this should _not_ be added to the testPresets. I do not have deep enough CMake knowledge to know why, but cmake cannot parse the same jobs parameter in the testPresets.

example invalid presets sections
```
    "buildPresets": [
        {
            "name": "conan-debug",
            "configurePreset": "conan-debug",
            "jobs": 16
        }
    ],
    "testPresets": [
        {
            "name": "conan-debug",
            "configurePreset": "conan-debug",
            "jobs": 16
        }
    ]
```

produces the following error
```
$ cmake --build --target all --preset conan-relwithdebinfo
CMake Error: Could not read presets from <path to root directory>:
Error: @user2,21: Invalid extra field "jobs" in Preset
            "jobs": 16
                    ^
```


it builds in parallel with "jobs": 16 in only the buildPresets, and more importantly does not fail to read the presets.

@user1:
I see, yeah, lets remove it!

I'll leave jobs=42 (the answer to everything ;)  only for buildPresets