// Licensed under the terms of the GNU GPL
//
// (C) 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com)
+// (C) 2004 Novell, Inc
//
namespace Mono.CSharp
using System.IO;
using System.Text;
using System.Globalization;
- using Mono.Languages;
+ using System.Diagnostics;
- enum Target {
+ public enum Target {
Library, Exe, Module, WinExe
};
//
static ArrayList soft_references;
+ //
+ // Modules to be linked
+ //
+ static ArrayList modules;
+
// Lookup paths
static ArrayList link_paths;
- // Whether we want Yacc to output its progress
- static bool yacc_verbose = false;
-
// Whether we want to only run the tokenizer
static bool tokenize = false;
static string first_source;
- static Target target = Target.Exe;
- static string target_ext = ".exe";
-
static bool want_debugging_support = false;
static bool parse_only = false;
static bool timestamps = false;
static bool pause = false;
static bool show_counters = false;
- public static bool parser_verbose = false;
//
// Whether to load the initial config file (what CSC.RSP has by default)
//
static ArrayList resources;
static ArrayList embedded_resources;
-
+ static string win32ResourceFile;
+ static string win32IconFile;
+
//
// An array of the defines from the command line
//
// Whether the user has specified a different encoder manually
//
static bool using_default_encoder = true;
-
+
public static void ShowTime (string msg)
{
if (!timestamps)
int token, tokens = 0, errors = 0;
while ((token = lexer.token ()) != Token.EOF){
- Location l = lexer.Location;
tokens++;
if (token == Token.ERROR)
errors++;
SeekableStreamReader reader = new SeekableStreamReader (input, encoding, using_default_encoder);
parser = new CSharpParser (reader, file, defines);
- parser.yacc_verbose = yacc_verbose;
try {
parser.parse ();
} catch (Exception ex) {
input.Close ();
}
}
+
+ static void OtherFlags ()
+ {
+ Console.WriteLine (
+ "Other flags in the compiler\n" +
+ " --fatal Makes errors fatal\n" +
+ " --parse Only parses the source file\n" +
+ " --stacktrace Shows stack trace at error location\n" +
+ " --timestamp Displays time stamps of various compiler events\n" +
+ " -2 Enables experimental C# features\n" +
+ " -v Verbose parsing (for debugging the parser)\n" +
+ " --mcs-debug X Sets MCS debugging level to X\n");
+ }
static void Usage ()
{
"Mono C# compiler, (C) 2001 - 2003 Ximian, Inc.\n" +
"mcs [options] source-files\n" +
" --about About the Mono C# compiler\n" +
+ " -addmodule:MODULE Adds the module to the generated assembly\n" +
" -checked[+|-] Set default context to checked\n" +
" -codepage:ID Sets code page to the one in ID\n" +
" (number, `utf8' or `reset')\n" +
+ " -clscheck[+|-] Disables CLS Compliance verifications" + Environment.NewLine +
" -define:S1[;S2] Defines one or more symbols (short: /d:)\n" +
- " -debug[+-] Generate debugging information\n" +
+ " -debug[+|-] Generate debugging information\n" +
+ " -delaysign[+|-] Only insert the public key into the assembly (no signing)\n" +
" -doc:FILE XML Documentation file to generate\n" +
" -g Generate debugging information\n" +
- " --fatal Makes errors fatal\n" +
+ " -keycontainer:NAME The key pair container used to strongname the assembly\n" +
+ " -keyfile:FILE The strongname key file used to strongname the assembly\n" +
+ " -langversion:TEXT Specifies language version modes: ISO-1 or Default" + Environment.NewLine +
" -lib:PATH1,PATH2 Adds the paths to the assembly link path\n" +
" -main:class Specified the class that contains the entry point\n" +
" -noconfig[+|-] Disables implicit references to assemblies\n" +
" -nostdlib[+|-] Does not load core libraries\n" +
" -nowarn:W1[,W2] Disables one or more warnings\n" +
" -out:FNAME Specifies output file\n" +
- " --parse Only parses the source file\n" +
+ " -pkg:P1[,Pn] References packages P1..Pn\n" +
" --expect-error X Expect that error X will be encountered\n" +
" -recurse:SPEC Recursively compiles the files in SPEC ([dir]/file)\n" +
" -reference:ASS References the specified assembly (-r:ASS)\n" +
- " --stacktrace Shows stack trace at error location\n" +
" -target:KIND Specifies the target (KIND is one of: exe, winexe,\n" +
" library, module), (short: /t:)\n" +
- " --timestamp Displays time stamps of various compiler events\n" +
" -unsafe[+|-] Allows unsafe code\n" +
" -warnaserror[+|-] Treat warnings as errors\n" +
" -warn:LEVEL Sets warning level (the highest is 4, the default is 2)\n" +
- " -v Verbose parsing (for debugging the parser)\n" +
- " -2 Enables experimental C# features\n" +
+ " -help2 Show other help flags\n" +
"\n" +
"Resources:\n" +
" -linkresource:FILE[,ID] Links FILE as a resource\n" +
" -resource:FILE[,ID] Embed FILE as a resource\n" +
- " --mcs-debug X Sets MCS debugging level to X\n" +
- " @file Read response file for more options\n\n" +
+ " -win32res:FILE Specifies Win32 resource file (.res)\n" +
+ " -win32icon:FILE Use this icon for the output\n" +
+ " @file Read response file for more options\n\n" +
"Options can be of the form -option or /option");
}
"For more information on Mono, visit the project Web site\n" +
" http://www.go-mono.com\n\n" +
- "The compiler was written by Miguel de Icaza, Ravi Pratap and Martin Baulig");
+ "The compiler was written by Miguel de Icaza, Ravi Pratap, Martin Baulig, Marek Safar, Raja Harinath, Raja Harinath, Raja Harinath, Raja Harinath, Raja Harinath, Raja Harinath, Raja Harinath, Raja Harinath, Raja R Harinath");
Environment.Exit (0);
}
bool ok = MainDriver (args);
if (ok && Report.Errors == 0) {
- Console.Write("Compilation succeeded");
if (Report.Warnings > 0) {
- Console.Write(" - {0} warning(s)", Report.Warnings);
+ Console.WriteLine ("Compilation succeeded - {0} warning(s)", Report.Warnings);
}
- Console.WriteLine();
if (show_counters){
Console.WriteLine ("Counter1: " + counter1);
Console.WriteLine ("Counter2: " + counter2);
string total_log = "";
try {
- char[] path_chars = { '/', '\\', '.' };
+ char[] path_chars = { '/', '\\' };
if (assembly.IndexOfAny (path_chars) != -1) {
a = Assembly.LoadFrom (assembly);
} else {
- a = Assembly.Load (assembly);
+ string ass = assembly;
+ if (ass.EndsWith (".dll") || ass.EndsWith (".exe"))
+ ass = assembly.Substring (0, assembly.Length - 4);
+ a = Assembly.Load (ass);
}
TypeManager.AddAssembly (a);
} catch (FileNotFoundException){
foreach (string dir in link_paths){
string full_path = Path.Combine (dir, assembly);
- if (!assembly.EndsWith (".dll"))
+ if (!assembly.EndsWith (".dll") && !assembly.EndsWith (".exe"))
full_path += ".dll";
try {
}
}
+ static public void LoadModule (MethodInfo adder_method, string module)
+ {
+ Module m;
+ string total_log = "";
+
+ try {
+ try {
+ m = (Module)adder_method.Invoke (CodeGen.Assembly.Builder, new object [] { module });
+ }
+ catch (TargetInvocationException ex) {
+ throw ex.InnerException;
+ }
+ TypeManager.AddModule (m);
+
+ }
+ catch (FileNotFoundException){
+ foreach (string dir in link_paths){
+ string full_path = Path.Combine (dir, module);
+ if (!module.EndsWith (".netmodule"))
+ full_path += ".netmodule";
+
+ try {
+ try {
+ m = (Module)adder_method.Invoke (CodeGen.Assembly.Builder, new object [] { full_path });
+ }
+ catch (TargetInvocationException ex) {
+ throw ex.InnerException;
+ }
+ TypeManager.AddModule (m);
+ return;
+ } catch (FileNotFoundException ff) {
+ total_log += ff.FusionLog;
+ continue;
+ }
+ }
+ Report.Error (6, "Cannot find module `" + module + "'" );
+ Console.WriteLine ("Log: \n" + total_log);
+ } catch (BadImageFormatException f) {
+ Report.Error(6, "Cannot load module (bad file format)" + f.FusionLog);
+ } catch (FileLoadException f){
+ Report.Error(6, "Cannot load module " + f.FusionLog);
+ } catch (ArgumentNullException){
+ Report.Error(6, "Cannot load module (null argument)");
+ }
+ }
+
/// <summary>
/// Loads all assemblies referenced on the command line
/// </summary>
//
static void SplitPathAndPattern (string spec, out string path, out string pattern)
{
- int p = spec.LastIndexOf ("/");
+ int p = spec.LastIndexOf ('/');
if (p != -1){
//
// Windows does not like /file.cs, switch that to:
return;
}
- p = spec.LastIndexOf ("\\");
+ p = spec.LastIndexOf ('\\');
if (p != -1){
path = spec.Substring (0, p);
pattern = spec.Substring (p + 1);
string path, pattern;
SplitPathAndPattern (spec, out path, out pattern);
- if (pattern.IndexOf ("*") == -1){
+ if (pattern.IndexOf ('*') == -1){
ProcessFile (spec);
return;
}
static void TestWarningConflict ()
{
- if (Report.Warnings == 0 && Report.WarningsAreErrors) {
+ if (RootContext.WarningLevel == 0 && Report.WarningsAreErrors) {
Report.Error (1901, "Conflicting options specified: Warning level 0; Treat warnings as errors");
Environment.Exit (1);
}
static void SetupV2 ()
{
- RootContext.V2 = true;
+ RootContext.Version = LanguageVersion.Default;
defines.Add ("__V2__");
}
static bool UnixParseOption (string arg, ref string [] args, ref int i)
{
switch (arg){
- case "-vv":
- parser_verbose = true;
- return true;
-
case "-v":
- yacc_verbose = true;
+ CSharpParser.yacc_verbose_flag++;
return true;
case "--version":
Usage ();
Environment.Exit (0);
return true;
-
+
case "--define":
if ((i + 1) >= args.Length){
Usage ();
string type = args [++i];
switch (type){
case "library":
- target = Target.Library;
- target_ext = ".dll";
+ RootContext.Target = Target.Library;
+ RootContext.TargetExt = ".dll";
break;
case "exe":
- target = Target.Exe;
+ RootContext.Target = Target.Exe;
break;
case "winexe":
- target = Target.WinExe;
+ RootContext.Target = Target.WinExe;
break;
case "module":
- target = Target.Module;
- target_ext = ".dll";
+ RootContext.Target = Target.Module;
+ RootContext.TargetExt = ".dll";
break;
default:
TargetUsage ();
//
static bool CSCParseOption (string option, ref string [] args, ref int i)
{
- int idx = option.IndexOf (":");
+ int idx = option.IndexOf (':');
string arg, value;
if (idx == -1){
case "/target":
switch (value){
case "exe":
- target = Target.Exe;
+ RootContext.Target = Target.Exe;
break;
case "winexe":
- target = Target.WinExe;
+ RootContext.Target = Target.WinExe;
break;
case "library":
- target = Target.Library;
- target_ext = ".dll";
+ RootContext.Target = Target.Library;
+ RootContext.TargetExt = ".dll";
break;
case "module":
- target = Target.Module;
- target_ext = ".netmodule";
+ RootContext.Target = Target.Module;
+ RootContext.TargetExt = ".netmodule";
break;
default:
resources.Add (value);
return true;
+
+ case "/pkg": {
+ string packages;
+
+ if (value == ""){
+ Usage ();
+ Environment.Exit (1);
+ }
+ packages = String.Join (" ", value.Split (new Char [] { ';', ',', '\n', '\r'}));
+
+ ProcessStartInfo pi = new ProcessStartInfo ();
+ pi.FileName = "pkg-config";
+ pi.RedirectStandardOutput = true;
+ pi.UseShellExecute = false;
+ pi.Arguments = "--libs " + packages;
+ Process p = null;
+ try {
+ p = Process.Start (pi);
+ } catch (Exception e) {
+ Report.Error (-27, "Couldn't run pkg-config: " + e.Message);
+ Environment.Exit (1);
+ }
+
+ if (p.StandardOutput == null){
+ Report.Warning (-27, "Specified package did not return any information");
+ return true;
+ }
+ string pkgout = p.StandardOutput.ReadToEnd ();
+ p.WaitForExit ();
+ if (p.ExitCode != 0) {
+ Report.Error (-27, "Error running pkg-config. Check the above output.");
+ Environment.Exit (1);
+ }
+
+ if (pkgout != null){
+ string [] xargs = pkgout.Trim (new Char [] {' ', '\n', '\r', '\t'}).
+ Split (new Char [] { ' ', '\t'});
+ args = AddArgs (args, xargs);
+ }
+
+ p.Close ();
+ return true;
+ }
case "/res":
case "/resource":
if (value == ""){
- Report.Error (5, arg + " requires an argument");
+ Report.Error (5, "-resource requires an argument");
Environment.Exit (1);
}
if (embedded_resources == null)
embedded_resources = new ArrayList ();
- embedded_resources.Add (value);
+ if (embedded_resources.Contains (value)) {
+ Report.Error (1508, String.Format ("The resource identifier '{0}' has already been used in this assembly.", value));
+ }
+ else if (value.IndexOf (',') != -1 && embedded_resources.Contains (value.Split (',')[1])) {
+ Report.Error (1508, String.Format ("The resource identifier '{0}' has already been used in this assembly.", value));
+ }
+ else {
+ embedded_resources.Add (value);
+ }
return true;
case "/recurse":
if (value == ""){
- Report.Error (5, "/recurse requires an argument");
+ Report.Error (5, "-recurse requires an argument");
Environment.Exit (1);
}
CompileFiles (value, true);
case "/r":
case "/reference": {
if (value == ""){
- Report.Error (5, arg + " requires an argument");
+ Report.Error (5, "-reference requires an argument");
Environment.Exit (1);
}
}
return true;
}
- case "/doc": {
+ case "/addmodule": {
if (value == ""){
Report.Error (5, arg + " requires an argument");
Environment.Exit (1);
}
- // TODO handle the /doc argument to generate xml doc
+
+ string [] refs = value.Split (new char [] { ';', ',' });
+ foreach (string r in refs){
+ modules.Add (r);
+ }
+ return true;
+ }
+ case "/win32res": {
+ if (value == "") {
+ Report.Error (5, arg + " requires an argument");
+ Environment.Exit (1);
+ }
+
+ win32ResourceFile = value;
+ return true;
+ }
+ case "/win32icon": {
+ if (value == "") {
+ Report.Error (5, arg + " requires an argument");
+ Environment.Exit (1);
+ }
+
+ win32IconFile = value;
+ return true;
+ }
+ case "/doc": {
+ if (value == ""){
+ Report.Error (2006, arg + " requires an argument");
+ Environment.Exit (1);
+ }
+ RootContext.Documentation = new Documentation (value);
return true;
}
case "/lib": {
link_paths.Add (dir);
return true;
}
+
+ case "/debug-":
+ want_debugging_support = false;
+ return true;
case "/debug":
case "/debug+":
RootContext.Checked = false;
return true;
+ case "/clscheck":
+ case "/clscheck+":
+ return true;
+
+ case "/clscheck-":
+ RootContext.VerifyClsCompliance = false;
+ return true;
+
case "/unsafe":
case "/unsafe+":
RootContext.Unsafe = true;
load_default_config = false;
return true;
+ case "/help2":
+ OtherFlags ();
+ Environment.Exit(0);
+ return true;
+
case "/help":
case "/?":
Usage ();
case "/fullpaths":
return true;
- case "/win32icon":
- Report.Error (5, "/win32icon is currently not supported");
+ case "/keyfile":
+ if (value == String.Empty) {
+ Report.Error (5, arg + " requires an argument");
+ Environment.Exit (1);
+ }
+ RootContext.StrongNameKeyFile = value;
return true;
-
+ case "/keycontainer":
+ if (value == String.Empty) {
+ Report.Error (5, arg + " requires an argument");
+ Environment.Exit (1);
+ }
+ RootContext.StrongNameKeyContainer = value;
+ return true;
+ case "/delaysign+":
+ RootContext.StrongNameDelaySign = true;
+ return true;
+ case "/delaysign-":
+ RootContext.StrongNameDelaySign = false;
+ return true;
+
case "/v2":
case "/2":
+ Console.WriteLine ("The compiler option -2 is obsolete. Please use /langversion instead");
SetupV2 ();
return true;
+ case "/langversion":
+ switch (value.ToLower (CultureInfo.InvariantCulture)) {
+ case "iso-1":
+ RootContext.Version = LanguageVersion.ISO_1;
+ return true;
+
+ case "default":
+ SetupV2 ();
+ return true;
+ }
+ Report.Error (1617, "Invalid option '{0}' for /langversion; must be ISO-1 or Default", value);
+ Environment.Exit (1);
+ return false;
+
case "/codepage":
int cp = -1;
}
return true;
}
- Report.Error (2007, String.Format ("Unrecognized command-line option: '{0}'", option));
- Environment.Exit (1);
+
+ //Report.Error (2007, String.Format ("Unrecognized command-line option: '{0}'", option));
+ //Environment.Exit (1);
return false;
}
+
+ static string [] AddArgs (string [] args, string [] extra_args)
+ {
+ string [] new_args;
+ new_args = new string [extra_args.Length + args.Length];
+
+ // if args contains '--' we have to take that into account
+ // split args into first half and second half based on '--'
+ // and add the extra_args before --
+ int split_position = Array.IndexOf (args, "--");
+ if (split_position != -1)
+ {
+ Array.Copy (args, new_args, split_position);
+ extra_args.CopyTo (new_args, split_position);
+ Array.Copy (args, split_position, new_args, split_position + extra_args.Length, args.Length - split_position);
+ }
+ else
+ {
+ args.CopyTo (new_args, 0);
+ extra_args.CopyTo (new_args, args.Length);
+ }
+
+ return new_args;
+ }
/// <summary>
/// Parses the arguments, and drives the compilation
references = new ArrayList ();
soft_references = new ArrayList ();
+ modules = new ArrayList ();
link_paths = new ArrayList ();
SetupDefaultDefines ();
// path.
//
- int argc = args.Length;
- for (i = 0; i < argc; i++){
+ for (i = 0; i < args.Length; i++){
string arg = args [i];
-
+ if (arg == "")
+ continue;
+
if (arg.StartsWith ("@")){
- string [] new_args, extra_args;
+ string [] extra_args;
string response_file = arg.Substring (1);
if (response_file_list == null)
return false;
}
- new_args = new string [extra_args.Length + argc];
- args.CopyTo (new_args, 0);
- extra_args.CopyTo (new_args, argc);
- args = new_args;
- argc = new_args.Length;
+ args = AddArgs (args, extra_args);
continue;
}
if (tokenize)
return true;
-
- if (first_source == null){
+
+ //
+ // This will point to the NamespaceEntry of the last file that was parsed, and may
+ // not be meaningful when resolving classes from other files. So, reset it to prevent
+ // silent bugs.
+ //
+ RootContext.Tree.Types.NamespaceEntry = null;
+
+ //
+ // If we are an exe, require a source file for the entry point
+ //
+ if (RootContext.Target == Target.Exe || RootContext.Target == Target.WinExe){
+ if (first_source == null){
+ Report.Error (2008, "No files to compile were specified");
+ return false;
+ }
+
+ }
+
+ //
+ // If there is nothing to put in the assembly, and we are not a library
+ //
+ if (first_source == null && embedded_resources == null && resources == null){
Report.Error (2008, "No files to compile were specified");
return false;
}
if (parse_only)
return true;
+
+ Tokenizer.Cleanup ();
//
// Load Core Library for default compilation
if (timestamps)
ShowTime ("Loading references");
link_paths.Add (GetSystemDir ());
+ link_paths.Add (Directory.GetCurrentDirectory ());
LoadReferences ();
if (timestamps)
// Quick hack
//
if (output_file == null){
- int pos = first_source.LastIndexOf (".");
+ int pos = first_source.LastIndexOf ('.');
if (pos > 0)
- output_file = first_source.Substring (0, pos) + target_ext;
+ output_file = first_source.Substring (0, pos) + RootContext.TargetExt;
else
- output_file = first_source + target_ext;
+ output_file = first_source + RootContext.TargetExt;
}
CodeGen.Init (output_file, output_file, want_debugging_support);
- TypeManager.AddModule (CodeGen.ModuleBuilder);
+ if (RootContext.Target == Target.Module) {
+ PropertyInfo module_only = typeof (AssemblyBuilder).GetProperty ("IsModuleOnly", BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);
+ if (module_only == null) {
+ Report.Error (0, new Location (-1), "Cannot use /target:module on this runtime: try the Mono runtime instead.");
+ Environment.Exit (1);
+ }
+
+ MethodInfo set_method = module_only.GetSetMethod (true);
+ set_method.Invoke (CodeGen.Assembly.Builder, BindingFlags.Default, null, new object[]{true}, null);
+ }
+
+ TypeManager.AddModule (CodeGen.Module.Builder);
+
+ if (modules.Count > 0) {
+ MethodInfo adder_method = typeof (AssemblyBuilder).GetMethod ("AddModule", BindingFlags.Instance|BindingFlags.NonPublic);
+ if (adder_method == null) {
+ Report.Error (0, new Location (-1), "Cannot use /addmodule on this runtime: Try the Mono runtime instead.");
+ Environment.Exit (1);
+ }
+
+ foreach (string module in modules)
+ LoadModule (adder_method, module);
+ }
- DateTime start = DateTime.Now;
TypeManager.ComputeNamespaces ();
- DateTime end = DateTime.Now;
//
// Before emitting, we need to get the core
if (timestamps)
ShowTime ("Resolving tree");
RootContext.ResolveTree ();
+
if (Report.Errors > 0)
return false;
if (timestamps)
ShowTime ("Populate tree");
if (!RootContext.StdLib)
RootContext.BootCorlib_PopulateCoreTypes ();
+
RootContext.PopulateTypes ();
RootContext.DefineTypes ();
+ if (RootContext.Documentation != null &&
+ !RootContext.Documentation.OutputDocComment (
+ output_file))
+ return false;
+
TypeManager.InitCodeHelpers ();
//
return false;
}
+ if (RootContext.VerifyClsCompliance) {
+ CodeGen.Assembly.ResolveClsCompliance ();
+ if (CodeGen.Assembly.IsClsCompliant) {
+ AttributeTester.VerifyModulesClsCompliance ();
+ TypeManager.LoadAllImportedTypes ();
+ AttributeTester.VerifyTopLevelNameClsCompliance ();
+ }
+ }
+
//
// The code generator
//
RootContext.CloseTypes ();
PEFileKinds k = PEFileKinds.ConsoleApplication;
-
- if (target == Target.Library || target == Target.Module){
- k = PEFileKinds.Dll;
-
- if (RootContext.MainClass != null)
- Report.Error (2017, "Can not specify -main: when building module or library");
- } else if (target == Target.Exe)
- k = PEFileKinds.ConsoleApplication;
- else if (target == Target.WinExe)
- k = PEFileKinds.WindowApplication;
+
+ switch (RootContext.Target) {
+ case Target.Library:
+ case Target.Module:
+ k = PEFileKinds.Dll; break;
+ case Target.Exe:
+ k = PEFileKinds.ConsoleApplication; break;
+ case Target.WinExe:
+ k = PEFileKinds.WindowApplication; break;
+ }
- if (target == Target.Exe || target == Target.WinExe){
+ if (RootContext.NeedsEntryPoint) {
MethodInfo ep = RootContext.EntryPoint;
- if (ep == null){
+ if (ep == null) {
+ if (RootContext.MainClass != null) {
+ DeclSpace main_cont = RootContext.Tree.Decls [RootContext.MainClass] as DeclSpace;
+ if (main_cont == null) {
+ Report.Error (1555, output_file, "Could not find '{0}' specified for Main method", RootContext.MainClass);
+ return false;
+ }
+
+ if (!(main_cont is ClassOrStruct)) {
+ Report.Error (1556, output_file, "'{0}' specified for Main method must be a valid class or struct", RootContext.MainClass);
+ return false;
+ }
+
+ Report.Error (1558, main_cont.Location, "'{0}' does not have a suitable static Main method", main_cont.GetSignatureForError ());
+ return false;
+ }
+
if (Report.Errors == 0)
Report.Error (5001, "Program " + output_file +
" does not have an entry point defined");
return false;
}
-
- CodeGen.AssemblyBuilder.SetEntryPoint (ep, k);
+
+ CodeGen.Assembly.Builder.SetEntryPoint (ep, k);
+ } else if (RootContext.MainClass != null) {
+ Report.Error (2017, "Can not specify -main: when building module or library");
}
//
} else
file = res = spec;
- CodeGen.AssemblyBuilder.AddResourceFile (res, file);
+ CodeGen.Assembly.Builder.AddResourceFile (res, file);
}
}
object[] margs = new object [2];
Type[] argst = new Type [2];
argst [0] = argst [1] = typeof (string);
- MethodInfo embed_res = typeof (AssemblyBuilder).GetMethod ("EmbedResourceFile", argst);
+
+ MethodInfo embed_res = typeof (AssemblyBuilder).GetMethod (
+ "EmbedResourceFile", BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic,
+ null, CallingConventions.Any, argst, null);
+
if (embed_res == null) {
- Report.Warning (0, new Location (-1), "Cannot embed resources on this runtime: try the Mono runtime instead.");
+ Report.Warning (0, new Location (-1),
+ "Cannot embed resources on this runtime: try the Mono runtime instead.");
} else {
foreach (string spec in embedded_resources) {
int cp;
if (cp != -1){
margs [0] = spec.Substring (cp + 1);
margs [1] = spec.Substring (0, cp);
- } else
- margs [0] = margs [1] = spec;
+ } else {
+ margs [1] = spec;
+ margs [0] = Path.GetFileName (spec);
+ }
if (File.Exists ((string) margs [1]))
- embed_res.Invoke (CodeGen.AssemblyBuilder, margs);
+ embed_res.Invoke (CodeGen.Assembly.Builder, margs);
else {
Report.Error (1566, "Can not find the resource " + margs [1]);
}
}
}
+ //
+ // Add Win32 resources
+ //
+
+ CodeGen.Assembly.Builder.DefineVersionInfoResource ();
+
+ if (win32ResourceFile != null) {
+ try {
+ CodeGen.Assembly.Builder.DefineUnmanagedResource (win32ResourceFile);
+ }
+ catch (ArgumentException) {
+ Report.Warning (0, new Location (-1), "Cannot embed win32 resources on this runtime: try the Mono runtime instead.");
+ }
+ }
+
+ if (win32IconFile != null) {
+ MethodInfo define_icon = typeof (AssemblyBuilder).GetMethod ("DefineIconResource", BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);
+ if (define_icon == null) {
+ Report.Warning (0, new Location (-1), "Cannot embed icon resource on this runtime: try the Mono runtime instead.");
+ }
+ define_icon.Invoke (CodeGen.Assembly.Builder, new object [] { win32IconFile });
+ }
+
if (Report.Errors > 0)
return false;
Timer.ShowTimers ();
- if (Report.ExpectedError != 0){
- Console.WriteLine("Failed to report expected error " + Report.ExpectedError);
- Environment.Exit (1);
+ if (Report.ExpectedError != 0) {
+ if (Report.Errors == 0) {
+ Console.WriteLine ("Failed to report expected error " + Report.ExpectedError + ".\n" +
+ "No other errors reported.");
+
+ Environment.Exit (2);
+ } else {
+ Console.WriteLine ("Failed to report expected error " + Report.ExpectedError + ".\n" +
+ "However, other errors were reported.");
+
+ Environment.Exit (1);
+ }
+
+
return false;
}
#endif
return (Report.Errors == 0);
}
-
}
//