module Godi_script:This module contains library functions for GODI configuration scripts written in OCaml. This is mainly intended for the conf-foo packages.sig..end
In order to activate such a script, define the following variables in the driver Makefile of conf-foo:
CONF_SCRIPT: The name of the script, usually configure.gcs
(gcs = GODI configuration script). The suffix "gcs" enables a special
calling convention that automatically finds the O'Caml interpreter
and that loads the libraries str and unix, and, of course,
godi_script.CONF_SCRIPT_ARGS: Arguments to be passed to the script.
LOCALBASE: The GODI prefix of this installationCC: The name of the C compilerCFLAGS: General flags for C compilingLDFLAGS: General flags for linkingCREATE_SHLIBS: Whether C libraries must be shared ("yes") or notSHLIB_TYPE: The type of shared libraries used by the OSELF_RPATH: Whether to use RPATH at all ("yes") or notELF_RPATH_FLAG: The name of the RPATH flag, if any.SEARCH_LIBS: The list of standard library locationsMAKE: The name of the make program to use for upstream MakefilesRM, CP, ...
val runcmd : string -> intSys.command, but preferable.val runcmdf : ('a, unit, string, int) Pervasives.format4 -> 'aruncmd, but accepts a printf-like format string.val findcmd : ?path:string list -> string -> stringNot_found.
The command is searched in the locations enumerated by the environment
variable PATH, by default, or in the locations passed by the
path argument.val system_path : unit -> string listPATHval search_libs_path : unit -> string listSEARCH_LIBSval read_file : string -> stringval write_file : string -> string -> unitval read_from_cmd : string -> int * stringval read_from_cmdf : ('a, unit, string, int * string) Pervasives.format4 -> 'aread_from_cmd, but accepts a printf-like format string.val env : string -> string"" if the variable does
not exist.val env_req : string -> stringval env_opt : string -> string optionNone if the variable
is empty or does not exist.
Remember that the exit code 0 means that the command was successful.
type 'a cmdstate
'aval code : 'a cmdstate -> intval result : 'a cmdstate -> 'a optionval return_code : int -> 'a cmdstate -> 'a cmdstateval return_result : 'a option -> 'a cmdstate -> 'a cmdstateval initial_state : unit -> 'a cmdstatetype'acmdlet ='a cmdstate -> 'a cmdstate
val cmd : string -> 'a cmdletval cmdf : ('a, unit, string, 'b cmdlet) Pervasives.format4 -> 'acmd but accepts a printf-like format stringval cmd_output : string -> string cmdletval cmdf_output : ('a, unit, string, string cmdlet) Pervasives.format4 -> 'acmd_output but accepts a printf-like format stringval set_code : int -> 'a cmdletval set_code_from : ('a cmdstate -> int) -> 'a cmdletval set_bool_code : bool -> 'a cmdlettrue, and to 1 if the boolean is false.val set_bool_code_from : ('a cmdstate -> bool) -> 'a cmdletset_code_bool).
This function is useful to call non-commandlets from a sequence of commandlets. For instace, to just print messages:
cmd1 &-
set_bool_code_from (fun _ -> printf "Here I am\n"; true) &-
cmd2
val (&-) : 'a cmdlet -> 'a cmdlet -> 'a cmdletval (|-) : 'a cmdlet -> 'a cmdlet -> 'a cmdletval ignore_code : 'a cmdlet -> 'a cmdletval eval : 'a cmdlet -> 'a optionNone is always returned if the exit code is non-zero, regardless of
whether there is a result value or not.val eval_test : 'a cmdlet -> booltrue if the exit code is 0,
and false if the exit code is non-zero.
eval (cmd_output "ls /a" |- cmd_output "ls /b")
Loops should be programmed with recursion, or by folding:
eval
(List.fold_left
(fun acc x ->
acc |- cmdf_output "ls %s" (Filename.quote x))
(set_bool_code true)
[ "/a"; "/b"; "/c" ]
)
val log : string -> unitval logf : ('a, unit, string, unit) Pervasives.format4 -> 'alog, but accepts a printf-like format stringmake syntax. However, these
files should only contain name=value settings, and not more.
The values should not contain any references to other variables
("${name}"), and the dollar character must be written $$.val print_conf_file : string -> (string * string) list -> unitfile the list of variable settingsval parse_conf_file : string -> (string * string) listfiletypelang_env =[ `C of c_env ]
type c_env = {
|
c_env_file : |
(* | The file this record was parsed from. The first string is the absolute file name, and the second string is the name prefix used in this file | *) |
|
c_incdirs : |
(* | List of directories for "#include" | *) |
|
c_libdirs : |
(* | List of library directories | *) |
|
c_libs : |
(* | Names of libraries (w/o "lib" and suffix) | *) |
|
c_flags : |
(* | Further flags for C compiling | *) |
|
c_ld_flags : |
(* | Further flags for linking | *) |
|
c_elf_rpath : |
(* | Whether c_libdirs must be added to the
runtime lookup path | *) |
|
c_config_script : |
(* | The name of a foreign config script | *) |
|
c_godi_deps : |
(* | List of additional GODI dependencies to output | *) |
|
c_requirements : |
(* | Requirements to link test programs | *) |
c_incdirs can be translated to further C compiler flags;
the c_libdirs and c_libs can be translated to further linker
flags. The c_flags and c_ld_flags are additional flags.
It is also allowed to only fill c_flags and c_ld_flags and let
the other components empty.
The c_config_script is the name of another script that can be called
to get the C compiler and linker flags (e.g. pkg-config scripts).
The c_godi_deps are dependencies to GODI packages that are required
at run-time to make the C library available. (These are usually
base-foo packages. Configuration packages must not be put into this
list!)
The c_requirements lists environments that are necessary to compile
and link programs, but that are not merged into the regular output.
For instance,
many graphics libraries depend on the X11 library.
A note about shell quoting: The above lists of flags should not
contain any shell metacharacters such that quoting is not necessary
at all. As the flags are processed by further scripts it is expected
that quoting will be taken wrong anyway, so it is the best strategy
to avoid quoting.
val empty_c_env : c_envc_env where the lists are empty, the options are None, and the
boolean fields are false.val c_env_from_config_script : ?arg_cflags:string ->
?arg_ldflags:string ->
?args:string list -> script_name:string -> unit -> c_envscript_name (which must be an absolute file name)
and extracts the c_env from it. The C compiler flags are obtained
by calling the script with argument arg_cflags, and the linker
flags are obtained by calling the script with argument arg_ldflags.
The default for arg_cflags is "--cflags", and the default
for arg_ldflags is "--libs". (These work in most cases.)
In args one can pass further arguments.
The function fails if the configure script cannot be called, or
if it does not exit with code 0.
val create_test_whether_c_function_exists : string -> stringval c_flags : ?with_requirements:bool -> c_env -> string listwith_requirements=true, the flags mentioned in c_requirements
are also returned (default: false).val c_ld_flags : ?with_requirements:bool -> c_env -> string listwith_requirements=true, the flags mentioned in c_requirements
are also returned (default: false).val c_compiler_name : unit -> stringval c_compile_test : c_env -> string -> string cmdletval run_test : string cmdletval find_c_library : ?godi_deps:string list ->
?pref_incdir:string ->
?pref_libdir:string ->
?flags:string list ->
?ld_flags:string list ->
?inc_name:string ->
?requirements:c_env list ->
?locations:string list ->
?frameworks:string list ->
libs:string list ->
test:(c_env -> c_env option) ->
unit -> c_env cmdletpref_incdir
and pref_libdir are tried. The second choice are the frameworks
(Mac OS X only). If this is not successful, too, searching continues
with the locations found in the environment variable SEARCH_LIBS
(by default, unless overriden by locations).
A C library is found if:
inc_name is found (if passed), andtest returns a non-None valuetest is the result of the
commandlet.
The C environment passed to the test function is properly set
up:
c_incdirs contains the tested include locationc_libdirs contains the tested library locationc_libs is libsc_flags is flagsc_ld_flags is ld_flags, optionally enriched by the necessary
framework flagsc_elf_rpath is tried c_config_script is always Nonec_godi_deps is set to godi_deps, but only when the preferred
location is triedframeworks : If non-empty, and if the system is Mac OS X, this
is a list of frameworks to try.val parse_c_result : file:string -> prefix:string -> unit -> c_envfile where the variables
use prefix.
The syntax written by print_c_result is recognised plus a number
of legacy notations.
val print_c_result : ?vars:(string * string) list ->
file:string -> prefix:string -> c_env -> unitfile and to the screen.
The prefix is prepended to the variables in file.
Example: print_c_result ~file:"conf-foo.mk" ~prefix:"CONF_FOO" ce
The component c_env_file is ignored (except in c_requirements
where it is output to the <prefix>_REQS variable).
The following standard variable names are used in the printed file:
<prefix>_INCDIRS: The include directories. /usr/include is omitted
from this list.<prefix>_LIBDIRS: The library directories. /usr/lib is omitted
from this list.<prefix>_LIBNAMES: The library names.<prefix>_CFLAGS: The additional flags for C compiling<prefix>_LDFLAGS: The additional flags for linking<prefix>_NEED_RPATH: Whether the RPATH flag is needed ("yes") or not
("no")<prefix>_TOTAL_CFLAGS: The combined flags for C compiling from
both INCDIRS and CFLAGS. Flags from required libraries are omitted.<prefix>_TOTAL_LDFLAGS: The combined flags for linking from
all of LIBDIRS, LIBS, LDFLAGS, and NEED_RPATH. Flags from
required libraries are omitted.<prefix>_SCRIPT: The name of the external config script<prefix>_DEPENDS: The additional GODI dependencies<prefix>_REQS: The requirements, if bound to files (to be used
by nested configuration packages)vars are appended to the file, if passed. Useful to output
further non-standard variables.val main_c_finder : ?godi_deps:string list Pervasives.ref ->
?pref_incdir:string option Pervasives.ref ->
?pref_libdir:string option Pervasives.ref ->
?c_flags:string list Pervasives.ref ->
?ld_flags:string list Pervasives.ref -> unit -> unitfind_c_library.
The arguments godi_deps,
pref_incdir, pref_libdir, c_flags, and ld_flags can
be set by command-line if a string reference is passed to the
function.
Example:
let pref_incdir = ref None in
let pref_libdir = ref None in
main_c_finder ~pref_incdir ~pref_libdir ();
let c_opt = eval
(find_c_library
?pref_incdir:!pref_incdir
?pref_libdir:!pref_libdir
~libs:... ~test:... ()) in
match c_opt with
None -> failwith "Cannot find library"
| Some c -> print_c_result ~file:"conf-foo.mk" ~prefix:"CONF_FOO" c
val main_config_finder : script_basename:string -> unit -> stringc_env_from_config_script).
In script_basename one must pass the name of the script to call,
without directory, e.g. "foo-config". The script is looked up
in the SEARCH_LIBS and PATH locations. A command-line parameter
may be used to override the location.
The absolute path of the script is returned as string.
Whole example:
let test ce = ... ;;
let cmd = main_config_finder ~script_basename:"foo-config" () ;;
let ce = c_env_from_config_script ~script_name:cmd () ;;
match test ce with
Some ce' ->
print_c_result ~file:"conf-foo.mk" ~prefix:"CONF_FOO" ce'
| None ->
failwith "Cannot find library"