Skip to content

Commit 0d6f0fa

Browse files
committed
Export metadata
1 parent 0dac9c0 commit 0d6f0fa

File tree

8 files changed

+160
-4
lines changed

8 files changed

+160
-4
lines changed

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="../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="4.7.2" /> -->
21+
<PackageReference Include="Fable.Core" Version="3.1.6" />
22+
<PackageReference Include="Dotnet.ProjInfo" Version="0.44.0" />
23+
</ItemGroup>
24+
</Project>

global.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
{
22
"sdk": {
3-
"version": "3.1.302"
3+
"version": "3.1.402"
44
},
55
"tools": {
6-
"dotnet": "3.1.302",
6+
"dotnet": "3.1.402",
77
"vs": {
88
"version": "16.4",
99
"components": [

src/absil/ilwrite.fs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2439,6 +2439,9 @@ let GenMethodDefAsRow cenv env midx (md: ILMethodDef) =
24392439
if cenv.entrypoint <> None then failwith "duplicate entrypoint"
24402440
else cenv.entrypoint <- Some (true, midx)
24412441
let codeAddr =
2442+
#if EXPORT_METADATA
2443+
0x0000
2444+
#else
24422445
(match md.Body.Contents with
24432446
| MethodBody.IL ilmbody ->
24442447
let addr = cenv.nextCodeAddr
@@ -2484,6 +2487,7 @@ let GenMethodDefAsRow cenv env midx (md: ILMethodDef) =
24842487
| MethodBody.Native ->
24852488
failwith "cannot write body of native method - Abstract IL cannot roundtrip mixed native/managed binaries"
24862489
| _ -> 0x0000)
2490+
#endif
24872491

24882492
UnsharedRow
24892493
[| ULong codeAddr
@@ -3460,6 +3464,7 @@ let writeBinaryAndReportMappings (outfile,
34603464
match signer, modul.Manifest with
34613465
| Some _, _ -> signer
34623466
| _, None -> signer
3467+
#if !EXPORT_METADATA
34633468
| None, Some {PublicKey=Some pubkey} ->
34643469
(dprintn "Note: The output assembly will be delay-signed using the original public"
34653470
dprintn "Note: key. In order to load it you will need to either sign it with"
@@ -3469,6 +3474,7 @@ let writeBinaryAndReportMappings (outfile,
34693474
dprintn "Note: private key when converting the assembly, assuming you have access to"
34703475
dprintn "Note: it."
34713476
Some (ILStrongNameSigner.OpenPublicKey pubkey))
3477+
#endif
34723478
| _ -> signer
34733479

34743480
let modul =

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
@@ -1782,6 +1782,38 @@ and [<Sealed>] TcImports(tcConfigP: TcConfigProvider, initialResolutions: TcAsse
17821782
global_g <- Some tcGlobals
17831783
#endif
17841784
frameworkTcImports.SetTcGlobals tcGlobals
1785+
1786+
#if EXPORT_METADATA
1787+
let metadataPath = __SOURCE_DIRECTORY__ + "/../../temp/metadata/"
1788+
let writeMetadata (dllInfo: ImportedBinary) =
1789+
let outfile = Path.GetFullPath(metadataPath + Path.GetFileName(dllInfo.FileName))
1790+
let ilModule = dllInfo.RawMetadata.TryGetILModuleDef().Value
1791+
try
1792+
let args: ILBinaryWriter.options = {
1793+
ilg = ilGlobals
1794+
pdbfile = None
1795+
emitTailcalls = false
1796+
deterministic = false
1797+
showTimes = false
1798+
portablePDB = false
1799+
embeddedPDB = false
1800+
embedAllSource = false
1801+
embedSourceList = []
1802+
sourceLink = ""
1803+
checksumAlgorithm = tcConfig.checksumAlgorithm
1804+
signer = None
1805+
dumpDebugInfo = false
1806+
pathMap = tcConfig.pathMap }
1807+
ILBinaryWriter.WriteILBinary (outfile, args, ilModule, id)
1808+
with Failure msg ->
1809+
printfn "Export error: %s" msg
1810+
1811+
let! dllinfos, _ccuinfos = frameworkTcImports.RegisterAndImportReferencedAssemblies (ctok, tcResolutions.GetAssemblyResolutions())
1812+
dllinfos |> List.iter writeMetadata
1813+
let! dllinfos, _ccuinfos = frameworkTcImports.RegisterAndImportReferencedAssemblies (ctok, tcAltResolutions.GetAssemblyResolutions())
1814+
dllinfos |> List.iter writeMetadata
1815+
#endif
1816+
17851817
return tcGlobals, frameworkTcImports
17861818
}
17871819

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>

0 commit comments

Comments
 (0)