Jbuilder: simple way to organize config files, directories for multiple modules/packages

I would like to generate different libraries (or do I mean packages?) using jbuilder in a single directory tree (a single git repo). This sounds simple, and is surely possible, but I’ve been having trouble.

I have one executable, foo (but later there will be others). foo.ml is in bin.

I have various source files for libraries:

bar1.ml, bar2.ml are supposed to make up the bar package (or do I mean library??), so that I can refer to modules Bar.Bar1, Bar.Bar2.

baz1.ml, baz2.ml are supposed to make up the baz package …, etc.

These are all in lib.

I put bar* and baz* in a single directory, with multiple (name ...) clauses in the library stanza in jbuild in that directory. Each of the name clauses has a modules clause to specify wht files to use. However, then when I run jbuilder build @install from the project root, I get this error concerning lib/jbuild

Error: The current scope doesn't define package "baz".
The only packages for which you can declare elements to be installed in this directory are:
- bar (because of bar.opam)

OK, so I copy bar.opam to baz.opam. Now I have two identical opam files. Then I get this error concerning the bin/jbuild:

Error: I can't determine automatically which package this (install ...) stanza is for. I have the choice between these ones:
- bar  (because of bar.opam)
- baz (because of baz.opam)
You need to add a (package ...) field in this (install ...) stanza

(I also tried putting bar and baz in separate directories with separate jbuild files. That didn’t work, either, although I don’t recall at the moment what the errors were. But I’m happy to organize the directory structure in whatever way makes things easier for me.

I don’t care very much about the details because this is really a very simple, exploratory project. I don’t intend to create an opam package, at this point, at least. The source is available on github, but anyone who wants it can just clone the repo. I have fewer than 10 source files, and the only reason I want to bundle source files into packages/libraries is for the sake of organization. There is an executable, but it’s not the main executable. I expect to be writing others as part of the same repo soon.

(If you want to see the actual repo, it’s https://github.com/mars0i/imp/tree/jbuilder . Seemed simpler to rename things to foo, bar above, but you’ll figure it out.)


Update: I was confused by the reference in the second error to an install stanza I didn’t have. Maybe the error is misleading, or maybe there’s an auto-generated install stanza. I tried adding an install stanza to bin/jbuild, with a package statement referencing a newly created package file main.opam, but the “I can’t determine …” error returned, although now with three “because of” lines.

I am beginning to think jbuilder is designed to create exactly one package per source root. If so, OK.

In any event, it’s easier to assume that. All problems disappear! :slight_smile: Good enough for me, for now at least.

Multi-package builds certainly work if you use a separate sub-directory for each package. I’m not sure whether it would work with everything in a single directory, but doing it that way adds complexity for no reason anyway (because you then have to specify manually which modules go in which package).

In any case, make sure that your library name matches the package name.

Thanks @talex5. It’s very helpful to know that that should work.

So I went back to implementing the two packages in separate directories–expecting to report essentially the same errors here–but found that I was able to get it to work. :smile:

Not sure what I was doing wrong before when I was experimenting with different directories. I have probably learned a few things from trying to get it to work without separate directories, and that allowed me to get it right this time.

It seems that learning a new build system is always like this for me. Lots of puzzling, frustrating errors, until I finally figure out what constraints I must follow to make it work, and then it just works. I think I’ve seen the same thing happen to other people, so maybe it’s a common experience.