diff options
author | Miguel de Icaza <miguel@gnome.org> | 2009-04-29 01:52:06 +0400 |
---|---|---|
committer | Miguel de Icaza <miguel@gnome.org> | 2009-04-29 01:52:06 +0400 |
commit | ab4caa1fbba47d12f454b11c9339e6911e713d28 (patch) | |
tree | adb0062d346461b8a30575874b207a862cb432c0 /mcs/build | |
parent | f21ba58f85048602c688aad544c93efc360d4c3d (diff) |
csproj generator
svn path=/trunk/mcs/; revision=132897
Diffstat (limited to 'mcs/build')
-rw-r--r-- | mcs/build/csproj/csproj.tmpl | 57 | ||||
-rw-r--r-- | mcs/build/csproj/genproj.cs | 448 | ||||
-rw-r--r-- | mcs/build/library.make | 18 | ||||
-rw-r--r-- | mcs/build/rules.make | 2 |
4 files changed, 525 insertions, 0 deletions
diff --git a/mcs/build/csproj/csproj.tmpl b/mcs/build/csproj/csproj.tmpl new file mode 100644 index 00000000000..d6df8615f60 --- /dev/null +++ b/mcs/build/csproj/csproj.tmpl @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{155AEF28-C81F-405D-9072-9D52780E3E70}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <OutputPath>@OUTPUTDIR@</OutputPath>
+ <DefineConstants>@DEFINECONSTANTS@</DefineConstants>
+ <CscToolPath>@CSCTOOOLPATH@</CscToolPath>
+ @NOSTDLIB@
+ @ALLOWUNSAFE@
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>mscorlib</RootNamespace>
+ <AssemblyName>@ASSEMBLYNAME@</AssemblyName>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <StartupObject>
+ </StartupObject>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>@DEFINECONSTANTS@</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>@DEFINECONSTANTS@</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <ItemGroup>
+ @SOURCES@
+ </ItemGroup>
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+ <PropertyGroup>
+ <PreBuildEvent>copy ..\..\ecma.pub ..</PreBuildEvent>
+ </PropertyGroup>
+ <ItemGroup>
+ <Folder Include="Properties\" />
+ </ItemGroup>
+</Project>
diff --git a/mcs/build/csproj/genproj.cs b/mcs/build/csproj/genproj.cs new file mode 100644 index 00000000000..446b781f290 --- /dev/null +++ b/mcs/build/csproj/genproj.cs @@ -0,0 +1,448 @@ +using System; +using System.IO; +using System.Collections.Generic; +using System.Text; +using System.Globalization; + +public enum Target { + Library, Exe, Module, WinExe +} + +public enum LanguageVersion +{ + ISO_1 = 1, + Default_MCS = 2, + ISO_2 = 3, + LINQ = 4, + Future = 5, + Default = LINQ +} + +class MsbuildGenerator { + static string read () + { + return Console.ReadLine (); + } + + // Currently used + static bool Unsafe = false; + static StringBuilder defines = new StringBuilder (); + static bool StdLib = true; + + // Currently unused + static Target Target = Target.Exe; + static string TargetExt = ".exe"; + static string OutputFile; + static bool Optimize = true; + static bool VerifyClsCompliance = true; + + static string win32IconFile; + static bool want_debugging_support = true; + static bool Checked = false; + static bool WarningsAreErrors; + static Dictionary<string,string> embedded_resources = new Dictionary<string,string> (); + static List<string> references = new List<string> (); + static List<string> warning_as_error = new List<string> (); + static int WarningLevel = 4; + static List<int> ignore_warning = new List<int> (); + static bool load_default_config = true; + static string StrongNameKeyFile; + static string StrongNameKeyContainer; + static bool StrongNameDelaySign = false; + static LanguageVersion Version = LanguageVersion.Default; + static string CodePage; + + static readonly char[] argument_value_separator = new char [] { ';', ',' }; + + static void Usage () + { + Console.WriteLine ("Invalid argument"); + } + + // + // This parses the -arg and /arg options to the compiler, even if the strings + // in the following text use "/arg" on the strings. + // + static bool CSCParseOption (string option, ref string [] args) + { + int idx = option.IndexOf (':'); + string arg, value; + + if (idx == -1){ + arg = option; + value = ""; + } else { + arg = option.Substring (0, idx); + + value = option.Substring (idx + 1); + } + + switch (arg.ToLower (CultureInfo.InvariantCulture)){ + case "/nologo": + return true; + + case "/t": + case "/target": + switch (value){ + case "exe": + Target = Target.Exe; + break; + + case "winexe": + Target = Target.WinExe; + break; + + case "library": + Target = Target.Library; + TargetExt = ".dll"; + break; + + case "module": + Target = Target.Module; + TargetExt = ".netmodule"; + break; + + default: + return false; + } + return true; + + case "/out": + if (value.Length == 0){ + Usage (); + Environment.Exit (1); + } + OutputFile = value; + return true; + + case "/o": + case "/o+": + case "/optimize": + case "/optimize+": + Optimize = true; + return true; + + case "/o-": + case "/optimize-": + Optimize = false; + return true; + + case "/incremental": + case "/incremental+": + case "/incremental-": + // nothing. + return true; + + case "/d": + case "/define": { + if (value.Length == 0){ + Usage (); + Environment.Exit (1); + } + + foreach (string d in value.Split (argument_value_separator)){ + if (defines.Length != 0) + defines.Append (";"); + defines.Append (d); + } + + return true; + } + + case "/bugreport": + // + // We should collect data, runtime, etc and store in the file specified + // + return true; + case "/linkres": + case "/linkresource": + case "/res": + case "/resource": + bool embeded = arg [1] == 'r' || arg [1] == 'R'; + string[] s = value.Split (argument_value_separator); + switch (s.Length) { + case 1: + if (s[0].Length == 0) + goto default; + embedded_resources [s[0]] = Path.GetFileName (s[0]); + break; + case 2: + embedded_resources [s [0]] = s [1]; + break; + case 3: + Console.WriteLine ("Does not support this method yet: {0}", arg); + Environment.Exit (1); + break; + default: + Console.WriteLine ("Wrong number of arguments for option `{0}'", option); + Environment.Exit (1); + break; + + } + + return true; + + case "/recurse": + Console.WriteLine ("/recurse not supported"); + Environment.Exit (1); + return true; + + case "/r": + case "/reference": { + if (value.Length == 0){ + Console.WriteLine ("-reference requires an argument"); + Environment.Exit (1); + } + + string[] refs = value.Split (argument_value_separator); + foreach (string r in refs){ + string val = r; + int index = val.IndexOf ('='); + if (index > -1) { + Console.WriteLine ("/reference = not supported"); + Environment.Exit (1); + //string alias = r.Substring (0, index); + //string assembly = r.Substring (index + 1); + //AddExternAlias (alias, assembly); + //return true; + } + + if (val.Length != 0) + references.Add (val); + } + return true; + } + case "/main": + case "/m": + case "/addmodule": + case "/win32res": + case "/doc": + case "/lib": + { + Console.WriteLine ("{0} = not supported", option); + Environment.Exit (1); + return true; + } + case "/win32icon": { + win32IconFile = value; + return true; + } + case "/debug-": + want_debugging_support = false; + return true; + + case "/debug": + case "/debug+": + want_debugging_support = true; + return true; + + case "/checked": + case "/checked+": + Checked = true; + return true; + + case "/checked-": + Checked = false; + return true; + + case "/clscheck": + case "/clscheck+": + return true; + + case "/clscheck-": + VerifyClsCompliance = false; + return true; + + case "/unsafe": + case "/unsafe+": + Unsafe = true; + return true; + + case "/unsafe-": + Unsafe = false; + return true; + + case "/warnaserror": + case "/warnaserror+": + if (value.Length == 0) { + WarningsAreErrors = true; + } else { + foreach (string wid in value.Split (argument_value_separator)) + warning_as_error.Add (wid); + } + return true; + + case "/warnaserror-": + if (value.Length == 0) { + WarningsAreErrors = false; + } else { + foreach (string wid in value.Split (argument_value_separator)) + warning_as_error.Remove (wid); + } + return true; + + case "/warn": + WarningLevel = Int32.Parse (value); + return true; + + case "/nowarn": { + string [] warns; + + if (value.Length == 0){ + Console.WriteLine ("/nowarn requires an argument"); + Environment.Exit (1); + } + + warns = value.Split (argument_value_separator); + foreach (string wc in warns){ + try { + if (wc.Trim ().Length == 0) + continue; + + int warn = Int32.Parse (wc); + if (warn < 1) { + throw new ArgumentOutOfRangeException("warn"); + } + ignore_warning.Add (warn); + } catch { + Console.WriteLine (String.Format("`{0}' is not a valid warning number", wc)); + Environment.Exit (1); + } + } + return true; + } + + case "/noconfig": + load_default_config = false; + return true; + + case "/nostdlib": + case "/nostdlib+": + StdLib = false; + return true; + + case "/nostdlib-": + StdLib = true; + return true; + + case "/fullpaths": + return true; + + case "/keyfile": + if (value == String.Empty) { + Console.WriteLine ("{0} requires an argument", arg); + Environment.Exit (1); + } + StrongNameKeyFile = value; + return true; + case "/keycontainer": + if (value == String.Empty) { + Console.WriteLine ("{0} requires an argument", arg); + Environment.Exit (1); + } + StrongNameKeyContainer = value; + return true; + case "/delaysign+": + StrongNameDelaySign = true; + return true; + case "/delaysign-": + StrongNameDelaySign = false; + return true; + + case "/langversion": + switch (value.ToLower (CultureInfo.InvariantCulture)) { + case "iso-1": + Version = LanguageVersion.ISO_1; + return true; + + case "default": + Version = LanguageVersion.Default; + return true; + case "iso-2": + Version = LanguageVersion.ISO_2; + return true; + case "future": + Version = LanguageVersion.Future; + return true; + } + Console.WriteLine ("Invalid option `{0}' for /langversion. It must be either `ISO-1', `ISO-2' or `Default'", value); + Environment.Exit (1); + return true; + + case "/codepage": + CodePage = value; + return true; + } + + return false; + } + + static void Main (string [] args) + { + if (args.Length != 1){ + Console.WriteLine ("You must specify the template file"); + return; + } + + string boot, mcs, flags, output_name, built_sources, library_output, response; + + boot = read (); + mcs = read (); + flags = read (); + output_name = read (); + built_sources = read (); + library_output = read (); + response = read (); + + string [] f = flags.Split (); + for (int i = 0; i < f.Length; i++){ + if (f [i][0] == '/') + f [i] = "/" + f [i].Substring (1); + + if (CSCParseOption (f [0], ref f)) + continue; + Console.WriteLine ("Failure"); + Environment.Exit (1); + } + + string [] source_files; + using (var reader = new StreamReader (response)){ + source_files = reader.ReadToEnd ().Split (); + } + StringBuilder sources = new StringBuilder (); + foreach (string s in source_files){ + if (s.Length == 0) + continue; + sources.Append (String.Format (" <Compile Include=\"{0}\" />\n", s)); + } + + var input = new StreamReader (args [0]); + string template = input.ReadToEnd (); + + // + // Replace the template values + // + + // + // ARGH: The CscToolPath will require more temporary setups to work properly + // corlib does this: + // MONO_PATH=./../../class/lib/net_2_0: false ./../../mcs/gmcs.exe + // + // this means: + // runtime: ../../class/lib/net_2_0 + // compiler: ../../mcs/gmcs.exe + // + // And our current `csc' script fails for this as it assumes that the + // compiler will be in the same place as the runtime + // + string output = template. + Replace ("@DEFINES@", defines.ToString ()). + Replace ("@NOSTDLIB@", StdLib ? "" : "<NoStdLib>true</NoStdLib>"). + Replace ("@ALLOWUNSAFE@", Unsafe ? "<AllowUnsafeBlocks>true</AllowUnsafeBlocks>" : ""). + Replace ("@ASSEMBLYNAME@", Path.GetFileNameWithoutExtension (output_name)). + Replace ("@OUTPUTDIR@", Path.GetDirectoryName (library_output)). + Replace ("@SOURCES@", sources.ToString ()); + + Console.WriteLine (output); + } +}
\ No newline at end of file diff --git a/mcs/build/library.make b/mcs/build/library.make index e8bd0658013..85e892edb55 100644 --- a/mcs/build/library.make +++ b/mcs/build/library.make @@ -78,6 +78,22 @@ endif all-local: $(the_lib) +ifeq ($(LIBRARY_COMPILE),$(BOOT_COMPILE)) +is_boot=true +else +is_boot=false +endif + +csproj-local: + (echo $(is_boot); \ + echo $(MCS); \ + echo $(USE_MCS_FLAGS) $(LIBRARY_FLAGS) $(LIB_MCS_FLAGS); \ + echo $(LIBRARY_NAME); \ + echo $(BUILT_SOURCES_cmdline); \ + echo $(build_lib); \ + echo $(response)) | mono $(topdir)/build/csproj/genproj.exe $(topdir)/build/csproj/csproj.tmpl > `basename $(LIBRARY_NAME) .dll`.csproj + + install-local: all-local test-local: all-local uninstall-local: @@ -213,6 +229,8 @@ else $(LIBRARY_COMPILE) $(LIBRARY_FLAGS) $(LIB_MCS_FLAGS) -target:library -out:$@ $(BUILT_SOURCES_cmdline) @$(response) $(SN) $(SNFLAGS) $@ $(LIBRARY_SNK) endif + + ifdef ENABLE_AOT ifneq (,$(filter $(AOT_IN_PROFILES), $(PROFILE))) $(Q_AOT) MONO_PATH=$(the_libdir) $(RUNTIME) --aot=bind-to-runtime-version $@ > $(PROFILE)_aot.log 2>&1 diff --git a/mcs/build/rules.make b/mcs/build/rules.make index 6ae77550463..43cc69dd8e3 100644 --- a/mcs/build/rules.make +++ b/mcs/build/rules.make @@ -127,6 +127,8 @@ do-run-test: do-%: %-recursive $(MAKE) $*-local +csproj: do-csproj + # The way this is set up, any profile-specific subdirs list should # be listed _before_ including rules.make. However, the default # SUBDIRS list can come after, so don't use the eager := syntax when |