-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for Ninja Multi-Config
generator
#3
Comments
When reading the configurations for a given configure preset we get a vector of configurations. I don't use Ninja Multi-Config myself and thus this vector of configurations always has only one element. Therefore, currently I just get the first element in the vector of configurations. In the case of multi-config, this vector has three elements. The current implementation just gets the first one, which is likely the debug build. I took a look at which changes would be required to support this. One limitation at the moment is that when configuring the user selects the desired preset from a list of configure presets. Then, when building, I just assume that there is a build preset with the same name of the configure preset and use that. One way to solve this issue is to have a build preset for each build type (Debug, Release, etc), all referencing the same configure preset using the Ninja Multi-Config generator. Then the code in cmake-integration would need to change to read build preset names, instead of configure preset names. With this, the usage would be similar to what we have currently. But I don't know how it would work when presets are not employed. Could you elaborate how you usually configure and build with different configurations from the command line using the Ninja Multi-Config generator. |
Using a build dir generated by the Ninja Multi-Config generator is (by default) no different than using the normal Ninja generator. You can just say:
or
This will, by default, build the To build the other configurations, cmake supports the
or:
JFYI: There are some additional variables to control the Multi Config build. The more interesting ones are:
|
Looking at /.cmake/api/v1/reply/codemodel-v2-*.json, the multi config variant just has muliple elements in the I.e. for a project with targets
whereas the Multi Config case has:
So what would make sense is to construct a Multi Config target list containing elements like:
(or put the config at the beginning - this is a personal preference). |
If you haven't spent time on this yet: I'm currently looking at the sources and will create a pull request. |
The three elements are the default (s.
Even the presets could reference Multi-Config generators. So preset type builds should also support multiple configs.
I wasn't able to follow you there. Maybe because I have not used CMake presets. But I think it is less complicated since presets and (multi-)configs are orthogonal (as mentioned above, a preset could use a multi-config generator - Microsoft has example for that: https://docs.microsoft.com/de-de/cpp/build/cmake-presets-vs?view=msvc-170#linux-example). The solution I implemented in #4 should work for preset and non preset builds. Basically, for preset + multi-config builds you now get a compile command of:
whereas for non-preset builds you get:
For non multi-config builds, the |
An example for such a generator is 'Ninja Multi-Config'. The commit changes the 'target-name' variables/functions to 'target' which is now a combination of the actual 'target name' and the 'configuration name' separated by `cmake-integration--multi-config-separator' (in case of a non multi-config generator, the configuration name is nil and 'target' is identical to 'target name'). The handling of the 'all' target has changed, too. It is now included in the list you get from `check-if-build-folder-exists-and-throws-if-not' (since it also needs to have the multi-config variants). In addition to the above, I also added a call to `check-if-build-folder-exists-and-throws-if-not' in `cmake-integration-run-last-target'. Closes darcamo#3.
An example for such a generator is `Ninja Multi-Config` (introduced in CMake 3.17). The commit changes the semantic (and name) of `target-name` variables/functions to `target` which is now a combination of the actual _target name_ and the _configuration name_ separated by `cmake-integration--multi-config-separator` (in the - now - special case of a _non multi-config_ generator, the _configuration name_ is nil and _target_ is identical to _target name_). The handling of the `all` target has changed, too. It is now included in the list you get from `cmake-integration-get-cmake-targets-from-codemodel-json-file` (since it also needs to have the _multi-config_ variants). In addition to the above, I also added a call to `check-if-build-folder-exists-and-throws-if-not` in `cmake-integration-run-last-target`. Closes darcamo#3.
An example for such a generator is `Ninja Multi-Config` (introduced in CMake 3.17). The commit changes the semantic (and name) of `target-name` variables/functions to `target` which is now a combination of the actual _target name_ and the _configuration name_ separated by `cmake-integration--multi-config-separator` (in the - now - special case of a _non multi-config_ generator, the _configuration name_ is nil and _target_ is identical to _target name_). The handling of the `all` target has changed, too. It is now included in the list you get from `cmake-integration-get-cmake-targets-from-codemodel-json-file` (since it also needs to have the _multi-config_ variants). In addition to the above, I also added a call to `check-if-build-folder-exists-and-throws-if-not` in `cmake-integration-run-last-target`. Closes darcamo#3.
There are different types of presets. There is a "configure preset", a "build preset", and a "test preset".
it's using a configure preset because you are configuring. Also, notice that the command is run from the folder with the CMakeLists.txt file and does not specify the build folder, which is obtained from the preset. If you add There are two approaches here.
I think using approach 1 works better and build presets can be reintroduced later in a better way. |
An example for such a generator is `Ninja Multi-Config` (introduced in CMake 3.17). The commit changes the semantic (and name) of `target-name` variables/functions to `target` which is now a combination of the actual _target name_ and the _configuration name_ separated by `cmake-integration--multi-config-separator` (in the - now - special case of a _non multi-config_ generator, the _configuration name_ is nil and _target_ is identical to _target name_). The handling of the `all` target has changed, too. It is now included in the list you get from `cmake-integration-get-cmake-targets-from-codemodel-json-file` (since it also needs to have the _multi-config_ variants). In addition to the above, I also added a call to `check-if-build-folder-exists-and-throws-if-not` in `cmake-integration-run-last-target`. Closes darcamo#3.
An example for such a generator is `Ninja Multi-Config` (introduced in CMake 3.17). The commit changes the semantic (and name) of `target-name` variables/functions to `target` which is now a combination of the actual _target name_ and the _configuration name_ separated by `cmake-integration--multi-config-separator` (in the - now - special case of a _non multi-config_ generator, the _configuration name_ is nil and _target_ is identical to _target name_). The handling of the `all` target has changed, too. It is now included in the list you get from `cmake-integration-get-cmake-targets-from-codemodel-json-file` (since it also needs to have the _multi-config_ variants). In addition to the above, I also added a call to `check-if-build-folder-exists-and-throws-if-not` in `cmake-integration-run-last-target`. Closes darcamo#3.
Could you send me a preset file which contains these different types? |
Here is a presets file containing a "default" build and configure presets, as well as a preset using "Ninja Multi-Config". Save this as {
"version": 3,
"cmakeMinimumRequired": {
"major": 3,
"minor": 21,
"patch": 0
},
"configurePresets": [
{
"name": "default",
"displayName": "Default build using Ninja generator",
"generator": "Ninja",
"binaryDir": "build",
},
{
"name": "ninjamulticonfig",
"displayName": "Multi-Config configure preset",
"description": "Default build using Ninja Multi-Config generator",
"generator": "Ninja Multi-Config",
"binaryDir": "${sourceDir}/build-multi/",
"inherits": "default"
}
],
"buildPresets": [
{
"name": "default",
"displayName": "Default build preset",
"configurePreset": "default"
},
{
"name": "ninjamulticonfig",
"displayName": "Build preset using ninja multi-config",
"configurePreset": "ninjamulticonfig",
"configuration": "Release"
}
]
} |
Thanks! (BTW, the default configurePreset has an extra comma in the binaryDir line which irritates the json parser.) Ok, I think I have a better understanding now. But I still wonder what the buildPresets really do. In your example, they basically serve the purpose of selecting a binaryDir (created by the linked configurePreset). In a way, they just create an alias name for binaryDir: I.e. instead of:
you can now say:
Is that all buildPresets are used for? Or do they provide some additional benefits? I probably need to have a closer look at the CMake presets documentation... Interestingly, the project to which I added the presets file already had a binaryDir named
So CMake doesn't check if the linked configurePreset actually supports the requested configuration. However, after I removed the non-preset /build/ dir and recreated it using the default confgurePreset, I can add a configuration=RelWithDebInfo to the (non multi-config) default buildPreset, and CMake just ignores that (so there is some consistency checking going on). |
Some further tests have shown that, In case of a multi-config binaryDir, a buildPreset also allows to select the default config. I.e.:
behaves as if a And, according to the documentation (https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html), there are some additional attributes which can be configured via buildPresets. So they do have their purpose. |
Since this issue is already closed, I opened a new issue #7 to discuss the buildPreset handling. |
CMake version 3.17 added the
Ninja Multi-Config
generator (https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html?highlight=ninja%20multi#generator:Ninja%20Multi-Config) which supports multiple build types in a single binary (build) directory (currently:Debug
,Release
,ReleaseWithDebInfo
).When using cmake-integration with a
Ninja Multi-Config
build directory, it should offer targets for all combinations of target name and build type/config.The text was updated successfully, but these errors were encountered: