Skip to content

Commit 4f4a8a8

Browse files
committed
Export metadata
1 parent 05b0569 commit 4f4a8a8

File tree

9 files changed

+178
-4
lines changed

9 files changed

+178
-4
lines changed

.vscode/launch.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
// Use IntelliSense to learn about possible attributes.
3+
// Hover to view descriptions of existing attributes.
4+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5+
"version": "0.2.0",
6+
"configurations": [
7+
{
8+
"name": ".NET Core Launch (console)",
9+
"type": "coreclr",
10+
"request": "launch",
11+
"program": "${workspaceFolder}/artifacts/bin/fcs-export/Debug/netcoreapp3.1/fcs-export.dll",
12+
"args": [],
13+
"cwd": "${workspaceFolder}/fcs/fcs-export",
14+
"console": "internalConsole",
15+
"stopAtEntry": false
16+
}
17+
]
18+
}

eng/Versions.props

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@
6868
<!-- https://pkgs.dev.azure.com/azure-public/vside/_packaging/vs-buildservices/nuget/v3/index.json; --></RestoreSources>
6969
<!-- System.* packages -->
7070
<SystemBuffersVersion>4.5.1</SystemBuffersVersion>
71-
<SystemCollectionsImmutableVersion>5.0.0-preview.8.20407.11</SystemCollectionsImmutableVersion>
71+
<SystemCollectionsImmutableVersion>1.7.1</SystemCollectionsImmutableVersion>
7272
<SystemConsoleVersion>4.3.0</SystemConsoleVersion>
7373
<SystemDataSqlClientPackageVersion>4.3.0</SystemDataSqlClientPackageVersion>
7474
<SystemDesignVersion>4.0.0</SystemDesignVersion>
@@ -81,7 +81,7 @@
8181
<SystemNetRequestsVersion>4.3.0</SystemNetRequestsVersion>
8282
<SystemNetSecurityVersion>4.3.0</SystemNetSecurityVersion>
8383
<SystemReflectionEmitVersion>4.3.0</SystemReflectionEmitVersion>
84-
<SystemReflectionMetadataVersion>5.0.0-preview.8.20407.11</SystemReflectionMetadataVersion>
84+
<SystemReflectionMetadataVersion>1.8.1</SystemReflectionMetadataVersion>
8585
<SystemReflectionTypeExtensionsVersion>4.3.0</SystemReflectionTypeExtensionsVersion>
8686
<SystemRuntimeCachingVersion>1.5.0</SystemRuntimeCachingVersion>
8787
<SystemRuntimeVersion>4.3.0</SystemRuntimeVersion>

fcs/build.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/usr/bin/env bash
2+
3+
dotnet build -c Release src/buildtools/buildtools.proj
4+
dotnet build -c Release src/fsharp/FSharp.Compiler.Service
5+
dotnet run -c Release -p fcs/fcs-export

