Using NetModules for Reducing Compilation Costs

May 8, 2010

one comment

A relatively obscure feature of .NET deployment is the concept of a netmodule. An assembly can contain multiple netmodules, which can be compiled separately and relinked into the assembly without recompiling other netmodules that constitute the assembly. Effectively, netmodules form a linkage boundary for managed assemblies.

The Web is full of old samples from the pre-Whidbey era that show how to use netmodules, and I got an email with a question on the subject a couple of days ago, so here’s a trivial example that shows how you can use netmodules to reduce compilation costs. First of all, we have a few source files, let’s call them A, B, and C:

//A.cs
internal class A { public static void a() { } }

//B.cs
internal class B { public static void b() { } }

//C.cs
class C {
    static void Main() {
        A.a(); B.b();

    }
}

What we’d like to do is compile A.cs and B.cs into separate netmodules, and link them together with C.cs into a single executable program. Should A.cs ever change, we would like the ability to relink the resulting executable without having to recompile B.cs—and that’s one thing netmodules can do for you.

Unfortunately, there’s no easy way to use netmodules from Visual Studio, so I wrote you a makefile:

A.netmodule: A.cs
    csc /t:module /out:A.netmodule A.cs

B.netmodule: B.cs
    csc /t:module /out:B.netmodule B.cs

all: A.netmodule B.netmodule C.cs
    csc /t:exe /out:C.exe /addmodule:A.netmodule /addmodule:B.netmodule C.cs

clean:
    del A.netmodule
    del B.netmodule
    del C.exe

This makefile can incrementally generate A.netmodule and B.netmodule from A.cs and B.cs respectively, and link them with C.cs into C.exe when necessary. If only A.cs changes, there’s no need to recompile B.cs; if only C.cs changes, there’s no need to recompile A.cs or B.cs.

You can try this out yourself by creating the three files (A.cs, B.cs, C.cs) anywhere on your file system and then creating a makefile with the above contents. Next, open a Visual Studio command prompt, navigate to that directory, and run nmake all.

Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

one comment

  1. Judah Gabriel HimangoMay 9, 2010 ב 7:46 AM

    I’m building a distributed .NET build system atop MSBuild. Using .netmodules would be a big help in parallelizing compilations.

    The problem, of course, is how to know which files go into which modules. For example, if I put class A into a.netmodule, it may have a dependency on class B and class C, and those have dependencies on other classes, and so on.

    Is there some way to specify “class A, and all its dependencies, go into this .netmodule”?

    Reply