Closed fred-r closed 1 year ago
@slhultgren @mdortel-stm @lmestm @vgrstm
See also : #158
@fred-r, thanks a lot for raising this and don't be sorry. Searching for clarity is always the right thing and ensuring a solid written specification is what we should aim for.
My reading of it is:
1) If you have a fully specified component selection in your project (ST::Device:Driver:UART&debug_variant@1.0.0 that comes from a pack) then we 'define' that if the same component being specified in the gpdsc would "replace"/"override" (no merging) the one from the pack. In MDK today by default the component selection does not specify the version of the component, therefore the gpdsc could also specify a version > 1.0.0
and again the component specified by the gpdsc would replace the one from the pack.
2) I don't think that Cvariant is optional
in that way. If the selected component contains a Cvariant description, then it cannot be 'replaced' with a component described in the gpdsc that has a different Cvariant or no Cvariant at all
3) If the selected component does not contain a Cvariant specification. If there is a component available (pack or gpdsc) that does not specify a Cvariant either, then this must be selected. The fuzziness starts if there does not exist a component without Cvariant, any component with a Cvariant can be chosen. If any of these other components has the attribute isDefaultVariant="true"
set, then this one is selected. It was designed in that way to provide a migration in case in the life-cycle of a component, it is require to split it into multiple variants.
Note: it is strongly suggested that the pack vendor avoids a mix of component IDs with and without Cvariant. If a split of a component into multiple variants is required, all the component variants shall have a Cvariant attribute set.
4) Let's be clear, if the gpdsc describes a component it must include a Cversion attribute. We can have conditions without Cversion specification and in the csolution, cproject and clayer yml files we can specify components without specifying a version.
If we have selected a fixed version component and the gpdsc describes a different version I think we should get an error as conceptually we cannot have the same component selected twice with different versions (have not tried this yet). So it requires the user to decide. I would recommend that the user does not select a component with version and rely on the generator to generate a suitable component version. But maybe there is a use case where the user would need to use a different version of the generator in order to have a component version generated that matches the version requirements
5) If the project selects a component without version and the generator tries to override an existing component but specifies a version that is smaller than the one from a pack, then the version from the generator is ignored just like any other small component version found in any previous pack version that is currently installed.
How can we best rephrase and extend the specification to make the handling defined better?
Just to comment that part (because @jkrech already made the job I guesss):
as the variant is optional in the component id
The variant is not optional. It is just that is not always in the component id because not all components are dealing with variants. But, as soon as you have variants, they must be part of the id.
@jkrech maybe that information should be expressed in a different way: it is optional from an XML validation point of view but it is not an optional part of the id. My wording: Cvariant is a mandatory part of the id, even if empty.
@fred-r thanks for raising this questions. I think there are multiple problems.
Component Definition
CSub and CVariant are optional, components names such as ARM::CMSIS:Core
are therefore possible. This is already covered in the Open-CMSIS-Pack spec and does not require further information.
Multiple pack versions in same csolution
MDK allows to add multiple versions of a software pack, and to pick components from older pack version by explicitly specifying component versions. However, in practice this feature is not used and I'm leaning towards dropping support for it to keep the tool flow simpler.
Q: Are we aligned on this view?
This information is missing in YML-Input-Format.md
Partly defined components
A component can be partly defined in csolution
input files by omitting Cvendor
, Cvariant
, and Cversion
. The component select algorithm resolves this to a fully defined component by:
csolution
input files.The fully defined component is shown in the *.cbuild.yml
file.
Multiple component definitions
If a component is added more then once in csolution
input files (*.cproject.yml
, *.clayer.yml
, *.genlayer.yml
).
*.cproject.yml
, *.clayer.yml
files.*.genlayer.yml
files another component definition is accepted, but the csolution
tool verifies that definition resolves to the same fully defined component, otherwise an error is issued.In a nutshell, it is possible to write in:
cproject.yml: - component: CMSIS:RTOS2:FreeRTOS
genlayer.yml: - component: ARM::CMSIS:RTOS2:FreeRTOS&Cortex-M@10.4.6
However if both definitions do not resolve to the very same component, an error is issued.
@brondani If we are all OK, I will add above information to the manual.
@ReinhardKeil Currently multiple component definitions for the same context are not allowed, regardless of being in cproject.yml
or clayer.yml
files. Multiple definitions are a symptom of a wrong structure, in my opinion the user should review and fix (error
severity).
@brondani thanks for reviewing. I have changed wording in the text above from warning to error.
For the genlayer.yml, this should be reviewed tomorrow.
Thanks all for the clarifications.
To me, maybe the spec can be updated to:
Point (1) is clearly in the scope of the Open-CMSIS-Pack spec. For point (2), should it be specified in the pack spec too, or the YML format spec ?
The split between the 2 specs is unclear to me. Initially, I believed that:
But probably it is more:
What do you think ?
From my point of view, this issue is incorporated in the documentation: https://github.com/Open-CMSIS-Pack/devtools/blob/main/tools/projmgr/docs/Manual/YML-Input-Format.md#component-name-conventions
csolution is just one way to implement a "project management with packs". I therefore do not suggest to start another standardization effort with it. csolution will be used in our VS Code implementation and on KSC.
I will close this issue next week, provided not other feedback is given.
Closing as no further feedback
Dear all,
I am sorry to probably reopen a very old and complex discussion...but I am unsure about my understanding of components.
The spec says:
I understand that to clearly "identify" without any doubt a component we need Cclass/Cgroup/Csub/Cversion.
Implicitly, I guess the vendor is also part of this identification becasue a bit further in the spec, it is written:
All this comes from this section: https://open-cmsis-pack.github.io/Open-CMSIS-Pack-Spec/main/html/cp_PackTutorial.html#cp_PackSteps
It is also explained here:
But, as pointed out in ticket #156, the variant brings some confusion.
In fact, I'd like to take the case of a .gpdsc (even if it will be replaced, the concept will remain I guess).
Say that in my project I selected ST::Device:Driver:UART&debug_variant@1.0.0
Then, I run a generator and a .gpdsc comes into picture.
What if:
this gpdsc defines ST::Device:Driver:UART&debug_variant@1.0.0 ==> this is easy, we replace the initial component as it is clearly the same one. But I did not see it written in the spec: one may think we should merge the 2 definitions...and what does merging mean then?
this gpdsc defines ST::Device:Driver:UART&release_variant@1.0.0 ==> as the variant is optional in the component id, shall we assume it is the same component ? Do we replace it ? Or do we reject the gpdsc component and stick to the initial component because it is a different variant ?
this gpdsc defines ST::Device:Driver:UART@1.0.0 ==> this is sufficient according to the spec to have an identity. Shall we replace the initial component ? With its default variant ?
this gpdsc defines ST::Device:Driver:UART&debug_variant@1.1.0 ==> the version is part of the identity. Shall we conclude it is a different component and insert it in addition to the version 1.0.0 ? I do think this is not what is intended here. But, if I follow the spec that's not the same component...so what to do ?
4a => reject it because we want the exact same version to have the same component as pdsc 4b => replace the initial component because the version is greater 4c => add it in addition to version 1.0.0 because it is not the same identity...
To me, it is unclear how the gpdsc shall be managed with regards to this. I assume that:
So, I guess that the rule is : only one same "base component" in a project. Then we need rules when a conflict occur:
I think we are missing some rules to manage all the cases I have listed. And, to me, the root cause of this confusion is the question : "what is a component ?" What makes several "flavors" of a component exclusive ?
I think we cannot let it down to the UI to solve it by restricting the choices.