fcs/fcs-export/Program.fs

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
open System.IO
2+
open System.Collections.Generic
3+
open FSharp.Compiler
4+
open FSharp.Compiler.SourceCodeServices
5+
6+
let readRefs (folder : string) (projectFile: string) =
7+
let runProcess (workingDir: string) (exePath: string) (args: string) =
8+
let psi = System.Diagnostics.ProcessStartInfo()
9+
psi.FileName <- exePath
10+
psi.WorkingDirectory <- workingDir
11+
psi.RedirectStandardOutput <- false
12+
psi.RedirectStandardError <- false
13+
psi.Arguments <- args
14+
psi.CreateNoWindow <- true
15+
psi.UseShellExecute <- false
16+
17+
use p = new System.Diagnostics.Process()
18+
p.StartInfo <- psi
19+
p.Start() |> ignore
20+
p.WaitForExit()
21+
22+
let exitCode = p.ExitCode
23+
exitCode, ()
24+
25+
let runCmd exePath args = runProcess folder exePath (args |> String.concat " ")
26+
let msbuildExec = Dotnet.ProjInfo.Inspect.dotnetMsbuild runCmd
27+
let result = Dotnet.ProjInfo.Inspect.getProjectInfo ignore msbuildExec Dotnet.ProjInfo.Inspect.getFscArgs projectFile
28+
match result with
29+
| Ok(Dotnet.ProjInfo.Inspect.GetResult.FscArgs x) ->
30+
x
31+
|> List.filter (fun s -> s.StartsWith("-r:"))
32+
|> List.map (fun s -> s.Replace("-r:", ""))
33+
| _ -> []
34+
35+
let mkStandardProjectReferences () =
36+
let file = "fcs-export.fsproj"
37+
let projDir = __SOURCE_DIRECTORY__
38+
readRefs projDir file
39+
40+
let mkProjectCommandLineArgsForScript (dllName, fileNames) =
41+
[| yield "--simpleresolution"
42+
yield "--noframework"
43+
yield "--debug:full"
44+
yield "--define:DEBUG"
45+
yield "--optimize-"
46+
yield "--out:" + dllName
47+
yield "--doc:test.xml"
48+
yield "--warn:3"
49+
yield "--fullpaths"
50+
yield "--flaterrors"
51+
yield "--target:library"
52+
for x in fileNames do
53+
yield x
54+
let references = mkStandardProjectReferences ()
55+
for r in references do
56+
yield "-r:" + r
57+
|]
58+
59+
let checker = FSharpChecker.Create()
60+
61+
let parseAndCheckScript (file, input) =
62+
let dllName = Path.ChangeExtension(file, ".dll")
63+
let projName = Path.ChangeExtension(file, ".fsproj")
64+
let args = mkProjectCommandLineArgsForScript (dllName, [file])
65+
printfn "file: %s" file
66+
args |> Array.iter (printfn "args: %s")
67+
let projectOptions = checker.GetProjectOptionsFromCommandLineArgs (projName, args)
68+
let parseRes, typedRes = checker.ParseAndCheckFileInProject(file, 0, input, projectOptions) |> Async.RunSynchronously
69+
70+
if parseRes.Errors.Length > 0 then
71+
printfn "---> Parse Input = %A" input
72+
printfn "---> Parse Error = %A" parseRes.Errors
73+
74+
match typedRes with
75+
| FSharpCheckFileAnswer.Succeeded(res) -> parseRes, res
76+
| res -> failwithf "Parsing did not finish... (%A)" res
77+
78+
[<EntryPoint>]
79+
let main argv =
80+
ignore argv
81+
printfn "Exporting metadata..."
82+
let file = "/temp/test.fsx"
83+
let input = "let a = 42"
84+
let sourceText = FSharp.Compiler.Text.SourceText.ofString input
85+
// parse script just to export metadata
86+
let parseRes, typedRes = parseAndCheckScript(file, sourceText)
87+
printfn "Exporting is done."
88+
0

fcs/fcs-export/fcs-export.fsproj

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>netcoreapp3.1</TargetFramework>
6+
<DisableImplicitFSharpCoreReference>true</DisableImplicitFSharpCoreReference>
7+
</PropertyGroup>
8+
9+
<ItemGroup>
10+
<Compile Include="Program.fs" />
11+
</ItemGroup>
12+
13+
<ItemGroup>
14+
<!-- <ProjectReference Include="../../src/fsharp/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj" /> -->
15+
<Reference Include="../../artifacts/bin/FSharp.Compiler.Service/Release/netstandard2.0/FSharp.Core.dll" />
16+
<Reference Include="../../artifacts/bin/FSharp.Compiler.Service/Release/netstandard2.0/FSharp.Compiler.Service.dll" />
17+
</ItemGroup>
18+
19+
<ItemGroup>
20+
<!-- <PackageReference Include="FSharp.Core" Version="5.0.0" /> -->
21+
<PackageReference Include="Fable.Core" Version="3.1.6" />
22+
<PackageReference Include="Dotnet.ProjInfo" Version="0.44.0" />
23+
</ItemGroup>
24+
</Project>

src/buildtools/buildtools.targets

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
BeforeTargets="CoreCompile">
2121

2222
<PropertyGroup>
23-
<FsLexPath Condition="'$(FsLexPath)' == ''">$(ArtifactsDir)\Bootstrap\fslex\fslex.dll</FsLexPath>
23+
<FsLexPath Condition="'$(FsLexPath)' == ''">$(ArtifactsDir)\bin\fslex\Release\netcoreapp3.1\fslex.dll</FsLexPath>
2424
</PropertyGroup>
2525

2626
<!-- Create the output directory -->
@@ -44,7 +44,7 @@
4444
BeforeTargets="CoreCompile">
4545

4646
<PropertyGroup>
47-
<FsYaccPath Condition="'$(FsYaccPath)' == ''">$(ArtifactsDir)\Bootstrap\fsyacc\fsyacc.dll</FsYaccPath>
47+
<FsYaccPath Condition="'$(FsYaccPath)' == ''">$(ArtifactsDir)\bin\fsyacc\Release\netcoreapp3.1\fsyacc.dll</FsYaccPath>
4848
</PropertyGroup>
4949

5050
<!-- Create the output directory -->

