Support resx file embedding

- Added resgen tool and takes .resx and makes .resources
- Write .resources and .rsp to obj folder
This commit is contained in:
David Fowler 2015-10-18 21:07:48 -07:00
parent 6ba4781c4f
commit fc64db1f73
9 changed files with 195 additions and 10 deletions

View file

@ -36,6 +36,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "dnxhost", "dnxhost", "{0773
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.Tools.Compiler.Csc", "src\Microsoft.DotNet.Tools.Compiler.Csc\Microsoft.DotNet.Tools.Compiler.Csc.xproj", "{B559378C-FC03-45FA-893C-71784F28E0A2}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.Tools.Resgen", "src\Microsoft.DotNet.Tools.Resgen\Microsoft.DotNet.Tools.Resgen.xproj", "{585FC6F6-48E0-4EA5-8015-0264614E97C0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -66,6 +68,10 @@ Global
{B559378C-FC03-45FA-893C-71784F28E0A2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B559378C-FC03-45FA-893C-71784F28E0A2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B559378C-FC03-45FA-893C-71784F28E0A2}.Release|Any CPU.Build.0 = Release|Any CPU
{585FC6F6-48E0-4EA5-8015-0264614E97C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{585FC6F6-48E0-4EA5-8015-0264614E97C0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{585FC6F6-48E0-4EA5-8015-0264614E97C0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{585FC6F6-48E0-4EA5-8015-0264614E97C0}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -78,5 +84,6 @@ Global
{303677D5-7312-4C3F-BAEE-BEB1A9BD9FE6} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F}
{07731125-77D7-4B83-B7B2-C865C6B8A6E8} = {13F8C30C-1011-459C-82B2-0ACDD73EDA18}
{B559378C-FC03-45FA-893C-71784F28E0A2} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F}
{585FC6F6-48E0-4EA5-8015-0264614E97C0} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F}
EndGlobalSection
EndGlobal

View file

@ -60,6 +60,8 @@ rc=$?; if [[ $rc != 0 ]]; then exit $rc; fi
$STAGE0_PUBLISH --framework dnxcore50 --runtime $RID --output "$STAGE1_DIR" "$REPOROOT/src/Microsoft.DotNet.Tools.Compiler.Csc"
rc=$?; if [[ $rc != 0 ]]; then exit $rc; fi
$STAGE0_PUBLISH --framework dnxcore50 --runtime $RID --output "$STAGE1_DIR" "$REPOROOT/src/Microsoft.DotNet.Tools.Publish"
rc=$?; if [[ $rc != 0 ]]; then exit $rc; fi
$STAGE0_PUBLISH --framework dnxcore50 --runtime $RID --output "$STAGE1_DIR" "$REPOROOT/src/Microsoft.DotNet.Tools.Resgen"
# Add stage1 to the path and use it to build stage2
export PATH=$STAGE1_DIR:$PATH
@ -73,3 +75,5 @@ dotnet publish --framework dnxcore50 --runtime $RID --output "$STAGE2_DIR" "$REP
rc=$?; if [[ $rc != 0 ]]; then exit $rc; fi
dotnet publish --framework dnxcore50 --runtime $RID --output "$STAGE2_DIR" "$REPOROOT/src/Microsoft.DotNet.Tools.Publish"
rc=$?; if [[ $rc != 0 ]]; then exit $rc; fi
dotnet publish --framework dnxcore50 --runtime $RID --output "$STAGE2_DIR" "$REPOROOT/src/Microsoft.DotNet.Tools.Resgen"
rc=$?; if [[ $rc != 0 ]]; then exit $rc; fi

View file

@ -59,6 +59,10 @@ echo Building stage1 dotnet-publish.exe ...
dotnet-publish --framework dnxcore50 --runtime %RID% --output "%STAGE1_DIR%" "%REPOROOT%\src\Microsoft.DotNet.Tools.Publish"
if errorlevel 1 goto fail
echo Building stage1 dotnet-publish.exe ...
dotnet-publish --framework dnxcore50 --runtime %RID% --output "%STAGE1_DIR%" "%REPOROOT%\src\Microsoft.DotNet.Tools.Resgen"
if errorlevel 1 goto fail
echo Re-building dotnet tools with the bootstrapped version
REM This should move into a proper build script of some kind once we are bootstrapped
set PATH=%STAGE1_DIR%;%PATH%
@ -85,6 +89,10 @@ echo Building stage2 dotnet-publish.exe ...
dotnet publish --framework dnxcore50 --runtime %RID% --output "%STAGE2_DIR%" "%REPOROOT%\src\Microsoft.DotNet.Tools.Publish"
if errorlevel 1 goto fail
echo Building stage2 dotnet-publish.exe ...
dotnet publish --framework dnxcore50 --runtime %RID% --output "%STAGE2_DIR%" "%REPOROOT%\src\Microsoft.DotNet.Tools.Resgen"
if errorlevel 1 goto fail
echo Bootstrapped dotnet to %STAGE2_DIR%
popd

View file

@ -14,6 +14,7 @@ namespace Microsoft.DotNet.Cli.Utils
public static readonly string CoreRunName = "corerun" + ExeSuffix;
public static readonly string DefaultConfiguration = "Debug";
public static readonly string BinDirectoryName = "bin";
public static readonly string ObjDirectoryName = "obj";
public static readonly string HostsPathEnvironmentVariable = "DOTNET_CLR_HOSTS_PATH";
public static readonly string CSCPathEnvironmentVariable = "DOTNET_CSC_PATH";

View file

@ -145,11 +145,22 @@ namespace Microsoft.DotNet.Tools.Compiler
context.TargetFramework.GetTwoDigitShortFolderName());
}
string intermediateOutputPath = Path.Combine(
context.ProjectFile.ProjectDirectory,
Constants.ObjDirectoryName,
configuration,
context.TargetFramework.GetTwoDigitShortFolderName());
if (!Directory.Exists(outputPath))
{
Directory.CreateDirectory(outputPath);
}
if (!Directory.Exists(intermediateOutputPath))
{
Directory.CreateDirectory(intermediateOutputPath);
}
// Get compilation options
var compilationOptions = context.ProjectFile.GetCompilerOptions(context.TargetFramework, configuration);
var outputName = Path.Combine(outputPath, context.ProjectFile.Name + ".dll");
@ -184,13 +195,16 @@ namespace Microsoft.DotNet.Tools.Compiler
// Add project source files
compilerArgs.AddRange(context.ProjectFile.Files.SourceFiles);
AddResources(context.ProjectFile, compilerArgs);
if (!AddResources(context.ProjectFile, compilerArgs, intermediateOutputPath))
{
return false;
}
// TODO: Read this from the project
const string compiler = "csc";
// Write RSP file
var rsp = Path.Combine(outputPath, $"dotnet-compile.{compiler}.rsp");
var rsp = Path.Combine(intermediateOutputPath, $"dotnet-compile.{compiler}.rsp");
File.WriteAllLines(rsp, compilerArgs);
var result = Command.Create($"dotnet-compile-{compiler}", $"\"{rsp}\"")
@ -202,14 +216,14 @@ namespace Microsoft.DotNet.Tools.Compiler
if (result.ExitCode == 0)
{
Reporter.Output.WriteLine($"Compiled to {outputPath} successfully!".Green().Bold());
Reporter.Output.WriteLine($"Compiled {context.ProjectFile.Name} successfully!".Green().Bold());
return true;
}
return false;
}
private static void AddResources(Project project, List<string> compilerArgs)
private static bool AddResources(Project project, List<string> compilerArgs, string intermediateOutputPath)
{
string root = PathUtility.EnsureTrailingSlash(project.ProjectDirectory);
@ -220,12 +234,6 @@ namespace Microsoft.DotNet.Tools.Compiler
var resourcePath = resourceFile.Key;
if (ResourcePathUtility.IsResxResourceFile(resourcePath))
{
// TODO: Handle resource files
continue;
}
if (string.IsNullOrEmpty(resourceFile.Value))
{
// No logical name, so use the file name
@ -241,8 +249,36 @@ namespace Microsoft.DotNet.Tools.Compiler
var name = CreateCSharpManifestResourceName.CreateManifestName(resourceName, rootNamespace);
var fileName = resourcePath;
if (ResourcePathUtility.IsResxResourceFile(fileName))
{
var ext = Path.GetExtension(fileName);
if (string.Equals(ext, ".resx", StringComparison.OrdinalIgnoreCase))
{
// {file}.resx -> {file}.resources
var resourcesFile = Path.Combine(intermediateOutputPath, name);
var result = Command.Create("resgen", $"{fileName} {resourcesFile}")
.ForwardStdErr()
.ForwardStdOut()
.RunAsync()
.GetAwaiter()
.GetResult();
if (result.ExitCode != 0)
{
return false;
}
// Use this as the resource name instead
fileName = resourcesFile;
}
}
compilerArgs.Add($"-resource:\"{fileName}\",{name}");
}
return true;
}
private static ISet<ProjectDescription> Sort(Dictionary<string, ProjectDescription> projects)

