193 lines
4.1 KiB
Org Mode
193 lines
4.1 KiB
Org Mode
This document gives simple usage examples of Jbuilder.
|
|
|
|
* Building a hello world program
|
|
|
|
In a directory of your choice, write this =jbuild= file:
|
|
|
|
#+begin_src scheme
|
|
(executables
|
|
((names (hello_world))))
|
|
#+end_src
|
|
|
|
This =hello_world.ml= file:
|
|
|
|
#+begin_src ocaml
|
|
print_endline "Hello, world!"
|
|
#+end_src
|
|
|
|
And build it with:
|
|
|
|
#+begin_src sh
|
|
jbuilder hello_world.exe
|
|
#+end_src
|
|
|
|
The executable will be built as =_jbuild/default/hello_world.exe=
|
|
|
|
* Building a hello world program using Lwt
|
|
|
|
In a directory of your choice, write this =jbuild= file:
|
|
|
|
#+begin_src scheme
|
|
(executables
|
|
((names (hello_world))
|
|
(libraries (lwt.unix))))
|
|
#+end_src
|
|
|
|
This =hello_world.ml= file:
|
|
|
|
#+begin_src scheme
|
|
Lwt_main.run (Lwt_io.printf "Hello, world!\n")
|
|
#+end_src
|
|
|
|
And build it with:
|
|
|
|
#+begin_src sh
|
|
jbuilder hello_world.exe
|
|
#+end_src
|
|
|
|
The executable will be built as =_jbuild/default/hello_world.exe=
|
|
|
|
* Defining a library using Lwt and ocaml-re
|
|
|
|
Write this jbuild:
|
|
|
|
#+begin_src scheme
|
|
(library
|
|
((name mylib)
|
|
(public_name mylib)
|
|
(libraries (re lwt))))
|
|
#+end_src
|
|
|
|
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.
|
|
|
|
* Using cppo
|
|
|
|
Add this field to your =library= or =executables= stanzas:
|
|
|
|
#+begin_src scheme
|
|
(preprocess (command "cppo -V OCAML:${ocaml_version}"))
|
|
#+end_src
|
|
|
|
Additionnaly, if you are include a =config.h= file, you need to
|
|
declare the dependency to this file via:
|
|
|
|
#+begin_src scheme
|
|
(preprocessor_deps (config.h))
|
|
#+end_src
|
|
|
|
** Using the .cppo.ml style like the ocamlbuild plugin
|
|
|
|
Write this in your jbuild:
|
|
|
|
#+begin_src scheme
|
|
(rule
|
|
((targets (foo.ml))
|
|
(deps (foo.cppo.ml <other files that foo.ml includes>))
|
|
(rule (run cppo ${<} -o ${@}))))
|
|
#+end_src
|
|
|
|
* 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:
|
|
|
|
#+begin_src scheme
|
|
(library
|
|
((name mylib)
|
|
(public_name mylib)
|
|
(libraries (re lwt))
|
|
(c_names (mystubs)
|
|
(c_flags (-I/blah/include))
|
|
(c_library_flags (-lblah)))))
|
|
#+end_src
|
|
|
|
* 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:
|
|
|
|
#+begin_src scheme
|
|
(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}))))
|
|
#+end_src
|
|
|
|
Then create a =config= subdirectory and write this =jbuild=:
|
|
|
|
#+begin_src scheme
|
|
(executables
|
|
((names (discover))
|
|
(libraries (base stdio configurator))))
|
|
#+end_src
|
|
|
|
as well as this =discover.ml= file:
|
|
|
|
#+begin_src ocaml
|
|
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))
|
|
#+end_src
|
|
* Using a custom code generator
|
|
|
|
To generate a file =foo.ml= using a program from another directory:
|
|
|
|
#+begin_src scheme
|
|
(rule
|
|
((targets (foo.ml))
|
|
(deps (../generator/gen.exe))
|
|
(action (run ${<} -o ${@}))))
|
|
#+end_src
|
|
|
|
* Defining tests
|
|
|
|
Write this in your =jbuild= file:
|
|
|
|
#+begin_src scheme
|
|
(alias
|
|
((name (runtest))
|
|
(deps (my-test-program.exe))
|
|
(action (run ${<}))))
|
|
#+end_src
|
|
|
|
And run the tests with:
|
|
|
|
#+begin_src sh
|
|
jbuilder runtest
|
|
#+end_src
|