2 // Mono.AssemblyLinker.AssemblyLinker
5 // Zoltan Varga (vargaz@freemail.hu)
7 // (C) Ximian, Inc. http://www.ximian.com
8 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
12 using System
.Globalization
;
14 using System
.Collections
;
15 using System
.Collections
.Generic
;
16 using System
.Security
.Cryptography
;
18 using System
.Configuration
.Assemblies
;
20 using IKVM
.Reflection
;
21 using IKVM
.Reflection
.Emit
;
22 using Mono
.Security
.Cryptography
;
24 namespace Mono
.AssemblyLinker
27 public string fileName
;
33 public string fileName
;
35 public bool isEmbedded
;
36 public bool isPrivate
;
51 public enum Platform
{
60 public class AssemblyLinker
{
62 ArrayList inputFiles
= new ArrayList ();
63 ArrayList resources
= new ArrayList ();
64 ArrayList cattrs
= new ArrayList ();
77 bool isTemplateFile
= false;
78 Target target
= Target
.Dll
;
79 Platform platform
= Platform
.AnyCPU
;
80 DelaySign delaysign
= DelaySign
.NotSet
;
86 public static int Main (String
[] args
) {
87 return new AssemblyLinker ().DynMain (args
);
90 private int DynMain (String
[] args
) {
91 using (universe
= new Universe (UniverseOptions
.MetadataOnly
)) {
92 universe
.LoadFile (typeof (object).Assembly
.Location
);
101 private void ParseArgs (string[] args
)
103 ArrayList flat_args
= new ArrayList ();
105 // Process response files
106 Hashtable response_files
= new Hashtable ();
107 foreach (string str
in args
) {
108 if (str
[0] != '@') {
114 ReportMissingFileSpec ("@");
116 string resfile_name
= Path
.GetFullPath (str
.Substring (1));
117 if (response_files
.ContainsKey (resfile_name
))
118 Report (1006, "Response file '" + resfile_name
+ "' was already included");
119 response_files
[resfile_name
] = resfile_name
;
120 LoadArgs (resfile_name
, flat_args
);
123 if (flat_args
.Count
== 0)
126 foreach (string str
in flat_args
) {
127 if ((str
[0] != '-') && (str
[0] != '/')) {
128 inputFiles
.Add (GetModuleInfo (str
));
132 if (!ParseOption(str
)) {
134 // cope with absolute filenames for modules on unix, as
135 // they also match the option pattern
137 // `/home/test.cs' is considered as a module, however
138 // '/test.cs' is considered as error
139 if (str
.Length
> 2 && str
.IndexOf ('/', 2) != -1) {
140 inputFiles
.Add (GetModuleInfo (str
));
145 Report (1013, String
.Format ("Unrecognized command line option: '{0}'", str
));
150 if ((inputFiles
.Count
== 0) && (resources
.Count
== 0))
151 Report (1016, "No valid input files were specified");
154 Report (1017, "No target filename was specified");
156 if (target
== Target
.Dll
&& (entryPoint
!= null))
157 Report (1035, "Libraries cannot have an entry point");
159 if (target
== Target
.Exe
&& (entryPoint
== null))
160 Report (1036, "Entry point required for executable applications");
163 private bool ParseOption (string str
)
166 string opt
= GetCommand (str
, out arg
);
176 ReportMissingFileSpec (opt
);
177 ResourceInfo res
= new ResourceInfo ();
178 res
.isEmbedded
= true;
179 String
[] parts
= arg
.Split (',');
180 res
.fileName
= parts
[0];
181 if (parts
.Length
> 1)
182 res
.name
= parts
[1];
183 if (parts
.Length
> 2) {
188 res
.isPrivate
= true;
191 ReportInvalidArgument (opt
, parts
[2]);
201 ReportMissingFileSpec (opt
);
202 ResourceInfo res
= new ResourceInfo ();
203 String
[] parts
= arg
.Split (',');
204 res
.fileName
= parts
[0];
205 if (parts
.Length
> 1)
206 res
.name
= parts
[1];
207 if (parts
.Length
> 2)
208 res
.target
= parts
[2];
209 if (parts
.Length
> 3) {
214 res
.isPrivate
= true;
217 ReportInvalidArgument (opt
, parts
[3]);
227 ReportMissingArgument (opt
);
229 string realArg
= arg
;
230 if (realArg
.StartsWith ("0x"))
231 realArg
= realArg
.Substring (2);
232 uint val
= Convert
.ToUInt32 (realArg
, 16);
233 AddCattr (typeof (System
.Reflection
.AssemblyAlgorithmIdAttribute
), typeof (uint), val
);
234 } catch (Exception
) {
235 ReportInvalidArgument (opt
, arg
);
240 ReportNotImplemented (opt
);
244 ReportNotImplemented (opt
);
248 ReportNotImplemented (opt
);
254 ReportMissingText (opt
);
259 case "configuration":
261 ReportMissingText (opt
);
262 AddCattr (typeof (System
.Reflection
.AssemblyConfigurationAttribute
), arg
);
268 ReportMissingText (opt
);
275 ReportMissingText (opt
);
283 delaysign
= DelaySign
.Yes
;
288 delaysign
= DelaySign
.No
;
294 ReportMissingText (opt
);
301 ReportMissingFileSpec (opt
);
302 ResourceInfo res
= new ResourceInfo ();
303 res
.name
= "Security.Evidence";
305 res
.isEmbedded
= true;
306 res
.isPrivate
= true;
312 ReportMissingText (opt
);
314 AddCattr (typeof (System
.Reflection
.AssemblyFileVersionAttribute
), arg
);
319 ReportMissingArgument (opt
);
321 string realArg
= arg
;
322 if (realArg
.StartsWith ("0x"))
323 realArg
= realArg
.Substring (2);
324 uint val
= Convert
.ToUInt32 (realArg
, 16);
325 AddCattr (typeof (System
.Reflection
.AssemblyFlagsAttribute
), typeof (uint), val
);
326 } catch (Exception
) {
327 ReportInvalidArgument (opt
, arg
);
338 ReportMissingText (opt
);
345 ReportMissingText (opt
);
351 ReportMissingText (opt
);
360 ReportMissingFileSpec (opt
);
366 ReportMissingText (opt
);
367 switch (arg
.ToLowerInvariant ()) {
369 platform
= Platform
.Arm
;
372 platform
= Platform
.AnyCPU
;
375 platform
= Platform
.X86
;
378 platform
= Platform
.X64
;
381 platform
= Platform
.IA64
;
383 case "anycpu32bitpreferred":
384 platform
= Platform
.AnyCPU32Preferred
;
387 ReportInvalidArgument (opt
, arg
);
395 ReportMissingText (opt
);
400 case "productversion":
402 ReportMissingText (opt
);
403 AddCattr (typeof (System
.Reflection
.AssemblyInformationalVersionAttribute
), arg
);
409 ReportMissingText (opt
);
420 Report (0, "target:win is not implemented");
423 ReportInvalidArgument (opt
, arg
);
430 ReportMissingFileSpec (opt
);
431 isTemplateFile
= true;
432 templateFile
= Path
.Combine (Directory
.GetCurrentDirectory (), arg
);
437 ReportMissingText (opt
);
444 ReportMissingText (opt
);
450 // This option conflicts with the standard UNIX meaning
455 AddCattr (typeof (System
.Reflection
.AssemblyVersionAttribute
), arg
);
460 ReportMissingFileSpec (opt
);
466 ReportMissingFileSpec (opt
);
473 private bool RunningOnUnix
{
475 // check for Unix platforms - see FAQ for more details
476 // http://www.mono-project.com/FAQ:_Technical#How_to_detect_the_execution_platform_.3F
477 int platform
= (int) Environment
.OSVersion
.Platform
;
478 return ((platform
== 4) || (platform
== 128) || (platform
== 6));
482 private ModuleInfo
GetModuleInfo (string str
)
484 string [] parts
= str
.Split (',');
485 ModuleInfo mod
= new ModuleInfo ();
486 mod
.fileName
= parts
[0];
487 if (parts
.Length
> 1)
488 mod
.target
= parts
[1];
492 private string GetCommand (string str
, out string command_arg
) {
493 if ((str
[0] == '-') && (str
.Length
> 1) && (str
[1] == '-'))
494 str
= str
.Substring (1);
496 int end_index
= str
.IndexOfAny (new char[] {':', '='}
, 1);
497 string command
= str
.Substring (1,
498 end_index
== -1 ? str
.Length
- 1 : end_index
- 1);
500 if (end_index
!= -1) {
501 command_arg
= str
.Substring (end_index
+1);
502 if (command_arg
== String
.Empty
)
508 return command
.ToLower ();
511 private void AddCattr (System
.Type attrType
, System
.Type arg
, object value) {
512 var importedAttrType
= universe
.Import(attrType
);
513 var importedArg
= universe
.Import(arg
);
515 cattrs
.Add (new CustomAttributeBuilder (importedAttrType
.GetConstructor (new [] { importedArg }
), new [] { value }
));
518 private void AddCattr (System
.Type attrType
, object value) {
519 AddCattr (attrType
, typeof (string), value);
522 private void PrintVersion () {
523 Console
.WriteLine ("Mono Assembly Linker (al.exe) version " + Consts
.MonoVersion
);
526 private void Version () {
528 Environment
.Exit (0);
531 private void Usage () {
534 foreach (string s
in usage
)
535 Console
.WriteLine (s
);
536 Environment
.Exit (0);
539 private void Report (int errorNum
, string msg
) {
540 Console
.WriteLine (String
.Format ("ALINK: error A{0:0000}: {1}", errorNum
, msg
));
541 Environment
.Exit (1);
544 private void ReportWarning (int errorNum
, string msg
) {
545 Console
.WriteLine (String
.Format ("ALINK: warning A{0:0000}: {1}", errorNum
, msg
));
548 private void ReportInvalidArgument (string option
, string value) {
549 Report (1012, String
.Format ("'{0}' is not a valid setting for option '{1}'", value, option
));
552 private void ReportMissingArgument (string option
) {
553 Report (1003, String
.Format ("Compiler option '{0}' must be followed by an argument", option
));
556 private void ReportNotImplemented (string option
) {
557 Report (0, String
.Format ("Compiler option '{0}' is not implemented", option
));
560 private void ReportMissingFileSpec (string option
) {
561 Report (1008, String
.Format ("Missing file specification for '{0}' command-line option", option
));
564 private void ReportMissingText (string option
) {
565 Report (1010, String
.Format ("Missing ':<text>' for '{0}' option", option
));
568 // copied from /mcs/mcs/codegen.cs
569 private void SetPublicKey (AssemblyName an
, byte[] strongNameBlob
)
571 // check for possible ECMA key
572 if (strongNameBlob
.Length
== 16) {
573 // will be rejected if not "the" ECMA key
574 an
.SetPublicKey (strongNameBlob
);
576 // take it, with or without, a private key
577 RSA rsa
= CryptoConvert
.FromCapiKeyBlob (strongNameBlob
);
578 // and make sure we only feed the public part to Sys.Ref
579 byte[] publickey
= CryptoConvert
.ToCapiPublicKeyBlob (rsa
);
581 // AssemblyName.SetPublicKey requires an additional header
582 byte[] publicKeyHeader
= new byte [12] { 0x00, 0x24, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00 }
;
584 byte[] encodedPublicKey
= new byte [12 + publickey
.Length
];
585 Buffer
.BlockCopy (publicKeyHeader
, 0, encodedPublicKey
, 0, 12);
586 Buffer
.BlockCopy (publickey
, 0, encodedPublicKey
, 12, publickey
.Length
);
587 an
.SetPublicKey (encodedPublicKey
);
591 private void SetKeyPair (AssemblyName aname
)
593 if (keyfile
!= null) {
594 if (!File
.Exists (keyfile
)) {
595 Report (1044, String
.Format ("Couldn't open '{0}' key file.", keyfile
));
598 using (FileStream fs
= File
.OpenRead (keyfile
)) {
599 byte[] data
= new byte [fs
.Length
];
601 fs
.Read (data
, 0, data
.Length
);
603 if (delaysign
== DelaySign
.Yes
) {
604 SetPublicKey (aname
, data
);
606 CryptoConvert
.FromCapiPrivateKeyBlob (data
);
607 aname
.KeyPair
= new StrongNameKeyPair (data
);
610 catch (CryptographicException
) {
611 if (delaysign
!= DelaySign
.Yes
) {
612 if (data
.Length
== 16) {
613 // error # is different for ECMA key
614 Report (1019, "Could not strongname the assembly. " +
615 "ECMA key can only be used to delay-sign assemblies");
617 Report (1028, String
.Format ("Key file {0}' is missing it's private key " +
618 "or couldn't be decoded.", keyfile
));
621 Report (1044, String
.Format ("Couldn't decode '{0}' key file.", keyfile
));
626 } else if (keyname
!= null) {
627 // delay-sign doesn't apply to key containers
628 aname
.KeyPair
= new StrongNameKeyPair (keyname
);
632 private void DoIt () {
633 AssemblyName aname
= new AssemblyName ();
634 aname
.Name
= Path
.GetFileNameWithoutExtension (outFile
);
636 aname
.CultureInfo
= new CultureInfo (culture
);
638 string fileName
= Path
.GetFileName (outFile
);
647 aname
= ReadCustomAttributesFromTemplateFile (templateFile
, aname
);
649 if (!String
.IsNullOrEmpty (title
))
650 AddCattr (typeof (System
.Reflection
.AssemblyTitleAttribute
), title
);
651 if (!String
.IsNullOrEmpty (description
))
652 AddCattr (typeof (System
.Reflection
.AssemblyDescriptionAttribute
), description
);
653 if (!String
.IsNullOrEmpty (company
))
654 AddCattr (typeof (System
.Reflection
.AssemblyCompanyAttribute
), company
);
655 if (!String
.IsNullOrEmpty (product
))
656 AddCattr (typeof (System
.Reflection
.AssemblyProductAttribute
), product
);
657 if (!String
.IsNullOrEmpty (copyright
))
658 AddCattr (typeof (System
.Reflection
.AssemblyCopyrightAttribute
), copyright
);
659 if (!String
.IsNullOrEmpty (trademark
))
660 AddCattr (typeof (System
.Reflection
.AssemblyTrademarkAttribute
), trademark
);
664 if (fileName
!= outFile
)
665 ab
= universe
.DefineDynamicAssembly (aname
, AssemblyBuilderAccess
.Save
, Path
.GetDirectoryName (outFile
));
667 ab
= universe
.DefineDynamicAssembly (aname
, AssemblyBuilderAccess
.Save
);
669 foreach (CustomAttributeBuilder cb
in cattrs
)
670 ab
.SetCustomAttribute (cb
);
676 foreach (ModuleInfo mod
in inputFiles
) {
677 if (mod
.target
!= null) {
678 File
.Copy (mod
.fileName
, mod
.target
, true);
679 mod
.fileName
= mod
.target
;
682 bool isAssembly
= false;
684 AssemblyName
.GetAssemblyName (mod
.fileName
);
691 ReportWarning (1020, "Ignoring included assembly '" + mod
.fileName
+ "'");
693 ab
.__AddModule (universe
.OpenRawModule(mod
.fileName
));
700 if (entryPoint
!= null) {
701 string mainClass
= entryPoint
.Substring (0, entryPoint
.LastIndexOf ('.'));
702 string mainMethod
= entryPoint
.Substring (entryPoint
.LastIndexOf ('.') + 1);
704 MethodInfo mainMethodInfo
= null;
707 IKVM
.Reflection
.Type mainType
= ab
.GetType (mainClass
);
708 if (mainType
!= null)
709 mainMethodInfo
= mainType
.GetMethod (mainMethod
);
711 catch (Exception ex
) {
712 Console
.WriteLine (ex
);
714 if (mainMethodInfo
!= null)
715 ab
.SetEntryPoint (mainMethodInfo
);
717 Report (1037, "Unable to find the entry point method '" + entryPoint
+ "'");
724 ab
.DefineVersionInfoResource ();
726 if (win32IconFile
!= null) {
728 ab
.__DefineIconResource (File
.ReadAllBytes (win32IconFile
));
730 catch (Exception ex
) {
731 Report (1031, "Error reading icon '" + win32IconFile
+ "' --" + ex
);
735 if (win32ResFile
!= null) {
737 ab
.DefineUnmanagedResource (win32ResFile
);
739 catch (Exception ex
) {
740 Report (1019, "Metadata failure creating assembly -- " + ex
);
744 ModuleBuilder mainModule
= null;
746 foreach (ResourceInfo res
in resources
) {
747 if (res
.name
== null)
748 res
.name
= Path
.GetFileName (res
.fileName
);
750 foreach (ResourceInfo res2
in resources
)
751 if ((res
!= res2
) && (res
.name
== res2
.name
))
752 Report (1046, String
.Format ("Resource identifier '{0}' has already been used in this assembly", res
.name
));
754 if (res
.isEmbedded
) {
755 if (mainModule
== null) {
756 mainModule
= ab
.DefineDynamicModule (fileName
, fileName
, false);
759 Stream stream
= new MemoryStream (File
.ReadAllBytes (res
.fileName
));
761 mainModule
.DefineManifestResource (res
.name
, stream
, res
.isPrivate
? ResourceAttributes
.Private
: ResourceAttributes
.Public
);
764 if (res
.target
!= null) {
765 File
.Copy (res
.fileName
, res
.target
, true);
766 res
.fileName
= res
.target
;
769 // AddResourceFile must receive a file name and not a path.
770 // Drop directory and give warning if we have a path.
771 var resourceFileName
= Path
.GetFileName(res
.fileName
);
772 if (Path
.GetDirectoryName (res
.fileName
) != null || Path
.IsPathRooted(res
.fileName
)) {
773 ReportWarning (99999,
774 String
.Format ("Path '{0}' in the resource name is not supported. Using just file name '{1}'",
779 ab
.AddResourceFile (res
.name
, resourceFileName
,
780 res
.isPrivate
? ResourceAttributes
.Private
: ResourceAttributes
.Public
);
784 PortableExecutableKinds pekind
= PortableExecutableKinds
.ILOnly
;
785 ImageFileMachine machine
;
789 pekind
|= PortableExecutableKinds
.Required32Bit
;
790 machine
= ImageFileMachine
.I386
;
793 pekind
|= PortableExecutableKinds
.PE32Plus
;
794 machine
= ImageFileMachine
.AMD64
;
797 machine
= ImageFileMachine
.IA64
;
799 case Platform
.AnyCPU32Preferred
:
800 pekind
|= PortableExecutableKinds
.Preferred32Bit
;
801 machine
= ImageFileMachine
.I386
;
804 machine
= ImageFileMachine
.ARM
;
806 case Platform
.AnyCPU
:
808 machine
= ImageFileMachine
.I386
;
813 ab
.Save (fileName
, pekind
, machine
);
815 catch (Exception ex
) {
816 Report (1019, "Metadata failure creating assembly -- " + ex
);
820 private AssemblyName
ReadCustomAttributesFromTemplateFile (string templateFile
, AssemblyName aname
)
822 // LAMESPEC: according to MSDN, the template assembly must have a
823 // strong name but this is not enforced
824 var asm
= universe
.LoadFile (templateFile
);
826 // Create missing assemblies, we don't want to load them!
827 // Code taken from ikdasm
828 var names
= new HashSet
<string> ();
829 AssemblyName
[] assembly_refs
= asm
.ManifestModule
.__GetReferencedAssemblies ();
831 var resolved_assemblies
= new Assembly
[assembly_refs
.Length
];
832 for (int i
= 0; i
< resolved_assemblies
.Length
; i
++) {
833 string name
= assembly_refs
[i
].Name
;
835 while (names
.Contains (name
)) {
836 name
= name
+ "_" + i
;
839 resolved_assemblies
[i
] = universe
.CreateMissingAssembly (assembly_refs
[i
].FullName
);
841 asm
.ManifestModule
.__ResolveReferencedAssemblies (resolved_assemblies
);
843 foreach (var attr_data
in asm
.__GetCustomAttributes (null, false)) {
844 string asm_name
= attr_data
.AttributeType
.Assembly
.GetName ().Name
;
845 if (asm_name
!= "mscorlib")
848 switch (attr_data
.AttributeType
.FullName
) {
849 case "System.Reflection.AssemblyKeyFileAttribute": {
851 // ignore if specified on command line
854 // / AssemblyKeyFileAttribute .ctor(string keyFile)
855 string key_file_value
= (string) attr_data
.ConstructorArguments
[0].Value
;
857 if (!String
.IsNullOrEmpty (key_file_value
))
858 keyfile
= Path
.Combine (Path
.GetDirectoryName (templateFile
), key_file_value
);
862 case "System.Reflection.AssemblyDelaySignAttribute": {
863 if (delaysign
!= DelaySign
.NotSet
)
864 // ignore if specified on command line
867 // AssemblyDelaySignAttribute .ctor(bool delaySign)
868 bool delay_sign_value
= (bool) attr_data
.ConstructorArguments
[0].Value
;
869 delaysign
= delay_sign_value
? DelaySign
.Yes
: DelaySign
.No
;
873 case "System.Reflection.AssemblyKeyNameAttribute": {
875 // ignore if specified on command line
878 // AssemblyKeyNameAttribute .ctor(string keyName)
879 string key_name_value
= (string) attr_data
.ConstructorArguments
[0].Value
;
881 // ignore null or zero-length keyname
882 if (!String
.IsNullOrEmpty (key_name_value
))
883 keyname
= key_name_value
;
887 case "System.Reflection.AssemblyTitleAttribute": {
889 // ignore if specified on command line
892 // AssemblyTitleAttribute .ctor(string title)
893 string title_value
= (string) attr_data
.ConstructorArguments
[0].Value
;
895 if (!String
.IsNullOrEmpty (title_value
))
900 case "System.Reflection.AssemblyDescriptionAttribute": {
901 if (description
!= null)
902 // ignore if specified on command line
905 // AssemblyDescriptionAttribute .ctor(string description)
906 string description_value
= (string) attr_data
.ConstructorArguments
[0].Value
;
908 if (!String
.IsNullOrEmpty (description_value
))
909 description
= description_value
;
913 case "System.Reflection.AssemblyProductAttribute": {
915 // ignore if specified on command line
918 // AssemblyProductAttribute .ctor(string product)
919 string product_value
= (string) attr_data
.ConstructorArguments
[0].Value
;
921 if (!String
.IsNullOrEmpty (product_value
))
922 product
= product_value
;
926 case "System.Reflection.AssemblyCompanyAttribute": {
928 // ignore if specified on command line
931 // AssemblyCompanyAttribute .ctor(string company)
932 string company_value
= (string) attr_data
.ConstructorArguments
[0].Value
;
934 if (!String
.IsNullOrEmpty (company_value
))
935 company
= company_value
;
940 case "System.Reflection.AssemblyCopyrightAttribute": {
941 if (copyright
!= null)
942 // ignore if specified on command line
945 // AssemblyCopyrightAttribute .ctor(string copyright)
946 string copyright_value
= (string) attr_data
.ConstructorArguments
[0].Value
;
948 if (!String
.IsNullOrEmpty (copyright_value
))
949 copyright
= copyright_value
;
953 case "System.Reflection.AssemblyTrademarkAttribute": {
954 if (trademark
!= null)
955 // ignore if specified on command line
958 // AssemblyTrademarkAttribute .ctor(string trademark)
959 string trademark_value
= (string) attr_data
.ConstructorArguments
[0].Value
;
961 if (!String
.IsNullOrEmpty (trademark_value
))
962 trademark
= trademark_value
;
968 var asm_name_for_template_file
= asm
.GetName ();
969 aname
.Version
= asm_name_for_template_file
.Version
;
970 aname
.HashAlgorithm
= asm_name_for_template_file
.HashAlgorithm
;
975 private void LoadArgs (string file
, ArrayList args
) {
976 StreamReader f
= null;
979 f
= new StreamReader (file
);
981 StringBuilder sb
= new StringBuilder ();
983 while ((line
= f
.ReadLine ()) != null){
986 for (int i
= 0; i
< t
; i
++){
989 if (c
== '"' || c
== '\''){
992 for (i
++; i
< t
; i
++){
999 } else if (c
== ' '){
1001 args
.Add (sb
.ToString ());
1008 args
.Add (sb
.ToString ());
1012 } catch (Exception ex
) {
1013 Report (1007, "Error opening response file '" + file
+ "' -- '" + ex
.Message
+ "'");
1021 "Usage: al [options] [sources]",
1022 "Options: ('/out' must be specified)",
1024 " /? or /help Display this usage message",
1025 " @<filename> Read response file for more options",
1026 " /algid:<id> Algorithm used to hash files (in hexadecimal)",
1027 " /base[address]:<addr> Base address for the library",
1028 " /bugreport:<filename> Create a 'Bug Report' file",
1029 " /comp[any]:<text> Company name",
1030 " /config[uration]:<text> Configuration string",
1031 " /copy[right]:<text> Copyright message",
1032 " /c[ulture]:<text> Supported culture",
1033 " /delay[sign][+|-] Delay sign this assembly",
1034 " /descr[iption]:<text> Description",
1035 " /e[vidence]:<filename> Security evidence file to embed",
1036 " /fileversion:<version> Optional Win32 version (overrides assembly version)",
1037 " /flags:<flags> Assembly flags (in hexadecimal)",
1038 " /fullpaths Display files using fully-qualified filenames",
1039 " /keyf[ile]:<filename> File containing key to sign the assembly",
1040 " /keyn[ame]:<text> Key container name of key to sign assembly",
1041 " /main:<method> Specifies the method name of the entry point",
1042 " /nologo Suppress the startup banner and copyright message",
1043 " /out:<filename> Output file name for the assembly manifest",
1044 " /platform:<text> Limit which platforms this code can run on; must be",
1045 " one of x86, Itanium, x64, arm, anycpu32bitpreferred,",
1046 " or anycpu (the default)",
1047 " /prod[uct]:<text> Product name",
1048 " /productv[ersion]:<text> Product version",
1049 " /t[arget]:lib[rary] Create a library",
1050 " /t[arget]:exe Create a console executable",
1051 " /t[arget]:win[exe] Create a Windows executable",
1052 " /template:<filename> Specifies an assembly to get default options from",
1053 " /title:<text> Title",
1054 " /trade[mark]:<text> Trademark message",
1055 " /v[ersion]:<version> Version (use * to auto-generate remaining numbers)",
1056 " /win32icon:<filename> Use this icon for the output",
1057 " /win32res:<filename> Specifies the Win32 resource file",
1059 "Sources: (at least one source input is required)",
1060 " <filename>[,<targetfile>] add file to assembly",
1061 " /embed[resource]:<filename>[,<name>[,Private]]",
1062 " embed the file as a resource in the assembly",
1063 " /link[resource]:<filename>[,<name>[,<targetfile>[,Private]]]",
1064 " link the file as a resource to the assembly",