Skip to content
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

Discussion: Custom Solution/Project Config Mapping #447

Open
michael-hawker opened this issue Feb 1, 2023 · 6 comments
Open

Discussion: Custom Solution/Project Config Mapping #447

michael-hawker opened this issue Feb 1, 2023 · 6 comments

Comments

@michael-hawker
Copy link
Contributor

michael-hawker commented Feb 1, 2023

Related to #437

Originally posted by @michael-hawker in #446 (comment)

@jeffkl I can type anything in the Platform dialog:

image

I was also, previously to this commit, trying to pass ARM64 in:

dotnet slngen --platform "Any CPU;x64;x86;ARM64"

But that gets stripped by the null.

If there are custom tooling/msbuild sdks, etc... that may be used by a project, they may care about non-standard platforms, like the Uno Platform iOS ones:

image

Originally posted by @jeffkl in #446 (comment)

@michael-hawker this is extremely complicated from the command-line. Visual Studio has two concepts: Solution configuration and Project configuration. The hard part is mapping project configurations to solution configurations. When you use the UI, you get a nice grid and can create a solution platform and map it to the appropriate project platform. In some cases you'll want to create a solution configuration like "Custom Thing" but when you build it you want to map that to "x86" for the project.

Since SlnGen is a command-line tool, I haven't found a good way for a user to convey these mappings. At the moment, there are some built-in mappings for C++ projects, when you select a solution platform of Any CPU, it will build x86 or amd64 if the project supports one of those.

What works best is for the projects to convey what they support which is how SlnGen dynamically discovers configurations and platforms. If an SDK-style CSPROJ has:

<PropertyGroup>
  <Platforms>AnyCPU;x86;x64</Platforms>
</PropertyGroup>

Then SlnGen will generate a solution with the correct solution platforms and map it to the project platforms. What's missing is any way to convey a mapping. I'm not sure if its worth it at the moment but we could look into something like:

<ItemGroup>
  <SlnGenSolutionPlatform Condition="'$(Platform)' == 'x64'">MyCustomPlatform</SlnGenSolutionPlatform>
</ItemGroup>

But I'm not sure how many people need this functionality. In the 5 years that I've worked on SlnGen, no one has asked for custom mappings like this...

@michael-hawker
Copy link
Contributor Author

@jeffkl figured I'd start a new issue to continue the discussion.

Not sure if we need this either, but just know it's something I'm seeing with our Uno Platform project configurations, but we're not really focused on trying to build for other platforms like iOS and Android at the moment, so not sure if it's a problem for us.

Maybe this is something @jeromelaban from Uno can comment on a bit more about how this works in their system.

I do think the properties for msbuild would be the way to go, but probably not a huge priority at the moment.

@hknielsen
Copy link

I have a similar issue.
It seem that if it does not match on the Configuration passed, it will just grab the first config the Project have defined;
https://github.com/microsoft/slngen/blob/main/src/Microsoft.VisualStudio.SlnGen/SlnFile.cs#L658

It would be great if we can define what Configuration to choose for this project in the matrix, based on the SolutionConfiguration. Ie. Conditinally, similar to @michael-hawker SlnGenSolutionPlatform:

<SlnGenSolutionConfiguration Condition='$(Configuration) == Debug'>Foo</...

@hknielsen
Copy link

hknielsen commented Nov 6, 2023

We are also looking at using SlnGen for generating our solutions, but will be blocked until we have something to handle these cases.

If we can agree on some solution im willing to make a prototype to battle test it, we have some pretty convoluted Configurations.

cc @jeffkl for input as well.

Also wonder how the Visual Studio team are going to solve this issue for something similar to Traversal projects instead of Solutions;
https://developercommunity.visualstudio.com/t/Clean-up-sln-VisualStudio-solution-fil/988209#T-N10433845

@jeffkl
Copy link
Collaborator

jeffkl commented Nov 6, 2023

I'd be fine with custom mappings of solution platforms to project platforms. The built-in mappings are determined here: https://github.com/microsoft/slngen/blob/main/src/Microsoft.VisualStudio.SlnGen/SlnFile.cs#L663-L803

At the moment only certain platforms are recognized: https://github.com/microsoft/slngen/blob/main/src/Microsoft.VisualStudio.SlnGen/SlnFile.cs#L621-L644

So maybe users need to be able to define what they consider "valid" platforms? Technically SlnGen could just treat all values it finds as valid but it would need checks later on that every single project had a correct mapping. For example:

Project Platforms
ProjectA Any CPU
ProjectB iPhone
ProjectC x64
ProjectC x86

How would you specify that when building the solution platform Any CPU, that ProjectB should build iPhone and visa versa?

The built-in mappings make sense because if a project only defines Any CPU but the solution platform is x86, then Any CPU is built.

I think we'd need an MSBuild item to indicate that if the solution platform is a particular value but the project does not support it, which platform to build.

<ItemGroup>
  <SolutionPlatform Include="Any CPU" Platforms="x64;x86;iPhone" />
  <SolutionPlatform Include="x64" Platforms="Any CPU;x86;iPhone" />
  <SolutionPlatform Include="x86" Platforms="Any CPU;x64iPhone" />
  <SolutionPlatform Include="iPhone" Platforms="Any CPU;x64;x86" />
</ItemGroup>

These items redefine the current mappings and indicate that if a solution platform is iPhone and the project does not have that platform, to fall back to Any CPU if found, otherwise try x64, and finally x86. I think if a mapping isn't found, a error or warning should be emitted indicating that the user hasn't properly defined mappings and projects won't be built.

The items could also just be additive, preserving existing mappings:

<ItemGroup>
  <SolutionPlatform Include="Any CPU" AdditionalPlatforms="iPhone" />
  <SolutionPlatform Include="x64" AdditionalPlatforms="iPhone" />
  <SolutionPlatform Include="x86" AdditionalPlatforms="iPhone" />
  <SolutionPlatform Include="iPhone" AdditionalPlatforms="Any CPU;x64;x86" />
</ItemGroup>

This means for any give solution platform, use the value for AdditionalPlatforms as a fallback mapping for project platform.

@hknielsen
Copy link

hknielsen commented Nov 6, 2023

I like the idea of using Items to map between the different platforms. We need the same setup for configurations, and it makes sense to combine them, as Solution Config|Platform can change the Project's Configuration+Platform.
So maybe keeping the same logic as you describe @jeffkl , but using the combination as VS also does;

<ItemGroup>
  <SolutionConfiguration Include="Debug|Any CPU" ConfigurationPlatform="Debug+x64;Debug|x86;Debug|iPhone" />
  <SolutionConfiguration Include="Debug|x64" ConfigurationPlatform="Debug|Any CPU;Debug|x86;Debug|iPhone" />
  ...
</ItemGroup>

Then we get the full matrix defined on the choosen Solution Configuration.
I would ideally split up the Configuration and Platform instead of this magic +, and then the Result. Any ideas, or does that fit?

@hknielsen
Copy link

Another thing we also need to remember supporting are Build Deploy configuration settings, im wondering how we can get those playing nicely together, or if we should add an item for each, ie;

  • SolutionConfiguration
  • SolutionPlatform
  • SolutionBuild
  • SolutionDeploy

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants