-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Publish to Single-File #3132
Publish to Single-File #3132
Conversation
@nguerrera @fadimounir @sbomer please review. |
@dotnet-bot test this please |
d84a6a1
to
3bd01b7
Compare
@@ -85,6 +86,9 @@ Copyright (c) .NET Foundation. All rights reserved. | |||
--> | |||
<Target Name="PrepareForPublish"> | |||
|
|||
<NETSdkError Condition="'$(_IsExecutable)' != 'true'" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be checking PublishSingleFile
as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh you already fixed it. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @sbomer; as you know, I saw the feedback over your shoulder :)
<comment>{StrBegin="NETSDK1098: "}</comment> | ||
</data> | ||
<data name="CannotHaveSingleFileWithoutExecutable" xml:space="preserve"> | ||
<value>NETSDK1099: Publishing to a single-file is currently only supported for executable applications.</value> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
currently [](start = 54, length = 9)
I feel we should remove "currently". If we support this in the future, we can delete this error message
<PropertyGroup> | ||
<!-- Handle the case where IncludeSymbolsInSingleFile may not be defined --> | ||
<EmbedPDBs Condition="'$(IncludeSymbolsInSingleFile)' == 'true'">true</EmbedPDBs> | ||
<EmbedPDBs Condition="'$(IncludeSymbolsInSingleFile)' != 'true'">false</EmbedPDBs> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should also handle the .pdb/.map files created by crossgen here. We can do this later (I want to make some changes to the R2R related stuff first). Please file an issue to track this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change implements support for publishing apps to a [single file](https://github.com/dotnet/designs/blob/master/accepted/single-file/design.md). * ``dotnet publish /p:PublishSingleFile=true`` causes the contents of the "original" publish directory to a single file in the actual publish directory * Files marked with the meta-data ``<ExcludeFromSingleFile>false<ExcludeFromSingleFile>`` are left in the publish directory unbundled. This includes PDB files by default * PDB files can be bundled into the single file by setting ``/p:IncludeSymbolsInSingleFile=true`` Publishing to a single file requires publishing wrt a RID using an apphost, because the generated file is the platform-specific AppHost executable with embedded dependencies.
The property to trigger R2R compilation was changed from "Ready2Run" to "PublishReadyToRun". Update this in a test case.
ff8ef28
to
1cc9352
Compare
In this change 1cc9352 @fadimounir I updated a test case to use the new name |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good overall. Some minor feedback.
foreach(var item in FilesToBundle) | ||
{ | ||
fileSpec.Add(new FileSpec(sourcePath: item.ItemSpec, | ||
bundleRelativePath: item.GetMetadata("RelativePath"))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bundleRelativePath: item.GetMetadata("RelativePath"))); | |
bundleRelativePath: item.GetMetadata(MetadataKeys.RelativePath))); |
Not sure if I got that exactly right, but there's a class with constants for metadata. Use that.
Bundler bundler = new Bundler(AppHostName, OutputDir, EmbedPDBs, ShowDisgnosticOutput); | ||
var fileSpec = new List<FileSpec>(FilesToBundle.Length); | ||
|
||
foreach(var item in FilesToBundle) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
foreach(var item in FilesToBundle) | |
foreach (var item in FilesToBundle) |
nit: spacing
============================================================ | ||
--> | ||
<Target Name="_CopyResolvedFilesToPublishPreserveNewest" | ||
DependsOnTargets="_ComputeResolvedFilesToPublishTypes" | ||
Inputs="@(_ResolvedFileToPublishPreserveNewest)" | ||
Outputs="@(_ResolvedFileToPublishPreserveNewest->'$(PublishDir)%(RelativePath)')"> | ||
|
||
<ItemGroup> | ||
<_ResolvedUnBundledFileToPublishPreserveNewest |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
<_ResolvedUnBundledFileToPublishPreserveNewest | |
<_ResolvedUnbundledFileToPublishPreserveNewest |
nit on casing. Un is not a word on its own.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Obviously, rename all references to it too.)
<PropertyGroup> | ||
<!-- Handle the case where IncludeSymbolsInSingleFile may not be defined --> | ||
<EmbedPDBs Condition="'$(IncludeSymbolsInSingleFile)' == 'true'">true</EmbedPDBs> | ||
<EmbedPDBs Condition="'$(IncludeSymbolsInSingleFile)' != 'true'">false</EmbedPDBs> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
EmbedPDBs is a pretty generic name since there is also a concept of embeddign PDB in dll (DebugType=Embedded). You can avoid having a new name, by defaulting IncludeSymbolsInSingleFile to false when empty. This is very idiomatic in msbuild, you will see it all over the place.
<PropertyGroup>
<IncludeSymbolsInSingleFile Condition="'$(IncludeSymbolsInSingleFile)' == ''">false</IncludeSymbolsInSingleFile>
</PropertyGroup>
I don't even think you need the comment if you do that, it is pretty obvious what this handles.
Then pass EmbedPdbs="$(IncludeSymbolsInSingleFile)
[Required] | ||
public string AppHostName { get; set; } | ||
[Required] | ||
public bool EmbedPDBs { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
public bool EmbedPDBs { get; set; } | |
public bool IncludeSymbols { get; set; } |
I think it is worth using the same terminology throughout, and the public facing name is symbols for this feature.
|
||
protected override void ExecuteCore() | ||
{ | ||
Bundler bundler = new Bundler(AppHostName, OutputDir, EmbedPDBs, ShowDisgnosticOutput); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bundler bundler = new Bundler(AppHostName, OutputDir, EmbedPDBs, ShowDisgnosticOutput); | |
var bundler = new Bundler(AppHostName, OutputDir, EmbedPDBs, ShowDisgnosticOutput); |
nit: type is obvious
Condition="'$(PublishSingleFile)' == 'true'" | ||
DependsOnTargets="_ComputeFilesToBundle" | ||
Inputs="@(_FilesToBundle)" | ||
Outputs="$(PublishDir)\$(AssemblyName)$(_NativeExecutableExtension)"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Outputs="$(PublishDir)\$(AssemblyName)$(_NativeExecutableExtension)"> | |
Outputs="$(PublishDir)$(AssemblyName)$(_NativeExecutableExtension)"> |
We ensure trailing slash and you can see this is how PublishDir is used elsewhere. This is another common idiom in msbuild, it prevents accidental writing to root of disk if something is undefined. I once deleted my entire hard drive this way so I stick to this now :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Funny story, a similar issue caused CoreFx build perf to tank once, the cause $(SomeProperty)\**\*.extension
. Someone renamed SomeProperty
and CI passed...
@nguerrera: I've made the corrections you suggested in this commit: 9246cad |
var bundler = new Bundler(AppHostName, OutputDir, IncludeSymbols, ShowDisgnosticOutput); | ||
var fileSpec = new List<FileSpec>(FilesToBundle.Length); | ||
|
||
Array.ForEach(FilesToBundle, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did you change this to Array.ForEach? I liked the foreach loop better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK @nguerrera, I pushed 25c2b42 which revers back to the foreach() loop.
[Required] | ||
public bool ShowDisgnosticOutput { get; set; } | ||
|
||
protected override void ExecuteCore() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I love how delightfully simple this task ended up being. :)
[Required] | ||
public string OutputDir { get; set; } | ||
[Required] | ||
public bool ShowDisgnosticOutput { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
public bool ShowDisgnosticOutput { get; set; } | |
public bool ShowDiagnosticOutput { get; set; } |
Just spotted a typo
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, fixed it in 671de2d
77e4d36
to
671de2d
Compare
@dotnet-bot test dotnet-sdk-public-ci |
671de2d
to
4bb3c69
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice!
…build 20191007.2 (dotnet#3132) - Microsoft.NET.Sdk.Razor - 3.0.1-servicing.19507.2
This change implements support for publishing apps to a single file.
dotnet publish /p:PublishSingleFile=true
causes the contents of the "original" publish directory to a single file in the actual publish directory<ExcludeFromSingleFile>false<ExcludeFromSingleFile>
are left in the publish directory unbundled. This includes PDB files by default/p:IncludeSymbolsInSingleFile=true
Publishing to a single file requires publishing wrt a RID using an apphost, because the generated file is the platform-specific AppHost executable with embedded dependencies.