Replacing al.exe with csc.exe

I've seen a awful lot of comments lately about all the cool stuff that can be done with al.exe.  I'd just like to point out that with very few exceptions csc.exe can do almost everything that al.exe can do.  One of those exceptions deals with the /template option. Another one has to do with managed resources (see below).  The last one will have to wait for my next blog (unless you think you're smart enough to guess it, and yes that is a challenge).

I think the problem is just a matter of naming.  People think a compiler is just for compiling, so when they don't have any source to compile, they look for something else to do the job.  They find al.exe and stop looking.  So here's my attempt to correct some of these misconceptions (and point out some of the few legitimate differences).

  • al.exe is the perfect tool for resources.  Wrong.  It is no better or worse than csc.exe.  What little code they don't actually share by way of alink.dll, was copied and pasted.  Now granted the IDE doesn't do a great job of exposing this functionality, but it you've got a custom build rule to call, al.exe, you might as well have a custom build rule to call csc.exe.  Now here's the only difference between csc.exe and al.exe: al.exe will allow you to specify resources as being private (meaning they're only accessible within that assembly).  Now if you understand how localization and satellite assemblies work, then you'll also know that it requires resources to be public.  Also even if they are private, anything with reflection permission can also get at them, not to mention anybody who can read your binary.  So this just seems like a non-feature.  Although for the 2005 csc.exe is getting “,Private“!
  • al.exe is better at linking modules.  Wrong.  First of all there is no linking of modules in the classic native world of .obj/.lib linking where you end up with a single self-contained executable binary (Although the VC linker team has a new feature that changes that).  csc.exe simply requires you to pass the netmodules with a switch: “/addmodule:<filename>“ to create a multi-file assembly just like al.exe
  • al.exe has all those cool switches that csc.exe doesn't, there must be something different.  Well I guess there is, al.exe allows the switches and custom attributes compiled into source, but csc.exe only allows custom attributes compiled in source.  The same functionality is there, just different ways to get at it.  One small feature only in al.exe is that al.exe will allow a command-line argument to override potentially conflicting custom attributes.  So if two modules have different assembly versions, you can pick the one you want (or specify an entirely different version) using the al.exe /version switch.
  • What about “/main“?  Well al.exe simply generates a small method that call the real Main method given as the argument.  You could do the exact same thing using csc.exe by generating a short source file that looks something like this:

    class __EntryPoint {    static int Main(string [] args) {        return TheRealClass.TheRealMain(args);    }}

  • What about “/evidence“?  That's exactly the same as doing “/embed:<filename>,Security.Evidence,Private“.  csc.exe doesn't support the private (see above), but that, again, doesn't really matter.

Well in writing this, I think I've convinced myself, there are still a few worth wile difference, but not many.

--Grant