Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)

Improved the wrapper: it is now a separate component invoking the executable's main method through the refelection API

svn path=/nixpkgs/trunk/; revision=29239

+265 -94
-64
pkgs/build-support/dotnetenv/Wrapper.cs.in
··· 1 - using System; 2 - using System.Reflection; 3 - using System.IO; 4 - 5 - namespace @NAMESPACE@ 6 - { 7 - class @MAINCLASSNAME@Wrapper 8 - { 9 - private String[] AssemblySearchPaths = { @ASSEMBLYSEARCHPATHS@ }; 10 - 11 - public @MAINCLASSNAME@Wrapper() 12 - { 13 - AppDomain currentDomain = AppDomain.CurrentDomain; 14 - currentDomain.AssemblyResolve += new ResolveEventHandler(MyResolveEventHandler); 15 - } 16 - 17 - static void Main(string[] args) 18 - { 19 - // Initialise the wrapper so that the missing library assemblies are loaded 20 - new @MAINCLASSNAME@Wrapper(); 21 - 22 - // Call the original main method 23 - @MAINCLASSNAME@.Main2(args); 24 - } 25 - 26 - private Assembly MyResolveEventHandler(object sender, ResolveEventArgs args) 27 - { 28 - //This handler is called only when the common language runtime tries to bind to the assembly and fails. 29 - 30 - //Retrieve the list of referenced assemblies in an array of AssemblyName. 31 - Assembly MyAssembly, executingAssemblies; 32 - string assemblyPath = ""; 33 - 34 - executingAssemblies = Assembly.GetExecutingAssembly(); 35 - AssemblyName[] referencedAssemblies = executingAssemblies.GetReferencedAssemblies(); 36 - 37 - //Loop through the array of referenced assembly names. 38 - foreach (AssemblyName assemblyName in referencedAssemblies) 39 - { 40 - //Check for the assembly names that have raised the "AssemblyResolve" event. 41 - if (assemblyName.FullName.Substring(0, assemblyName.FullName.IndexOf(",")) == args.Name.Substring(0, args.Name.IndexOf(","))) 42 - { 43 - //Retrieve the name of the assembly from where it has to be loaded. 44 - String dllName = args.Name.Substring(0, args.Name.IndexOf(",")) + ".dll"; 45 - 46 - //Search for the right path of the library assembly 47 - foreach (String currentAssemblyPath in AssemblySearchPaths) 48 - { 49 - assemblyPath = currentAssemblyPath + "/" + dllName; 50 - if (File.Exists(assemblyPath)) 51 - break; 52 - } 53 - } 54 - } 55 - 56 - //Load the assembly from the specified path. 57 - MyAssembly = Assembly.LoadFrom(assemblyPath); 58 - 59 - //Return the loaded assembly. 60 - return MyAssembly; 61 - } 62 - 63 - } 64 - }
+20
pkgs/build-support/dotnetenv/Wrapper/Wrapper.sln
··· 1 +  2 + Microsoft Visual Studio Solution File, Format Version 11.00 3 + # Visual Studio 2010 4 + Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wrapper", "Wrapper\Wrapper.csproj", "{D01B3597-E85E-42F4-940A-EF5AE712942F}" 5 + EndProject 6 + Global 7 + GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 + Debug|x86 = Debug|x86 9 + Release|x86 = Release|x86 10 + EndGlobalSection 11 + GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 + {D01B3597-E85E-42F4-940A-EF5AE712942F}.Debug|x86.ActiveCfg = Debug|x86 13 + {D01B3597-E85E-42F4-940A-EF5AE712942F}.Debug|x86.Build.0 = Debug|x86 14 + {D01B3597-E85E-42F4-940A-EF5AE712942F}.Release|x86.ActiveCfg = Release|x86 15 + {D01B3597-E85E-42F4-940A-EF5AE712942F}.Release|x86.Build.0 = Release|x86 16 + EndGlobalSection 17 + GlobalSection(SolutionProperties) = preSolution 18 + HideSolutionNode = FALSE 19 + EndGlobalSection 20 + EndGlobal
+36
pkgs/build-support/dotnetenv/Wrapper/Wrapper/Properties/AssemblyInfo.cs
··· 1 + using System.Reflection; 2 + using System.Runtime.CompilerServices; 3 + using System.Runtime.InteropServices; 4 + 5 + // General Information about an assembly is controlled through the following 6 + // set of attributes. Change these attribute values to modify the information 7 + // associated with an assembly. 8 + [assembly: AssemblyTitle("Wrapper")] 9 + [assembly: AssemblyDescription("")] 10 + [assembly: AssemblyConfiguration("")] 11 + [assembly: AssemblyCompany("Philips Healthcare")] 12 + [assembly: AssemblyProduct("Wrapper")] 13 + [assembly: AssemblyCopyright("Copyright © Philips Healthcare 2011")] 14 + [assembly: AssemblyTrademark("")] 15 + [assembly: AssemblyCulture("")] 16 + 17 + // Setting ComVisible to false makes the types in this assembly not visible 18 + // to COM components. If you need to access a type in this assembly from 19 + // COM, set the ComVisible attribute to true on that type. 20 + [assembly: ComVisible(false)] 21 + 22 + // The following GUID is for the ID of the typelib if this project is exposed to COM 23 + [assembly: Guid("2045ce22-78c7-4cd6-ad0a-9367f8a49738")] 24 + 25 + // Version information for an assembly consists of the following four values: 26 + // 27 + // Major Version 28 + // Minor Version 29 + // Build Number 30 + // Revision 31 + // 32 + // You can specify all the values or you can default the Build and Revision Numbers 33 + // by using the '*' as shown below: 34 + // [assembly: AssemblyVersion("1.0.*")] 35 + [assembly: AssemblyVersion("1.0.0.0")] 36 + [assembly: AssemblyFileVersion("1.0.0.0")]
+78
pkgs/build-support/dotnetenv/Wrapper/Wrapper/Wrapper.cs.in
··· 1 + using System; 2 + using System.Reflection; 3 + using System.IO; 4 + 5 + namespace @NAMESPACE@Wrapper 6 + { 7 + class @MAINCLASSNAME@Wrapper 8 + { 9 + private String[] AssemblySearchPaths = { @ASSEMBLYSEARCHPATH@ }; 10 + 11 + private String ExePath = @"@EXEPATH@"; 12 + 13 + private String MainClassName = "@NAMESPACE@.@MAINCLASSNAME@"; 14 + 15 + private Assembly exeAssembly; 16 + 17 + public @MAINCLASSNAME@Wrapper(string[] args) 18 + { 19 + // Attach the resolve event handler to the AppDomain so that missing library assemblies will be searched 20 + AppDomain currentDomain = AppDomain.CurrentDomain; 21 + currentDomain.AssemblyResolve += new ResolveEventHandler(MyResolveEventHandler); 22 + 23 + // Dynamically load the executable assembly 24 + exeAssembly = Assembly.LoadFrom(ExePath); 25 + 26 + // Lookup the main class 27 + Type mainClass = exeAssembly.GetType(MainClassName); 28 + 29 + // Lookup the main method 30 + MethodInfo mainMethod = mainClass.GetMethod("Main"); 31 + 32 + // Invoke the main method 33 + mainMethod.Invoke(this, new Object[] {args}); 34 + } 35 + 36 + static void Main(string[] args) 37 + { 38 + new @MAINCLASSNAME@Wrapper(args); 39 + } 40 + 41 + private Assembly MyResolveEventHandler(object sender, ResolveEventArgs args) 42 + { 43 + //This handler is called only when the common language runtime tries to bind to the assembly and fails. 44 + 45 + //Retrieve the list of referenced assemblies in an array of AssemblyName. 46 + Assembly MyAssembly; 47 + string assemblyPath = ""; 48 + 49 + AssemblyName[] referencedAssemblies = exeAssembly.GetReferencedAssemblies(); 50 + 51 + //Loop through the array of referenced assembly names. 52 + foreach (AssemblyName assemblyName in referencedAssemblies) 53 + { 54 + //Check for the assembly names that have raised the "AssemblyResolve" event. 55 + if (assemblyName.FullName.Substring(0, assemblyName.FullName.IndexOf(",")) == args.Name.Substring(0, args.Name.IndexOf(","))) 56 + { 57 + //Retrieve the name of the assembly from where it has to be loaded. 58 + String dllName = args.Name.Substring(0, args.Name.IndexOf(",")) + ".dll"; 59 + 60 + //Search for the right path of the library assembly 61 + foreach (String currentAssemblyPath in AssemblySearchPaths) 62 + { 63 + assemblyPath = currentAssemblyPath + "/" + dllName; 64 + if (File.Exists(assemblyPath)) 65 + break; 66 + } 67 + } 68 + } 69 + 70 + //Load the assembly from the specified path. 71 + MyAssembly = Assembly.LoadFrom(assemblyPath); 72 + 73 + //Return the loaded assembly. 74 + return MyAssembly; 75 + } 76 + 77 + } 78 + }
+57
pkgs/build-support/dotnetenv/Wrapper/Wrapper/Wrapper.csproj.in
··· 1 + <?xml version="1.0" encoding="utf-8"?> 2 + <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 3 + <PropertyGroup> 4 + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> 5 + <Platform Condition=" '$(Platform)' == '' ">x86</Platform> 6 + <ProductVersion>8.0.30703</ProductVersion> 7 + <SchemaVersion>2.0</SchemaVersion> 8 + <ProjectGuid>{D01B3597-E85E-42F4-940A-EF5AE712942F}</ProjectGuid> 9 + <OutputType>Exe</OutputType> 10 + <AppDesignerFolder>Properties</AppDesignerFolder> 11 + <RootNamespace>@ROOTNAMESPACE@</RootNamespace> 12 + <AssemblyName>@ASSEMBLYNAME@</AssemblyName> 13 + <TargetFrameworkVersion>v4.0</TargetFrameworkVersion> 14 + <TargetFrameworkProfile>Client</TargetFrameworkProfile> 15 + <FileAlignment>512</FileAlignment> 16 + </PropertyGroup> 17 + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' "> 18 + <PlatformTarget>x86</PlatformTarget> 19 + <DebugSymbols>true</DebugSymbols> 20 + <DebugType>full</DebugType> 21 + <Optimize>false</Optimize> 22 + <OutputPath>bin\Debug\</OutputPath> 23 + <DefineConstants>DEBUG;TRACE</DefineConstants> 24 + <ErrorReport>prompt</ErrorReport> 25 + <WarningLevel>4</WarningLevel> 26 + </PropertyGroup> 27 + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' "> 28 + <PlatformTarget>x86</PlatformTarget> 29 + <DebugType>pdbonly</DebugType> 30 + <Optimize>true</Optimize> 31 + <OutputPath>bin\Release\</OutputPath> 32 + <DefineConstants>TRACE</DefineConstants> 33 + <ErrorReport>prompt</ErrorReport> 34 + <WarningLevel>4</WarningLevel> 35 + </PropertyGroup> 36 + <ItemGroup> 37 + <Reference Include="System" /> 38 + <Reference Include="System.Core" /> 39 + <Reference Include="System.Xml.Linq" /> 40 + <Reference Include="System.Data.DataSetExtensions" /> 41 + <Reference Include="Microsoft.CSharp" /> 42 + <Reference Include="System.Data" /> 43 + <Reference Include="System.Xml" /> 44 + </ItemGroup> 45 + <ItemGroup> 46 + <Compile Include="Wrapper.cs" /> 47 + <Compile Include="Properties\AssemblyInfo.cs" /> 48 + </ItemGroup> 49 + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> 50 + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 51 + Other similar extension points exist, see Microsoft.Common.targets. 52 + <Target Name="BeforeBuild"> 53 + </Target> 54 + <Target Name="AfterBuild"> 55 + </Target> 56 + --> 57 + </Project>
+16 -28
pkgs/build-support/dotnetenv/build-solution.nix
··· 8 8 , options ? "/p:Configuration=Debug;Platform=Win32" 9 9 , assemblyInputs ? [] 10 10 , preBuild ? "" 11 - , wrapMain ? false 12 - , namespace ? null 13 - , mainClassName ? null 11 + , modifyPublicMain ? false 14 12 , mainClassFile ? null 15 13 }: 16 14 17 - assert wrapMain -> namespace != null && mainClassName != null && mainClassFile != null; 15 + assert modifyPublicMain -> mainClassFile != null; 18 16 19 17 let 20 18 wrapperCS = ./Wrapper.cs.in; ··· 29 27 ''; 30 28 31 29 preBuild = '' 32 - ${preBuild} 33 - 34 - # Create wrapper class with main method 35 - ${stdenv.lib.optionalString wrapMain '' 36 - # Generate assemblySearchPaths string array contents 37 - for path in ${toString assemblyInputs} 38 - do 39 - assemblySearchArray="$assemblySearchPaths @\"$(cygpath --windows $path | sed 's|\\|\\\\|g')\"" 40 - done 41 - 42 - sed -e "s|@NAMESPACE@|${namespace}|" \ 43 - -e "s|@MAINCLASSNAME@|${mainClassName}|" \ 44 - -e "s|@ASSEMBLYSEARCHPATHS@|$assemblySearchArray|" \ 45 - ${wrapperCS} > $(dirname ${mainClassFile})/${mainClassName}Wrapper.cs 46 - 47 - # Rename old main method and make it publically accessible 48 - # so that the wrapper can invoke it 49 - sed -i -e "s|static void Main|public static void Main2|g" ${mainClassFile} 50 - 51 - # Add the wrapper to the C# project file so that will be build as well 52 - find . -name \*.csproj | while read file 53 - do 54 - sed -i -e "s|$(basename ${mainClassFile})|$(basename ${mainClassFile});${mainClassName}Wrapper.cs|" "$file" 55 - done 30 + ${stdenv.lib.optionalString modifyPublicMain '' 31 + sed -i -e "s|static void Main|public static void Main|" ${mainClassFile} 56 32 ''} 33 + ${preBuild} 57 34 ''; 58 35 59 36 installPhase = '' ··· 80 57 81 58 ensureDir $out 82 59 MSBuild.exe ${toString slnFile} /nologo /t:${targets} /p:IntermediateOutputPath=$(cygpath --windows $out)\\ /p:OutputPath=$(cygpath --windows $out)\\ /verbosity:${verbosity} ${options} 60 + 61 + # Because .NET assemblies store strings as UTF-16 internally, we cannot detect 62 + # hashes. Therefore a text files containing the proper paths is created 63 + # We can also use this file the propagate transitive dependencies. 64 + 65 + ensureDir $out/nix-support 66 + 67 + for i in ${toString assemblyInputs} 68 + do 69 + echo $i >> $out/nix-support/dotnet-assemblies 70 + done 83 71 ''; 84 72 }
+9 -2
pkgs/build-support/dotnetenv/default.nix
··· 1 1 {stdenv, dotnetfx}: 2 2 3 + let dotnetenv = 3 4 { 4 5 buildSolution = import ./build-solution.nix { 5 6 inherit stdenv; 6 7 dotnetfx = dotnetfx.pkg; 7 8 }; 8 - 9 + 10 + buildWrapper = import ./wrapper.nix { 11 + inherit dotnetenv; 12 + }; 13 + 9 14 inherit (dotnetfx) assembly20Path wcfPath referenceAssembly30Path referenceAssembly35Path; 10 - } 15 + }; 16 + in 17 + dotnetenv
+49
pkgs/build-support/dotnetenv/wrapper.nix
··· 1 + {dotnetenv}: 2 + 3 + { name 4 + , src 5 + , baseDir ? "." 6 + , slnFile 7 + , targets ? "ReBuild" 8 + , verbosity ? "detailed" 9 + , options ? "/p:Configuration=Debug;Platform=Win32" 10 + , assemblyInputs ? [] 11 + , preBuild ? "" 12 + , namespace 13 + , mainClassName 14 + , mainClassFile 15 + , modifyPublicMain ? true 16 + }: 17 + 18 + let 19 + application = dotnetenv.buildSolution { 20 + inherit name src baseDir slnFile targets verbosity; 21 + inherit options assemblyInputs preBuild; 22 + inherit modifyPublicMain mainClassFile; 23 + }; 24 + in 25 + dotnetenv.buildSolution { 26 + name = "${name}-wrapper"; 27 + src = ./Wrapper; 28 + slnFile = "Wrapper.sln"; 29 + assemblyInputs = [ application ]; 30 + preBuild = '' 31 + export exePath=$(cygpath --windows $(find ${application} -name \*.exe) | sed 's|\\|\\\\|g') 32 + 33 + # Generate assemblySearchPaths string array contents 34 + for path in ${toString assemblyInputs} 35 + do 36 + assemblySearchArray="$assemblySearchArray @\"$(cygpath --windows $path | sed 's|\\|\\\\|g')\"" 37 + done 38 + 39 + sed -e "s|@ROOTNAMESPACE@|${namespace}Wrapper|" \ 40 + -e "s|@ASSEMBLYNAME@|${namespace}|" \ 41 + Wrapper/Wrapper.csproj.in > Wrapper/Wrapper.csproj 42 + 43 + sed -e "s|@NAMESPACE@|${namespace}|g" \ 44 + -e "s|@MAINCLASSNAME@|${mainClassName}|g" \ 45 + -e "s|@EXEPATH@|$exePath|g" \ 46 + -e "s|@ASSEMBLYSEARCHPATH@|$assemblySearchArray|" \ 47 + Wrapper/Wrapper.cs.in > Wrapper/Wrapper.cs 48 + ''; 49 + }