summary refs log tree commit diff
diff options
context:
space:
mode:
authorSander van der Burg <s.vanderburg@tudelft.nl>2011-09-13 15:47:54 +0000
committerSander van der Burg <s.vanderburg@tudelft.nl>2011-09-13 15:47:54 +0000
commit06891d39973eb7bbf080657a57acd6180d4d85ae (patch)
treef4255ec7c978b63bcc1bbd785b3b5c9bb2379f63
parent15293fa398700986bc9ee66529e0cd03aa9183e1 (diff)
downloadnixpkgs-06891d39973eb7bbf080657a57acd6180d4d85ae.tar
nixpkgs-06891d39973eb7bbf080657a57acd6180d4d85ae.tar.gz
nixpkgs-06891d39973eb7bbf080657a57acd6180d4d85ae.tar.bz2
nixpkgs-06891d39973eb7bbf080657a57acd6180d4d85ae.tar.lz
nixpkgs-06891d39973eb7bbf080657a57acd6180d4d85ae.tar.xz
nixpkgs-06891d39973eb7bbf080657a57acd6180d4d85ae.tar.zst
nixpkgs-06891d39973eb7bbf080657a57acd6180d4d85ae.zip
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
-rw-r--r--pkgs/build-support/dotnetenv/Wrapper/Wrapper.sln20
-rw-r--r--pkgs/build-support/dotnetenv/Wrapper/Wrapper/Properties/AssemblyInfo.cs36
-rwxr-xr-xpkgs/build-support/dotnetenv/Wrapper/Wrapper/Wrapper.cs.in (renamed from pkgs/build-support/dotnetenv/Wrapper.cs.in)36
-rw-r--r--pkgs/build-support/dotnetenv/Wrapper/Wrapper/Wrapper.csproj.in57
-rw-r--r--pkgs/build-support/dotnetenv/build-solution.nix44
-rw-r--r--pkgs/build-support/dotnetenv/default.nix11
-rw-r--r--pkgs/build-support/dotnetenv/wrapper.nix49
7 files changed, 212 insertions, 41 deletions
diff --git a/pkgs/build-support/dotnetenv/Wrapper/Wrapper.sln b/pkgs/build-support/dotnetenv/Wrapper/Wrapper.sln
new file mode 100644
index 00000000000..f2e7d4cf8b2
--- /dev/null
+++ b/pkgs/build-support/dotnetenv/Wrapper/Wrapper.sln
@@ -0,0 +1,20 @@
+

+Microsoft Visual Studio Solution File, Format Version 11.00

+# Visual Studio 2010

+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wrapper", "Wrapper\Wrapper.csproj", "{D01B3597-E85E-42F4-940A-EF5AE712942F}"

+EndProject

+Global

+	GlobalSection(SolutionConfigurationPlatforms) = preSolution

+		Debug|x86 = Debug|x86

+		Release|x86 = Release|x86

+	EndGlobalSection

+	GlobalSection(ProjectConfigurationPlatforms) = postSolution

+		{D01B3597-E85E-42F4-940A-EF5AE712942F}.Debug|x86.ActiveCfg = Debug|x86

+		{D01B3597-E85E-42F4-940A-EF5AE712942F}.Debug|x86.Build.0 = Debug|x86

+		{D01B3597-E85E-42F4-940A-EF5AE712942F}.Release|x86.ActiveCfg = Release|x86

+		{D01B3597-E85E-42F4-940A-EF5AE712942F}.Release|x86.Build.0 = Release|x86

+	EndGlobalSection

+	GlobalSection(SolutionProperties) = preSolution

+		HideSolutionNode = FALSE

+	EndGlobalSection

+EndGlobal

diff --git a/pkgs/build-support/dotnetenv/Wrapper/Wrapper/Properties/AssemblyInfo.cs b/pkgs/build-support/dotnetenv/Wrapper/Wrapper/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000000..633d23c05ff
--- /dev/null
+++ b/pkgs/build-support/dotnetenv/Wrapper/Wrapper/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;

+using System.Runtime.CompilerServices;

+using System.Runtime.InteropServices;

+

+// General Information about an assembly is controlled through the following 

+// set of attributes. Change these attribute values to modify the information

+// associated with an assembly.

+[assembly: AssemblyTitle("Wrapper")]

+[assembly: AssemblyDescription("")]

+[assembly: AssemblyConfiguration("")]

