-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Support setting a root output path for all projects in a repo or solution with a single property #3497
Comments
Straw man:
|
I found that I also need to default the Directory.Build.props <Project>
<PropertyGroup>
<Configuration Condition="$(Configuration) == ''">Debug</Configuration>
<RepoRoot>$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)\..\..\'))</RepoRoot>
<BaseOutputPath>$(RepoRoot)bin\$(Configuration)\$(MSBuildProjectName)\</BaseOutputPath>
<BaseIntermediateOutputPath>$(RepoRoot)obj\$(Configuration)\$(MSBuildProjectName)\</BaseIntermediateOutputPath>
</PropertyGroup>
</Project> ConsoleApp1.csproj: <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net46</TargetFramework>
<OutputType>Exe</OutputType>
<OutDir>$(RepoRoot)bin\$(Configuration)</OutDir>
</PropertyGroup>
</Project> |
Never mind, |
Updated straw man:
This swaps the position of Platform and Configuration, to match what the current logic in MSBuild and the .NET SDK use. |
I think the following are the files where changes need to be made to support this:
We might also be able to unify some of the logic between Microsoft.Common.CurrentVersion.targets and Microsoft.NET.DefaultOutputPaths.targets, but that may be more complex / risky than would be worth it.
We should either update this warning to also cover |
This is what I came up with a while back: |
@dsplaisted I'm not a fan of deep folder hierarchy. Can't we take all the variables that identifies as a build parameter and put them into single property and use that property in the path. That way we can reuse that property later on and also have an identifier that effectively identifies a build config. What I did before:In the <!--
We need to initialize `BuildFolder` separately and before the `MSBuild.OutputPaths.targets` import,
since `MSBuildProjectExtensionsPath` uses it to import custom props from Package Managers and Tools.
-->
<PropertyGroup Label="Build">
<BuildFolder Condition="'$(BuildFolder)' == ''">build</BuildFolder>
<BuildPath Condition="'$(BuildPath)' == ''">$(BuildFolder)\</BuildPath>
<BuildPath Condition="!HasTrailingSlash('$(BuildPath)')">$(BuildPath)\</BuildPath>
<BuildPath Condition="$([System.IO.Path]::IsPathRooted('$(BuildPath)')) AND !$(BuildPath.StartsWith('$(MSBuildProjectDirectory)'))">$(BuildPath)$(BuildFolder)\$(MSBuildProjectName)\</BuildPath>
<_InitialBuildPath>$(BuildPath)</_InitialBuildPath>
</PropertyGroup> In the <PropertyGroup Label="Build">
<IntermediateOutputFolder Condition="'$(IntermediateOutputFolder)' == ''">obj</IntermediateOutputFolder>
<BaseIntermediateOutputPath>$(BuildPath)$(IntermediateOutputFolder)\</BaseIntermediateOutputPath>
<IntermediateOutputPath>$(BaseIntermediateOutputPath)</IntermediateOutputPath>
<OutputFolder Condition="'$(OutputFolder)' == ''">bin</OutputFolder>
<BaseOutputPath>$(BuildPath)$(OutputFolder)\</BaseOutputPath>
<OutputPath>$(BaseOutputPath)</OutputPath>
</PropertyGroup> And wherever we want to append a property that differentiates a build, we do this there... make sure that property won't change afterwards. For e.g.: <!-- Each property is appended where it's set after and won't change afterwards -->
<PropertyGroup Condition="'$(Configuration)' != ''">
<BuildContext Condition="!$(BuildContext.EndsWith('-'))">$(BuildContext)-</BuildContext>
<BuildContext>$(BuildContext)$(Configuration)</BuildContext>
</PropertyGroup>
<PropertyGroup Condition="'$(Platform)' != '' AND '$(Platform)' != 'AnyCPU'">
<BuildContext Condition="!$(BuildContext.EndsWith('-'))">$(BuildContext)-</BuildContext>
<BuildContext>$(BuildContext)$(Platform)</BuildContext>
</PropertyGroup> Then, we append the build identifier to the path at the very last in property evaluation or may be, if possible, first in one of the preparation targets... <!-- Place these at last in evaluation or first in targets -->
<PropertyGroup>
<BuildContext Condition="'$(BuildContext.Trim('-'))' != ''">$(BuildContext.Trim('-'))</BuildContext>
</PropertyGroup>
<PropertyGroup Condition="'$(BuildContext)' != ''">
<IntermediateOutputPath>$(IntermediateOutputPath)$(BuildContext)\</IntermediateOutputPath>
<OutputPath>$(OutputPath)$(BuildContext)\</OutputPath>
</PropertyGroup> That's how I'm currently using it. NoteI created it when the first .NET Sdk was released and have never changed the logic, even though v1->v2->v3 had some changes that broke many people's build. |
Here's my Gist that I use in both Sdk and Legacy projects: |
Any status on this? |
We'd like to do this in .NET 5, but we're not sure if we'll be able to or not yet. |
I most definitely vote yes on this feature. As I mentioned in #3483, some of these work-arounds mentioned might run into issues with WPF projects. |
Here's my take on this via SDK's side: Nirmal4G/dotnet-sdk@ab012dc
Thus, freeing up
|
@dsplaisted Can I give a gentle nudge on this for .NET 6? 😄 I run into this on every new project. |
A most simple workaround i was able to hack after reading all related info here, because other published examples messed up my builds for whatever reason. I'm using it for
<Project>
<PropertyGroup>
<PublishDir>$(SmartOutputPath)\$(MSBuildProjectName)</PublishDir>
</PropertyGroup>
</Project>
cp Directory.Build.props ./ # from whatever place you store ci-cd related files
dotnet publish src/Apps.sln -p:SmartOutputPath=$PWD/publish # abs paths only! Results:
|
I was wondering, isn’t this now covered by the dotnet 8 sdk? |
Yes, |
I see that in .net 8 artifacts are flattened by project, but not by structure if projects were placed in different subfolders. What happens if i have a solution with |
@Rast1234 This comment shows how you can preserve the project structure in the output path. It would be ideal if we could generate an error if there is a conflict, but since the projects are built separately I can't think of a good way that we would detect this. |
closing in favor of |
The |
Currently there are several different properties that control where project output goes. If you want all project output for a repo to go under a single folder, it is certainly possible to set this up, but it involves setting several properties, and knowing how to include
$(MSBuildProjectName)
as part of the path. For example, you can put the following in a Directory.Build.props file (assuming all your projects use Microsoft.NET.Sdk):We would like to add a single property (for example
RootOutputPath
) that handles this automatically.See also dotnet/sdk#867
The text was updated successfully, but these errors were encountered: