rescript-compiler
rescript-compiler copied to clipboard
Make BuckleScript a drop in replacement for `ocamlc`.
I'm aware that bsc
can be used for the most part exactly like ocamlc
, but I am not clear if there are some differences. Could you please enumerate how bsc
is not quite a drop in replacement for ocamlc
, and what needs to be done to make it a drop in replacement?
Suppose we have our custom jenga rules that builds using ocamlc
and produces libraries using -a
for example. It would be awesome if you could simply change all of the references to ocamlc
with bsc
. What will it take to do this, and should it be a goal? It would tremendously help with the goal of being able to compile a library to either JavaScript or native.
Apologies if this is covered somewhere, but I did check the docs.
note bsc
will be more like ocamlopt
, cmj
is like cmx
. (OCaml bytecode compiler get real separate compilation, only interface needed, not any cross module optimization)
The missing part as you said, is the -a
flag which does not make sense currently in Buckle(we have plan to add it, but needs more time for design #288), but since you are going to implement a build system in jengaboot, it should be not too hard to ignore such rule, no?
The other part is -bs-package-name $npm_package_name
and -bs-package-output path/to/store/js/files
.
Note that you can customize cmi
, cmj
output for support namespace like ocamlopt. The JS files are fixed (relative path to package.json
) is due to JS files are really not relocatable, you can not install JS files after build (this only works for google module system but not commonjs).
Bob, about relocating output files. With npm
, it is very common to do npm link
which creates symlinks so MyPackage
might be compiled by many other things that depend on MyPackage
, each of them having different compilation rules. Therefore it is important that our build system be able to support outputing the build artifacts to another directory somewhere (where we might mirror the node modules directory if needed).
Also, it seems that the most compelling feature is being able to take any of the OCaml libraries and trivially turn them into bs libraries. If bs supported the exact compiler interface as ocamlopt
, then it would be very easy to convert any existing library by simply changing one or two things in the Makefile
.
It is fine to do npm link
, since, for JS files, the recorded path is relative to package.json
.
It also supports outputting the build artifact to different directory (for cm* files, it behaves exactly like ocamlopt, for js files, user can specify the output path by -bs-package-output
)
To make it work with Makefile
, probably user need do two things:
#.
OCAMLOPT=bsc -bs-package-name $npm_package_name -bs-package-output lib/js
#. replace cmx
with cmj
We can provide a dummy option support for -a
if that helps, what do you think
myProject/
├── node_modules/
│ └── myDependency/
│ ├── package.json
│ └── myDependencySource.re
├── package.json
├── _build/
└── mySourceFile.re
That is a typical npm setup. We need to build everything into _build
. Even the source files for node_modules/myDependency
. There are many good reasons:
- You can delete
_build
and it removes all build artifacts for all packages. -
myDependency
might be symlinked to another installation location, and we can't dump artifacts in there because it might be symlinked by many dependers, and they would all be stepping on eachother's artifacts.
If BuckleScript's CLI API matched ocamlc
then the -o
flag would be sufficient to output compilation artifacts for dependencies into _build
.
Is -bs-package-output
the same thing as -o
? If so, why not just call it -o
to make it even easier to get it to work with a build system.
I think a dummy -a
would also be a good idea, but -a
also remembers link flags and then the final linking stage will use them - which might actually be useful for BS one day too.
I think I'm just not seeing the benefits of deviating at all from the ocaml compiler flag API, but I'm sure you've thought of good reasons.
The problem of -o
is that its location depends on where you run the command, for JS output, we need fix its location(relative to package.json) no matter where user runs the command.
bsc
accept multiple -bs-package-output
so user can spit out goog module, commonjs and amd all at the same time
If user follows some convention, always generate js
files in package.json/lib/js
then it is pretty easy to adapt
The problem of -o is that its location depends on where you run the command, for JS output, we need fix its location(relative to package.json) no matter where user runs the command.
You could put that burden on the person who supplies the -o
flag. In our case, we might have a very different convention for where it goes anyways. We will make sure that people who depend on that output, will supply the right -I
flag to pick it up correctly. That style of cli interface is a pain, and BS does much better, but the main value is that tons of existing build systems went through that pain, and it would be good to support them (maybe this is a good community task to pick up, if it's lower priority for you).
You could put that burden on the person who supplies the -o flag.
That would be too restrictive to normal users.
I am a little worried that if the author of the package does not have interest or minimal commitment to support buckle, this would not be a sustainable effort, since there are a number of ways to break it, introducing c stubs without providing JS polyfills (via deps or using Str
etc). And there are bunch of optimizations can be applied to vanilla OCaml libraries to make it faster in JS backend, if the author does not have interest in supporting JS backend, then we could not get optimal JS code generated.
The scala community does have some special build rules to make it work in scalajs, tweaking the build system with some extra flags is the minimal effort compared with other more subtle stuff, just my opinions.
Btw, if other people are interested in contributing, we can discuss how to make it work better
My company is considering moving some of our existing OCaml code to run on Node.js to leverage existing JS libraries. Not being able to use opam deps is a major blocker for existing code with transitive requirements. We would be willing to lend some effort to make this easier.
Currently, it seems like a viable path for us might be to use JS-of-ocaml and Bucklescript in the same Node.js process, with some codegen to simplify talking between them.
Yeah not being able to use PPX's easily via opam has stalled a lot of what I've been doing... ^.^;
Looks like this issue is no longer relevant?
Yes, this does not seem relevant anymore, closing.