Skip to content

Commit 1e42fbe

Browse files
committed
Export metadata
1 parent 00c4671 commit 1e42fbe

File tree

8 files changed

+175
-2
lines changed

8 files changed

+175
-2
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/net5.0/fcs-export.dll",
12+
"args": [],
13+
"cwd": "${workspaceFolder}/fcs/fcs-export",
14+
"console": "internalConsole",
15+
"stopAtEntry": false
16+
}
17+
]
18+
}

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: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
open System.IO
2+
open System.Collections.Generic
3+
open FSharp.Compiler.CodeAnalysis
4+
5+
let readRefs (folder : string) (projectFile: string) =
6+
let runProcess (workingDir: string) (exePath: string) (args: string) =
7+
let psi = System.Diagnostics.ProcessStartInfo()
8+
psi.FileName <- exePath
9+
psi.WorkingDirectory <- workingDir
10+
psi.RedirectStandardOutput <- false
11+
psi.RedirectStandardError <- false
12+
psi.Arguments <- args
13+
psi.CreateNoWindow <- true
14+
psi.UseShellExecute <- false
15+
16+
use p = new System.Diagnostics.Process()
17+
p.StartInfo <- psi
18+
p.Start() |> ignore
19+
p.WaitForExit()
20+
21+
let exitCode = p.ExitCode
22+
exitCode, ()
23+
24+
let runCmd exePath args = runProcess folder exePath (args |> String.concat " ")
25+
let msbuildExec = Dotnet.ProjInfo.Inspect.dotnetMsbuild runCmd
26+
let result = Dotnet.ProjInfo.Inspect.getProjectInfo ignore msbuildExec Dotnet.ProjInfo.Inspect.getFscArgs projectFile
27+
match result with
28+
| Ok(Dotnet.ProjInfo.Inspect.GetResult.FscArgs x) ->
29+
x
30+
|> List.filter (fun s -> s.StartsWith("-r:"))
31+
|> List.map (fun s -> s.Replace("-r:", ""))
32+
| _ -> []
33+
34+
let mkStandardProjectReferences () =
35+
let file = "fcs-export.fsproj"
36+
let projDir = __SOURCE_DIRECTORY__
37+
readRefs projDir file
38+
39+
let mkProjectCommandLineArgsForScript (dllName, fileNames) =
40+
[| yield "--simpleresolution"
41+
yield "--noframework"
42+
yield "--debug:full"
43+
yield "--define:DEBUG"
44+
yield "--optimize-"
45+
yield "--out:" + dllName
46+
yield "--doc:test.xml"
47+
yield "--warn:3"
48+
yield "--fullpaths"
49+
yield "--flaterrors"
50+
yield "--target:library"
51+
for x in fileNames do
52+
yield x
53+
let references = mkStandardProjectReferences ()
54+
for r in references do
55+
yield "-r:" + r
56+
|]
57+
58+
let checker = FSharpChecker.Create()
59+
60+
let parseAndCheckScript (file, input) =
61+
let dllName = Path.ChangeExtension(file, ".dll")
62+
let projName = Path.ChangeExtension(file, ".fsproj")
63+
let args = mkProjectCommandLineArgsForScript (dllName, [file])
64+
printfn "file: %s" file
65+
args |> Array.iter (printfn "args: %s")
66+
let projectOptions = checker.GetProjectOptionsFromCommandLineArgs (projName, args)
67+
let parseRes, typedRes = checker.ParseAndCheckFileInProject(file, 0, input, projectOptions) |> Async.RunSynchronously
68+
69+
if parseRes.Diagnostics.Length > 0 then
70+
printfn "---> Parse Input = %A" input
71+
printfn "---> Parse Error = %A" parseRes.Diagnostics
72+
73+
match typedRes with
74+
| FSharpCheckFileAnswer.Succeeded(res) -> parseRes, res
75+
| res -> failwithf "Parsing did not finish... (%A)" res
76+
77+
[<EntryPoint>]
78+
let main argv =
79+
ignore argv
80+
printfn "Exporting metadata..."
81+
let file = "/temp/test.fsx"
82+
let input = "let a = 42"
83+
let sourceText = FSharp.Compiler.Text.SourceText.ofString input
84+
// parse script just to export metadata
85+
let parseRes, typedRes = parseAndCheckScript(file, sourceText)
86+
printfn "Exporting is done."
87+
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>net5.0</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.1" /> -->
21+
<PackageReference Include="Fable.Core" Version="3.2.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\net5.0\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\net5.0\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
@@ -1892,6 +1892,38 @@ and [<Sealed>] TcImports(tcConfigP: TcConfigProvider, initialResolutions: TcAsse
18921892
global_g <- Some tcGlobals
18931893
#endif
18941894
frameworkTcImports.SetTcGlobals tcGlobals
1895+
1896+
#if EXPORT_METADATA
1897+
let metadataPath = __SOURCE_DIRECTORY__ + "/../../temp/metadata/"
1898+
let writeMetadata (dllInfo: ImportedBinary) =
1899+
let outfile = Path.GetFullPath(metadataPath + Path.GetFileName(dllInfo.FileName))
1900+
let ilModule = dllInfo.RawMetadata.TryGetILModuleDef().Value
1901+
try
1902+
let args: AbstractIL.ILBinaryWriter.options = {
1903+
ilg = ilGlobals
1904+
pdbfile = None
1905+
emitTailcalls = false
1906+
deterministic = false
1907+
showTimes = false
1908+
portablePDB = false
1909+
embeddedPDB = false
1910+
embedAllSource = false
1911+
embedSourceList = []
1912+
sourceLink = ""
1913+
checksumAlgorithm = tcConfig.checksumAlgorithm
1914+
signer = None
1915+
dumpDebugInfo = false
1916+
pathMap = tcConfig.pathMap }
1917+
AbstractIL.ILBinaryWriter.WriteILBinary (outfile, args, ilModule, id)
1918+
with Failure msg ->
1919+
printfn "Export error: %s" msg
1920+
1921+
let! dllinfos, _ccuinfos = frameworkTcImports.RegisterAndImportReferencedAssemblies (ctok, tcResolutions.GetAssemblyResolutions())
1922+
dllinfos |> List.iter writeMetadata
1923+
let! dllinfos, _ccuinfos = frameworkTcImports.RegisterAndImportReferencedAssemblies (ctok, tcAltResolutions.GetAssemblyResolutions())
1924+
dllinfos |> List.iter writeMetadata
1925+
#endif
1926+
18951927
return tcGlobals, frameworkTcImports
18961928
}
18971929

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
<NoWarn>$(NoWarn);44;45;54;55;57;61;62;69;65;75;1204;2003;NU5125</NoWarn>
99
<AssemblyName>FSharp.Compiler.Service</AssemblyName>
1010
<AllowCrossTargeting>true</AllowCrossTargeting>
11+
<DefineConstants>$(DefineConstants);EXPORT_METADATA</DefineConstants>
1112
<DefineConstants>$(DefineConstants);COMPILER</DefineConstants>
1213
<DefineConstants>$(DefineConstants);ENABLE_MONO_SUPPORT</DefineConstants>
1314
<OtherFlags>$(OtherFlags) /warnon:3218 /warnon:1182 /warnon:3390 --maxerrors:20 --extraoptimizationloops:1 --times</OtherFlags>

src/fsharp/absil/ilwrite.fs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2445,6 +2445,9 @@ let GenMethodDefAsRow cenv env midx (md: ILMethodDef) =
24452445
if cenv.entrypoint <> None then failwith "duplicate entrypoint"
24462446
else cenv.entrypoint <- Some (true, midx)
24472447
let codeAddr =
2448+
#if EXPORT_METADATA
2449+
0x0000
2450+
#else
24482451
(match md.Body with
24492452
| MethodBody.IL ilmbodyLazy ->
24502453
let ilmbody = ilmbodyLazy.Value
@@ -2491,6 +2494,7 @@ let GenMethodDefAsRow cenv env midx (md: ILMethodDef) =
24912494
| MethodBody.Native ->
24922495
failwith "cannot write body of native method - Abstract IL cannot roundtrip mixed native/managed binaries"
24932496
| _ -> 0x0000)
2497+
#endif
24942498

24952499
UnsharedRow
24962500
[| ULong codeAddr
@@ -3511,6 +3515,7 @@ and writeBinaryAndReportMappingsAux (stream: Stream, leaveStreamOpen: bool,
35113515
match signer, modul.Manifest with
35123516
| Some _, _ -> signer
35133517
| _, None -> signer
3518+
#if !EXPORT_METADATA
35143519
| None, Some {PublicKey=Some pubkey} ->
35153520
(dprintn "Note: The output assembly will be delay-signed using the original public"
35163521
dprintn "Note: key. In order to load it you will need to either sign it with"
@@ -3520,6 +3525,7 @@ and writeBinaryAndReportMappingsAux (stream: Stream, leaveStreamOpen: bool,
35203525
dprintn "Note: private key when converting the assembly, assuming you have access to"
35213526
dprintn "Note: it."
35223527
Some (ILStrongNameSigner.OpenPublicKey pubkey))
3528+
#endif
35233529
| _ -> signer
35243530

35253531
let modul =

0 commit comments

Comments
 (0)