boo-lang / boo

The Boo Programming Language.
BSD 3-Clause "New" or "Revised" License
874 stars 148 forks source link

Boo Compiling issues #210

Closed physics-sec closed 4 years ago

physics-sec commented 4 years ago

Hi! I'm having some issues compiling Boo source code to a .exe with the booc.exe compiler.

This is my program:

import System

def numberOfCPUCores() as int:
    coreCount = 0
    using searcher = System.Management.ManagementObjectSearcher("Select * from Win32_Processor"):
        using items = searcher.Get():
            for item as duck in items:
                coreCount += int.Parse(item["NumberOfCores"].ToString())
    return coreCount

def Main(argv as (string)):
    print "Hi!"
    cpu = numberOfCPUCores()
    print "result: $cpu"
    return

As you can see, it prints the amount of CPU cores.
I compiled it with this command:

.\booc.exe -ducky -platform:x64 -target:exe -nologo -r:System,System.Core,System.Web.Extensions,System.Management,Boo.Lang.Compiler.dll,Boo.Lang.dll,Boo.Lang.Extensions.dll,Boo.Lang.Parser.dll .\program.boo

If I run program.exe in boo/bin/ (where all the DLLs are) it works perfectly:

Hi!
result: 2

If I run it in my destktop (or some other folder without the boo's DLLs) I get this:

Hi!

Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'Boo.Lang, Version=2.0.9.5, Culture=neutral, PublicKeyToken=32c39770e9a21a67' or one of its dependencies. The system cannot find the file specified.
   at ProgramModule.numberOfCPUCores()
   at ProgramModule.Main(String[] argv)

While compiling, I'm referencing the Boo.Lang.dll assembly, shoudn't this make the binary executable on any Windows system?

If I print the assemblies with:

    for asm in AppDomain.CurrentDomain.GetAssemblies():
        print asm.ToString()

I get:

mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
program, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null

So, it seems that the Boo's DLLs are not being referenced?
What am I doing wrong?

Thank you in advance!

masonwheeler commented 4 years ago

The part you're missing is that dependency assembly loading happens lazily in the CLR, rather than eagerly. You're using the duck type in the numberOfCPUCores method. This is implemented via an interface defined in Boo.Lang.dll, so the CLR tries to load the assembly when it enters that method, rather than at the start of the program.

If you loop over every assembly loaded in the current AppDomain before you've run that method, it won't show Boo.Lang because it hasn't been loaded yet. If you were to run that code after numberOfCPUCores, you would see it in the list.

physics-sec commented 4 years ago

Thank you for the fast response!

Your are right, it does appear after I called the numberOfCPUCores method.

Although I still have the issue that when I run program.exe on a folder without the DLLs, it fails (because it can't find the Boo.Lang assembly). Any ideas how can I fix this?

masonwheeler commented 4 years ago

You fix it by putting Boo.Lang.dll in the same folder as program.exe when you deploy it. Or by not using any types or features that need that assembly, such as duck. Or if you want to really get fancy, you can use a tool like ILMerge to merge the DLL into the EXE. But the simplest solution is to just make sure your dependencies are where they're supposed to be: alongside the EXE..

physics-sec commented 4 years ago

Great! thank you very much 😄