6

I am working on a project where we're porting the Racket Language to .NET using DLR.

We build up an expression tree and invoke the CompileToMethod() Method:

Relevant executable emission code: (taken from How to Save an Expression Tree as the Main Entry Point to a New Executable Disk File?)

//Wrap the program into a block expression
Expression code = Expression.Block(new ParameterExpression[] { env, voidSingleton}, program);

var asmName = new AssemblyName("Foo");
var asmBuilder = AssemblyBuilder.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave);
var moduleBuilder = asmBuilder.DefineDynamicModule("Foo", "Foo.exe");
var typeBuilder = moduleBuilder.DefineType("Program", TypeAttributes.Public);

var methodBuilder = typeBuilder.DefineMethod("Main",
            MethodAttributes.Static, typeof(void), new[] { typeof(string) });

Expression.Lambda<Action>(code).CompileToMethod(methodBuilder);

typeBuilder.CreateType();
asmBuilder.SetEntryPoint(methodBuilder);
asmBuilder.Save("Foo.exe");

we have our runtime library Runtime_rkt.dll which contains relevant runtime type conversions, backing objects, etc.

When we place Foo.exe and Runtime_rkt.dll in the same directory everything works fine. The issue we're having is when we (obviously) move the runtime library to else where. Ultimately we will want to install it in C:\Windows\Microsoft.NET\assembly\GAC_MSIL like IronPython does. [Solved using GAC]

[edit] New Question for Extra pts Is there any way we can statically compile all the runtime methods into the executable?

Community
  • 1
  • 1
Scotty Bauer
  • 1,277
  • 9
  • 14
  • 1
    I think that if you [add it to the GAC properly](http://msdn.microsoft.com/en-us/library/dkkx7f79) (not just copy it to the directory), it should work. – svick Mar 19 '14 at 02:27
  • 2
    Good luck. But Expression generally generates rather crap code :( If I had to do IronScheme again, I would use the CCI instead of the DLR. – leppie Mar 27 '14 at 19:30
  • @leppie That's not what I wanted to hear :(. It's a little late for us to switch to CCI as well, but thanks for that info, if we ever decide to re-do this. – Scotty Bauer Mar 27 '14 at 20:50
  • 1
    https://www.youtube.com/watch?v=R6_eWWfNB54 – Hans Passant Mar 27 '14 at 21:50
  • 1
    @ScottyBauer: If you have good enough abstraction layers, it should be easy to swap. Unfortunately, I coupled my code too tightly with the DLR. Eventually, I just branched off the DLR and started modding to my liking and remove all the dynamic Python stuff. You may want to see if IronScheme would be a helpful platform to do this. I have been thru most of these problems already, and might even be interested in working on a Racket compat layer (they are not really that far off each other, IronScheme even has typed scheme based on Racket's ;p). That said, Racket is a huge beast! – leppie Mar 28 '14 at 05:20
  • 1
    @ScottyBauer: Just to add, you biggest problems with static compilation of expanded libraries is not the code, but dealing with environments and compilable exported macros. Environments in my case, I just serialize, and having that, allows me to have compilable macros :) Also, the compiled libraries (in Assembly form) tend to be ugly as hell due to hygiene, and are generally not usable (via a reference) directly from other .NET code due to initialization needing to be done (for Scheme). That is one problem I am still trying to solve gracefully. – leppie Mar 28 '14 at 05:27
  • Also, I recommend never adding things to the GAC unless you really hate your users :( GAC = evil. – justin.m.chase May 28 '14 at 15:44

1 Answers1

0
  1. After you put the run-time library to the GAC everything should work, shouldn't it? Why don't you do it right now?
  2. Try explaining yourself how the built executable is going to locate the run-time library meanwhile
  3. Look into ILMerge
  4. Look into new native compilation of .net assemblies MS is rolling out this year. It is advertised to not only compile to native code, but also include all libraries and CLR itself into the exe file.
  5. You can always subscribe to AppDomain.AssemblyResolve event. Obviously you'd have to compile that subscription into your generated exe file.
  6. You can configure folders where CLR looks for DLLs in config file.