3.5 KiB
- Building a hello world program
- Building a hello world program using Lwt
- Defining a library using Lwt and ocaml-re
- Defining a library with C stubs
- Defining a library with C stubs using pkg-config
- Using a custom code generator
- Defining tests
This document gives simple usage examples of Jbuilder.
Building a hello world program
In a directory of your choice, write this jbuild
file:
(executables
((names (hello_world))))
This hello_world.ml
file:
print_endline "Hello, world!"
And build it with:
jbuilder hello_world.exe
The executable will be built as _build/default/hello_world.exe
Building a hello world program using Lwt
In a directory of your choice, write this jbuild
file:
(executables
((names (hello_world))
(libraries (lwt.unix))))
This hello_world.ml
file:
Lwt_main.run (Lwt_io.printf "Hello, world!\n")
And build it with:
jbuilder hello_world.exe
The executable will be built as _build/default/hello_world.exe
Defining a library using Lwt and ocaml-re
Write this jbuild:
(library
((name mylib)
(public_name mylib)
(libraries (re lwt))))
The library will be composed of all the modules in the same
directory. Outside of the library, module Foo
will be accessible as
Mylib.Foo
, unless you write an explicit mylib.ml
file.
You can them use this library in any other directory by adding mylib
to the (libraries ...)
field.
Defining a library with C stubs
Assuming you have a file called mystubs.c
, that you need to pass
-I/blah/include
to compile it and -lblah
at link time, write this
jbuild:
(library
((name mylib)
(public_name mylib)
(libraries (re lwt))
(c_names (mystubs)
(c_flags (-I/blah/include))
(c_library_flags (-lblah)))))
Defining a library with C stubs using pkg-config
Same context as before, but using pkg-config
to query the
compilation and link flags. Write this jbuild:
(library
((name mylib)
(public_name mylib)
(libraries (re lwt))
(c_names (mystubs)
(c_flags (:include c_flags.sexp))
(c_library_flags (:include c_library_flags.sexp)))))
(rule
((targets (c_flags.sexp
c_library_flags.sexp))
(deps (config/discover.exe))
(action (run ${<} -ocamlc ${OCAMLC}))))
Then create a config
subdirectory and write this jbuild
:
(executables
((names (discover))
(libraries (base stdio configurator))))
as well as this discover.ml
file:
open Base
open Stdio
module C = Configurator
let write_sexp fn sexp =
Out_channel.write_all fn ~data:(Sexp.to_string sexp)
let () =
C.main ~name:"mylib" (fun c ->
let default : C.Pkg_config.package_conf =
{ libs = ["-lblah"]
; cflags = []
}
in
let conf =
match C.Pkg_config.get c with
| None -> default
| Some pc ->
Option.value (C.Pkg_config.query pc ~package:"blah") ~default
in
write_sexp "c_flags.sexp" (sexp_of_list sexp_of_string conf.libs);
write_sexp "c_library_flags.sexp" (sexp_of_list sexp_of_string conf.cflags))
Using a custom code generator
To generate a file foo.ml
using a program from another directory:
(rule
((targets (foo.ml))
(deps (../generator/gen.exe))
(action (run ${<} -o ${@}))))
Defining tests
Write this in your jbuild
file:
(alias
((name (runtest))
(deps (my-test-program.exe))
(action (run ${<}))))
And run the tests with:
jbuilder runtest