#obake#
Simple, developer-centric build system for OCaml.
##Motivation##
Strong static typing in a language like ocaml makes traditional build management tools a pain to work with when actually writing code. The problem is the compilation fails if any little thing is wrong, so if you make a small change to a module, and want to test it, you have to fix a bunch of compiler errors before Make will build you an executable. This can be a major annoyance when making significant changes to a subsystem that other systems compile against. This is a mismatch between build systems designed to build and deploy the contents of a code repository and the workflow of software developers.
This problem is normally solved by an IDE, which will often let you run a unit test as long as it's direct dependencies can be built. But in ocaml there is no such IDE.
OBake only requires you to define a source, build, and bin directories, as well as package dependencies via findlib. You can then compile individual .ml and .mli files and their dependencies. ml files can also be compiled to executable binaries simply by adding the -e switch. OBake discovers what dependencies a source file has at run time, and compiles all dependent source files that have changed since their last compilation.
##Quick Start (Example)##
- Generate an obake.yml configuration file for your project at the root of the project tree.
> cd example-ocaml-project
> obake --generate-config
generating config file: './obake.yml'
done.
-
Change the name of the sources directory if necessary in the yml file. Add any package dependencies (the obake.yml file tells you how).
-
Enter the src directory and compile Porsche.ml. It relies on the Color module so it will consider Color "stale" as well b/c it won't find a prebuilt version. The rules for whether just the mli or both the ml and mli files of Color are compiled are somewhat subtle. See the docs for the -b, -m, and -o options for more info.
> cd src
> obake Porsche.ml
Stale Targets:
(
/vc/oss/obake/dev/example-ocaml-project/src/Color.cmi ,
/vc/oss/obake/dev/example-ocaml-project/src/Porsche.cmo ,
/vc/oss/obake/dev/example-ocaml-project/src/Porsche.cmi
)
-
Can always clean up the built files and binaries.
> obake -c -
Compile the Porche module into a machine code executable.
> obake -m -e Porsche.ml Stale Targets: ( /vc/oss/obake/dev/example-ocaml-project/src/Color.cmx , /vc/oss/obake/dev/example-ocaml-project/src/Color.cmi , /vc/oss/obake/dev/example-ocaml-project/src/Porsche.cmx , /vc/oss/obake/dev/example-ocaml-project/src/Porsche.cmi ) > ls ../bin/ Porsche.bin
##Pitfalls##
-
Source code files may be separated into directories inside the src/ directory. However, obake will treat them all as if they were in a single directory. This means that two modules in different subdirectories may NOT have the same name, as obake cannot tell them apart. Source codes should therefore refer to each other as if they were modules in the same directory.
-
[Bug] If an executable is stale or non-existent, but the corresponding .cmx or .cmo file is up-to-date, obake will not build you a new executable.
-
At around 50 stale or uncompiled modules, Obake's dependency detection slows to the point of being useless. (There's an 2^n operation in there when it calls ocamldep recursively. The current implementation is very brute force.) To work around this, try to compile some subdirectories that have no dependencies on other subdirectories first, then the module that was taking too long to compile. Note this is only a problem after running a 'clean' operation. Once everything is compiling, if you edit one file and recompile, it will compile quickly.
##Prerequisites##
- Ruby 1.8.7 and text/highlight gem
> [sudo] apt-get install ruby
> [sudo] gem install text-highlight
- OCaml (3.09+) and ocamlfind
> [sudo] apt-get install ocaml
> [sudo] apt-get install ocaml-findlib
OBake
Synopsis
obake {-q|-v} {-f } {-h} {-gt} {-m|-b} {-e} {-c} {-p} {-o}
Description
OBake is a Bare-minimum build tool for Ocaml that is not make.
Options
'+' indicates option can be set in config file.
_________
+ Verbosity
How much info to print during execution
-q, --quiet
Print errors only
-v, --verbose
Print full config report on init, plus other info
____________________
Config File Location
The name of a config file to use other than the default
-f ,
--config-file
__________
Print Help
-h, --help
Prints this help message
____________________
Generate Config File
-gt, --generate-config
Generates an example config file and places it at ./obake.yml
_____________
+ Compiler Mode
Ocaml can compile to machine code or byte code. The two are functionally
equivalent at both compile time and runtime, but byte code is faster to compile
and slower at runtime. Has no real effect when compiling .mli (header) files.
-m, --machine-code
Compile all files to machine code using ocamlopt
-b, --byte-code
Compile all files to byte code using ocamlc. This is the default.
_________________
Build Executables
OBake can build executables by deducing exactly which modules are needed to link
the target source files' compiled version and then perform the linking step.
Executables are given extension .bin and placed in the binDir defined in the
config file.
-e, --executable
Build executables for the input filenames
_____
Clean
Delete contents of buildDir and binDir before doing any compilation. Can be used
independently of compiling operations, that is ">obake -c myFile.ml" will clear
the output directories and then compile myFile.ml, while ">obake -c" will simply
clear the output directories and quit.
-c, --clean
Clean before proceeding to compilation.
________________
Enable Profiling
Enable profiling of executables. All files will need to be recompiled, as well as
the linking step. Running the exec will then generate a dump file, which can be
viewed with gprof or XXX. Only affects machine-code compiled files.
-p, --profiling
Enable executables to be analyzed by a profiler.
_________________________
Force ByteCode Impl Files
When compiling byte code files, the default is to only requirecmi (compiled
headers) of dependencies to be present. This will force the cmo (compiled impls)
of dependency modules to be built. This is turned on automatically when building
byte code executables.
-o, --force-cmos
Force implementation (cmo) dependencies for byte code comp.
Config File
The config file used will be the first instance of obake.yml found when ascending
the directories of the local machine's filesytem, starting at the directory this
command is run from. Use --generate-config to create a template config file at
'./obake.yml'.
Config File Only Options
These options can only be set through a config file.
_________________
Sources Directory
The root directory of where the project sources are. While the specific files
to compile will be given as arguments on the commandline, the location of all
source files to consider is necessary to auto-detect dependencies.
_______________
Build Directory
The directory where files generated by obake will be output to. This includes
.ml and .mli files genrated by the lexer and parser but not executable .bin
files.
_____________________
Executables Directory
The directory where files linked into executables by obake will beoutput to.
_________
Libraries
A list of ocamlfind package names to include in the compilation. Valid values
can be found by the command'>ocamlfind list'
-/end help