• Places
    • Home
    • Graphs
    • Prefixes
  • Admin
    • Users
    • Settings
    • Plugins
    • Statistics
  • CPACK
    • Home
    • List packs
    • Submit pack
  • Repository
    • Load local file
    • Load from HTTP
    • Load from library
    • Remove triples
    • Clear repository
  • Query
    • YASGUI SPARQL Editor
    • Simple Form
    • SWISH Prolog shell
  • Help
    • Documentation
    • Tutorial
    • Roadmap
    • HTTP Services
  • Login

15.5 Developing a pack
All Application Manual Name SummaryHelp

  • Documentation
    • Reference manual
      • Packs: community add-ons
        • Developing a pack
          • The pack meta data
          • Packs with foreign code
            • Compiling a foreign extension using a simple Makefile
            • Publishing a pack
            • Compiling a foreign extension using CMake
          • Updating a package
    • Packages

15.5.2 Packs with foreign code

Many packs include C or C++ resources. Such packs include the C or C++ resources in a subdirectory of the pack. There are no restrictions for naming this subdirectory or structuring the source files in this directory. The build process must create native modules in the directory lib/<arch>, where <arch> is the architecture as obtained by the Prolog flag arch.

The build process identifies control files that tell the package manager which build tool to use. The package manager populates the process environment with variables that provide details about the running Prolog instance. This environment is saved in a file buildenv.sh in the pack root or build directory. By sourcing this file, the user may run the build tools by hand for debugging purposes.

The build process consists of five steps that are described below

dependencies
This step currently only supports conan. It is executed if either conanfile.txt or conanfile.py is found in the root directory of the pack.
configure
This preparation step is executed if one of CMakeLists.txt (cmake), configure, configure.in (autoconf), configure.ac or Makefile.am (automake) are found. The program to manage them is in parenthesis.
build
Build the process. When configured using (cmake) this will use (cmake). Otherwise either Makefile or makefile is expected and Unix make is used to build the process.
test
Test the project. Either uses cmake or the GNU convention make check.
install
Install the project. Either uses cmake or the GNU convention make install.

While running the above tools, the environment is populated. The names of the variables provided depends on the pack_version(Version) metadata. We give the names for version 2, with the names for version 1 in parenthesis if this differs from the version 2 name.

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). If not present we must assume‘1’.
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-cpp2.h.
SWIPL_LIBRARIES_DIR
CMake style variable that contains the directory holding libswipl
SWIPL_CC (CC)
C compiler used to build SWI-Prolog.
SWIPL_CXX (CXX)
C++ compiler used to build SWI-Prolog.
SWIPL_LD (LD)
Linker used to link SWI-Prolog.
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.

15.5.2.1 Compiling a foreign extension using a simple Makefile

If the package requires some C code to be compiled that has no dependencies and needs no configuration it is probably easiest to use a simple Unix make file. We assume pack_version(2). Here is a simple Makefile. We assume the pack contains a file c/environ.c that contains the C source. Following the GNU guidelines, the Makefile must define the following targets:

all (default)
Build the foreign extension. In this very simple case we build the resulting module directly in the target directory.
check
Test the package. This is executed after the default build target.
install
Install the package. In this case this does nothing.
clean
Clean the package. This target disposes intermediate build products.
distclean
Restore the package to its fully clean state. This implies that all built products and intermediate build products are removed. The distclean target is used by pack_rebuild/1.
MODULE= $(SWIPL_MODULE_DIR)/environ.$(SOEXT)
CFLAGS= $(SWIPL_CFLAGS)

all:    $(MODULE)

OBJ=c/environ.o

$(MODULE): $(OBJ)
        mkdir -p $(SWIPL_MODULE_DIR)
        $(SWIPL_LD) $(SWIPL_MODULE_LDFLAGS) -o $@ $(OBJ) $(SWIPL_MODULE_LIB)

check::
        $(SWIPL) -g run_tests -t halt test/test_environ.pl
install::
clean:
        rm -f $(OBJ)
distclean: clean
        rm -f $(MODULE)

15.5.2.2 Publishing a pack

As described in section 15.4, a pack is distributed either as an archive file or as a GIT repository. We strongly encourage using a GIT repository as that gives good version and provenance support. Packs may be published by hand by making the archive or git repository available from a globally accessible place on the internet and installing the pack from this location. This process is streamlined, notably for GIT packs using pack_publish/2 and the app pack. To publish a pack a local GIT repository that has publicly accessible origin,

  1. Update version(Version) in pack.pl
  2. Commit all changes, make sure the the repository is clean.
  3. Run
    swipl pack publish .

This will

  1. Verify the repository is clean and on the default branch.
  2. Tag the repository with V<version>. By default, the tag will be signed. Please setup signing for GIT or use the “--no-sign`` option.
  3. Push the repository and release tag.
  4. Figure out the download location, either from the download(URL) metadata or the GIT remote information.
  5. Install the package and its dependencies in a temporary isolated pack environment.
  6. On success, register the pack with the server.
  7. Delete the isolated pack environment.

Similarly, a pack can be published from a public archive using the command below. When using an archive, never change the content of the archive but, instead, create a new archive with a new version.

swipl pack publish URL

15.5.2.3 Compiling a foreign extension using CMake

If the package is more complicated, a simple Makefile typically does not suffice. In this case we have two options. One is to use the GNU autoconf or automake. However, cmake is getting more popular and provides much better support for non-POSIX platforms, e.g., Windows. This section discusses building the same package as section 15.5.2.1 using cmake.

To use cmake, add the content below as the file CMakeLists.txt to the root directory of the pack. SWI-Prolog ships with a cmake include file named swipl.cmake that deals with most of the configuration issues. Comments in the file below explain the various steps of the process.

cmake_minimum_required(VERSION 3.5)
project(swipl-pack-environ)

# Include swipl.cmake from the running SWI-Prolog's home
list(INSERT CMAKE_MODULE_PATH 0 $ENV{SWIPL_HOME_DIR}/cmake)
include(swipl)

# Create the library as a CMake module
add_library(environ MODULE c/environ.c)

# Link the library to SWI-Prolog.  This also removes the `lib` prefix
# from the target on systems that define a common library file prefix
target_link_swipl(environ)

# Install the foreign taget. `${swipl_module_dir}` contains the
# directory for installing modules for this architecture.

install(TARGETS environ
        DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/${swipl_module_dir})

# Run  tests.  This  is  executed   before    the   pack  is  installed.
# swipl_test(name) runs Prolog with the command line below.
#
#    swipl -p foreign=${CMAKE_CURRENT_SOURCE_DIR}/${swipl_module_dir} \
#          -p library=${CMAKE_CURRENT_SOURCE_DIR}/prolog \
#          --on-error=status \
#          -g test_${name} \
#          -t halt \
#          ${CMAKE_CURRENT_SOURCE_DIR}/test/test_${name}.pl
#
# This  implies  that  a  test  `name`  must    be  defined  in  a  file
# `test/test_${name}.pl`, which exports a  predicate `test_${name}`. The
# test succeeds if this predicate  succeeds   and  no error messages are
# printed.

enable_testing()
swipl_add_test(environ)

ClioPatria (version V3.1.1-51-ga0b30a5)