Failing to link standard library in OCaml-Java - ocaml

I need to convert a simple OCaml file into JAR file so that I can run atop JVM platform.
This OCaml file needs to use the Big_int module. There is this line of code
open Big_int
But it always returns me this line of error Error: Reference to undefined globalBig_int'` when I try to run ocamljava to convert it into jar file.
ocamljava -o myprog.jar source.ml
I am able to see big_int.cmi, big_int.cmj, big_int.cmx, big_int.mli, nums.cma, nums.cmja, etc on this directory /Users/myname/.opam/ocamljava-2.0-alpha2/lib/ocaml. I know that the Big_int is residing inside these libraries; but I don't know how to link them into compilation.
By the way, I'm using OCamlJava 2.0.

Erencie,
Entering open Big_int only accesses the compiled interface (.cmi file) for big_int, but does not load the implementation of big_int.
Implementations for user modules can be entered with the #load directive.
In your case, you want to do the following:
#load "file-name";;
This is going to load in memory a bytecode object file (.cmo file) or library file (.cma file) produced by the batch compiler ocamlc.
Thus you should do the following:
#load "big_int.cmo";;
If the object file for big_int does not exist yet, you should compile big_int.ml first.
Please let me know if you have any questions!

You should probably add the "nums" library to the command-line, as in:
ocamljava nums.cmja source.ml
Also note that the implementation of "nums" in OCaml-Java has been only
lightly tested, and may contain bugs. If you encounter a bug, it would
be nice to report it at https://github.com/xclerc/ocamljava.

Related

How to compile and execute a stand-alone SML-NJ executable

I have seen one other answer link but what I don't understand is what is basis.cm and what's it's use?
You are asking two questions.
What is basis.cm and what's it's use?
This is the Basis library. It allows the use of built-in functions.
How to compile and execute a stand-alone SML-NJ executable
Assuming you followed Jesper Reenberg's tutorial on how to execute a heap image, the next thing you need in order to have SML/NJ produce a stand-alone executable is to convert this heap image. One should hypothetically be able to do this using heap2exec, a tool that takes the heap image, e.g. the .x86-linux file generated on my system, and generates an .asm file that can be assembled and linked.
Unfortunately, this tool is not very well-maintained, so you have to
Go to the smlnj.org page and fix the download-link by removing 'www.' (this page and the SourceForge page don't contain the same explanations or assumptions about argument count, and neither page's download link work).
Download and extract this tool, and fix the 'build' script so it points to your ml-build tool
Fix the tool's argument use by changing [inf, outf] to [_, inf, outf]
Run ./build which generates 'heap2asm.x86-linux' on my system
For example, in order to generate an .asm file for the heap2asm program itself, run
sml #SMLload heap2asm.x86-linux heap2asm.x86-linux heap2asm.s
At this point, I have unfortunately been unable to produce an executable that works. E.g. if you run gcc -c heap2asm.s and ld heap2asm.o, you get a warning of a missing _start label. The resulting executable segfaults even if you rename the existing _sml_heap_image label to _start. That is, it seems that a piece of entry code that the runtime environment normally delivers is missing here.
At this point, discard SML/NJ and use MLton for producing stand-alone binaries.

load|use|require a library object file within an Ocaml source file

The Ocaml manual contains an exercise (here) in which library object files are loaded in the toplevel loop (the ocaml interactive interpreter) in the following way:
#load "dynlink.cma";;
#load "camlp4o.cma";;
I'm trying to replicate the subsequent code in a compilable source file, and the code requires the above library object files. Can I load these files with a line of code within the source file and compile it with ocamlc? I've tried "#load", "load", "#use", "use", "#require", "require", and all these proceded by "#directory" and "directory". I know that you can include modules with "include ;;", but this shouldn't work either, because they're just library files, not modules. I've tried to find a way to do this in the manual, but to no avail.
Do I need to reference the files in the compilation command? If so, how do I do this?
Directives starting with a # character are used only in the toplevel and are not strictly part of the OCaml language. In a file that you want to compile, you don't use # directives. See the OCaml manual Chapter 9. The #load directives are for loading a library. When compiling a file, you have to tell the compiler to use the library (on the command line, not in the file). It's good to learn the compiler commands directly at first, but eventually you should use ocamlfind and oasis, which make compilation much easier.
I'm assuming your source is written using extensions implemented by camlp4o. To compile your source, you can say:
ocamlc -pp camlp4o -o myfile myfile.ml
I believe the complexities of the #load command are required only when you want to use the extensions in the toplevel (the interpreter).

