Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make BuckleScript a drop in replacement for ocamlc. #638

Closed
jordwalke opened this issue Aug 13, 2016 · 13 comments
Closed

Make BuckleScript a drop in replacement for ocamlc. #638

jordwalke opened this issue Aug 13, 2016 · 13 comments

Comments

@jordwalke
Copy link

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.

@jordwalke
Copy link
Author

Apologies if this is covered somewhere, but I did check the docs.

@bobzhang
Copy link
Member

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).

@jordwalke
Copy link
Author

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).

@jordwalke
Copy link
Author

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.

@bobzhang
Copy link
Member

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

@jordwalke
Copy link
Author

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:

  1. You can delete _build and it removes all build artifacts for all packages.
  2. 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.

@bobzhang
Copy link
Member

bobzhang commented Aug 16, 2016

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

@jordwalke
Copy link
Author

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).

@bobzhang
Copy link
Member

bobzhang commented Sep 8, 2016

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

@gtrak
Copy link

gtrak commented Nov 8, 2017

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.

@OvermindDL1
Copy link
Contributor

Yeah not being able to use PPX's easily via opam has stalled a lot of what I've been doing... ^.^;

@yawaramin
Copy link
Contributor

Looks like this issue is no longer relevant?

@cknitt
Copy link
Member

cknitt commented May 27, 2023

Yes, this does not seem relevant anymore, closing.

@cknitt cknitt closed this as completed May 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants