merge with master
This commit is contained in:
commit
15cbb75e45
55 changed files with 2065 additions and 310 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -35,3 +35,6 @@ TestResults/
|
|||
|
||||
# Profiler result files, just in case they are left lying around :)
|
||||
.vs/
|
||||
|
||||
# CMake generated files
|
||||
cmake/
|
|
@ -38,40 +38,174 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.Tools.Resg
|
|||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.ProjectModel", "src\Microsoft.DotNet.ProjectModel\Microsoft.DotNet.ProjectModel.xproj", "{303677D5-7312-4C3F-BAEE-BEB1A9BD9FE6}"
|
||||
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
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
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|x64 = Release|x64
|
||||
RelWithDebInfo|Any CPU = RelWithDebInfo|Any CPU
|
||||
RelWithDebInfo|x64 = RelWithDebInfo|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{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|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.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.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.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.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.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.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.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.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.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.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.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.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.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
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -85,5 +219,9 @@ Global
|
|||
{B559378C-FC03-45FA-893C-71784F28E0A2} = {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}
|
||||
{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
|
||||
EndGlobal
|
||||
|
|
|
@ -4,9 +4,9 @@ Build Status
|
|||
------------
|
||||
|
||||
| |Ubuntu 14.04 |Windows |Mac OS X |
|
||||
|---------|:------:|:------:|:------:|:------:|:-------:|:-------:|
|
||||
|**Debug**|[![Build Status](http://dotnet-ci.cloudapp.net/job/Private/job/dotnet_cli_debug_ubuntu/badge/icon)](http://dotnet-ci.cloudapp.net/job/Private/job/dotnet_cli_debug_ubuntu/)|[![Build Status](http://dotnet-ci.cloudapp.net/job/Private/job/dotnet_cli_debug_windows_nt/badge/icon)](http://dotnet-ci.cloudapp.net/job/Private/job/dotnet_cli_debug_windows_nt/)|[![Build Status](http://dotnet-ci.cloudapp.net/job/Private/job/dotnet_cli_debug_osx/badge/icon)](http://dotnet-ci.cloudapp.net/job/Private/job/dotnet_cli_debug_osx/) |
|
||||
|**Release**|[![Build Status](http://dotnet-ci.cloudapp.net/job/Private/job/dotnet_cli_release_ubuntu/badge/icon)](http://dotnet-ci.cloudapp.net/job/Private/job/dotnet_cli_release_ubuntu/)|[![Build Status](http://dotnet-ci.cloudapp.net/job/Private/job/dotnet_cli_release_windows_nt/badge/icon)](http://dotnet-ci.cloudapp.net/job/Private/job/dotnet_cli_release_windows_nt/)|[![Build Status](http://dotnet-ci.cloudapp.net/job/Private/job/dotnet_cli_release_osx/badge/icon)](http://dotnet-ci.cloudapp.net/job/Private/job/dotnet_cli_release_osx/) |
|
||||
|---------|:------:|:------:|:------:|
|
||||
|**Debug**|[![Build Status](http://dotnet-ci.cloudapp.net/buildStatus/icon?job=Private/dotnet_cli_debug_ubuntu)](http://dotnet-ci.cloudapp.net/job/Private/job/dotnet_cli_debug_ubuntu/)|[![Build Status](http://dotnet-ci.cloudapp.net/buildStatus/icon?job=Private/dotnet_cli_debug_windows_nt)](http://dotnet-ci.cloudapp.net/job/Private/job/dotnet_cli_debug_windows_nt/)|[![Build Status](http://dotnet-ci.cloudapp.net/buildStatus/icon?job=Private/dotnet_cli_debug_osx)](http://dotnet-ci.cloudapp.net/job/Private/job/dotnet_cli_debug_osx/) |
|
||||
|**Release**|[![Build Status](http://dotnet-ci.cloudapp.net/buildStatus/icon?job=Private/dotnet_cli_release_ubuntu)](http://dotnet-ci.cloudapp.net/job/Private/job/dotnet_cli_release_ubuntu/)|[![Build Status](http://dotnet-ci.cloudapp.net/buildStatus/icon?job=Private/dotnet_cli_release_windows_nt)](http://dotnet-ci.cloudapp.net/job/Private/job/dotnet_cli_release_windows_nt/)|[![Build Status](http://dotnet-ci.cloudapp.net/buildStatus/icon?job=Private/dotnet_cli_release_osx)](http://dotnet-ci.cloudapp.net/job/Private/job/dotnet_cli_release_osx/) |
|
||||
|
||||
|
||||
|
||||
|
|
1
build.sh
1
build.sh
|
@ -1,7 +1,6 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# $1 is passed to package to enable deb or pkg packaging
|
||||
|
||||
set -e
|
||||
|
||||
SOURCE="${BASH_SOURCE[0]}"
|
||||
|
|
68
scripts/_common.sh
Normal file
68
scripts/_common.sh
Normal file
|
@ -0,0 +1,68 @@
|
|||
# Source this to add some fancy stuff to your scripts
|
||||
|
||||
# Detect build servers
|
||||
if [[ ! -z "$JENKINS_URL" || ! -z "$BUILD_BUILDID" ]]; then
|
||||
# Jenkins or VSO build, disable colors because they make things gross.
|
||||
NO_COLOR=1
|
||||
fi
|
||||
|
||||
if [ "$NO_COLOR" != "1" ]; then
|
||||
# ANSI Colors
|
||||
RCol='\e[0m' # Text Reset
|
||||
|
||||
# Regular Bold Underline High Intensity BoldHigh Intens Background High Intensity Backgrounds
|
||||
Bla='\e[0;30m'; BBla='\e[1;30m'; UBla='\e[4;30m'; IBla='\e[0;90m'; BIBla='\e[1;90m'; On_Bla='\e[40m'; On_IBla='\e[0;100m';
|
||||
Red='\e[0;31m'; BRed='\e[1;31m'; URed='\e[4;31m'; IRed='\e[0;91m'; BIRed='\e[1;91m'; On_Red='\e[41m'; On_IRed='\e[0;101m';
|
||||
Gre='\e[0;32m'; BGre='\e[1;32m'; UGre='\e[4;32m'; IGre='\e[0;92m'; BIGre='\e[1;92m'; On_Gre='\e[42m'; On_IGre='\e[0;102m';
|
||||
Yel='\e[0;33m'; BYel='\e[1;33m'; UYel='\e[4;33m'; IYel='\e[0;93m'; BIYel='\e[1;93m'; On_Yel='\e[43m'; On_IYel='\e[0;103m';
|
||||
Blu='\e[0;34m'; BBlu='\e[1;34m'; UBlu='\e[4;34m'; IBlu='\e[0;94m'; BIBlu='\e[1;94m'; On_Blu='\e[44m'; On_IBlu='\e[0;104m';
|
||||
Pur='\e[0;35m'; BPur='\e[1;35m'; UPur='\e[4;35m'; IPur='\e[0;95m'; BIPur='\e[1;95m'; On_Pur='\e[45m'; On_IPur='\e[0;105m';
|
||||
Cya='\e[0;36m'; BCya='\e[1;36m'; UCya='\e[4;36m'; ICya='\e[0;96m'; BICya='\e[1;96m'; On_Cya='\e[46m'; On_ICya='\e[0;106m';
|
||||
Whi='\e[0;37m'; BWhi='\e[1;37m'; UWhi='\e[4;37m'; IWhi='\e[0;97m'; BIWhi='\e[1;97m'; On_Whi='\e[47m'; On_IWhi='\e[0;107m';
|
||||
fi
|
||||
|
||||
cecho()
|
||||
{
|
||||
local text=$1
|
||||
printf "%b\n" "$text"
|
||||
}
|
||||
|
||||
banner()
|
||||
{
|
||||
local text=$1
|
||||
cecho "${BGre}*** $text ***${RCol}"
|
||||
}
|
||||
|
||||
info()
|
||||
{
|
||||
local text=$1
|
||||
cecho "${Gre}info :${RCol} $text"
|
||||
}
|
||||
|
||||
warning()
|
||||
{
|
||||
local text=$1
|
||||
cecho "${Yel}warn :${RCol} $text" 1>&2
|
||||
}
|
||||
|
||||
error()
|
||||
{
|
||||
local text=$1
|
||||
cecho "${Red}error:${RCol} $text" 1>&2
|
||||
}
|
||||
|
||||
UNAME=$(uname)
|
||||
|
||||
if [ -z "$RID" ]; then
|
||||
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
|
||||
error "unknown OS: $UNAME" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
|
@ -13,68 +13,70 @@ popd
|
|||
set RID=win7-x64
|
||||
set TFM=dnxcore50
|
||||
set DNX_DIR=%REPOROOT%\artifacts\%RID%\dnx
|
||||
set STAGE0_DIR=%REPOROOT%\artifacts\%RID%\stage0
|
||||
set STAGE1_DIR=%REPOROOT%\artifacts\%RID%\stage1
|
||||
set STAGE2_DIR=%REPOROOT%\artifacts\%RID%\stage2
|
||||
set HOST_DIR=%REPOROOT%\artifacts\%RID%\corehost
|
||||
set START_PATH=%PATH%
|
||||
|
||||
where dnvm >nul 2>nul
|
||||
if %errorlevel% == 0 goto have_dnvm
|
||||
echo DNVM must be installed to bootstrap dotnet
|
||||
exit /B 1
|
||||
if "%CONFIGURATION%" equ "" set CONFIGURATION=Debug
|
||||
|
||||
:have_dnvm
|
||||
if not exist %DNX_DIR% mkdir %DNX_DIR%
|
||||
set DNX_HOME=%DNX_DIR%
|
||||
set DNX_USER_HOME=%DNX_DIR%
|
||||
set DNX_GLOBAL_HOME=%DNX_DIR%
|
||||
call %~dp0dnvm2.cmd upgrade -a dotnet_stage0
|
||||
if errorlevel 1 goto fail
|
||||
|
||||
echo Installing and use-ing the latest CoreCLR x64 DNX ...
|
||||
call dnvm install -nonative -u latest -r coreclr -arch x64 -alias dotnet_bootstrap
|
||||
pushd "%DNX_DIR%"
|
||||
cd "runtimes\dnx-*"
|
||||
set DNX_ROOT=%CD%\bin
|
||||
REM Gross! But CMD has no other way to do this :(
|
||||
where dotnet > "%temp%\dotnet-cli-build-temp.tmp"
|
||||
set /P DOTNET_PATH= < "%temp%\dotnet-cli-build-temp.tmp"
|
||||
pushd "%DOTNET_PATH%\.."
|
||||
set STAGE0_DIR=%CD%
|
||||
set DNX_ROOT=%STAGE0_DIR%\dnx
|
||||
popd
|
||||
if errorlevel 1 goto fail
|
||||
|
||||
call dnvm use dotnet_bootstrap -r coreclr -arch x64
|
||||
if errorlevel 1 goto fail
|
||||
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 %STAGE1_DIR% rd /s /q %STAGE1_DIR%
|
||||
if exist "%HOST_DIR%" rd /s /q "%HOST_DIR%"
|
||||
mkdir "%HOST_DIR%"
|
||||
copy "%CONFIGURATION%\*" "%HOST_DIR%"
|
||||
|
||||
echo Running 'dnu restore' to restore packages for DNX-hosted projects
|
||||
call dnu restore "%REPOROOT%"
|
||||
popd
|
||||
|
||||
if exist "%STAGE1_DIR%" rd /s /q "%STAGE1_DIR%"
|
||||
|
||||
echo Running 'dotnet restore' to restore packages
|
||||
call dotnet restore "%REPOROOT%"
|
||||
if errorlevel 1 goto fail
|
||||
|
||||
echo Building basic dotnet tools using older dotnet SDK version
|
||||
|
||||
set DOTNET_HOME=%STAGE0_DIR%
|
||||
set DOTNET_USER_HOME=%STAGE0_DIR%
|
||||
set DOTNET_GLOBAL_HOME=%STAGE0_DIR%
|
||||
|
||||
call %~dp0dnvm2 upgrade
|
||||
if errorlevel 1 goto fail
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
REM This should move into a proper build script of some kind once we are bootstrapped
|
||||
set PATH=%STAGE1_DIR%;%START_PATH%
|
||||
|
@ -82,52 +84,51 @@ set PATH=%STAGE1_DIR%;%START_PATH%
|
|||
if exist %STAGE2_DIR% rd /s /q %STAGE2_DIR%
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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 ...
|
||||
call %~dp0crossgen/crossgen_roslyn.cmd %STAGE2_DIR%
|
||||
call "%~dp0crossgen/crossgen_roslyn.cmd" "%STAGE2_DIR%"
|
||||
if errorlevel 1 goto fail
|
||||
|
||||
REM Copy DNX in to stage2
|
||||
xcopy /s /q %DNX_ROOT% %STAGE2_DIR%\dnx\
|
||||
xcopy /s /q "%DNX_ROOT%" "%STAGE2_DIR%\dnx\"
|
||||
|
||||
REM Clean up some things we don't need
|
||||
rd /s /q %STAGE2_DIR%\dnx\lib\Microsoft.Dnx.DesignTimeHost
|
||||
rd /s /q %STAGE2_DIR%\dnx\lib\Microsoft.Dnx.Project
|
||||
del %STAGE2_DIR%\dnx\dnu.cmd
|
||||
REM Copy the dotnet-restore script
|
||||
copy "%~dp0dotnet-restore.cmd" "%STAGE2_DIR%\dotnet-restore.cmd"
|
||||
|
||||
REM Copy and CHMOD the dotnet-restore script
|
||||
copy %~dp0dotnet-restore.cmd %STAGE2_DIR%\dotnet-restore.cmd
|
||||
|
||||
# Smoke-test the output
|
||||
REM Smoke-test the output
|
||||
set PATH=%STAGE2_DIR%;%START_PATH%
|
||||
|
||||
del "%REPOROOT%\test\TestApp\project.lock.json"
|
||||
dotnet restore "%REPOROOT%\test\TestApp" --runtime "%RID%"
|
||||
dotnet restore "%REPOROOT%\test\TestApp" --runtime "%RID%" --quiet
|
||||
dotnet publish "%REPOROOT%\test\TestApp" --framework "%TFM%" --runtime "%RID%" --output "%REPOROOT%\artifacts\%RID%\smoketest"
|
||||
|
||||
"%REPOROOT%/artifacts/%RID%/smoketest/TestApp"
|
||||
if errorlevel 1 goto fail
|
||||
|
||||
REM Check that a compiler error is reported
|
||||
dotnet compile "%REPOROOT%\test\compile\failing\SimpleCompilerError" --framework "%TFM%"
|
||||
dotnet compile "%REPOROOT%\test\compile\failing\SimpleCompilerError" --framework "%TFM%" >nul
|
||||
if %errorlevel% == 0 goto fail
|
||||
|
||||
echo Bootstrapped dotnet to %STAGE2_DIR%
|
||||
|
|
|
@ -2,11 +2,6 @@
|
|||
|
||||
set -e
|
||||
|
||||
[ -z "$CONFIGURATION" ] && CONFIGURATION=Debug
|
||||
|
||||
# TODO: Replace this with a dotnet generation
|
||||
TFM=dnxcore50
|
||||
|
||||
SOURCE="${BASH_SOURCE[0]}"
|
||||
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
|
||||
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
||||
|
@ -16,124 +11,110 @@ done
|
|||
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
||||
REPOROOT="$( cd -P "$DIR/.." && pwd )"
|
||||
|
||||
START_PATH=$PATH
|
||||
|
||||
echo "Bootstrapping dotnet.exe using DNX"
|
||||
|
||||
if [ -z "$RID" ]; then
|
||||
UNAME=$(uname)
|
||||
if [ "$UNAME" == "Darwin" ]; then
|
||||
RID=osx.10.10-x64
|
||||
elif [ "$UNAME" == "Linux" ]; then
|
||||
# Detect Distro?
|
||||
RID=ubuntu.14.04-x64
|
||||
else
|
||||
echo "Unknown OS: $UNAME" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
source "$DIR/_common.sh"
|
||||
|
||||
OUTPUT_ROOT=$REPOROOT/artifacts/$RID
|
||||
DNX_DIR=$OUTPUT_ROOT/dnx
|
||||
STAGE0_DIR=$OUTPUT_ROOT/stage0
|
||||
STAGE1_DIR=$OUTPUT_ROOT/stage1
|
||||
STAGE2_DIR=$OUTPUT_ROOT/stage2
|
||||
HOST_DIR=$OUTPUT_ROOT/corehost
|
||||
|
||||
if [ "$DOTNET_CI_SKIP_STAGE0_INSTALL" != "1" ]; then
|
||||
echo "Installing stage0"
|
||||
# Use a sub-shell to ensure the DNVM gets cleaned up
|
||||
rm -Rf $STAGE0_DIR
|
||||
mkdir -p $STAGE0_DIR
|
||||
$DIR/install-stage0.sh $STAGE0_DIR $DIR/dnvm2.sh
|
||||
else
|
||||
echo "Skipping stage0 because DOTNET_CI_SKIP_STAGE0_INSTALL"
|
||||
fi
|
||||
|
||||
export PATH=$STAGE0_DIR/bin:$PATH
|
||||
|
||||
echo "Installing and use-ing the latest CoreCLR x64 DNX ..."
|
||||
mkdir -p $DNX_DIR
|
||||
|
||||
export DNX_HOME=$DNX_DIR
|
||||
export DNX_USER_HOME=$DNX_DIR
|
||||
export DNX_GLOBAL_HOME=$DNX_DIR
|
||||
|
||||
if ! type dnvm > /dev/null 2>&1; then
|
||||
curl -o $DNX_DIR/dnvm.sh https://raw.githubusercontent.com/aspnet/Home/dev/dnvm.sh
|
||||
source $DNX_DIR/dnvm.sh
|
||||
fi
|
||||
|
||||
dnvm install latest -u -r coreclr
|
||||
|
||||
# Make sure we got a DNX
|
||||
if ! type dnx > /dev/null 2>&1; then
|
||||
echo "DNX is required to bootstrap stage1" 1>&2
|
||||
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
|
||||
|
||||
DNX_ROOT=$(dirname $(which dnx))
|
||||
[ -z "$CONFIGURATION" ] && CONFIGURATION=Debug
|
||||
|
||||
echo "Running 'dnu restore' to restore packages"
|
||||
# TODO: Replace this with a dotnet generation
|
||||
TFM=dnxcore50
|
||||
|
||||
dnu restore "$REPOROOT" --runtime osx.10.10-x64 --runtime ubuntu.14.04-x64 --runtime osx.10.11-x64
|
||||
REPOROOT="$( cd -P "$DIR/.." && pwd )"
|
||||
|
||||
START_PATH=$PATH
|
||||
|
||||
banner "Installing stage0"
|
||||
[ -d "~/.dotnet" ] || mkdir -p "~/.dotnet"
|
||||
source $DIR/dnvm2.sh
|
||||
dnvm upgrade -a dotnet_stage0
|
||||
DNX_ROOT="$(dirname $(which dotnet))/dnx"
|
||||
|
||||
banner "Restoring packages"
|
||||
|
||||
dotnet restore "$REPOROOT" --runtime osx.10.10-x64 --runtime ubuntu.14.04-x64 --runtime osx.10.11-x64 --quiet
|
||||
|
||||
# Clean up stage1
|
||||
[ -d "$STAGE1_DIR" ] && rm -Rf "$STAGE1_DIR"
|
||||
|
||||
echo "Building basic dotnet tools using Stage 0"
|
||||
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"
|
||||
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.Csc"
|
||||
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"
|
||||
|
||||
# Deploy CLR host to the output
|
||||
cp "$HOST_DIR/corehost" "$STAGE1_DIR"
|
||||
|
||||
# Add stage1 to the path and use it to build stage2
|
||||
export PATH=$STAGE1_DIR:$START_PATH
|
||||
|
||||
# Make corerun explicitly executable
|
||||
chmod a+x $STAGE1_DIR/corerun
|
||||
|
||||
# Clean up stage2
|
||||
[ -d "$STAGE2_DIR" ] && rm -Rf "$STAGE2_DIR"
|
||||
|
||||
echo "Building stage2 dotnet using stage1 ..."
|
||||
banner "Building stage2 dotnet using compiled stage1 ..."
|
||||
dotnet publish --framework "$TFM" --runtime $RID --output "$STAGE2_DIR" --configuration "$CONFIGURATION" "$REPOROOT/src/Microsoft.DotNet.Cli"
|
||||
dotnet publish --framework "$TFM" --runtime $RID --output "$STAGE2_DIR" --configuration "$CONFIGURATION" "$REPOROOT/src/Microsoft.DotNet.Tools.Compiler"
|
||||
dotnet publish --framework "$TFM" --runtime $RID --output "$STAGE2_DIR" --configuration "$CONFIGURATION" "$REPOROOT/src/Microsoft.DotNet.Tools.Compiler.Csc"
|
||||
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"
|
||||
|
||||
# Deploy CLR host to the output
|
||||
cp "$HOST_DIR/corehost" "$STAGE2_DIR"
|
||||
|
||||
# Make Stage 2 Folder Accessible
|
||||
chmod -R a+r $REPOROOT
|
||||
|
||||
# Copy DNX in to stage2
|
||||
cp -R $DNX_ROOT $STAGE2_DIR/dnx
|
||||
|
||||
# Clean up some things we don't need
|
||||
rm -Rf $STAGE2_DIR/dnx/lib/Microsoft.Dnx.DesignTimeHost
|
||||
rm -Rf $STAGE2_DIR/dnx/lib/Microsoft.Dnx.Project
|
||||
rm $STAGE2_DIR/dnx/dnu
|
||||
|
||||
# Copy and CHMOD the dotnet-restore script
|
||||
cp $DIR/dotnet-restore.sh $STAGE2_DIR/dotnet-restore
|
||||
chmod a+x $STAGE2_DIR/dotnet-restore
|
||||
|
||||
# Smoke-test the output
|
||||
banner "Testing stage2 ..."
|
||||
export PATH=$STAGE2_DIR:$START_PATH
|
||||
|
||||
rm "$REPOROOT/test/TestApp/project.lock.json"
|
||||
dotnet restore "$REPOROOT/test/TestApp" --runtime "$RID"
|
||||
dotnet publish "$REPOROOT/test/TestApp" --framework "$TFM" --runtime "$RID" --output "$REPOROOT/artifacts/$RID/smoketest"
|
||||
dotnet restore "$REPOROOT/test/TestApp"
|
||||
dotnet compile "$REPOROOT/test/TestApp" --output "$REPOROOT/artifacts/$RID/smoketest"
|
||||
|
||||
export CLRHOST_CLR_PATH=$STAGE2_DIR
|
||||
|
||||
OUTPUT=$($REPOROOT/artifacts/$RID/smoketest/TestApp)
|
||||
[ "$OUTPUT" == "This is a test app" ] || (echo "Smoke test failed!" && exit 1)
|
||||
[ "$OUTPUT" == "This is a test app" ] || (error "Smoke test failed!" && exit 1)
|
||||
|
||||
# Check that a compiler error is reported
|
||||
set +e
|
||||
dotnet compile "$REPOROOT/test/compile/failing/SimpleCompilerError" --framework "$TFM" 2>/dev/null >/dev/null
|
||||
rc=$?
|
||||
if [ $rc == 0 ]; then
|
||||
echo "Compiler failure test failed! The compiler did not fail to compile!"
|
||||
error "Compiler failure test failed! The compiler did not fail to compile!"
|
||||
exit 1
|
||||
fi
|
||||
set -e
|
||||
|
|
|
@ -1,7 +1,15 @@
|
|||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
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
|
||||
SCRIPT_DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
||||
|
||||
source "$SCRIPT_DIR/_common.sh"
|
||||
|
||||
# Some things depend on HOME and it may not be set. We should fix those things, but until then, we just patch a value in
|
||||
if [ -z "$HOME" ]; then
|
||||
|
@ -11,12 +19,9 @@ if [ -z "$HOME" ]; then
|
|||
mkdir -p $HOME
|
||||
fi
|
||||
|
||||
# Set the build number using CI build number
|
||||
BASE_VERSION=0.0.2-alpha1
|
||||
if [ ! -z "$BUILD_NUMBER" ]; then
|
||||
export DOTNET_BUILD_VERSION="$BASE_VERSION-$(printf "%05d" $BUILD_NUMBER)"
|
||||
echo "Building version $DOTNET_BUILD_VERSION"
|
||||
fi
|
||||
# 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.
|
||||
LAST_COMMIT_TIMESTAMP=$(git log -1 --format=%ct)
|
||||
export DOTNET_BUILD_VERSION=0.0.1-alpha-$(date -ud @$LAST_COMMIT_TIMESTAMP "+%Y%m%d-%H%M%S")
|
||||
|
||||
if [[ "$(uname)" == "Linux" ]]; then
|
||||
# Set Docker Container name to be unique
|
||||
|
|
10
scripts/cmake-gen.cmd
Normal file
10
scripts/cmake-gen.cmd
Normal 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
22
scripts/cmake-gen.sh
Executable 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
|
|
@ -8,27 +8,35 @@ popd
|
|||
REM Replace with a robust method for finding the right crossgen.exe
|
||||
set CROSSGEN_UTIL=%UserProfile%\.dnx\packages\runtime.win7-x64.Microsoft.NETCore.Runtime.CoreCLR\1.0.1-beta-23428\tools\crossgen.exe
|
||||
|
||||
REM Crossgen currently requires itself to be next to mscorlib
|
||||
copy %CROSSGEN_UTIL% /Y %BIN_DIR% > nul
|
||||
|
||||
pushd %BIN_DIR%
|
||||
|
||||
%CROSSGEN_UTIL% /nologo /Platform_Assemblies_Paths %BIN_DIR% System.Collections.Immutable.dll
|
||||
REM It must also be called mscorlib, not mscorlib.ni
|
||||
if exist mscorlib.ni.dll (
|
||||
copy /Y mscorlib.ni.dll mscorlib.dll > nul
|
||||
)
|
||||
|
||||
crossgen /nologo /ReadyToRun /Platform_Assemblies_Paths %BIN_DIR% System.Collections.Immutable.dll
|
||||
if not %errorlevel% EQU 0 goto fail
|
||||
|
||||
%CROSSGEN_UTIL% /nologo /Platform_Assemblies_Paths %BIN_DIR% System.Reflection.Metadata.dll
|
||||
crossgen /nologo /ReadyToRun /Platform_Assemblies_Paths %BIN_DIR% System.Reflection.Metadata.dll
|
||||
if not %errorlevel% EQU 0 goto fail
|
||||
|
||||
%CROSSGEN_UTIL% /nologo /Platform_Assemblies_Paths %BIN_DIR% Microsoft.CodeAnalysis.dll
|
||||
crossgen /nologo /ReadyToRun /Platform_Assemblies_Paths %BIN_DIR% Microsoft.CodeAnalysis.dll
|
||||
if not %errorlevel% EQU 0 goto fail
|
||||
|
||||
%CROSSGEN_UTIL% /nologo /Platform_Assemblies_Paths %BIN_DIR% Microsoft.CodeAnalysis.CSharp.dll
|
||||
crossgen /nologo /ReadyToRun /Platform_Assemblies_Paths %BIN_DIR% Microsoft.CodeAnalysis.CSharp.dll
|
||||
if not %errorlevel% EQU 0 goto fail
|
||||
|
||||
%CROSSGEN_UTIL% /nologo /Platform_Assemblies_Paths %BIN_DIR% Microsoft.CodeAnalysis.VisualBasic.dll
|
||||
crossgen /nologo /ReadyToRun /Platform_Assemblies_Paths %BIN_DIR% Microsoft.CodeAnalysis.VisualBasic.dll
|
||||
if not %errorlevel% EQU 0 goto fail
|
||||
|
||||
%CROSSGEN_UTIL% /nologo /Platform_Assemblies_Paths %BIN_DIR% csc.exe
|
||||
crossgen /nologo /ReadyToRun /Platform_Assemblies_Paths %BIN_DIR% csc.exe
|
||||
if not %errorlevel% EQU 0 goto fail
|
||||
|
||||
%CROSSGEN_UTIL% /nologo /Platform_Assemblies_Paths %BIN_DIR% vbc.exe
|
||||
crossgen /nologo /ReadyToRun /Platform_Assemblies_Paths %BIN_DIR% vbc.exe
|
||||
if not %errorlevel% EQU 0 goto fail
|
||||
|
||||
popd
|
||||
|
|
39
scripts/dev-install.sh
Executable file
39
scripts/dev-install.sh
Executable 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
|
|
@ -85,7 +85,7 @@ Set-Variable -Option Constant "DefaultUserDirectoryName" ".dotnet"
|
|||
Set-Variable -Option Constant "DefaultGlobalDirectoryName" "dotnet"
|
||||
Set-Variable -Option Constant "OldUserDirectoryNames" @(".kre", ".k")
|
||||
Set-Variable -Option Constant "RuntimePackageName" "dotnet"
|
||||
Set-Variable -Option Constant "DefaultFeed" "https://distaspnet.blob.core.windows.net/dotnet"
|
||||
Set-Variable -Option Constant "DefaultFeed" "https://dotnetcli.blob.core.windows.net/dotnet"
|
||||
Set-Variable -Option Constant "DefaultFeedKey" "DNX_FEED"
|
||||
Set-Variable -Option Constant "DefaultUnstableFeed" "https://aspdist.blob.core.windows.net/assets/dnvm/"
|
||||
Set-Variable -Option Constant "DefaultUnstableFeedKey" "DNX_UNSTABLE_FEED"
|
||||
|
@ -540,7 +540,7 @@ function Find-Package {
|
|||
_WriteOut "Determining latest version"
|
||||
$RuntimeId = $runtimeInfo.RuntimeId
|
||||
_WriteDebug "Latest RuntimeId: $RuntimeId"
|
||||
$url = Join-UrlFragments $Feed,$channel,"dnvm","index"
|
||||
$url = Join-UrlFragments $Feed,$channel,"dnvm","latest.win.index"
|
||||
_WriteDebug "Index URL: $url"
|
||||
|
||||
$wc = New-Object System.Net.WebClient
|
||||
|
@ -554,13 +554,14 @@ function Find-Package {
|
|||
}
|
||||
|
||||
if($runtimeInfo.Version -eq "latest") {
|
||||
$version = $index | ?{$_ -match "Latest: (?<version>.+)?"} | %{$matches["version"]}
|
||||
#/Binaries/0.0.1-alpha-00003/dotnet-osx-x64.0.0.1-alpha-00003.tar.gz
|
||||
$version = $index | ?{$_ -match "^.+/dotnet-$($runtimeInfo.OS)-$($runtimeInfo.Architecture).(?<version>.+)?.zip"} | %{$matches["version"]}
|
||||
} else {
|
||||
$version = $runtimeInfo.Version
|
||||
}
|
||||
|
||||
if($version) {
|
||||
$urlPart = $index | ?{$_ -match "Filename: (?<url>.+?$RuntimeId.$version.zip)"} | %{$matches["url"]}
|
||||
$urlPart = $index
|
||||
_WriteDebug "Found Package Path: $urlPart"
|
||||
$downloadUrl = Join-UrlFragments $Feed,$channel,$urlPart
|
||||
_WriteDebug "Found $version at $downloadUrl"
|
||||
|
|
|
@ -11,7 +11,7 @@ _DNVM_RUNTIME_FOLDER_NAME=".dotnet"
|
|||
_DNVM_COMMAND_NAME="dnvm"
|
||||
_DNVM_PACKAGE_MANAGER_NAME="dnu"
|
||||
_DNVM_VERSION_MANAGER_NAME=".NET Version Manager"
|
||||
_DNVM_DEFAULT_FEED="https://distaspnet.blob.core.windows.net/dotnet"
|
||||
_DNVM_DEFAULT_FEED="https://dotnetcli.blob.core.windows.net/dotnet"
|
||||
_DNVM_DEFAULT_CHANNEL="dev"
|
||||
_DNVM_DEFAULT_UNSTABLE_CHANNEL="dev"
|
||||
_DNVM_UPDATE_LOCATION="https://raw.githubusercontent.com/aspnet/Home/dev/dnvm.sh"
|
||||
|
@ -89,14 +89,13 @@ __dnvm_find_latest() {
|
|||
#dnx-coreclr-linux-x64
|
||||
local packageId="$_DNVM_RUNTIME_PACKAGE_NAME-$os-$arch"
|
||||
|
||||
local url="$DNX_ACTIVE_FEED/$DNX_ACTIVE_CHANNEL/dnvm/index"
|
||||
local url="$DNX_ACTIVE_FEED/$DNX_ACTIVE_CHANNEL/dnvm/latest.$os.index"
|
||||
local index="$(curl $url 2>/dev/null)"
|
||||
|
||||
local version="$(export IFS=; echo $index | sed -n 's/Latest: \(.*\)/\1/p')"
|
||||
local fullPackageId="$packageId.$version"
|
||||
local filename="$(export IFS=; echo $index | sed -n "s/Filename: \(.*$fullPackageId\)/\1/p")"
|
||||
local version="$(export IFS=; echo $index | sed -n "s/^.*$packageId\.\(.*\)\.tar\.gz$/\1/p")"
|
||||
|
||||
local downloadUrl="$DNX_ACTIVE_FEED/$DNX_ACTIVE_CHANNEL/$index"
|
||||
|
||||
local downloadUrl="$DNX_ACTIVE_FEED/$DNX_ACTIVE_CHANNEL/$filename"
|
||||
echo $version $downloadUrl
|
||||
}
|
||||
|
||||
|
@ -522,7 +521,7 @@ dnvm()
|
|||
if [[ "$versionOrAlias" == "latest" ]]; then
|
||||
echo "Determining latest version"
|
||||
read versionOrAlias downloadUrl < <(__dnvm_find_latest "$arch" "$os")
|
||||
echo "DownoadURL: $downloadUrl"
|
||||
echo "DownloadURL: $downloadUrl"
|
||||
[[ $? == 1 ]] && echo "Error: Could not find latest version from feed $DNX_ACTIVE_FEED" && return 1
|
||||
printf "%b\n" "Latest version is ${Cya}$versionOrAlias located at $downloadUrl${RCol}"
|
||||
else
|
||||
|
|
|
@ -1,14 +1,33 @@
|
|||
# Dockerfile that creates a container suitable to build dotnet-cli
|
||||
FROM microsoft/aspnet:1.0.0-beta8-coreclr
|
||||
FROM debian:jessie
|
||||
|
||||
RUN apt-get update
|
||||
RUN apt-get install -y wget
|
||||
# This could become a "microsoft/coreclr" image, since it just installs the dependencies for CoreCLR (and stdlib)
|
||||
# Install CoreCLR dependencies
|
||||
RUN apt-get update && \
|
||||
apt-get -qqy install unzip curl libicu-dev libunwind8 gettext libssl-dev libcurl3-gnutls zlib1g
|
||||
|
||||
# Install Package 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 wget -O - http://llvm.org/apt/llvm-snapshot.gpg.key | apt-key add -
|
||||
RUN apt-get update
|
||||
RUN apt-get install -y debhelper build-essential devscripts git liblttng-ust-dev lldb-3.6-dev
|
||||
# No longer need to install DNX since it is embedded (and soon will be gone!)
|
||||
|
||||
# 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 && \
|
||||
curl http://llvm.org/apt/llvm-snapshot.gpg.key | apt-key add - && \
|
||||
apt-get update && \
|
||||
apt-get install -y debhelper build-essential devscripts git liblttng-ust-dev lldb-3.6-dev lldb-3.6 clang
|
||||
|
||||
# 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
|
||||
WORKDIR /opt/code
|
||||
|
|
|
@ -8,6 +8,8 @@ while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symli
|
|||
done
|
||||
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
||||
|
||||
source $DIR/_common.sh
|
||||
|
||||
cd $DIR/..
|
||||
|
||||
[ -z "$DOTNET_BUILD_CONTAINER_TAG" ] && DOTNET_BUILD_CONTAINER_TAG="dotnetcli-build"
|
||||
|
@ -15,15 +17,15 @@ cd $DIR/..
|
|||
[ -z "$DOCKER_HOST_SHARE_DIR" ] && DOCKER_HOST_SHARE_DIR=$(pwd)
|
||||
[ -z "$BUILD_COMMAND" ] && BUILD_COMMAND="/opt/code/build.sh"
|
||||
|
||||
echo $DOCKER_HOST_SHARE_DIR
|
||||
|
||||
# Build the docker container (will be fast if it is already built)
|
||||
banner "Building Docker Container"
|
||||
docker build -t $DOTNET_BUILD_CONTAINER_TAG scripts/docker/
|
||||
|
||||
# Run the build in the container
|
||||
docker run --rm --sig-proxy=true \
|
||||
--name $DOTNET_BUILD_CONTAINER_NAME \
|
||||
banner "Launching build in Docker Container"
|
||||
info "Using code from: $DOCKER_HOST_SHARE_DIR"
|
||||
docker run -t --rm --sig-proxy=true \
|
||||
--name $DOTNET_BUILD_CONTAINER_NAME \
|
||||
-v $DOCKER_HOST_SHARE_DIR:/opt/code \
|
||||
-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
|
||||
|
|
|
@ -8,6 +8,8 @@ while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symli
|
|||
done
|
||||
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
||||
|
||||
source "$DIR/_common.sh"
|
||||
|
||||
cd $DIR/..
|
||||
|
||||
[ -z "$DOTNET_BUILD_CONTAINER_TAG" ] && DOTNET_BUILD_CONTAINER_TAG="dotnetcli-build"
|
||||
|
@ -15,13 +17,16 @@ cd $DIR/..
|
|||
[ -z "$DOCKER_HOST_SHARE_DIR" ] && DOCKER_HOST_SHARE_DIR=$(pwd)
|
||||
|
||||
# Build the docker container (will be fast if it is already built)
|
||||
info "Building docker container"
|
||||
docker build -t $DOTNET_BUILD_CONTAINER_TAG scripts/docker/
|
||||
|
||||
# First thing make sure all of our build containers are stopped
|
||||
info "Terminating and cleaning all running containers"
|
||||
docker stop $DOTNET_BUILD_CONTAINER_NAME
|
||||
docker rm $DOTNET_BUILD_CONTAINER_NAME
|
||||
|
||||
# Remove the sticky bit on directories created by docker so we can delete them
|
||||
info "Cleaning directories created by docker build"
|
||||
docker run --rm \
|
||||
-v $DOCKER_HOST_SHARE_DIR:/opt/code \
|
||||
-e DOTNET_BUILD_VERSION=$DOTNET_BUILD_VERSION \
|
||||
|
|
22
scripts/dockerrun.sh
Executable file
22
scripts/dockerrun.sh
Executable 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
|
|
@ -12,4 +12,4 @@ DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
|||
# work around restore timeouts on Mono
|
||||
[ -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" "$@"
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
STAGE0_DIR=$1
|
||||
DNVM_PATH=$2
|
||||
|
||||
export DOTNET_USER_HOME=$STAGE0_DIR
|
||||
|
||||
source $DNVM_PATH
|
||||
|
||||
dnvm upgrade -a dotnet_stage0
|
||||
|
||||
VER=`dnvm alias dotnet_stage0`
|
||||
mv $STAGE0_DIR/sdks/$VER $STAGE0_DIR/bin
|
|
@ -11,11 +11,10 @@ while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symli
|
|||
done
|
||||
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
||||
|
||||
UNAME=$(uname)
|
||||
source "$DIR/_common.sh"
|
||||
|
||||
|
||||
if [ "$UNAME" != "Linux" ]; then
|
||||
echo "Error: Build only supported on Linux"
|
||||
errro "Debian Package build only supported on Linux"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
@ -34,6 +33,8 @@ execute(){
|
|||
}
|
||||
|
||||
create_empty_debian_layout(){
|
||||
banner "Creating empty debian package layout"
|
||||
|
||||
rm -rf $PACKAGE_LAYOUT_DIR
|
||||
mkdir -p $PACKAGE_LAYOUT_DIR
|
||||
|
||||
|
@ -44,6 +45,8 @@ create_empty_debian_layout(){
|
|||
}
|
||||
|
||||
copy_files_to_debian_layout(){
|
||||
banner "Copying files to debian layout"
|
||||
|
||||
# Copy Built Binaries
|
||||
cp -a "$REPO_BINARIES_DIR/." "$PACKAGE_LAYOUT_DIR/package_root"
|
||||
|
||||
|
@ -52,12 +55,16 @@ copy_files_to_debian_layout(){
|
|||
}
|
||||
|
||||
create_debian_package(){
|
||||
banner "Packing .deb"
|
||||
|
||||
mkdir -p $PACKAGE_OUTPUT_DIR
|
||||
|
||||
|
||||
$REPO_ROOT/package_tool/package_tool $PACKAGE_LAYOUT_DIR $PACKAGE_OUTPUT_DIR
|
||||
}
|
||||
|
||||
test_debian_package(){
|
||||
banner "Testing debian package"
|
||||
|
||||
git clone https://github.com/sstephenson/bats.git /tmp/bats
|
||||
pushd /tmp/bats
|
||||
./install.sh /usr/local
|
||||
|
|
|
@ -8,22 +8,9 @@ while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symli
|
|||
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
|
||||
REPOROOT="$( cd -P "$DIR/.." && pwd )"
|
||||
|
||||
if [ -z "$DOTNET_BUILD_VERSION" ]; then
|
||||
TIMESTAMP=$(date "+%Y%m%d%H%M%S")
|
||||
|
@ -33,18 +20,20 @@ fi
|
|||
STAGE2_DIR=$REPOROOT/artifacts/$RID/stage2
|
||||
|
||||
if [ ! -d "$STAGE2_DIR" ]; then
|
||||
echo "Missing stage2 output in $STAGE2_DIR" 1>&2
|
||||
error "missing stage2 output in $STAGE2_DIR" 1>&2
|
||||
exit
|
||||
fi
|
||||
|
||||
PACKAGE_DIR=$REPOROOT/artifacts/packages/dnvm
|
||||
[ -d "$PACKAGE_DIR" ] || mkdir -p $PACKAGE_DIR
|
||||
|
||||
PACKAGE_NAME=$PACKAGE_DIR/dotnet-${OSNAME}-x64.${DOTNET_BUILD_VERSION}.tar.gz
|
||||
PACKAGE_SHORT_NAME=dotnet-${OSNAME}-x64.${DOTNET_BUILD_VERSION}
|
||||
PACKAGE_NAME=$PACKAGE_DIR/${PACKAGE_SHORT_NAME}.tar.gz
|
||||
|
||||
cd $STAGE2_DIR
|
||||
|
||||
# Correct all the mode flags
|
||||
banner "Packaging $PACKAGE_SHORT_NAME"
|
||||
|
||||
# Managed code doesn't need 'x'
|
||||
find . -type f -name "*.dll" | xargs chmod 644
|
||||
|
@ -63,6 +52,6 @@ find . -type f ! -name "*.*" | xargs chmod 755
|
|||
# Tar up the stage2 artifacts
|
||||
tar -czf $PACKAGE_NAME *
|
||||
|
||||
echo "Packaged stage2 to $PACKAGE_NAME"
|
||||
info "Packaged stage2 to $PACKAGE_NAME"
|
||||
|
||||
$DIR/publish.sh $PACKAGE_NAME
|
||||
|
|
|
@ -66,7 +66,7 @@ Write-Host "Uploading $fileName to dotnet feed.."
|
|||
|
||||
$Upload_URI = "https://$env:STORAGE_ACCOUNT.blob.core.windows.net/$env:STORAGE_CONTAINER/$env:CHANNEL/$Folder/$env:DOTNET_BUILD_VERSION/$fileName$env:SASTOKEN"
|
||||
|
||||
Invoke-WebRequest -URI $Upload_URI -Method PUT -Headers @{"x-ms-blob-type"="BlockBlob"; "x-ms-date"="2015-10-23";"x-ms-version"="2013-08-15"} -InFile $file
|
||||
Invoke-WebRequest -URI "$Upload_URI" -Method PUT -Headers @{"x-ms-blob-type"="BlockBlob"; "x-ms-date"="2015-10-23";"x-ms-version"="2013-08-15"} -InFile $file
|
||||
|
||||
$ReturnCode = $LASTEXITCODE
|
||||
|
||||
|
|
|
@ -8,11 +8,21 @@
|
|||
# $SASTOKEN
|
||||
# $REPO_ID
|
||||
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
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
|
||||
SCRIPT_DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
||||
|
||||
source "$SCRIPT_DIR/_common.sh"
|
||||
|
||||
UPLOAD_FILE=$1
|
||||
UPLOAD_JSON_FILE="package_upload.json"
|
||||
|
||||
banner "Publishing package"
|
||||
|
||||
execute(){
|
||||
if ! validate_env_variables; then
|
||||
# fail silently if the required variables are not available for publishing the file.
|
||||
|
@ -40,22 +50,22 @@ validate_env_variables(){
|
|||
local ret=0
|
||||
|
||||
if [[ -z "$DOTNET_BUILD_VERSION" ]]; then
|
||||
echo "DOTNET_BUILD_VERSION environment variable not set"
|
||||
warning "DOTNET_BUILD_VERSION environment variable not set"
|
||||
ret=1
|
||||
fi
|
||||
|
||||
if [[ -z "$SASTOKEN" ]]; then
|
||||
echo "SASTOKEN environment variable not set"
|
||||
warning "SASTOKEN environment variable not set"
|
||||
ret=1
|
||||
fi
|
||||
|
||||
if [[ -z "$STORAGE_ACCOUNT" ]]; then
|
||||
echo "STORAGE_ACCOUNT environment variable not set"
|
||||
warning "STORAGE_ACCOUNT environment variable not set"
|
||||
ret=1
|
||||
fi
|
||||
|
||||
if [[ -z "$STORAGE_CONTAINER" ]]; then
|
||||
echo "STORAGE_CONTAINER environment variable not set"
|
||||
warning "STORAGE_CONTAINER environment variable not set"
|
||||
ret=1
|
||||
fi
|
||||
|
||||
|
@ -68,9 +78,10 @@ validate_env_variables(){
|
|||
}
|
||||
|
||||
upload_file_to_blob_storage(){
|
||||
|
||||
local filename=$(basename $UPLOAD_FILE)
|
||||
|
||||
banner "Uploading $filename to blob storage"
|
||||
|
||||
if [[ $filename == *.deb || $filename == *.pkg ]]; then
|
||||
FOLDER="Installers"
|
||||
elif [[ $filename == *.tar.gz ]]; then
|
||||
|
@ -83,9 +94,9 @@ upload_file_to_blob_storage(){
|
|||
result=$?
|
||||
|
||||
if [ "$result" -gt "0" ]; then
|
||||
echo "Error: Uploading the $filename to blob storage - $result"
|
||||
error "uploading the $filename to blob storage - $result"
|
||||
else
|
||||
echo "Successfully uploaded $filename to blob storage."
|
||||
info "successfully uploaded $filename to blob storage."
|
||||
fi
|
||||
|
||||
return $result
|
||||
|
|
|
@ -8,10 +8,8 @@ namespace Microsoft.DotNet.Cli.Utils
|
|||
{
|
||||
internal static class Constants
|
||||
{
|
||||
// TODO: On Unix, exe suffix is empty string...
|
||||
public static readonly string ExeSuffix = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".exe" : "";
|
||||
public static readonly string CoreConsoleName = "coreconsole" + ExeSuffix;
|
||||
public static readonly string CoreRunName = "corerun" + ExeSuffix;
|
||||
public static readonly string ExeSuffix = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".exe" : string.Empty;
|
||||
public static readonly string HostExecutableName = "corehost" + ExeSuffix;
|
||||
public static readonly string DefaultConfiguration = "Debug";
|
||||
public static readonly string BinDirectoryName = "bin";
|
||||
public static readonly string ObjDirectoryName = "obj";
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,29 +9,29 @@ namespace Microsoft.Extensions.ProjectModel.Compilation
|
|||
/// <summary>
|
||||
/// Gets the library that produced this export
|
||||
/// </summary>
|
||||
public LibraryDescription Library { get; }
|
||||
|
||||
public LibraryDescription Library { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of fully-qualified paths to MSIL binaries required to run
|
||||
/// </summary>
|
||||
public IEnumerable<string> RuntimeAssemblies { get; }
|
||||
public IEnumerable<LibraryAsset> RuntimeAssemblies { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of fully-qualified paths to native binaries required to run
|
||||
/// </summary>
|
||||
public IEnumerable<string> NativeLibraries { get; }
|
||||
public IEnumerable<LibraryAsset> NativeLibraries { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of fully-qualified paths to MSIL metadata references
|
||||
/// </summary>
|
||||
public IEnumerable<string> CompilationAssemblies { get; }
|
||||
public IEnumerable<LibraryAsset> CompilationAssemblies { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of fully-qualified paths to source code file references
|
||||
/// </summary>
|
||||
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;
|
||||
CompilationAssemblies = compileAssemblies;
|
||||
|
@ -40,4 +40,4 @@ namespace Microsoft.Extensions.ProjectModel.Compilation
|
|||
NativeLibraries = nativeLibraries;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ namespace Microsoft.Extensions.ProjectModel.Compilation
|
|||
continue;
|
||||
}
|
||||
|
||||
var compilationAssemblies = new List<string>();
|
||||
var compilationAssemblies = new List<LibraryAsset>();
|
||||
var sourceReferences = new List<string>();
|
||||
|
||||
var libraryExport = GetExport(library);
|
||||
|
@ -71,7 +71,7 @@ namespace Microsoft.Extensions.ProjectModel.Compilation
|
|||
// so we rebuild the library export
|
||||
foreach (var reference in libraryExport.CompilationAssemblies)
|
||||
{
|
||||
if (seenMetadataReferences.Add(Path.GetFileNameWithoutExtension(reference)))
|
||||
if (seenMetadataReferences.Add(reference.Name))
|
||||
{
|
||||
compilationAssemblies.Add(reference);
|
||||
}
|
||||
|
@ -115,13 +115,13 @@ namespace Microsoft.Extensions.ProjectModel.Compilation
|
|||
|
||||
private LibraryExport ExportPackage(PackageDescription package)
|
||||
{
|
||||
var nativeLibraries = new List<string>();
|
||||
var nativeLibraries = new List<LibraryAsset>();
|
||||
PopulateAssets(package, package.Target.NativeLibraries, nativeLibraries);
|
||||
|
||||
var runtimeAssemblies = new List<string>();
|
||||
var runtimeAssemblies = new List<LibraryAsset>();
|
||||
PopulateAssets(package, package.Target.RuntimeAssemblies, runtimeAssemblies);
|
||||
|
||||
var compileAssemblies = new List<string>();
|
||||
var compileAssemblies = new List<LibraryAsset>();
|
||||
PopulateAssets(package, package.Target.CompileTimeAssemblies, compileAssemblies);
|
||||
|
||||
var sourceReferences = new List<string>();
|
||||
|
@ -135,14 +135,17 @@ namespace Microsoft.Extensions.ProjectModel.Compilation
|
|||
|
||||
private LibraryExport ExportProject(ProjectDescription project)
|
||||
{
|
||||
var compileAssemblies = new List<string>();
|
||||
var compileAssemblies = new List<LibraryAsset>();
|
||||
var sourceReferences = new List<string>();
|
||||
|
||||
if (!string.IsNullOrEmpty(project.TargetFrameworkInfo?.AssemblyPath))
|
||||
{
|
||||
// Project specifies a pre-compiled binary. We're done!
|
||||
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
|
||||
{
|
||||
|
@ -150,7 +153,10 @@ namespace Microsoft.Extensions.ProjectModel.Compilation
|
|||
var outputPath = GetOutputPath(project);
|
||||
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
|
||||
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)
|
||||
{
|
||||
var compilationOptions = project.Project.GetCompilerOptions(project.Framework, _configuration);
|
||||
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
|
||||
_configuration,
|
||||
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)
|
||||
|
@ -186,7 +191,7 @@ namespace Microsoft.Extensions.ProjectModel.Compilation
|
|||
|
||||
path = path.Replace("{configuration}", configuration);
|
||||
|
||||
return Path.Combine(project.ProjectDirectory, path);
|
||||
return path;
|
||||
}
|
||||
|
||||
private LibraryExport ExportFrameworkLibrary(LibraryDescription library)
|
||||
|
@ -200,10 +205,10 @@ namespace Microsoft.Extensions.ProjectModel.Compilation
|
|||
// since they assume the runtime library is present already
|
||||
return new LibraryExport(
|
||||
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<LibraryAsset>());
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -225,9 +230,11 @@ namespace Microsoft.Extensions.ProjectModel.Compilation
|
|||
continue;
|
||||
}
|
||||
|
||||
var path = Path.Combine(package.Path, assemblyPath);
|
||||
paths.Add(path);
|
||||
assets.Add(new LibraryAsset(
|
||||
Path.GetFileNameWithoutExtension(assemblyPath),
|
||||
assemblyPath,
|
||||
Path.Combine(package.Path, assemblyPath)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ namespace Microsoft.Extensions.ProjectModel
|
|||
{
|
||||
public LibraryDescription(
|
||||
LibraryIdentity identity,
|
||||
string hash,
|
||||
string path,
|
||||
IEnumerable<LibraryRange> dependencies,
|
||||
NuGetFramework framework,
|
||||
|
@ -25,6 +26,7 @@ namespace Microsoft.Extensions.ProjectModel
|
|||
{
|
||||
Path = path;
|
||||
Identity = identity;
|
||||
Hash = hash;
|
||||
Dependencies = dependencies ?? Enumerable.Empty<LibraryRange>();
|
||||
Framework = framework;
|
||||
Resolved = resolved;
|
||||
|
@ -32,6 +34,7 @@ namespace Microsoft.Extensions.ProjectModel
|
|||
}
|
||||
|
||||
public LibraryIdentity Identity { get; }
|
||||
public string Hash { get; }
|
||||
public HashSet<LibraryRange> RequestedRanges { get; } = new HashSet<LibraryRange>(new LibraryRangeEqualityComparer());
|
||||
public List<LibraryDescription> Parents { get; } = new List<LibraryDescription>();
|
||||
public string Path { get; }
|
||||
|
|
|
@ -7,12 +7,13 @@ namespace Microsoft.Extensions.ProjectModel
|
|||
{
|
||||
public PackageDescription(
|
||||
string path,
|
||||
LockFilePackageLibrary package,
|
||||
LockFileTargetLibrary lockFileLibrary,
|
||||
LockFilePackageLibrary package,
|
||||
LockFileTargetLibrary lockFileLibrary,
|
||||
IEnumerable<LibraryRange> dependencies,
|
||||
bool compatible)
|
||||
: base(
|
||||
new LibraryIdentity(package.Name, package.Version, LibraryType.Package),
|
||||
"sha512-" + package.Sha512,
|
||||
path,
|
||||
dependencies: dependencies,
|
||||
framework: null,
|
||||
|
|
|
@ -13,6 +13,7 @@ namespace Microsoft.Extensions.ProjectModel
|
|||
public ProjectDescription(string name, string path)
|
||||
: base(
|
||||
new LibraryIdentity(name, LibraryType.Project),
|
||||
string.Empty, // Projects don't have hashes
|
||||
path,
|
||||
Enumerable.Empty<LibraryRange>(),
|
||||
framework: null,
|
||||
|
@ -28,6 +29,7 @@ namespace Microsoft.Extensions.ProjectModel
|
|||
bool resolved) :
|
||||
base(
|
||||
new LibraryIdentity(project.Name, project.Version, LibraryType.Project),
|
||||
string.Empty, // Projects don't have hashes
|
||||
project.ProjectFilePath,
|
||||
dependencies,
|
||||
targetFrameworkInfo.FrameworkName,
|
||||
|
|
|
@ -42,6 +42,7 @@ namespace Microsoft.Extensions.ProjectModel.Resolution
|
|||
{
|
||||
return new LibraryDescription(
|
||||
new LibraryIdentity(libraryRange.Name, new NuGetVersion(assemblyVersion), LibraryType.ReferenceAssembly),
|
||||
string.Empty, // Framework assemblies don't have hashes
|
||||
path,
|
||||
Enumerable.Empty<LibraryRange>(),
|
||||
targetFramework,
|
||||
|
|
|
@ -13,6 +13,7 @@ namespace Microsoft.Extensions.ProjectModel.Resolution
|
|||
{
|
||||
return new LibraryDescription(
|
||||
new LibraryIdentity(libraryRange.Name, libraryRange.VersionRange?.MinVersion, libraryRange.Target),
|
||||
hash: null,
|
||||
path: null,
|
||||
dependencies: Enumerable.Empty<LibraryRange>(),
|
||||
framework: targetFramework,
|
||||
|
@ -20,4 +21,4 @@ namespace Microsoft.Extensions.ProjectModel.Resolution
|
|||
compatible: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
27
src/Microsoft.DotNet.ProjectModel/RuntimeIdentifier.cs
Normal file
27
src/Microsoft.DotNet.ProjectModel/RuntimeIdentifier.cs
Normal 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";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -41,7 +41,7 @@ namespace Microsoft.DotNet.Tools.Compiler.Csc
|
|||
{
|
||||
hostRoot = AppContext.BaseDirectory;
|
||||
}
|
||||
var corerun = Path.Combine(hostRoot, Constants.CoreRunName);
|
||||
var corerun = Path.Combine(hostRoot, Constants.HostExecutableName);
|
||||
var cscExe = Path.Combine(hostRoot, "csc.exe");
|
||||
return File.Exists(corerun) && File.Exists(cscExe)
|
||||
? Command.Create(corerun, $@"""{cscExe}"" {cscArgs}")
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
"dotnet-compile-csc": "Microsoft.DotNet.Tools.Compiler.Csc"
|
||||
},
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.TestHost": "1.0.0-beta-23428",
|
||||
"Microsoft.NETCore.Runtime": "1.0.1-beta-23428",
|
||||
|
||||
"System.Console": "4.0.0-beta-23428",
|
||||
|
|
|
@ -164,8 +164,13 @@ namespace Microsoft.DotNet.Tools.Compiler
|
|||
|
||||
// Get compilation options
|
||||
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
|
||||
var compilerArgs = new List<string>()
|
||||
{
|
||||
|
@ -178,13 +183,13 @@ namespace Microsoft.DotNet.Tools.Compiler
|
|||
compilerArgs.Add("-nowarn:CS1701");
|
||||
compilerArgs.Add("-nowarn:CS1702");
|
||||
compilerArgs.Add("-nowarn:CS1705");
|
||||
|
||||
|
||||
// Add compilation options to the args
|
||||
ApplyCompilationOptions(compilationOptions, compilerArgs);
|
||||
|
||||
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}\""));
|
||||
}
|
||||
|
||||
|
@ -239,6 +244,12 @@ namespace Microsoft.DotNet.Tools.Compiler
|
|||
|
||||
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);
|
||||
|
||||
return success;
|
||||
|
@ -320,6 +331,45 @@ namespace Microsoft.DotNet.Tools.Compiler
|
|||
Directory.CreateDirectory(path);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
Reporter.Output.Writer.WriteLine();
|
||||
|
@ -433,7 +483,7 @@ namespace Microsoft.DotNet.Tools.Compiler
|
|||
{
|
||||
var severity = error.category == CanonicalError.Parts.Category.Error ?
|
||||
DiagnosticMessageSeverity.Error : DiagnosticMessageSeverity.Warning;
|
||||
|
||||
|
||||
return new DiagnosticMessage(
|
||||
error.code,
|
||||
error.text,
|
||||
|
@ -449,7 +499,7 @@ namespace Microsoft.DotNet.Tools.Compiler
|
|||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private static void PrintDiagnostic(DiagnosticMessage diag)
|
||||
{
|
||||
switch (diag.Severity)
|
||||
|
|
|
@ -6,6 +6,7 @@ using System.Runtime.InteropServices;
|
|||
using Microsoft.Dnx.Runtime.Common.CommandLine;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
using Microsoft.Extensions.ProjectModel;
|
||||
using Microsoft.Extensions.ProjectModel.Compilation;
|
||||
using NuGet.Frameworks;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Publish
|
||||
|
@ -139,80 +140,31 @@ namespace Microsoft.DotNet.Tools.Publish
|
|||
PublishFiles(export.NativeLibraries, outputPath);
|
||||
}
|
||||
|
||||
int exitCode;
|
||||
if (context.RuntimeIdentifier.StartsWith("win"))
|
||||
{
|
||||
exitCode = PublishForWindows(context, outputPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
exitCode = PublishForUnix(context, outputPath);
|
||||
}
|
||||
// Publish the application itself
|
||||
PublishHost(context, outputPath);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
private static int PublishForWindows(ProjectContext context, string outputPath)
|
||||
private static int PublishHost(ProjectContext context, string outputPath)
|
||||
{
|
||||
if (context.TargetFramework.IsDesktop())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
var coreConsole = Path.Combine(outputPath, Constants.CoreConsoleName);
|
||||
if(!File.Exists(coreConsole))
|
||||
var hostPath = Path.Combine(AppContext.BaseDirectory, Constants.HostExecutableName);
|
||||
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());
|
||||
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());
|
||||
Reporter.Error.WriteLine($"Cannot find {Constants.HostExecutableName} in the dotnet directory.".Red());
|
||||
return 1;
|
||||
}
|
||||
|
||||
var outputExe = Path.Combine(outputPath, context.ProjectFile.Name + Constants.ExeSuffix);
|
||||
|
||||
// Rename the {app}.exe to {app}.dll
|
||||
File.Copy(outputExe, Path.ChangeExtension(outputExe, ".dll"), overwrite: true);
|
||||
|
||||
// Change coreconsole.exe to the {app}.exe name
|
||||
File.Copy(coreConsole, outputExe, overwrite: true);
|
||||
// Copy the host
|
||||
File.Copy(hostPath, outputExe, overwrite: true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -280,11 +232,11 @@ namespace Microsoft.DotNet.Tools.Publish
|
|||
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)
|
||||
{
|
||||
File.Copy(file, Path.Combine(outputPath, Path.GetFileName(file)), overwrite: true);
|
||||
File.Copy(file.ResolvedPath, Path.Combine(outputPath, Path.GetFileName(file.ResolvedPath)), overwrite: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
"resgen": "Microsoft.DotNet.Tools.Resgen"
|
||||
},
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.TestHost": "1.0.0-beta-23428",
|
||||
"Microsoft.NETCore.Runtime": "1.0.1-beta-23428",
|
||||
"System.Console": "4.0.0-beta-23428",
|
||||
"System.Collections": "4.0.11-beta-23428",
|
||||
|
|
33
src/corehost/CMakeLists.txt
Normal file
33
src/corehost/CMakeLists.txt
Normal 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
22
src/corehost/inc/args.h
Normal 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
|
36
src/corehost/inc/coreclr.h
Normal file
36
src/corehost/inc/coreclr.h
Normal 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
107
src/corehost/inc/pal.h
Normal 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
|
38
src/corehost/inc/tpafile.h
Normal file
38
src/corehost/inc/tpafile.h
Normal 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
24
src/corehost/inc/trace.h
Normal 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
11
src/corehost/inc/utils.h
Normal 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
73
src/corehost/src/args.cpp
Normal 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;
|
||||
}
|
107
src/corehost/src/coreclr.cpp
Normal file
107
src/corehost/src/coreclr.cpp
Normal 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
214
src/corehost/src/main.cpp
Normal 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);
|
||||
}
|
178
src/corehost/src/pal.unix.cpp
Normal file
178
src/corehost/src/pal.unix.cpp
Normal 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;
|
||||
}
|
177
src/corehost/src/pal.windows.cpp
Normal file
177
src/corehost/src/pal.windows.cpp
Normal 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;
|
||||
}
|
248
src/corehost/src/tpafile.cpp
Normal file
248
src/corehost/src/tpafile.cpp
Normal 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);
|
||||
}
|
57
src/corehost/src/trace.cpp
Normal file
57
src/corehost/src/trace.cpp
Normal 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);
|
||||
}
|
||||
}
|
57
src/corehost/src/utils.cpp
Normal file
57
src/corehost/src/utils.cpp
Normal 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);
|
||||
}
|
|
@ -5,14 +5,11 @@
|
|||
},
|
||||
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Runtime": "1.0.1-23428",
|
||||
"System.IO": "4.0.10-beta-23420",
|
||||
"System.Console": "4.0.0-beta-23420",
|
||||
"System.Runtime": "4.0.20-beta-23420",
|
||||
"System.Diagnostics.Process": "4.1.0-beta-23420",
|
||||
|
||||
"Microsoft.NETCore.ConsoleHost": "1.0.0-beta-23428",
|
||||
"Microsoft.NETCore.TestHost": "1.0.0-beta-23428"
|
||||
"Microsoft.NETCore.Runtime": "1.0.1-beta-23428"
|
||||
},
|
||||
|
||||
"frameworks": {
|
||||
|
|
Loading…
Reference in a new issue