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 -> int
Sys.command
, but preferable.val runcmdf : ('a, unit, string, int) Pervasives.format4 -> 'a
runcmd
, but accepts a printf
-like format string.val findcmd : ?path:string list -> string -> string
Not_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 list
PATH
val search_libs_path : unit -> string list
SEARCH_LIBS
val read_file : string -> string
val write_file : string -> string -> unit
val read_from_cmd : string -> int * string
val read_from_cmdf : ('a, unit, string, int * string) Pervasives.format4 -> 'a
read_from_cmd
, but accepts a printf
-like format string.val env : string -> string
""
if the variable does
not exist.val env_req : string -> string
val env_opt : string -> string option
None
if the variable
is empty or does not exist.
Remember that the exit code 0 means that the command was successful.
type 'a
cmdstate
'a
val code : 'a cmdstate -> int
val result : 'a cmdstate -> 'a option
val return_code : int -> 'a cmdstate -> 'a cmdstate
val return_result : 'a option -> 'a cmdstate -> 'a cmdstate
val initial_state : unit -> 'a cmdstate
type'a
cmdlet ='a cmdstate -> 'a cmdstate
val cmd : string -> 'a cmdlet
val cmdf : ('a, unit, string, 'b cmdlet) Pervasives.format4 -> 'a
cmd
but accepts a printf
-like format stringval cmd_output : string -> string cmdlet
val cmdf_output : ('a, unit, string, string cmdlet) Pervasives.format4 -> 'a
cmd_output
but accepts a printf
-like format stringval set_code : int -> 'a cmdlet
val set_code_from : ('a cmdstate -> int) -> 'a cmdlet
val set_bool_code : bool -> 'a cmdlet
true
, and to 1 if the boolean is false
.val set_bool_code_from : ('a cmdstate -> bool) -> 'a cmdlet
set_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 cmdlet
val (|-) : 'a cmdlet -> 'a cmdlet -> 'a cmdlet
val ignore_code : 'a cmdlet -> 'a cmdlet
val eval : 'a cmdlet -> 'a option
None
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 -> bool
true
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 -> unit
val logf : ('a, unit, string, unit) Pervasives.format4 -> 'a
log
, 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 -> unit
file
the list of variable settingsval parse_conf_file : string -> (string * string) list
file
typelang_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_env
c_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_env
script_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 -> string
val c_flags : ?with_requirements:bool -> c_env -> string list
with_requirements=true
, the flags mentioned in c_requirements
are also returned (default: false
).val c_ld_flags : ?with_requirements:bool -> c_env -> string list
with_requirements=true
, the flags mentioned in c_requirements
are also returned (default: false
).val c_compiler_name : unit -> string
val c_compile_test : c_env -> string -> string cmdlet
val run_test : string cmdlet
val 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 cmdlet
pref_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 libs
c_flags
is flags
c_ld_flags
is ld_flags
, optionally enriched by the necessary
framework flagsc_elf_rpath
is tried c_config_script
is always None
c_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_env
file
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 -> unit
file
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 -> unit
find_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 -> string
c_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"