src/fsharp/CompilerImports.fs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1779,6 +1779,38 @@ and [<Sealed>] TcImports(tcConfigP: TcConfigProvider, initialResolutions: TcAsse
17791779
global_g <- Some tcGlobals
17801780
#endif
17811781
frameworkTcImports.SetTcGlobals tcGlobals
1782+
1783+
#if EXPORT_METADATA
1784+
let metadataPath = __SOURCE_DIRECTORY__ + "/../../temp/metadata/"
1785+
let writeMetadata (dllInfo: ImportedBinary) =
1786+
let outfile = Path.GetFullPath(metadataPath + Path.GetFileName(dllInfo.FileName))
1787+
let ilModule = dllInfo.RawMetadata.TryGetILModuleDef().Value
1788+
try
1789+
let args: ILBinaryWriter.options = {
1790+
ilg = ilGlobals
1791+
pdbfile = None
1792+
emitTailcalls = false
1793+
deterministic = false
1794+
showTimes = false
1795+
portablePDB = false
1796+
embeddedPDB = false
1797+
embedAllSource = false
1798+
embedSourceList = []
1799+
sourceLink = ""
1800+
checksumAlgorithm = tcConfig.checksumAlgorithm
1801+
signer = None
1802+
dumpDebugInfo = false
1803+
pathMap = tcConfig.pathMap }
1804+
ILBinaryWriter.WriteILBinary (outfile, args, ilModule, id)
1805+
with Failure msg ->
1806+
printfn "Export error: %s" msg
1807+
1808+
let! dllinfos, _ccuinfos = frameworkTcImports.RegisterAndImportReferencedAssemblies (ctok, tcResolutions.GetAssemblyResolutions())
1809+
dllinfos |> List.iter writeMetadata
1810+
let! dllinfos, _ccuinfos = frameworkTcImports.RegisterAndImportReferencedAssemblies (ctok, tcAltResolutions.GetAssemblyResolutions())
1811+
dllinfos |> List.iter writeMetadata
1812+
#endif
1813+
17821814
return tcGlobals, frameworkTcImports
17831815
}
17841816

src/fsharp/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
<TargetFrameworks>netstandard2.0</TargetFrameworks>
66
<NoWarn>$(NoWarn);44;62;69;65;54;61;75;62;9;2003;NU5125</NoWarn>
77
<AllowCrossTargeting>true</AllowCrossTargeting>
8+
<DefineConstants>$(DefineConstants);EXPORT_METADATA</DefineConstants>
89
<DefineConstants>$(DefineConstants);COMPILER_SERVICE_AS_DLL</DefineConstants>
910
<DefineConstants>$(DefineConstants);COMPILER</DefineConstants>
1011
<DefineConstants>$(DefineConstants);ENABLE_MONO_SUPPORT</DefineConstants>

src/fsharp/absil/ilwrite.fs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2444,6 +2444,9 @@ let GenMethodDefAsRow cenv env midx (md: ILMethodDef) =
24442444
if cenv.entrypoint <> None then failwith "duplicate entrypoint"
24452445
else cenv.entrypoint <- Some (true, midx)
24462446
let codeAddr =
2447+
#if EXPORT_METADATA
2448+
0x0000
2449+
#else
24472450
(match md.Body.Contents with
24482451
| MethodBody.IL ilmbody ->
24492452
let addr = cenv.nextCodeAddr
@@ -2489,6 +2492,7 @@ let GenMethodDefAsRow cenv env midx (md: ILMethodDef) =
24892492
| MethodBody.Native ->
24902493
failwith "cannot write body of native method - Abstract IL cannot roundtrip mixed native/managed binaries"
24912494
| _ -> 0x0000)
2495+
#endif
24922496

24932497
UnsharedRow
24942498
[| ULong codeAddr
@@ -3465,6 +3469,7 @@ let writeBinaryAndReportMappings (outfile,
34653469
match signer, modul.Manifest with
34663470
| Some _, _ -> signer
34673471
| _, None -> signer
3472+
#if !EXPORT_METADATA
34683473
| None, Some {PublicKey=Some pubkey} ->
34693474
(dprintn "Note: The output assembly will be delay-signed using the original public"
34703475
dprintn "Note: key. In order to load it you will need to either sign it with"
@@ -3474,6 +3479,7 @@ let writeBinaryAndReportMappings (outfile,
34743479
dprintn "Note: private key when converting the assembly, assuming you have access to"
34753480
dprintn "Note: it."
34763481
Some (ILStrongNameSigner.OpenPublicKey pubkey))
3482+
#endif
34773483
| _ -> signer
34783484

34793485
let modul =

0 commit comments

Comments
 (0)