From 52fb016688b1ba71878dde90c9e246a8c8f20bf0 Mon Sep 17 00:00:00 2001 From: "Kevin Ransom (msft)" Date: Tue, 27 Sep 2016 09:42:23 -0700 Subject: [PATCH 01/14] Improve scope arrangement for portable pdbs --- src/FSharpSource.Settings.targets | 2 +- src/absil/ilwritepdb.fs | 168 ++++++++++++++++-------------- 2 files changed, 93 insertions(+), 77 deletions(-) diff --git a/src/FSharpSource.Settings.targets b/src/FSharpSource.Settings.targets index f9f6c3b8657..0507decd7c7 100644 --- a/src/FSharpSource.Settings.targets +++ b/src/FSharpSource.Settings.targets @@ -25,7 +25,7 @@ - full + portable portable false prompt diff --git a/src/absil/ilwritepdb.fs b/src/absil/ilwritepdb.fs index e25211b3cce..6de9b454890 100644 --- a/src/absil/ilwritepdb.fs +++ b/src/absil/ilwritepdb.fs @@ -284,107 +284,123 @@ let generatePortablePdb fixupSPs showTimes (info:PdbData) = match minfo.Range with | None -> Array.empty | Some (_,_) -> minfo.SequencePoints - - let getDocumentHandle d = - if docs.Length = 0 || d < 0 || d > docs.Length then + + let getDocumentHandle d = + if docs.Length = 0 || d < 0 || d > docs.Length then Unchecked.defaultof else match documentIndex.TryGetValue(docs.[d].File) with | false, _ -> Unchecked.defaultof | true, f -> f - // Return a document that the entire method body is declared within. - // If part of the method body is in another document returns nil handle. - let tryGetSingleDocumentIndex = - let mutable singleDocumentIndex = 0 - for i in 0 .. sps.Length - 1 do - let index = sps.[i].Document - if index <> singleDocumentIndex then - singleDocumentIndex <- index - singleDocumentIndex - - // Filter out feefee (Hidden) sequence points - let sps = sps |> Array.filter(fun sp -> sp.Line <> 0xfeefee && sp.EndLine <> 0xfeefee) - if sps.Length = 0 then Unchecked.defaultof, Unchecked.defaultof else - let mutable previousNonHiddenStartLine = -1 - let mutable previousNonHiddenStartColumn = -1 - let mutable previousDocumentIndex = -1 - let mutable singleDocumentIndex = tryGetSingleDocumentIndex - let mutable currentDocumentIndex = previousDocumentIndex + // Return a document that the entire method body is declared within. + // If part of the method body is in another document returns nil handle. + let tryGetSingleDocumentIndex = + let mutable singleDocumentIndex = sps.[0].Document + for i in 1 .. sps.Length - 1 do + if sps.[i].Document <> singleDocumentIndex then + singleDocumentIndex <- -1 + singleDocumentIndex let builder = new BlobBuilder() + builder.WriteCompressedInteger(minfo.LocalSignatureToken) - for i in 0 .. (sps.Length - 1) do - if previousDocumentIndex <> currentDocumentIndex then - // optional document in header or document record: - if previousDocumentIndex <> -1 then - // optional document in header or document record - builder.WriteCompressedInteger(0) - builder.WriteCompressedInteger(currentDocumentIndex) - previousDocumentIndex <- currentDocumentIndex - - // delta IL offset: - if i > 0 then - builder.WriteCompressedInteger(sps.[i].Offset - sps.[i - 1].Offset) - else - builder.WriteCompressedInteger(sps.[i].Offset) + // Initial document: When sp's spread over more than one document we put the initial document here. + let singleDocumentIndex = tryGetSingleDocumentIndex - let deltaLines = sps.[i].EndLine - sps.[i].Line - let deltaColumns = sps.[i].EndColumn - sps.[i].Column - builder.WriteCompressedInteger(deltaLines) + if singleDocumentIndex = -1 then + builder.WriteCompressedInteger( MetadataTokens.GetRowNumber(DocumentHandle.op_Implicit(getDocumentHandle (sps.[0].Document))) ) - if deltaLines = 0 then - builder.WriteCompressedInteger(deltaColumns) - else - builder.WriteCompressedSignedInteger(deltaColumns) + let mutable previousNonHiddenStartLine = -1 + let mutable previousNonHiddenStartColumn = 0 - // delta Start Lines & Columns: - if previousNonHiddenStartLine < 0 then - builder.WriteCompressedInteger(sps.[i].Line) - builder.WriteCompressedInteger(sps.[i].Column) - else - builder.WriteCompressedSignedInteger(sps.[i].Line - previousNonHiddenStartLine) - builder.WriteCompressedSignedInteger(sps.[i].Column - previousNonHiddenStartColumn) + for i in 0 .. (sps.Length - 1) do - previousNonHiddenStartLine <- sps.[i].Line - previousNonHiddenStartColumn <- sps.[i].Column + if singleDocumentIndex <> -1 && sps.[i].Document <> singleDocumentIndex then + builder.WriteCompressedInteger( 0 ) + builder.WriteCompressedInteger( MetadataTokens.GetRowNumber(DocumentHandle.op_Implicit(getDocumentHandle (sps.[i].Document))) ) + else + // Sequence-point-record + let offsetDelta = + if i > 0 then sps.[i].Offset - sps.[i - 1].Offset // delta from previous offset + else sps.[i].Offset // delta IL offset + + if i < 1 || offsetDelta <> 0 then // ILOffset must not be 0 + builder.WriteCompressedInteger(offsetDelta) + + if sps.[i].Line = 0xfeefee && sps.[i].EndLine = 0xfeefee then // Hidden-sequence-point-record + builder.WriteCompressedInteger(0) + builder.WriteCompressedInteger(0) + else // Non-hidden-sequence-point-record + let deltaLines = sps.[i].EndLine - sps.[i].Line // lines + builder.WriteCompressedInteger(deltaLines) + + let deltaColumns = sps.[i].EndColumn - sps.[i].Column // Columns + if deltaLines = 0 then + builder.WriteCompressedInteger(deltaColumns) + else + builder.WriteCompressedSignedInteger(deltaColumns) + + if previousNonHiddenStartLine < 0 then // delta Start Line & Column: + builder.WriteCompressedInteger(sps.[i].Line) + builder.WriteCompressedInteger(sps.[i].Column) + else + builder.WriteCompressedSignedInteger(sps.[i].Line - previousNonHiddenStartLine) + builder.WriteCompressedSignedInteger(sps.[i].Column - previousNonHiddenStartColumn) + + previousNonHiddenStartLine <- sps.[i].Line + previousNonHiddenStartColumn <- sps.[i].Column getDocumentHandle singleDocumentIndex, metadata.GetOrAddBlob(builder) + metadata.AddMethodDebugInformation(docHandle, sequencePointBlob) |> ignore + // Write the scopes let nextHandle handle = MetadataTokens.LocalVariableHandle(MetadataTokens.GetRowNumber(LocalVariableHandle.op_Implicit(handle)) + 1) - let rec writePdbScope scope = - if scope.Children.Length = 0 then - metadata.AddLocalScope(MetadataTokens.MethodDefinitionHandle(minfo.MethToken), - Unchecked.defaultof, - nextHandle lastLocalVariableHandle, - Unchecked.defaultof, - 0, - scope.EndOffset - scope.StartOffset) |>ignore - else - metadata.AddLocalScope(MetadataTokens.MethodDefinitionHandle(minfo.MethToken), - Unchecked.defaultof, - nextHandle lastLocalVariableHandle, - Unchecked.defaultof, - scope.StartOffset, - scope.EndOffset - scope.StartOffset) |>ignore - - for localVariable in scope.Locals do - lastLocalVariableHandle <- metadata.AddLocalVariable(LocalVariableAttributes.None, localVariable.Index, metadata.GetOrAddString(localVariable.Name)) - - scope.Children |> Array.iter (writePdbScope) - - writePdbScope minfo.RootScope - metadata.AddMethodDebugInformation(docHandle, sequencePointBlob) |> ignore) + let writePdbScope scope = + let scopeSorter (scope1:PdbMethodScope) (scope2:PdbMethodScope) = + if scope1.StartOffset > scope2.StartOffset then 1 + elif scope1.StartOffset < scope2.StartOffset then -1 + elif (scope1.EndOffset - scope1.StartOffset) > (scope2.EndOffset - scope2.StartOffset) then -1 + elif (scope1.EndOffset - scope1.StartOffset) < (scope2.EndOffset - scope2.StartOffset) then 1 + else 0 + + let collectScopes scope = + let list = new List() + let rec toList scope = + list.Add scope + scope.Children |> Seq.iter(fun s -> toList s) + toList scope + list.ToArray() + + collectScopes scope |> Array.sortWith scopeSorter + |> Seq.iter(fun s -> + if scope.Children.Length = 0 then + metadata.AddLocalScope(MetadataTokens.MethodDefinitionHandle(minfo.MethToken), + Unchecked.defaultof, + nextHandle lastLocalVariableHandle, + Unchecked.defaultof, + 0, s.EndOffset - s.StartOffset) |>ignore + else + metadata.AddLocalScope(MetadataTokens.MethodDefinitionHandle(minfo.MethToken), + Unchecked.defaultof, + nextHandle lastLocalVariableHandle, + Unchecked.defaultof, + s.StartOffset, s.EndOffset - s.StartOffset) |>ignore + + for localVariable in scope.Locals do + lastLocalVariableHandle <- metadata.AddLocalVariable(LocalVariableAttributes.None, localVariable.Index, metadata.GetOrAddString(localVariable.Name)) + ) + writePdbScope minfo.RootScope ) let entryPoint = - match info.EntryPoint with + match info.EntryPoint with | None -> MetadataTokens.MethodDefinitionHandle(0) - | Some x -> MetadataTokens.MethodDefinitionHandle(x) + | Some x -> MetadataTokens.MethodDefinitionHandle(x) let serializer = PortablePdbBuilder(metadata, externalRowCounts, entryPoint, null) let blobBuilder = new BlobBuilder() From 022f5de2a0cae8a02bc9c958d702504969a9719f Mon Sep 17 00:00:00 2001 From: "Kevin Ransom (msft)" Date: Fri, 30 Sep 2016 11:47:19 -0700 Subject: [PATCH 02/14] Git: 1) Enable implicit sequence points for portable pdbs 2) Minor rename and cleanup for portable pdb generation --- src/absil/il.fs | 18 ++++++++++-------- src/absil/il.fsi | 1 + src/absil/ilread.fs | 5 +++-- src/absil/ilwrite.fs | 15 ++++++++------- src/absil/ilwritepdb.fs | 17 ++++++++--------- src/fsharp/CompileOptions.fs | 7 ++----- src/fsharp/fsc.fs | 3 ++- 7 files changed, 34 insertions(+), 32 deletions(-) diff --git a/src/absil/il.fs b/src/absil/il.fs index 3d8f458ad8f..2eed6e672ad 100755 --- a/src/absil/il.fs +++ b/src/absil/il.fs @@ -1766,13 +1766,13 @@ type ILAssemblyManifest = AssemblyLongevity: ILAssemblyLongevity; DisableJitOptimizations: bool; JitTracking: bool; + IgnoreSymbolStoreSequencePoints: bool; Retargetable: bool; /// Records the types impemented by other modules. ExportedTypes: ILExportedTypesAndForwarders; /// Records whether the entrypoint resides in another module. EntrypointElsewhere: ILModuleRef option; - } type ILModuleDef = @@ -3196,9 +3196,10 @@ let mkILSimpleModule assname modname dll subsystemVersion useHighEntropyVA tdefs Locale=locale CustomAttrs=emptyILCustomAttrs; AssemblyLongevity=ILAssemblyLongevity.Unspecified; - DisableJitOptimizations= 0 <> (flags &&& 0x4000); - JitTracking=0 <> (flags &&& 0x8000); // always turn these on - Retargetable= 0 <> (flags &&& 0x100); + DisableJitOptimizations = 0 <> (flags &&& 0x4000); + JitTracking = (0 <> (flags &&& 0x8000)); // always turn these on + IgnoreSymbolStoreSequencePoints= (0 <> (flags &&& 0x2000)); + Retargetable = (0 <> (flags &&& 0x100)); ExportedTypes=exportedTypes; EntrypointElsewhere=None }; @@ -3681,13 +3682,14 @@ type ILGlobals with member this.mkDebuggableAttributeV2(jitTracking, ignoreSymbolStoreSequencePoints, jitOptimizerDisabled, enableEnC) = let tref = mkSystemDiagnosticsDebuggableTypeRef this + let debuggingMode = (if jitTracking then 1 else 0) ||| + (if jitOptimizerDisabled then 256 else 0) ||| + (if ignoreSymbolStoreSequencePoints then 2 else 0) ||| + (if enableEnC then 4 else 0) mkILCustomAttribute this (tref,[mkILNonGenericValueTy (tref_DebuggableAttribute_DebuggingModes this)], (* See System.Diagnostics.DebuggableAttribute.DebuggingModes *) - [ILAttribElem.Int32( (if jitTracking then 1 else 0) ||| - (if jitOptimizerDisabled then 256 else 0) ||| - (if ignoreSymbolStoreSequencePoints then 2 else 0) ||| - (if enableEnC then 4 else 0))],[]) + [ILAttribElem.Int32( debuggingMode )],[]) member this.mkCompilerGeneratedAttribute () = mkILCustomAttribute this (tref_CompilerGeneratedAttribute this, [], [], []) diff --git a/src/absil/il.fsi b/src/absil/il.fsi index 6afa9974997..43520c2af17 100644 --- a/src/absil/il.fsi +++ b/src/absil/il.fsi @@ -1428,6 +1428,7 @@ type ILAssemblyManifest = AssemblyLongevity: ILAssemblyLongevity; DisableJitOptimizations: bool; JitTracking: bool; + IgnoreSymbolStoreSequencePoints: bool; Retargetable: bool; /// Records the types impemented by this asssembly in auxiliary /// modules. diff --git a/src/absil/ilread.fs b/src/absil/ilread.fs index 2a856e622a9..0c0b543d834 100644 --- a/src/absil/ilread.fs +++ b/src/absil/ilread.fs @@ -1586,8 +1586,9 @@ and seekReadAssemblyManifest ctxt idx = EntrypointElsewhere=(if fst ctxt.entryPointToken = TableNames.File then Some (seekReadFile ctxt (snd ctxt.entryPointToken)) else None) Retargetable = 0 <> (flags &&& 0x100) DisableJitOptimizations = 0 <> (flags &&& 0x4000) - JitTracking = 0 <> (flags &&& 0x8000) } - + JitTracking = 0 <> (flags &&& 0x8000) + IgnoreSymbolStoreSequencePoints = 0 <> (flags &&& 0x2000) } + and seekReadAssemblyRef ctxt idx = ctxt.seekReadAssemblyRef idx and seekReadAssemblyRefUncached ctxtH idx = let ctxt = getHole ctxtH diff --git a/src/absil/ilwrite.fs b/src/absil/ilwrite.fs index 966de947a05..3beaf31e083 100644 --- a/src/absil/ilwrite.fs +++ b/src/absil/ilwrite.fs @@ -2862,17 +2862,18 @@ and GetManifsetAsAssemblyRow cenv m = UShort (match m.Version with None -> 0us | Some (_,_,_,w) -> w) ULong ( (match m.AssemblyLongevity with - | ILAssemblyLongevity.Unspecified -> 0x0000 - | ILAssemblyLongevity.Library -> 0x0002 + | ILAssemblyLongevity.Unspecified -> 0x0000 + | ILAssemblyLongevity.Library -> 0x0002 | ILAssemblyLongevity.PlatformAppDomain -> 0x0004 - | ILAssemblyLongevity.PlatformProcess -> 0x0006 - | ILAssemblyLongevity.PlatformSystem -> 0x0008) ||| + | ILAssemblyLongevity.PlatformProcess -> 0x0006 + | ILAssemblyLongevity.PlatformSystem -> 0x0008) ||| (if m.Retargetable then 0x100 else 0x0) ||| // Setting these causes peverify errors. Hence both ilread and ilwrite ignore them and refuse to set them. // Any debugging customattributes will automatically propagate - // REVIEW: No longer appears to be the case... - (if m.JitTracking then 0x8000 else 0x0) ||| - (if m.DisableJitOptimizations then 0x4000 else 0x0) ||| + // REVIEW: No longer appears to be the case + (if m.IgnoreSymbolStoreSequencePoints then 0x2000 else 0x0) ||| + (if m.DisableJitOptimizations then 0x4000 else 0x0) ||| + (if m.JitTracking then 0x8000 else 0x0) ||| (match m.PublicKey with None -> 0x0000 | Some _ -> 0x0001) ||| 0x0000) (match m.PublicKey with None -> Blob 0 | Some x -> Blob (GetBytesAsBlobIdx cenv x)) StringE (GetStringHeapIdx cenv m.Name) diff --git a/src/absil/ilwritepdb.fs b/src/absil/ilwritepdb.fs index 6de9b454890..87bf4fafb0f 100644 --- a/src/absil/ilwritepdb.fs +++ b/src/absil/ilwritepdb.fs @@ -275,7 +275,7 @@ let generatePortablePdb fixupSPs showTimes (info:PdbData) = let mutable lastLocalVariableHandle = Unchecked.defaultof metadata.SetCapacity(TableIndex.MethodDebugInformation, info.Methods.Length) - info.Methods |> Array.iteri (fun _i minfo -> + info.Methods |> Array.iter (fun minfo -> let docHandle, sequencePointBlob = let sps = match minfo.SequencePoints with @@ -361,7 +361,7 @@ let generatePortablePdb fixupSPs showTimes (info:PdbData) = // Write the scopes let nextHandle handle = MetadataTokens.LocalVariableHandle(MetadataTokens.GetRowNumber(LocalVariableHandle.op_Implicit(handle)) + 1) - let writePdbScope scope = + let writeMethodScope scope = let scopeSorter (scope1:PdbMethodScope) (scope2:PdbMethodScope) = if scope1.StartOffset > scope2.StartOffset then 1 elif scope1.StartOffset < scope2.StartOffset then -1 @@ -375,16 +375,15 @@ let generatePortablePdb fixupSPs showTimes (info:PdbData) = list.Add scope scope.Children |> Seq.iter(fun s -> toList s) toList scope - list.ToArray() + list.ToArray() |> Array.sortWith scopeSorter - collectScopes scope |> Array.sortWith scopeSorter - |> Seq.iter(fun s -> - if scope.Children.Length = 0 then + collectScopes scope |> Seq.iter(fun s -> + if s.Children.Length = 0 then metadata.AddLocalScope(MetadataTokens.MethodDefinitionHandle(minfo.MethToken), Unchecked.defaultof, nextHandle lastLocalVariableHandle, Unchecked.defaultof, - 0, s.EndOffset - s.StartOffset) |>ignore + 0, s.EndOffset - s.StartOffset ) |>ignore else metadata.AddLocalScope(MetadataTokens.MethodDefinitionHandle(minfo.MethToken), Unchecked.defaultof, @@ -392,10 +391,10 @@ let generatePortablePdb fixupSPs showTimes (info:PdbData) = Unchecked.defaultof, s.StartOffset, s.EndOffset - s.StartOffset) |>ignore - for localVariable in scope.Locals do + for localVariable in s.Locals do lastLocalVariableHandle <- metadata.AddLocalVariable(LocalVariableAttributes.None, localVariable.Index, metadata.GetOrAddString(localVariable.Name)) ) - writePdbScope minfo.RootScope ) + writeMethodScope minfo.RootScope ) let entryPoint = match info.EntryPoint with diff --git a/src/fsharp/CompileOptions.fs b/src/fsharp/CompileOptions.fs index ccf2c6e96e6..fb4ac15bcd8 100644 --- a/src/fsharp/CompileOptions.fs +++ b/src/fsharp/CompileOptions.fs @@ -407,7 +407,6 @@ let SetOptimizeOff(tcConfigB : TcConfigBuilder) = tcConfigB.optSettings <- { tcConfigB.optSettings with localOptUser = Some false } tcConfigB.optSettings <- { tcConfigB.optSettings with crossModuleOptUser = Some false } tcConfigB.optSettings <- { tcConfigB.optSettings with lambdaInlineThreshold = 0 } - tcConfigB.ignoreSymbolStoreSequencePoints <- false; tcConfigB.doDetuple <- false; tcConfigB.doTLR <- false; tcConfigB.doFinalSimplify <- false; @@ -417,8 +416,6 @@ let SetOptimizeOn(tcConfigB : TcConfigBuilder) = tcConfigB.optSettings <- { tcConfigB.optSettings with localOptUser = Some true } tcConfigB.optSettings <- { tcConfigB.optSettings with crossModuleOptUser = Some true } tcConfigB.optSettings <- { tcConfigB.optSettings with lambdaInlineThreshold = 6 } - - tcConfigB.ignoreSymbolStoreSequencePoints <- true; tcConfigB.doDetuple <- true; tcConfigB.doTLR <- true; tcConfigB.doFinalSimplify <- true; @@ -474,9 +471,9 @@ let SetDebugSwitch (tcConfigB : TcConfigBuilder) (dtype : string option) (s : Op match dtype with | Some(s) -> match s with - | "portable" -> tcConfigB.portablePDB <- true ; tcConfigB.embeddedPDB <- false; tcConfigB.jitTracking <- true + | "portable" -> tcConfigB.portablePDB <- true ; tcConfigB.embeddedPDB <- false; tcConfigB.jitTracking <- true; tcConfigB.ignoreSymbolStoreSequencePoints <- true | "pdbonly" -> tcConfigB.portablePDB <- false; tcConfigB.embeddedPDB <- false; tcConfigB.jitTracking <- false - | "embedded" -> tcConfigB.portablePDB <- true; tcConfigB.embeddedPDB <- true; tcConfigB.jitTracking <- true + | "embedded" -> tcConfigB.portablePDB <- true; tcConfigB.embeddedPDB <- true; tcConfigB.jitTracking <- true; tcConfigB.ignoreSymbolStoreSequencePoints <- true | "full" -> tcConfigB.portablePDB <- false; tcConfigB.embeddedPDB <- false; tcConfigB.jitTracking <- true | _ -> error(Error(FSComp.SR.optsUnrecognizedDebugType(s), rangeCmdArgs)) | None -> tcConfigB.portablePDB <- false; tcConfigB.embeddedPDB <- false; tcConfigB.jitTracking <- s = OptionSwitch.On; diff --git a/src/fsharp/fsc.fs b/src/fsharp/fsc.fs index 73be4f34e89..4cac232336e 100755 --- a/src/fsharp/fsc.fs +++ b/src/fsharp/fsc.fs @@ -1053,7 +1053,7 @@ module MainModuleBuilder = [tcGlobals.ilg.typ_Int32],[ILAttribElem.Int32( 8)], []) yield! iattrs yield! codegenResults.ilAssemAttrs - if Option.isSome pdbfile then + if Option.isSome pdbfile then yield (tcGlobals.ilg.mkDebuggableAttributeV2 (tcConfig.jitTracking, tcConfig.ignoreSymbolStoreSequencePoints, disableJitOptimizations, false (* enableEnC *) )) yield! reflectedDefinitionAttrs ] @@ -1069,6 +1069,7 @@ module MainModuleBuilder = CustomAttrs = manifestAttrs DisableJitOptimizations=disableJitOptimizations JitTracking= tcConfig.jitTracking + IgnoreSymbolStoreSequencePoints = tcConfig.ignoreSymbolStoreSequencePoints SecurityDecls=secDecls } let resources = From 3a6dd4f1492d8118e85c648528481aafa2939724 Mon Sep 17 00:00:00 2001 From: "Kevin Ransom (msft)" Date: Fri, 30 Sep 2016 14:19:37 -0700 Subject: [PATCH 03/14] Start enabling /embed --- src/fsharp/CompileOps.fs | 9 ++++++++- src/fsharp/CompileOps.fsi | 4 ++++ src/fsharp/CompileOptions.fs | 17 +++++++++++++---- src/fsharp/FSComp.txt | 2 ++ 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/fsharp/CompileOps.fs b/src/fsharp/CompileOps.fs index 7ada6090e9e..ebd72234fcf 100644 --- a/src/fsharp/CompileOps.fs +++ b/src/fsharp/CompileOps.fs @@ -2073,6 +2073,9 @@ type TcConfigBuilder = mutable jitTracking : bool mutable portablePDB : bool mutable embeddedPDB : bool + mutable embedAllSource : bool + mutable embedSourceList : string list + mutable ignoreSymbolStoreSequencePoints : bool mutable internConstantStrings : bool mutable extraOptimizationIterations : int @@ -2242,7 +2245,9 @@ type TcConfigBuilder = useSignatureDataFile = false jitTracking = true portablePDB = true - embeddedPDB = true + embeddedPDB = false + embedAllSource = false + embedSourceList = [] ignoreSymbolStoreSequencePoints = false internConstantStrings = true extraOptimizationIterations = 0 @@ -2732,6 +2737,8 @@ type TcConfig private (data : TcConfigBuilder,validate:bool) = member x.jitTracking = data.jitTracking member x.portablePDB = data.portablePDB member x.embeddedPDB = data.embeddedPDB + member x.embedAllSource = data.embedAllSource + member x.embedSourceList = data.embedSourceList member x.ignoreSymbolStoreSequencePoints = data.ignoreSymbolStoreSequencePoints member x.internConstantStrings = data.internConstantStrings member x.extraOptimizationIterations = data.extraOptimizationIterations diff --git a/src/fsharp/CompileOps.fsi b/src/fsharp/CompileOps.fsi index 34a4f8bf763..b383c43a141 100755 --- a/src/fsharp/CompileOps.fsi +++ b/src/fsharp/CompileOps.fsi @@ -307,6 +307,8 @@ type TcConfigBuilder = mutable jitTracking : bool mutable portablePDB : bool mutable embeddedPDB : bool + mutable embedAllSource : bool + mutable embedSourceList : string list mutable ignoreSymbolStoreSequencePoints : bool mutable internConstantStrings : bool mutable extraOptimizationIterations : int @@ -461,6 +463,8 @@ type TcConfig = member jitTracking : bool member portablePDB : bool member embeddedPDB : bool + member embedAllSource : bool + member embedSourceList : string list member ignoreSymbolStoreSequencePoints : bool member internConstantStrings : bool member extraOptimizationIterations : int diff --git a/src/fsharp/CompileOptions.fs b/src/fsharp/CompileOptions.fs index fb4ac15bcd8..39a6f7e1640 100644 --- a/src/fsharp/CompileOptions.fs +++ b/src/fsharp/CompileOptions.fs @@ -422,7 +422,7 @@ let SetOptimizeOn(tcConfigB : TcConfigBuilder) = let SetOptimizeSwitch (tcConfigB : TcConfigBuilder) switch = if (switch = OptionSwitch.On) then SetOptimizeOn(tcConfigB) else SetOptimizeOff(tcConfigB) - + let SetTailcallSwitch (tcConfigB : TcConfigBuilder) switch = tcConfigB.emitTailcalls <- (switch = OptionSwitch.On) @@ -479,6 +479,9 @@ let SetDebugSwitch (tcConfigB : TcConfigBuilder) (dtype : string option) (s : Op | None -> tcConfigB.portablePDB <- false; tcConfigB.embeddedPDB <- false; tcConfigB.jitTracking <- s = OptionSwitch.On; tcConfigB.debuginfo <- s = OptionSwitch.On +let SetEmbedAllSourceSwitch (tcConfigB : TcConfigBuilder) switch = + if (switch = OptionSwitch.On) then tcConfigB.embedAllSource <- true else tcConfigB.embedAllSource <- false + let setOutFileName tcConfigB s = tcConfigB.outputFile <- Some s @@ -504,7 +507,6 @@ let tagAddress = "
" let tagInt = "" let tagNone = "" - // PrintOptionInfo //---------------- @@ -521,6 +523,8 @@ let PrintOptionInfo (tcConfigB:TcConfigBuilder) = printfn " jitTracking . . . . . : %+A" tcConfigB.jitTracking printfn " portablePDB. . . . . . : %+A" tcConfigB.portablePDB printfn " embeddedPDB. . . . . . : %+A" tcConfigB.embeddedPDB + printfn " embedAllSource . . . . : %+A" tcConfigB.embedAllSource + printfn " embedSourceList. . . . : %+A" tcConfigB.embedSourceList printfn " debuginfo . . . . . . : %+A" tcConfigB.debuginfo printfn " resolutionEnvironment : %+A" tcConfigB.resolutionEnvironment printfn " product . . . . . . . : %+A" tcConfigB.productNameForBannerText @@ -664,7 +668,13 @@ let codeGenerationFlags isFsi (tcConfigB : TcConfigBuilder) = CompilerOption("debug", tagFullPDBOnlyPortable, OptionString (fun s -> SetDebugSwitch tcConfigB (Some(s)) OptionSwitch.On), None, Some (FSComp.SR.optsDebug(if isFsi then "pdbonly" else "full"))) - CompilerOption("optimize", tagNone, OptionSwitch (SetOptimizeSwitch tcConfigB) , None, + CompilerOption("embed", tagNone, OptionSwitch (SetEmbedAllSourceSwitch tcConfigB) , None, + Some (FSComp.SR.optsOptimize())) + + CompilerOption("embed", tagFileList, OptionStringList (fun s ->SetEmbedListSwitch, None, + Some (FSComp.SR.optsLib())) + + CompilerOption("optimize", tagNone, OptionSwitch (SetOptimizeSwitch tcConfigB) , None, Some (FSComp.SR.optsOptimize())) CompilerOption("tailcalls", tagNone, OptionSwitch (SetTailcallSwitch tcConfigB), None, @@ -672,7 +682,6 @@ let codeGenerationFlags isFsi (tcConfigB : TcConfigBuilder) = CompilerOption("crossoptimize", tagNone, OptionSwitch (crossOptimizeSwitch tcConfigB), None, Some (FSComp.SR.optsCrossoptimize())) - ] diff --git a/src/fsharp/FSComp.txt b/src/fsharp/FSComp.txt index 8f14f835865..3b5512591ad 100644 --- a/src/fsharp/FSComp.txt +++ b/src/fsharp/FSComp.txt @@ -840,6 +840,8 @@ optsResource,"Embed the specified managed resource" optsLinkresource,"Link the specified resource to this assembly where the resinfo format is [,[,public|private]]" optsDebugPM,"Emit debug information (Short form: -g)" optsDebug,"Specify debugging type: full, portable, embedded, pdbonly. ('%s' is the default if no debuggging type specified and enables attaching a debugger to a running program, 'portable' is a cross-platform format, 'embedded' is a cross-platform format embedded into the output file)." +optsEmbedAllSource,"Embed all source files in the Portable PDB (requires --debug:portable or --debug:embedded" +optsEmbedSpecificSource,"Embed specific source files in the Portable PDB. (requires --debug:portable or --debug:embedded" optsOptimize,"Enable optimizations (Short form: -O)" optsTailcalls,"Enable or disable tailcalls" optsCrossoptimize,"Enable or disable cross-module optimizations" From cfe36dedc09966e733b82aeaf4d5b19dfceeac5c Mon Sep 17 00:00:00 2001 From: "Kevin Ransom (msft)" Date: Mon, 3 Oct 2016 12:49:50 -0700 Subject: [PATCH 04/14] Saved --- tests/fsharpqa/Source/CompilerOptions/fsc/pdb/env.lst | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/fsharpqa/Source/CompilerOptions/fsc/pdb/env.lst b/tests/fsharpqa/Source/CompilerOptions/fsc/pdb/env.lst index 9124761257b..32dc7495aee 100644 --- a/tests/fsharpqa/Source/CompilerOptions/fsc/pdb/env.lst +++ b/tests/fsharpqa/Source/CompilerOptions/fsc/pdb/env.lst @@ -12,9 +12,7 @@ NOMONO SOURCE=pdb01.fs SCFLAGS="-g --pdb:pdb01x.pdb" PRECMD="IF EXIST NOMONO SOURCE=pdb01.fs SCFLAGS="--debug --pdb:d\\pdb01.pdb" PRECMD="setup.cmd" POSTCMD="IF NOT EXIST d\\pdb01.pdb EXIT 1" # different file w/ -g (in a directory) NOMONO SOURCE=pdb01.fs SCFLAGS="--debug --pdb:.\\pdb01.pdb" PRECMD="IF EXIST pdb01.pdb DEL pdb01.pdb" POSTCMD="IF NOT EXIST pdb01.pdb EXIT 1" # different file w/ -g (in current dir) -NOMONO SOURCE=pdb01.fs SCFLAGS="-g --pdb:.\\pdb01.fs" PRECMD="IF EXIST pdb01.pdb DEL pdb01.pdb" POSTCMD="IF NOT EXIST pdb01.pdb EXIT 1" # different file w/ -g (try to overwrite) - -NOMONO SOURCE=pdb01.fs SCFLAGS="-g --debug:embedded" PRECMD="IF EXIST pdb01.pdb DEL pdb01.pdb" POSTCMD="IF EXIST pdb01.pdb EXIT 1" # If pdb file exists then it didn't embed so fail. +NOMONO SOURCE=pdb01.fs SCFLAGS="-g --debug:embedded --pdb:.\\pdbembedded.pdb" PRECMD="IF EXIST pdbembedded.pdb DEL pdbembedded.pdb" POSTCMD="IF EXIST pdbembedded.pdb dir pdbembedded.pdb&EXIT 1" # If pdb file exists then it didn't embed so fail. # Case sensitive SOURCE=pdb02.fs SCFLAGS="--PDB -g" POSTCMD="IF EXIST pdb02.pdb EXIT 1" # --PDB From a162a6cc6150eb78b6949655fe44eee800490ddf Mon Sep 17 00:00:00 2001 From: "Kevin Ransom (msft)" Date: Mon, 3 Oct 2016 16:37:13 -0700 Subject: [PATCH 05/14] Fix manifest --- it was inadvertently updated with debuggableattribute flags. --- src/absil/il.fs | 2 +- src/absil/ilwrite.fs | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/absil/il.fs b/src/absil/il.fs index 2eed6e672ad..f45ea175cd6 100755 --- a/src/absil/il.fs +++ b/src/absil/il.fs @@ -3198,7 +3198,7 @@ let mkILSimpleModule assname modname dll subsystemVersion useHighEntropyVA tdefs AssemblyLongevity=ILAssemblyLongevity.Unspecified; DisableJitOptimizations = 0 <> (flags &&& 0x4000); JitTracking = (0 <> (flags &&& 0x8000)); // always turn these on - IgnoreSymbolStoreSequencePoints= (0 <> (flags &&& 0x2000)); + IgnoreSymbolStoreSequencePoints = (0 <> (flags &&& 0x2000)); Retargetable = (0 <> (flags &&& 0x100)); ExportedTypes=exportedTypes; EntrypointElsewhere=None diff --git a/src/absil/ilwrite.fs b/src/absil/ilwrite.fs index 3beaf31e083..55e2983054a 100644 --- a/src/absil/ilwrite.fs +++ b/src/absil/ilwrite.fs @@ -2871,8 +2871,6 @@ and GetManifsetAsAssemblyRow cenv m = // Setting these causes peverify errors. Hence both ilread and ilwrite ignore them and refuse to set them. // Any debugging customattributes will automatically propagate // REVIEW: No longer appears to be the case - (if m.IgnoreSymbolStoreSequencePoints then 0x2000 else 0x0) ||| - (if m.DisableJitOptimizations then 0x4000 else 0x0) ||| (if m.JitTracking then 0x8000 else 0x0) ||| (match m.PublicKey with None -> 0x0000 | Some _ -> 0x0001) ||| 0x0000) (match m.PublicKey with None -> Blob 0 | Some x -> Blob (GetBytesAsBlobIdx cenv x)) From 7c2d7fdc19863e5dadbfc7a48716f71cc7362ee1 Mon Sep 17 00:00:00 2001 From: "Kevin Ransom (msft)" Date: Tue, 4 Oct 2016 10:03:36 -0700 Subject: [PATCH 06/14] reset debug build to full pdpbs --- src/FSharpSource.Settings.targets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FSharpSource.Settings.targets b/src/FSharpSource.Settings.targets index 0507decd7c7..f9f6c3b8657 100644 --- a/src/FSharpSource.Settings.targets +++ b/src/FSharpSource.Settings.targets @@ -25,7 +25,7 @@ - portable + full portable false prompt From 358cda284c9fe577613e735298e41b4e24e01032 Mon Sep 17 00:00:00 2001 From: "Kevin Ransom (msft)" Date: Thu, 6 Oct 2016 17:57:18 -0700 Subject: [PATCH 07/14] Fix up test baselines --- src/FSharpSource.Settings.targets | 7 +- src/absil/ilwrite.fs | 12 ++- src/absil/ilwrite.fsi | 2 + src/absil/ilwritepdb.fs | 98 ++++++++++++++++--- src/absil/ilwritepdb.fsi | 2 +- src/fsharp/CompileOps.fs | 6 +- src/fsharp/CompileOps.fsi | 1 + src/fsharp/CompileOptions.fs | 8 +- src/fsharp/FSComp.txt | 4 +- src/fsharp/fsc.fs | 2 + .../fsc/help/help40.437.1033.bsl | 3 + .../fsi/exename/help40.437.1033.bsl | 3 + .../fsi/help/help-nologo.437.1033.bsl | 3 + .../fsi/help/help40-nologo.437.1033.bsl | 3 + .../fsi/help/help40.437.1033.bsl | 3 + 15 files changed, 127 insertions(+), 30 deletions(-) diff --git a/src/FSharpSource.Settings.targets b/src/FSharpSource.Settings.targets index 0507decd7c7..bc0a2aa84a8 100644 --- a/src/FSharpSource.Settings.targets +++ b/src/FSharpSource.Settings.targets @@ -25,11 +25,12 @@ - portable - portable + full + embedded false prompt - $(OtherFlags) --no-jit-optimize + $(OtherFlags) --no-jit-optimize + $(OtherFlags) --no-jit-optimize --embed DEBUG;TRACE;CODE_ANALYSIS;$(DefineConstants) DEBUG=True,TRACE=True,CODE_ANALYSIS=True,$(DefineConstants) false diff --git a/src/absil/ilwrite.fs b/src/absil/ilwrite.fs index 3beaf31e083..d3f457db429 100644 --- a/src/absil/ilwrite.fs +++ b/src/absil/ilwrite.fs @@ -3538,7 +3538,7 @@ let writeDirectory os dict = let writeBytes (os: BinaryWriter) (chunk:byte[]) = os.Write(chunk,0,chunk.Length) -let writeBinaryAndReportMappings (outfile, ilg, pdbfile: string option, signer: ILStrongNameSigner option, portablePDB, embeddedPDB, +let writeBinaryAndReportMappings (outfile, ilg, pdbfile: string option, signer: ILStrongNameSigner option, portablePDB, embeddedPDB, embedAllSource, embedSourceList, fixupOverlappingSequencePoints, emitTailcalls, showTimes, dumpDebugInfo) modul noDebugData = // Store the public key from the signer into the manifest. This means it will be written // to the binary and also acts as an indicator to leave space for delay sign @@ -3692,7 +3692,7 @@ let writeBinaryAndReportMappings (outfile, ilg, pdbfile: string option, signer: let pdbOpt = match portablePDB with | true -> - let struct (uncompressedLength, contentId, stream) as pdbStream = generatePortablePdb fixupOverlappingSequencePoints showTimes pdbData + let struct (uncompressedLength, contentId, stream) as pdbStream = generatePortablePdb fixupOverlappingSequencePoints embedAllSource embedSourceList showTimes pdbData if embeddedPDB then Some (compressPortablePdbStream uncompressedLength contentId stream) else Some (pdbStream) | _ -> None @@ -4262,6 +4262,8 @@ type options = pdbfile: string option portablePDB: bool embeddedPDB: bool + embedAllSource: bool + embedSourceList: string list signer: ILStrongNameSigner option fixupOverlappingSequencePoints: bool emitTailcalls : bool @@ -4269,6 +4271,6 @@ type options = dumpDebugInfo:bool } let WriteILBinary (outfile, (args: options), modul, noDebugData) = - ignore (writeBinaryAndReportMappings (outfile, args.ilg, args.pdbfile, args.signer, args.portablePDB, args.embeddedPDB, - args.fixupOverlappingSequencePoints, args.emitTailcalls, args.showTimes, - args.dumpDebugInfo) modul noDebugData) + ignore (writeBinaryAndReportMappings (outfile, args.ilg, args.pdbfile, args.signer, args.portablePDB, args.embeddedPDB, + args.embedAllSource, args.embedSourceList, args.fixupOverlappingSequencePoints, + args.emitTailcalls, args.showTimes, args.dumpDebugInfo) modul noDebugData) diff --git a/src/absil/ilwrite.fsi b/src/absil/ilwrite.fsi index 51d1842b208..f1b43e6ae21 100644 --- a/src/absil/ilwrite.fsi +++ b/src/absil/ilwrite.fsi @@ -20,6 +20,8 @@ type options = pdbfile: string option portablePDB: bool embeddedPDB: bool + embedAllSource: bool + embedSourceList: string list signer : ILStrongNameSigner option fixupOverlappingSequencePoints : bool emitTailcalls: bool diff --git a/src/absil/ilwritepdb.fs b/src/absil/ilwritepdb.fs index 87bf4fafb0f..d17878928a5 100644 --- a/src/absil/ilwritepdb.fs +++ b/src/absil/ilwritepdb.fs @@ -19,6 +19,31 @@ open Microsoft.FSharp.Compiler.AbstractIL.Internal.Library open Microsoft.FSharp.Compiler.ErrorLogger open Microsoft.FSharp.Compiler.Range + +type BlobBuildingStream () = + inherit Stream() + + static let chunkSize = 32 * 1024 + let builder = new BlobBuilder(chunkSize) + + override this.CanWrite with get() = true + override this.CanRead with get() = false + override this.CanSeek with get() = false + override this.Length with get() = int64(builder.Count) + + override this.Write(buffer:byte array, offset:int, count:int) = builder.WriteBytes(buffer, offset, count) + override this.WriteByte(value:byte) = builder.WriteByte(value) + member this.WriteInt32(value:int) = builder.WriteInt32(value) + member this.ToImmutableArray() = builder.ToImmutableArray() + member this.TryWriteBytes(stream:Stream, length:int) = builder.TryWriteBytes(stream, length) + + override this.Flush() = () + override this.Dispose(_disposing:bool) = () + override this.Seek(_offset:int64, _origin:SeekOrigin) = raise (new NotSupportedException()) + override this.Read(_buffer:byte array, _offset:int, _count:int) = raise (new NotSupportedException()) + override this.SetLength(_value:int64) = raise (new NotSupportedException()) + override val Position = 0L with get, set + // -------------------------------------------------------------------- // PDB types // -------------------------------------------------------------------- @@ -227,7 +252,7 @@ let fixupOverlappingSequencePoints fixupSPs showTimes methods = Array.sortInPlaceBy fst allSps spCounts, allSps -let generatePortablePdb fixupSPs showTimes (info:PdbData) = +let generatePortablePdb fixupSPs (embedAllSource:bool) (embedSourceList:string list) showTimes (info:PdbData) = sortMethods showTimes info let _spCounts, _allSps = fixupOverlappingSequencePoints fixupSPs showTimes info.Methods let externalRowCounts = getRowCounts info.TableRowCounts @@ -253,23 +278,72 @@ let generatePortablePdb fixupSPs showTimes (info:PdbData) = metadata.GetOrAddBlob(writer) let corSymLanguageTypeFSharp = System.Guid(0xAB4F38C9u, 0xB6E6us, 0x43baus, 0xBEuy, 0x3Buy, 0x58uy, 0x08uy, 0x0Buy, 0x2Cuy, 0xCCuy, 0xE3uy) + let embeddedSource = System.Guid(0x0e8a571bu, 0x6926us, 0x466eus, 0xb4uy, 0xaduy, 0x8auy, 0xb0uy, 0x46uy, 0x11uy, 0xf5uy, 0xfeuy) + + /// + /// The maximum number of bytes in to write out uncompressed. + /// + /// This prevents wasting resources on compressing tiny files with little to negative gain + /// in PDB file size. + /// + /// Chosen as the point at which we start to see > 10% blob size reduction using all + /// current source files in corefx and roslyn as sample data. + /// + let sourceCompressionThreshold = 200 + let documentIndex = + let includeSource file = + let isInList = + if embedSourceList |> List.length = 0 then false + else + match embedSourceList |> List.tryFind(fun f -> String.Compare(file, f, StringComparison.InvariantCulture) = 0) with + | Some _ -> true + | None -> false + + if not embedAllSource && not isInList || not (File.Exists(file)) then + None + else + let stream = File.OpenRead(file) + let length64 = stream.Length + if length64 > int64(Int32.MaxValue) then raise (new IOException("File is too long")) + + let builder = new BlobBuildingStream() + let length = int(length64) + if length < sourceCompressionThreshold then + builder.WriteInt32(0) + builder.TryWriteBytes(stream, length) |> ignore + else + builder.WriteInt32(length) |>ignore + use deflater = new DeflateStream(builder, CompressionMode.Compress, true) + stream.CopyTo(deflater) |> ignore + Some (builder.ToImmutableArray()) + let mutable index = new Dictionary(docs.Length) metadata.SetCapacity(TableIndex.Document, docs.Length) for doc in docs do let handle = match checkSum doc.File with | Some (hashAlg, checkSum) -> - serializeDocumentName doc.File, - metadata.GetOrAddGuid(hashAlg), - metadata.GetOrAddBlob(checkSum.ToImmutableArray()), - metadata.GetOrAddGuid(corSymLanguageTypeFSharp) + let h = + (serializeDocumentName doc.File, + metadata.GetOrAddGuid(hashAlg), + metadata.GetOrAddBlob(checkSum.ToImmutableArray()), + metadata.GetOrAddGuid(corSymLanguageTypeFSharp)) |> metadata.AddDocument + match includeSource doc.File with + | None -> () + | Some blob -> + printf "AddCustomDebugInformation : %A" doc.File + metadata.AddCustomDebugInformation(DocumentHandle.op_Implicit(h), + metadata.GetOrAddGuid(embeddedSource), + metadata.GetOrAddBlob(blob)) |> ignore + h | None -> - serializeDocumentName doc.File, - metadata.GetOrAddGuid(System.Guid.Empty), - metadata.GetOrAddBlob(ImmutableArray.Empty), - metadata.GetOrAddGuid(corSymLanguageTypeFSharp) - |> metadata.AddDocument + let h = + (serializeDocumentName doc.File, + metadata.GetOrAddGuid(System.Guid.Empty), + metadata.GetOrAddBlob(ImmutableArray.Empty), + metadata.GetOrAddGuid(corSymLanguageTypeFSharp)) |> metadata.AddDocument + h index.Add(doc.File, handle) index @@ -291,7 +365,7 @@ let generatePortablePdb fixupSPs showTimes (info:PdbData) = else match documentIndex.TryGetValue(docs.[d].File) with | false, _ -> Unchecked.defaultof - | true, f -> f + | true, h -> h if sps.Length = 0 then Unchecked.defaultof, Unchecked.defaultof @@ -306,7 +380,6 @@ let generatePortablePdb fixupSPs showTimes (info:PdbData) = singleDocumentIndex let builder = new BlobBuilder() - builder.WriteCompressedInteger(minfo.LocalSignatureToken) // Initial document: When sp's spread over more than one document we put the initial document here. @@ -356,7 +429,6 @@ let generatePortablePdb fixupSPs showTimes (info:PdbData) = previousNonHiddenStartColumn <- sps.[i].Column getDocumentHandle singleDocumentIndex, metadata.GetOrAddBlob(builder) - metadata.AddMethodDebugInformation(docHandle, sequencePointBlob) |> ignore // Write the scopes diff --git a/src/absil/ilwritepdb.fsi b/src/absil/ilwritepdb.fsi index 1baf1d4b98c..81f5272a188 100644 --- a/src/absil/ilwritepdb.fsi +++ b/src/absil/ilwritepdb.fsi @@ -82,7 +82,7 @@ type idd = iddData: byte[]; iddChunk: BinaryChunk } -val generatePortablePdb : fixupSPs:bool -> showTimes:bool -> info:PdbData -> struct (int64 * BlobContentId * MemoryStream) +val generatePortablePdb : fixupSPs:bool -> embedAllSource:bool -> embedSourceList:string list -> showTimes:bool -> info:PdbData -> struct (int64 * BlobContentId * MemoryStream) val compressPortablePdbStream : uncompressedLength:int64 -> contentId:BlobContentId -> stream:MemoryStream -> struct (int64 * BlobContentId * MemoryStream) val embedPortablePdbInfo : uncompressedLength:int64 -> contentId:BlobContentId -> stream:MemoryStream -> showTimes:bool -> fpdb:string -> cvChunk:BinaryChunk -> pdbChunk:BinaryChunk -> idd[] val writePortablePdbInfo : contentId:BlobContentId -> stream:MemoryStream -> showTimes:bool -> fpdb:string -> cvChunk:BinaryChunk -> idd[] diff --git a/src/fsharp/CompileOps.fs b/src/fsharp/CompileOps.fs index ebd72234fcf..a651b05f986 100644 --- a/src/fsharp/CompileOps.fs +++ b/src/fsharp/CompileOps.fs @@ -2376,7 +2376,7 @@ type TcConfigBuilder = | None -> false if ok && not (List.contains absolutePath tcConfigB.includes) then tcConfigB.includes <- tcConfigB.includes ++ absolutePath - + member tcConfigB.AddLoadedSource(m,path,pathLoadedFrom) = if FileSystem.IsInvalidPathShim(path) then warning(Error(FSComp.SR.buildInvalidFilename(path),m)) @@ -2389,7 +2389,9 @@ type TcConfigBuilder = ComputeMakePathAbsolute pathLoadedFrom path if not (List.contains path (List.map snd tcConfigB.loadedSources)) then tcConfigB.loadedSources <- tcConfigB.loadedSources ++ (m,path) - + + member tcConfigB.AddEmbeddedSourceFile (file) = + tcConfigB.embedSourceList <- tcConfigB.embedSourceList ++ file member tcConfigB.AddEmbeddedResource filename = tcConfigB.embedResources <- tcConfigB.embedResources ++ filename diff --git a/src/fsharp/CompileOps.fsi b/src/fsharp/CompileOps.fsi index b383c43a141..fc77fec23a9 100755 --- a/src/fsharp/CompileOps.fsi +++ b/src/fsharp/CompileOps.fsi @@ -379,6 +379,7 @@ type TcConfigBuilder = member AddIncludePath : range * string * string -> unit member AddReferencedAssemblyByPath : range * string -> unit member RemoveReferencedAssemblyByPath : range * string -> unit + member AddEmbeddedSourceFile : string -> unit member AddEmbeddedResource : string -> unit static member SplitCommandLineResourceInfo : string -> string * string * ILResourceAccess diff --git a/src/fsharp/CompileOptions.fs b/src/fsharp/CompileOptions.fs index 39a6f7e1640..17b75b7157a 100644 --- a/src/fsharp/CompileOptions.fs +++ b/src/fsharp/CompileOptions.fs @@ -573,7 +573,7 @@ let errorsAndWarningsFlags (tcConfigB : TcConfigBuilder) = CompilerOption("nowarn", tagWarnList, OptionStringList (fun n -> tcConfigB.TurnWarningOff(rangeCmdArgs,n)), None, Some (FSComp.SR.optsNowarn())); - + CompilerOption("warnon", tagWarnList, OptionStringList (fun n -> tcConfigB.TurnWarningOn(rangeCmdArgs,n)), None, Some(FSComp.SR.optsWarnOn())); @@ -669,10 +669,10 @@ let codeGenerationFlags isFsi (tcConfigB : TcConfigBuilder) = Some (FSComp.SR.optsDebug(if isFsi then "pdbonly" else "full"))) CompilerOption("embed", tagNone, OptionSwitch (SetEmbedAllSourceSwitch tcConfigB) , None, - Some (FSComp.SR.optsOptimize())) + Some (FSComp.SR.optsEmbedAllSource())) - CompilerOption("embed", tagFileList, OptionStringList (fun s ->SetEmbedListSwitch, None, - Some (FSComp.SR.optsLib())) + CompilerOption("embed", tagFileList, OptionStringList (fun f -> tcConfigB.AddEmbeddedSourceFile f), None, + Some ( FSComp.SR.optsEmbedSource())); CompilerOption("optimize", tagNone, OptionSwitch (SetOptimizeSwitch tcConfigB) , None, Some (FSComp.SR.optsOptimize())) diff --git a/src/fsharp/FSComp.txt b/src/fsharp/FSComp.txt index 3b5512591ad..b58a2cb80a2 100644 --- a/src/fsharp/FSComp.txt +++ b/src/fsharp/FSComp.txt @@ -836,12 +836,12 @@ optsReference,"Reference an assembly (Short form: -r)" optsWin32res,"Specify a Win32 resource file (.res)" optsWin32manifest,"Specify a Win32 manifest file" optsNowin32manifest,"Do not include the default Win32 manifest" +optsEmbedAllSource,"Embed all source files in the portable PDB file" +optsEmbedSource,"Embed specific source files in the portable PDB file" optsResource,"Embed the specified managed resource" optsLinkresource,"Link the specified resource to this assembly where the resinfo format is [,[,public|private]]" optsDebugPM,"Emit debug information (Short form: -g)" optsDebug,"Specify debugging type: full, portable, embedded, pdbonly. ('%s' is the default if no debuggging type specified and enables attaching a debugger to a running program, 'portable' is a cross-platform format, 'embedded' is a cross-platform format embedded into the output file)." -optsEmbedAllSource,"Embed all source files in the Portable PDB (requires --debug:portable or --debug:embedded" -optsEmbedSpecificSource,"Embed specific source files in the Portable PDB. (requires --debug:portable or --debug:embedded" optsOptimize,"Enable optimizations (Short form: -O)" optsTailcalls,"Enable or disable tailcalls" optsCrossoptimize,"Enable or disable cross-module optimizations" diff --git a/src/fsharp/fsc.fs b/src/fsharp/fsc.fs index 4cac232336e..74dee8a5bab 100755 --- a/src/fsharp/fsc.fs +++ b/src/fsharp/fsc.fs @@ -1743,6 +1743,8 @@ module FileWriter = showTimes = tcConfig.showTimes portablePDB = tcConfig.portablePDB embeddedPDB = tcConfig.embeddedPDB + embedAllSource = tcConfig.embedAllSource + embedSourceList = tcConfig.embedSourceList signer = GetSigner signingInfo fixupOverlappingSequencePoints = false dumpDebugInfo = tcConfig.dumpDebugInfo }, diff --git a/tests/fsharpqa/Source/CompilerOptions/fsc/help/help40.437.1033.bsl b/tests/fsharpqa/Source/CompilerOptions/fsc/help/help40.437.1033.bsl index 1d028d6669d..57209f1d262 100644 --- a/tests/fsharpqa/Source/CompilerOptions/fsc/help/help40.437.1033.bsl +++ b/tests/fsharpqa/Source/CompilerOptions/fsc/help/help40.437.1033.bsl @@ -56,6 +56,9 @@ Copyright (c) Microsoft Corporation. All Rights Reserved. cross-platform format, 'embedded' is a cross-platform format embedded into the output file). +--embed[+|-] Embed all source files in the portable PDB file +--embed: Embed specific source files in the portable PDB + file --optimize[+|-] Enable optimizations (Short form: -O) --tailcalls[+|-] Enable or disable tailcalls --crossoptimize[+|-] Enable or disable cross-module optimizations diff --git a/tests/fsharpqa/Source/CompilerOptions/fsi/exename/help40.437.1033.bsl b/tests/fsharpqa/Source/CompilerOptions/fsi/exename/help40.437.1033.bsl index 61dc02ef058..c65668cefb2 100644 --- a/tests/fsharpqa/Source/CompilerOptions/fsi/exename/help40.437.1033.bsl +++ b/tests/fsharpqa/Source/CompilerOptions/fsi/exename/help40.437.1033.bsl @@ -19,6 +19,9 @@ Usage: fsharpi [script.fsx []] 'portable' is a cross-platform format, 'embedded' is a cross-platform format embedded into the output file). +--embed[+|-] Embed all source files in the portable PDB file +--embed: Embed specific source files in the portable PDB + file --optimize[+|-] Enable optimizations (Short form: -O) --tailcalls[+|-] Enable or disable tailcalls --crossoptimize[+|-] Enable or disable cross-module optimizations diff --git a/tests/fsharpqa/Source/CompilerOptions/fsi/help/help-nologo.437.1033.bsl b/tests/fsharpqa/Source/CompilerOptions/fsi/help/help-nologo.437.1033.bsl index 272f7d9eb65..87f6750cb61 100644 --- a/tests/fsharpqa/Source/CompilerOptions/fsi/help/help-nologo.437.1033.bsl +++ b/tests/fsharpqa/Source/CompilerOptions/fsi/help/help-nologo.437.1033.bsl @@ -17,6 +17,9 @@ Usage: fsi.exe [script.fsx []] specified and enables attaching a debugger to a running program. 'portable' is a cross-platform format). +--embed[+|-] Embed all source files in the portable PDB file +--embed: Embed specific source files in the portable PDB +file --optimize[+|-] Enable optimizations (Short form: -O) --tailcalls[+|-] Enable or disable tailcalls --crossoptimize[+|-] Enable or disable cross-module optimizations diff --git a/tests/fsharpqa/Source/CompilerOptions/fsi/help/help40-nologo.437.1033.bsl b/tests/fsharpqa/Source/CompilerOptions/fsi/help/help40-nologo.437.1033.bsl index a044d368a20..0108146bd6f 100644 --- a/tests/fsharpqa/Source/CompilerOptions/fsi/help/help40-nologo.437.1033.bsl +++ b/tests/fsharpqa/Source/CompilerOptions/fsi/help/help40-nologo.437.1033.bsl @@ -19,6 +19,9 @@ Usage: fsi.exe [script.fsx []] 'portable' is a cross-platform format, 'embedded' is a cross-platform format embedded into the output file). +--embed[+|-] Embed all source files in the portable PDB file +--embed: Embed specific source files in the portable PDB +file --optimize[+|-] Enable optimizations (Short form: -O) --tailcalls[+|-] Enable or disable tailcalls --crossoptimize[+|-] Enable or disable cross-module optimizations diff --git a/tests/fsharpqa/Source/CompilerOptions/fsi/help/help40.437.1033.bsl b/tests/fsharpqa/Source/CompilerOptions/fsi/help/help40.437.1033.bsl index a0d495ad635..be21d430bce 100644 --- a/tests/fsharpqa/Source/CompilerOptions/fsi/help/help40.437.1033.bsl +++ b/tests/fsharpqa/Source/CompilerOptions/fsi/help/help40.437.1033.bsl @@ -21,6 +21,9 @@ Usage: fsi.exe [script.fsx []] 'portable' is a cross-platform format, 'embedded' is a cross-platform format embedded into the output file). +--embed[+|-] Embed all source files in the portable PDB file +--embed: Embed specific source files in the portable PDB +file --optimize[+|-] Enable optimizations (Short form: -O) --tailcalls[+|-] Enable or disable tailcalls --crossoptimize[+|-] Enable or disable cross-module optimizations From 91a49e7b0d262da3925529ffb2c421513f3596f2 Mon Sep 17 00:00:00 2001 From: "Kevin Ransom (msft)" Date: Fri, 7 Oct 2016 15:36:44 -0700 Subject: [PATCH 08/14] Make build setup switch offable --- build.cmd | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/build.cmd b/build.cmd index 2440d345648..3303f56f9c8 100644 --- a/build.cmd +++ b/build.cmd @@ -64,6 +64,8 @@ for %%i in (%BUILD_FSC_DEFAULT%) do ( call :SET_CONFIG %%i ) setlocal disableDelayedExpansion echo. +rem disable setup build by setting FSC_BUILD_SETUP=0 +if /i '%FSC_BUILD_SETUP%' == '' (set FSC_BUILD_SETUP=1) goto :MAIN :SET_CONFIG @@ -96,7 +98,7 @@ if /i '%ARG%' == 'all' ( set BUILD_CORECLR=1 set BUILD_PORTABLE=1 set BUILD_VS=1 - set BUILD_SETUP=1 + set BUILD_SETUP=%FSC_BUILD_SETUP% set TEST_COMPILERUNIT=1 set TEST_NET40_COREUNIT=1 @@ -120,7 +122,7 @@ if /i '%ARG%' == 'microbuild' ( set BUILD_CORECLR=0 set BUILD_PORTABLE=1 set BUILD_VS=1 - set BUILD_SETUP=1 + set BUILD_SETUP=%FSC_BUILD_SETUP% set TEST_COMPILERUNIT=1 set TEST_NET40_COREUNIT=1 @@ -143,7 +145,7 @@ if /i '%ARG%' == 'ci' ( set BUILD_CORECLR=1 set BUILD_PORTABLE=1 set BUILD_VS=1 - set BUILD_SETUP=1 + set BUILD_SETUP=%FSC_BUILD_SETUP% set TEST_COMPILERUNIT=1 set TEST_NET40_COREUNIT=1 @@ -164,7 +166,7 @@ if /i '%ARG%' == 'ci_part1' ( set BUILD_CORECLR=0 set BUILD_PORTABLE=1 set BUILD_VS=1 - set BUILD_SETUP=1 + set BUILD_SETUP=%FSC_BUILD_SETUP% set TEST_COMPILERUNIT=1 set TEST_NET40_COREUNIT=0 From 210eddfda39aba92ffba7dedbe1b2221bb2b788b Mon Sep 17 00:00:00 2001 From: "Kevin Ransom (msft)" Date: Mon, 10 Oct 2016 17:54:25 -0700 Subject: [PATCH 09/14] Add testcase for portablepdb generation many let bindings --- src/absil/ilwritepdb.fs | 3 +- .../LetBindings/Basic/ManyLetBindings.fs | 188 ++++++++++++++++++ .../LetBindings/Basic/env.lst | 5 +- 3 files changed, 192 insertions(+), 4 deletions(-) diff --git a/src/absil/ilwritepdb.fs b/src/absil/ilwritepdb.fs index b63c202625e..a393fa1c87b 100644 --- a/src/absil/ilwritepdb.fs +++ b/src/absil/ilwritepdb.fs @@ -296,7 +296,7 @@ let generatePortablePdb fixupSPs (embedAllSource:bool) (embedSourceList:string l let isInList = if embedSourceList |> List.length = 0 then false else - match embedSourceList |> List.tryFind(fun f -> String.Compare(file, f, StringComparison.InvariantCulture) = 0) with + match embedSourceList |> List.tryFind(fun f -> String.Compare(file, f, StringComparison.OrdinalIgnoreCase ) = 0) with | Some _ -> true | None -> false @@ -428,7 +428,6 @@ let generatePortablePdb fixupSPs (embedAllSource:bool) (embedSourceList:string l previousNonHiddenStartColumn <- sps.[i].Column getDocumentHandle singleDocumentIndex, metadata.GetOrAddBlob(builder) - metadata.AddMethodDebugInformation(docHandle, sequencePointBlob) |> ignore metadata.AddMethodDebugInformation(docHandle, sequencePointBlob) |> ignore diff --git a/tests/fsharpqa/Source/Conformance/DeclarationElements/LetBindings/Basic/ManyLetBindings.fs b/tests/fsharpqa/Source/Conformance/DeclarationElements/LetBindings/Basic/ManyLetBindings.fs index f5ca30545c0..c4d01c11fbd 100644 --- a/tests/fsharpqa/Source/Conformance/DeclarationElements/LetBindings/Basic/ManyLetBindings.fs +++ b/tests/fsharpqa/Source/Conformance/DeclarationElements/LetBindings/Basic/ManyLetBindings.fs @@ -513,3 +513,191 @@ let x508 = "508" let x509 = "509" let x510 = "510" let x511 = "511" +let x512 = "512" +let x513 = "513" +let x514 = "514" +let x515 = "515" +let x516 = "516" +let x517 = "517" +let x518 = "518" +let x519 = "519" +let x520 = "520" +let x521 = "521" +let x522 = "522" +let x523 = "523" +let x524 = "524" +let x525 = "525" +let x526 = "526" +let x527 = "527" +let x528 = "528" +let x529 = "529" +let x530 = "530" +let x531 = "531" +let x532 = "532" +let x533 = "533" +let x534 = "534" +let x535 = "535" +let x536 = "536" +let x537 = "537" +let x538 = "538" +let x539 = "539" +let x540 = "540" +let x541 = "541" +let x542 = "542" +let x543 = "543" +let x544 = "544" +let x545 = "545" +let x546 = "546" +let x547 = "547" +let x548 = "548" +let x549 = "549" +let x550 = "550" +let x551 = "551" +let x552 = "552" +let x553 = "553" +let x554 = "554" +let x555 = "555" +let x556 = "556" +let x557 = "557" +let x558 = "558" +let x559 = "559" +let x560 = "560" +let x561 = "561" +let x562 = "562" +let x563 = "563" +let x564 = "564" +let x565 = "565" +let x566 = "566" +let x567 = "567" +let x568 = "568" +let x569 = "569" +let x570 = "570" +let x571 = "571" +let x572 = "572" +let x573 = "573" +let x574 = "574" +let x575 = "575" +let x576 = "576" +let x577 = "577" +let x578 = "578" +let x579 = "579" +let x580 = "580" +let x581 = "581" +let x582 = "582" +let x583 = "583" +let x584 = "584" +let x585 = "585" +let x586 = "586" +let x587 = "587" +let x588 = "588" +let x589 = "589" +let x590 = "590" +let x591 = "591" +let x592 = "592" +let x593 = "593" +let x594 = "594" +let x595 = "595" +let x596 = "596" +let x597 = "597" +let x598 = "598" +let x599 = "599" +let x600 = "600" +let x601 = "601" +let x602 = "602" +let x603 = "603" +let x604 = "604" +let x605 = "605" +let x606 = "606" +let x607 = "607" +let x608 = "608" +let x609 = "609" +let x610 = "610" +let x611 = "611" +let x612 = "612" +let x613 = "613" +let x614 = "614" +let x615 = "615" +let x616 = "616" +let x617 = "617" +let x618 = "618" +let x619 = "619" +let x620 = "620" +let x621 = "621" +let x622 = "622" +let x623 = "623" +let x624 = "624" +let x625 = "625" +let x626 = "626" +let x627 = "627" +let x628 = "628" +let x629 = "629" +let x630 = "630" +let x631 = "631" +let x632 = "632" +let x633 = "633" +let x634 = "634" +let x635 = "635" +let x636 = "636" +let x637 = "637" +let x638 = "638" +let x639 = "639" +let x640 = "640" +let x641 = "641" +let x642 = "642" +let x643 = "643" +let x644 = "644" +let x645 = "645" +let x646 = "646" +let x647 = "647" +let x648 = "648" +let x649 = "649" +let x650 = "650" +let x651 = "651" +let x652 = "652" +let x653 = "653" +let x654 = "654" +let x655 = "655" +let x656 = "656" +let x657 = "657" +let x658 = "658" +let x659 = "659" +let x660 = "660" +let x661 = "661" +let x662 = "662" +let x663 = "663" +let x664 = "664" +let x665 = "665" +let x666 = "666" +let x667 = "667" +let x668 = "668" +let x669 = "669" +let x670 = "670" +let x671 = "671" +let x672 = "672" +let x673 = "673" +let x674 = "674" +let x675 = "675" +let x676 = "676" +let x677 = "677" +let x678 = "678" +let x679 = "679" +let x680 = "680" +let x681 = "681" +let x682 = "682" +let x683 = "683" +let x684 = "684" +let x685 = "685" +let x686 = "686" +let x687 = "687" +let x688 = "688" +let x689 = "689" +let x690 = "690" +let x691 = "691" +let x692 = "692" +let x693 = "693" +let x694 = "694" +let x695 = "695" +let x696 = "696" +let x697 = "697" +let x698 = "698" +let x699 = "699" diff --git a/tests/fsharpqa/Source/Conformance/DeclarationElements/LetBindings/Basic/env.lst b/tests/fsharpqa/Source/Conformance/DeclarationElements/LetBindings/Basic/env.lst index 1b523e68034..7685eb450c1 100644 --- a/tests/fsharpqa/Source/Conformance/DeclarationElements/LetBindings/Basic/env.lst +++ b/tests/fsharpqa/Source/Conformance/DeclarationElements/LetBindings/Basic/env.lst @@ -4,8 +4,9 @@ SOURCE=Pathological04.fs SCFLAGS=-a # Pathological04.fs SOURCE=E_Pathological05.fs SCFLAGS=--test:ErrorRanges # E_Pathological05.fs SOURCE=E_Pathological06.fs SCFLAGS=--test:ErrorRanges # E_Pathological06.fs - - SOURCE=ManyLetBindings.fs SCFLAGS="--debug:full --optimize-" # ManyLetBindings.fs + + SOURCE=ManyLetBindings.fs SCFLAGS="--debug:full --optimize-" # Full ManyLetBindings.fs + SOURCE=ManyLetBindings.fs SCFLAGS="--debug:portable --optimize-" # Portable ManyLetBindings.fs SOURCE=SanityCheck.fs # SanityCheck.fs SOURCE=nestedLetBindings.fs # nestedLetBindings.fs From 9909b706f5fbac09afd9e94845e91ed9fdf6e6d0 Mon Sep 17 00:00:00 2001 From: "Kevin Ransom (msft)" Date: Tue, 11 Oct 2016 14:01:27 -0700 Subject: [PATCH 10/14] Add --sourcelink command line options and test cases --- .gitignore | 1 + src/FSharpSource.targets | 17 +++++++++++++++++ src/absil/ilwrite.fs | 7 ++++--- src/absil/ilwrite.fsi | 1 + src/absil/ilwritepdb.fs | 2 +- src/absil/ilwritepdb.fsi | 2 +- src/fsharp/CompileOps.fs | 3 +++ src/fsharp/CompileOps.fsi | 2 ++ src/fsharp/CompileOptions.fs | 3 +++ src/fsharp/FSComp.txt | 2 ++ src/fsharp/fsc.fs | 9 +++++++-- .../fsc/help/help40.437.1033.bsl | 2 ++ .../Source/CompilerOptions/fsc/pdb/env.lst | 4 ++++ .../Source/CompilerOptions/fsc/pdb/pdb06.fs | 4 ++++ .../CompilerOptions/fsc/pdb/source_link.json | 1 + 15 files changed, 53 insertions(+), 7 deletions(-) create mode 100644 tests/fsharpqa/Source/CompilerOptions/fsc/pdb/pdb06.fs create mode 100644 tests/fsharpqa/Source/CompilerOptions/fsc/pdb/source_link.json diff --git a/.gitignore b/.gitignore index 1c0ff437d77..40f09ad07ce 100644 --- a/.gitignore +++ b/.gitignore @@ -102,3 +102,4 @@ tests/fsharp/core/array/dont.run.peverify tests/fsharp/core/innerpoly/dont.run.peverify tests/fsharp/typecheck/sigs/neg94-pre.dll times +source_link.json \ No newline at end of file diff --git a/src/FSharpSource.targets b/src/FSharpSource.targets index aaa2e141077..0ce3d46ef65 100644 --- a/src/FSharpSource.targets +++ b/src/FSharpSource.targets @@ -542,8 +542,25 @@ + + + + + $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory.TrimEnd("\")))) + + + + + + + + + + + + diff --git a/src/absil/ilwrite.fs b/src/absil/ilwrite.fs index 9ca851d3ed9..618246aee04 100644 --- a/src/absil/ilwrite.fs +++ b/src/absil/ilwrite.fs @@ -3537,7 +3537,7 @@ let writeDirectory os dict = let writeBytes (os: BinaryWriter) (chunk:byte[]) = os.Write(chunk,0,chunk.Length) let writeBinaryAndReportMappings (outfile, ilg, pdbfile: string option, signer: ILStrongNameSigner option, portablePDB, embeddedPDB, embedAllSource, embedSourceList, - fixupOverlappingSequencePoints, emitTailcalls, showTimes, dumpDebugInfo) modul noDebugData = + sourceLink, fixupOverlappingSequencePoints, emitTailcalls, showTimes, dumpDebugInfo) modul noDebugData = // Store the public key from the signer into the manifest. This means it will be written // to the binary and also acts as an indicator to leave space for delay sign @@ -3690,7 +3690,7 @@ let writeBinaryAndReportMappings (outfile, ilg, pdbfile: string option, signer: let pdbOpt = match portablePDB with | true -> - let struct (uncompressedLength, contentId, stream) as pdbStream = generatePortablePdb fixupOverlappingSequencePoints embedAllSource embedSourceList showTimes pdbData + let struct (uncompressedLength, contentId, stream) as pdbStream = generatePortablePdb fixupOverlappingSequencePoints embedAllSource embedSourceList sourceLink showTimes pdbData if embeddedPDB then Some (compressPortablePdbStream uncompressedLength contentId stream) else Some (pdbStream) | _ -> None @@ -4262,6 +4262,7 @@ type options = embeddedPDB: bool embedAllSource: bool embedSourceList: string list + sourceLink: string signer: ILStrongNameSigner option fixupOverlappingSequencePoints: bool emitTailcalls : bool @@ -4270,5 +4271,5 @@ type options = let WriteILBinary (outfile, (args: options), modul, noDebugData) = ignore (writeBinaryAndReportMappings (outfile, args.ilg, args.pdbfile, args.signer, args.portablePDB, args.embeddedPDB, - args.embedAllSource, args.embedSourceList, args.fixupOverlappingSequencePoints, + args.embedAllSource, args.embedSourceList, args.sourceLink, args.fixupOverlappingSequencePoints, args.emitTailcalls, args.showTimes, args.dumpDebugInfo) modul noDebugData) diff --git a/src/absil/ilwrite.fsi b/src/absil/ilwrite.fsi index f1b43e6ae21..3ee76893062 100644 --- a/src/absil/ilwrite.fsi +++ b/src/absil/ilwrite.fsi @@ -22,6 +22,7 @@ type options = embeddedPDB: bool embedAllSource: bool embedSourceList: string list + sourceLink: string signer : ILStrongNameSigner option fixupOverlappingSequencePoints : bool emitTailcalls: bool diff --git a/src/absil/ilwritepdb.fs b/src/absil/ilwritepdb.fs index a393fa1c87b..81d4232a643 100644 --- a/src/absil/ilwritepdb.fs +++ b/src/absil/ilwritepdb.fs @@ -252,7 +252,7 @@ let fixupOverlappingSequencePoints fixupSPs showTimes methods = Array.sortInPlaceBy fst allSps spCounts, allSps -let generatePortablePdb fixupSPs (embedAllSource:bool) (embedSourceList:string list) showTimes (info:PdbData) = +let generatePortablePdb fixupSPs (embedAllSource:bool) (embedSourceList:string list) (_sourceLink:string) showTimes (info:PdbData) = sortMethods showTimes info let _spCounts, _allSps = fixupOverlappingSequencePoints fixupSPs showTimes info.Methods let externalRowCounts = getRowCounts info.TableRowCounts diff --git a/src/absil/ilwritepdb.fsi b/src/absil/ilwritepdb.fsi index 81f5272a188..4ad4ce03e66 100644 --- a/src/absil/ilwritepdb.fsi +++ b/src/absil/ilwritepdb.fsi @@ -82,7 +82,7 @@ type idd = iddData: byte[]; iddChunk: BinaryChunk } -val generatePortablePdb : fixupSPs:bool -> embedAllSource:bool -> embedSourceList:string list -> showTimes:bool -> info:PdbData -> struct (int64 * BlobContentId * MemoryStream) +val generatePortablePdb : fixupSPs:bool -> embedAllSource:bool -> embedSourceList:string list -> sourceLink: string -> showTimes:bool -> info:PdbData -> struct (int64 * BlobContentId * MemoryStream) val compressPortablePdbStream : uncompressedLength:int64 -> contentId:BlobContentId -> stream:MemoryStream -> struct (int64 * BlobContentId * MemoryStream) val embedPortablePdbInfo : uncompressedLength:int64 -> contentId:BlobContentId -> stream:MemoryStream -> showTimes:bool -> fpdb:string -> cvChunk:BinaryChunk -> pdbChunk:BinaryChunk -> idd[] val writePortablePdbInfo : contentId:BlobContentId -> stream:MemoryStream -> showTimes:bool -> fpdb:string -> cvChunk:BinaryChunk -> idd[] diff --git a/src/fsharp/CompileOps.fs b/src/fsharp/CompileOps.fs index a651b05f986..08d0ac24235 100644 --- a/src/fsharp/CompileOps.fs +++ b/src/fsharp/CompileOps.fs @@ -2075,6 +2075,7 @@ type TcConfigBuilder = mutable embeddedPDB : bool mutable embedAllSource : bool mutable embedSourceList : string list + mutable sourceLink : string mutable ignoreSymbolStoreSequencePoints : bool mutable internConstantStrings : bool @@ -2248,6 +2249,7 @@ type TcConfigBuilder = embeddedPDB = false embedAllSource = false embedSourceList = [] + sourceLink = "" ignoreSymbolStoreSequencePoints = false internConstantStrings = true extraOptimizationIterations = 0 @@ -2741,6 +2743,7 @@ type TcConfig private (data : TcConfigBuilder,validate:bool) = member x.embeddedPDB = data.embeddedPDB member x.embedAllSource = data.embedAllSource member x.embedSourceList = data.embedSourceList + member x.sourceLink = data.sourceLink member x.ignoreSymbolStoreSequencePoints = data.ignoreSymbolStoreSequencePoints member x.internConstantStrings = data.internConstantStrings member x.extraOptimizationIterations = data.extraOptimizationIterations diff --git a/src/fsharp/CompileOps.fsi b/src/fsharp/CompileOps.fsi index fc77fec23a9..4a64066b915 100755 --- a/src/fsharp/CompileOps.fsi +++ b/src/fsharp/CompileOps.fsi @@ -309,6 +309,7 @@ type TcConfigBuilder = mutable embeddedPDB : bool mutable embedAllSource : bool mutable embedSourceList : string list + mutable sourceLink : string mutable ignoreSymbolStoreSequencePoints : bool mutable internConstantStrings : bool mutable extraOptimizationIterations : int @@ -466,6 +467,7 @@ type TcConfig = member embeddedPDB : bool member embedAllSource : bool member embedSourceList : string list + member sourceLink : string member ignoreSymbolStoreSequencePoints : bool member internConstantStrings : bool member extraOptimizationIterations : int diff --git a/src/fsharp/CompileOptions.fs b/src/fsharp/CompileOptions.fs index 9a18ce46308..26fbb90b44b 100644 --- a/src/fsharp/CompileOptions.fs +++ b/src/fsharp/CompileOptions.fs @@ -525,6 +525,7 @@ let PrintOptionInfo (tcConfigB:TcConfigBuilder) = printfn " embeddedPDB. . . . . . : %+A" tcConfigB.embeddedPDB printfn " embedAllSource . . . . : %+A" tcConfigB.embedAllSource printfn " embedSourceList. . . . : %+A" tcConfigB.embedSourceList + printfn " sourceLink . . . . . . : %+A" tcConfigB.sourceLink printfn " debuginfo . . . . . . : %+A" tcConfigB.debuginfo printfn " resolutionEnvironment : %+A" tcConfigB.resolutionEnvironment printfn " product . . . . . . . : %+A" tcConfigB.productNameForBannerText @@ -672,6 +673,8 @@ let codeGenerationFlags isFsi (tcConfigB : TcConfigBuilder) = Some (FSComp.SR.optsEmbedAllSource())) CompilerOption("embed", tagFileList, OptionStringList (fun f -> tcConfigB.AddEmbeddedSourceFile f), None, Some ( FSComp.SR.optsEmbedSource())); + CompilerOption("sourcelink", tagFile, OptionString (fun f -> tcConfigB.sourceLink <- f), None, + Some ( FSComp.SR.optsSourceLink())); ] let codegen = [CompilerOption("optimize", tagNone, OptionSwitch (SetOptimizeSwitch tcConfigB) , None, diff --git a/src/fsharp/FSComp.txt b/src/fsharp/FSComp.txt index 9c5975d50aa..f7bd72a0dd3 100644 --- a/src/fsharp/FSComp.txt +++ b/src/fsharp/FSComp.txt @@ -838,7 +838,9 @@ optsWin32manifest,"Specify a Win32 manifest file" optsNowin32manifest,"Do not include the default Win32 manifest" optsEmbedAllSource,"Embed all source files in the portable PDB file" optsEmbedSource,"Embed specific source files in the portable PDB file" +optsSourceLink,"Source link information file to embed in the portable PDB file" 1501,optsEmbeddedSourceRequirePortablePDBs,"--embed switch only supported when emitting a Portable PDB (--debug:portable or --debug:embedded)" +1502,optsSourceLinkRequirePortablePDBs,"--sourcelink switch only supported when emitting a Portable PDB (--debug:portable or --debug:embedded)" optsResource,"Embed the specified managed resource" optsLinkresource,"Link the specified resource to this assembly where the resinfo format is [,[,public|private]]" optsDebugPM,"Emit debug information (Short form: -g)" diff --git a/src/fsharp/fsc.fs b/src/fsharp/fsc.fs index 46333d48d60..fe9b09f0215 100755 --- a/src/fsharp/fsc.fs +++ b/src/fsharp/fsc.fs @@ -271,8 +271,12 @@ let ProcessCommandLineFlags (tcConfigB: TcConfigBuilder,setProcessThreadLocals,a // This is where flags are interpreted by the command line fsc.exe. ParseCompilerOptions (collect, GetCoreFscCompilerOptions tcConfigB, List.tail (PostProcessCompilerArgs abbrevArgs argv)) - if (tcConfigB.embedAllSource || tcConfigB.embedSourceList |> List.length <> 0) && (not (tcConfigB.portablePDB || tcConfigB.embeddedPDB)) then - error(Error(FSComp.SR.optsEmbeddedSourceRequirePortablePDBs(),rangeCmdArgs)) + + if not (tcConfigB.portablePDB || tcConfigB.embeddedPDB) then + if tcConfigB.embedAllSource || (tcConfigB.embedSourceList |> List.length <> 0) then + error(Error(FSComp.SR.optsEmbeddedSourceRequirePortablePDBs(), rangeCmdArgs)) + if not (String.IsNullOrEmpty(tcConfigB.sourceLink)) then + error(Error(FSComp.SR.optsSourceLinkRequirePortablePDBs(),rangeCmdArgs)) let inputFiles = List.rev !inputFilesRef @@ -1748,6 +1752,7 @@ module FileWriter = embeddedPDB = tcConfig.embeddedPDB embedAllSource = tcConfig.embedAllSource embedSourceList = tcConfig.embedSourceList + sourceLink = tcConfig.sourceLink signer = GetSigner signingInfo fixupOverlappingSequencePoints = false dumpDebugInfo = tcConfig.dumpDebugInfo }, diff --git a/tests/fsharpqa/Source/CompilerOptions/fsc/help/help40.437.1033.bsl b/tests/fsharpqa/Source/CompilerOptions/fsc/help/help40.437.1033.bsl index 57209f1d262..d7f5e7eda32 100644 --- a/tests/fsharpqa/Source/CompilerOptions/fsc/help/help40.437.1033.bsl +++ b/tests/fsharpqa/Source/CompilerOptions/fsc/help/help40.437.1033.bsl @@ -59,6 +59,8 @@ Copyright (c) Microsoft Corporation. All Rights Reserved. --embed[+|-] Embed all source files in the portable PDB file --embed: Embed specific source files in the portable PDB file +--sourcelink: Source link information file to embed in the + portable PDB file --optimize[+|-] Enable optimizations (Short form: -O) --tailcalls[+|-] Enable or disable tailcalls --crossoptimize[+|-] Enable or disable cross-module optimizations diff --git a/tests/fsharpqa/Source/CompilerOptions/fsc/pdb/env.lst b/tests/fsharpqa/Source/CompilerOptions/fsc/pdb/env.lst index 938bd76d2e7..773aa533a0f 100644 --- a/tests/fsharpqa/Source/CompilerOptions/fsc/pdb/env.lst +++ b/tests/fsharpqa/Source/CompilerOptions/fsc/pdb/env.lst @@ -20,6 +20,10 @@ NOMONO SOURCE=pdb01.fs SCFLAGS="-g --out:pdbembedded.exe --debug:embedded --embe NOMONO SOURCE=pdb05.fs SCFLAGS="-g --debug:full --embed" # --embed with --debug:full is build error NOMONO SOURCE=pdb05.fs SCFLAGS="-g --debug:pdbonly --embed" # --embed with --debug:pdbonly is build error +NOMONO SOURCE=pdb05.fs SCFLAGS="-g --debug:full --embed" # --embed with --debug:full is build error +NOMONO SOURCE=pdb05.fs SCFLAGS="-g --debug:pdbonly --embed" # --embed with --debug:pdbonly is build error + + NOMONO SOURCE=pdb05.fs SCFLAGS="-g --out:pdbportable.exe --debug:full --embed:pdb05.fs # --embed:filelist with --debug:full is build error NOMONO SOURCE=pdb05.fs SCFLAGS="-g --out:pdbportable.exe --debug:pdbonly --embed:pdb05.fs" # --embed:filelist with --debug:pdbonly is build error diff --git a/tests/fsharpqa/Source/CompilerOptions/fsc/pdb/pdb06.fs b/tests/fsharpqa/Source/CompilerOptions/fsc/pdb/pdb06.fs new file mode 100644 index 00000000000..a692f1faaa9 --- /dev/null +++ b/tests/fsharpqa/Source/CompilerOptions/fsc/pdb/pdb06.fs @@ -0,0 +1,4 @@ +// #Regression #NoMT #CompilerOptions #NoMono +//.+sourcelink switch only supported when emitting a Portable PDB .+ + +exit 1 diff --git a/tests/fsharpqa/Source/CompilerOptions/fsc/pdb/source_link.json b/tests/fsharpqa/Source/CompilerOptions/fsc/pdb/source_link.json new file mode 100644 index 00000000000..eafb857151f --- /dev/null +++ b/tests/fsharpqa/Source/CompilerOptions/fsc/pdb/source_link.json @@ -0,0 +1 @@ +{"documents": { "/*" : "ffffffffffffffffffffffffffffffffffffffff/*" }} From 94becafcb535ba6a998132538350126bbc998e9a Mon Sep 17 00:00:00 2001 From: "Kevin Ransom (msft)" Date: Wed, 12 Oct 2016 09:12:23 -0700 Subject: [PATCH 11/14] Generate and embed sourcelink in pdb --- src/FSharpSource.Settings.targets | 14 +++++------ src/FSharpSource.targets | 4 +-- src/absil/ilwritepdb.fs | 25 +++++++++++++------ src/fsharp/FSComp.txt | 1 + .../FSharp.Core.Unittests.fsproj | 2 -- 5 files changed, 27 insertions(+), 19 deletions(-) diff --git a/src/FSharpSource.Settings.targets b/src/FSharpSource.Settings.targets index bc0a2aa84a8..35e8648f4e5 100644 --- a/src/FSharpSource.Settings.targets +++ b/src/FSharpSource.Settings.targets @@ -16,6 +16,9 @@ $(ToolsDir)net45\ false + + + obj\$(Configuration)\$(TargetFramework)\ @@ -26,11 +29,11 @@ full - embedded + portable false prompt - $(OtherFlags) --no-jit-optimize - $(OtherFlags) --no-jit-optimize --embed + $(OtherFlags) --no-jit-optimize + $(OtherFlags) --embed --sourcelink:$(IntermediateOutputPath)source_link.json DEBUG;TRACE;CODE_ANALYSIS;$(DefineConstants) DEBUG=True,TRACE=True,CODE_ANALYSIS=True,$(DefineConstants) false @@ -57,11 +60,6 @@ 3 - - - obj\$(Configuration)\$(TargetFramework)\ - - $(DefineConstants),VS_VERSION_DEV12=True $(DefineConstants);VS_VERSION_DEV12 diff --git a/src/FSharpSource.targets b/src/FSharpSource.targets index 0ce3d46ef65..de1b77dfbe0 100644 --- a/src/FSharpSource.targets +++ b/src/FSharpSource.targets @@ -548,7 +548,7 @@ - + $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory.TrimEnd("\")))) @@ -560,7 +560,7 @@ - + diff --git a/src/absil/ilwritepdb.fs b/src/absil/ilwritepdb.fs index 81d4232a643..57a2e51f2d1 100644 --- a/src/absil/ilwritepdb.fs +++ b/src/absil/ilwritepdb.fs @@ -252,7 +252,7 @@ let fixupOverlappingSequencePoints fixupSPs showTimes methods = Array.sortInPlaceBy fst allSps spCounts, allSps -let generatePortablePdb fixupSPs (embedAllSource:bool) (embedSourceList:string list) (_sourceLink:string) showTimes (info:PdbData) = +let generatePortablePdb fixupSPs (embedAllSource:bool) (embedSourceList:string list) (sourceLink:string) showTimes (info:PdbData) = sortMethods showTimes info let _spCounts, _allSps = fixupOverlappingSequencePoints fixupSPs showTimes info.Methods let externalRowCounts = getRowCounts info.TableRowCounts @@ -277,8 +277,9 @@ let generatePortablePdb fixupSPs (embedAllSource:bool) (embedSourceList:string l metadata.GetOrAddBlob(writer) - let corSymLanguageTypeFSharp = System.Guid(0xAB4F38C9u, 0xB6E6us, 0x43baus, 0xBEuy, 0x3Buy, 0x58uy, 0x08uy, 0x0Buy, 0x2Cuy, 0xCCuy, 0xE3uy) - let embeddedSource = System.Guid(0x0e8a571bu, 0x6926us, 0x466eus, 0xb4uy, 0xaduy, 0x8auy, 0xb0uy, 0x46uy, 0x11uy, 0xf5uy, 0xfeuy) + let corSymLanguageTypeId = System.Guid(0xAB4F38C9u, 0xB6E6us, 0x43baus, 0xBEuy, 0x3Buy, 0x58uy, 0x08uy, 0x0Buy, 0x2Cuy, 0xCCuy, 0xE3uy) + let embeddedSourceId = System.Guid(0x0e8a571bu, 0x6926us, 0x466eus, 0xb4uy, 0xaduy, 0x8auy, 0xb0uy, 0x46uy, 0x11uy, 0xf5uy, 0xfeuy) + let sourceLinkId = System.Guid(0xcc110556u, 0xa091us, 0x4d38us, 0x9fuy, 0xecuy, 0x25uy, 0xabuy, 0x9auy, 0x35uy, 0x1auy, 0x6auy) /// /// The maximum number of bytes in to write out uncompressed. @@ -319,7 +320,8 @@ let generatePortablePdb fixupSPs (embedAllSource:bool) (embedSourceList:string l Some (builder.ToImmutableArray()) let mutable index = new Dictionary(docs.Length) - metadata.SetCapacity(TableIndex.Document, docs.Length) + let docLength = docs.Length + if String.IsNullOrEmpty(sourceLink) then 1 else 0 + metadata.SetCapacity(TableIndex.Document, docLength) for doc in docs do let handle = match checkSum doc.File with @@ -328,12 +330,12 @@ let generatePortablePdb fixupSPs (embedAllSource:bool) (embedSourceList:string l (serializeDocumentName doc.File, metadata.GetOrAddGuid(hashAlg), metadata.GetOrAddBlob(checkSum.ToImmutableArray()), - metadata.GetOrAddGuid(corSymLanguageTypeFSharp)) |> metadata.AddDocument + metadata.GetOrAddGuid(corSymLanguageTypeId)) |> metadata.AddDocument match includeSource doc.File with | None -> () | Some blob -> metadata.AddCustomDebugInformation(DocumentHandle.op_Implicit(h), - metadata.GetOrAddGuid(embeddedSource), + metadata.GetOrAddGuid(embeddedSourceId), metadata.GetOrAddBlob(blob)) |> ignore h | None -> @@ -341,9 +343,18 @@ let generatePortablePdb fixupSPs (embedAllSource:bool) (embedSourceList:string l (serializeDocumentName doc.File, metadata.GetOrAddGuid(System.Guid.Empty), metadata.GetOrAddBlob(ImmutableArray.Empty), - metadata.GetOrAddGuid(corSymLanguageTypeFSharp)) |> metadata.AddDocument + metadata.GetOrAddGuid(corSymLanguageTypeId)) |> metadata.AddDocument h index.Add(doc.File, handle) + + if not (String.IsNullOrEmpty(sourceLink)) then + let fs = File.OpenRead(sourceLink) + let ms = new MemoryStream() + fs.CopyTo(ms) + metadata.AddCustomDebugInformation( + ModuleDefinitionHandle.op_Implicit(EntityHandle.ModuleDefinition), + metadata.GetOrAddGuid(sourceLinkId), + metadata.GetOrAddBlob(ms.ToArray())) |> ignore index let mutable lastLocalVariableHandle = Unchecked.defaultof diff --git a/src/fsharp/FSComp.txt b/src/fsharp/FSComp.txt index f7bd72a0dd3..7b7698c9cfd 100644 --- a/src/fsharp/FSComp.txt +++ b/src/fsharp/FSComp.txt @@ -841,6 +841,7 @@ optsEmbedSource,"Embed specific source files in the portable PDB file" optsSourceLink,"Source link information file to embed in the portable PDB file" 1501,optsEmbeddedSourceRequirePortablePDBs,"--embed switch only supported when emitting a Portable PDB (--debug:portable or --debug:embedded)" 1502,optsSourceLinkRequirePortablePDBs,"--sourcelink switch only supported when emitting a Portable PDB (--debug:portable or --debug:embedded)" +srcFileTooLarge,"Source file is too large to embed in a portable PDB" optsResource,"Embed the specified managed resource" optsLinkresource,"Link the specified resource to this assembly where the resinfo format is [,[,public|private]]" optsDebugPM,"Emit debug information (Short form: -g)" diff --git a/src/fsharp/FSharp.Core.Unittests/FSharp.Core.Unittests.fsproj b/src/fsharp/FSharp.Core.Unittests/FSharp.Core.Unittests.fsproj index ce345f5da96..2945ab3d88e 100644 --- a/src/fsharp/FSharp.Core.Unittests/FSharp.Core.Unittests.fsproj +++ b/src/fsharp/FSharp.Core.Unittests/FSharp.Core.Unittests.fsproj @@ -30,14 +30,12 @@ true - full false $(DefineConstants);DEBUG;TRACE prompt 3 - pdbonly true $(DefineConstants);TRACE prompt From ff3b8ee55e919565c991367259d7b7e52f667a54 Mon Sep 17 00:00:00 2001 From: "Kevin Ransom (msft)" Date: Wed, 12 Oct 2016 18:52:32 -0700 Subject: [PATCH 12/14] Feedback --- src/absil/ilwritepdb.fs | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/absil/ilwritepdb.fs b/src/absil/ilwritepdb.fs index a393fa1c87b..ad8411c008e 100644 --- a/src/absil/ilwritepdb.fs +++ b/src/absil/ilwritepdb.fs @@ -26,10 +26,10 @@ type BlobBuildingStream () = static let chunkSize = 32 * 1024 let builder = new BlobBuilder(chunkSize) - override this.CanWrite with get() = true - override this.CanRead with get() = false - override this.CanSeek with get() = false - override this.Length with get() = int64(builder.Count) + override this.CanWrite = true + override this.CanRead = false + override this.CanSeek = false + override this.Length = int64(builder.Count) override this.Write(buffer:byte array, offset:int, count:int) = builder.WriteBytes(buffer, offset, count) override this.WriteByte(value:byte) = builder.WriteByte(value) @@ -294,11 +294,9 @@ let generatePortablePdb fixupSPs (embedAllSource:bool) (embedSourceList:string l let documentIndex = let includeSource file = let isInList = - if embedSourceList |> List.length = 0 then false + if embedSourceList.Length = 0 then false else - match embedSourceList |> List.tryFind(fun f -> String.Compare(file, f, StringComparison.OrdinalIgnoreCase ) = 0) with - | Some _ -> true - | None -> false + embedSourceList |> List.tryFind(fun f -> String.Compare(file, f, StringComparison.OrdinalIgnoreCase ) = 0) |> Option.isSome if not embedAllSource && not isInList || not (File.Exists(file)) then None @@ -324,7 +322,7 @@ let generatePortablePdb fixupSPs (embedAllSource:bool) (embedSourceList:string l let handle = match checkSum doc.File with | Some (hashAlg, checkSum) -> - let h = + let dbgInfo = (serializeDocumentName doc.File, metadata.GetOrAddGuid(hashAlg), metadata.GetOrAddBlob(checkSum.ToImmutableArray()), @@ -332,17 +330,17 @@ let generatePortablePdb fixupSPs (embedAllSource:bool) (embedSourceList:string l match includeSource doc.File with | None -> () | Some blob -> - metadata.AddCustomDebugInformation(DocumentHandle.op_Implicit(h), + metadata.AddCustomDebugInformation(DocumentHandle.op_Implicit(dbgInfo), metadata.GetOrAddGuid(embeddedSource), metadata.GetOrAddBlob(blob)) |> ignore - h + dbgInfo | None -> - let h = + let dbgInfo = (serializeDocumentName doc.File, metadata.GetOrAddGuid(System.Guid.Empty), metadata.GetOrAddBlob(ImmutableArray.Empty), metadata.GetOrAddGuid(corSymLanguageTypeFSharp)) |> metadata.AddDocument - h + dbgInfo index.Add(doc.File, handle) index From 62905a6a619c07d39973c717f42e22c6747a5bf1 Mon Sep 17 00:00:00 2001 From: "Kevin Ransom (msft)" Date: Wed, 12 Oct 2016 20:52:15 -0700 Subject: [PATCH 13/14] Fix merge error --- src/absil/ilwritepdb.fs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/absil/ilwritepdb.fs b/src/absil/ilwritepdb.fs index 63be9d4ff07..5dde376d185 100644 --- a/src/absil/ilwritepdb.fs +++ b/src/absil/ilwritepdb.fs @@ -332,7 +332,7 @@ let generatePortablePdb fixupSPs (embedAllSource:bool) (embedSourceList:string l match includeSource doc.File with | None -> () | Some blob -> - metadata.AddCustomDebugInformation(DocumentHandle.op_Implicit(h), + metadata.AddCustomDebugInformation(DocumentHandle.op_Implicit(dbgInfo), metadata.GetOrAddGuid(embeddedSourceId), metadata.GetOrAddBlob(blob)) |> ignore dbgInfo @@ -342,7 +342,7 @@ let generatePortablePdb fixupSPs (embedAllSource:bool) (embedSourceList:string l metadata.GetOrAddGuid(System.Guid.Empty), metadata.GetOrAddBlob(ImmutableArray.Empty), metadata.GetOrAddGuid(corSymLanguageTypeId)) |> metadata.AddDocument - h + dbgInfo index.Add(doc.File, handle) if not (String.IsNullOrEmpty(sourceLink)) then From 7a95430a48b9ffec41a743dab44de8d184d72cc5 Mon Sep 17 00:00:00 2001 From: "Kevin Ransom (msft)" Date: Thu, 13 Oct 2016 21:39:35 -0700 Subject: [PATCH 14/14] Fix bad merge --- tests/fsharpqa/Source/CompilerOptions/fsc/pdb/env.lst | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/fsharpqa/Source/CompilerOptions/fsc/pdb/env.lst b/tests/fsharpqa/Source/CompilerOptions/fsc/pdb/env.lst index 773aa533a0f..938bd76d2e7 100644 --- a/tests/fsharpqa/Source/CompilerOptions/fsc/pdb/env.lst +++ b/tests/fsharpqa/Source/CompilerOptions/fsc/pdb/env.lst @@ -20,10 +20,6 @@ NOMONO SOURCE=pdb01.fs SCFLAGS="-g --out:pdbembedded.exe --debug:embedded --embe NOMONO SOURCE=pdb05.fs SCFLAGS="-g --debug:full --embed" # --embed with --debug:full is build error NOMONO SOURCE=pdb05.fs SCFLAGS="-g --debug:pdbonly --embed" # --embed with --debug:pdbonly is build error -NOMONO SOURCE=pdb05.fs SCFLAGS="-g --debug:full --embed" # --embed with --debug:full is build error -NOMONO SOURCE=pdb05.fs SCFLAGS="-g --debug:pdbonly --embed" # --embed with --debug:pdbonly is build error - - NOMONO SOURCE=pdb05.fs SCFLAGS="-g --out:pdbportable.exe --debug:full --embed:pdb05.fs # --embed:filelist with --debug:full is build error NOMONO SOURCE=pdb05.fs SCFLAGS="-g --out:pdbportable.exe --debug:pdbonly --embed:pdb05.fs" # --embed:filelist with --debug:pdbonly is build error