Using Ocamlbuild plugins with Oasis - ocaml

What is the proper way to integrate Ocamlbuild plugins like Ocamlbuild-protoc into a project managed by Oasis? I know how to manually edit myocamlbuild.ml to invoke the plugin, but that's not enough, because the proper tags have not been set. According to this particular plugin docs, it needs to be invoked with the following command, but I don't know how to do it in Oasis:
ocamlbuild -use-ocamlfind -plugin-tag "package(ocamlbuild_protoc)" target.native
Or is there maybe builtin support for Ocamlbuild plugins in Oasis that I missed?

Add to your _oasis file (outside any section) the line AlphaFeatures: ocamlbuild_more_args and XOCamlbuildExtraArgs: "-plugin-tag 'package(ocamlbuild_protoc)'".

Related

Documentation generation for BuckleScript project

Is there any way to generate code documentation for BuckleScript or Reason? I've tried using ocamldoc, but I don't know how to include node package dependencies automatically.
There isn't an automatic resolution yet for node packages. You can manually specify each dependent package in the ocamldoc command, e.g.:
ocamldoc -html -d doc -I node_modules/bs-webapi/lib/ocaml -I node_modules/bs-fetch/lib/ocaml -I node_modules/bs-platform/lib/ocaml src/YourModule.re
The directory includes are fairly predictable, you just have to point at the lib/ocaml directories in each package, ocamldoc will find their compiled .cmi files and pull in the required type information from there.
This also means that you'll first need to have done bsb -make-world, to compile all those .cmis.
There’s a tool which, supposedly, automatically performs a lot of the orchestration of ocamldoc described by #Yawar, called BsDoc.
Note that I have not used this myself; but it it supposed to be the go-to for a lot of BuckleScript-specific projects (i.e. using bsb with npm-installed dependencies, not dune with opam-installed dependencies.)

Using ocamlmktop with ocamlbuild

I have a project that builds successfully using ocamlbuild. However, I would also like an easy way to interact with the project's individual functions from different modules via the toplevel but my attempts at using ocamlmktop haven't worked out as I'd like. I've found that unless I manually put the .cmi files in the active directory, I get an "Unbound module" error. The command I'm currently using to build is:
ocamlfind ocamlmktop -I _build -o my_ocaml -linkpkg -package str module1.cmo module2.cmo
Is there a better, less hacky way to get the toplevel to work in this project structure without moving cmi files out of the _build directory?
Edit: I've figured out that I can get it to load the types and modules if I run the toplevel as
./my_ocaml -I _build
But this still seems hacky. Is there a way to bake the search path or cmi files in perhaps?
Edit 2: I think the solution to my problem may actually be not to compile a custom toplevel at all given this restriction about interface files. I have instead added load directives to my .ocamlinit to use the modules. If anybody has better ideas to solve this, I'd greatly appreciate it.
You can build a toplevel by listing the module names you want in a my_ocaml.mltop file:
Module1
Module2
subdir/Module3
Then building the target my_ocaml.top will call ocamlmktop in the expected way, and you can run the resulting my_ocaml.top toplevel.
This does not change the way that you need to add _build to the include path for the type-checker to be able to find the .cmi files. You can do this when you invoke the toplevel by passing the command-line arguments -I _build, or from the toplevel with #dir "_build";; -- the last command can also be put in your .ocamlinit if you prefer.

How to find the interface i.e. the set of provided function of an OCaml package?

I need to use parse an OCaml source file into a typed AST and I believe ppx_jane is the right package to do the work. After installing it using opam, I still don't know what functions are available.
This is a link to the ppx_jane package on opam. It tells no more than the basic info and dependencies.
Though I could search on Github to see how other programmers call functions provided by this package, I still cannot get an exhaustive list of all available functions.
A bit late but for your original problem, (OCaml source file -> typed AST ) doesn't ocamlc -dtypedtree a.ml do the job?
About knowing the set of function provided by an OCaml module there are several options. Here's few of them:
looking at the doc online
in your favorite toplevel :
#require "package_name";;
#show Module_name;;
ocamlc -i module.ml

How to configure _oasis for OCaml to set 'Profile' flag

I have an existing project in OCaml and one _oasis file. I don't know where to enable the profiling flag for ocamlbuild.
I looked up Oasis manual and the code, and found there was a variable profile available in setup.data. I assume this was what Oasis auto generated.
Where and what should I include in _oasis to set profile to true ?
You can activate the ocamlbuild_more_args feature.
On top of your _oasis file:
AlphaFeatures: ocamlbuild_more_args
Then, in your Package:
XOCamlbuildExtraArgs: your_ocamlbuild_option
I can't find any -profile option in ocamlbuild though, so I'm not sure of what this is about. Also, this option is still quite unstable.
A better way to handle that would be to modify your _tags file accordingly. It is generated by oasis but you can modify it.
EDIT:
setup.data informs you of environment variables. As for profile, it shows if the -p option will be passed to ocamlopt. You can pass it using the NativeOpt field.
You can enable the oasis profile flag by adding the --enable-profile argument to the ./configure flag. But so far, I have only noticed any effect when I enabled native code compilation (CompiledObject: native in _oasis). Even then, the profiling generation is only done for gprof.
I suggest you to use _tags file as it is the easiest way. Just add the following to your _tags:
<true> : profile
You run this command:
echo "<true> : profile" >> _tags
in the folder where your _tags file is located.
If you still want to use _oasis file, then you can use NativeOpt field, to add options that will be passed to native compiler, i.e., ocamlopt.

Ocamlbuild override the default options

My installation of OCaml does not recognize #!, therefore camlp4o cannot be ran standalone. It must be invoked as "ocamlrun camlp4o".
I try to add a flag in the plugin. But the new flag is simply added to the existing flag.
The result is that ocamlbuild will invoke the compiler with
"-pp camlp4o ocamlrun camlp4o".
A working workaround is to introduce a new tag 'my_camlp4o'. However, the documentation of ocamlbuild did mention the capability of 'overriding' defaults. It seems ocamlc, ocamlopt can be overridden. But can we override camlp4o? Can it be done in plugins?
There is support for changing defaults in Ocamlbuild, through the -ocamlc <command>, -ocamldep <command> etc. command-line options. Unfortunately, camlp4 is currently not part of the set of customizable commands. Could you please use the issue tracker to request this feature?
(In the meantime I recommend a workaround, eg. you replace the ocamlrun executable in your PATH by an executable script that does the right thing.)
Edit
Another workaround is to do all your compilation through ocamlfind, which has support for overriding the camlp4 command (see the documentation), and can be used as a basis for all ocamlbuild command with the -use-ocamlfind option. Unfortunately, ocamlfind itself only supports preprocessing at compile-time (when invoking the actual compiler), not stand-alone source-to-source processing, so that may not cover your own use case.