, ,

A couple of weeks ago Jayson Knight invited me to join the CSMVP’sCSModules package. This project was created to incorporate several CSModules written by CS MVP’s. So I bought into that project by bringing along my Akismet spam rule.

At that point in time, for each CSModule there was a single Visual Studio project, all bound together in a Visual Studio solution. But our goal was to incorporate all modules into a single assembly, so the user only has to copy one DLL to his /bin web folder.

My first idea was to put all sources into a single project. However, since every CS MVP wrote his module in his favorite language, there were both C# and VB.NET projects. Unfortunately, in Visual Studio projects have a certain type supporting only a single language.

But luckily, even if there’s no support by the IDE, you still can compile different .NET languages into one assembly. The solution are modules. A module is a unit of compilation, comparable to .obj files in C++. It can’t stand by its own, but must be linked into an assembly before it can be used. Basically, a module is an assembly without a manifest. You can get more details on MSDN at .netmodule Files as Linker Input. Additionally I recommend reading Junfeng Zhang’s Netmodule vs. Assembly and Multimodule Assemblies.

Knowing the concept of modules, I was able to write a MSBuild project file to compile all CSModules into a single assembly. Here’s an (extremely) simplified version:

<Project
  DefaultTargets="build"
  xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
        
  <!-- Target folders -->
  <PropertyGroup>
    <SourcePath>src</SourcePath>
  </PropertyGroup>

  <!-- Specify the sources to include, excluding any assembly info's -->
  <ItemGroup>
    <CSFiles
      Include="$(SourcePath)/**/*.cs"
      Exclude="$(SourcePath)/**/assemblyinfo.cs"/>
    <VBFiles 
      Include="$(SourcePath)/**/*.vb" 
      Exclude="$(SourcePath)/**/assemblyinfo.vb;$(SourcePath)/**/My Project/*"/>
  </ItemGroup>

  <!-- Specify all referenced assembly -->
  <ItemGroup>
    <References Include="lib/2.1 RTM/*.dll" />
  </ItemGroup>

  <!-- Target files -->
  <PropertyGroup>
    <OutputModule>MyModule</OutputModule>
  </PropertyGroup>

  <!-- builds the CSMVPs.CSModules assembly -->
  <Target 
    Name="build"
    Inputs="@(CSFiles);@(VBFiles);@(References)" 
    Outputs="$(OutputModule).dll">

    <!-- compile C# sources -->
    <CSC
      Sources="@(CSFiles)"
      References="@(References)" 
      OutputAssembly="$(OutputModule).CS.netmodule"
      TargetType="module">
    </CSC>
      
    <!-- compile VB.NET sources -->
    <VBC
      Sources="@(VBFiles)"
      References="@(References)" 
      OutputAssembly="$(OutputModule).VB.netmodule"
      TargetType="module">
    </VBC>

    <!-- link the C# and VB.NET modules -->
    <Exec 
      Command="link /dll /ltcg /out:$(OutputModule).dll *.netmodule" />
  </Target>
</Project>

Comments

Anonymous

Thanks - that was great help.

Not being a MSBuild guru I just (proudly) managed to integrate several c# based projects in a single file assembly - after modifying parts of the central build and .csproj xmls to ensure I would actually get netmodules from VS2005.

I am still struggling to remove the external references from the assembly which I need for the VS IDE - not sure it matters, maybe for purity only. The code works as csc when adding netmodules that implement the same types as ref’d projects/dlls apparently overwrites the external reference - at least it issues a warning.

I would hope sometime this to be supported by VS.

Again - thanks for posting this!

tb

Anonymous

The command of tag not found. ¿link.exe is a external file? My system doesn't have this executable. ¿I should download it anywhere?

Thomas Freudenberg

link.exe is an external tool, which is installed with Visual Studio. To execute the script you have to either open the Visual Studio 2008 Command Prompt or set the PATH environment variable manually.

Leave a Comment

Your email address will not be published. Required fields are marked *

Loading...