gauche.configure
- Generating build files ¶This is a utility library to write a configure script. It is used to check the system properties and generates build files (usually Makefile) from templates.
The primary purpose is to replace autoconf-generated configure shell scripts in Gauche extension packages.
The advantage of using autoconf is that it generates a script that runs on most vanilla unix variants, for it only uses minimal shell features and basic unix commands. However, when you configure Gauche extension, you sure have Gauche already, so you don’t need to limit yourself with minimal environment.
Writing a configure script directly in Gauche means developers don’t need an extra step to generate configure before distribution. They can directly check-in configure in the source repo, and anybody who pulls the source tree can run configure at once without having autoconf.
Currently, gauche.configure
only covers small subset of
autoconf, though, so if you need to write complex tests
you may have to switch back to autoconf. We’ll add tests
as needed.
The core feature of gauche.configure
is the ability to generate files
(e.g. Makefile) from templates (e.g. Makefile.in) with replacing
parameters. We follow autoconf convention, so the substitution parameters
in a template is written like @VAR@
. You should be able
to reuse Makefile.in used for autoconf without changing them.
The API corresponds to autoconf’s AC_*
macros, while we use
cf-
prefix instead.
• Structure of configure script: | ||
• Configure API: |
A configure script tests running system’s properties to determine values of substitution parameters, then read one or more template build files, and write out one output build file for each, replacing substitution parameters for the assigned values.
By convention, a template file has a suffix .in
, and
the corresponding output file is named without the suffix.
For example, Makefile.in
is a template that generates
Makefile
.
Templates may contain substitution parameters, noted @PARAMETER_NAME@
.
This is a fragment of a typical Makefile template:
GAUCHE_PACKAGE = "@GAUCHE_PACKAGE@" SOEXT = @SOEXT@ LOCAL_PATHS = "@LOCAL_PATHS@" foo.$(SOEXT): $(foo_SRCS) $(GAUCHE_PACKAGE) compile \ --local=$(LOCAL_PATHS) --verbose foo $(foo_SRCS)
When processed by configure
, @GAUCHE_PACKAGE@
,
@SOEXT@
and @LOCAL_PATHS@
are replaced
with appropriate values. If you know autoconf, you are already
familiar with this.
The Gauche configure script is structurally similar to autoconf’s
configure.in
, but you can use full power of Scheme.
The following is the minimal configure script:
#!/usr/bin/env gosh (use gauche.configure) (cf-init-gauche-extension) (cf-output-default)
This script does several common tasks.
The cf-init-gauche-extension
does the following:
--prefix
, and
--with-local=PATH:PATH:...
which adds PATH/include
s and PATH/lib
s to
the header and library search paths.
You can handle more arguments by adding
cf-arg-with
and cf-arg-enable
before
cf-init-gauche-extension
.
package.scm
. Package name and version are taken
from it. Dependencies are also checked.
@prefix@
.
And cf-output-default
does the following:
VERSION
file.
Makefile.in
’s in the source directory and its subdirectories,
and process them
to generate Makefile
s.
If config header files (typically config.h
) are specified by
cf-config-headers
, process input files
(e.g. config.h.in
) to generate the header files.
In general, a configure
script consists of the following parts:
--with-PACKAGE
and/or --enable-FEATURE
options you want to handle, by
cf-with-arg
and cf-enable-arg
, respectively.
cf-init
or cf-init-gauche-extension
sets up global context and
parses command-line arguments passed to configure
.
It also process package metainformation in package.scm, if it exists.
cf-output
or cf-output-default
to process template files.
Most cf-*
API corresponds to autoconf’s AC_*
or
AS_*
macros. We need argument declarations
before cf-init
so that it can generate help message
including custom arguments in one pass.
{gauche.configure
}
This is a convenience API that packages several boilerplate cf-*
function calls in one call. This must be called exactly once in a
configure script.
Specifically, it calls cf-arg-with
to process --with-local
,
then calls cf-init
with no arguments to initialize,
then sets the following substitution parameters:
GOSH
Path to gosh
.
GAUCHE_CONFIG
Path to gauche-config
.
GAUCHE_PACKAGE
Path to gauche-package
.
GAUCHE_INSTALL
Path to gauche-install
.
GAUCHE_CESCONV
Path to gauche-cesconv
.
GAUCHE_PKGINCDIR
Result of gauche-config --pkgincdir
GAUCHE_PKGLIBDIR
Result of gauche-config --pkglibdir
GAUCHE_PKGARCHDIR
Result of gauche-config --pkgarchdir
The --with-local
command-line argument should take a parameter, which is
a colon-separated list of paths. It becomes a value of substitution parameter
LOCAL_PATHS
. The default Makefile.in
template passes
its value to gauche-package
via the --local
argument.
When the C extension is compiled and linked, the
include
and lib
subdirectories of the given paths are
searched for headers and libraries, respectively.
For example, if the extension requires a library foo and you install
it under /opt/foo
(that is, headers in /opt/foo/include
and library objects in /opt/foo/lib
), then you can pass
--with-local=/opt/foo
to configure the extension.
If you don’t like these default behavior, you can call individual
cf-*
functions instead. See cf-init
below.
{gauche.configure
}
Initialize the configure system. Corresponds to autoconf’s AC_INIT
.
This must be called once in the
configure script, before any feature-test procedures.
(If you call cf-init-gauche-extension
, cf-init
is called
from it.)
First, it checks if a file named package.scm is
in the same directory as the configure script,
and reads the Gauche package description from it. The package description
contains package name, version, dependencies, etc.
See gauche.package
- Package metainformation, for the details.
It then parses the command-line arguments, sets up the configure environment, and (if package.scm defines dependencies) check if the system has required packages.
The optional arguments are only supported for the backward compatibility
if you don’t have package.scm. You need at least
to provide package-name and package-version to tell
what package you’re configuring. They are used as the value
of substitution parameter PACKAGE_NAME
and PACKAGE_VERSION
.
The other optional arguments, maintainer-email and
homepage-url, are used to initialize PACKAGE_BUGREPORT
and
PACKAGE_URL
. These arguments are compatible to autoconf’s
AC_INIT
macro.
We recommend to always use package.scm and omit all the optional
arguments, because it allows you to maintain the package metainformation
in one place. When package.scm is read, PACKAGE_BUGREPORT
is initialized by the first entry of maintainers
slot of
the package description, and PACKAGE_URL
is initialized
by its homepage
slot.
See gauche.package
- Package metainformation, for description of slots of the package
description.
Note that if there’s package.scm and you provide
the optional arguments, they must match, or cf-init
raises an
error. It is to catch errors during transition in which you forgot
to update either one.
This procedure sets up a bunch of standard substitution parameters
such as prefix
, bindir
or srcdir
. To see what
substitution parameters are set, you can call cf-show-substs
after cf-init
.
{gauche.configure
}
Make the configure script accept feature selection argument and
package selection argument, respectively. The corresponding
autoconf macros are AC_ARG_ENABLE
and AC_ARG_WITH
.
Those procedures must be called before calling cf-init
or cf-init-gauche-extension
.
The feature and package arguments must be a symbol.
A feature selection argument is in a form of either
--enable-feature=val
,
--enable-feature
, or --disable-feature
.
The latter two are equivalent to --enable-feature=yes
and --enable-feature=no
, respectively.
It is to select an optional feature provided with the package itself.
A package selection argument is in a form of either
--with-package=val
,
--with-package
and --without-package
.
The latter two are equivalent to --with-package=yes
and --with-package=no
, respectively.
It is to select an external software package to be used with
this package.
When cf-init
finds these arguments during command-line processing,
it adds entry of feature
or package to the global tables, with the value val.
Those global tables can be accessed with cf-feature-ref
and
cf-package-ref
procedures below.
The help-string argument must be a string and
is used as is to list the help
of the option in part of usage message displayed by
configure --help
. You can use cf-help-string
below
to create a help string that fits nicely in the usage message.
If optional proc-if-given argument is given, it must be a procedure
that accepts one argument, val. It is called when cf-init
finds one of those arguments.
If optional proc-if-not-given argument is given, it must be a procedure
that accepts no arguments. It is called when cf-init
doesn’t find any of those arguments.
The following is to accept --with-local=PATH:PATH:…
.
(This cf-arg-with
call is included in cf-init-gauche-extension
).
Note that the help string (the second argument) is generated by
cf-help-string
call. The command-line parameter followed by
--with-local
is passed as the argument of the procedure
in the third argument:
(cf-arg-with 'local (cf-help-string "--with-local=PATH:PATH..." "For each PATH, add PATH/include to the include search paths and PATH/lib to the library search paths. Useful if you have some libraries installed in non-standard places. ") (^[with-local] (unless (member with-local '("yes" "no" "")) (cf-subst 'LOCAL_PATHS with-local))) (^[] (cf-subst 'LOCAL_PATHS "")))
{gauche.configure
}
Return a string formatted suitable to show as an option’s help message.
The result can be passed to help-string argument of
cf-arg-enable
and cf-arg-with
, to ensure that
configure --help
will produce a consistently formatted output.
This corresponds to autoconf’s AS_HELP_STRING
.
Call it as follows, and it’ll indent and fill the description nicely.
(cf-help-string "--option=ARG" "Give ARG as the value of option")
{gauche.configure
}
Lookup a symbol name from the global feature table and the
global package table, respectively.
These can be called after cf-init
.
For example, if you’ve called cf-arg-enable
with foofeature
,
and the user has invoked the configure
script with
--with-foofeature=full
, then (cf-feature-ref 'foofeature)
returns "full"
. If the user hasn’t given the command-line
argument, #f
is returned.
If you add or change the value of features or packages,
you can use generalized set!
as
(set! (cf-feature-ref 'NAME) VALUE)
etc.
The cf-init
procedure opens the default log drain
that goes to config.log
, and you can use log-format
to write to it (See gauche.logger
- User-level logging, for the details of logging).
However, to have consistent message format conveniently, the following procedures are provided. They emits the message both to log files and the current output port (in slightly different formats so that the console messages align nicely visually.)
{gauche.configure
}
Writes out “checking XXX...” message. The fmt and arg …
arguments are passed to format
to produce the “XXX” part
(see Formatting output).
For the current output port, this does not emit the trailing newline,
expecting cf-msg-result
will be called subsequently.
Here’s an excerpt of the source that uses cf-msg-checking
and cf-msg-result
:
(define (compiler-can-produce-executable?) (cf-msg-checking "whether the ~a compiler works" (~ (cf-lang)'name)) (rlet1 result ($ run-compiler-with-content (cf-lang-link-m (cf-lang)) (cf-lang-null-program-m (cf-lang))) (cf-msg-result (if result "yes" "no"))))
This produces a console output like this:
checking whether the C compiler works... yes
while the log file records more info:
checking: whether the C compiler works ... whatever logging message from run-compiler-with-content ... result: yes
This corresponds to autoconf’s AC_MSG_CHECKING
.
{gauche.configure
}
The fmt and arg … are passed to format
, and
the formatted message and newline is written out
(see Formatting output). Typically, the message is simply
“yes” or “no”, or the name (of a library, a header, etc.) that is found.
For the log file, it records “result: XXX” where XXX is the
formatted message. Supposed to be used with cf-msg-checking
; see the
example of cf-msg-checking
above.
This corresponds to autoconf’s AC_MSG_RESULT
.
{gauche.configure
}
Produces formatted message to both console and log. Newline is added.
This corresponds to autoconf’s AC_MSG_NOTICE
.
{gauche.configure
}
Produces “Warning: XXX” and
“Error: XXX” messages, respectively.
The fmt and arg … are passed to format
to
generate XXX part (see Formatting output).
Additionally, cf-msg-error
exits with exit code 1.
These corresponds to
autoconf’s AC_MSG_WARN
and AC_MSG_ERROR
.
NB: AC_MSG_ERROR
can specify the exit code,
but cf-msg-error
uses fixed exit code (1) for now.
{gauche.configure
}
Convenience routine to replace shell’s echo
command.
If the argument list ends with > file
or
>> file
, where file is a string file name,
then this works just like shell’s echo
; that is,
args except the last two are written to file, space
separated, newline terminated. Using >
supersedes
file, while >>
appends to it.
If the argument list doesn’t end with those redirection message, it writes out the argument to both the current output port and the log file, space separated, newline terminated. For the log file, the message is prefixed with “Message:”.
The configure script maintains two global tables, definition tables
and parameter tables. Definition tables is used for C preprocessor
definitions, and parameter tables are used for @PARAMETER@
substitutions. (Do not confuse substitution parameters with
Scheme’s parameter objects (see Parameters)).
{gauche.configure
}
Registers C preprocessor definition of symbol with value.
Value can be any Scheme objects, but it is emitted to a command
line (in -DSYMBOL=VALUE
form) or in config.h
(in #define SYMBOL VALUE
form) using display
, so
you want to avoid including funny characters. If value is
omitted, 1
is assumed.
NB: To #define
a string value, e.g. #define FOO "foo"
,
you have to call as (cf-define 'FOO "\"foo\"")
.
This corresponds to autoconf’s AC_DEFINE
.
{gauche.configure
}
Returns #t
iff symbol is cf-define
d.
{gauche.configure
}
Registers a substitution parameter symbol with value.
While processing output files, @symbol@ in the template
is substituted with value.
Value is usually a string, but can be any Scheme objects;
its display
representation.
If value is #f
or omitted, it works a bit differently.
If symbol hasn’t been registered as a substitution parameter,
it is registered with an empty string as its value. If symbol has
already been registered, however, its value is left intact.
This corresponds to autoconf’s AC_SUBST
, but we require
the value (while autoconf can refer to the shell variable value as default).
{gauche.configure
}
Prepend or append value to the substitution parameter symbol,
using delimiter delim. If the substitution parameter isn’t
defined, value becomes the sole value of the parameter,
except when default is given and not an empty string.
If delim is omitted, single whitespace is used.
A substitution parameter is often used to accrue command line arguments
(e.g. -I include-dir
for a compiler), and these procedures
comes handy.
{gauche.configure
}
Temporarily replace substitution parameters with new values. This
could be useful for example to run some compilation checks with
different parameters.
Binding may be one of the following forms:
(var value)
Temporarily substitue parameter var’s value to value.
(var + value)
Temporarily append value to the parameter var, using
a space as a delimiter. See cf-subst-append
above.
(var value +)
Temporarily prepend value to the parameter var, using
a space as a delimiter. See cf-subst-prepend
above.
(with-cf-subst ((LIBS "-L<path> -l<lib>")) (cf-try-compile-and-link ...))
In autoconf, this pattern is realized by saving the current value of the substituion parameter, modify it, run checks, and restore the old value. It is tedious.
{gauche.configure
}
Returns true iff symbol is registered as a substitution parameter by
cf-subst
.
{gauche.configure
}
Lookup the environment variable with the name symbol and if it is found,
use its value as the substitution value. If it is not found, and
if symbol hasn’t been already registered as a substitution parameter,
register it with an empty string as its value; otherwise, do nothing.
For example,
if you call (cf-arg-var 'MYCFLAGS)
, then the user
can provide the value of @MYCFLAGS@
as
MYCFLAGS=-g ./configure
.
This corresponds to autoconf’s AC_ARG_VAR
, but we lack the ability
of setting the help string. That’s because cf-arg-var
must
be run after cf-init
, but the help message is constructed
within cf-init
.
{gauche.configure
}
This looks up the value of the substitution parameter symbol.
If there’s no such substitution parameter registered,
it returns default when it’s provided, otherwise
throws an error.
{gauche.configure
}
Looks up the value of the substitution parameter cf-ref,
but it returns empty string if it’s unregistered. Useful
to use within string interpolation, e.g. #"gosh ~(cf$'GOSHFLAGS)"
.
{gauche.configure
}
Check if a named executable program exists in search paths, and if it
exists, sets the substitution parameter sym to the name
of the found program. The name to search is specified by prog-or-progs,
which is either a string or a list of strings.
The difference of cf-check-prog
and cf-path-prog
is that
cf-check-prog
uses the basename of the found program, while
cf-path-prog
uses its full path. These corresponds to
autoconf’s AC_CHECK_PROG
, AC_CHECK_PROGS
,
AC_PATH_PROG
and AC_PATH_PROGS
.
For example, the following
feature test searches either one of cc
, gcc
, tcc
or pcc
in PATH
and sets the substitution parameter MY_CC
to the name of the found one.
(cf-check-prog 'MY_CC '("cc" "gcc" "tcc" "pcc"))
If multiple program names is given, the search is done in the following
order: First, we search for the first item (cc
, in the above
example) for each of paths, then the second, etc. For example,
if we have /usr/local/bin:/usr/bin:/bin
in PATH
and
we have /usr/local/bin/tcc
and /usr/bin/gcc
, the above
feature test sets MY_CC
to "gcc"
. If you use cf-path-prog
instead, MY_CC
gets "/usr/bin/gcc"
.
If no program is found, sym is set to the keyword argument default if it is given, otherwise sym is left unset.
If the value keyword argument is given, its value is used instead of the found program name to be set to sym.
The list of search paths is taken from PATH
environment
variable. You can override the list by the paths keyword
argument, which must be a list of directory names. It may contain
nonexistent directory names, which are silently skipped.
The filter keyword argument, if given, must be a predicate
that takes full pathname of the executable program. It is called
when the procedure finds matching executable; the filter procedure
may reject it by returning #f
, in which case the procedure
keeps searching.
Note: If the substitution parameter sym is already set
at the time these procedure is called, these procedures do nothing.
Combined with cf-arg-var
, it allows the configure script caller
to override the feature test. For example, suppose you have the
following in the configure
script:
(cf-arg-var 'GREP) (cf-path-prog 'GREP '("egrep" "fgrep" "grep"))
A user can override the test by calling configure
like this:
$ ./configure GREP=mygrep
{gauche.configure
}
A convenience feature test to find C++ compiler. This searches
popular names of C++ compilers from the search paths, sets the
substitution parameter CXX
to the compiler’s name,
then tries to compile a small
program with it to see it can generate an executable.
This corresponds to autoconf’s AC_PROG_CXX
.
CXX
is cf-arg-var
’ed in this procedure. If a user
provide the value when he calls configure
, the searching
is skipped, but the check of generating an executable is still
performed.
If the substitution parameter CXXFLAGS
is set, its value
is used to check if the compiler can generate an executable.
CXXFLAGS
is cf-arg-var
’ed in this procedure.
This procedure also emulates autoconf’s AC_PROG_CXX
behavior—
if CXX
is not set, but CCC
is set, then we set
CXX
by the value of CCC
and skip searching.
{gauche.configure
}
Check if a header file header exists and usable, by
compiling a source program of the current language
that includes the named header file.
Return #t
if the header is usable, #f
if not.
Both procedure does the same thing. The name cf-check-header
corresponds to autoconf’s AC_CHECK_HEADER
.
If header requires other headers being included or
preprocessor symbols defined before it,
you can pass a list of strings to be emitted before the check
in the includes keyword arguments. The given strings
are just concatenated and used as a C program fragment.
The default value is provided by cf-includes-default
.
The following example sets C preprocessor symbol HAVE_CRYPT_H
to
1 if crypt.h is available. (Note: For this kind of common task,
you can use cf-check-headers
below. The advantage of using
cf-check-header
is that you can write other actions in Scheme
depending on the result.)
(when (cf-check-header "crypt.h") (cf-define "HAVE_CRYPT_H" 1))
{gauche.configure
}
Codify a common pattern of checking the availability of headers and
sets C preprocessor definitions.
This corresponds to autoconf’s AC_CHECK_HEADERS
.
This procedure is invoked for the side effects,
and returns an undefined vlaue.
See this example:
(cf-check-headers '("unistd.h" "stdint.h" "inttypes.h" "rpc/types.h"))
This checks availability of each of listed headers,
and sets C preprocessor definition HAVE_UNISTD_H
,
HAVE_STDINT_H
, HAVE_INTTYPES_H
and
HAVE_RPC_TYPES_H
to 1 if the corresponding header
file is available.
A list of strings given to includes are emitted to the
C source file before the inclusion of the testing header. You can
give necessary headers and/or C preprocessor definitions there;
if omitted, cf-includes-default
provides
the default list of such headers.
The keyword argument if-found and if-not-found are procedures to be called when a header is found to be available or to be unavailable, respectively. The procedure receives the name of the header.
The name of the C preprocessor definition is derived from the
header name by upcasing it and replacing non-alphanumeric characters
for _
. Note that this substitution is not injective:
Both gdbm/ndbm.h and gdbm-ndbm.h yield
GDBM_NDBM_H
. If you need to distinguish such files
you have to use cf-check-header
.
{gauche.configure
}
Returns a list of strings that are included in the check program by
default. It is actually a combination of C preprocessor #ifdef
s
and #include
s, and would probably be better to be called
cf-prologue-default
or something, but the corresponding
autoconf macro is AC_INCLUDES_DEFAULT
so we stick to this name.
Usually you don’t need to call this explicitly. Not giving the
includes
argument to cf-check-header
and
cf-check-headers
will make cf-includes-default
called implicitly.
{gauche.configure
}
Test if type is defined as a type name.
Return #t
if type is defined, #f
otherwise.
Two procedures are the same. The name cf-check-type
corresponds to AC_CHECK_TYPE
.
A list of strings given to includes are emitted to the
C source file before the inclusion of the testing header. You can
give necessary headers and/or C preprocessor definitions there;
if omitted, cf-includes-default
provides
the default list of such headers.
{gauche.configure
}
For each type in the list types, call cf-check-type
to
see it is defined as a type. If it is,
defines HAVE_type
, and calls if-found with the
type as an argument if provide. If the type is not defined and
if-not-found is provided, calls it with the type as an argument.
The argument includes is passed to cf-check-type
.
This corresponds to autoconf’s AC_CHECK_TYPES
.
Returns an undefiend value. This procedure is for side effects.
;; May define HAVE_PTRDIFF_T and/or HAVE_UNSIGNED_LONG_LONG_INT ;; depending on its availability: (cf-check-types '("ptrdiff_t" "unsigned long long int")) ;; Example of using includes to add an extra header. (cf-check-types '("float_t") :includes `(,@(cf-includes-default) "#include <math.h>\n"))
{gauche.configure
}
Test if symbol is declared as a cpp macro, a variable,
a constant, or a function.
Return #t
if type is defined,
#f
otherwise.
Two procedures are the same. The name cf-check-decl
corresponds
to autoconf’s AC_CHECK_DECL
.
A list of strings given to includes are emitted to the
C source file before the inclusion of the testing header. You can
give necessary headers and/or C preprocessor definitions there;
if omitted, cf-includes-default
provides
the default list of such headers.
{gauche.configure
}
For each symbol in symbols, call cf-check-decl
to see
if it is declared. If it is, define HAVE_DECL_symbol
to
1, and calls if-found with the symbol if provided.
If it is not declared, define HAVE_DECL_symbol
to 0,
and calls if-not-found with the symbol if provided.
This corresponds to autoconf’s AC_CHECK_DECLS
.
The argument includes is passed to cf-check-decl
.
This procedure returns an undefined value. This procedure is for side effects.
Note that, unlike other cf-check-*
routines which leave
HAVE_*
macro undefined when the item isn’t found, this one
always defines the macro and differentiate the result with its value.
This behavior is the same as AC_CHECK_DECLS
.
{gauche.configure
}
The aggregate.member argument is a string of aggregate type name
and its member concatenated by a dot, e.g. "struct password.pw_gecos"
.
It can also be a submember, e.g. "struct foo.bar.baz"
.
The aggregate part can be any type name (typedef-ed name is ok).
This test checks if member is a member of aggregate, and
returns #t
if so, or returns #f
if not.
Two procedures are the same. The name cf-check-member
corresponds to autoconf’s AC_CHECK_MEMBER
.
A list of strings given to includes are emitted to the
C source file before the inclusion of the testing header. You can
give necessary headers and/or C preprocessor definitions there;
if omitted, cf-includes-default
provides
the default list of such headers.
{gauche.configure
}
For each aggregate.member
in members, call cf-check-member
.
If the test passes, defines HAVE_aggregate_member
,
and calls if-found with aggregate.member if provided.
If the test fails, calls if-not-found with aggregate.member
if provided.
This corresponds to autoconf’s AC_CHECK_MEMBERS
.
The include argument is passed to cf-check-member
.
;; Defines HAVE_STRUCT_ST_RDEV and/or HAVE_STRUCT_ST_BLKSIZE ;; depending on their availability: (cf-check-members '("struct stat.st_rdev" "struct stat.st_blksize"))
This procedure is for side effects, and returns an undefined value.
{gauche.configure
}
See if a function func is available. This emits C code
to call func (with dummy declaration) and tries to compile and link,
using current value of substitution parameter LIBS
.
The value of cf-includes-default
is at the top of the emitted C code.
They return #t
if func is available, #f
otherwise.
Two procedures are the same. The name cf-check-func
corresponds to autoconf’s AC_CHECK_FUNC
.
{gauche.configure
}
For each function name func in funcs, call cf-check-func
to determine availability. If it is available, define
HAVE_func
, and calls if-found
with func
if provided. If it is not available, calls if-not-found
with func if provided.
This corresponds to autoconf’s AC_CHECK_FUNCS
.
This procedure is for side effects, and returns an undefined value.
{gauche.configure
}
See if a library lib can be linked and a function fn in it
is callable. Return #t
it is, #t
if not.
Two procedures are the same. The name cf-check-lib
corresponds to autoconf’s AC_CHECK_LIB
.
Give the name you pass after -l
option to lib;
for example, if you want to check availability of libm
, you can
say as follows:
(cf-check-lib "m" "sin")
This generates a C source that calls fn and try to compile and link it to generate executable. If linking lib requires additional libraries, it should be listed in other-libs:
(cf-check-lib "Xt" "XtDisplay" :other-libs '("-lX11" "-lSM" "-lICE"))
If compilation and linking succeeds,
if-found is called at the
tail position with
the library name ("m"
and "Xt"
in the above examples,
respectively) as the argument.
The default behavior is to add
-llib
in the left of substitution parameter LIBS
,
and set HAVE_LIBlib
definition, then
returns #t
.
If compilation or linking fails, if-not-found is called at
the tail position with the library name. The default behavior is
to return #f
.
The default behavior of if-found and if-not-found allows
cf-check-lib
to be used as predicate as well. If you merery
want to take an action depending on whether the library is found or
not, you can write like this:
(unless (cf-check-lib "foo" "foo_fn) ... do something if libfoo isn't available ...)
Use if-found and/or if-not-found only if you want to override the default behaviors.
{gauche.configure
}
Like cf-check-lib
, but can be used if you’re not sure which
library contains desired function.
This corresponds to autoconf’s AC_SEARCH_LIBS
. Note that
this takes function name first, while cf-check-lib
takes
function name second—blame autoconf for this inconsistency.
First it tests if fn is available without any library in libs
(that is, with the ones already in LIBS
and specified in
other-libs). If not, it tests each library in libs
in turn.
If fn is found, if-found is called at the tail position,
with the name of
the library as an argument (if fn is available without any
library, the argument is #f
). If omitted, and a library
is required, then the library is
added to the substitution parameter LIBS
.
The default procedure returns #t
.
If fn isn’t found in any of the libraries, if-not-found
is called at the tail position
with #f
as the argument. The default procedure
does nothing and just returns #f
.
The default behavior of if-found and if-not-found allows
cf-search-libs
to be used as predicate as well. If you give
alternative procedures, keep in mind that their return value
will be returned to cf-search-libs
.
{gauche.configure
}
This corresponds to autoconf’s AC_PATH_X
. It checks if
X11 is available, and returns three values.
The first value is a boolean value indicates if X11 is available. The second and third values are strings for the directory name to find X11 headers and libraries, respectively. The second and third value can be empty strings if the compiler doesn’t need additional flags to find X11 stuff.
This does not set other substituion parameters.
You typically want to use cf-path-xtra
below instead.
(In autoconf, AC_PATH_X
sets shell variables to tell
the results. In Scheme, it is more natural to use return
values.)
{gauche.configure
}
Check X11 availability with cf-path-x
above, and
sets up the following substitution parameters:
X_CFLAGS
Additional CFLAGS needed to build with X11.
X_PRE_LIBS
Additional library link flags (-llib …
)
that need to come before -lX11
flag.
X_LIBS
Additional library search flags (-Ldir …
)
to link with X11. (Note: The name is for the compatibility
with autoconf. It should really be named as X_LDFLAGS
.)
X_EXTRA_LIBS
Additional library search flags (-Ldir …
)
to link with X11. Those libraries should come after -lX11
flag.
This procedure corresponds to autoconf’s AC_PATH_XTRA
.
Note that -lX11
is not included in those parameters;
they must be specified explicitly.
If X11 is not available, those parameters get empty strings.
The gauche.configure
module provides a generic mechanism
to construct a small test program, compile it, and run it.
Currently we only support C
and C++
; we’ll add support
for other languages as needed.
{gauche.configure
}
Returns a current language, which is an opaque object.
Currently C and C++ are supported; see cf-lang-C
and
cf-lang-C++
below.
The current language is used by compiler tests.
{gauche.configure
}
Returns an opaque object representing C or C++, respectively.
You can use them to parameterize cf-lang
to run
compiler tests.
(parameterize ([cf-lang (cf-lang-C++)]) ... run compiler tests ...)
{gauche.configure
}
Returns a string tree that consists a stand-alone program for
the current language. Prologue and body must be a
string or a list of strings. If it is a list, strings are
concatenated with newlines.
Prologue comes at the beginning of
the source, and body is included in the part of the program
that’s executed. If the current language is C, the code fragment:
(use text.tree) (write-tree (cf-lang-program '("#include <stdio.h>" "#include <stdlib.h>") '("printf(\"()\");")))
would produce something like this:
#include <stdio.h> #include <stdlib.h> int main(){ printf("()"); ; return 0; }
{gauche.configure
}
This is a convenience routine. It returns a string tree
of a program in the current language, that creates a file
named conftest.out, then exits with zero status on
success, or nonzero status on failure.
{gauche.configure
}
Returns a string tree of a program in the current language,
that calls func-name as a function with no arguments.
{gauche.configure
}
The arguments must be a string or a list of strings. If it is
a list, it is taken as a list of lines, concatenated with newlines.
This test generates a program with the given content,
using cf-lang-program
, then try to compile it.
On success, #t
is returned. On failure, #f
is returned.
The generated program, command line, and the result is logged.
{gauche.configure
}
The arguments must be a string or a list of strings. If it is
a list, it is taken as a list of lines, concatenated with newlines.
This test generates a program with the given content,
using cf-lang-program
, then try to compile and link it.
On success, #t
is returned. On failure, #f
is returned.
The generated program, command line, and the result is logged.
{gauche.configure
}
A convenience routine to produce typical output.
It does the following:
cf-make-gpd
.
VERSION
file that contains the value of
PACKAGE_VERSION
substitution parameter.
Makefile.in
’s under the source directory
(the value of substitution parameter srcdir
),
and process them to produce Makefile
’s.
If file … are given, file.in
are also
processed as well to produce file.
See cf-output
below for the details.
cf-config-headers
,
process them as well.
{gauche.configure
}
Generates file’s from the input templates.
This corresponds to autoconf’s AC_OUTPUT
.
For each file, a file named file.in is read
as a template. Within the file, @PARAMETER@
is substituted
with the value of (cf$ 'PARAMETER)
. If the named parameter
isn’t registered, a warning is issued and the parameter is left
unsubstituted.
If config headers are not registered via cf-config-headers
,
a substitution parameter DEFS
is replaced with
all the definitions in the form of -D...
. For example,
if you have checked header files foo/bar.h and
foo/baz.h, DEFS
gets the value
-DHAVE_FOO_BAR_H -DHAVE_FOO_BAZ_H
.
If config header is registered by cf-config-headers
,
they are processed as well. In such case, the substitution
parameter DEFS
gets the value -DHAVE_CONFIG_H
.
{gauche.configure
}
Sets up config header files to be processed. Usually a config header
file is named config.h, and contains definitions determined
by feature tests.
The header-or-headers argument may be a string header-spec
or a list of string header-specs, where each header spec is
a header file name (e.g. "config.h"
) or a header name
and a input file name concatenated with a colon
(e.g. "config.h:config.h.templ"
). If it’s just a header name,
input file name is assumed to be the header file name with ".in"
appended.
The input template of config header file contains a bunch of
#undef
directives, such as the following:
/* Gauche ABI version string */ #undef GAUCHE_ABI_VERSION /* Define if Gauche handles multi-byte character as EUC-JP */ #undef GAUCHE_CHAR_ENCODING_EUC_JP /* Define if Gauche handles multi-byte character as Shift JIS */ #undef GAUCHE_CHAR_ENCODING_SJIS /* Define if Gauche handles multi-byte character as UTF-8 */ #undef GAUCHE_CHAR_ENCODING_UTF_8
Once processed, the generated header file has either
#undef
line is replaced with #define
, or
commented out, depending on the definitions determined by feature
tests.
/* Gauche ABI version string */ #define GAUCHE_ABI_VERSION "0.97" /* Define if Gauche handles multi-byte character as EUC-JP */ /* #undef GAUCHE_CHAR_ENCODING_EUC_JP */ /* Define if Gauche handles multi-byte character as Shift JIS */ /* #undef GAUCHE_CHAR_ENCODING_SJIS */ /* Define if Gauche handles multi-byte character as UTF-8 */ #define GAUCHE_CHAR_ENCODING_UTF_8 /**/
Note that the lines other than #undef
are copied as they are.
The substitution parameter DEFS
behaves differently whether
config header is specified or not. If no config header is registered,
The value of DEFS
is a C command-line arguments for definitions,
e.g. -DGAUCHE_ABI_VERSION=0.97 -DGAUCHE_CHAR_ENCODING_UTF8
.
If config header files are registered, the value of DEFS
becomes
simply -DHAVE_CONFIG_H
.
{gauche.configure
}
Print all substitution parameters; this is for debugging.
For each substitution parameter name and value,
formatter is called with them; the default is
(^[k v] (format #t "~16s ~s" k v))
.
{gauche.configure
}
Generate gpd (Gauche package description) file,
PACKAGE_NAME.gpd, where PACKAGE_NAME
is the
package’s name either taken form package.scm or
the argument to cf-init
.
See gauche.package
- Package metainformation, for the package description file format.