+[assembly: AssemblyCompany("Philips Healthcare")]

+[assembly: AssemblyProduct("Wrapper")]

+[assembly: AssemblyCopyright("Copyright © Philips Healthcare 2011")]

+[assembly: AssemblyTrademark("")]

+[assembly: AssemblyCulture("")]

+

+// Setting ComVisible to false makes the types in this assembly not visible 

+// to COM components.  If you need to access a type in this assembly from 

+// COM, set the ComVisible attribute to true on that type.

+[assembly: ComVisible(false)]

+

+// The following GUID is for the ID of the typelib if this project is exposed to COM

+[assembly: Guid("2045ce22-78c7-4cd6-ad0a-9367f8a49738")]

+

+// Version information for an assembly consists of the following four values:

+//

+//      Major Version

+//      Minor Version 

+//      Build Number

+//      Revision

+//

+// You can specify all the values or you can default the Build and Revision Numbers 

+// by using the '*' as shown below:

+// [assembly: AssemblyVersion("1.0.*")]

+[assembly: AssemblyVersion("1.0.0.0")]

+[assembly: AssemblyFileVersion("1.0.0.0")]

diff --git a/pkgs/build-support/dotnetenv/Wrapper.cs.in b/pkgs/build-support/dotnetenv/Wrapper/Wrapper/Wrapper.cs.in
index 1c70946d06f..4ea0d6ee6fa 100755
--- a/pkgs/build-support/dotnetenv/Wrapper.cs.in
+++ b/pkgs/build-support/dotnetenv/Wrapper/Wrapper/Wrapper.cs.in
@@ -2,25 +2,40 @@ using System;
 using System.Reflection;

 using System.IO;

 

-namespace @NAMESPACE@

