<< Back to previous view

[CLJCLR-25] Clojure.Compile.exe create single dll for all compiled .clj files Created: 02/Aug/13  Updated: 14/Sep/13

Status: Reopened
Project: ClojureCLR
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Major
Reporter: Devin Garner Assignee: David Miller
Resolution: Unresolved Votes: 1
Labels: None

Attachments: Text File 0001-PATCH-Add-NDesk.Options-ManyConsole-via-NuGet-to-all.patch    
Patch: Code

 Description   

I've created a patch for ClojureCLR that allows the Clojure.Compile.exe to build a single .dll or .exe when given a list of .clj files. This is basically the same concept as the ILMerge, but it gives the benefit to the programmer with a project containing many .clj files, rather than only to clojure.dll itself.

The merged/separate option can be specified at the commandline, so users can choose the previous method if they prefer.

I didn't remove ILMerge from the ClojureCLR build process, but it should theoretically be easy to do if desired.

ILMerge is working, but its license doesn't allow redistribution & would require each programmer to learn to use the tool (unless its built into nLeiningen & vsClojure). It seems better if Clojure.Compile.exe doesn't make tons of dlls in the first place.

The basic usage is:

Clojure.Compile.exe -include test.clj -include test2.clj -outputAssemblyName test.dll
-or-
Clojure.Compile.exe -i test.clj -i test2.clj -o test.dll

If you leave off the -o parameter, it functions the same as previously.



 Comments   
Comment by David Miller [ 14/Sep/13 2:37 PM ]

Simplified CLI to
Clojure.Compile.exe [-o outputAssemblyName] cljFileName...

Comment by David Miller [ 14/Sep/13 3:14 PM ]

I thought I had run the test suite one last time before committing – apparently not. The fix committed as 7745dec blows three tests. One test shows the :arglists metadata on functions has the wrong type. Two other tests error out function-serialization.

In addition, :file metadata went from relative paths to absolute paths, so the metadata in distributed ClojureCLR will show the file paths on my development machine.

I'm going to roll this change back until these are fixed.





[CLJCLR-33] REPL input broken Created: 03/Aug/14  Updated: 04/Aug/14

Status: Open
Project: ClojureCLR
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Shlomo Shuck Assignee: David Miller
Resolution: Unresolved Votes: 0
Labels: None
Environment:

ClojureCLR 1.5.0 Release, Ubuntu 14.04, Mono 3.2.8


Attachments: File getline.cs    

 Description   

REPL doesn't handle backspace character correctly, even backing up over the "user=>" prompt, yet apparently not being captured at all during evaluation. Also, this is what happens when I type "clojure " <---space, instead of "*clojure" <----dash, while trying to evaluate "*clojure-version":

$ mono Clojure.Main.exe
Clojure 1.5.0
user=> *clojure CompilerException System.InvalidOperationException: Unable to resolve symbol: *clojure in this context
at clojure.lang.Compiler.ResolveIn (clojure.lang.Namespace n, clojure.lang.Symbol symbol, Boolean allowPrivate) [0x00000] in <filename unknown>:0
at clojure.lang.Compiler.Resolve (clojure.lang.Symbol symbol) [0x00000] in <filename unknown>:0
at clojure.lang.Compiler.AnalyzeSymbol (clojure.lang.Symbol symbol) [0x00000] in <filename unknown>:0
at clojure.lang.Compiler.Analyze (clojure.lang.CljCompiler.Ast.ParserContext pcontext, System.Object form, System.String name) [0x00000] in <filename unknown>:0 , compiling: (NO_SOURCE_PATH:0:0)

...and further input is ignored, requiring ^C to exit.



 Comments   
Comment by Shlomo Shuck [ 03/Aug/14 1:16 PM ]

Markup mangled my bug report obviously, whoops. I meant that I hit space after asterisk clojure instead of a dash.

Comment by David Miller [ 03/Aug/14 2:51 PM ]

This has been a problem on Mono from the beginning.
I've asked several people about it, but I don't have a solution.
I'll put a query up on the mailing list and see if anyone has a suggestion.

Comment by Shlomo Shuck [ 04/Aug/14 11:38 PM ]

For what it's worth, a C# REPL comes bundled with Mono which works well. The REPL code is a 900-line program which uses a 1000-line getline library. The latter has no dependencies outside of the System namespace, which is good, but I have no clue as to how it'd work with MS .NET. Anyway, I've attached it for your consideration (path in Ubuntu "mono" package source is mcs/tools/csharp/getline.cs).





[CLJCLR-32] RT.load does not correctly map namespace to source file or dll name Created: 30/Jun/14  Updated: 22/Aug/14

Status: Open
Project: ClojureCLR
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Antti Karanta Assignee: David Miller
Resolution: Unresolved Votes: 0
Labels: None


 Description   

