Add a shared runtime aware host

And use it in dotnet-compile
This commit is contained in:
Andrew Stanton-Nurse 2015-10-21 15:21:14 -07:00
parent d8ab5357fd
commit e70a169b28
45 changed files with 1881 additions and 152 deletions

3
.gitignore vendored
View file

@ -35,3 +35,6 @@ TestResults/
# Profiler result files, just in case they are left lying around :) # Profiler result files, just in case they are left lying around :)
.vs/ .vs/
# CMake generated files
cmake/

View file

@ -38,40 +38,174 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.Tools.Resg
EndProject EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.ProjectModel", "src\Microsoft.DotNet.ProjectModel\Microsoft.DotNet.ProjectModel.xproj", "{303677D5-7312-4C3F-BAEE-BEB1A9BD9FE6}" Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.ProjectModel", "src\Microsoft.DotNet.ProjectModel\Microsoft.DotNet.ProjectModel.xproj", "{303677D5-7312-4C3F-BAEE-BEB1A9BD9FE6}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "corehost", "corehost", "{C0CA389D-A35E-4082-BC05-598C9D6301BC}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ALL_BUILD", "src\corehost\cmake\ALL_BUILD.vcxproj", "{8DF8403E-0DDC-4E6C-9930-4C1006E96B2F}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "corehost", "src\corehost\cmake\corehost.vcxproj", "{3673DD4B-F7D3-40A1-A756-F8354A5B74CD}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZERO_CHECK", "src\corehost\cmake\ZERO_CHECK.vcxproj", "{5D67FC6A-6392-4807-97BC-D13CA0FF5E6D}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
MinSizeRel|Any CPU = MinSizeRel|Any CPU
MinSizeRel|x64 = MinSizeRel|x64
Release|Any CPU = Release|Any CPU Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
RelWithDebInfo|Any CPU = RelWithDebInfo|Any CPU
RelWithDebInfo|x64 = RelWithDebInfo|x64
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{60CF7E6C-D6C8-439D-B7B7-D8A27E29BE2C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {60CF7E6C-D6C8-439D-B7B7-D8A27E29BE2C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{60CF7E6C-D6C8-439D-B7B7-D8A27E29BE2C}.Debug|Any CPU.Build.0 = Debug|Any CPU {60CF7E6C-D6C8-439D-B7B7-D8A27E29BE2C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{60CF7E6C-D6C8-439D-B7B7-D8A27E29BE2C}.Debug|x64.ActiveCfg = Debug|Any CPU
{60CF7E6C-D6C8-439D-B7B7-D8A27E29BE2C}.Debug|x64.Build.0 = Debug|Any CPU
{60CF7E6C-D6C8-439D-B7B7-D8A27E29BE2C}.MinSizeRel|Any CPU.ActiveCfg = Release|Any CPU
{60CF7E6C-D6C8-439D-B7B7-D8A27E29BE2C}.MinSizeRel|Any CPU.Build.0 = Release|Any CPU
{60CF7E6C-D6C8-439D-B7B7-D8A27E29BE2C}.MinSizeRel|x64.ActiveCfg = Release|Any CPU
{60CF7E6C-D6C8-439D-B7B7-D8A27E29BE2C}.MinSizeRel|x64.Build.0 = Release|Any CPU
{60CF7E6C-D6C8-439D-B7B7-D8A27E29BE2C}.Release|Any CPU.ActiveCfg = Release|Any CPU {60CF7E6C-D6C8-439D-B7B7-D8A27E29BE2C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{60CF7E6C-D6C8-439D-B7B7-D8A27E29BE2C}.Release|Any CPU.Build.0 = Release|Any CPU {60CF7E6C-D6C8-439D-B7B7-D8A27E29BE2C}.Release|Any CPU.Build.0 = Release|Any CPU
{60CF7E6C-D6C8-439D-B7B7-D8A27E29BE2C}.Release|x64.ActiveCfg = Release|Any CPU
{60CF7E6C-D6C8-439D-B7B7-D8A27E29BE2C}.Release|x64.Build.0 = Release|Any CPU
{60CF7E6C-D6C8-439D-B7B7-D8A27E29BE2C}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
{60CF7E6C-D6C8-439D-B7B7-D8A27E29BE2C}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
{60CF7E6C-D6C8-439D-B7B7-D8A27E29BE2C}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
{60CF7E6C-D6C8-439D-B7B7-D8A27E29BE2C}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
{61B7C351-C77D-43F7-B56F-BB1440178E10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {61B7C351-C77D-43F7-B56F-BB1440178E10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{61B7C351-C77D-43F7-B56F-BB1440178E10}.Debug|Any CPU.Build.0 = Debug|Any CPU {61B7C351-C77D-43F7-B56F-BB1440178E10}.Debug|Any CPU.Build.0 = Debug|Any CPU
{61B7C351-C77D-43F7-B56F-BB1440178E10}.Debug|x64.ActiveCfg = Debug|Any CPU
{61B7C351-C77D-43F7-B56F-BB1440178E10}.Debug|x64.Build.0 = Debug|Any CPU
{61B7C351-C77D-43F7-B56F-BB1440178E10}.MinSizeRel|Any CPU.ActiveCfg = Release|Any CPU
{61B7C351-C77D-43F7-B56F-BB1440178E10}.MinSizeRel|Any CPU.Build.0 = Release|Any CPU
{61B7C351-C77D-43F7-B56F-BB1440178E10}.MinSizeRel|x64.ActiveCfg = Release|Any CPU
{61B7C351-C77D-43F7-B56F-BB1440178E10}.MinSizeRel|x64.Build.0 = Release|Any CPU
{61B7C351-C77D-43F7-B56F-BB1440178E10}.Release|Any CPU.ActiveCfg = Release|Any CPU {61B7C351-C77D-43F7-B56F-BB1440178E10}.Release|Any CPU.ActiveCfg = Release|Any CPU
{61B7C351-C77D-43F7-B56F-BB1440178E10}.Release|Any CPU.Build.0 = Release|Any CPU {61B7C351-C77D-43F7-B56F-BB1440178E10}.Release|Any CPU.Build.0 = Release|Any CPU
{61B7C351-C77D-43F7-B56F-BB1440178E10}.Release|x64.ActiveCfg = Release|Any CPU
{61B7C351-C77D-43F7-B56F-BB1440178E10}.Release|x64.Build.0 = Release|Any CPU
{61B7C351-C77D-43F7-B56F-BB1440178E10}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
{61B7C351-C77D-43F7-B56F-BB1440178E10}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
{61B7C351-C77D-43F7-B56F-BB1440178E10}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
{61B7C351-C77D-43F7-B56F-BB1440178E10}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
{0A309227-A9D8-4DDF-88DD-326B57B04378}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0A309227-A9D8-4DDF-88DD-326B57B04378}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0A309227-A9D8-4DDF-88DD-326B57B04378}.Debug|Any CPU.Build.0 = Debug|Any CPU {0A309227-A9D8-4DDF-88DD-326B57B04378}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0A309227-A9D8-4DDF-88DD-326B57B04378}.Debug|x64.ActiveCfg = Debug|Any CPU
{0A309227-A9D8-4DDF-88DD-326B57B04378}.Debug|x64.Build.0 = Debug|Any CPU
{0A309227-A9D8-4DDF-88DD-326B57B04378}.MinSizeRel|Any CPU.ActiveCfg = Release|Any CPU
{0A309227-A9D8-4DDF-88DD-326B57B04378}.MinSizeRel|Any CPU.Build.0 = Release|Any CPU
{0A309227-A9D8-4DDF-88DD-326B57B04378}.MinSizeRel|x64.ActiveCfg = Release|Any CPU
{0A309227-A9D8-4DDF-88DD-326B57B04378}.MinSizeRel|x64.Build.0 = Release|Any CPU
{0A309227-A9D8-4DDF-88DD-326B57B04378}.Release|Any CPU.ActiveCfg = Release|Any CPU {0A309227-A9D8-4DDF-88DD-326B57B04378}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0A309227-A9D8-4DDF-88DD-326B57B04378}.Release|Any CPU.Build.0 = Release|Any CPU {0A309227-A9D8-4DDF-88DD-326B57B04378}.Release|Any CPU.Build.0 = Release|Any CPU
{0A309227-A9D8-4DDF-88DD-326B57B04378}.Release|x64.ActiveCfg = Release|Any CPU
{0A309227-A9D8-4DDF-88DD-326B57B04378}.Release|x64.Build.0 = Release|Any CPU
{0A309227-A9D8-4DDF-88DD-326B57B04378}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
{0A309227-A9D8-4DDF-88DD-326B57B04378}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
{0A309227-A9D8-4DDF-88DD-326B57B04378}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
{0A309227-A9D8-4DDF-88DD-326B57B04378}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
{391D6AD6-0FD5-4E1E-A4C8-6B5439D197B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {391D6AD6-0FD5-4E1E-A4C8-6B5439D197B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{391D6AD6-0FD5-4E1E-A4C8-6B5439D197B5}.Debug|Any CPU.Build.0 = Debug|Any CPU {391D6AD6-0FD5-4E1E-A4C8-6B5439D197B5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{391D6AD6-0FD5-4E1E-A4C8-6B5439D197B5}.Debug|x64.ActiveCfg = Debug|Any CPU
{391D6AD6-0FD5-4E1E-A4C8-6B5439D197B5}.Debug|x64.Build.0 = Debug|Any CPU
{391D6AD6-0FD5-4E1E-A4C8-6B5439D197B5}.MinSizeRel|Any CPU.ActiveCfg = Release|Any CPU
{391D6AD6-0FD5-4E1E-A4C8-6B5439D197B5}.MinSizeRel|Any CPU.Build.0 = Release|Any CPU
{391D6AD6-0FD5-4E1E-A4C8-6B5439D197B5}.MinSizeRel|x64.ActiveCfg = Release|Any CPU
{391D6AD6-0FD5-4E1E-A4C8-6B5439D197B5}.MinSizeRel|x64.Build.0 = Release|Any CPU
{391D6AD6-0FD5-4E1E-A4C8-6B5439D197B5}.Release|Any CPU.ActiveCfg = Release|Any CPU {391D6AD6-0FD5-4E1E-A4C8-6B5439D197B5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{391D6AD6-0FD5-4E1E-A4C8-6B5439D197B5}.Release|Any CPU.Build.0 = Release|Any CPU {391D6AD6-0FD5-4E1E-A4C8-6B5439D197B5}.Release|Any CPU.Build.0 = Release|Any CPU
{391D6AD6-0FD5-4E1E-A4C8-6B5439D197B5}.Release|x64.ActiveCfg = Release|Any CPU
{391D6AD6-0FD5-4E1E-A4C8-6B5439D197B5}.Release|x64.Build.0 = Release|Any CPU
{391D6AD6-0FD5-4E1E-A4C8-6B5439D197B5}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
{391D6AD6-0FD5-4E1E-A4C8-6B5439D197B5}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
{391D6AD6-0FD5-4E1E-A4C8-6B5439D197B5}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
{391D6AD6-0FD5-4E1E-A4C8-6B5439D197B5}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
{B559378C-FC03-45FA-893C-71784F28E0A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B559378C-FC03-45FA-893C-71784F28E0A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B559378C-FC03-45FA-893C-71784F28E0A2}.Debug|Any CPU.Build.0 = Debug|Any CPU {B559378C-FC03-45FA-893C-71784F28E0A2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B559378C-FC03-45FA-893C-71784F28E0A2}.Debug|x64.ActiveCfg = Debug|Any CPU
{B559378C-FC03-45FA-893C-71784F28E0A2}.Debug|x64.Build.0 = Debug|Any CPU
{B559378C-FC03-45FA-893C-71784F28E0A2}.MinSizeRel|Any CPU.ActiveCfg = Release|Any CPU
{B559378C-FC03-45FA-893C-71784F28E0A2}.MinSizeRel|Any CPU.Build.0 = Release|Any CPU
{B559378C-FC03-45FA-893C-71784F28E0A2}.MinSizeRel|x64.ActiveCfg = Release|Any CPU
{B559378C-FC03-45FA-893C-71784F28E0A2}.MinSizeRel|x64.Build.0 = Release|Any CPU
{B559378C-FC03-45FA-893C-71784F28E0A2}.Release|Any CPU.ActiveCfg = Release|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 {B559378C-FC03-45FA-893C-71784F28E0A2}.Release|Any CPU.Build.0 = Release|Any CPU
{B559378C-FC03-45FA-893C-71784F28E0A2}.Release|x64.ActiveCfg = Release|Any CPU
{B559378C-FC03-45FA-893C-71784F28E0A2}.Release|x64.Build.0 = Release|Any CPU
{B559378C-FC03-45FA-893C-71784F28E0A2}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
{B559378C-FC03-45FA-893C-71784F28E0A2}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
{B559378C-FC03-45FA-893C-71784F28E0A2}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
{B559378C-FC03-45FA-893C-71784F28E0A2}.RelWithDebInfo|x64.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.ActiveCfg = Debug|Any CPU
{585FC6F6-48E0-4EA5-8015-0264614E97C0}.Debug|Any CPU.Build.0 = Debug|Any CPU {585FC6F6-48E0-4EA5-8015-0264614E97C0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{585FC6F6-48E0-4EA5-8015-0264614E97C0}.Debug|x64.ActiveCfg = Debug|Any CPU
{585FC6F6-48E0-4EA5-8015-0264614E97C0}.Debug|x64.Build.0 = Debug|Any CPU
{585FC6F6-48E0-4EA5-8015-0264614E97C0}.MinSizeRel|Any CPU.ActiveCfg = Release|Any CPU
{585FC6F6-48E0-4EA5-8015-0264614E97C0}.MinSizeRel|Any CPU.Build.0 = Release|Any CPU
{585FC6F6-48E0-4EA5-8015-0264614E97C0}.MinSizeRel|x64.ActiveCfg = Release|Any CPU
{585FC6F6-48E0-4EA5-8015-0264614E97C0}.MinSizeRel|x64.Build.0 = Release|Any CPU
{585FC6F6-48E0-4EA5-8015-0264614E97C0}.Release|Any CPU.ActiveCfg = Release|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 {585FC6F6-48E0-4EA5-8015-0264614E97C0}.Release|Any CPU.Build.0 = Release|Any CPU
{585FC6F6-48E0-4EA5-8015-0264614E97C0}.Release|x64.ActiveCfg = Release|Any CPU
{585FC6F6-48E0-4EA5-8015-0264614E97C0}.Release|x64.Build.0 = Release|Any CPU
{585FC6F6-48E0-4EA5-8015-0264614E97C0}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
{585FC6F6-48E0-4EA5-8015-0264614E97C0}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
{585FC6F6-48E0-4EA5-8015-0264614E97C0}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
{585FC6F6-48E0-4EA5-8015-0264614E97C0}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
{303677D5-7312-4C3F-BAEE-BEB1A9BD9FE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {303677D5-7312-4C3F-BAEE-BEB1A9BD9FE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{303677D5-7312-4C3F-BAEE-BEB1A9BD9FE6}.Debug|Any CPU.Build.0 = Debug|Any CPU {303677D5-7312-4C3F-BAEE-BEB1A9BD9FE6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{303677D5-7312-4C3F-BAEE-BEB1A9BD9FE6}.Debug|x64.ActiveCfg = Debug|Any CPU
{303677D5-7312-4C3F-BAEE-BEB1A9BD9FE6}.Debug|x64.Build.0 = Debug|Any CPU
{303677D5-7312-4C3F-BAEE-BEB1A9BD9FE6}.MinSizeRel|Any CPU.ActiveCfg = Release|Any CPU
{303677D5-7312-4C3F-BAEE-BEB1A9BD9FE6}.MinSizeRel|Any CPU.Build.0 = Release|Any CPU
{303677D5-7312-4C3F-BAEE-BEB1A9BD9FE6}.MinSizeRel|x64.ActiveCfg = Release|Any CPU
{303677D5-7312-4C3F-BAEE-BEB1A9BD9FE6}.MinSizeRel|x64.Build.0 = Release|Any CPU
{303677D5-7312-4C3F-BAEE-BEB1A9BD9FE6}.Release|Any CPU.ActiveCfg = Release|Any CPU {303677D5-7312-4C3F-BAEE-BEB1A9BD9FE6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{303677D5-7312-4C3F-BAEE-BEB1A9BD9FE6}.Release|Any CPU.Build.0 = Release|Any CPU {303677D5-7312-4C3F-BAEE-BEB1A9BD9FE6}.Release|Any CPU.Build.0 = Release|Any CPU
{303677D5-7312-4C3F-BAEE-BEB1A9BD9FE6}.Release|x64.ActiveCfg = Release|Any CPU
{303677D5-7312-4C3F-BAEE-BEB1A9BD9FE6}.Release|x64.Build.0 = Release|Any CPU
{303677D5-7312-4C3F-BAEE-BEB1A9BD9FE6}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
{303677D5-7312-4C3F-BAEE-BEB1A9BD9FE6}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
{303677D5-7312-4C3F-BAEE-BEB1A9BD9FE6}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
{303677D5-7312-4C3F-BAEE-BEB1A9BD9FE6}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
{8DF8403E-0DDC-4E6C-9930-4C1006E96B2F}.Debug|Any CPU.ActiveCfg = Debug|x64
{8DF8403E-0DDC-4E6C-9930-4C1006E96B2F}.Debug|x64.ActiveCfg = Debug|x64
{8DF8403E-0DDC-4E6C-9930-4C1006E96B2F}.Debug|x64.Build.0 = Debug|x64
{8DF8403E-0DDC-4E6C-9930-4C1006E96B2F}.MinSizeRel|Any CPU.ActiveCfg = MinSizeRel|x64
{8DF8403E-0DDC-4E6C-9930-4C1006E96B2F}.MinSizeRel|x64.ActiveCfg = MinSizeRel|x64
{8DF8403E-0DDC-4E6C-9930-4C1006E96B2F}.MinSizeRel|x64.Build.0 = MinSizeRel|x64
{8DF8403E-0DDC-4E6C-9930-4C1006E96B2F}.Release|Any CPU.ActiveCfg = Release|x64
{8DF8403E-0DDC-4E6C-9930-4C1006E96B2F}.Release|x64.ActiveCfg = Release|x64
{8DF8403E-0DDC-4E6C-9930-4C1006E96B2F}.Release|x64.Build.0 = Release|x64
{8DF8403E-0DDC-4E6C-9930-4C1006E96B2F}.RelWithDebInfo|Any CPU.ActiveCfg = RelWithDebInfo|x64
{8DF8403E-0DDC-4E6C-9930-4C1006E96B2F}.RelWithDebInfo|x64.ActiveCfg = RelWithDebInfo|x64
{8DF8403E-0DDC-4E6C-9930-4C1006E96B2F}.RelWithDebInfo|x64.Build.0 = RelWithDebInfo|x64
{3673DD4B-F7D3-40A1-A756-F8354A5B74CD}.Debug|Any CPU.ActiveCfg = Debug|x64
{3673DD4B-F7D3-40A1-A756-F8354A5B74CD}.Debug|x64.ActiveCfg = Debug|x64
{3673DD4B-F7D3-40A1-A756-F8354A5B74CD}.Debug|x64.Build.0 = Debug|x64
{3673DD4B-F7D3-40A1-A756-F8354A5B74CD}.MinSizeRel|Any CPU.ActiveCfg = MinSizeRel|x64
{3673DD4B-F7D3-40A1-A756-F8354A5B74CD}.MinSizeRel|x64.ActiveCfg = MinSizeRel|x64
{3673DD4B-F7D3-40A1-A756-F8354A5B74CD}.MinSizeRel|x64.Build.0 = MinSizeRel|x64
{3673DD4B-F7D3-40A1-A756-F8354A5B74CD}.Release|Any CPU.ActiveCfg = Release|x64
{3673DD4B-F7D3-40A1-A756-F8354A5B74CD}.Release|x64.ActiveCfg = Release|x64
{3673DD4B-F7D3-40A1-A756-F8354A5B74CD}.Release|x64.Build.0 = Release|x64
{3673DD4B-F7D3-40A1-A756-F8354A5B74CD}.RelWithDebInfo|Any CPU.ActiveCfg = RelWithDebInfo|x64
{3673DD4B-F7D3-40A1-A756-F8354A5B74CD}.RelWithDebInfo|x64.ActiveCfg = RelWithDebInfo|x64
{3673DD4B-F7D3-40A1-A756-F8354A5B74CD}.RelWithDebInfo|x64.Build.0 = RelWithDebInfo|x64
{5D67FC6A-6392-4807-97BC-D13CA0FF5E6D}.Debug|Any CPU.ActiveCfg = Debug|x64
{5D67FC6A-6392-4807-97BC-D13CA0FF5E6D}.Debug|x64.ActiveCfg = Debug|x64
{5D67FC6A-6392-4807-97BC-D13CA0FF5E6D}.Debug|x64.Build.0 = Debug|x64
{5D67FC6A-6392-4807-97BC-D13CA0FF5E6D}.MinSizeRel|Any CPU.ActiveCfg = MinSizeRel|x64
{5D67FC6A-6392-4807-97BC-D13CA0FF5E6D}.MinSizeRel|x64.ActiveCfg = MinSizeRel|x64
{5D67FC6A-6392-4807-97BC-D13CA0FF5E6D}.MinSizeRel|x64.Build.0 = MinSizeRel|x64
{5D67FC6A-6392-4807-97BC-D13CA0FF5E6D}.Release|Any CPU.ActiveCfg = Release|x64
{5D67FC6A-6392-4807-97BC-D13CA0FF5E6D}.Release|x64.ActiveCfg = Release|x64
{5D67FC6A-6392-4807-97BC-D13CA0FF5E6D}.Release|x64.Build.0 = Release|x64
{5D67FC6A-6392-4807-97BC-D13CA0FF5E6D}.RelWithDebInfo|Any CPU.ActiveCfg = RelWithDebInfo|x64
{5D67FC6A-6392-4807-97BC-D13CA0FF5E6D}.RelWithDebInfo|x64.ActiveCfg = RelWithDebInfo|x64
{5D67FC6A-6392-4807-97BC-D13CA0FF5E6D}.RelWithDebInfo|x64.Build.0 = RelWithDebInfo|x64
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@ -85,5 +219,9 @@ Global
{B559378C-FC03-45FA-893C-71784F28E0A2} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F} {B559378C-FC03-45FA-893C-71784F28E0A2} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F}
{585FC6F6-48E0-4EA5-8015-0264614E97C0} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F} {585FC6F6-48E0-4EA5-8015-0264614E97C0} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F}
{303677D5-7312-4C3F-BAEE-BEB1A9BD9FE6} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F} {303677D5-7312-4C3F-BAEE-BEB1A9BD9FE6} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F}
{C0CA389D-A35E-4082-BC05-598C9D6301BC} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F}
{8DF8403E-0DDC-4E6C-9930-4C1006E96B2F} = {C0CA389D-A35E-4082-BC05-598C9D6301BC}
{3673DD4B-F7D3-40A1-A756-F8354A5B74CD} = {C0CA389D-A35E-4082-BC05-598C9D6301BC}
{5D67FC6A-6392-4807-97BC-D13CA0FF5E6D} = {C0CA389D-A35E-4082-BC05-598C9D6301BC}
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal

View file

@ -1,7 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# #
# $1 is passed to package to enable deb or pkg packaging # $1 is passed to package to enable deb or pkg packaging
set -e set -e
SOURCE="${BASH_SOURCE[0]}" SOURCE="${BASH_SOURCE[0]}"

View file

@ -66,4 +66,3 @@ if [ -z "$RID" ]; then
exit 1 exit 1
fi fi
fi fi

View file

@ -15,20 +15,37 @@ set TFM=dnxcore50
set DNX_DIR=%REPOROOT%\artifacts\%RID%\dnx set DNX_DIR=%REPOROOT%\artifacts\%RID%\dnx
set STAGE1_DIR=%REPOROOT%\artifacts\%RID%\stage1 set STAGE1_DIR=%REPOROOT%\artifacts\%RID%\stage1
set STAGE2_DIR=%REPOROOT%\artifacts\%RID%\stage2 set STAGE2_DIR=%REPOROOT%\artifacts\%RID%\stage2
set HOST_DIR=%REPOROOT%\artifacts\%RID%\corehost
set START_PATH=%PATH% set START_PATH=%PATH%
if "%CONFIGURATION%" equ "" set CONFIGURATION=Debug
call %~dp0dnvm2.cmd upgrade -a dotnet_stage0 call %~dp0dnvm2.cmd upgrade -a dotnet_stage0
if errorlevel 1 goto fail if errorlevel 1 goto fail
REM Gross! But CMD has no other way to do this :( REM Gross! But CMD has no other way to do this :(
where dotnet > %temp%\dotnet-cli-build-temp.tmp where dotnet > "%temp%\dotnet-cli-build-temp.tmp"
set /P DOTNET_PATH=<%temp%\dotnet-cli-build-temp.tmp set /P DOTNET_PATH= < "%temp%\dotnet-cli-build-temp.tmp"
pushd %DOTNET_PATH%\.. pushd "%DOTNET_PATH%\.."
set STAGE0_DIR=%CD% set STAGE0_DIR=%CD%
set DNX_ROOT=%STAGE0_DIR%\dnx set DNX_ROOT=%STAGE0_DIR%\dnx
popd popd
if exist %STAGE1_DIR% rd /s /q %STAGE1_DIR% echo Building corehost
set CMAKE_OUTPUT=%~dp0..\src\corehost\cmake
if not exist "%CMAKE_OUTPUT%" mkdir "%CMAKE_OUTPUT%"
pushd "%CMAKE_OUTPUT%"
cmake .. -G "Visual Studio 14 2015 Win64"
if %errorlevel% neq 0 exit /b %errorlevel%
msbuild ALL_BUILD.vcxproj /p:Configuration="%CONFIGURATION%"
if exist "%HOST_DIR%" rd /s /q "%HOST_DIR%"
mkdir "%HOST_DIR%"
copy "%CONFIGURATION%\*" "%HOST_DIR%"
popd
if exist "%STAGE1_DIR%" rd /s /q "%STAGE1_DIR%"
echo Running 'dotnet restore' to restore packages echo Running 'dotnet restore' to restore packages
call dotnet restore "%REPOROOT%" call dotnet restore "%REPOROOT%"
@ -37,25 +54,29 @@ if errorlevel 1 goto fail
echo Building basic dotnet tools using older dotnet SDK version echo Building basic dotnet tools using older dotnet SDK version
echo Building stage1 dotnet.exe ... echo Building stage1 dotnet.exe ...
dotnet publish --framework %TFM% --runtime %RID% --output "%STAGE1_DIR%" "%REPOROOT%\src\Microsoft.DotNet.Cli" dotnet publish --framework "%TFM%" --runtime "%RID%" --output "%STAGE1_DIR%" --configuration "%CONFIGURATION%" "%REPOROOT%\src\Microsoft.DotNet.Cli"
if errorlevel 1 goto fail if errorlevel 1 goto fail
echo Building stage1 dotnet-compile.exe ... echo Building stage1 dotnet-compile.exe ...
dotnet publish --framework %TFM% --runtime %RID% --output "%STAGE1_DIR%" "%REPOROOT%\src\Microsoft.DotNet.Tools.Compiler" dotnet publish --framework "%TFM%" --runtime "%RID%" --output "%STAGE1_DIR%" --configuration "%CONFIGURATION%" "%REPOROOT%\src\Microsoft.DotNet.Tools.Compiler"
if errorlevel 1 goto fail if errorlevel 1 goto fail
echo Building stage1 dotnet-compile-csc.exe ... echo Building stage1 dotnet-compile-csc.exe ...
dotnet publish --framework %TFM% --runtime %RID% --output "%STAGE1_DIR%" "%REPOROOT%\src\Microsoft.DotNet.Tools.Compiler.Csc" dotnet publish --framework "%TFM%" --runtime "%RID%" --output "%STAGE1_DIR%" --configuration "%CONFIGURATION%" "%REPOROOT%\src\Microsoft.DotNet.Tools.Compiler.Csc"
if errorlevel 1 goto fail if errorlevel 1 goto fail
echo Building stage1 dotnet-publish.exe ... echo Building stage1 dotnet-publish.exe ...
dotnet publish --framework %TFM% --runtime %RID% --output "%STAGE1_DIR%" "%REPOROOT%\src\Microsoft.DotNet.Tools.Publish" dotnet publish --framework "%TFM%" --runtime "%RID%" --output "%STAGE1_DIR%" --configuration "%CONFIGURATION%" "%REPOROOT%\src\Microsoft.DotNet.Tools.Publish"
if errorlevel 1 goto fail if errorlevel 1 goto fail
echo Building stage1 dotnet-publish.exe ... echo Building stage1 dotnet-publish.exe ...
dotnet publish --framework %TFM% --runtime %RID% --output "%STAGE1_DIR%" "%REPOROOT%\src\Microsoft.DotNet.Tools.Resgen" dotnet publish --framework "%TFM%" --runtime "%RID%" --output "%STAGE1_DIR%" --configuration "%CONFIGURATION%" "%REPOROOT%\src\Microsoft.DotNet.Tools.Resgen"
if errorlevel 1 goto fail if errorlevel 1 goto fail
REM deploy corehost.exe to the output
copy "%HOST_DIR%\corehost.exe" "%STAGE1_DIR%"
if exist "%HOST_DIR%\corehost.pdb" copy "%HOST_DIR%\corehost.pdb" "%STAGE1_DIR%"
echo Re-building dotnet tools with the bootstrapped version 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 REM This should move into a proper build script of some kind once we are bootstrapped
set PATH=%STAGE1_DIR%;%START_PATH% set PATH=%STAGE1_DIR%;%START_PATH%
@ -63,34 +84,38 @@ set PATH=%STAGE1_DIR%;%START_PATH%
if exist %STAGE2_DIR% rd /s /q %STAGE2_DIR% if exist %STAGE2_DIR% rd /s /q %STAGE2_DIR%
echo Building stage2 dotnet.exe ... echo Building stage2 dotnet.exe ...
dotnet publish --framework %TFM% --runtime %RID% --output "%STAGE2_DIR%" "%REPOROOT%\src\Microsoft.DotNet.Cli" dotnet publish --framework "%TFM%" --runtime "%RID%" --output "%STAGE2_DIR%" --configuration "%CONFIGURATION%" "%REPOROOT%\src\Microsoft.DotNet.Cli"
if errorlevel 1 goto fail if errorlevel 1 goto fail
echo Building stage2 dotnet-compile.exe ... echo Building stage2 dotnet-compile.exe ...
dotnet publish --framework %TFM% --runtime %RID% --output "%STAGE2_DIR%" "%REPOROOT%\src\Microsoft.DotNet.Tools.Compiler" dotnet publish --framework "%TFM%" --runtime "%RID%" --output "%STAGE2_DIR%" --configuration "%CONFIGURATION%" "%REPOROOT%\src\Microsoft.DotNet.Tools.Compiler"
if errorlevel 1 goto fail if errorlevel 1 goto fail
echo Building stage2 dotnet-compile-csc.exe ... echo Building stage2 dotnet-compile-csc.exe ...
dotnet publish --framework %TFM% --runtime %RID% --output "%STAGE2_DIR%" "%REPOROOT%\src\Microsoft.DotNet.Tools.Compiler.Csc" dotnet publish --framework "%TFM%" --runtime "%RID%" --output "%STAGE2_DIR%" --configuration "%CONFIGURATION%" "%REPOROOT%\src\Microsoft.DotNet.Tools.Compiler.Csc"
if errorlevel 1 goto fail if errorlevel 1 goto fail
echo Building stage2 dotnet-publish.exe ... echo Building stage2 dotnet-publish.exe ...
dotnet publish --framework %TFM% --runtime %RID% --output "%STAGE2_DIR%" "%REPOROOT%\src\Microsoft.DotNet.Tools.Publish" dotnet publish --framework "%TFM%" --runtime "%RID%" --output "%STAGE2_DIR%" --configuration "%CONFIGURATION%" "%REPOROOT%\src\Microsoft.DotNet.Tools.Publish"
if errorlevel 1 goto fail if errorlevel 1 goto fail
echo Building stage2 dotnet-publish.exe ... echo Building stage2 dotnet-publish.exe ...
dotnet publish --framework %TFM% --runtime %RID% --output "%STAGE2_DIR%" "%REPOROOT%\src\Microsoft.DotNet.Tools.Resgen" dotnet publish --framework "%TFM%" --runtime "%RID%" --output "%STAGE2_DIR%" --configuration "%CONFIGURATION%" "%REPOROOT%\src\Microsoft.DotNet.Tools.Resgen"
if errorlevel 1 goto fail if errorlevel 1 goto fail
REM deploy corehost.exe to the output
copy "%HOST_DIR%/corehost.exe" "%STAGE2_DIR%"
if exist "%HOST_DIR%/corehost.pdb" copy "%HOST_DIR/corehost.pdb" "%STAGE2_DIR%"
echo Crossgening Roslyn compiler ... echo Crossgening Roslyn compiler ...
call %~dp0crossgen/crossgen_roslyn.cmd %STAGE2_DIR% call "%~dp0crossgen/crossgen_roslyn.cmd" "%STAGE2_DIR%"
if errorlevel 1 goto fail if errorlevel 1 goto fail
REM Copy DNX in to stage2 REM Copy DNX in to stage2
xcopy /s /q %DNX_ROOT% %STAGE2_DIR%\dnx\ xcopy /s /q "%DNX_ROOT%" "%STAGE2_DIR%\dnx\"
REM Copy the dotnet-restore script REM Copy the dotnet-restore script
copy %~dp0dotnet-restore.cmd %STAGE2_DIR%\dotnet-restore.cmd copy "%~dp0dotnet-restore.cmd" "%STAGE2_DIR%\dotnet-restore.cmd"
REM Smoke-test the output REM Smoke-test the output
set PATH=%STAGE2_DIR%;%START_PATH% set PATH=%STAGE2_DIR%;%START_PATH%

View file

@ -9,9 +9,23 @@ while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symli
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done done
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
REPOROOT="$( cd -P "$DIR/.." && pwd )"
source "$DIR/_common.sh" source "$DIR/_common.sh"
OUTPUT_ROOT=$REPOROOT/artifacts/$RID
DNX_DIR=$OUTPUT_ROOT/dnx
STAGE1_DIR=$OUTPUT_ROOT/stage1
STAGE2_DIR=$OUTPUT_ROOT/stage2
HOST_DIR=$OUTPUT_ROOT/corehost
if ! type -p cmake >/dev/null; then
error "cmake is required to build the native host 'corehost'"
error "OS X w/Homebrew: 'brew install cmake'"
error "Ubuntu: 'sudo apt-get install cmake'"
exit 1
fi
[ -z "$CONFIGURATION" ] && CONFIGURATION=Debug [ -z "$CONFIGURATION" ] && CONFIGURATION=Debug
# TODO: Replace this with a dotnet generation # TODO: Replace this with a dotnet generation
@ -21,13 +35,8 @@ REPOROOT="$( cd -P "$DIR/.." && pwd )"
START_PATH=$PATH START_PATH=$PATH
OUTPUT_ROOT=$REPOROOT/artifacts/$RID
DNX_DIR=$OUTPUT_ROOT/dnx
STAGE1_DIR=$OUTPUT_ROOT/stage1
STAGE2_DIR=$OUTPUT_ROOT/stage2
banner "Installing stage0" banner "Installing stage0"
[ -d "~/.dotnet" ] || mkdir -p "~/.dotnet"
source $DIR/dnvm2.sh source $DIR/dnvm2.sh
dnvm upgrade -a dotnet_stage0 dnvm upgrade -a dotnet_stage0
DNX_ROOT="$(dirname $(which dotnet))/dnx" DNX_ROOT="$(dirname $(which dotnet))/dnx"
@ -39,6 +48,18 @@ dotnet restore "$REPOROOT" --runtime osx.10.10-x64 --runtime ubuntu.14.04-x64 --
# Clean up stage1 # Clean up stage1
[ -d "$STAGE1_DIR" ] && rm -Rf "$STAGE1_DIR" [ -d "$STAGE1_DIR" ] && rm -Rf "$STAGE1_DIR"
banner "Building corehost"
pushd "$REPOROOT/src/corehost" 2>&1 >/dev/null
[ -d "cmake/$RID" ] || mkdir -p "cmake/$RID"
cd "cmake/$RID"
cmake ../.. -G "Unix Makefiles" -DCMAKE_BUILD_TYPE:STRING=$CONFIGURATION
make
# Publish to artifacts
[ -d "$HOST_DIR" ] || mkdir -p $HOST_DIR
cp "$REPOROOT/src/corehost/cmake/$RID/corehost" $HOST_DIR
popd 2>&1 >/dev/null
banner "Building stage1 using downloaded stage0" banner "Building stage1 using downloaded stage0"
dotnet publish --framework "$TFM" --runtime $RID --output "$STAGE1_DIR" --configuration "$CONFIGURATION" "$REPOROOT/src/Microsoft.DotNet.Cli" dotnet publish --framework "$TFM" --runtime $RID --output "$STAGE1_DIR" --configuration "$CONFIGURATION" "$REPOROOT/src/Microsoft.DotNet.Cli"
dotnet publish --framework "$TFM" --runtime $RID --output "$STAGE1_DIR" --configuration "$CONFIGURATION" "$REPOROOT/src/Microsoft.DotNet.Tools.Compiler" dotnet publish --framework "$TFM" --runtime $RID --output "$STAGE1_DIR" --configuration "$CONFIGURATION" "$REPOROOT/src/Microsoft.DotNet.Tools.Compiler"
@ -46,12 +67,12 @@ dotnet publish --framework "$TFM" --runtime $RID --output "$STAGE1_DIR" --config
dotnet publish --framework "$TFM" --runtime $RID --output "$STAGE1_DIR" --configuration "$CONFIGURATION" "$REPOROOT/src/Microsoft.DotNet.Tools.Publish" dotnet publish --framework "$TFM" --runtime $RID --output "$STAGE1_DIR" --configuration "$CONFIGURATION" "$REPOROOT/src/Microsoft.DotNet.Tools.Publish"
dotnet publish --framework "$TFM" --runtime $RID --output "$STAGE1_DIR" --configuration "$CONFIGURATION" "$REPOROOT/src/Microsoft.DotNet.Tools.Resgen" dotnet publish --framework "$TFM" --runtime $RID --output "$STAGE1_DIR" --configuration "$CONFIGURATION" "$REPOROOT/src/Microsoft.DotNet.Tools.Resgen"
# Deploy CLR host to the output
cp "$HOST_DIR/corehost" "$STAGE1_DIR"
# Add stage1 to the path and use it to build stage2 # Add stage1 to the path and use it to build stage2
export PATH=$STAGE1_DIR:$START_PATH export PATH=$STAGE1_DIR:$START_PATH
# Make corerun explicitly executable
chmod a+x $STAGE1_DIR/corerun
# Clean up stage2 # Clean up stage2
[ -d "$STAGE2_DIR" ] && rm -Rf "$STAGE2_DIR" [ -d "$STAGE2_DIR" ] && rm -Rf "$STAGE2_DIR"
@ -62,6 +83,9 @@ dotnet publish --framework "$TFM" --runtime $RID --output "$STAGE2_DIR" --config
dotnet publish --framework "$TFM" --runtime $RID --output "$STAGE2_DIR" --configuration "$CONFIGURATION" "$REPOROOT/src/Microsoft.DotNet.Tools.Publish" dotnet publish --framework "$TFM" --runtime $RID --output "$STAGE2_DIR" --configuration "$CONFIGURATION" "$REPOROOT/src/Microsoft.DotNet.Tools.Publish"
dotnet publish --framework "$TFM" --runtime $RID --output "$STAGE2_DIR" --configuration "$CONFIGURATION" "$REPOROOT/src/Microsoft.DotNet.Tools.Resgen" dotnet publish --framework "$TFM" --runtime $RID --output "$STAGE2_DIR" --configuration "$CONFIGURATION" "$REPOROOT/src/Microsoft.DotNet.Tools.Resgen"
# Deploy CLR host to the output
cp "$HOST_DIR/corehost" "$STAGE2_DIR"
# Make Stage 2 Folder Accessible # Make Stage 2 Folder Accessible
chmod -R a+r $REPOROOT chmod -R a+r $REPOROOT
@ -77,8 +101,10 @@ banner "Testing stage2 ..."
export PATH=$STAGE2_DIR:$START_PATH export PATH=$STAGE2_DIR:$START_PATH
rm "$REPOROOT/test/TestApp/project.lock.json" rm "$REPOROOT/test/TestApp/project.lock.json"
dotnet restore "$REPOROOT/test/TestApp" --runtime "$RID" dotnet restore "$REPOROOT/test/TestApp"
dotnet publish "$REPOROOT/test/TestApp" --framework "$TFM" --runtime "$RID" --output "$REPOROOT/artifacts/$RID/smoketest" dotnet compile "$REPOROOT/test/TestApp" --output "$REPOROOT/artifacts/$RID/smoketest"
export CLRHOST_CLR_PATH=$STAGE2_DIR
OUTPUT=$($REPOROOT/artifacts/$RID/smoketest/TestApp) OUTPUT=$($REPOROOT/artifacts/$RID/smoketest/TestApp)
[ "$OUTPUT" == "This is a test app" ] || (error "Smoke test failed!" && exit 1) [ "$OUTPUT" == "This is a test app" ] || (error "Smoke test failed!" && exit 1)

View file

@ -19,12 +19,9 @@ if [ -z "$HOME" ]; then
mkdir -p $HOME mkdir -p $HOME
fi fi
# Set the build number using CI build number # UTC Timestamp of the last commit is used as the build number. This is for easy synchronization of build number between Windows, OSX and Linux builds.
BASE_VERSION=0.0.2-alpha1 LAST_COMMIT_TIMESTAMP=$(git log -1 --format=%ct)
if [ ! -z "$BUILD_NUMBER" ]; then export DOTNET_BUILD_VERSION=0.0.1-alpha-$(date -ud @$LAST_COMMIT_TIMESTAMP "+%Y%m%d-%H%M%S")
export DOTNET_BUILD_VERSION="$BASE_VERSION-$(printf "%05d" $BUILD_NUMBER)"
info "Building version $DOTNET_BUILD_VERSION"
fi
if [[ "$(uname)" == "Linux" ]]; then if [[ "$(uname)" == "Linux" ]]; then
# Set Docker Container name to be unique # Set Docker Container name to be unique

10
scripts/cmake-gen.cmd Normal file
View file

@ -0,0 +1,10 @@
@echo off
REM Generate project files for the coreclr host
set CMAKE_OUTPUT=%~dp0..\src\corehost\cmake
if not exist %CMAKE_OUTPUT% mkdir %CMAKE_OUTPUT%
pushd %CMAKE_OUTPUT%
cmake .. -G "Visual Studio 14 2015 Win64"
if %errorlevel% neq 0 exit /b %errorlevel%
popd

22
scripts/cmake-gen.sh Executable file
View file

@ -0,0 +1,22 @@
#!/usr/bin/env bash
set -e
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
SOURCE="$(readlink "$SOURCE")"
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
source "$DIR/_common.sh"
# Generate make files for the coreclr host
CMAKE_OUTPUT=$DIR/../src/corehost/cmake/$RID
if [ ! -d $CMAKE_OUTPUT ]; then
mkdir -p $CMAKE_OUTPUT
fi
pushd $CMAKE_OUTPUT
cmake ../.. -G "Unix Makefiles"
popd

39
scripts/dev-install.sh Executable file
View file

@ -0,0 +1,39 @@
#!/usr/bin/env bash
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
SOURCE="$(readlink "$SOURCE")"
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
REPOROOT="$( cd -P "$DIR/.." && pwd )"
source "$DIR/_common.sh"
if [ -z "$RID" ]; then
UNAME=$(uname)
if [ "$UNAME" == "Darwin" ]; then
OSNAME=osx
RID=osx.10.10-x64
elif [ "$UNAME" == "Linux" ]; then
# Detect Distro?
OSNAME=linux
RID=ubuntu.14.04-x64
else
echo "Unknown OS: $UNAME" 1>&2
exit 1
fi
fi
OUTPUT_ROOT=$REPOROOT/artifacts/$RID
DNX_DIR=$OUTPUT_ROOT/dnx
HOST_DIR=$OUTPUT_ROOT/clrhost
STAGE1_DIR=$OUTPUT_ROOT/stage1
STAGE2_DIR=$OUTPUT_ROOT/stage2
DESTINATION=$(eval echo "~/.dotnet/sdks/dotnet-${OSNAME}-x64.0.0.1-dev")
info "Symlinking $STAGE2_DIR to $DESTINATION"
rm -f $DESTINATION
ln -s $STAGE2_DIR $DESTINATION

View file

@ -2,19 +2,32 @@
FROM debian:jessie FROM debian:jessie
# This could become a "microsoft/coreclr" image, since it just installs the dependencies for CoreCLR (and stdlib) # This could become a "microsoft/coreclr" image, since it just installs the dependencies for CoreCLR (and stdlib)
# Install CoreCLR dependencies (and clean APT cache) # Install CoreCLR dependencies
RUN apt-get update && \ RUN apt-get update && \
apt-get -qqy install unzip curl libicu-dev libunwind8 gettext libssl-dev libcurl3-gnutls zlib1g && \ apt-get -qqy install unzip curl libicu-dev libunwind8 gettext libssl-dev libcurl3-gnutls zlib1g
rm -rf /var/lib/apt/lists/*
# No longer need to install DNX since it is embedded (and soon will be gone!) # No longer need to install DNX since it is embedded (and soon will be gone!)
# Install Package Build Prereqs (and clean up APT cache after to save space in the image) # Install Build Prereqs
RUN echo "deb http://llvm.org/apt/trusty/ llvm-toolchain-trusty-3.6 main" | tee /etc/apt/sources.list.d/llvm.list && \ RUN echo "deb http://llvm.org/apt/trusty/ llvm-toolchain-trusty-3.6 main" | tee /etc/apt/sources.list.d/llvm.list && \
curl http://llvm.org/apt/llvm-snapshot.gpg.key | apt-key add - && \ curl http://llvm.org/apt/llvm-snapshot.gpg.key | apt-key add - && \
apt-get update && \ apt-get update && \
apt-get install -y debhelper build-essential devscripts git liblttng-ust-dev lldb-3.6-dev && \ apt-get install -y debhelper build-essential devscripts git liblttng-ust-dev lldb-3.6-dev lldb-3.6 clang
rm -rf /var/lib/apt/lists/*
# Install latest cmake
RUN mkdir -p /opt/src/cmake && \
cd /opt/src/cmake && \
curl -O https://cmake.org/files/v3.4/cmake-3.4.0-rc2.tar.gz && \
tar xzf cmake-3.4.0-rc2.tar.gz && \
cd cmake-3.4.0-rc2 && \
./bootstrap && \
make && \
make install && \
cd /opt && \
rm -Rf /opt/src/cmake
# Use clang as c++ compiler
RUN update-alternatives --set c++ /usr/bin/clang++
# Set working directory # Set working directory
WORKDIR /opt/code WORKDIR /opt/code

View file

@ -24,9 +24,8 @@ docker build -t $DOTNET_BUILD_CONTAINER_TAG scripts/docker/
# Run the build in the container # Run the build in the container
banner "Launching build in Docker Container" banner "Launching build in Docker Container"
info "Using code from: $DOCKER_HOST_SHARE_DIR" info "Using code from: $DOCKER_HOST_SHARE_DIR"
docker run --rm --sig-proxy=true \ docker run -t --rm --sig-proxy=true \
--name $DOTNET_BUILD_CONTAINER_NAME \ --name $DOTNET_BUILD_CONTAINER_NAME \
-v $DOCKER_HOST_SHARE_DIR:/opt/code \ -v $DOCKER_HOST_SHARE_DIR:/opt/code \
-e DOTNET_BUILD_VERSION=$DOTNET_BUILD_VERSION \ -e DOTNET_BUILD_VERSION=$DOTNET_BUILD_VERSION \
-e DOTNET_CI_SKIP_STAGE0_INSTALL=$DOTNET_CI_SKIP_STAGE0_INSTALL \
$DOTNET_BUILD_CONTAINER_TAG $BUILD_COMMAND $1 $DOTNET_BUILD_CONTAINER_TAG $BUILD_COMMAND $1

22
scripts/dockerrun.sh Executable file
View file

@ -0,0 +1,22 @@
#!/usr/bin/env bash
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
SOURCE="$(readlink "$SOURCE")"
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
source "$DIR/_common.sh"
cd $DIR/..
[ -z "$DOTNET_BUILD_CONTAINER_TAG" ] && DOTNET_BUILD_CONTAINER_TAG="dotnetcli-build"
[ -z "$DOTNET_BUILD_CONTAINER_NAME" ] && DOTNET_BUILD_CONTAINER_NAME="dotnetcli-build-container"
[ -z "$DOCKER_HOST_SHARE_DIR" ] && DOCKER_HOST_SHARE_DIR=$(pwd)
# Enter the container
docker run -it --rm --sig-proxy=true \
-v $DOCKER_HOST_SHARE_DIR:/opt/code \
$DOTNET_BUILD_CONTAINER_TAG

View file

@ -12,4 +12,4 @@ DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
# work around restore timeouts on Mono # work around restore timeouts on Mono
[ -z "$MONO_THREADS_PER_CPU" ] && export MONO_THREADS_PER_CPU=50 [ -z "$MONO_THREADS_PER_CPU" ] && export MONO_THREADS_PER_CPU=50
exec "$DIR/dnx/dnx" "$DIR/dnx/lib/Microsoft.Dnx.Tooling/Microsoft.Dnx.Tooling.dll" "restore" "$@" exec "$DIR/dnx/dnx" "$DIR/dnx/lib/Microsoft.Dnx.Tooling/Microsoft.Dnx.Tooling.dll" "restore" --runtime "osx.10.10-x64" --runtime "ubuntu.14.04-x64" "$@"

View file

@ -8,14 +8,10 @@ namespace Microsoft.DotNet.Cli.Utils
{ {
internal static class Constants internal static class Constants
{ {
// TODO: On Unix, exe suffix is empty string... public static readonly string ExeSuffix = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".exe" : string.Empty;
public static readonly string ExeSuffix = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".exe" : ""; public static readonly string HostExecutableName = "corehost" + ExeSuffix;
public static readonly string CoreConsoleName = "coreconsole" + ExeSuffix;
public static readonly string CoreRunName = "corerun" + ExeSuffix;
public static readonly string DefaultConfiguration = "Debug"; public static readonly string DefaultConfiguration = "Debug";
public static readonly string BinDirectoryName = "bin"; public static readonly string BinDirectoryName = "bin";
public static readonly string ObjDirectoryName = "obj"; public static readonly string ObjDirectoryName = "obj";
public static readonly string ClrPathEnvironmentVariable = "DOTNET_CLR_PATH";
} }
} }

View file

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Microsoft.Extensions.ProjectModel.Compilation
{
public struct LibraryAsset
{
public string Name { get; }
public string RelativePath { get; }
public string ResolvedPath { get; }
public LibraryAsset(string name, string relativePath, string resolvedPath)
{
Name = name;
RelativePath = relativePath;
ResolvedPath = resolvedPath;
}
}
}

View file

@ -14,24 +14,24 @@ namespace Microsoft.Extensions.ProjectModel.Compilation
/// <summary> /// <summary>
/// Gets a list of fully-qualified paths to MSIL binaries required to run /// Gets a list of fully-qualified paths to MSIL binaries required to run
/// </summary> /// </summary>
public IEnumerable<string> RuntimeAssemblies { get; } public IEnumerable<LibraryAsset> RuntimeAssemblies { get; }
/// <summary> /// <summary>
/// Gets a list of fully-qualified paths to native binaries required to run /// Gets a list of fully-qualified paths to native binaries required to run
/// </summary> /// </summary>
public IEnumerable<string> NativeLibraries { get; } public IEnumerable<LibraryAsset> NativeLibraries { get; }
/// <summary> /// <summary>
/// Gets a list of fully-qualified paths to MSIL metadata references /// Gets a list of fully-qualified paths to MSIL metadata references
/// </summary> /// </summary>
public IEnumerable<string> CompilationAssemblies { get; } public IEnumerable<LibraryAsset> CompilationAssemblies { get; }
/// <summary> /// <summary>
/// Gets a list of fully-qualified paths to source code file references /// Gets a list of fully-qualified paths to source code file references
/// </summary> /// </summary>
public IEnumerable<string> SourceReferences { get; } public IEnumerable<string> SourceReferences { get; }
public LibraryExport(LibraryDescription library, IEnumerable<string> compileAssemblies, IEnumerable<string> sourceReferences, IEnumerable<string> runtimeAssemblies, IEnumerable<string> nativeLibraries) public LibraryExport(LibraryDescription library, IEnumerable<LibraryAsset> compileAssemblies, IEnumerable<string> sourceReferences, IEnumerable<LibraryAsset> runtimeAssemblies, IEnumerable<LibraryAsset> nativeLibraries)
{ {
Library = library; Library = library;
CompilationAssemblies = compileAssemblies; CompilationAssemblies = compileAssemblies;

View file

@ -60,7 +60,7 @@ namespace Microsoft.Extensions.ProjectModel.Compilation
continue; continue;
} }
var compilationAssemblies = new List<string>(); var compilationAssemblies = new List<LibraryAsset>();
var sourceReferences = new List<string>(); var sourceReferences = new List<string>();
var libraryExport = GetExport(library); var libraryExport = GetExport(library);
@ -71,7 +71,7 @@ namespace Microsoft.Extensions.ProjectModel.Compilation
// so we rebuild the library export // so we rebuild the library export
foreach (var reference in libraryExport.CompilationAssemblies) foreach (var reference in libraryExport.CompilationAssemblies)
{ {
if (seenMetadataReferences.Add(Path.GetFileNameWithoutExtension(reference))) if (seenMetadataReferences.Add(reference.Name))
{ {
compilationAssemblies.Add(reference); compilationAssemblies.Add(reference);
} }
@ -115,13 +115,13 @@ namespace Microsoft.Extensions.ProjectModel.Compilation
private LibraryExport ExportPackage(PackageDescription package) private LibraryExport ExportPackage(PackageDescription package)
{ {
var nativeLibraries = new List<string>(); var nativeLibraries = new List<LibraryAsset>();
PopulateAssets(package, package.Target.NativeLibraries, nativeLibraries); PopulateAssets(package, package.Target.NativeLibraries, nativeLibraries);
var runtimeAssemblies = new List<string>(); var runtimeAssemblies = new List<LibraryAsset>();
PopulateAssets(package, package.Target.RuntimeAssemblies, runtimeAssemblies); PopulateAssets(package, package.Target.RuntimeAssemblies, runtimeAssemblies);
var compileAssemblies = new List<string>(); var compileAssemblies = new List<LibraryAsset>();
PopulateAssets(package, package.Target.CompileTimeAssemblies, compileAssemblies); PopulateAssets(package, package.Target.CompileTimeAssemblies, compileAssemblies);
var sourceReferences = new List<string>(); var sourceReferences = new List<string>();
@ -135,14 +135,17 @@ namespace Microsoft.Extensions.ProjectModel.Compilation
private LibraryExport ExportProject(ProjectDescription project) private LibraryExport ExportProject(ProjectDescription project)
{ {
var compileAssemblies = new List<string>(); var compileAssemblies = new List<LibraryAsset>();
var sourceReferences = new List<string>(); var sourceReferences = new List<string>();
if (!string.IsNullOrEmpty(project.TargetFrameworkInfo?.AssemblyPath)) if (!string.IsNullOrEmpty(project.TargetFrameworkInfo?.AssemblyPath))
{ {
// Project specifies a pre-compiled binary. We're done! // Project specifies a pre-compiled binary. We're done!
var assemblyPath = ResolvePath(project.Project, _configuration, project.TargetFrameworkInfo.AssemblyPath); var assemblyPath = ResolvePath(project.Project, _configuration, project.TargetFrameworkInfo.AssemblyPath);
compileAssemblies.Add(assemblyPath); compileAssemblies.Add(new LibraryAsset(
project.Project.Name,
assemblyPath,
Path.Combine(project.Project.ProjectDirectory, assemblyPath)));
} }
else else
{ {
@ -150,7 +153,10 @@ namespace Microsoft.Extensions.ProjectModel.Compilation
var outputPath = GetOutputPath(project); var outputPath = GetOutputPath(project);
if (project.Project.Files.SourceFiles.Any()) if (project.Project.Files.SourceFiles.Any())
{ {
compileAssemblies.Add(outputPath); compileAssemblies.Add(new LibraryAsset(
project.Project.Name,
outputPath,
Path.Combine(project.Project.ProjectDirectory, outputPath)));
} }
} }
@ -161,18 +167,17 @@ namespace Microsoft.Extensions.ProjectModel.Compilation
} }
// No support for ref or native in projects, so runtimeAssemblies is just the same as compileAssemblies and nativeLibraries are empty // No support for ref or native in projects, so runtimeAssemblies is just the same as compileAssemblies and nativeLibraries are empty
return new LibraryExport(project, compileAssemblies, sourceReferences, compileAssemblies, Enumerable.Empty<string>()); return new LibraryExport(project, compileAssemblies, sourceReferences, compileAssemblies, Enumerable.Empty<LibraryAsset>());
} }
private string GetOutputPath(ProjectDescription project) private string GetOutputPath(ProjectDescription project)
{ {
var compilationOptions = project.Project.GetCompilerOptions(project.Framework, _configuration); var compilationOptions = project.Project.GetCompilerOptions(project.Framework, _configuration);
return Path.Combine( return Path.Combine(
project.Project.ProjectDirectory,
"bin", // This can't access the Constant in Cli Utils. But the output path stuff is temporary right now anyway "bin", // This can't access the Constant in Cli Utils. But the output path stuff is temporary right now anyway
_configuration, _configuration,
project.Framework.GetTwoDigitShortFolderName(), project.Framework.GetTwoDigitShortFolderName(),
project.Project.Name + (compilationOptions.EmitEntryPoint.GetValueOrDefault() ? ".exe" : ".dll")); project.Project.Name + ".dll");
} }
private static string ResolvePath(Project project, string configuration, string path) private static string ResolvePath(Project project, string configuration, string path)
@ -186,7 +191,7 @@ namespace Microsoft.Extensions.ProjectModel.Compilation
path = path.Replace("{configuration}", configuration); path = path.Replace("{configuration}", configuration);
return Path.Combine(project.ProjectDirectory, path); return path;
} }
private LibraryExport ExportFrameworkLibrary(LibraryDescription library) private LibraryExport ExportFrameworkLibrary(LibraryDescription library)
@ -200,10 +205,10 @@ namespace Microsoft.Extensions.ProjectModel.Compilation
// since they assume the runtime library is present already // since they assume the runtime library is present already
return new LibraryExport( return new LibraryExport(
library, library,
new[] { library.Path }, new[] { new LibraryAsset(library.Identity.Name, library.Path, library.Path) },
Enumerable.Empty<string>(), Enumerable.Empty<string>(),
Enumerable.Empty<string>(), Enumerable.Empty<LibraryAsset>(),
Enumerable.Empty<string>()); Enumerable.Empty<LibraryAsset>());
} }
private IEnumerable<string> GetSharedSources(PackageDescription package) private IEnumerable<string> GetSharedSources(PackageDescription package)
@ -216,7 +221,7 @@ namespace Microsoft.Extensions.ProjectModel.Compilation
} }
private void PopulateAssets(PackageDescription package, IEnumerable<LockFileItem> section, IList<string> paths) private void PopulateAssets(PackageDescription package, IEnumerable<LockFileItem> section, IList<LibraryAsset> assets)
{ {
foreach (var assemblyPath in section) foreach (var assemblyPath in section)
{ {
@ -225,8 +230,10 @@ namespace Microsoft.Extensions.ProjectModel.Compilation
continue; continue;
} }
var path = Path.Combine(package.Path, assemblyPath); assets.Add(new LibraryAsset(
paths.Add(path); Path.GetFileNameWithoutExtension(assemblyPath),
assemblyPath,
Path.Combine(package.Path, assemblyPath)));
} }
} }
} }

View file

@ -17,6 +17,7 @@ namespace Microsoft.Extensions.ProjectModel
{ {
public LibraryDescription( public LibraryDescription(
LibraryIdentity identity, LibraryIdentity identity,
string hash,
string path, string path,
IEnumerable<LibraryRange> dependencies, IEnumerable<LibraryRange> dependencies,
NuGetFramework framework, NuGetFramework framework,
@ -25,6 +26,7 @@ namespace Microsoft.Extensions.ProjectModel
{ {
Path = path; Path = path;
Identity = identity; Identity = identity;
Hash = hash;
Dependencies = dependencies ?? Enumerable.Empty<LibraryRange>(); Dependencies = dependencies ?? Enumerable.Empty<LibraryRange>();
Framework = framework; Framework = framework;
Resolved = resolved; Resolved = resolved;
@ -32,6 +34,7 @@ namespace Microsoft.Extensions.ProjectModel
} }
public LibraryIdentity Identity { get; } public LibraryIdentity Identity { get; }
public string Hash { get; }
public HashSet<LibraryRange> RequestedRanges { get; } = new HashSet<LibraryRange>(new LibraryRangeEqualityComparer()); public HashSet<LibraryRange> RequestedRanges { get; } = new HashSet<LibraryRange>(new LibraryRangeEqualityComparer());
public List<LibraryDescription> Parents { get; } = new List<LibraryDescription>(); public List<LibraryDescription> Parents { get; } = new List<LibraryDescription>();
public string Path { get; } public string Path { get; }

View file

@ -13,6 +13,7 @@ namespace Microsoft.Extensions.ProjectModel
bool compatible) bool compatible)
: base( : base(
new LibraryIdentity(package.Name, package.Version, LibraryType.Package), new LibraryIdentity(package.Name, package.Version, LibraryType.Package),
"sha512-" + package.Sha512,
path, path,
dependencies: dependencies, dependencies: dependencies,
framework: null, framework: null,

View file

@ -13,6 +13,7 @@ namespace Microsoft.Extensions.ProjectModel
public ProjectDescription(string name, string path) public ProjectDescription(string name, string path)
: base( : base(
new LibraryIdentity(name, LibraryType.Project), new LibraryIdentity(name, LibraryType.Project),
string.Empty, // Projects don't have hashes
path, path,
Enumerable.Empty<LibraryRange>(), Enumerable.Empty<LibraryRange>(),
framework: null, framework: null,
@ -28,6 +29,7 @@ namespace Microsoft.Extensions.ProjectModel
bool resolved) : bool resolved) :
base( base(
new LibraryIdentity(project.Name, project.Version, LibraryType.Project), new LibraryIdentity(project.Name, project.Version, LibraryType.Project),
string.Empty, // Projects don't have hashes
project.ProjectFilePath, project.ProjectFilePath,
dependencies, dependencies,
targetFrameworkInfo.FrameworkName, targetFrameworkInfo.FrameworkName,

View file

@ -42,6 +42,7 @@ namespace Microsoft.Extensions.ProjectModel.Resolution
{ {
return new LibraryDescription( return new LibraryDescription(
new LibraryIdentity(libraryRange.Name, new NuGetVersion(assemblyVersion), LibraryType.ReferenceAssembly), new LibraryIdentity(libraryRange.Name, new NuGetVersion(assemblyVersion), LibraryType.ReferenceAssembly),
string.Empty, // Framework assemblies don't have hashes
path, path,
Enumerable.Empty<LibraryRange>(), Enumerable.Empty<LibraryRange>(),
targetFramework, targetFramework,

View file

@ -13,6 +13,7 @@ namespace Microsoft.Extensions.ProjectModel.Resolution
{ {
return new LibraryDescription( return new LibraryDescription(
new LibraryIdentity(libraryRange.Name, libraryRange.VersionRange?.MinVersion, libraryRange.Target), new LibraryIdentity(libraryRange.Name, libraryRange.VersionRange?.MinVersion, libraryRange.Target),
hash: null,
path: null, path: null,
dependencies: Enumerable.Empty<LibraryRange>(), dependencies: Enumerable.Empty<LibraryRange>(),
framework: targetFramework, framework: targetFramework,

View file

@ -0,0 +1,27 @@
using System.Runtime.InteropServices;
namespace Microsoft.Extensions.ProjectModel
{
public static class RuntimeIdentifier
{
public static string Current { get; } = DetermineRID();
private static string DetermineRID()
{
// TODO: Not this, obviously. Do proper RID detection
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
return "win7-x64";
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
return "ubuntu.14.04-x64";
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
return "osx.10.10-x64";
}
return "unknown";
}
}
}

View file

@ -41,7 +41,7 @@ namespace Microsoft.DotNet.Tools.Compiler.Csc
{ {
hostRoot = AppContext.BaseDirectory; hostRoot = AppContext.BaseDirectory;
} }
var corerun = Path.Combine(hostRoot, Constants.CoreRunName); var corerun = Path.Combine(hostRoot, Constants.HostExecutableName);
var cscExe = Path.Combine(hostRoot, "csc.exe"); var cscExe = Path.Combine(hostRoot, "csc.exe");
return File.Exists(corerun) && File.Exists(cscExe) return File.Exists(corerun) && File.Exists(cscExe)
? Command.Create(corerun, $@"""{cscExe}"" {cscArgs}") ? Command.Create(corerun, $@"""{cscExe}"" {cscArgs}")

View file

@ -8,7 +8,6 @@
"dotnet-compile-csc": "Microsoft.DotNet.Tools.Compiler.Csc" "dotnet-compile-csc": "Microsoft.DotNet.Tools.Compiler.Csc"
}, },
"dependencies": { "dependencies": {
"Microsoft.NETCore.TestHost": "1.0.0-beta-23428",
"Microsoft.NETCore.Runtime": "1.0.1-beta-23428", "Microsoft.NETCore.Runtime": "1.0.1-beta-23428",
"System.Console": "4.0.0-beta-23428", "System.Console": "4.0.0-beta-23428",

View file

@ -158,7 +158,12 @@ namespace Microsoft.DotNet.Tools.Compiler
// Get compilation options // Get compilation options
var compilationOptions = context.ProjectFile.GetCompilerOptions(context.TargetFramework, configuration); var compilationOptions = context.ProjectFile.GetCompilerOptions(context.TargetFramework, configuration);
var outputName = Path.Combine(outputPath, context.ProjectFile.Name + (compilationOptions.EmitEntryPoint.GetValueOrDefault() ? ".exe" : ".dll")); var outputExtension = ".dll";
if (context.TargetFramework.IsDesktop() && compilationOptions.EmitEntryPoint.GetValueOrDefault())
{
outputExtension = ".exe";
}
var outputName = Path.Combine(outputPath, context.ProjectFile.Name + outputExtension);
// Assemble args // Assemble args
var compilerArgs = new List<string>() var compilerArgs = new List<string>()
@ -178,7 +183,7 @@ namespace Microsoft.DotNet.Tools.Compiler
foreach (var dependency in dependencies) foreach (var dependency in dependencies)
{ {
compilerArgs.AddRange(dependency.CompilationAssemblies.Select(r => $"-r:\"{r}\"")); compilerArgs.AddRange(dependency.CompilationAssemblies.Select(r => $"-r:\"{r.ResolvedPath}\""));
compilerArgs.AddRange(dependency.SourceReferences.Select(s => $"\"{s}\"")); compilerArgs.AddRange(dependency.SourceReferences.Select(s => $"\"{s}\""));
} }
@ -233,11 +238,56 @@ namespace Microsoft.DotNet.Tools.Compiler
var success = result.ExitCode == 0; var success = result.ExitCode == 0;
if (success && !context.TargetFramework.IsDesktop() && compilationOptions.EmitEntryPoint.GetValueOrDefault())
{
var runtimeContext = ProjectContext.Create(context.ProjectDirectory, context.TargetFramework, new [] { RuntimeIdentifier.Current });
EmitHost(outputPath, context.ProjectFile.Name, runtimeContext.CreateExporter(configuration));
}
PrintSummary(success, diagnostics); PrintSummary(success, diagnostics);
return success; return success;
} }
private static void EmitHost(string outputPath, string projectName, LibraryExporter exporter)
{
// Write the Host information file (basically a simplified form of the lock file)
List<string> lines = new List<string>();
foreach(var export in exporter.GetAllExports())
{
lines.AddRange(GenerateLines(export, export.RuntimeAssemblies, "runtime"));
lines.AddRange(GenerateLines(export, export.NativeLibraries, "native"));
}
File.WriteAllLines(Path.Combine(outputPath, projectName + ".deps"), lines);
// Copy the host in
CopyHost(Path.Combine(outputPath, projectName + Constants.ExeSuffix));
}
private static void CopyHost(string target)
{
var hostPath = Path.Combine(AppContext.BaseDirectory, Constants.HostExecutableName);
File.Copy(hostPath, target);
}
private static IEnumerable<string> GenerateLines(LibraryExport export, IEnumerable<LibraryAsset> items, string type)
{
return items.Select(item =>
EscapeCsv(export.Library.Identity.Type.Value) + "," +
EscapeCsv(export.Library.Identity.Name) + "," +
EscapeCsv(export.Library.Identity.Version.ToNormalizedString()) + "," +
EscapeCsv(export.Library.Hash) + "," +
EscapeCsv(type) + "," +
EscapeCsv(item.Name) + "," +
EscapeCsv(item.RelativePath) + ",");
}
private static string EscapeCsv(string input)
{
return "\"" + input.Replace("\\", "\\\\").Replace("\"", "\\\"") + "\"";
}
private static void PrintSummary(bool success, List<DiagnosticMessage> diagnostics) private static void PrintSummary(bool success, List<DiagnosticMessage> diagnostics)
{ {
Reporter.Output.Writer.WriteLine(); Reporter.Output.Writer.WriteLine();

View file

@ -6,6 +6,7 @@ using System.Runtime.InteropServices;
using Microsoft.Dnx.Runtime.Common.CommandLine; using Microsoft.Dnx.Runtime.Common.CommandLine;
using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.Cli.Utils;
using Microsoft.Extensions.ProjectModel; using Microsoft.Extensions.ProjectModel;
using Microsoft.Extensions.ProjectModel.Compilation;
using NuGet.Frameworks; using NuGet.Frameworks;
namespace Microsoft.DotNet.Tools.Publish namespace Microsoft.DotNet.Tools.Publish
@ -139,80 +140,31 @@ namespace Microsoft.DotNet.Tools.Publish
PublishFiles(export.NativeLibraries, outputPath); PublishFiles(export.NativeLibraries, outputPath);
} }
int exitCode; // Publish the application itself
if (context.RuntimeIdentifier.StartsWith("win")) PublishHost(context, outputPath);
{
exitCode = PublishForWindows(context, outputPath);
}
else
{
exitCode = PublishForUnix(context, outputPath);
}
Reporter.Output.WriteLine($"Published to {outputPath}".Green().Bold()); Reporter.Output.WriteLine($"Published to {outputPath}".Green().Bold());
return exitCode;
}
private static int PublishForUnix(ProjectContext context, string outputPath)
{
if (context.TargetFramework.IsDesktop())
{
return 0;
}
var coreConsole = Path.Combine(outputPath, Constants.CoreConsoleName);
if(!File.Exists(coreConsole))
{
Reporter.Error.WriteLine($"Cannot find {Constants.CoreConsoleName} in the output. You must have a direct dependency on Microsoft.NETCore.ConsoleHost (for now)");
return 1;
}
var coreRun = Path.Combine(outputPath, Constants.CoreRunName);
if(!File.Exists(coreRun))
{
Reporter.Error.WriteLine($"Cannot find {Constants.CoreRunName} in the output. You must have a direct dependency on Microsoft.NETCore.TestHost (for now)");
return 1;
}
var outputExe = Path.Combine(outputPath, context.ProjectFile.Name);
// Rename the {app}.exe to {app}.dll
File.Copy(outputExe + ".exe", outputExe + ".dll", overwrite: true);
// Change coreconsole.exe to the {app}.exe name
File.Copy(coreConsole, outputExe, overwrite: true);
// Delete the original managed .exe
File.Delete(outputExe + ".exe");
return 0; return 0;
} }
private static int PublishForWindows(ProjectContext context, string outputPath) private static int PublishHost(ProjectContext context, string outputPath)
{ {
if (context.TargetFramework.IsDesktop()) if (context.TargetFramework.IsDesktop())
{ {
return 0; return 0;
} }
var coreConsole = Path.Combine(outputPath, Constants.CoreConsoleName); var hostPath = Path.Combine(AppContext.BaseDirectory, Constants.HostExecutableName);
if(!File.Exists(coreConsole)) if(!File.Exists(hostPath))
{ {
Reporter.Error.WriteLine($"Cannot find {Constants.CoreConsoleName} in the output. You must have a direct dependency on Microsoft.NETCore.ConsoleHost (for now)".Red()); Reporter.Error.WriteLine($"Cannot find {Constants.HostExecutableName} in the dotnet directory.".Red());
return 1;
}
var coreRun = Path.Combine(outputPath, Constants.CoreRunName);
if(!File.Exists(coreRun))
{
Reporter.Error.WriteLine($"Cannot find {Constants.CoreRunName} in the output. You must have a direct dependency on Microsoft.NETCore.TestHost (for now)".Red());
return 1; return 1;
} }
var outputExe = Path.Combine(outputPath, context.ProjectFile.Name + Constants.ExeSuffix); var outputExe = Path.Combine(outputPath, context.ProjectFile.Name + Constants.ExeSuffix);
// Rename the {app}.exe to {app}.dll // Copy the host
File.Copy(outputExe, Path.ChangeExtension(outputExe, ".dll"), overwrite: true); File.Copy(hostPath, outputExe, overwrite: true);
// Change coreconsole.exe to the {app}.exe name
File.Copy(coreConsole, outputExe, overwrite: true);
return 0; return 0;
} }
@ -280,11 +232,11 @@ namespace Microsoft.DotNet.Tools.Publish
return path + trailingCharacter; return path + trailingCharacter;
} }
private static void PublishFiles(IEnumerable<string> files, string outputPath) private static void PublishFiles(IEnumerable<LibraryAsset> files, string outputPath)
{ {
foreach (var file in files) foreach (var file in files)
{ {
File.Copy(file, Path.Combine(outputPath, Path.GetFileName(file)), overwrite: true); File.Copy(file.ResolvedPath, Path.Combine(outputPath, Path.GetFileName(file.ResolvedPath)), overwrite: true);
} }
} }
} }

View file

@ -8,7 +8,6 @@
"resgen": "Microsoft.DotNet.Tools.Resgen" "resgen": "Microsoft.DotNet.Tools.Resgen"
}, },
"dependencies": { "dependencies": {
"Microsoft.NETCore.TestHost": "1.0.0-beta-23428",
"Microsoft.NETCore.Runtime": "1.0.1-beta-23428", "Microsoft.NETCore.Runtime": "1.0.1-beta-23428",
"System.Console": "4.0.0-beta-23428", "System.Console": "4.0.0-beta-23428",
"System.Collections": "4.0.11-beta-23428", "System.Collections": "4.0.11-beta-23428",

View file

@ -0,0 +1,33 @@
cmake_minimum_required (VERSION 3.1)
project (corehost)
set (CMAKE_CXX_STANDARD 11)
include_directories(inc)
# CMake does not recommend using globbing since it messes with the freshness checks
set(SOURCES
src/args.cpp
src/main.cpp
src/tpafile.cpp
src/trace.cpp
src/utils.cpp
src/coreclr.cpp
inc/args.h
inc/pal.h
inc/tpafile.h
inc/trace.h
inc/coreclr.h
inc/utils.h)
if(WIN32)
list(APPEND SOURCES src/pal.windows.cpp)
else()
list(APPEND SOURCES src/pal.unix.cpp)
endif()
add_executable(corehost ${SOURCES})
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
add_definitions(-D__LINUX__)
target_link_libraries (corehost "dl")
endif()

22
src/corehost/inc/args.h Normal file
View file

@ -0,0 +1,22 @@
#ifndef ARGS_H
#define ARGS_H
#include "pal.h"
#include "trace.h"
struct arguments_t
{
trace::level_t trace_level;
pal::string_t own_path;
pal::string_t managed_application;
pal::string_t clr_path;
int app_argc;
const pal::char_t** app_argv;
arguments_t();
};
bool parse_arguments(const int argc, const pal::char_t* argv[], arguments_t& args);
#endif // ARGS_H

View file

@ -0,0 +1,36 @@
#ifndef CLR_H
#define CLR_H
#include "pal.h"
#include "trace.h"
namespace coreclr
{
typedef void* host_handle_t;
typedef unsigned int domain_id_t;
bool bind(const pal::string_t& libcoreclr_path);
void unload();
pal::hresult_t initialize(
const char* exe_path,
const char* app_domain_friendly_name,
const char** property_keys,
const char** property_values,
int property_count,
host_handle_t* host_handle,
domain_id_t* domain_id);
pal::hresult_t shutdown(host_handle_t host_handle, domain_id_t domain_id);
pal::hresult_t execute_assembly(
host_handle_t host_handle,
domain_id_t domain_id,
int argc,
const char** argv,
const char* managed_assembly_path,
unsigned int* exit_code);
};
#endif

107
src/corehost/inc/pal.h Normal file
View file

@ -0,0 +1,107 @@
#ifndef PAL_H
#define PAL_H
#include <string>
#include <vector>
#include <fstream>
#include <iostream>
#include <cstring>
#include <cstdarg>
#include <tuple>
#if defined(_WIN32)
#include <Windows.h>
#define HOST_EXE_NAME L"corehost.exe"
#define xerr std::wcerr
#define xout std::wcout
#define DIR_SEPARATOR L'\\'
#define PATH_SEPARATOR L';'
#define PATH_MAX MAX_PATH
#define _X(s) L ## s
#else
#include <cstdlib>
#include <libgen.h>
#define HOST_EXE_NAME "corehost"
#define xerr std::cerr
#define xout std::cout
#define DIR_SEPARATOR '/'
#define PATH_SEPARATOR ':'
#define _X(s) s
#define S_OK 0x00000000
#define E_NOTIMPL 0x80004001
#define E_FAIL 0x80004005
#define SUCCEEDED(Status) ((Status) >= 0)
#endif
#if defined(_WIN32)
#define LIBCORECLR_NAME L"coreclr.dll"
#elif defined(__APPLE__)
#define LIBCORECLR_NAME "libcoreclr.dylib"
#else
#define LIBCORECLR_NAME "libcoreclr.so"
#endif
#if !defined(PATH_MAX) && !defined(_WIN32)
#define PATH_MAX 4096
#endif
namespace pal
{
#if defined(_WIN32)
typedef wchar_t char_t;
typedef std::wstring string_t;
typedef std::ifstream ifstream_t;
typedef HRESULT hresult_t;
typedef HMODULE dll_t;
typedef FARPROC proc_t;
inline int strcmp(const char_t* str1, const char_t* str2) { return ::wcscmp(str1, str2); }
inline int strcasecmp(const char_t* str1, const char_t* str2) { return ::_wcsicmp(str1, str2); }
inline size_t strlen(const char_t* str) { return ::wcslen(str); }
inline void err_vprintf(const char_t* format, va_list vl) { ::vfwprintf(stderr, format, vl); ::fputws(_X("\r\n"), stderr); }
pal::string_t to_palstring(const std::string& str);
std::string to_stdstring(const pal::string_t& str);
#else
typedef char char_t;
typedef std::string string_t;
typedef std::ifstream ifstream_t;
typedef long hresult_t;
typedef void* dll_t;
typedef void* proc_t;
inline int strcmp(const char_t* str1, const char_t* str2) { return ::strcmp(str1, str2); }
inline int strcasecmp(const char_t* str1, const char_t* str2) { return ::strcasecmp(str1, str2); }
inline size_t strlen(const char_t* str) { return ::strlen(str); }
inline void err_vprintf(const char_t* format, va_list vl) { ::vfprintf(stderr, format, vl); ::fputc('\n', stderr); }
inline pal::string_t to_palstring(const std::string& str) { return str; }
inline std::string to_stdstring(const pal::string_t& str) { return str; }
#endif
bool realpath(string_t& path);
bool file_exists(const string_t& path);
std::vector<pal::string_t> readdir(const string_t& path);
bool get_own_executable_path(string_t& recv);
bool getenv(const char_t* name, string_t& recv);
bool get_default_packages_directory(string_t& recv);
bool is_path_rooted(const string_t& path);
int xtoi(const char_t* input);
bool load_library(const char_t* path, dll_t& dll);
proc_t get_symbol(dll_t library, const char* name);
void unload_library(dll_t library);
}
#endif // PAL_H

View file

@ -0,0 +1,38 @@
#ifndef TPAFILE_H
#define TPAFILE_H
#include <vector>
#include "pal.h"
#include "trace.h"
struct tpaentry_t
{
pal::string_t library_type;
pal::string_t library_name;
pal::string_t library_version;
pal::string_t library_hash;
pal::string_t asset_type;
pal::string_t asset_name;
pal::string_t relative_path;
};
class tpafile
{
public:
bool load(pal::string_t path);
void add_from_local_dir(const pal::string_t& dir);
void add_package_dir(pal::string_t dir);
void add_native_search_path(pal::string_t dir);
void write_tpa_list(pal::string_t& output);
void write_native_paths(pal::string_t& output);
private:
std::vector<tpaentry_t> m_entries;
std::vector<pal::string_t> m_native_search_paths;
std::vector<pal::string_t> m_package_search_paths;
};
#endif // TPAFILE_H

24
src/corehost/inc/trace.h Normal file
View file

@ -0,0 +1,24 @@
#ifndef TRACE_H
#define TRACE_H
#include "pal.h"
namespace trace
{
enum class level_t
{
Error = 0,
Warning = 1,
Info = 2,
Verbose = 3
};
void set_level(level_t level);
bool is_enabled(level_t level);
void verbose(const pal::char_t* format, ...);
void info(const pal::char_t* format, ...);
void warning(const pal::char_t* format, ...);
void error(const pal::char_t* format, ...);
};
#endif // TRACE_H

11
src/corehost/inc/utils.h Normal file
View file

@ -0,0 +1,11 @@
#ifndef UTILS_H
#define UTILS_H
#include "pal.h"
pal::string_t change_extension(const pal::string_t& filename, const pal::char_t* new_extension);
pal::string_t get_directory(const pal::string_t& path);
pal::string_t get_filename(const pal::string_t& path);
void append_path(pal::string_t& path1, const pal::char_t* path2);
#endif

73
src/corehost/src/args.cpp Normal file
View file

@ -0,0 +1,73 @@
#include "args.h"
#include "utils.h"
arguments_t::arguments_t() :
trace_level(trace::level_t::Error),
managed_application(_X("")),
clr_path(_X("")),
app_argc(0),
app_argv(nullptr)
{
}
void display_help()
{
xerr <<
_X("Usage: " HOST_EXE_NAME " [ASSEMBLY] [ARGUMENTS]\n")
_X("Execute the specified managed assembly with the passed in arguments\n\n")
_X("The Host's behavior can be altered using the following environment variables:\n")
_X(" CLRHOST_CLR_PATH Set the directory which contains the CoreCLR runtime. Overrides all other values for CLR search paths\n")
_X(" CLRHOST_TRACE Set to affect trace levels (0 = Errors only (default), 1 = Warnings, 2 = Info, 3 = Verbose)\n");
}
bool parse_arguments(const int argc, const pal::char_t* argv[], arguments_t& args)
{
// Get the full name of the application
if (!pal::get_own_executable_path(args.own_path) || !pal::realpath(args.own_path))
{
trace::error(_X("failed to locate current executable"));
return false;
}
auto own_name = get_filename(args.own_path);
auto own_dir = get_directory(args.own_path);
if (own_name.compare(HOST_EXE_NAME) == 0)
{
// corerun mode. First argument is managed app
if (argc < 2)
{
display_help();
return false;
}
args.managed_application = pal::string_t(argv[1]);
args.app_argc = argc - 2;
args.app_argv = &argv[2];
}
else
{
// coreconsole mode. Find the managed app in the same directory
pal::string_t managed_app(own_dir);
managed_app.push_back(DIR_SEPARATOR);
managed_app.append(change_extension(own_name, _X(".dll")));
args.managed_application = managed_app;
args.app_argv = &argv[1];
args.app_argc = argc - 1;
}
// Read trace environment variable
pal::string_t trace_str;
if (pal::getenv(_X("CLRHOST_TRACE"), trace_str))
{
auto trace_val = pal::xtoi(trace_str.c_str());
if (trace_val >= (int)trace::level_t::Error && trace_val <= (int)trace::level_t::Verbose)
{
args.trace_level = (trace::level_t)trace_val;
}
}
// Read CLR path from environment variable
pal::getenv(_X("CLRHOST_CLR_PATH"), args.clr_path);
return true;
}

View file

@ -0,0 +1,107 @@
#include <cassert>
#include "coreclr.h"
#include "utils.h"
static pal::dll_t g_coreclr = nullptr;
// Prototype of the coreclr_initialize function from coreclr.dll
typedef pal::hresult_t (*coreclr_initialize_fn)(
const char* exePath,
const char* appDomainFriendlyName,
int propertyCount,
const char** propertyKeys,
const char** propertyValues,
coreclr::host_handle_t* hostHandle,
unsigned int* domainId);
// Prototype of the coreclr_shutdown function from coreclr.dll
typedef pal::hresult_t (*coreclr_shutdown_fn)(
coreclr::host_handle_t hostHandle,
unsigned int domainId);
// Prototype of the coreclr_execute_assembly function from coreclr.dll
typedef pal::hresult_t (*coreclr_execute_assembly_fn)(
coreclr::host_handle_t hostHandle,
unsigned int domainId,
int argc,
const char** argv,
const char* managedAssemblyPath,
unsigned int* exitCode);
static coreclr_shutdown_fn coreclr_shutdown = nullptr;
static coreclr_initialize_fn coreclr_initialize = nullptr;
static coreclr_execute_assembly_fn coreclr_execute_assembly = nullptr;
bool coreclr::bind(const pal::string_t& libcoreclr_path)
{
assert(g_coreclr == nullptr);
pal::string_t coreclr_dll_path(libcoreclr_path);
append_path(coreclr_dll_path, LIBCORECLR_NAME);
if(!pal::load_library(coreclr_dll_path.c_str(), g_coreclr))
{
return false;
}
coreclr_initialize = (coreclr_initialize_fn)pal::get_symbol(g_coreclr, "coreclr_initialize");
coreclr_shutdown = (coreclr_shutdown_fn)pal::get_symbol(g_coreclr, "coreclr_shutdown");
coreclr_execute_assembly = (coreclr_execute_assembly_fn)pal::get_symbol(g_coreclr, "coreclr_execute_assembly");
return true;
}
void coreclr::unload()
{
assert(g_coreclr != nullptr && coreclr_initialize != nullptr);
pal::unload_library(g_coreclr);
}
pal::hresult_t coreclr::initialize(
const char* exe_path,
const char* app_domain_friendly_name,
const char** property_keys,
const char** property_values,
int property_count,
host_handle_t* host_handle,
domain_id_t* domain_id)
{
assert(g_coreclr != nullptr && coreclr_initialize != nullptr);
return coreclr_initialize(
exe_path,
app_domain_friendly_name,
property_count,
property_keys,
property_values,
host_handle,
domain_id);
}
pal::hresult_t coreclr::shutdown(host_handle_t host_handle, domain_id_t domain_id)
{
assert(g_coreclr != nullptr && coreclr_shutdown != nullptr);
return coreclr_shutdown(host_handle, domain_id);
}
pal::hresult_t coreclr::execute_assembly(
host_handle_t host_handle,
domain_id_t domain_id,
int argc,
const char** argv,
const char* managed_assembly_path,
unsigned int* exit_code)
{
assert(g_coreclr != nullptr && coreclr_execute_assembly != nullptr);
return coreclr_execute_assembly(
host_handle,
domain_id,
argc,
argv,
managed_assembly_path,
exit_code);
}

214
src/corehost/src/main.cpp Normal file
View file

@ -0,0 +1,214 @@
#include "pal.h"
#include "args.h"
#include "trace.h"
#include "tpafile.h"
#include "utils.h"
#include "coreclr.h"
void get_tpafile_path(const pal::string_t& app_base, const pal::string_t& app_name, pal::string_t& tpapath)
{
tpapath.reserve(app_base.length() + app_name.length() + 5);
tpapath.append(app_base);
tpapath.push_back(DIR_SEPARATOR);
// Remove the extension from the app_name
auto ext_location = app_name.find_last_of('.');
if (ext_location != std::string::npos)
{
tpapath.append(app_name.substr(0, ext_location));
}
else
{
tpapath.append(app_name);
}
tpapath.append(_X(".deps"));
}
int run(arguments_t args, pal::string_t app_base, tpafile tpa)
{
tpa.add_from_local_dir(app_base);
// Add packages directory
pal::string_t packages_dir;
if (!pal::get_default_packages_directory(packages_dir))
{
trace::info(_X("did not find local packages directory"));
// We can continue, the app may have it's dependencies locally
}
else
{
trace::info(_X("using packages directory: %s"), packages_dir.c_str());
tpa.add_package_dir(packages_dir);
}
// Add native search path
trace::info(_X("using native search path: %s"), packages_dir.c_str());
tpa.add_native_search_path(args.clr_path);
// Build TPA list and search paths
pal::string_t tpalist;
tpa.write_tpa_list(tpalist);
pal::string_t search_paths;
tpa.write_native_paths(search_paths);
// Build CoreCLR properties
const char* property_keys[] = {
"TRUSTED_PLATFORM_ASSEMBLIES",
"APP_PATHS",
"APP_NI_PATHS",
"NATIVE_DLL_SEARCH_DIRECTORIES",
"AppDomainCompatSwitch"
};
auto tpa_cstr = pal::to_stdstring(tpalist);
auto app_base_cstr = pal::to_stdstring(app_base);
auto search_paths_cstr = pal::to_stdstring(search_paths);
const char* property_values[] = {
// TRUSTED_PLATFORM_ASSEMBLIES
tpa_cstr.c_str(),
// APP_PATHS
app_base_cstr.c_str(),
// APP_NI_PATHS
app_base_cstr.c_str(),
// NATIVE_DLL_SEARCH_DIRECTORIES
search_paths_cstr.c_str(),
// AppDomainCompatSwitch
"UseLatestBehaviorWhenTFMNotSpecified"
};
// Dump TPA list
trace::verbose(_X("TPA List: %s"), tpalist.c_str());
// Dump native search paths
trace::verbose(_X("Native Paths: %s"), search_paths.c_str());
// Bind CoreCLR
if (!coreclr::bind(args.clr_path))
{
trace::error(_X("failed to bind to coreclr"));
return 1;
}
// Initialize CoreCLR
coreclr::host_handle_t host_handle;
coreclr::domain_id_t domain_id;
auto hr = coreclr::initialize(
pal::to_stdstring(args.own_path).c_str(),
"clrhost",
property_keys,
property_values,
sizeof(property_keys) / sizeof(property_keys[0]),
&host_handle,
&domain_id);
if (!SUCCEEDED(hr))
{
trace::error(_X("failed to initialize CoreCLR, HRESULT: 0x%X"), hr);
return 1;
}
// Convert the args (probably not the most performant way to do this...)
auto argv_strs = new std::string[args.app_argc];
auto argv = new const char*[args.app_argc];
for (int i = 0; i < args.app_argc; i++)
{
argv_strs[i] = pal::to_stdstring(pal::string_t(args.app_argv[i]));
argv[i] = argv_strs[i].c_str();
}
// Execute the application
unsigned int exit_code = 1;
hr = coreclr::execute_assembly(
host_handle,
domain_id,
args.app_argc,
argv,
pal::to_stdstring(args.managed_application).c_str(),
&exit_code);
if (!SUCCEEDED(hr))
{
trace::error(_X("failed to execute managed app, HRESULT: 0x%X"), hr);
return 1;
}
// Shut down the CoreCLR
hr = coreclr::shutdown(host_handle, domain_id);
if (!SUCCEEDED(hr))
{
trace::warning(_X("failed to shut down CoreCLR, HRESULT: 0x%X"), hr);
}
coreclr::unload();
return exit_code;
}
#if defined(_WIN32)
int __cdecl wmain(const int argc, const pal::char_t* argv[])
#else
int main(const int argc, const pal::char_t* argv[])
#endif
{
arguments_t args;
if (!parse_arguments(argc, argv, args))
{
return 1;
}
// Configure tracing
trace::set_level(args.trace_level);
trace::info(_X("tracing enabled"));
// Resolve paths
if (!pal::realpath(args.managed_application))
{
trace::error(_X("failed to locate managed application: %s"), args.managed_application.c_str());
return 1;
}
trace::info(_X("preparing to launch managed application: %s"), args.managed_application.c_str());
trace::info(_X("host path: %s"), args.own_path.c_str());
pal::string_t argstr;
for (int i = 0; i < args.app_argc; i++)
{
argstr.append(args.app_argv[i]);
argstr.append(_X(","));
}
trace::info(_X("App argc: %d"), args.app_argc);
trace::info(_X("App argv: %s"), argstr.c_str());
auto app_base = get_directory(args.managed_application);
auto app_name = get_filename(args.managed_application);
if (args.clr_path.empty())
{
// Use the directory containing the managed assembly
args.clr_path = app_base;
}
if (!pal::realpath(args.clr_path))
{
trace::error(_X("failed to locate CLR files at %s"), args.clr_path.c_str());
return 1;
}
trace::info(_X("using CLR files from: %s"), args.clr_path.c_str());
trace::info(_X("preparing to launch: %s"), app_name.c_str());
trace::info(_X("using app base: %s"), app_base.c_str());
// Check for and load tpa file
pal::string_t tpafile_path;
get_tpafile_path(app_base, app_name, tpafile_path);
trace::info(_X("checking for TPA File at: %s"), tpafile_path.c_str());
tpafile tpa;
if (!tpa.load(tpafile_path))
{
trace::error(_X("invalid TPA file"));
return 1;
}
return run(args, app_base, tpa);
}

View file

@ -0,0 +1,178 @@
#include "pal.h"
#include "utils.h"
#include "trace.h"
#include <dlfcn.h>
#include <dirent.h>
#include <sys/stat.h>
#if defined(__APPLE__)
#include <mach-o/dyld.h>
#endif
#if defined(__LINUX__)
#define symlinkEntrypointExecutable "/proc/self/exe"
#elif !defined(__APPLE__)
#define symlinkEntrypointExecutable "/proc/curproc/exe"
#endif
bool pal::load_library(const char_t* path, dll_t& dll)
{
dll = dlopen(path, RTLD_LAZY);
if (dll == nullptr)
{
trace::error(_X("failed to load %s, error: %s"), path, dlerror());
return false;
}
return true;
}
pal::proc_t pal::get_symbol(dll_t library, const char* name)
{
auto result = dlsym(library, name);
if (result == nullptr)
{
trace::error(_X("failed to resolve library symbol %s, error: %s"), name, dlerror());
}
return result;
}
void pal::unload_library(dll_t library)
{
if (dlclose(library) != 0)
{
trace::warning(_X("failed to unload library, error: %s"), dlerror());
}
}
int pal::xtoi(const char_t* input)
{
return atoi(input);
}
bool pal::is_path_rooted(const pal::string_t& path)
{
return path.front() == '/';
}
bool pal::get_default_packages_directory(pal::string_t& recv)
{
if (!pal::getenv("HOME", recv))
{
return false;
}
append_path(recv, _X(".dnx"));
append_path(recv, _X("packages"));
return true;
}
#if defined(__APPLE__)
bool pal::get_own_executable_path(pal::string_t& recv)
{
uint32_t path_length = 0;
if (_NSGetExecutablePath(nullptr, &path_length) == -1)
{
char path_buf[path_length];
if (_NSGetExecutablePath(path_buf, &path_length) == 0)
{
recv.assign(path_buf);
return true;
}
}
return false;
}
#else
bool pal::get_own_executable_path(pal::string_t& recv)
{
// Just return the symlink to the exe from /proc
// We'll call realpath on it later
recv.assign(symlinkEntrypointExecutable);
return true;
}
#endif
bool pal::getenv(const pal::char_t* name, pal::string_t& recv)
{
auto result = ::getenv(name);
if (result != nullptr)
{
recv.assign(result);
}
// We don't return false. Windows does have a concept of an error reading the variable,
// but Unix just returns null, which we treat as the variable not existing.
return true;
}
bool pal::realpath(pal::string_t& path)
{
pal::char_t buf[PATH_MAX];
auto resolved = ::realpath(path.c_str(), buf);
if (resolved == nullptr)
{
if (errno == ENOENT)
{
return false;
}
perror("realpath()");
return false;
}
path.assign(resolved);
return true;
}
bool pal::file_exists(const pal::string_t& path)
{
struct stat buffer;
return (::stat(path.c_str(), &buffer) == 0);
}
std::vector<pal::string_t> pal::readdir(const pal::string_t& path)
{
std::vector<pal::string_t> files;
auto dir = opendir(path.c_str());
if (dir != nullptr)
{
struct dirent* entry = nullptr;
while((entry = readdir(dir)) != nullptr)
{
// We are interested in files only
switch (entry->d_type)
{
case DT_REG:
break;
// Handle symlinks and file systems that do not support d_type
case DT_LNK:
case DT_UNKNOWN:
{
std::string fullFilename;
fullFilename.append(path);
fullFilename.push_back(DIR_SEPARATOR);
fullFilename.append(entry->d_name);
struct stat sb;
if (stat(fullFilename.c_str(), &sb) == -1)
{
continue;
}
if (!S_ISREG(sb.st_mode))
{
continue;
}
}
break;
default:
continue;
}
files.push_back(pal::string_t(entry->d_name));
}
}
return files;
}

View file

@ -0,0 +1,177 @@
#include "pal.h"
#include "trace.h"
#include "utils.h"
bool pal::load_library(const char_t* path, dll_t& dll)
{
dll = ::LoadLibraryW(path);
if (dll == nullptr)
{
trace::error(_X("failed to load coreclr.dll from %s, HRESULT: 0x%X"), path, HRESULT_FROM_WIN32(GetLastError()));
return false;
}
// Pin the module
HMODULE dummy_module;
if (!::GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN, path, &dummy_module))
{
trace::error(_X("failed to pin library: %s"));
return false;
}
if (trace::is_enabled(trace::level_t::Info))
{
pal::char_t buf[PATH_MAX];
::GetModuleFileNameW(dll, buf, PATH_MAX);
trace::info(_X("loaded library from %s"), buf);
}
return true;
}
pal::proc_t pal::get_symbol(dll_t library, const char* name)
{
return ::GetProcAddress(library, name);
}
void pal::unload_library(dll_t library)
{
// No-op. On windows, we pin the library, so it can't be unloaded.
}
bool pal::get_default_packages_directory(string_t& recv)
{
if (!pal::getenv(_X("USERPROFILE"), recv))
{
return false;
}
append_path(recv, _X(".dnx"));
append_path(recv, _X("packages"));
return true;
}
bool pal::is_path_rooted(const string_t& path)
{
return path.length() >= 2 && path[1] == L':';
}
bool pal::getenv(const char_t* name, string_t& recv)
{
auto length = ::GetEnvironmentVariableW(name, nullptr, 0);
if (length == 0)
{
auto err = GetLastError();
if (err == ERROR_ENVVAR_NOT_FOUND)
{
// Leave the receiver empty and return success
return true;
}
trace::error(_X("failed to read enviroment variable '%s', HRESULT: 0x%X"), name, HRESULT_FROM_WIN32(GetLastError()));
return false;
}
auto buf = new char_t[length];
if (::GetEnvironmentVariableW(name, buf, length) == 0)
{
trace::error(_X("failed to read enviroment variable '%s', HRESULT: 0x%X"), name, HRESULT_FROM_WIN32(GetLastError()));
return false;
}
recv.assign(buf);
delete[] buf;
return true;
}
int pal::xtoi(const char_t* input)
{
return ::_wtoi(input);
}
bool pal::get_own_executable_path(string_t& recv)
{
char_t program_path[MAX_PATH];
DWORD dwModuleFileName = ::GetModuleFileNameW(NULL, program_path, MAX_PATH);
if (dwModuleFileName == 0 || dwModuleFileName >= MAX_PATH) {
return false;
}
recv.assign(program_path);
return true;
}
std::string pal::to_stdstring(const string_t& str)
{
// Calculate the size needed
auto length = ::WideCharToMultiByte(CP_ACP, 0, str.c_str(), -1, nullptr, 0, nullptr, nullptr);
// Allocate a string
auto buf = new char[length];
auto res = ::WideCharToMultiByte(CP_ACP, 0, str.c_str(), (int)str.length(), buf, length, nullptr, nullptr);
if (res == -1)
{
return std::string();
}
auto copied = std::string(buf);
delete[] buf;
return copied;
}
pal::string_t pal::to_palstring(const std::string& str)
{
// Calculate the size needed
auto length = ::MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, nullptr, 0);
// Allocate a string
auto buf = new char_t[length];
auto res = ::MultiByteToWideChar(CP_ACP, 0, str.c_str(), (int)str.length(), buf, length);
if (res == -1)
{
return string_t();
}
auto copied = string_t(buf);
delete[] buf;
return copied;
}
bool pal::realpath(string_t& path)
{
char_t buf[MAX_PATH];
auto res = ::GetFullPathNameW(path.c_str(), MAX_PATH, buf, nullptr);
if (res == 0 || res > MAX_PATH)
{
trace::error(_X("error resolving path: %s"), path.c_str());
return false;
}
path.assign(buf);
return true;
}
bool pal::file_exists(const string_t& path)
{
WIN32_FIND_DATAW data;
auto find_handle = ::FindFirstFileW(path.c_str(), &data);
bool found = find_handle != INVALID_HANDLE_VALUE;
::FindClose(find_handle);
return found;
}
std::vector<pal::string_t> pal::readdir(const string_t& path)
{
std::vector<string_t> files;
string_t search_string(path);
search_string.push_back(DIR_SEPARATOR);
search_string.push_back(L'*');
WIN32_FIND_DATAW data;
auto handle = ::FindFirstFileW(search_string.c_str(), &data);
do
{
string_t filepath(path);
filepath.push_back(DIR_SEPARATOR);
filepath.append(data.cFileName);
files.push_back(filepath);
} while (::FindNextFileW(handle, &data));
::FindClose(handle);
return files;
}

View file

@ -0,0 +1,248 @@
#include <set>
#include <functional>
#include "trace.h"
#include "tpafile.h"
#include "utils.h"
bool read_field(pal::string_t line, int& offset, pal::string_t& value_recv)
{
// The first character should be a '"'
if (line[offset] != '"')
{
trace::error(_X("error reading TPA file"));
return false;
}
offset++;
// Set up destination buffer (it can't be bigger than the original line)
pal::char_t buf[PATH_MAX];
auto buf_offset = 0;
// Iterate through characters in the string
for (; offset < line.length(); offset++)
{
// Is this a '\'?
if (line[offset] == '\\')
{
// Skip this character and read the next character into the buffer
offset++;
buf[buf_offset] = line[offset];
}
// Is this a '"'?
else if (line[offset] == '\"')
{
// Done! Advance to the pointer after the input
offset++;
break;
}
else
{
// Take the character
buf[buf_offset] = line[offset];
}
buf_offset++;
}
buf[buf_offset] = '\0';
value_recv.assign(buf);
// Consume the ',' if we have one
if (line[offset] == ',')
{
offset++;
}
return true;
}
bool tpafile::load(pal::string_t path)
{
// Check if the file exists, if not, there is nothing to add
if (!pal::file_exists(path))
{
return true;
}
// Open the file
pal::ifstream_t file(path);
if (!file.good())
{
// Failed to open the file!
return false;
}
// Read lines from the file
while (true)
{
std::string line;
std::getline(file, line);
auto line_palstr = pal::to_palstring(line);
if (file.eof())
{
break;
}
auto offset = 0;
tpaentry_t entry;
// Read fields
if (!(read_field(line_palstr, offset, entry.library_type))) return false;
if (!(read_field(line_palstr, offset, entry.library_name))) return false;
if (!(read_field(line_palstr, offset, entry.library_version))) return false;
if (!(read_field(line_palstr, offset, entry.library_hash))) return false;
if (!(read_field(line_palstr, offset, entry.asset_type))) return false;
if (!(read_field(line_palstr, offset, entry.asset_name))) return false;
if (!(read_field(line_palstr, offset, entry.relative_path))) return false;
m_entries.push_back(entry);
}
return true;
}
void tpafile::add_from_local_dir(const pal::string_t& dir)
{
trace::verbose(_X("adding files from %s to TPA"), dir.c_str());
const pal::char_t * const tpa_extensions[] = {
_X(".ni.dll"), // Probe for .ni.dll first so that it's preferred if ni and il coexist in the same dir
_X(".dll"),
_X(".ni.exe"),
_X(".exe"),
};
std::set<pal::string_t> added_assemblies;
// Get directory entries
auto files = pal::readdir(dir);
for (auto ext : tpa_extensions)
{
auto len = pal::strlen(ext);
for (auto file : files)
{
// Can't be a match if it's the same length as the extension :)
if (file.length() > len)
{
// Extract the same amount of text from the end of file name
auto file_ext = file.substr(file.length() - len, len);
// Check if this file name matches
if (pal::strcasecmp(ext, file_ext.c_str()) == 0)
{
// Get the assembly name by stripping the extension
// and add it to the set so we can de-dupe
auto asm_name = file.substr(0, file.length() - len);
// TODO(anurse): Also check if already in TPA file
if (added_assemblies.find(asm_name) == added_assemblies.end())
{
added_assemblies.insert(asm_name);
tpaentry_t entry;
entry.asset_type = pal::string_t(_X("runtime"));
entry.library_name = pal::string_t(asm_name);
entry.library_version = pal::string_t(_X(""));
pal::string_t relpath(dir);
relpath.push_back(DIR_SEPARATOR);
relpath.append(file);
entry.relative_path = relpath;
entry.asset_name = asm_name;
trace::verbose(_X("adding %s to TPA list from %s"), asm_name.c_str(), relpath.c_str());
m_entries.push_back(entry);
}
}
}
}
}
}
void tpafile::write_tpa_list(pal::string_t& output)
{
std::set<pal::string_t> items;
for (auto entry : m_entries)
{
if (pal::strcmp(entry.asset_type.c_str(), _X("runtime")) == 0 && items.find(entry.asset_name) == items.end())
{
// Resolve the full path
for (auto search_path : m_package_search_paths)
{
pal::string_t candidate;
candidate.reserve(search_path.length() +
entry.library_name.length() +
entry.library_version.length() +
entry.relative_path.length() + 3);
candidate.append(search_path);
append_path(candidate, entry.library_name.c_str());
append_path(candidate, entry.library_version.c_str());
append_path(candidate, entry.relative_path.c_str());
if (pal::file_exists(candidate))
{
trace::verbose(_X("adding tpa entry: %s"), candidate.c_str());
output.append(candidate);
output.push_back(PATH_SEPARATOR);
items.insert(entry.asset_name);
break;
}
}
}
}
}
void tpafile::write_native_paths(pal::string_t& output)
{
std::set<pal::string_t> items;
for (auto search_path : m_native_search_paths)
{
if (items.find(search_path) == items.end())
{
trace::verbose(_X("adding native search path: %s"), search_path.c_str());
output.append(search_path);
output.push_back(PATH_SEPARATOR);
items.insert(search_path);
}
}
for (auto entry : m_entries)
{
auto dir = entry.relative_path.substr(0, entry.relative_path.find_last_of(DIR_SEPARATOR));
if (pal::strcmp(entry.asset_type.c_str(), _X("native")) == 0 && items.find(dir) == items.end())
{
// Resolve the full path
for (auto search_path : m_package_search_paths)
{
pal::string_t candidate;
candidate.reserve(search_path.length() +
entry.library_name.length() +
entry.library_version.length() +
dir.length() + 3);
candidate.append(search_path);
append_path(candidate, entry.library_name.c_str());
append_path(candidate, entry.library_version.c_str());
append_path(candidate, entry.relative_path.c_str());
if (pal::file_exists(candidate))
{
trace::verbose(_X("adding native search path: %s"), candidate.c_str());
output.append(candidate);
output.push_back(PATH_SEPARATOR);
items.insert(dir);
break;
}
}
}
}
}
void tpafile::add_package_dir(pal::string_t dir)
{
m_package_search_paths.push_back(dir);
}
void tpafile::add_native_search_path(pal::string_t dir)
{
m_native_search_paths.push_back(dir);
}

View file

@ -0,0 +1,57 @@
#include "trace.h"
static trace::level_t g_level = trace::level_t::Error;
void trace::set_level(trace::level_t new_level)
{
g_level = new_level;
}
bool trace::is_enabled(trace::level_t level)
{
return level <= g_level;
}
void trace::verbose(const pal::char_t* format, ...)
{
if (trace::is_enabled(trace::level_t::Verbose))
{
va_list args;
va_start(args, format);
pal::err_vprintf(format, args);
va_end(args);
}
}
void trace::info(const pal::char_t* format, ...)
{
if (trace::is_enabled(trace::level_t::Info))
{
va_list args;
va_start(args, format);
pal::err_vprintf(format, args);
va_end(args);
}
}
void trace::error(const pal::char_t* format, ...)
{
if (trace::is_enabled(trace::level_t::Error))
{
va_list args;
va_start(args, format);
pal::err_vprintf(format, args);
va_end(args);
}
}
void trace::warning(const pal::char_t* format, ...)
{
if (trace::is_enabled(trace::level_t::Warning))
{
va_list args;
va_start(args, format);
pal::err_vprintf(format, args);
va_end(args);
}
}

View file

@ -0,0 +1,57 @@
#include "utils.h"
void append_path(pal::string_t& path1, const pal::char_t* path2)
{
if (pal::is_path_rooted(path2))
{
path1.assign(path2);
}
else
{
if (path1.back() != DIR_SEPARATOR)
{
path1.push_back(DIR_SEPARATOR);
}
path1.append(path2);
}
}
pal::string_t change_extension(const pal::string_t& filename, const pal::char_t* new_extension)
{
pal::string_t result(filename);
auto ext_sep = result.find_last_of('.');
if (ext_sep != pal::string_t::npos)
{
// We need to strip off the old extension
result.erase(ext_sep);
}
// Append the new extension
result.append(new_extension);
return result;
}
pal::string_t get_filename(const pal::string_t& path)
{
// Find the last dir separator
auto path_sep = path.find_last_of(DIR_SEPARATOR);
if (path_sep == pal::string_t::npos)
{
return pal::string_t(path);
}
return path.substr(path_sep + 1);
}
pal::string_t get_directory(const pal::string_t& path)
{
// Find the last dir separator
auto path_sep = path.find_last_of(DIR_SEPARATOR);
if (path_sep == pal::string_t::npos)
{
return pal::string_t(path);
}
return path.substr(0, path_sep);
}

View file

@ -5,14 +5,11 @@
}, },
"dependencies": { "dependencies": {
"Microsoft.NETCore.Runtime": "1.0.1-beta-23428",
"System.IO": "4.0.10-beta-23420", "System.IO": "4.0.10-beta-23420",
"System.Console": "4.0.0-beta-23420", "System.Console": "4.0.0-beta-23420",
"System.Runtime": "4.0.20-beta-23420", "System.Runtime": "4.0.20-beta-23420",
"System.Diagnostics.Process": "4.1.0-beta-23420", "System.Diagnostics.Process": "4.1.0-beta-23420",
"Microsoft.NETCore.Runtime": "1.0.1-beta-23428"
"Microsoft.NETCore.ConsoleHost": "1.0.0-beta-23428",
"Microsoft.NETCore.TestHost": "1.0.0-beta-23428"
}, },
"frameworks": { "frameworks": {