why I am getting "invalid command name "MZ"" on loading a dll on wish console?

I have a library and I have generated tcl bindings for the same using swig. The dll thus generated is xyz_tcl.dll if my original lib dll us xyz.dll. but when I try to load the dll its says "invalid command name "MZ"". Can any one tell me what could be reason for it.
The MZ is almost certainly the first few bytes of the DLL (it's the “magic number” of the file format) so at a guess you're trying to do:
source xyz_tcl.dll
That won't work. It contains compiled C code that integrates with Tcl, but not a Tcl script. Instead, you need to do:
load xyz_tcl.dll
Of course, it should be build into a package (which is a directory containing the required DLLs and a file pkgIndex.tcl) which would then let you do something like this instead:
package require xyz
(The pkgIndex.tcl file contains instructions on how to define the package using the other files, through load and source as necessary.)
I think that something (tcl?) is trying to execute the DLL as a script - the first two bytes of a Windows executable file are 'M' and 'Z'.
For historical reasons, every Win32 executable has a small 16-bit MS-DOS header just before the actual Win32 PE header, and the signature bytes for the 16-bit header are "MZ".

examine library (.cma) signature from console

Say I have an OCaml library file foo.cma. Is there a command line tool to print the signature of the functions and other types defined there ? The ocamlbrowser utility seems to be windows-based (complains about the $DISPLAY environment variable). The use case is that I am doing a:
ocamlc -c foo.cma main.ml
and get:
File "main.ml", line 13, characters 33-47:
Error: Unbound value ListUtil.split
ListUtil.split ought to reside in foo.cma but I don't know a console-based tool to verify it.
On Debian/Ubuntu, you have "ocamlobjinfo":
ocamlobjinfo stdlib.cma
will display all the unit names included in stdlib.cma. Then, you can create a short file:
include SomeModule
and compile it with -i to see what is defined in module SomeModule.
In the toplevel, I just load the cma file:
#load "foo.cma";;
Then I re-defined a module just to see the signature:
module Chunk = Foo;;
In order to compile the code referencing ListUtil.split the compiler needs to find the corresponding listUtil.cmi file. In order to link that code compiler will need the cma (or cmo) file containing the implementation. See http://mirror.ocamlcore.org/caml.inria.fr/pub/ml-archives/caml-list/2008/09/2bc9b38171177af5dc0d832a365d290d.en.html for some explanation.

How can I load an external file/program in memory and then execute it (C++ and Unix)?

Let's say I have an executable file called "execfile". I want to read that file using a C++ program (on Unix) and then execute it from memory. I know this is possible on Windows but I was not able to find a solution for Unix.
In pseudo-code it would be something like this:
declare buffer (char *)
readfile "execfile" in buffer
execute buffer
Just to make it clear: obviously I could just execute the file using system("execfile"), but, as I said, this is not what I intend to do.
Thank you.
EDIT 1: To make it even more clear (and the reason why I can't use dlopen): the reason I need this functionality is because the executable files are going to be generated dynamically and so I cannot just build all of them at once in a single library. To be more precise I'm building a tool that will first encrypt an executable file with a key and then it will be able to execute that encrypted file, first decrypting it and then executing it (and I don't want to have a copy of the decrypted file on the file system).
You cannot without writing a mountain of code. Loading and linking an a.out is a kernel facility, not a user mode facility, on linux.
You'd be better off making a shared library and loading it with dlopen.
The solution to load-and-run -- not necessarily in C++ -- is to use dlopen+dlsym to load dynamic library and obtain a pointer to function defined in the library.
See C++ dlopen mini HOWTO for description of solving problems with C++ symbols in dynamic libraries.