When doing (from C#)

RT.load( "my.util", true );

and having directory containing my\util.clj on CLOJURE_LOAD_PATH I get

System.IO.FileNotFoundException: Could not locate my.util.clj.dll or my.util.clj on load path.

I believe the latter is wrong - it should be looking for my\util.clj on load path?

Also, there is a problem with compiled assemblies whose namespace contains -'s. For example, if I have compiled namespace myns.foo-bar (in file myns\foo_bar.clj) it produces myns.foo_bar.clj.dll. If I try to load it like so:

RT.load( "myns.foo-bar", true );
System.IO.FileNotFoundException: Could not locate myns.foo-bar.clj.dll or myns.foo-bar.clj on load path.

I think RT.load should "know" that compiling a namespace with - character in it is mapped to _ on the corresponding dll or source file name.



 Comments   
Comment by David Miller [ 16/Aug/14 2:35 PM ]

One should not be calling RT.load directly. Most functions in the RT namespace are not for C# code doing Clojure interop.

In the case of RT.load specifically, internally it is called only once, during system init, to load clojure/core.

Instead of direct calls, use the new interop capability to call from C# to Clojure functions.
The Clojure.var method is actually clojure.clr.api.Clojure.var

IFn load= Clojure.var("clojure.core", "+");
load.invoke("my.util");

See if this works for you.

Comment by Antti Karanta [ 21/Aug/14 1:49 AM ]

Ah, ok, I thought RT's methods were public API, I think I picked this usage up from an example somewhere and it seemed to work. And mostly does.

I'm currently using Clojure-CLR 1.5.0 and class clojure.clr.api.Clojure does not seem to exist. I take it is new in 1.6.0? What is the recommended way to load a namespace / var in 1.5.0?

Comment by David Miller [ 21/Aug/14 10:46 AM ]

That class is indeed new in 1.6.0. In 1.50, you can do exactly what clojure.clr.api does:

private static Symbol asSym(object o)

{ String str = o as String; Symbol s = str != null ? Symbol.intern(str) : (Symbol)o; return s; }

public static IFn var(object qualifiedName)

{ Symbol s = asSym(qualifiedName); return var(s.Namespace, s.Name); }

public static IFn var(object ns, object name)

{ return Var.intern(asSym(ns), asSym(name)); }

If you have two strings, one for namespace, one for name, this simplifies to

Var x = clojure.lang.Var.intern(ns,name);

Comment by Antti Karanta [ 22/Aug/14 6:07 AM ]

For some reason clojure.core/load does not seem to be able to find the given namespace (i.e. the corresponding .dll) whereas RT.load does find it.

Do I need to perform some extra dance steps to tell clojure.core/load where to look for the dlls? Preferably no environment variables like CLOJURE_LOAD_PATH involved. In practice they will be in the same directory as other dlls in my app (and I can easily programmatically find that out where that is if need be). Unfortunately it is neither the current dir nor the dir of the executing assembly.

BTW, automatically adding the location of Clojure.dll to the load path would likely solve at least my issue with clojure.core/load and I would guess it to be generally useful, too.





[CLJCLR-37] spit does not truncate, leaves tail of original file if output is shorter length. Created: 29/Sep/14  Updated: 29/Sep/14

Status: Open
Project: ClojureCLR
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: David Miller Assignee: David Miller
Resolution: Unresolved Votes: 0
Labels: None


 Description   

For example:

(spit "c:/tmp/spit.txt" "012345")
(spit "c:/tmp/spit.txt" "BB")

Results in a file containing: BB345.

Reported via email by cees van Kemenade.






[CLJCLR-38] Use Type.AssemblyQualifiedName in ObjExpr.EmitValue when generating code for types Created: 01/Oct/14  Updated: 01/Oct/14

Status: Open
Project: ClojureCLR
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: David Miller Assignee: David Miller
Resolution: Unresolved Votes: 0
Labels: None


 Description   

ilg.EmitString(((Type)value).AssemblyQualifiedName); // <- instead of FullName
ilg.EmitCall(Compiler.Method_RT_classForName);

Using AssemblyQualifiedName instead of FullName should make the RT.classForName call succeed more quickly.






[CLJCLR-49] ArraySeq.createFromObject broken on arrays of value types Created: 14/Nov/14  Updated: 14/Nov/14

Status: Open
Project: ClojureCLR
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Ramsey Nasser Assignee: David Miller
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Arcadia


Attachments: File CLJCLR-49.diff    

 Description   

Calling seq on CLR arrays eventually comes to ArraySeq.createFromObject, which handles arrays of primitive and reference types correctly, but throws an exception when called with an array of value types. Value types have a TypeCode of Object, just like reference types, so they both fall into the branch on line 91 of ArraySeq, which attempts an object[] prefix cast. Casting an array of value types to an array of reference types is not allowed, so this will throw an exception.

Original Arcadia issue: https://github.com/arcadia-unity/Arcadia/issues/75. The example case makes use of Unity types, but the same should hold for any CLR environment.



 Comments   
Comment by Ramsey Nasser [ 14/Nov/14 1:19 PM ]

The provided patch fixes the problem by leveraging CLR generics and the already present TypedArraySeq class for value types. The following changes were needed

1. TypedArraySeq was made public and non-abstract, and given generic implementations for its previously abstract methods
2. The default case in ArraySeq.createFromObject was replaced by a runtime reflective instantiation of the correct generic version of TypedArraySeq for the input type

Comment by Ramsey Nasser [ 14/Nov/14 2:41 PM ]

The only odd part of the patch is the ConvertNum implementation, which right now just casts to the generic type, mirroring what ArraySeq_object does. Not sure what else to do there, but I have other questions about ConvertNum.

TypedArraySeq could conceivably replace all the hard coded ArraySeq_* subclasses. This would result in much smaller (~65% smaller), simpler code. They seem to all do the exact same thing, except in the ConvertNum method, which brings up a few questions. Why is ConvertNum there, and why is it so concerned with numbers? It is only used in the IList.IndexOf implementation, where input is run through a Util.IsNumeric check before converting to a number via ConvertNum, and only then looking up the index. This means that IndexOf will always return -1 for anything that is not numeric. Is there a reason for this behavior, or is it a bug? As usual I'm not aware of the farther reaching implications of these implementation details.

If it is a bug, then I propose we replace ConvertNum with ConvertToType or just Convert that converts a value to the generic type of the TypedArraySeq and remove the Util.IsNumeric check from IndexOf. I can provide this patch.





[CLJCLR-48] Error when starting Clojure.Main.exe Created: 26/Oct/14  Updated: 19/Nov/14

Status: Open
Project: ClojureCLR
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Kerry Todyruik Assignee: David Miller
Resolution: Unresolved Votes: 0
Labels: None
Environment:

OS X, Running Mono



 Description   

I received the following error when trying to start ClojureCLR through Mono.

Release 4.0 general$ mono Clojure.Main.exe

Unhandled Exception:
System.TypeInitializationException: An exception was thrown by the type initializer for Clojure.CljMain ---> System.TypeInitializationException: An exception was thrown by the type initializer for clojure.lang.RT ---> System.IO.FileNotFoundException: Could not locate clojure.core.clj.dll or clojure/core.clj on load path.
at clojure.lang.RT.load (System.String relativePath, Boolean failIfNotFound) [0x00000] in <filename unknown>:0
at clojure.lang.RT.load (System.String relativePath) [0x00000] in <filename unknown>:0
at clojure.lang.RT.DoInit () [0x00000] in <filename unknown>:0
at clojure.lang.RT..cctor () [0x00000] in <filename unknown>:0
— End of inner exception stack trace —
at Clojure.CljMain..cctor () [0x00000] in <filename unknown>:0
— End of inner exception stack trace —
[ERROR] FATAL UNHANDLED EXCEPTION: System.TypeInitializationException: An exception was thrown by the type initializer for Clojure.CljMain ---> System.TypeInitializationException: An exception was thrown by the type initializer for clojure.lang.RT ---> System.IO.FileNotFoundException: Could not locate clojure.core.clj.dll or clojure/core.clj on load path.
at clojure.lang.RT.load (System.String relativePath, Boolean failIfNotFound) [0x00000] in <filename unknown>:0
at clojure.lang.RT.load (System.String relativePath) [0x00000] in <filename unknown>:0
at clojure.lang.RT.DoInit () [0x00000] in <filename unknown>:0
at clojure.lang.RT..cctor () [0x00000] in <filename unknown>:0
— End of inner exception stack trace —
at Clojure.CljMain..cctor () [0x00000] in <filename unknown>:0
— End of inner exception stack trace —



 Comments   
Comment by Dan Jacka [ 19/Nov/14 2:46 AM ]

I hit the same error on Mono on Ubuntu. In my case creating softlinks to Clojure.dll named clojure.core.clj.dll, etc. (full list here) worked - afterwards I was able to fire up a REPL. Hope this helps.

Comment by David Miller [ 19/Nov/14 3:13 PM ]

Good for short-term workaround.
We need to figure out why assembly resolution differs on Mono. The ILMerge'd Clojure.dll contains the embedded dlls, as you've figured out. Why they aren't picked up directly, I don't know.
Need some debugging time under Mono.





[CLJCLR-44] Expose RT.GetFindFilePaths Created: 06/Oct/14  Updated: 06/Oct/14

Status: Open
Project: ClojureCLR
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Greg Chapman Assignee: David Miller
Resolution: Unresolved Votes: 0
Labels: None


 Description   

I believe it would be occasionally useful to have the information returned by RT.GetFindFilePaths when exploring/debugging at the repl. It seems like making the method public ought not to cause any problems.






Generated at Sun Nov 23 11:28:56 CST 2014 using JIRA 4.4#649-r158309.