View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>585fc6f6-48e0-4ea5-8015-0264614e97c0</ProjectGuid>
<RootNamespace>Microsoft.DotNet.Tools.Resgen</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

View file

@ -0,0 +1,54 @@
using System.IO;
using System.Resources;
using System.Xml.Linq;
using Microsoft.Dnx.Runtime.Common.CommandLine;
using Microsoft.DotNet.Cli.Utils;
namespace Microsoft.DotNet.Tools.Resgen
{
public class Program
{
public static int Main(string[] args)
{
DebugHelper.HandleDebugSwitch(ref args);
var app = new CommandLineApplication();
app.Name = "resgen";
app.FullName = "Resource compiler";
app.Description = "Microsoft (R) .NET Resource Generator";
app.HelpOption("-h|--help");
var inputFile = app.Argument("<input>", "The .resx file to transform");
var outputFile = app.Argument("<output>", "The .resources file to produce");
app.OnExecute(() =>
{
WriteResourcesFile(inputFile.Value, outputFile.Value);
return 0;
});
return app.Execute(args);
}
private static void WriteResourcesFile(string resxFilePath, string outputFile)
{
using (var fs = File.OpenRead(resxFilePath))
using (var outfs = File.Create(outputFile))
{
var document = XDocument.Load(fs);
var rw = new ResourceWriter(outfs);
foreach (var e in document.Root.Elements("data"))
{
string name = e.Attribute("name").Value;
string value = e.Element("value").Value;
rw.AddResource(name, value);
}
rw.Generate();
}
}
}
}

View file

@ -0,0 +1,23 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Microsoft.DotNet.Tools.Resgen")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Microsoft.DotNet.Tools.Resgen")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("585fc6f6-48e0-4ea5-8015-0264614e97c0")]

View file

@ -0,0 +1,32 @@
{
"name": "resgen",
"version": "1.0.0-*",
"compilationOptions": {
"emitEntryPoint": true
},
"commands": {
"resgen": "Microsoft.DotNet.Tools.Resgen"
},
"dependencies": {
"Microsoft.NETCore.TestHost": "1.0.0-*",
"Microsoft.NETCore.Runtime": "1.0.1-*",
"System.Console": "4.0.0-*",
"System.Collections": "4.0.11-*",
"System.Linq": "4.0.1-*",
"System.Diagnostics.Process": "4.1.0-*",
"System.IO.FileSystem": "4.0.1-*",
"Microsoft.DotNet.Cli.Utils": {
"type": "build",
"version": "1.0.0-*"
},
"Microsoft.Extensions.CommandLineUtils.Sources": {
"type": "build",
"version": "1.0.0-*"
},
"System.Xml.XDocument": "4.0.11-*",
"System.Resources.ReaderWriter": "4.0.0-*"
},
"frameworks": {
"dnxcore50": { }
}
}