+namespace @NAMESPACE@Wrapper

 {

     class @MAINCLASSNAME@Wrapper

     {

-        private String[] AssemblySearchPaths = { @ASSEMBLYSEARCHPATHS@ };

+        private String[] AssemblySearchPaths = { @ASSEMBLYSEARCHPATH@ };

 

-        public @MAINCLASSNAME@Wrapper()

+        private String ExePath = @"@EXEPATH@";

+

+        private String MainClassName = "@NAMESPACE@.@MAINCLASSNAME@";

+

+        private Assembly exeAssembly;

+

+        public @MAINCLASSNAME@Wrapper(string[] args)

         {

+            // Attach the resolve event handler to the AppDomain so that missing library assemblies will be searched

             AppDomain currentDomain = AppDomain.CurrentDomain;

             currentDomain.AssemblyResolve += new ResolveEventHandler(MyResolveEventHandler);

+

+            // Dynamically load the executable assembly

+            exeAssembly = Assembly.LoadFrom(ExePath);

+

+            // Lookup the main class

+            Type mainClass = exeAssembly.GetType(MainClassName);

+

+            // Lookup the main method

+            MethodInfo mainMethod = mainClass.GetMethod("Main");

+

+            // Invoke the main method

+            mainMethod.Invoke(this, new Object[] {args});

         }

 

         static void Main(string[] args)

         {

-            // Initialise the wrapper so that the missing library assemblies are loaded

-            new @MAINCLASSNAME@Wrapper();

-

-            // Call the original main method

-            @MAINCLASSNAME@.Main2(args);

+            new @MAINCLASSNAME@Wrapper(args);

         }

 

         private Assembly MyResolveEventHandler(object sender, ResolveEventArgs args)

@@ -28,11 +43,10 @@ namespace @NAMESPACE@
             //This handler is called only when the common language runtime tries to bind to the assembly and fails.

 

             //Retrieve the list of referenced assemblies in an array of AssemblyName.

-            Assembly MyAssembly, executingAssemblies;

+            Assembly MyAssembly;

             string assemblyPath = "";

 

-            executingAssemblies = Assembly.GetExecutingAssembly();

-            AssemblyName[] referencedAssemblies = executingAssemblies.GetReferencedAssemblies();

+            AssemblyName[] referencedAssemblies = exeAssembly.GetReferencedAssemblies();

 

             //Loop through the array of referenced assembly names.

             foreach (AssemblyName assemblyName in referencedAssemblies)

diff --git a/pkgs/build-support/dotnetenv/Wrapper/Wrapper/Wrapper.csproj.in b/pkgs/build-support/dotnetenv/Wrapper/Wrapper/Wrapper.csproj.in
new file mode 100644
index 00000000000..a991bcb6933
--- /dev/null
+++ b/pkgs/build-support/dotnetenv/Wrapper/Wrapper/Wrapper.csproj.in
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>

+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

+  <PropertyGroup>

+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>

+    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>

+    <ProductVersion>8.0.30703</ProductVersion>

+    <SchemaVersion>2.0</SchemaVersion>

+    <ProjectGuid>{D01B3597-E85E-42F4-940A-EF5AE712942F}</ProjectGuid>

+    <OutputType>Exe</OutputType>

+    <AppDesignerFolder>Properties</AppDesignerFolder>

+    <RootNamespace>@ROOTNAMESPACE@</RootNamespace>

+    <AssemblyName>@ASSEMBLYNAME@</AssemblyName>

+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>

+    <TargetFrameworkProfile>Client</TargetFrameworkProfile>

+    <FileAlignment>512</FileAlignment>

+  </PropertyGroup>

+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">

+    <PlatformTarget>x86</PlatformTarget>

+    <DebugSymbols>true</DebugSymbols>

+    <DebugType>full</DebugType>

+    <Optimize>false</Optimize>

+    <OutputPath>bin\Debug\</OutputPath>

+    <DefineConstants>DEBUG;TRACE</DefineConstants>

+    <ErrorReport>prompt</ErrorReport>

+    <WarningLevel>4</WarningLevel>

+  </PropertyGroup>

+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">

+    <PlatformTarget>x86</PlatformTarget>

+    <DebugType>pdbonly</DebugType>

+    <Optimize>true</Optimize>

+    <OutputPath>bin\Release\</OutputPath>

+    <DefineConstants>TRACE</DefineConstants>

+    <ErrorReport>prompt</ErrorReport>

+    <WarningLevel>4</WarningLevel>

+  </PropertyGroup>

+  <ItemGroup>

+    <Reference Include="System" />

+    <Reference Include="System.Core" />

+    <Reference Include="System.Xml.Linq" />

+    <Reference Include="System.Data.DataSetExtensions" />

+    <Reference Include="Microsoft.CSharp" />

+    <Reference Include="System.Data" />

+    <Reference Include="System.Xml" />

+  </ItemGroup>

+  <ItemGroup>

+    <Compile Include="Wrapper.cs" />

+    <Compile Include="Properties\AssemblyInfo.cs" />

+  </ItemGroup>

+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

+  <!-- 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>

+  -->

+</Project>
\ No newline at end of file
diff --git a/pkgs/build-support/dotnetenv/build-solution.nix b/pkgs/build-support/dotnetenv/build-solution.nix
index da2097d9d52..8640cf0014f 100644
--- a/pkgs/build-support/dotnetenv/build-solution.nix
+++ b/pkgs/build-support/dotnetenv/build-solution.nix
@@ -8,13 +8,11 @@
 , options ? "/p:Configuration=Debug;Platform=Win32"
 , assemblyInputs ? []
 , preBuild ? ""
-, wrapMain ? false
-, namespace ? null
-, mainClassName ? null
+, modifyPublicMain ? false
 , mainClassFile ? null
 }:
 
-assert wrapMain -> namespace != null && mainClassName != null && mainClassFile != null;
+assert modifyPublicMain -> mainClassFile != null;
 
 let
   wrapperCS = ./Wrapper.cs.in;  
@@ -29,31 +27,10 @@ stdenv.mkDerivation {
   '';
   
   preBuild = ''
-    ${preBuild}
-    
-    # Create wrapper class with main method
-    ${stdenv.lib.optionalString wrapMain ''
-      # Generate assemblySearchPaths string array contents
-      for path in ${toString assemblyInputs}
-      do
-          assemblySearchArray="$assemblySearchPaths @\"$(cygpath --windows $path | sed 's|\\|\\\\|g')\""
-      done
-
-      sed -e "s|@NAMESPACE@|${namespace}|" \
-          -e "s|@MAINCLASSNAME@|${mainClassName}|" \
-	  -e "s|@ASSEMBLYSEARCHPATHS@|$assemblySearchArray|" \
-          ${wrapperCS} > $(dirname ${mainClassFile})/${mainClassName}Wrapper.cs
-
-      # Rename old main method and make it publically accessible
-      # so that the wrapper can invoke it
-      sed -i -e "s|static void Main|public static void Main2|g" ${mainClassFile}
-      
-      # Add the wrapper to the C# project file so that will be build as well
-      find . -name \*.csproj | while read file
-      do
-          sed -i -e "s|$(basename ${mainClassFile})|$(basename ${mainClassFile});${mainClassName}Wrapper.cs|" "$file"
-      done
+    ${stdenv.lib.optionalString modifyPublicMain ''
+      sed -i -e "s|static void Main|public static void Main|" ${mainClassFile}
     ''}
+    ${preBuild}
   '';
   
   installPhase = ''        
@@ -80,5 +57,16 @@ stdenv.mkDerivation {
     
     ensureDir $out
     MSBuild.exe ${toString slnFile} /nologo /t:${targets} /p:IntermediateOutputPath=$(cygpath --windows $out)\\ /p:OutputPath=$(cygpath --windows $out)\\ /verbosity:${verbosity} ${options}
+    
+    # Because .NET assemblies store strings as UTF-16 internally, we cannot detect
+    # hashes. Therefore a text files containing the proper paths is created
+    # We can also use this file the propagate transitive dependencies.
+    
+    ensureDir $out/nix-support
+    
+    for i in ${toString assemblyInputs}
+    do
+        echo $i >> $out/nix-support/dotnet-assemblies
+    done
   '';
 }
diff --git a/pkgs/build-support/dotnetenv/default.nix b/pkgs/build-support/dotnetenv/default.nix
index 2389a479029..781a5ba8c0e 100644
--- a/pkgs/build-support/dotnetenv/default.nix
+++ b/pkgs/build-support/dotnetenv/default.nix
@@ -1,10 +1,17 @@
 {stdenv, dotnetfx}:
 
+let dotnetenv =
 {
   buildSolution = import ./build-solution.nix {
     inherit stdenv;
     dotnetfx = dotnetfx.pkg;
   };
-    
+
+  buildWrapper = import ./wrapper.nix {
+    inherit dotnetenv;
+  };
+  
   inherit (dotnetfx) assembly20Path wcfPath referenceAssembly30Path referenceAssembly35Path;
-}
+};
+in
+dotnetenv
diff --git a/pkgs/build-support/dotnetenv/wrapper.nix b/pkgs/build-support/dotnetenv/wrapper.nix
new file mode 100644
index 00000000000..a82e410637d
--- /dev/null
+++ b/pkgs/build-support/dotnetenv/wrapper.nix
@@ -0,0 +1,49 @@
+{dotnetenv}:
+
+{ name
+, src
+, baseDir ? "."
+, slnFile
+, targets ? "ReBuild"
+, verbosity ? "detailed"
+, options ? "/p:Configuration=Debug;Platform=Win32"
+, assemblyInputs ? []
+, preBuild ? ""
+, namespace
+, mainClassName
+, mainClassFile
+, modifyPublicMain ? true
+}:
+
+let
+  application = dotnetenv.buildSolution {
+    inherit name src baseDir slnFile targets verbosity;
+    inherit options assemblyInputs preBuild;
+    inherit modifyPublicMain mainClassFile;
+  };
+in
+dotnetenv.buildSolution {
+  name = "${name}-wrapper";
+  src = ./Wrapper;
+  slnFile = "Wrapper.sln";
+  assemblyInputs = [ application ];
+  preBuild = ''
+    export exePath=$(cygpath --windows $(find ${application} -name \*.exe) | sed 's|\\|\\\\|g')
+    
+    # Generate assemblySearchPaths string array contents
+    for path in ${toString assemblyInputs}
+    do
+        assemblySearchArray="$assemblySearchArray @\"$(cygpath --windows $path | sed 's|\\|\\\\|g')\""
+    done
+    
+    sed -e "s|@ROOTNAMESPACE@|${namespace}Wrapper|" \
+        -e "s|@ASSEMBLYNAME@|${namespace}|" \
+        Wrapper/Wrapper.csproj.in > Wrapper/Wrapper.csproj
+    
+    sed -e "s|@NAMESPACE@|${namespace}|g" \
+        -e "s|@MAINCLASSNAME@|${mainClassName}|g" \
+	-e "s|@EXEPATH@|$exePath|g" \
+	-e "s|@ASSEMBLYSEARCHPATH@|$assemblySearchArray|" \
+        Wrapper/Wrapper.cs.in > Wrapper/Wrapper.cs
+  '';
+}