msbuild
msbuild copied to clipboard
dotnet publish uses debug configuration even if publishprofile has config=release
Issue Description
When publishing a project that has a publsh profile using Release, the program is being compiled in debug mode.
Steps to Reproduce
I have a project that has this publish profile:
<Project>
<PropertyGroup>
<Configuration>Release</Configuration>
<Platform>Any CPU</Platform>
<PublishDir>bin\Publish</PublishDir>
<PublishProtocol>FileSystem</PublishProtocol>
<_TargetId>Folder</_TargetId>
<TargetFramework>net6.0-windows</TargetFramework>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<SelfContained>false</SelfContained>
<PublishSingleFile>true</PublishSingleFile>
<PublishReadyToRun>false</PublishReadyToRun>
</PropertyGroup>
</Project>
And I publish the project using command line:
dotnet publish -p:PublishProfile=FolderProfile project.csproj
I assumed that, because the publish profile has RELEASE configuration, it's the configuration used for building the project.
but I have this code:
#if DEBUG
Console.WriteLine("Running in DEBUG");
#endif
Which is, unexpectedly, executed when I run the program.
If I publish the project using this command line:
dotnet publish -p:PublishProfile=FolderProfile -c:Release project.csproj
Everything is fine.
So, what I don't understand is why, if the publish profile already has a Release configuration, why it's also needed by the command line.
Expected Behavior
Having Release configuration in the publish profile should be enough for dotnet to run a Release build.
Actual Behavior
If the command line does not have '-c:Release' even if publish profile already has it, the program is built using Debug mode.
Versions & Configurations
SBuild version 17.3.1+2badb37d1 for .NET Framework 17.3.1.41501
dotnet --info .NET SDK (reflecting any global.json): Version: 6.0.401 Commit: 0906eae6f8
@nagilson can you take a look at this publish profile issue?
Definitely, I'll take a look into why this is happening.
Configuration is being set to Release by the Publish Profile but this looks like the same nonsense as the PublishRelease fiasco where it doesn't get imported early enough, so DebugSymbols and OutputPath, etc, are set to the wrong value.
@rainersigwald It's likely we could solve it in a similar way to how PublishRelease works, though that'd only take effect in the CLI and be kinda gross. An alternative is if we can make publish profiles basically the first or close to first thing that gets done in evaluation, which may have an impact on design time builds or something akin to that. We should discuss this further.
@rainersigwald @nagilson
Question:
With dot net 8, I am seeing the opposite behavior - if I do not specify the configuration as Debug with the CLI and have Debug set as the configuration in the publish profile, the project gets published in Release build.
Correct me if I am wrong, but this is the same bug, albeit different outcome because of the changes to publishing with dot net 8?
Yeah, this is the same bug, but now the default is Release so it becomes Release :)
I'm encountering a similar issue, but it's doesn't matter whether I'm using a publishing profile.
One of my projects (ControlR.Streamer) will build/publish all the referenced projects in Debug, even when using Release configuration. ControlR.Streamer itself will build/publish in Release, though.
But if I publish another project (ControlR.Agent) that references the same shared projects, they get built correctly in Release.
Maybe there's an incorrect configuration somewhere, but I'm just not seeing it. Any ideas?
(Source can be found here on experimental branch: https://github.com/bitbound/ControlR/tree/experimental)
IMO this is a duplicate of https://github.com/dotnet/sdk/issues/16792#issuecomment-1381937248 over at the SDK. Publish Profiles are not fully supported by the CLI in the same way they are inside VS, and at some point we should bring the CLI into alignment so users that use Publish Profiles have a bit more consistency.
IMO this is a duplicate of dotnet/sdk#16792 (comment) over at the SDK. Publish Profiles are not fully supported by the CLI in the same way they are inside VS, and at some point we should bring the CLI into alignment so users that use Publish Profiles have a bit more consistency.
But in my example above, I'm not using a publishing profile.
I was also able to repro this a couple times on brand new projects created with dotnet new console and dotnet new classlib, but it was inconsistent. I couldn't figure out what conditions suddenly caused it to happen, or why it would suddenly start working correctly again.
@bitbound in your case I believe it's because the sln in the ControlR.Streamer directory doesn't contain all of the projects that ControlR.Streamer depends on. When you build a solution, the solution's 'default configuration' defaults determine which Configuration each project builds with, and when you have projects missing from a Solution but referenced from a project in that solution they get the 'default' from that Solution, which in this case seems to be Debug.
I don't recommend having small solutions like this - consider a solution filter just for the Streamer project, or removing the solution at that project entirely. When I deleted the solution for Streamer only, a publish did build all referenced projects in the Release configuration as I expected.
The takeaway here is that solution files are not representative of how you think your projects build, one more reason why I don't care for them much :D
@baronfel
Hah! I figured I was just missing something. :) That solution file wasn't supposed to be there. It was a copy/paste mistake.
Thanks for your loaning me your eyes, good sir!
What I did here was to add -bl to the publish command, so I could get a binlog, and then loaded the binlog into the binlog viewer. That let me drill down into how the Streamer project was asking for the other projects to be built, and when I saw the sln appear I knew that was the core problem.
I'd highly recommend taking a look at binlogs, they're super handy for this kind of investigation!
TIL! Thanks for the tip! That will definitely be useful in the future.
When you build a solution, the solution's 'default configuration' defaults determine which Configuration each project builds with, and when you have projects missing from a Solution but referenced from a project in that solution they get the 'default' from that Solution, which in this case seems to be Debug.
Nit: when a project goes outside the solution, you get (by default, there's $(ShouldUnsetParentConfigurationAndPlatform)) the referenced project's default configuration, which is almost always Debug.