Cil Makefile Structure ---------------------- (Originally written by Scott, updated 11/19/01.) The build rules are spread out among several Makefiles: Makefile - toplevel driver Makefile, interprets a variety of command-line arguments (e.g. INFERBOX=infer), and has rules for all the tests/benchmarks Makefile.gcc - definitions of make variables that specify the syntax of invoking gcc; for example, it has "INC := -I", meaning -I is the option to name include directories Makefile.msvc - similar to above, but for MS's "cl.exe" command-line compiler (e.g. "INC := /I") Makefile.ccured - rules for building the 'ccured' program and runtime library Makefile.ocaml - generic Makefile for OCaml projects; includes targets to compile and link ML sources into bytecode or native code Makefile.combiner - rules for making the 'combiner' program Makefile.cil - rules for making the 'cilly' program ------------- Makefile ----------- Typical usage is to run only the toplevel Makefile, but specify options on the command line saying what to do. For example: make - build the bytecode 'ccured' and debug library Some of the more important command-line options: NATIVECAML=1 - build native code 'ccured' RELEASELIB=1 - build non-debug library OPTIM=1 - enable ccured's built-in optimizer module RELEASE=1 - native code, non-debug, optimizer enabled, etc. NOGC=1 - disable the garbage collector (use malloc/free) NOLINES=1 - disable #line directives in output COMMLINES=1 - print #line, but only as comments TRACE=flag1,.. - enable various debug output flags LOGCALLS=1 - transform code to print at every function entry LOGSTYLE=n - style for LOGCALLS; see Makefile for n's meaning INFERBOX=infer - turn on full ccured transformation; without this, it just transforms to Cil and outputs uninstrumented so for example "make RELEASE=1" will build release versions of things. Some other targets of interest: make clean - remove compilation byproducts, including executables make odoc - make OCamlDoc documentation .html files make setup - build *both* bytecode/native, debug/non-debug For convenience, we've put targets into the Makefile for various test programs and benchmarks we use. For example: make go INFERBOX=infer - build spec95 "go" benchmark in ccured mode make power - build Olden "power" benchmark in cil-only mode The line "below here are rules for building benchmarks" separates the benchmark targets. ------------- Makefile.ccured ----------- This file does three jobs: - supplies parameters to Makefile.ocaml that let it build the 'ccured' executable, which transforms C code to add runtime checks - says how to build the CCured runtime library - produce patched versions of some system #include files Among the info to build 'ccured', the most important is the "MODULES" line, which says what are the ML modules which comprise this program. Note that order is *very* important: the OCaml linker wants to see *no* forward references, so the modules admit a total order on dependencies. (If modules A and B call each other, you can list A first, and let B have an exported function reference which module A then sets to point at one of A's functions. Ugly, I know.) Some of the configuration rules from Makefile are repeated in Makefile.ocaml. This is unfortunate.. The runtime library contains wrappers for C library calls, and the Boehm-Weiser conservative garbage collector. The library's name is dependent on (1) which compiler you're using, (2) whether it's being build in debug mode or not, and (3) what the extension for libraries is on the current platform. For gcc/debug/linux, it's obj/ccured_GNUCC_debug.a. The garbage collector is built essentially independently, yielding its "gc.a" library. The CCured modules are then added to this. -------------- Makefile.ocaml ------------ This makefile is a generic OCaml build system. You tell it the names of the modules to build, and it compiles and links them. A major choice is whether to build bytecode or native code, determined by whether NATIVECAML is defined. The rules themselves are complicated because this makefile works hard to allow the source files (.ml, etc.) to live in a different directory than the compiled object files (.cmo, etc.). If you want to see the details of the build process, set the variable ECHOSTYLE_SCOTT (in your .ccuredrc, for example). This will print every command executed which has a side effect. Without this you'll just see English descriptions of what's happening. ------------- stylistic conventions ---------- For the most part, we try to use ":=" instead of "=". Basically, ":=" evaluates its right-hand-side the moment it's parsed, whereas the RHS of "=" is evaluated every time the variable is referenced. We find it's easier to predict how ":=" will behave, so unless the delayed evaluation of "=" is really desired, use ":=". Please indent the bodies of "ifdef..endif". This works fine, and makes the files much easier to read. (I'm not going to explore here the theology behind how *much* to indent...) -------------- references -------------- Main Cil docs: http://raw.cs.berkeley.edu/ccured/cil/index.html GNU Make manual: http://www.gnu.org/manual/make/html_chapter/make_toc.html "Recursive Make Considered Harmful", an interesting and informative article about how to use and misuse make: http://www.tip.net.au/~millerp/rmch/recu-make-cons-harm.html