2015-11-20 17:23:19 -08:00
using System ;
using System.Collections.Generic ;
2016-02-03 16:34:03 -08:00
using System.Linq ;
2016-04-19 22:51:32 -05:00
using Microsoft.DotNet.Cli.CommandLine ;
using Microsoft.DotNet.Cli.Utils ;
2015-11-20 17:23:19 -08:00
namespace Microsoft.DotNet.Tools.Compiler.Native
{
internal static class ArgumentsParser
{
internal static ArgValues Parse ( IEnumerable < string > args )
{
2016-04-19 22:51:32 -05:00
CommandLineApplication app = new CommandLineApplication ( ) ;
app . HelpOption ( "-h|--help" ) ;
2015-11-20 17:23:19 -08:00
2016-04-19 22:51:32 -05:00
CommandOption output = app . Option ( "--output <arg>" , "Output Directory for native executable." , CommandOptionType . SingleValue ) ;
CommandOption tempOutput = app . Option ( "--temp-output <arg>" , "Directory for intermediate files." , CommandOptionType . SingleValue ) ;
2015-12-16 15:45:24 -08:00
2016-04-19 22:51:32 -05:00
CommandOption configuration = app . Option ( "--configuration <arg>" , "debug/release build configuration. Defaults to debug." , CommandOptionType . SingleValue ) ;
CommandOption mode = app . Option ( "--mode <arg>" , "Code Generation mode. Defaults to ryujit." , CommandOptionType . SingleValue ) ;
2015-11-20 17:23:19 -08:00
2016-04-19 22:51:32 -05:00
CommandOption reference = app . Option ( "--reference <arg>..." , "Use to specify Managed DLL references of the app." , CommandOptionType . MultipleValue ) ;
2015-11-20 17:23:19 -08:00
2016-04-19 22:51:32 -05:00
// Custom Extensibility Points to support CoreRT workflow TODO better descriptions
CommandOption ilcarg = app . Option ( "--ilcarg <arg>..." , "Use to specify custom arguments for the IL Compiler." , CommandOptionType . MultipleValue ) ;
CommandOption ilcpath = app . Option ( "--ilcpath <arg>" , "Use to specify a custom build of IL Compiler." , CommandOptionType . SingleValue ) ;
CommandOption ilcsdkpath = app . Option ( "ilcsdkpath <arg>" , "Use to specify a custom build of IL Compiler SDK" , CommandOptionType . SingleValue ) ;
2015-11-20 17:23:19 -08:00
2016-04-19 22:51:32 -05:00
CommandOption linklib = app . Option ( "--linklib <arg>..." , "Use to link in additional static libs" , CommandOptionType . MultipleValue ) ;
2015-12-19 12:14:46 -08:00
2016-04-19 22:51:32 -05:00
// TEMPORARY Hack until CoreRT compatible Framework Libs are available
CommandOption appdepsdk = app . Option ( "--appdepsdk <arg>" , "Use to plug in custom appdepsdk path" , CommandOptionType . SingleValue ) ;
2015-11-20 17:23:19 -08:00
2016-04-19 22:51:32 -05:00
// Optional Log Path
CommandOption logpath = app . Option ( "--logpath <arg>" , "Use to dump Native Compilation Logs to a file." , CommandOptionType . SingleValue ) ;
2015-11-20 17:23:19 -08:00
2016-04-19 22:51:32 -05:00
// Optional flags to be passed to the native compiler
CommandOption cppcompilerflags = app . Option ( "--cppcompilerflags <arg>" , "Additional flags to be passed to the native compiler." , CommandOptionType . SingleValue ) ;
2015-11-20 17:23:19 -08:00
2016-04-19 22:51:32 -05:00
CommandArgument inputAssembly = app . Argument ( "INPUT_ASSEMBLY" , "The managed input assembly to compile to native." ) ;
2015-12-20 20:46:28 -08:00
2016-04-19 22:51:32 -05:00
ArgValues argValues = new ArgValues ( ) ;
app . OnExecute ( ( ) = >
{
if ( string . IsNullOrEmpty ( inputAssembly . Value ) )
{
Reporter . Error . WriteLine ( "Input Assembly is a required parameter." ) ;
return 1 ;
}
2016-02-03 16:34:03 -08:00
2016-04-19 22:51:32 -05:00
if ( configuration . HasValue ( ) )
{
try
2015-11-20 17:23:19 -08:00
{
2016-04-19 22:51:32 -05:00
argValues . BuildConfiguration = EnumExtensions . Parse < BuildConfiguration > ( configuration . Value ( ) ) ;
2015-11-20 17:23:19 -08:00
}
2016-04-19 22:51:32 -05:00
catch ( ArgumentException )
2015-11-20 17:23:19 -08:00
{
2016-04-19 22:51:32 -05:00
Reporter . Error . WriteLine ( $"Invalid Configuration Option: {configuration}" ) ;
return 1 ;
2015-11-20 17:23:19 -08:00
}
2016-04-19 22:51:32 -05:00
}
2015-11-20 17:23:19 -08:00
2016-04-19 22:51:32 -05:00
if ( mode . HasValue ( ) )
{
try
2015-11-20 17:23:19 -08:00
{
2016-04-19 22:51:32 -05:00
argValues . NativeMode = EnumExtensions . Parse < NativeIntermediateMode > ( mode . Value ( ) ) ;
2015-11-20 17:23:19 -08:00
}
2016-04-19 22:51:32 -05:00
catch ( ArgumentException )
{
Reporter . Error . WriteLine ( $"Invalid Mode Option: {mode}" ) ;
return 1 ;
}
}
argValues . InputManagedAssemblyPath = inputAssembly . Value ;
argValues . OutputDirectory = output . Value ( ) ;
argValues . IntermediateDirectory = tempOutput . Value ( ) ;
argValues . Architecture = ArchitectureMode . x64 ;
argValues . ReferencePaths = reference . Values ;
argValues . IlcArgs = ilcarg . Values . Select ( s = >
{
if ( ! s . StartsWith ( "\"" ) | | ! s . EndsWith ( "\"" ) )
2016-02-03 16:34:03 -08:00
{
2016-04-19 22:51:32 -05:00
throw new ArgumentException ( "--ilcarg must be specified in double quotes" , "ilcarg" ) ;
}
return s . Substring ( 1 , s . Length - 2 ) ;
2015-11-20 17:23:19 -08:00
} ) ;
2016-04-19 22:51:32 -05:00
argValues . IlcPath = ilcpath . Value ( ) ;
argValues . IlcSdkPath = ilcsdkpath . Value ( ) ;
argValues . LinkLibPaths = linklib . Values ;
argValues . AppDepSDKPath = appdepsdk . Value ( ) ;
argValues . LogPath = logpath . Value ( ) ;
argValues . CppCompilerFlags = cppcompilerflags . Value ( ) ;
Reporter . Output . WriteLine ( $"Input Assembly: {inputAssembly}" ) ;
return 0 ;
} ) ;
try
{
argValues . ReturnCode = app . Execute ( args . ToArray ( ) ) ;
2015-11-20 17:23:19 -08:00
}
2016-04-19 22:51:32 -05:00
catch ( Exception ex )
2015-11-20 17:23:19 -08:00
{
2016-04-19 22:51:32 -05:00
#if DEBUG
Console . Error . WriteLine ( ex ) ;
#else
Console . Error . WriteLine ( ex . Message ) ;
#endif
argValues . ReturnCode = 1 ;
2015-12-16 15:45:24 -08:00
}
2016-04-19 22:51:32 -05:00
if ( argValues . ReturnCode ! = 0 )
2015-12-16 15:45:24 -08:00
{
2016-04-19 22:51:32 -05:00
argValues . IsHelp = true ;
2015-11-20 17:23:19 -08:00
}
2016-04-19 22:51:32 -05:00
return argValues ;
2015-11-20 17:23:19 -08:00
}
}
}