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

Better support for non-standard $(Configuration) names #31918

Open
jonathanpeppers opened this issue Apr 20, 2023 · 9 comments
Open

Better support for non-standard $(Configuration) names #31918

jonathanpeppers opened this issue Apr 20, 2023 · 9 comments
Assignees
Labels
Area-NetSDK untriaged Request triage from a team member

Comments

@jonathanpeppers
Copy link
Member

jonathanpeppers commented Apr 20, 2023

Is your feature request related to a problem? Please describe.

.NET MAUI customers commonly create customer project configuration names, such as ReleaseProd, AdHoc, AppStore, etc.

Visual Studio gives a handy UI for creating configurations and setting properties based on them, and so customers use this to toggle values in their applications such as:

  • Service endpoint URLs: is it Dev or Prod? Using $(DefineConstants) and #if together.
  • iOS signing settings: is it a Release build for the App Store or Development/beta testing

The problem becomes once a custom configuration is made, customers have to somehow know lots of MSBuild properties to set. Starting with:

<!-- User-facing configuration-specific defaults -->
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<DebugSymbols Condition=" '$(DebugSymbols)' == '' ">true</DebugSymbols>
<Optimize Condition=" '$(Optimize)' == '' ">false</Optimize>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<Optimize Condition=" '$(Optimize)' == '' ">true</Optimize>
</PropertyGroup>

At minimum, they would need to know to set $(DebugSymbol) and $(Optimize) appropriately.

Then for mobile, they would also need:

  • For Debug scenarios
    • $(UseInterpreter) set to true for Hot Reload
    • $(EmbedAssembliesIntoApk) set to false for Android "fast deployment" / sideloading
  • For Release scenarios on Android
    • $(PublishTrimmed)
    • $(RunAOTCompilation)
    • $(AndroidPackageFormat) set to aab to create Android "app bundles" for Google Play instead of an .apk
  • The settings required on iOS further complicates things
    • Debug builds need $(PublishTrimmed)
    • Trimmer settings like $(DebuggerSupport) are off for Release mode

There may be several more iOS properties I've left out here.

Describe the solution you'd like

A simple approach would be introduction of new properties like $(IsDebug) and $(IsRelease) where the new code would instead do:

 <PropertyGroup Condition=" '$(Configuration)' == 'Debug' "> 
   <IsDebug Condition=" '$(IsDebug)' == '' ">true</IsDebug> 
 </PropertyGroup> 
  <PropertyGroup Condition=" '$(Configuration)' == 'Release' "> 
   <IsRelease Condition=" '$(IsRelease)' == '' ">true</IsRelease> 
 </PropertyGroup> 
 <PropertyGroup Condition=" '$(IsDebug)' == 'true' "> 
   <DebugSymbols Condition=" '$(DebugSymbols)' == '' ">true</DebugSymbols> 
   <Optimize Condition=" '$(Optimize)' == '' ">false</Optimize> 
 </PropertyGroup> 
 <PropertyGroup Condition=" '$(IsRelease)' == 'true' "> 
   <Optimize Condition=" '$(Optimize)' == '' ">true</Optimize> 
 </PropertyGroup> 

Customer projects would do:

<PropertyGroup Condition=" '$(Configuration)' == 'DebugFoo' ">
  <IsDebug>true</IsDebug>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'ReleaseFoo' ">
  <IsRelease>true</IsRelease>
</PropertyGroup>

And then any defaults defined in optional workloads, etc. are based on these new properties instead of the configuration name directly.

An alternative would be some new MSBuild feature to "inherit" or "extend" configurations. That may just be too much for solving this problem.

Links

@dotnet-issue-labeler dotnet-issue-labeler bot added Area-NetSDK untriaged Request triage from a team member labels Apr 20, 2023
@jonathanpeppers
Copy link
Member Author

@rolfbjarne is there anything you'd like to add here?

@rolfbjarne
Copy link
Member

We've documented the properties for iOS that depend on the configuration here: https://github.com/xamarin/xamarin-macios/blob/main/docs/configuration-properties.md

One point is what's the difference beteween "release" and "publish": would "dotnet build /p:Configuration=Release" be the same as "dotnet publish"? Or would we need a third option (say IsPublish) as well?

Otherwise I agree with everything in the description :)

@jonathanpeppers
Copy link
Member Author

jonathanpeppers commented Apr 21, 2023

There is a new $(PublishRelease) that will default to true in .NET 8:

https://learn.microsoft.com/dotnet/core/project-sdk/msbuild-props#publishrelease

So anything changed here, should keep this property in mind.

@rolfbjarne
Copy link
Member

Another idea could be to let the user tell us their intentions.

So we could have a BuildIntention property with a set of known values (say Debug, Release, Profile, etc.)

And maybe a PublishIntention property as well (with values such as AppStore, AdHoc, WebSite - each SDK would support a certain set of of intentions, and also define the meaning of each).

By default we'd do something like:

<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
    <BuildIntention Condition=" '$(BuildIntention)' == '' ">Debug</BuildIntention>
</PropertyGroup>
<PropertyGroup Condition=" '$(BuildIntention)' == 'Debug' "> 
    <DebugSymbols Condition=" '$(DebugSymbols)' == '' ">true</DebugSymbols> 
    <Optimize Condition=" '$(Optimize)' == '' ">false</Optimize> 
</PropertyGroup> 

@grendello
Copy link

@rolfbjarne I like your idea, but I would stay with just a single property, say BuildProfile (instead of BuildIntention - I think "profile" expresses the goal better in this case), with the semantics of your BuildIntention. PublishIntention is, IMO, unnecessary since publishing involves building at some point. A single variable with a restricted (but open for future additions) set of values would be easier to document, create less information overload.

@rolfbjarne
Copy link
Member

PublishIntention is, IMO, unnecessary since publishing involves building at some point.

This is intented to solve the following problem: for macOS (and Mac Catalyst), publishing to the App Store involves using a signing configuration that produces an app that won't run locally, and publishing outside of the App Store involves a signing configuration that produces an app that can't be published to the App Store. People get this wrong all the time (Apple didn't make signing particularly easy to be honest), but if we knew the developer's intentions, we could create better defaults, and show warnings/errors if the developer does something we know won't work. Right now our defaults are wrong half the time...

@mtanml
Copy link

mtanml commented May 2, 2024

Any updates on this? We have a MAUI project with 14 debug profiles and 14 release profiles to build all of our apps. Among other issues, hot reload isn't working. Thanks

@phillippschmedt
Copy link

@mtanml We have a similar scope on our configurations and also struggle with the hot reload bit the most. We tried to manually set all the android/ios defaults for our debug/release equivalent but it will still not work.

@jonathanpeppers
Copy link
Member Author

We have a MAUI project with 14 debug profiles and 14 release profiles

So, I would assume you have various MSBuild logic that has conditions on $(Configuration). A workaround for now would be to use a different property for now like $(Brand) and set it to your custom values like Nike and Adidas, for example. Then just use Debug and Release for $(Configuration), as it seems like the only sane approach. To toggle the $(Brand) value, you could set it your .csproj, Directory.Build.props, custom MSBuild file, etc.

However, I'm with you; it would be nice if the .NET SDK had support for this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-NetSDK untriaged Request triage from a team member
Projects
None yet
Development

No branches or pull requests

6 participants