This module implements the build system that is used by pack_install/1
and pack_rebuild/1. The build system is a plugin based system where each
plugin knows about a specific build toolchain. The plugins recognise
whether they are applicable based on the existence of files that are
unique to the toolchain. Currently it supports
- conan for the installation of dependencies
- cmake for configuration and building
- GNU tools including
automake
and autoconf
for configuration and building
build_steps(+Steps:list, SrcDir:atom, +Options) is det- Run the desired build steps. Normally, Steps is the list below,
optionally prefixed with
distclean
or clean
. [test]
may be
omited if --no-test
is effective.
[[dependencies], [configure], build, [test], install]
Each step finds an applicable toolchain based on known unique files
and calls the matching plugin to perform the step. A step may fail,
which causes the system to try an alternative. A step that wants to
abort the build process must throw an exception.
If a step fails, a warning message is printed. The message can be
suppressed by enclosing the step in square brackets. Thus, in the
above example of Steps, only failure by the build
and install
steps result in warning messages; failure of the other steps is
silent.
The failure of a step can be made into an error by enclosing it
in curly brackets, e.g. [[dependencies], [configure], {build}, [test], {install}]
would throw an exception if either the build
or install
step failed.
Options are:
- pack_version(N)
- where N is 1 or 2 (default: 1).
This determines the form of environment names that are set before
the build tools are calledd.
For version 1, names such as SWIPLVERSION or SWIHOME are used.
For version 2, names such as SWIPL_VERSION or SWIPL_HOME_DIR are used.
@tbd If no tool is willing to execute some step, the step is
skipped. This is ok for some steps such as dependencies
or test
.
Possibly we should force the install
step to succeed?
post_step(+Step, +State) is det[private]- Run code after completion of a step.
ensure_build_dir(+Dir, +State0, -State) is det- Create the build directory. Dir is normally either '.' to build in
the source directory or
build
to create a build
subdir.
build_environment(-Env, +Options) is det[private]- Options are documented under build_steps/3.
Assemble a clean build environment for creating extensions to
SWI-Prolog. Env is a list of Var=Value
pairs. The variable names
depend on the pack_version(Version)
term from pack.pl
. When
absent or 1
, the old names are used. These names are confusing and
conflict with some build environments. Using 2
(or later), the new
names are used. The list below first names the new name and than
between parenthesis, the old name. Provided variables are:
PATH
-
contains the environment path with the directory
holding the currently running SWI-Prolog instance prepended
in front of it. As a result,
swipl
is always present and
runs the same SWI-Prolog instance as the current Prolog process.
SWIPL
-
contains the absolute file name of the running executable.
SWIPL_PACK_VERSION
-
Version of the pack system (1 or 2)
SWIPL_VERSION
(SWIPLVERSION
)-
contains the numeric SWI-Prolog version defined as
Major*10000+Minor*100+Patch.
SWIPL_HOME_DIR
(SWIHOME
)-
contains the directory holding the SWI-Prolog home.
SWIPL_ARCH
(SWIARCH
)-
contains the machine architecture identifier.
SWIPL_MODULE_DIR
(PACKSODIR
)-
constains the destination directory for shared objects/DLLs
relative to a Prolog pack, i.e.,
lib/$SWIARCH
.
SWIPL_MODULE_LIB
(SWISOLIB
)-
The SWI-Prolog library or an empty string when it is not required
to link modules against this library (e.g., ELF systems)
SWIPL_LIB
(SWILIB
)-
The SWI-Prolog library we need to link to for programs that
embed SWI-Prolog (normally
-lswipl
).
SWIPL_INCLUDE_DIRS
-
CMake style variable that contains the directory holding
SWI-Prolog.h
, SWI-Stream.h
and SWI-cpp.h
.
SWIPL_LIBRARIES_DIR
-
CMake style variable that contains the directory holding
libswipl
SWIPL_CC
(CC
)-
Prefered C compiler
SWIPL_CXX
(CXX
)-
Prefered C++ compiler
SWIPL_LD
(LD
)-
Prefered linker
SWIPL_CFLAGS
(CFLAGS
)-
C-Flags for building extensions. Always contains
-ISWIPL-INCLUDE-DIR
.
SWIPL_MODULE_LDFLAGS
(LDSOFLAGS
)-
Link flags for linking modules.
SWIPL_MODULE_EXT
(SOEXT
)-
File name extension for modules (e.g.,
so
or dll
)
SWIPL_PREFIX
(PREFIX
)-
Install prefix for global binaries, libraries and include files.
- prolog:build_environment(-Name, -Value) is nondet[multifile]
- Hook to define the environment for building packs. This
Multifile hook extends the process environment for building
foreign extensions. A value provided by this hook overrules
defaults provided by def_environment/3. In addition to changing
the environment, this may be used to pass additional values to
the environment, as in:
prolog:build_environment('USER', User) :-
getenv('USER', User).
- Arguments:
-
Name | - is an atom denoting a valid variable name |
Value | - is either an atom or number representing the
value of the variable. |
def_environment(-Name, -Value, +Options) is nondet[private]- True if Name=Value must appear in the environment for building
foreign extensions.
prolog_library_dir(-Dir) is det[private]- True when Dir is the directory holding
libswipl.$SOEXT
default_c_compiler(-CC) is semidet[private]- Try to find a suitable C compiler for compiling packages with
foreign code.
- To be done
- - Needs proper defaults for Windows. Find MinGW? Find MSVC?
save_build_environment(+State:dict) is det[private]- Create a shell-script
buildenv.sh
that contains the build
environment. This may be sourced in the build directory to run the
build steps outside Prolog. It may also be useful for debugging
purposes.
prolog_install_prefix(-Prefix) is semidet- Return the directory that can be passed into
configure
or cmake
to install executables and other related resources in a similar
location as SWI-Prolog itself. Tries these rules:
- If the Prolog flag
pack_prefix
at a writable directory, use
this.
- If the current executable can be found on $PATH and the parent
of the directory of the executable is writable, use this.
- If the user has a writable
~/bin
directory, use ~
.
run_process(+Executable, +Argv, +Options) is det- Run Executable. Defined options:
- directory(+Dir)
- Execute in the given directory
- output(-Out)
- Unify Out with a list of codes representing stdout of the
command. Otherwise the output is handed to print_message/2
with level
informational
.
- error(-Error)
- As
output(Out)
, but messages are printed at level error
.
- env(+Environment)
- Environment passed to the new process.
If Executable is path(Program)
and we have an environment we make
sure to use the PATH
from this environment for searching
Program.
has_program(+Spec) is semidet[private]
has_program(+Spec, -Path) is semidet[private]
has_program(+Spec, -Path, +Env:list) is semidet[private]- True when the OS has the program Spec at the absolute file location
Path. Normally called as e.g.
has_program(path(cmake), CMakeExe)
.
The second allows passing in an environment as Name=Value pairs. If
this contains a value for PATH
, this is used rather than the
current path variable.
setup_path(+Programs) is det[private]- Deals with specific platforms to add specific directories to
$PATH
such that we can find the tools. Currently deals with
MinGW on Windows to provide make
and gcc
.
mingw_extend_path is semidet[private]- Check that gcc.exe is on
%PATH%
and if not, try to extend the
search path.
process_output(+Codes)//[private]- Emit process output using print_message/2. This preserves line
breaks.
Undocumented predicates
The following predicates are exported, but not or incorrectly documented.
has_program(Arg1, Arg2, Arg3)