Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
2734 lines (2468 sloc) 90.9 KB
# Generate autoconf files for project
#
# This is a code generator built using the iMatix GSL code generation
# language. See https://github.com/zeromq/gsl for details.
#
# Copyright (c) the Contributors as noted in the AUTHORS file.
# This file is part of zproject.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
register_target ("autotools", "GNU build system")
.macro generate_autoconf_files
.output "autogen.sh"
#!/usr/bin/env sh
$(project.GENERATED_WARNING_HEADER:)
# Script to generate all required files from fresh git checkout.
if [ ! -f src/Makemodule-local.am ] ; then
echo "autogen.sh: generating a dummy src/Makemodule-local.am to fulfill dependencies." 1>&2
touch src/Makemodule-local.am
fi
# Debian and Ubuntu do not shipt libtool anymore, but OSX does not ship libtoolize.
command -v libtoolize >/dev/null 2>&1
if [ $? -ne 0 ]; then
command -v libtool >/dev/null 2>&1
if [ $? -ne 0 ]; then
echo "autogen.sh: error: could not find libtool. libtool is required to run autogen.sh." 1>&2
exit 1
fi
fi
command -v autoreconf >/dev/null 2>&1
if [ $? -ne 0 ]; then
echo "autogen.sh: error: could not find autoreconf. autoconf and automake are required to run autogen.sh." 1>&2
exit 1
fi
command -v pkg-config >/dev/null 2>&1
if [ $? -ne 0 ]; then
echo "autogen.sh: error: could not find pkg-config. pkg-config is required to run autogen.sh." 1>&2
exit 1
fi
mkdir -p ./config
if [ $? -ne 0 ]; then
echo "autogen.sh: error: could not create directory: ./config." 1>&2
exit 1
fi
autoreconf --install --force --verbose -I config
status=$?
if [ $status -ne 0 ]; then
echo "autogen.sh: error: autoreconf exited with status $status" 1>&2
exit 1
fi
$(project.GENERATED_WARNING_HEADER:)
.chmod_x ("autogen.sh")
.if file.exists ("version.sh")
. echo "WARNING: Your workspace has a 'version.sh' - note that zproject no longer generates this, and its presence may confuse your builds; you may want to remove it (or bump manually for project version '$(project->version.major).$(project->version.minor).$(project->version.patch)')"
.endif
.# Generate infrastructure for services
.# This need to be done prior to configure.ac, otherwise service files
.# will not be listed in AC_CONFIG_FILES directive
.for project.main where ( defined(main.service) & main.service > 0 )
.if ( main.service ?= 1 | main.service ?= 3 )
. if !file.exists ("src/$(main.name).service.in")
. output "src/$(main.name).service.in"
# This is a skeleton created by zproject.
# You can add hand-written code here.
[Unit]
Description=$(main.name) service
After=network.target
# Requires=network.target
# Conflicts=shutdown.target
# PartOf=$(project.name).target
[Service]
Type=simple
# User=@uid@
Environment="prefix=@prefix@"
Environment='SYSTEMD_UNIT_FULLNAME=%n'
. if ( !defined(main.no_config) | main.no_config ?= 0 )
ExecStart=@prefix@/bin/$(main.name) @sysconfdir@/@PACKAGE@/$(main.name).cfg
. else
ExecStart=@prefix@/bin/$(main.name)
. endif
Restart=always
[Install]
WantedBy=multi-user.target
# WantedBy=$(project.name).target
. close
. else
. echo "NOT regenerating an existing src/$(main.name).service.in file; you might want to move yours out of the way and re-generate the project again to get updated settings"
. endif
.endif
.if ( main.service ?= 2 | main.service ?= 3 )
. if !file.exists ("src/$(main.name)@.service.in")
. output "src/$(main.name)@.service.in"
# This is a skeleton created by zproject.
# You can add hand-written code here.
[Unit]
Description=$(main.name) service for %I
After=network.target
# Requires=network.target
# Conflicts=shutdown.target
# PartOf=$(project.name).target
[Service]
Type=simple
# User=@uid@
Environment="prefix=@prefix@"
Environment='SYSTEMD_UNIT_FULLNAME=%n'
. if ( !defined(main.no_config) | main.no_config ?= 0 )
ExecStart=@prefix@/bin/$(main.name) @sysconfdir@/@PACKAGE@/$(main.name)@%i.cfg
. else
ExecStart=@prefix@/bin/$(main.name) %i
. endif
Restart=always
[Install]
WantedBy=multi-user.target
# WantedBy=$(project.name).target
. close
. else
. echo "NOT regenerating an existing src/$(main.name)@.service.in file; you might want to move yours out of the way and re-generate the project again to get updated settings"
. endif
.endif
.endfor
.#
.#
.#
.# Prepare timer units, assuming they restart the corresponding service units
.for project.main where ( defined(main.timer) & main.timer > 0 )
.if ( main.timer ?= 1 | main.timer ?= 3 )
. if !file.exists ("src/$(main.name).timer.in")
. output "src/$(main.name).timer.in"
# This is a skeleton created by zproject.
# You can add hand-written code here.
[Unit]
Description=Timer to regularly trigger the job done by $(main.name) service
PartOf=timers.target
# PartOf=multi-user.target
# PartOf=$(project.name).target
[Timer]
# Time to wait after booting before we run first time
OnBootSec=30
# Regular re-runs
OnUnitActiveSec=1min
### Run every night
OnCalendar=*-*-* 04:20:00
# Run instantly if last run was skipped (e.g. system powered off)
Persistent=true
# Do not record last-execution times
Persistent=false
# Which unit to trigger (defaults to same basename):
Unit=$(main.name).service
[Install]
WantedBy=timers.target
# WantedBy=multi-user.target
# WantedBy=$(project.name).target
. close
. else
. echo "NOT regenerating an existing src/$(main.name).timer.in file; you might want to move yours out of the way and re-generate the project again to get updated settings"
. endif
.endif
.#
.#
.#
.if ( main.timer ?= 2 | main.timer ?= 3 )
. if !file.exists ("src/$(main.name)@.timer.in")
. output "src/$(main.name)@.timer.in"
# This is a skeleton created by zproject.
# You can add hand-written code here.
[Unit]
Description=Timer to regularly trigger the job done by $(main.name) service for %I
PartOf=timers.target
# PartOf=multi-user.target
# PartOf=$(project.name).target
[Timer]
# Time to wait after booting before we run first time
OnBootSec=30
# Regular re-runs
OnUnitActiveSec=1min
### Run every night
OnCalendar=*-*-* 04:20:00
# Run instantly if last run was skipped (e.g. system powered off)
Persistent=true
# Do not record last-execution times
Persistent=false
# Which unit to trigger (defaults to same basename):
Unit=$(main.name)@%i.service
[Install]
WantedBy=timers.target
# WantedBy=multi-user.target
# WantedBy=$(project.name).target
. close
. else
. echo "NOT regenerating an existing src/$(main.name)@.timer.in file; you might want to move yours out of the way and re-generate the project again to get updated settings"
. endif
.endif
.endfor
.#
.#
.#
.# Generate services for non-main (accompanying bins)
.for project.bin where ( defined(bin.service) & bin.service > 0 )
.if ( bin.service ?= 1 | bin.service ?= 3 )
. if !file.exists ("src/$(bin.name).service.in")
. output "src/$(bin.name).service.in"
# This is a skeleton created by zproject.
# You can add hand-written code here.
[Unit]
Description=$(bin.name) service
After=network.target
# Requires=network.target
# Conflicts=shutdown.target
# PartOf=$(project.name).target
[Service]
Type=simple
# User=@uid@
Environment="prefix=@prefix@"
Environment='SYSTEMD_UNIT_FULLNAME=%n'
. if ( !defined(bin.no_config) | bin.no_config ?= 0 )
ExecStart=@prefix@/bin/$(bin.name) @sysconfdir@/@PACKAGE@/$(bin.name).cfg
. else
ExecStart=@prefix@/bin/$(bin.name)
. endif
Restart=always
[Install]
WantedBy=multi-user.target
# WantedBy=$(project.name).target
. close
. else
. echo "NOT regenerating an existing src/$(bin.name).service.in file; you might want to move yours out of the way and re-generate the project again to get updated settings"
. endif
.endif
.#
.#
.#
.if ( bin.service ?= 2 | bin.service ?= 3 )
. if !file.exists ("src/$(bin.name)@.service.in")
. output "src/$(bin.name)@.service.in"
# This is a skeleton created by zproject.
# You can add hand-written code here.
[Unit]
Description=$(bin.name) service for %I
After=network.target
# Requires=network.target
# Conflicts=shutdown.target
# PartOf=$(project.name).target
[Service]
Type=simple
# User=@uid@
Environment="prefix=@prefix@"
Environment='SYSTEMD_UNIT_FULLNAME=%n'
. if ( !defined(bin.no_config) | bin.no_config ?= 0 )
ExecStart=@prefix@/bin/$(bin.name) @sysconfdir@/@PACKAGE@/$(bin.name)@%i.cfg
. else
ExecStart=@prefix@/bin/$(bin.name) %i
. endif
Restart=always
[Install]
WantedBy=multi-user.target
# WantedBy=$(project.name).target
. close
. else
. echo "NOT regenerating an existing src/$(bin.name)@.service.in file; you might want to move yours out of the way and re-generate the project again to get updated settings"
. endif
.endif
.endfor
.#
.#
.#
.# Prepare timer units, assuming they restart the corresponding service units
.for project.bin where ( defined(bin.timer) & bin.timer > 0 )
.if ( bin.timer ?= 1 | bin.timer ?= 3 )
. if !file.exists ("src/$(bin.name).timer.in")
. output "src/$(bin.name).timer.in"
# This is a skeleton created by zproject.
# You can add hand-written code here.
[Unit]
Description=Timer to regularly trigger the job done by $(bin.name) service
PartOf=timers.target
# PartOf=multi-user.target
# PartOf=$(project.name).target
[Timer]
# Time to wait after booting before we run first time
OnBootSec=30
# Regular re-runs
OnUnitActiveSec=1min
### Run every night
OnCalendar=*-*-* 04:20:00
# Run instantly if last run was skipped (e.g. system powered off)
Persistent=true
# Do not record last-execution times
Persistent=false
# Which unit to trigger (defaults to same basename):
Unit=$(bin.name).service
[Install]
WantedBy=timers.target
# WantedBy=multi-user.target
# WantedBy=$(project.name).target
. close
. else
. echo "NOT regenerating an existing src/$(bin.name).timer.in file; you might want to move yours out of the way and re-generate the project again to get updated settings"
. endif
.endif
.#
.#
.#
.if ( bin.timer ?= 2 | bin.timer ?= 3 )
. if !file.exists ("src/$(bin.name)@.timer.in")
. output "src/$(bin.name)@.timer.in"
# This is a skeleton created by zproject.
# You can add hand-written code here.
[Unit]
Description=Timer to regularly trigger the job done by $(bin.name) service for %I
PartOf=timers.target
# PartOf=multi-user.target
# PartOf=$(project.name).target
[Timer]
# Time to wait after booting before we run first time
OnBootSec=30
# Regular re-runs
OnUnitActiveSec=1min
### Run every night
OnCalendar=*-*-* 04:20:00
# Run instantly if last run was skipped (e.g. system powered off)
Persistent=true
# Do not record last-execution times
Persistent=false
# Which unit to trigger (defaults to same basename):
Unit=$(bin.name)@%i.service
[Install]
WantedBy=timers.target
# WantedBy=multi-user.target
# WantedBy=$(project.name).target
. close
. else
. echo "NOT regenerating an existing src/$(bin.name)@.timer.in file; you might want to move yours out of the way and re-generate the project again to get updated settings"
. endif
.endif
.endfor
.if !file.exists (".clang-format")
. output ".clang-format"
# This is a skeleton created by zproject.
# You can add hand-written code here.
BasedOnStyle: LLVM
IndentWidth: 4
UseTab: Never
BreakBeforeBraces: Custom
BraceWrapping:
AfterClass: true
AfterControlStatement: false
AfterEnum: true
AfterFunction: true
AfterNamespace: true
AfterObjCDeclaration: true
AfterStruct: true
AfterUnion: true
BeforeCatch: true
BeforeElse: false
IndentBraces: false
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AllowShortIfStatementsOnASingleLine: false
IndentCaseLabels: true
BinPackArguments: true
BinPackParameters: false
AlignTrailingComments: true
AllowShortBlocksOnASingleLine: false
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortFunctionsOnASingleLine: InlineOnly
AlwaysBreakTemplateDeclarations: false
ColumnLimit: 80
MaxEmptyLinesToKeep: 2
KeepEmptyLinesAtTheStartOfBlocks: false
ContinuationIndentWidth: 2
PointerAlignment: Right
ReflowComments: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: Always
SpaceInEmptyParentheses: false
SpacesInAngles: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
SortIncludes: false
FixNamespaceComments: false
BreakBeforeBinaryOperators: NonAssignment
SpaceAfterTemplateKeyword: true
AlignAfterOpenBracket: Align
AlignOperands: true
BreakConstructorInitializers: AfterColon
ConstructorInitializerAllOnOneLineOrOnePerLine: true
SpaceAfterCStyleCast: true
BreakBeforeTernaryOperators: true
.else
. echo "NOT regenerating an existing .clang-format file; you might want to move yours out of the way and re-generate the project again to get updated settings"
.endif
.output "configure.ac"
$(project.GENERATED_WARNING_HEADER:)
# Note: if your project needs a customized configure script (compared to
# the code below 100% generated by zproject), please check first if your
# use-case can be handled by acinclude.m4 support in zproject_autotools.gsl
# (to AC_DEFUN an AX_PROJECT_LOCAL_HOOK, AX_PROJECT_LOCAL_HOOK_CONFIGVARS
# and/or AX_PROJECT_LOCAL_HOOK_FINAL) so you can avoid changing this file
# which would complicate re-generation of your project in the future.
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.61)
#
AC_INIT([$(project.name)],[$(->version.major).$(->version.minor).$(->version.patch)],[$(project.email)])
AC_CONFIG_AUX_DIR(config)
AC_CONFIG_MACRO_DIR(config)
AC_CONFIG_HEADERS([src/platform.h])
AM_INIT_AUTOMAKE([subdir-objects tar-ustar dist-zip foreign])
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
# This defines PACKAGE_VERSION_... in src/platform.h
PV_MAJOR=`echo $PACKAGE_VERSION | cut -d . -f 1`
PV_MINOR=`echo $PACKAGE_VERSION | cut -d . -f 2`
PV_PATCH=`echo $PACKAGE_VERSION | cut -d . -f 3`
AC_DEFINE_UNQUOTED([PACKAGE_VERSION_MAJOR],[$PV_MAJOR],
[$(PROJECT.PREFIX) major version])
AC_DEFINE_UNQUOTED([PACKAGE_VERSION_MINOR],[$PV_MINOR],
[$(PROJECT.PREFIX) minor version])
AC_DEFINE_UNQUOTED([PACKAGE_VERSION_PATCH],[$PV_PATCH],
[$(PROJECT.PREFIX) patchlevel])
# This lets us use PACKAGE_VERSION in Makefiles
AC_SUBST(PACKAGE_VERSION)
#
# Libtool -version-info (ABI version)
#
.if defined (project->abi)
# Currently $(project->abi.current):$(project->abi.revision):$(project->abi.age) ("stable"). Don't change this unless you
.else
# Currently 0:0:0 ("stable"). Don't change this unless you
.endif
# know exactly what you're doing and have read and understand
# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
#
# $(project.libname) -version-info
.if defined (project->abi)
LTVER="$(project->abi.current):$(project->abi.revision):$(project->abi.age)"
.else
LTVER="0:0:0"
.endif
AC_SUBST(LTVER)
# building in a subdirectory?
AM_CONDITIONAL([USING_VPATH], [test "x${srcdir}" != "x."])
# Capture c flags
$(PROJECT.PREFIX)_ORIG_CFLAGS="${CFLAGS:-none}"
# Checks for programs
AC_PROG_CC
AC_PROG_CC_C99
AM_PROG_CC_C_O
.if project.use_cxx
AC_PROG_CXX
AC_PROG_CXX_C_O
.endif
AC_LIBTOOL_WIN32_DLL
AC_PROG_LIBTOOL
AC_PROG_SED
AC_PROG_AWK
PKG_PROG_PKG_CONFIG
# Check endianess of the system
AC_C_BIGENDIAN
.if file.exists ("acinclude.m4")
# Optional project-local hook (acinclude.m4, add AC_DEFUN([AX_PROJECT_LOCAL_HOOK], [whatever]) )
ifdef([AX_PROJECT_LOCAL_HOOK],
[AX_PROJECT_LOCAL_HOOK])
.endif
# See if cppcheck is in PATH; this variable unblocks the "cppcheck" recipe
# (note that "make cppcheck.xml" can be used - and perhaps fail - regardless)
AC_CHECK_PROG([WITH_CPPCHECK], [cppcheck], [true], [false])
AM_CONDITIONAL(WITH_CPPCHECK, $WITH_CPPCHECK)
# Code coverage
AC_MSG_CHECKING([whether to enable GCov])
AC_ARG_WITH(gcov, [AS_HELP_STRING([--with-gcov=yes/no],
[With GCC Code Coverage reporting])],
[$(PROJECT.PREFIX)_GCOV="$withval"])
if test "x${$(PROJECT.PREFIX)_GCOV}" == "xyes"; then
CFLAGS="-O0 -g -fprofile-arcs -ftest-coverage"
if test "x${$(PROJECT.PREFIX)_ORIG_CFLAGS}" != "xnone"; then
CFLAGS="${CFLAGS} ${$(PROJECT.PREFIX)_ORIG_CFLAGS}"
fi
AM_CONDITIONAL(WITH_GCOV, true)
AC_MSG_RESULT([yes])
else
AM_CONDITIONAL(WITH_GCOV, false)
AC_MSG_RESULT([no])
fi
# Memory mis-use detection
AC_MSG_CHECKING([whether to enable ASan])
AC_ARG_ENABLE(address-sanitizer, [AS_HELP_STRING([--enable-address-sanitizer=yes/no],
[Build with GCC Address Sanitizer instrumentation])],
[$(PROJECT.PREFIX)_ASAN="$enableval"])
if test "x${$(PROJECT.PREFIX)_ASAN}" == "xyes"; then
CFLAGS="${CFLAGS} -fsanitize=address"
CXXFLAGS="${CXXFLAGS} -fsanitize=address"
AM_CONDITIONAL(ENABLE_ASAN, true)
AC_MSG_RESULT([yes])
else
AM_CONDITIONAL(ENABLE_ASAN, false)
AC_MSG_RESULT([no])
fi
# See if clang-format is in PATH; the result unblocks the relevant recipes
WITH_CLANG_FORMAT=""
AS_IF([test x"$CLANG_FORMAT" = x],
[AC_PATH_PROG([CLANG_FORMAT], [clang-format], [])],
[AC_CHECK_PROG([WITH_CLANG_FORMAT], [$CLANG_FORMAT], [true], [fail])])
AS_IF([test x"$CLANG_FORMAT" != x && test x"$WITH_CLANG_FORMAT" = x],
[AS_IF([test -x "$CLANG_FORMAT"],
[WITH_CLANG_FORMAT=true],
[AC_CHECK_PROG([WITH_CLANG_FORMAT], [$CLANG_FORMAT], [true], [false])])])
AS_IF([test "$WITH_CLANG_FORMAT" = fail],
[AC_MSG_ERROR([Caller explicitly referenced CLANG_FORMAT=$CLANG_FORMAT which was not found])])
AM_CONDITIONAL([WITH_CLANG_FORMAT], [$WITH_CLANG_FORMAT])
# Set pkgconfigdir
AC_ARG_WITH([pkgconfigdir], AS_HELP_STRING([--with-pkgconfigdir=PATH],
[Path to the pkgconfig directory [[LIBDIR/pkgconfig]]]),
[pkgconfigdir="$withval"], [pkgconfigdir='${libdir}/pkgconfig'])
AC_SUBST([pkgconfigdir])
# Use the provided pkgconfigdir not only to write our pkg-config data,
# but also as an additional location to look for other packages metadata.
AS_IF([test -n "${pkgconfigdir}" -a -d "${pkgconfigdir}"],
[AS_IF([test -z "${PKG_CONFIG_PATH}"],
[PKG_CONFIG_PATH="${pkgconfigdir}"],
[PKG_CONFIG_PATH="${pkgconfigdir}:${PKG_CONFIG_PATH}"])
export PKG_CONFIG_PATH
])
# Will be used to add flags to pkg-config useful when apps want to statically link
PKGCFG_LIBS_PRIVATE=""
# Archive user supplied flags
PREVIOUS_CFLAGS="${CFLAGS}"
PREVIOUS_LIBS="${LIBS}"
.for use
.# Far below, if the dependency search was not for a library, it will be done
.# for a program.
.# Debugging for using either a list of variants or a single name per legacy
.# (or simpler use-case) setup. Note that despite the same apparent name for
.# addressing, the variable and list contexts are different and separate.
.# Far below, if the dependency search was not for a library, it will be done
.# for a program.
.###echo "PROJECT: $(use.project) : '$(use.libname)' '$(use.pkgconfig)' '$(count(use.pkgconfig))' '$(count(use.linkname))'"
. if use.libname ?<> "" | use.pkgconfig ?<> "" | count(use.pkgconfig) > 0 | count(use.linkname) > 0
was_$(use.project:c)_check_lib_detected=no
. if optional
search_$(use.libname:c)="no"
. else
search_$(use.libname:c)="yes"
. endif
.# TOTHINK: Should this still be libname or ...
.# (loop over variants of libname, projname, linkname, pkgconfig?..)
AC_ARG_WITH([$(use.libname)],
[
AS_HELP_STRING([--with-$(use.libname)],
.# TODO: Should an explicit path win over pkgconfig?
[yes or no. Optionally specify $(use.libname) prefix (directory where its include/ and lib/ are located), but that is only used if pkgconfig metadata is not found first])
],
[
search_$(use.libname:c)="yes"
],
[
search_$(use.libname:c)="yes"
])
AS_CASE([x"${with_$(use.libname:c)}"],
[xyes], [search_$(use.libname:c)="yes"],
[xno], [search_$(use.libname:c)="no"])
. if !optional
dnl We do not abort right now, because the maintainer/developer may have
dnl something particular in mind, e.g. to build just parts of a project.
AS_IF([test x"${search_$(use.libname:c)}" = xno],
[AC_MSG_WARN([Required dependency on $(use.project:c) was explicitly disabled during configuration by '--with-$(use.libname)=no'; subsequent full build of $(project.name) may fail])])
. endif
AS_IF([test x"${search_$(use.libname:c)}" = xyes], [
# Archive previously detected and supplied flags
PRE_SEARCH_CFLAGS="${CFLAGS}"
PRE_SEARCH_LIBS="${LIBS}"
found_pkgconfig=""
found_linkname=""
. if use.pkgconfig ?<> ""
PKG_CHECK_MODULES([$(use.project:c)], [$(use.pkgconfig) >= $(use.min_version)\
. if defined(use.max_version)
$(use.pkgconfig) <= $(use.max_version)\
. endif
. if defined(use.next_incompatible_version)
$(use.pkgconfig) < $(use.next_incompatible_version)\
. endif
],
[
. if optional
AC_DEFINE(HAVE_$(USE.AM_LIB_MACRO), 1, [The optional\
.# At least one of these values is available, per check above
. if use.pkgconfig ?<> "" & use.pkgconfig ?<> use.libname
$(use.pkgconfig) pkg-config metadata\
. endif
. if use.libname ?<> ""
$(use.libname) library\
. endif
is to be used])
. endif
PKGCFG_LIBS_PRIVATE="$PKGCFG_LIBS_PRIVATE $$(use.project:c)_LIBS"
was_$(use.project:c)_check_lib_detected=pkgcfg
found_pkgconfig="$(use.pkgconfig)"
],
[
. endif
.# The alternate variants can be fallbacks to main pkgconfig (if defined)
.# or standalone (if only the list is provided)
. if count(use.pkgconfig) > 0
. for use.pkgconfig as pkgconfig_variant
AC_MSG_NOTICE([Retry by looking at another variant of pkg-config metadata: $(pkgconfig_variant)])
PKG_CHECK_MODULES([$(use.project:c)], [$(pkgconfig_variant) >= $(use.min_version)\
. if defined(use.max_version)
$(pkgconfig_variant) <= $(use.max_version)\
. endif
. if defined(use.next_incompatible_version)
$(pkgconfig_variant) < $(use.next_incompatible_version)\
. endif
],
[
. if optional
AC_DEFINE(HAVE_$(USE.AM_LIB_MACRO), 1, [The\
.# At least one of these values is available, per check above
. if use.pkgconfig ?<> "" & use.pkgconfig ?<> use.libname
$(pkgconfig_variant) pkg-config metadata\
. endif
. if use.libname ?<> ""
$(use.libname) library\
. endif
is to be used])
. endif
PKGCFG_LIBS_PRIVATE="$PKGCFG_LIBS_PRIVATE $$(use.project:c)_LIBS"
was_$(use.project:c)_check_lib_detected=pkgcfg
found_pkgconfig="$(pkgconfig_variant)"
],
[
. endfor
. endif
.# Code below is either fallback for failed pkgconfig search(es)
.# (if string and/or list was not empty) or a standalone linkability test
. if defined(use.test) & use.libname ?<> "" & ( use.linkname ?<> "" | count(use.linkname) > 0 )
. if use.pkgconfig ?<> "" | count(use.pkgconfig) > 0
AC_MSG_NOTICE([Package\
. if ( use.pkgconfig ?<> "" & count(use.pkgconfig) > 0 ) | count(use.pkgconfig) > 1
s\
. endif
. if use.pkgconfig ?<> ""
$(use.pkgconfig)\
. endif
. if count(use.pkgconfig) > 0
. for use.pkgconfig as pkgconfig_variant
$(pkgconfig_variant)\
. endfor
. endif
not found\
. if !(use.min_version = '0.0.0') | defined(use.max_version) |defined(use.next_incompatible_version)
with needed constraints\
. endif
; falling back to defined compilability tests])
. endif
.# TODO: loop for alternate linknames - all zproject infrastructure is here
$(use.project:c)_synthetic_cflags=""
$(use.project:c)_synthetic_libs="-l$(use.linkname)"
if test -n "${with_$(use.libname:c)}" && test x"${with_$(use.libname:c)}" != xyes && test x"${with_$(use.libname:c)}" != xno; then
if test -r "${with_$(use.libname:c)}/include/$(use.header)"; then
$(use.project:c)_synthetic_cflags="-I${with_$(use.libname:c)}/include"
$(use.project:c)_synthetic_libs="-L${with_$(use.libname:c)}/lib -l$(use.linkname)"
else
. if optional
AC_MSG_WARN([\
. else
AC_MSG_ERROR([\
. endif
Header file ${with_$(use.libname)}/include/$(use.header) was not found. Please check $(use.libname) prefix])
fi
else
AC_CHECK_HEADER([$(use.header)], [],
. if optional
AC_MSG_WARN([\
. else
AC_MSG_ERROR([\
. endif
Header file $(use.header) was not found in default search paths])
)
fi
.# TODO: I doubt this really finds libraries in non-default paths (including
.# our --with-... argument above); verify and perhaps set temporary LIBS and
.# CFLAGS values with added tested location for header and library files
.# using the PRE_SEARCH_LIBS and PRE_SEARCH_CFLAGS defined above just for
.# such sort of use-cases.
AC_CHECK_LIB([$(use.prefix)], [$(use.test:)],
[
was_$(use.project:c)_check_lib_detected=yes
PKGCFG_LIBS_PRIVATE="$PKGCFG_LIBS_PRIVATE -l$(use.linkname)"
found_linkname="$(use.linkname)"
. if optional
AC_DEFINE(HAVE_$(USE.AM_LIB_MACRO), 1, [The optional $(use.libname) library is to be used (as -l$(use.linkname))])
],
[])
. else
],
[AC_MSG_ERROR([cannot link with -l$(use.linkname), install $(use.libname)])])
. endif
. else
AC_MSG_WARN([Attribute 'test' is not set on zproject dependency '$(use.project)' - please ensure it is set])
. endif
.# if count of list of alternates is nonzero, close those fallback clauses too
.if count(use.pkgconfig) > 0
. for use.pkgconfig
])
. endfor
.endif
.if use.pkgconfig ?<> ""
.# if string was empty, code above was a standalone linkability test
])
.endif
dnl END of PKG_CHECK_MODULES and/or direct tests for $(use.libname:c)
AS_CASE(["x${was_$(use.project:c)_check_lib_detected}"],
[xpkgcfg], [
AC_SUBST([pkgconfig_name_$(use.libname:c)],[${found_pkgconfig}])
CFLAGS="${$(use.project:c)_CFLAGS} ${CFLAGS}"
LIBS="${$(use.project:c)_LIBS} ${LIBS}"
],
[xyes], [
AC_SUBST([pkgconfig_name_$(use.libname:c)],[${found_linkname}])
CFLAGS="${$(use.project:c)_synthetic_cflags} ${CFLAGS}"
LDFLAGS="${$(use.project:c)_synthetic_libs} ${LDFLAGS}"
LIBS="${$(use.project:c)_synthetic_libs} ${LIBS}"
AC_SUBST([$(use.project:c)_CFLAGS],[${$(use.project:c)_synthetic_cflags}])
AC_SUBST([$(use.project:c)_LIBS],[${$(use.project:c)_synthetic_libs}])
],
[xno], [
AC_SUBST([pkgconfig_name_$(use.libname:c)],[$(use.libname)])
.# No data defined to use a linkability test, or test failed
. if optional
AC_MSG_WARN([\
. else
AC_MSG_ERROR([\
. endif
Cannot find\
. if use.pkgconfig ?<> "" | count(use.pkgconfig) > 0
pkg-config metadata for $(use.libname)\
. if defined(use.max_version) | defined(use.next_incompatible_version)
>= $(use.min_version)\
. if defined(use.max_version)
and <= $(use.max_version)\
. endif
. if defined(use.next_incompatible_version)
and < $(use.next_incompatible_version)\
. endif
. else
$(use.min_version) or higher\
. endif
. endif
.# NOTE: No excessive looping tests for list of names below...
.# it is possible, but not worth the effort for cosmetics...
. if use.libname ?<> "" & use.pkgconfig ?<> use.libname
library $(use.libname)\
. endif
. if !(defined(use.test) | use.libname ?<> "")
, and no compilability tests were defined either\
. endif
])
])
])
dnl END of enabled attempts to search for $(use.libname:c)
. else
.# TODO: Extend with support for 'optional'
.# TODO: Extend with support for '--with-...=path/to/prog' and '--without-...'
AC_CHECK_PROG(HAVE_$(USE.PROJECT:C), $(use.project:c), yes)
if test x"$HAVE_$(USE.PROJECT:C)" != x"yes" ; then
AC_MSG_ERROR([Cannot find $(use.project)])
fi
. endif
.endfor
.# Restore user supplied flags
CFLAGS="${PREVIOUS_CFLAGS}"
LIBS="${PREVIOUS_LIBS}"
AC_SUBST(pkg_config_libs_private, $PKGCFG_LIBS_PRIVATE)
# Platform specific checks
$(project.name:c)_on_mingw32="no"
$(project.name:c)_on_cygwin="no"
$(project.name:c)_on_android="no"
$(project.name:c)_on_linux="no"
$(project.name:c)_on_gnu="no"
# Host specific checks
AC_CANONICAL_HOST
# Man pages are built/installed if asciidoc and xmlto are present
# --with-docs=no overrides this
AC_ARG_WITH([docs],
AS_HELP_STRING([--with-docs],
[Build and install man pages [default=yes]]),
[with_docs=$withval])
if test "x$with_docs" = "xno"; then
$(project.name:c)_build_doc="no"
$(project.name:c)_install_man="no"
else
# Determine whether or not documentation should be built and installed.
$(project.name:c)_build_doc="yes"
$(project.name:c)_install_man="yes"
# Check for asciidoc and xmlto and don't build the docs if these are not installed.
AC_CHECK_PROG($(project.name:c)_have_asciidoc, asciidoc, yes, no)
AC_CHECK_PROG($(project.name:c)_have_xmlto, xmlto, yes, no)
if test "x$$(project.name:c)_have_asciidoc" = "xno" -o "x$$(project.name:c)_have_xmlto" = "xno"; then
if test "x$with_docs" = "xyes" ; then
AC_MSG_ERROR([Build with docs was explicitly requested, but tools are not available])
fi
$(project.name:c)_build_doc="no"
# Tarballs built with 'make dist' ship with prebuilt documentation.
if ! test -f doc/$(project.name).7; then
$(project.name:c)_install_man="no"
AC_MSG_WARN([You are building an unreleased version of $(PROJECT.NAME) and asciidoc or xmlto are not installed.])
AC_MSG_WARN([Documentation will not be built and manual pages will not be installed.])
fi
fi
fi
AC_MSG_CHECKING([whether to build documentation])
AC_MSG_RESULT([$$(project.name:c)_build_doc])
AC_MSG_CHECKING([whether to install manpages])
AC_MSG_RESULT([$$(project.name:c)_install_man])
# Set some default features required by $(project.libname) code.
CPPFLAGS="-D$(PROJECT.PREFIX)_INTERNAL_BUILD -D_REENTRANT -D_THREAD_SAFE $CPPFLAGS"
# OS-specific tests
case "${host_os}" in
*linux*)
# Define on Linux to enable all library features
CPPFLAGS="-D_GNU_SOURCE -DLINUX $CPPFLAGS"
AC_DEFINE($(PROJECT.PREFIX)_HAVE_LINUX, 1, [Have Linux OS])
$(project.name:c)_on_linux="yes"
case "${host_os}" in
*android*)
AC_DEFINE($(PROJECT.PREFIX)_HAVE_ANDROID, 1, [Have Android OS])
$(project.name:c)_on_android="yes"
;;
esac
;;
*solaris*)
# Define on Solaris to enable all library features
CPPFLAGS="-D_PTHREADS $CPPFLAGS"
# Allow definitions of common OS-provided functions that are not in old standards
CPPFLAGS="-D__EXTENSIONS__ $CPPFLAGS"
AC_DEFINE($(PROJECT.PREFIX)_HAVE_SOLARIS, 1, [Have Solaris OS])
CFLAGS="${CFLAGS} -lsocket -lssp"
;;
*freebsd*)
# Define on FreeBSD to enable all library features
CPPFLAGS="-D__BSD_VISIBLE $CPPFLAGS"
AC_DEFINE($(PROJECT.PREFIX)_HAVE_FREEBSD, 1, [Have FreeBSD OS])
;;
*darwin*)
# Define on Darwin to enable all library features
CPPFLAGS="-D_DARWIN_C_SOURCE $CPPFLAGS"
AC_DEFINE($(PROJECT.PREFIX)_HAVE_OSX, 1, [Have DarwinOSX OS])
;;
*netbsd*)
# Define on NetBSD to enable all library features
CPPFLAGS="-D_NETBSD_SOURCE $CPPFLAGS"
AC_DEFINE($(PROJECT.PREFIX)_HAVE_NETBSD, 1, [Have NetBSD OS])
;;
*openbsd*)
# Define on OpenBSD to enable all library features
CPPFLAGS="-D_BSD_SOURCE $CPPFLAGS"
AC_DEFINE($(PROJECT.PREFIX)_HAVE_OPENBSD, 1, [Have OpenBSD OS])
;;
*nto-qnx*)
AC_DEFINE($(PROJECT.PREFIX)_HAVE_QNXNTO, 1, [Have QNX Neutrino OS])
;;
*aix*)
AC_DEFINE($(PROJECT.PREFIX)_HAVE_AIX, 1, [Have AIX OS])
;;
*hpux*)
# Define on HP-UX to enable all library features
CPPFLAGS="-D_POSIX_C_SOURCE=200112L"
AC_DEFINE($(PROJECT.PREFIX)_HAVE_HPUX, 1, [Have HPUX OS])
;;
*mingw32*)
# Disable format error due to incomplete ANSI C
CFLAGS="-Wno-error=format -Wno-unused-function -Wno-unused-variable -D_XOPEN_SOURCE $CFLAGS"
CPPFLAGS="-Wno-error=format -Wno-unused-function -Wno-unused-variable -D_XOPEN_SOURCE $CPPFLAGS"
AC_DEFINE($(PROJECT.PREFIX)_HAVE_WINDOWS, 1, [Have Windows OS])
AC_DEFINE($(PROJECT.PREFIX)_HAVE_MINGW32, 1, [Have MinGW32])
AC_CHECK_HEADERS(windows.h)
$(project.name:c)_on_mingw32="yes"
$(project.name:c)_install_man="no"
;;
*mingw64*)
# Define on MINGW64 to enable all libeary features
# Disable format error due to incomplete ANSI C
CFLAGS="-Wno-error=format -Wno-unused-function -Wno-unused-variable -D_XOPEN_SOURCE $CFLAGS"
CPPFLAGS="-Wno-error=format -Wno-unused-function -Wno-unused-variable -D_XOPEN_SOURCE $CPPFLAGS"
AC_DEFINE($(PROJECT.PREFIX)_HAVE_WINDOWS, 1, [Have Windows OS])
AC_DEFINE($(PROJECT.PREFIX)_HAVE_MINGW32, 1, [Have MinGW32])
AC_CHECK_HEADERS(windows.h)
$(project.name:c)_on_mingw32="yes"
$(project.name:c)_install_man="no"
;;
*cygwin*)
# Define on Cygwin to enable all library features
CPPFLAGS="-D_GNU_SOURCE $CPPFLAGS"
AC_DEFINE($(PROJECT.PREFIX)_HAVE_CYGWIN, 1, [Have Cygwin])
$(project.name:c)_on_cygwin="yes"
;;
gnu*)
# Define on GNU/Hurd to enable all library features
if test "x$GXX" = "xyes"; then
CPPFLAGS="-D_GNU_SOURCE $CPPFLAGS"
fi
AC_DEFINE($(PROJECT.PREFIX)_HAVE_GNU, 1, [Have GNU/Hurd OS])
$(project.name:c)_on_gnu="yes"
;;
*)
AC_MSG_ERROR([unsupported system: ${host_os}])
;;
esac
# Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS(errno.h arpa/inet.h netinet/tcp.h netinet/in.h stddef.h \\
stdlib.h string.h sys/socket.h sys/time.h unistd.h \\
limits.h ifaddrs.h)
AC_CHECK_HEADERS([net/if.h net/if_media.h linux/wireless.h], [], [],
[
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#include <stdint.h>
])
# Checks for typedefs, structures, and compiler characteristics.
AC_HEADER_STDBOOL
AC_C_CONST
AC_C_INLINE
AC_TYPE_SIZE_T
AC_TYPE_SSIZE_T
AC_HEADER_TIME
AC_TYPE_UINT32_T
AC_C_VOLATILE
AC_C_BIGENDIAN
AM_CONDITIONAL(ENABLE_SHARED, test "x$enable_shared" = "xyes")
AM_CONDITIONAL(ON_MINGW, test "x$$(project.name:c)_on_mingw32" = "xyes")
AM_CONDITIONAL(ON_CYGWIN, test "x$$(project.name:c)_on_cygwin" = "xyes")
AM_CONDITIONAL(ON_ANDROID, test "x$$(project.name:c)_on_android" = "xyes")
AM_CONDITIONAL(ON_LINUX, test "x$$(project.name:c)_on_linux" = "xyes")
AM_CONDITIONAL(ON_GNU, test "x$$(project.name:c)_on_gnu" = "xyes")
AM_CONDITIONAL(INSTALL_MAN, test "x$$(project.name:c)_install_man" = "xyes")
AM_CONDITIONAL(BUILD_DOC, test "x$$(project.name:c)_build_doc" = "xyes")
AC_ARG_ENABLE([dist_cmakefiles],
AS_HELP_STRING([--enable-dist_cmakefiles],
[Distribute CMakeLists.txt and related files [default depends: on if present and not cross compiling]]),
[enable_dist_cmakefiles=$enableval],
[AC_MSG_CHECKING([for presence of CMake recipes])
if test "x$cross_compiling" = "xyes"; then
enable_dist_cmakefiles=no
else
AC_CHECK_FILE($srcdir/CMakeLists.txt, [enable_dist_cmakefiles=yes], [enable_dist_cmakefiles=no])
fi
AC_MSG_RESULT([$enable_dist_cmakefiles])])
AM_CONDITIONAL(ENABLE_DIST_CMAKEFILES, test "x$enable_dist_cmakefiles" = "xyes")
.for project.main
# Check for $(name) intent
AC_ARG_ENABLE([$(name)],
AS_HELP_STRING([--enable-$(name)],
. if scope = "public"
[Compile and install '$(name)' [default=yes]]),
. else
[Compile '$(name)' in src [default=yes]]),
. endif
[enable_$(name:c)=$enableval],
[enable_$(name:c)=yes])
AM_CONDITIONAL([ENABLE_$(NAME:c)], [test x$enable_$(name:c) != xno])
AM_COND_IF([ENABLE_$(NAME:c)], [AC_MSG_NOTICE([ENABLE_$(NAME:c) defined])])
.endfor
# Checks for library functions.
AC_TYPE_SIGNAL
AC_CHECK_FUNCS(perror gettimeofday memset getifaddrs)
.if file.exists ("src/$(project.libname).sym")
# Symbol versioning support: snatched and adapted from libpng:
# http://www.opensource.apple.com/source/X11libs/X11libs-40/libpng/libpng-1.2.35/configure.ac
AC_MSG_CHECKING([if libraries can be versioned])
GLD="`$LD --help < /dev/null 2>/dev/null | grep version-script`"
AS_IF([test -n "$GLD"],
[have_ld_version_script=yes
AC_MSG_RESULT(yes)],
[have_ld_version_script=no
AC_MSG_RESULT(no)
AC_MSG_WARN(*** You have not enabled versioned symbols.)
])
AM_CONDITIONAL(HAVE_LD_VERSION_SCRIPT, test "$have_ld_version_script" = "yes")
AS_IF([test "$have_ld_version_script" = "yes"],
[AC_MSG_CHECKING([for symbol prefix])
SYMBOL_PREFIX=`echo "PREFIX=__USER_LABEL_PREFIX__" \\
| ${CPP-${CC-gcc} -E} - 2>&1 \\
| ${EGREP-grep} "^PREFIX=" \\
| ${SED-sed} "s:^PREFIX=::"`
AC_SUBST(SYMBOL_PREFIX)
AC_MSG_RESULT($SYMBOL_PREFIX)
CXXFLAG_VISIBILITY=""
gl_VISIBILITY
AS_CASE(["$CFLAG_VISIBILITY"],
[*-fvisibility-inlines-hidden*],[
CXXFLAG_VISIBILITY="$CFLAG_VISIBILITY"],
[*-fvisibility=hidden*],[
CXXFLAG_VISIBILITY="$CFLAG_VISIBILITY -fvisibility-inlines-hidden"])
AC_SUBST(CXXFLAG_VISIBILITY)
])
.endif
# enable specific system integration features
.for project.main where ( defined(main.service) & main.service > 0 )
. systemd = 1
.endfor
.if systemd ?= 1
AC_ARG_WITH([systemd-units],
AS_HELP_STRING([--with-systemd-units],
[Build and install with systemd units integration [default=no]]),
[with_systemd_units=$withval],
[with_systemd_units=no])
PKG_PROG_PKG_CONFIG
AC_ARG_WITH([systemdsystemunitdir],
[AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files])],,
[with_systemdsystemunitdir=auto])
AS_IF([test "x$with_systemdsystemunitdir" = "xyes" -o "x$with_systemdsystemunitdir" = "xauto"], [
def_systemdsystemunitdir=\$($PKG_CONFIG --variable=systemdsystemunitdir systemd)
AS_IF([test "x$def_systemdsystemunitdir" = "x"],
[AS_IF([test "x$with_systemdsystemunitdir" = "xyes"],
[AC_MSG_ERROR([systemd support requested but pkg-config unable to query systemd package])])
with_systemdsystemunitdir=no],
[with_systemdsystemunitdir="$def_systemdsystemunitdir"])])
AS_IF([test "x$with_systemdsystemunitdir" != "xno"],
[AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir])])
AM_CONDITIONAL([WITH_SYSTEMD_UNITS], [test "x$with_systemdsystemunitdir" != "xno" -a x$with_systemd_units != xno])
AM_COND_IF([WITH_SYSTEMD_UNITS],
[AC_DEFINE(WITH_SYSTEMD_UNITS, 1, [systemd units are going to be installed])
AC_SUBST(WITH_SYSTEMD_UNITS)],
[])
.endif
.if project.stable
if test "x$cross_compiling" = "xyes"; then
# Enable draft by default when cross-compiling
defaultval=yes
else
# enable draft API by default if we're in a git repository
# else disable it by default; then allow --enable-drafts=yes/no override
AC_CHECK_FILE($srcdir/.git, [defaultval=yes],
[AC_MSG_CHECKING([running under a git repository workspace])
AS_IF([git rev-parse --show-toplevel 2>/dev/null],
[defaultval=yes],
[defaultval=no])
AC_MSG_RESULT($defaultval)
])
fi
AC_ARG_ENABLE([drafts],
AS_HELP_STRING([--enable-drafts],
[Build and install draft classes and methods [default=yes]]),
[enable_drafts=$enableval],
[enable_drafts=$defaultval])
.else
# Project has no stable classes so enable draft API by default
enable_drafts=yes
.endif
AM_CONDITIONAL([ENABLE_DRAFTS], [test x$enable_drafts != xno])
if test "x$enable_drafts" = "xyes"; then
AC_MSG_NOTICE([Building stable and legacy API + draft API])
AC_DEFINE($(PROJECT.PREFIX)_BUILD_DRAFT_API, 1, [Provide draft classes and methods])
AC_SUBST(pkg_config_defines, "-D$(PROJECT.PREFIX)_BUILD_DRAFT_API=1")
else
AC_MSG_NOTICE([Building stable and legacy API (no draft API)])
AC_SUBST(pkg_config_defines, "")
fi
AC_ARG_ENABLE([Werror],
AS_HELP_STRING([--enable-Werror],
[Add -Wall -Werror to GCC/GXX arguments [default=no; default=auto if nothing specified as the specific argument value]]),
[AS_IF([test -n "$enableval"], [enable_Werror=$enableval], [enable_Werror=auto])],
[enable_Werror=no])
# These options are GNU compiler specific.
AS_IF([test "x$enable_Werror" = "xyes" || test "x$enable_Werror" = "xauto"],
[AS_IF([test -n "$CC"],[AS_IF([$CC --version 2>&1 | grep 'Free Software Foundation' > /dev/null && test "x$GCC" = "xyes"],
[AC_MSG_NOTICE([Enabling pedantic errors for GNU C])
CFLAGS="$CFLAGS -pedantic -Wall -Werror -Werror=format-security"],
[AC_MSG_NOTICE([Not enabling pedantic errors: compiler not supported by this recipe (not GNU C)])
AS_IF([test "x$enable_Werror" = "xyes"], [AC_MSG_ERROR([--enable-Werror=yes was requested and can not be satisfied for C: $CC])])
])])
AS_IF([test -n "$CXX"],[AS_IF([$CXX --version 2>&1 | grep 'Free Software Foundation' > /dev/null && test "x$GCC" = "xyes"],
[AC_MSG_NOTICE([Enabling pedantic errors for GNU C++])
CXXFLAGS="$CXXFLAGS -pedantic -Wall -Werror -Werror=format-security"],
[AC_MSG_NOTICE([Not enabling pedantic errors: compiler not supported by this recipe (not GNU C++)])
AS_IF([test "x$enable_Werror" = "xyes"], [AC_MSG_ERROR([--enable-Werror=yes was requested and can not be satisfied for C++: $CXX])])
])])
AS_IF([test -n "$CPP"],[AS_IF([$CPP --version 2>&1 | grep 'Free Software Foundation' > /dev/null && test "x$GCC" = "xyes"],
[AC_MSG_NOTICE([Enabling pedantic errors for GNU CPP preprocessor])
.if project.use_cxx
CPPFLAGS="$CPPFLAGS -pedantic -Werror -Wall"
.else
CPPFLAGS="$CPPFLAGS -pedantic -Werror -Wall -Wc++-compat"
.endif
],
[AC_MSG_NOTICE([Not enabling pedantic errors: preprocessor not supported by this recipe (not GNU CPP)])
AS_IF([test "x$enable_Werror" = "xyes"], [AC_MSG_ERROR([--enable-Werror=yes was requested and can not be satisfied for CPP: $CPP])])
])])
])
.if file.exists ("acinclude.m4")
# Optional project-local hook to (re-)define some variables that can be used
# in your project files generated from .in templates - in your acinclude.m4,
# add AC_DEFUN([AX_PROJECT_LOCAL_HOOK_CONFIGVARS], [whatever])
ifdef([AX_PROJECT_LOCAL_HOOK_CONFIGVARS],
[AX_PROJECT_LOCAL_HOOK_CONFIGVARS])
.endif
# Specify output files
.if count (class) + count (ac_config) > 0
AC_CONFIG_FILES([Makefile
. if count (class) > 0
doc/Makefile
include/Makefile
src/$(project.libname).pc
. endif
. for project.main where defined (main->extra)
. for extra where extra.cond ?<> "with_systemd_units"
src/$(extra.name)
. endfor
. endfor
. for project.main where ( defined(main.service) & main.service > 0 & ( !defined(main.no_config) | main.no_config ?= 0 ) )
src/$(main.name).cfg
. endfor
])
.else
AC_CONFIG_FILES([Makefile
. for project.main where ( defined(main.service) & main.service > 0 & ( !defined(main.no_config) | main.no_config ?= 0 ) )
src/$(main.name).cfg
. endfor
])
.endif
.if systemd ?= 1
AM_COND_IF([WITH_SYSTEMD_UNITS],
[AC_CONFIG_FILES([
. for project.main where ( defined(main.service) & main.service > 0 )
. if ( main.service ?= 1 | main.service ?= 3 )
. if file.exists("src/$(main.name).service.in")
src/$(main.name).service
. endif
. endif
. if ( main.service ?= 2 | main.service ?= 3 )
. if file.exists("src/$(main.name)@.service.in")
src/$(main.name)@.service
. endif
. endif
. endfor
. for project.main where ( defined(main.timer) & main.timer > 0 )
. if ( main.timer ?= 1 | main.timer ?= 3 )
. if file.exists("src/$(main.name).timer.in")
src/$(main.name).timer
. endif
. endif
. if ( main.timer ?= 2 | main.timer ?= 3 )
. if file.exists("src/$(main.name)@.timer.in")
src/$(main.name)@.timer
. endif
. endif
. endfor
. for project.bin where ( defined(bin.service) & bin.service > 0 )
. if ( bin.service ?= 1 | bin.service ?= 3 )
. if file.exists("src/$(bin.name).service.in")
src/$(bin.name).service
. endif
. endif
. if ( bin.service ?= 2 | bin.service ?= 3 )
. if file.exists("src/$(bin.name)@.service.in")
src/$(bin.name)@.service
. endif
. endif
. endfor
. for project.bin where ( defined(bin.timer) & bin.timer > 0 )
. if ( bin.timer ?= 1 | bin.timer ?= 3 )
. if file.exists("src/$(bin.name).timer.in")
src/$(bin.name).timer
. endif
. endif
. if ( bin.timer ?= 2 | bin.timer ?= 3 )
. if file.exists("src/$(bin.name)@.timer.in")
src/$(bin.name)@.timer
. endif
. endif
. endfor
])],
[])
.endif
.insert_snippet ("configure.ac")
.if file.exists ("acinclude.m4")
# Optional project-local hook to put some finishing touches in your configure
# script, override something compared to zproject-generated code, etc. - in
# your acinclude.m4, add AC_DEFUN([AX_PROJECT_LOCAL_HOOK_FINAL], [whatever])
ifdef([AX_PROJECT_LOCAL_HOOK_FINAL],
[AX_PROJECT_LOCAL_HOOK_FINAL])
.endif
AC_OUTPUT
# Print configure summary and list make options
AC_DEFUN([AX_SUMMARIZE_ENV],
[
BUILD_USER=${USER}
BUILD_ARCH=${host}
BUILD_HOST=${ac_hostname}
BUILD_DATE=$\(date +'%F %H:%M'\)
AC_DEFINE_UNQUOTED([BUILD_USER], "${BUILD_USER}", [The fine user who built the package])
AC_DEFINE_UNQUOTED([BUILD_ARCH], "${BUILD_ARCH}", [Architecture of the build host])
AC_DEFINE_UNQUOTED([BUILD_HOST], "${BUILD_HOST}", [Build host name])
AC_DEFINE_UNQUOTED([BUILD_DATE], "${BUILD_DATE}", [Build date])
AC_SUBST(BUILD_USER)
AC_SUBST(BUILD_ARCH)
AC_SUBST(BUILD_HOST)
AC_SUBST(BUILD_DATE)
AC_SUBST(BUILD_VERSION)
])
AC_DEFUN([AX_SUMMARIZE_CONFIG],
[
echo
echo '##########################################################################'
echo '# SUMMARY #'
echo '##########################################################################'
echo
echo Package version............... : $PACKAGE-$VERSION
echo
echo C compiler.................... : $CC
echo C compiler flags.............. : $CFLAGS
echo C++ compiler.................. : $CXX
echo C++ compiler flags............ : $CXXFLAGS
echo Configure date................ : $BUILD_DATE
echo Build architecture............ : $BUILD_ARCH
echo Build docs.................... : $$(project.name:c)_build_doc
echo Build host.................... : $BUILD_HOST
echo Build user.................... : $USER
echo Draft API..................... : $enable_drafts
echo Install dir................... : $prefix
echo Install man pages............. : $$(project.name:c)_install_man
echo
echo Help:
echo Use the Draft API \\(default = yes\\):
echo --enable-drafts=\\(yes\\|no\\)
echo
echo Build the docs and install the man pages \\(default = yes\\):
echo --with-docs=\\(yes\\|no\\) *requires asciidoc and xmlto
echo
echo '##########################################################################'
echo
echo Configure complete! Now proceed with:
echo " - 'make' compile the project"
echo " - 'make check' run the project's selftest"
echo " - 'make install' install the project to $prefix"
echo
echo Further options are:
echo " - 'make callcheck' run the project's selftest with valgrind to"
echo " check for performance leaks"
echo " - 'make check-verbose' run the project's selftest in verbose mode"
echo " - 'make code' generate code from models in src directory"
echo " (requires zproject and zproto)"
echo " - 'make debug' run the project's selftest under gdb"
echo " - 'make memcheck' run the project's selftest with valgrind to"
echo " check for memory leaks"
echo " - 'make coverage' generate project's selftest coverage report"
echo " expects --with-gcov option for configure"
echo " - 'make clang-format-check' check if project sources conform"
echo " to style requirements"
echo " - 'make clang-format' modify project sources to conform"
echo " to style requirements"
echo " - 'make clang-format-diff' modify as above and print 'git diff'"
echo
])
AX_SUMMARIZE_ENV
AX_SUMMARIZE_CONFIG
$(project.GENERATED_WARNING_HEADER:)
.output "src/.gitignore"
$(project.GENERATED_WARNING_HEADER:)
# Ignore files generated from .in templates
.if count (class) + count (ac_config) > 0
. if count (class) > 0
# + pkgconfig:
$(project.libname).pc
. endif
# + main->extra sources (if any):
. for project.main where defined (main->extra)
. for extra where extra.cond ?<> "with_systemd_units"
$(extra.name)
. endfor
. endfor
.endif
# + config files for mains (if any):
.for project.main where ( defined(main.service) & main.service > 0 & ( !defined(main.no_config) | main.no_config ?= 0 ) )
$(main.name).cfg
.endfor
.for project.bin where ( defined(bin.service) & bin.service > 0 & ( !defined(bin.no_config) | bin.no_config ?= 0 ) )
$(bin.name).cfg
.endfor
.if systemd ?= 1
# + systemd service unit for daemons (if any):
. for project.main where ( defined(main.service) & main.service > 0 )
. if ( main.service ?= 1 | main.service ?= 3 )
. if file.exists("src/$(main.name).service.in") | file.exists("src/$(main.name).service")
$(main.name).service
. endif
. endif
. if ( main.service ?= 2 | main.service ?= 3 )
. if file.exists("src/$(main.name)@.service.in") | file.exists("src/$(main.name)@.service")
$(main.name)@.service
. endif
. endif
. endfor
. for project.main where ( defined(main.timer) & main.timer > 0 )
. if ( main.timer ?= 1 | main.timer ?= 3 )
. if file.exists("src/$(main.name).timer.in") | file.exists("src/$(main.name).timer")
$(main.name).timer
. endif
. endif
. if ( main.timer ?= 2 | main.timer ?= 3 )
. if file.exists("src/$(main.name)@.timer.in") | file.exists("src/$(main.name)@.timer")
$(main.name)@.timer
. endif
. endif
. endfor
. for project.bin where ( defined(bin.service) & bin.service > 0 )
. if ( bin.service ?= 1 | bin.service ?= 3 )
. if file.exists("src/$(bin.name).service.in") | file.exists("src/$(bin.name).service")
$(bin.name).service
. endif
. endif
. if ( bin.service ?= 2 | bin.service ?= 3 )
. if file.exists("src/$(bin.name)@.service.in") | file.exists("src/$(bin.name)@.service")
$(bin.name)@.service
. endif
. endif
. endfor
. for project.bin where ( defined(bin.timer) & bin.timer > 0 )
. if ( bin.timer ?= 1 | bin.timer ?= 3 )
. if file.exists("src/$(bin.name).timer.in") | file.exists("src/$(bin.name).timer")
$(bin.name).timer
. endif
. endif
. if ( bin.timer ?= 2 | bin.timer ?= 3 )
. if file.exists("src/$(bin.name)@.timer.in") | file.exists("src/$(bin.name)@.timer")
$(bin.name)@.timer
. endif
. endif
. endfor
.endif
# location designated for writing self-tests:
selftest-rw/
$(project.GENERATED_WARNING_HEADER:)
.endmacro
.macro generate_automake_files
.output "Makefile.am"
$(project.GENERATED_WARNING_HEADER:)
.if systemd ?= 1
DISTCHECK_CONFIGURE_FLAGS = \\
--with-systemdsystemunitdir=$$dc_install_base/\$(systemdsystemunitdir)
.endif
ACLOCAL_AMFLAGS = -I config
.if project.use_cxx
AM_CXXFLAGS = \\
-std=c++11
.endif
AM_CPPFLAGS = \\
.for use where use.libname ?<> ""
\${$(use.project:c)_CFLAGS} \\
.endfor
.if project.use_cxx
-D__STDC_FORMAT_MACROS \\
.endif
-I\$(srcdir)/include
.libs = ""
.for use where use.libname ?<> ""
. libs += " \${$(use.project:c)_LIBS}"
.endfor
project_libs =$(libs:)
SUBDIRS = $(count (class)?? "doc"? "")
SUBDIRS += $(count (class)?? "include"? "")
DIST_SUBDIRS = $(count (class)?? "doc"? "")
DIST_SUBDIRS += $(count (class)?? "include"? "")
lib_LTLIBRARIES =
bin_PROGRAMS =
noinst_PROGRAMS =
check_PROGRAMS =
noinst_LTLIBRARIES =
TESTS =
# Prepare variables that can be populated (appended) in generated Makefiles or
# manually maintained src/Makemodule-local.am
EXTRA_DIST =
CLEANFILES =
DISTCLEANFILES =
if ENABLE_DIST_CMAKEFILES
EXTRA_DIST += \\
.for use
Find$(use.project:c).cmake \\
.endfor
.if file.exists ("src/CMakeLists-local.txt")
src/CMakeLists-local.txt \\
.endif
builds/cmake/Modules/ClangFormat.cmake \\
builds/cmake/clang-format-check.sh.in \\
builds/cmake/Config.cmake.in \\
CMakeLists.txt
endif
EXTRA_DIST += \\
.if file.exists ("bindings")
bindings \\
.endif
.for extra
src/$(extra.name) \\
.endfor
.for class where scope = "private"
src/$(name:$(project.filename_prettyprint)).$(project.header_ext) \\
.endfor
.for header where scope = "private"
src/$(name:$(project.filename_prettyprint)).$(project.header_ext) \\
.endfor
.if file.exists ("LICENSE")
LICENSE \\
.endif
.if file.exists ("README.txt")
README.txt \\
.endif
.if file.exists ("README.md")
README.md \\
.endif
.if file.exists ("CONTRIBUTING.md")
CONTRIBUTING.md \\
.endif
src/$(project.prefix)_classes.$(project.header_ext)
# NOTE: this "include" syntax is not a "make" but an "autotools" keyword,
# see https://www.gnu.org/software/automake/manual/html_node/Include.html
include \$(srcdir)/src/Makemodule.am
include \$(srcdir)/src/Makemodule-local.am # Optional project-local hook
$(project.GENERATED_WARNING_HEADER:)
.#
.# ===========================================================================
.if count (class)
.output "include/Makefile.am"
$(project.GENERATED_WARNING_HEADER:)
.if project.keep_tree
. if project.pkgincludedir
nobase_pkginclude_HEADERS = \\
. else
nobase_include_HEADERS = \\
. endif
.else
. if project.pkgincludedir
pkginclude_HEADERS = \\
. else
include_HEADERS = \\
. endif
.endif
.if file.exists ("include/$(project.prelude)")
$(project.prelude) \\
.endif
.if count (class, class.c_name = project.name) = 0
$(project.header:) \\
.endif
.for header where scope = "public"
$(name:$(project.filename_prettyprint)).$(project.header_ext) \\
.endfor
.for class where scope = "public" & !draft
$(name:$(project.filename_prettyprint)).$(project.header_ext) \\
.endfor
$(project.prefix)_library.$(project.header_ext)
.if count (class, scope = "public" & draft)
if ENABLE_DRAFTS
.if project.keep_tree
. if project.pkgincludedir
nobase_pkginclude_HEADERS += \\
. else
nobase_include_HEADERS += \\
. endif
.else
. if project.pkgincludedir
pkginclude_HEADERS += \\
. else
include_HEADERS += \\
. endif
.endif
. for class where scope = "public" & draft
$(name:$(project.filename_prettyprint)).$(project.header_ext)$(last ()?? "\n"? " \\")
. endfor
endif
.endif
.insert_snippet ("Makemodule")
$(project.GENERATED_WARNING_HEADER:)
.close
.- Here, close "if count(class)"
.endif
.----------------------------Start src/Makemodule.am----------------------------
.output "src/Makemodule.am"
$(project.GENERATED_WARNING_HEADER:)
.libs = ""
.if count (class)
. libs += "src/$(project.libname).la"
.endif
.if count (use)
. libs += " ${project_libs}"
.endif
program_libs = $(libs:)
# Programs need to link the c++ runtime if everything was compiled statically.
if !ENABLE_SHARED
program_libs += -lstdc++ -lm
endif
.if count (class)
lib_LTLIBRARIES += src/$(project.libname).la
pkgconfig_DATA = src/$(project.libname).pc
.endif
.------------Re-open if count (class)------------
.if count (class)
src_$(project.libname)_la_SOURCES = \\
.for class where !draft
. if file.exists ("src/$(name:$(project.filename_prettyprint)).$(project.source_ext)")
src/$(name:$(project.filename_prettyprint)).$(project.source_ext) \\
. else
src/$(name:$(project.filename_prettyprint)).c \\
. endif
. if file.exists ("src/$(name:c)_engine.inc")
src/$(name:c)_engine.inc \\
. endif
.endfor
.for extra
src/$(name) \\
.endfor
src/platform.h
.if count (class, draft)
if ENABLE_DRAFTS
src_$(project.libname)_la_SOURCES += \\
. for class where draft
. if file.exists ("src/$(name:$(project.filename_prettyprint)).$(project.source_ext)")
src/$(name:$(project.filename_prettyprint)).$(project.source_ext)\
. else
src/$(name:$(project.filename_prettyprint)).c\
. endif
. if file.exists ("src/$(name:c)_engine.inc")
\\
src/$(name:c)_engine.inc\
. endif
$(last ()?? "\n"? " \\")
. endfor
endif
.endif
.if count (class)
if ENABLE_DRAFTS
src_$(project.libname)_la_SOURCES += \\
. if project.use_cxx
src/$(project.prefix)_private_selftest.$(project.source_ext)
. else
src/$(project.prefix)_private_selftest.$(project.source_ext)
. endif
endif
.endif
src_$(project.libname)_la_CPPFLAGS = ${AM_CPPFLAGS}
.if project.use_cxx
src_$(project.libname)_la_CXXFLAGS = ${AM_CXXFLAGS}
.endif
src_$(project.libname)_la_LDFLAGS = \\
-version-info @LTVER@ \\
\$(LIBTOOL_EXTRA_LDFLAGS)
.if file.exists ("src/$(project.libname).sym")
if HAVE_LD_VERSION_SCRIPT
src_$(project.libname)_la_LDFLAGS += \\
-Wl,--version-script=\$(top_srcdir)/src/$(project.libname).sym
else
src_$(project.libname)_la_LDFLAGS += \\
-export-symbols \$(top_srcdir)/src/$(project.libname).sym
endif
.endif
if ON_MINGW
src_$(project.libname)_la_LDFLAGS += \\
-no-undefined \\
-avoid-version
endif
if ON_CYGWIN
src_$(project.libname)_la_LDFLAGS += \\
-no-undefined \\
-avoid-version
endif
src_$(project.libname)_la_LIBADD = ${project_libs}
.endif
.if systemd ?= 1
if WITH_SYSTEMD_UNITS
systemdsystemunit_DATA =
endif #WITH_SYSTEMD_UNITS
.endif
.for project.main
if ENABLE_$(NAME:c)
. if main.test ?= 1
check_PROGRAMS += src/$(main.name)
noinst_PROGRAMS += src/$(main.name)
. elsif main.scope = "public"
bin_PROGRAMS += src/$(main.name)
. else
noinst_PROGRAMS += src/$(main.name)
. endif
src_$(main.name:c)_CPPFLAGS = ${AM_CPPFLAGS}
src_$(main.name:c)_LDADD = ${program_libs}
src_$(name:c)_SOURCES = $(main.source)
.#
.# Systemd stuff
. if ( defined(main.service) & main.service > 0 )
src_$(main.name:c)_config_DATA =
. if ( !defined(main.no_config) | main.no_config ?= 0 )
src_$(main.name:c)_config_DATA += src/$(main.name).cfg
. endif
src_$(main.name:c)_configdir = \$(sysconfdir)/$(project.name)
. endif
. if ( defined(main.service) & main.service > 0 ) | ( defined(main.timer) & main.timer > 0 )
if WITH_SYSTEMD_UNITS
.# Systemd stuff for mains
. if ( defined(main.service) & main.service > 0 )
. if ( main.service ?= 1 | main.service ?= 3 )
systemdsystemunit_DATA += src/$(main.name).service
. endif
. if ( main.service ?= 2 | main.service ?= 3 )
systemdsystemunit_DATA += src/$(main.name)@.service
. endif
. endif
. if ( defined(main.timer) & main.timer > 0 )
. if ( main.timer ?= 1 | main.timer ?= 3 )
systemdsystemunit_DATA += src/$(main.name).timer
. endif
. if ( main.timer ?= 2 | main.timer ?= 3 )
systemdsystemunit_DATA += src/$(main.name)@.timer
. endif
. endif
endif #WITH_SYSTEMD_UNITS
. endif
endif #ENABLE_$(NAME:c)
.endfor
.for bin
. if first ()
# Install data into /usr/local/bin
dist_bin_SCRIPTS = \\
. endif
$(bin.name)$(last ()?? "\n"? " \\")
. if ( defined(bin.service) & bin.service > 0 ) | ( defined(bin.timer) & bin.timer > 0 )
if WITH_SYSTEMD_UNITS
.# Systemd stuff for bins
. if ( defined(bin.service) & bin.service > 0 )
. if ( bin.service ?= 1 | bin.service ?= 3 )
systemdsystemunit_DATA += src/$(bin.name).service
. endif
. if ( bin.service ?= 2 | bin.service ?= 3 )
systemdsystemunit_DATA += src/$(bin.name)@.service
. endif
. endif
. if ( defined(bin.timer) & bin.timer > 0 )
. if ( bin.timer ?= 1 | bin.timer ?= 3 )
systemdsystemunit_DATA += src/$(bin.name).timer
. endif
. if ( bin.timer ?= 2 | bin.timer ?= 3 )
systemdsystemunit_DATA += src/$(bin.name)@.timer
. endif
. endif
endif #WITH_SYSTEMD_UNITS
. endif
.endfor
.# copy&paste from zproject_redhat.gsl
.for project.target where ( target.name = "*" | target.name = "python_cffi" > 0 )
. python_cffi = 1
.endfor
.for class where defined (class.api)
. if first ()
# Install api files into /usr/local/share/zproject
apidir = @datadir@/zproject/$(project.name)
dist_api_DATA = \\
. if python_cffi ?= 1
api/python_cffi.slurp \\
. endif
. endif
.# Install files that the api includes
. for class.include
api/$(include.filename) \\
. endfor
$(class.api)$(last ()?? "\n"? " \\")
.endfor
.if count (project.class)
# define custom target for all products of /src
src: \\
. for project.main
\t\tsrc/$(main.name) \\
. endfor
\t\tsrc/$(project.libname).la
.endif
.for model
. if first ()
# Produce generated code from models in the src directory
code:
. endif
. if defined (model.script)
\tcd $\(srcdir)/src; gsl -topdir:.. -zproject:1 -script:$(script:) \
. for model.param
-$(param.name):$(param.value) \
. endfor
-q $(name:c).xml
. else
\tcd $\(srcdir)/src; gsl -topdir:.. -zproject:1 \
. if count(project.class, class.name = model.name & class.private)
-private:1 \
. endif
-q $(name).xml
. endif
. if last ()
\tcd $\(srcdir); gsl -target:- project.xml
. endif
.endfor
# Directories with test fixtures optionally provided by the project,
# and with volatile RW data possibly created by a selftest program.
# It is up to the project authors to populate the RO directory with
# filenames called from the selftest methods, if any. They will be
# EXTRA_DISTed by the recipes generated with with zproject, however,
# and copied into builddir (if different from srcdir) to simplify
# the "distcheck" and similar tests (so selftest can use same paths).
# Note that the RO directory must exist to fulfill EXTRA_DIST, so we
# add a stub file that can be committed to SCM by project developers.
# The RW directory will be automatically wiped by "make distclean".
SELFTEST_DIR_RO = src/selftest-ro
SELFTEST_DIR_RW = src/selftest-rw
# This is recreated on every invocation (as a selftest dependency),
# so tests run in a clean environment
$\(top_builddir)/$\(SELFTEST_DIR_RW):
\trm -rf "\$@"
\tmkdir -p "\$@"
# Note: for some reason "$<" misfired in rule below on Travis, so be explicit
if USING_VPATH
$\(abs_top_builddir)/$\(SELFTEST_DIR_RO): $\(abs_top_srcdir)/$\(SELFTEST_DIR_RO)
\t@echo " COPYDIR $\(SELFTEST_DIR_RO)"; \\
\trm -rf "$@"; \\
\tcp -r "$\(abs_top_srcdir)/$\(SELFTEST_DIR_RO)" "$@"
$\(top_builddir)/$\(SELFTEST_DIR_RO): $\(abs_top_builddir)/$\(SELFTEST_DIR_RO)
endif
$\(SELFTEST_DIR_RO): $\(top_builddir)/$\(SELFTEST_DIR_RO)
CLEANFILES += $\(top_builddir)/$\(SELFTEST_DIR_RW)/*
# Note that this syntax dists the whole directory - including subdirs (if any)
EXTRA_DIST += $\(SELFTEST_DIR_RO)
clean-local: clean-local-selftest-ro clean-local-selftest-rw
\.PHONY: clean-local-selftest-ro
clean-local-selftest-ro:
\t@if test "$\(top_builddir)" != "$\(top_srcdir)" ; then \\
\t\tif test -d "$\(top_builddir)/$\(SELFTEST_DIR_RO)" ; then \\
\t\t\tchmod -R u+w "$\(top_builddir)/$\(SELFTEST_DIR_RO)" ; \\
\t\t\trm -rf "$\(top_builddir)/$\(SELFTEST_DIR_RO)" ; \\
\t\tfi; \\
\tfi
# Unlike CLEANFILES setting above, this one whould also wipe created subdirs
\.PHONY: clean-local-selftest-rw
clean-local-selftest-rw:
\t@if test "$\(top_builddir)" != "$\(top_srcdir)" ; then \\
\t\tif test -d "$\(top_builddir)/$\(SELFTEST_DIR_RW)" ; then \\
\t\t\tchmod -R u+w "$\(top_builddir)/$\(SELFTEST_DIR_RW)" ; \\
\t\t\trm -rf "$\(top_builddir)/$\(SELFTEST_DIR_RW)" ; \\
\t\tfi; \\
\tfi
check-empty-selftest-rw:
\tif test -e $\(top_builddir)/$\(SELFTEST_DIR_RW) ; then \\
\t\tif test `find "$\(top_builddir)/$\(SELFTEST_DIR_RW)" | wc -l` -lt 1 ; then \\
\t\t\techo "FATAL: selftest did not tidy up the data it wrote" >&2 ; \\
\t\t\tfind "$\(top_builddir)/$\(SELFTEST_DIR_RW)" ; \\
\t\t\texit 2; \\
\t\telse true ; fi; \\
\telse true ; fi
check-local: src/$(project.prefix)_selftest $\(top_builddir)/$\(SELFTEST_DIR_RW) $\(top_builddir)/$\(SELFTEST_DIR_RO)
\t$\(LIBTOOL) --mode=execute $\(builddir)/src/$(project.prefix)_selftest
\t$\(MAKE) check-empty-selftest-rw
check-verbose: src/$(project.prefix)_selftest $\(top_builddir)/$\(SELFTEST_DIR_RW) $\(top_builddir)/$\(SELFTEST_DIR_RO)
\t$\(LIBTOOL) --mode=execute $\(builddir)/src/$(project.prefix)_selftest -v
\t$\(MAKE) check-empty-selftest-rw
# Run the selftest binary under valgrind to check for memory leaks
memcheck: src/$(project.prefix)_selftest $\(top_builddir)/$\(SELFTEST_DIR_RW) $\(top_builddir)/$\(SELFTEST_DIR_RO)
\t$\(LIBTOOL) --mode=execute valgrind --tool=memcheck \\
\t\t--leak-check=full --show-reachable=yes --error-exitcode=1 \\
\t\t--suppressions=$\(srcdir)/src/.valgrind.supp \\
\t\t$\(VALGRIND_OPTIONS) \\
\t\t$\(builddir)/src/$(project.prefix)_selftest
\t$\(MAKE) check-empty-selftest-rw
memcheck-verbose: src/$(project.prefix)_selftest $\(top_builddir)/$\(SELFTEST_DIR_RW) $\(top_builddir)/$\(SELFTEST_DIR_RO)
\t$\(LIBTOOL) --mode=execute valgrind --tool=memcheck \\
\t\t--leak-check=full --show-reachable=yes --error-exitcode=1 \\
\t\t--suppressions=$\(srcdir)/src/.valgrind.supp \\
\t\t$\(VALGRIND_OPTIONS) \\
\t\t$\(builddir)/src/$(project.prefix)_selftest -v
\t$\(MAKE) check-empty-selftest-rw
# Run the selftest binary under valgrind to check for performance leaks
callcheck: src/$(project.prefix)_selftest $\(top_builddir)/$\(SELFTEST_DIR_RW) $\(top_builddir)/$\(SELFTEST_DIR_RO)
\t$\(LIBTOOL) --mode=execute valgrind --tool=callgrind \\
\t\t$\(VALGRIND_OPTIONS) \\
\t\t$\(builddir)/src/$(project.prefix)_selftest
\t$\(MAKE) check-empty-selftest-rw
callcheck-verbose: src/$(project.prefix)_selftest $\(top_builddir)/$\(SELFTEST_DIR_RW) $\(top_builddir)/$\(SELFTEST_DIR_RO)
\t$\(LIBTOOL) --mode=execute valgrind --tool=callgrind \\
\t\t$\(VALGRIND_OPTIONS) \\
\t\t$\(builddir)/src/$(project.prefix)_selftest -v
\t$\(MAKE) check-empty-selftest-rw
# Run the selftest binary under gdb for debugging
debug: src/$(project.prefix)_selftest $\(top_builddir)/$\(SELFTEST_DIR_RW) $\(top_builddir)/$\(SELFTEST_DIR_RO)
\t$\(LIBTOOL) --mode=execute gdb -q \\
\t\t$\(builddir)/src/$(project.prefix)_selftest
\t$\(MAKE) check-empty-selftest-rw
debug-verbose: src/$(project.prefix)_selftest $\(top_builddir)/$\(SELFTEST_DIR_RW) $\(top_builddir)/$\(SELFTEST_DIR_RO)
\t$\(LIBTOOL) --mode=execute gdb -q \\
\t\t$\(builddir)/src/$(project.prefix)_selftest -v
\t$\(MAKE) check-empty-selftest-rw
# Run the selftest binary with verbose switch for tracing
animate: src/$(project.prefix)_selftest $\(top_builddir)/$\(SELFTEST_DIR_RW) $\(top_builddir)/$\(SELFTEST_DIR_RO)
\t$\(LIBTOOL) --mode=execute $\(builddir)/src/$(project.prefix)_selftest -v
\t$\(MAKE) check-empty-selftest-rw
animate-verbose: animate
if WITH_GCOV
coverage: src/$(project.prefix)_selftest $\(top_builddir)/$\(SELFTEST_DIR_RW) $\(top_builddir)/$\(SELFTEST_DIR_RO)
\t@echo "you had called configure --with-gcov"
\tlcov --base-directory . --directory . --zerocounters -q
\t\$(MAKE) check
\tlcov --base-directory . --directory . --capture -o coverage.info
\tlcov --remove coverage.info "/usr*" -o coverage.info
.if project.use_cxx
\tlcov --remove coverage.info "$(project.prefix)_selftest.$(project.source_ext)" -o coverage.info
.else
\tlcov --remove coverage.info "$(project.prefix)_selftest.$(project.source_ext)" -o coverage.info
.endif
\t\$(RM) -rf coverage/*
\tgenhtml -o coverage/ -t "$(project.name) test coverage" --num-spaces 4 coverage.info
else
coverage: src/$(project.prefix)_selftest
\t@echo "call make clean && configure --with-gcov to enable code coverage"
\t@exit 1
endif
# A series of tests that the codebase and recipes are pretty, easy
# to maintain and with predictable behavior. These generally are not
# expected to directly expose functional issues in the code, but
# still - there can be many reasons for failing such tests, and
# many lurking issues uncoverable by making code stylish again.
CHECK_STYLE_DEPS = check-gitignore
if WITH_CLANG_FORMAT
CHECK_STYLE_DEPS += clang-format-check
endif
check-style: \$(CHECK_STYLE_DEPS)
if WITH_CLANG_FORMAT
ALL_SOURCE_FILES = \$(wildcard \\
\t\$(top_srcdir)/src/*.c \\
\t\$(top_srcdir)/src/*.cc \\
\t\$(top_srcdir)/src/*.cpp \\
\t\$(top_srcdir)/src/*.h \\
\t\$(top_srcdir)/src/*.hpp \\
\t\$(top_srcdir)/tests/*.c \\
\t\$(top_srcdir)/tests/*.cc \\
\t\$(top_srcdir)/tests/*.cpp \\
\t\$(top_srcdir)/tests/*.h \\
\t\$(top_srcdir)/tests/*.hpp \\
\t\$(top_srcdir)/perf/*.c \\
\t\$(top_srcdir)/perf/*.cc \\
\t\$(top_srcdir)/perf/*.cpp \\
\t\$(top_srcdir)/perf/*.h \\
\t\$(top_srcdir)/perf/*.hpp \\
\t\$(top_srcdir)/tools/*.c \\
\t\$(top_srcdir)/tools/*.cc \\
\t\$(top_srcdir)/tools/*.cpp \\
\t\$(top_srcdir)/tools/*.h \\
\t\$(top_srcdir)/tools/*.hpp \\
\t\$(top_srcdir)/include/*.h \\
\t\$(top_srcdir)/include/*.hpp \\
)
# Check if any sources need to be fixed, report the filenames and an error code
clang-format-check: \$(ALL_SOURCE_FILES)
\t@if test -z "\$(CLANG_FORMAT)" ; then \\
\t\techo "FAILURE: CLANG_FORMAT program was not specified or found" >&2 ; \\
\t\texit 1 ; \\
\tfi
\t@FAILED=0 ; IFS=";" ; IDS="`printf '\\n\\b'`" ; export IFS IDS; \\
\t for FILE in \$(ALL_SOURCE_FILES) ; do \\
\t\ttest -s \$\$FILE || continue ; \\
\t\t\$(CLANG_FORMAT) -style=file -output-replacements-xml "\$\$FILE" | grep "<replacement " >/dev/null && \\
\t\t{ echo "\$\$FILE is not correctly formatted" >&2 ; FAILED=1; } ; \\
\t done; \\
\t if test "\$\$FAILED" != 0 ; then \\
\t\texit 1 ; \\
\t fi
# Change source formatting
clang-format: \$(ALL_SOURCE_FILES)
\t@if test -z "\$(CLANG_FORMAT)" ; then \\
\t\techo "FAILURE: CLANG_FORMAT program was not specified or found" >&2 ; \\
\t\texit 1 ; \\
\tfi
\t\$(CLANG_FORMAT) -style=file -i \$(ALL_SOURCE_FILES)
# Change source formatting AND report the diff
clang-format-diff: clang-format
\tgit diff \$(ALL_SOURCE_FILES)
# A destructive (will change code in workspace) but informative check; this is
# primarily intended for CI temporary workspaces where mutilation is acceptable.
# The envvar/makearg CI_REQUIRE_GOOD_CLANG_FORMAT manages if this test is fatal.
clang-format-check-CI:
\t@echo "CI-checking code style ..." >&2
\t@if \$(MAKE) clang-format-check ; then \\
\t echo "SUCCESS : Style checks have passed" >&2 ; \\
\telse \\
\t echo "" >&2 ; \\
\t if test -n "\$(CLANG_FORMAT)" ; then \\
\t echo "Style mismatches were found by clang-format; detailing below:" >&2 ; \\
\t \$(MAKE) VERBOSE=1 clang-format-diff ; \\
\t fi ; \\
\t if test x"\$(CI_REQUIRE_GOOD_CLANG_FORMAT)" = xtrue ; then \\
\t echo "FAILED : Style checks have failed and CI_REQUIRE_GOOD_CLANG_FORMAT==true" >&2 ; \\
\t exit 1 ; \\
\t fi ; \\
\t echo "WARNING : Style checks have failed, but the result is not-fatal because CI_REQUIRE_GOOD_CLANG_FORMAT!=true" >&2 ; \\
\tfi
else
clang-format clang-format-check clang-format-diff:
\t@echo "Install the clang-format program, reconfigure and re-run this request"
\t@exit 1
clang-format-check-CI:
\t@echo "Install the clang-format program, reconfigure and re-run this request"
\t@if test x"\$(CI_REQUIRE_GOOD_CLANG_FORMAT)" = xtrue ; then \\
\t echo "FAILED : Style checks have failed and CI_REQUIRE_GOOD_CLANG_FORMAT==true" >&2 ; \\
\t exit 1 ; \\
\t fi ; \\
\t echo "WARNING : Style checks have failed, but the result is not-fatal because CI_REQUIRE_GOOD_CLANG_FORMAT!=true" >&2
endif
# Note: analysis is not a target executed by default, so there is no
# safety-net for the "cppcheck.xml" recipe; there is one for the wrapper.
# A developer is expected to install tools in build environment, if needed.
# The results can be used to produce some statistics how project quality
# changes over many builds (with a relevant Jenkins plugin, for example).
if WITH_CPPCHECK
cppcheck: cppcheck.xml
else
cppcheck:
\t@echo "NOT ENABLED: cppcheck static analysis. Please install the toolkit and reconfigure, and/or make cppcheck.xml directly."
endif
cppcheck.xml:
\t@echo "Performing cppcheck static analysis..."
.if project.use_cxx
\tcppcheck --std=c++11 --enable=all --inconclusive --xml --xml-version=2 . 2>"$@"
.else
\tcppcheck --enable=all --inconclusive --xml --xml-version=2 . 2>"$@"
.endif
\t@echo "The cppcheck static analysis is done"
# Note: this recipe tests that the Git-based workspace reports no changed
# or untracked files - meaning there are no unexpected behaviors in the
# recipes (when checking after a build), and nothing was missed while
# updating the project structure (when checking in the midst of development
# or after regenerating the zproject skeletons), for example. For best
# results, developers are advised to also run this after executing their
# tests, to make sure they are stateless and clean as well. Caller may
# export envvar (or pass make argument) CI_REQUIRE_GOOD_GITIGNORE=false
# to explicitly disable fatality of this check, while still logging it.
# This recipe is "stateless" by itself, not causing any workspace changes:
check-gitignore:
\t@(if which git >/dev/null 2>&1 ; then \\
\t RES=0; \\
\t echo "Checking for untracked and not-ignored files in the workspace (should have no output below)..."; \\
\t git status -s | egrep '^\\?\\? ' && RES=1 ; \\
\t echo "Checking for modified tracked files in the workspace (should have no output below)..."; \\
\t git status -s | egrep '^ *M ' && RES=1 && git diff | cat ; \\
\t if [ "$$RES" = 0 ]; then \\
\t echo "PASS: $@"; exit 0 ; \\
\t else \\
\t if [ x"\$(CI_REQUIRE_GOOD_GITIGNORE)" = xfalse ] ; then \\
\t echo "WARNING: $@ found newly changed or untracked and not-ignored files (not a test failure due to CI_REQUIRE_GOOD_GITIGNORE==false)"; exit 0 ; \\
\t fi; \\
\t echo "FAIL: $@ (see workspace checks above)"; exit 1; \\
\t fi; \\
\t else \\
\t echo "SKIP: $@ (no git)"; exit 0 ; \\
\t fi )
# This calls the recipe above after building the project products and
# the selftest binary, and preparing the workspace for self-testing:
check-gitignore-all: all src/$(project.prefix)_selftest $\(top_builddir)/$\(SELFTEST_DIR_RW) $\(top_builddir)/$\(SELFTEST_DIR_RO)
\t$@\$(MAKE) check-gitignore
.insert_snippet ("Makemodule")
$(project.GENERATED_WARNING_HEADER:)
.close
.#
.#
.#
.# Create something that the developer can commit as the empty selftest-ro
.# directory, so the makefile EXTRA_DIST is always possible
.directory.create ("src/selftest-ro")
.output "src/selftest-ro/.gitkeep"
. echo "Please remember to use 'src/selftest-ro/' to store SCM-tracked selftest fixtures, and 'src/selftest-rw/' for files your selftest might create"
.close
.#
.#
.#
.# Generate infrastructure for services
.for project.main where ( defined(main.service) & main.service > 0 )
.if !defined(main.no_config) | main.no_config ?= 0
. if !file.exists ("src/$(main.name).cfg.in")
. output "src/$(main.name).cfg.in"
# $(main.name) configuration
# This is a skeleton created by zproject.
# You can add hand-written code here.
server
timeout = 10000 # Client connection timeout, msec
background = 0 # Run as background process
workdir = . # Working directory for daemon
verbose = 0 # Do verbose logging of activity?
. close
. else
. echo "NOT regenerating an existing src/$(main.name).cfg.in file; you might want to move yours out of the way and re-generate the project again to get updated settings"
. endif
.endif
.#
.#
.#
.endfor
.endmacro
.macro generate_libtool_files
.output "src/$(project.libname).pc.in"
$(project.GENERATED_WARNING_HEADER:)
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: $(project.libname)
Description: $(project.description:)
Version: @VERSION@
.if count (use)
Requires:\
. for use where use.optional = 0
@pkgconfig_name_$(use.libname:c)@\
. if (use.min_version <> '0.0.0')
>= $(use.min_version)\
. endif
. if defined(use.max_version) | defined(use.next_incompatible_version)
. if (use.min_version = '0.0.0')
>= 0.0.0
. endif
. if defined(use.max_version)
$(use.libname) <= $(use.max_version)\
. endif
. if defined(use.next_incompatible_version)
$(use.libname) < $(use.next_incompatible_version)\
. endif
. endif
. if !last ()
\
. endif
. endfor
.endif
Libs: -L${libdir} -l$(project.linkname)
Cflags: -I${includedir} @pkg_config_defines@
Libs.private: @pkg_config_libs_private@
$(project.GENERATED_WARNING_HEADER:)
.endmacro
.macro generate_mkman
.output "doc/mkman"
#! /usr/bin/perl
#
# mkman - Generates man pages from C source and header files.
#
# Syntax: './mkman srcname [outp rootsrcdir]'
# Must be executed in doc/ subdirectory under build workspace root.
# srcname - basename of .c or .cc source file located directly in the
# $rootsrcdir/src/ directory. For classes (MAN3) also implies
# a header (.h) file located directly in $rootsrcdir/include/.
# outp - (optional) filename without extension (will be chopped if
# provided) of the resulting TXT and DOC files; may be a
# slash-separated path e.g. for out-of-tree builds (distcheck).
# Defaults to: "$srcname"
# rootsrcdir - (optional) location of project source root (may differ
# from build root) where to look for input source-code files.
# Defaults to: ".." (good for in-tree builds)
#
# Copyright (c) 1996-2016 iMatix Corporation
# Copyright (c) 2016-2017 zproject community
#
# This is free software; you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation; either version 3 of the License, or (at your option) any later
# version.
#
# This software is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABIL-
# ITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
use File::Basename;
use Cwd;
sub pull {
local ($_) = @_;
if (/^(.*)(@[a-zA-Z0-9]+)(,(\\w*)\\s*)?/) {
$file = $1;
$tag = $2;
$opts = $4;
$text = "";
$ext = (fileparse("$file", qr/[^.]*/))[2];
die "Can't read '$file': $!"
unless open (SOURCE, $file);
while (<SOURCE>) {
if (/$tag/) {
while (<SOURCE>) {
last if /\\@discuss/ || /\\@end/ || /\\@ignore/ || /\\@header/;
$_ = " $_" if ($opts eq "code");
s/^ // if ($opts eq "left");
$_ = " $_" if ($opts eq "test");
s/^ / / if ($opts eq "test");
$text .= $_;
}
}
}
close (SOURCE);
# Add code fences for markdown highlighting
$text = "```$ext\\n$text```\\n" if (length $text) and ($opts eq "code" or $opts eq "test");
$text = "Please add '$tag' section in '$file'.\\n" unless $text;
return $text;
}
else {
print "E: bad pull request: $_\\n";
}
}
sub generate_manpage {
local ($name, $outp, $rootsrcdir) = @_;
$name = $1 if $name =~ /(\\w+)\\.\\w+/; # Chop off extensions
$outp = $1 if $outp =~ /^(.+)\\.[^\\.\\/]+$/;
$outp_basename = basename ($outp);
$outp_basename = $2 if $outp =~ /^(.*\\/)?(\\w+)$/;
if ($ENV{"V"} == "1") {
printf "D: generate_manpage() got name='$name' outp='$outp' outp_basename='$outp_basename' rootsrcdir='$rootsrcdir'\\n";
}
# Check if we're making the man page for a main program, or a class
$cat = 0; # Unknown category
$cat_text = "";
die "Can't open '" . cwd() . "/Makefile'"
unless open (MAKEFILE, "Makefile");
while (<MAKEFILE>) {
if (/MAN1.*$outp_basename\\.1/) {
.if project.use_cxx
$source = "$rootsrcdir/src/$name.$(project.source_ext)";
$header = "$rootsrcdir/src/$name.$(project.source_ext)";
.else
$source = "$rootsrcdir/src/$name.c";
$header = "$rootsrcdir/src/$name.c";
.endif
$cat = 1;
$cat_text = "Program for ";
last;
}
elsif (/MAN3.*$outp_basename\\.3/) {
.if project.use_cxx
$source = "$rootsrcdir/src/$name.$(project.source_ext)";
.else
$source = "$rootsrcdir/src/$name.c";
.endif
$header = "$rootsrcdir/include/$name.$(project.header_ext)";
$cat = 3;
$cat_text = "Class for ";
last;
}
}
close MAKEFILE;
die "The Makefile defined no manpage category for $outp_basename.1 or $name.3"
unless ($source ne "");
# Look for class title in 2nd line of source
# If there's no class file, leave hand-written man page alone
.if ! project.use_cxx
if (! open (SOURCE, $source)) {
# Support mixed-source projects (named C in config,
# but having both .c and .cc files in reality)
printf "Can't open C '$source', retry for C++\\n";
if ($header eq $source) {
$header .= "c";
}
$source .= "c"; # Retry for a *.cc filename
}
.endif
die "Can't open '$source'"
unless open (SOURCE, $source);
# NOTE: This duplication of lines is needed for proper work:
$_ = <SOURCE>;
$_ = <SOURCE>;
$title = "no title found";
$title = $1 if (/ \\w+ - (.*)/);
close (SOURCE);
printf " MKMAN[txt]\\t$source ";
if ($source ne $header) {
printf "+ $header ";
}
printf "\\t=> $outp.txt\\n";
# Open output file
die "Can't create '$outp.txt': $!"
unless open (OUTPUT, ">$outp.txt");
$underline = "=" x (length ($name) + 3);
$template = <<"END";
$name($cat)
$underline
NAME
----
$outp_basename - $cat_text$title
SYNOPSIS
--------
----
pull $header\\@interface
pull $source\\@interface,left
----
DESCRIPTION
-----------
pull $source\\@header,left
pull $source\\@discuss,left
EXAMPLE
-------
\.From $name\\_test method
----
pull $source\\@selftest,left
----
END
# Now process template
for (split /^/, $template) {
if (/^pull (.*)$/) {
print OUTPUT pull ($1);
}
else {
print OUTPUT $_;
}
}
close OUTPUT;
# Generate a simple text documentation for README.txt
printf " MKMAN[doc]\\t$source ";
if ($source ne $header) {
printf "+ $header ";
}
printf "\\t=> $outp.doc\\n";
die "Can't create '$outp.doc': $!"
unless open (OUTPUT, ">$outp.doc");
print OUTPUT "#### $outp_basename - $title\\n\\n";
print OUTPUT pull ("$source\\@header,left");
print OUTPUT "\\n";
print OUTPUT pull ("$source\\@discuss,left");
print OUTPUT "\\nThis is the class interface:\\n\\n";
print OUTPUT pull ("$header\\@interface,code");
print OUTPUT pull ("$source\\@interface,left");
print OUTPUT "\\nThis is the class self test code:\\n\\n";
print OUTPUT pull ("$source\\@selftest,test");
print OUTPUT "\\n";
close OUTPUT;
}
$name = shift (@ARGV);
$outp = shift (@ARGV);
if (!$outp) {
$outp=$name;
}
$rootsrcdir = shift (@ARGV);
if (!$rootsrcdir) {
$rootsrcdir="..";
}
if ($ENV{"V"} == "1") {
printf "D: got name='$name' outp='$outp' rootsrcdir='$rootsrcdir' from the start\\n";
}
generate_manpage ($name, $outp, $rootsrcdir);
.close
.chmod_x ("doc/mkman")
.endmacro
.function discover_manpages (project)
. man7 = "$(my.project.name).7"
. man3 = ""
. for my.project.class where scope = "public"
. man3 += " $(name:c).3"
. endfor
. man1 = ""
.### Note: here we keep the name rather than name:c so that the
.### manpages for binary programs match their name, at expense
.### of perhaps being built in a subdirectory.
. for my.project.main where scope = "public"
. man1 += " $(name).1"
. endfor
.endfunction
.macro generate_man_pages
.output "doc/Makefile.am"
$(project.GENERATED_WARNING_HEADER:)
.discover_manpages(project)
# Default target
all-local: doc
# Public programs ("main" tags in project.xml), auto-regenerated:
MAN1 =$(man1)
# Public classes ("class" tags in project.xml), auto-regenerated:
MAN3 =$(man3:no)
# Project overview, written by a human after initial skeleton:
# NOTE: stub doc/$(project.name).adoc is generated by GSL from project.xml
# and then comitted to SCM and maintained manually to describe the
# project (section 7 = Overview, conventions, and miscellaneous).
MAN7 = $(man7)
MAN_DOC = $\(MAN1) $\(MAN3) $\(MAN7)
# Assumption: the single .7 page only covers the project and is maintained
# manually. The SCM-tracked text source file name uses an .adoc extension
# so as not to conflict with generated .txt files (in cases when a "class"
# or a "main" name is same as overall project name).
MAN_TXT = $\(MAN7:%.7=%.adoc)
EXTRA_DIST = asciidoc.conf mkman
if INSTALL_MAN
dist_man_MANS = $\(MAN_DOC)
endif
if BUILD_DOC
MAN_TXT += $\(MAN1:%.1=%.txt)
MAN_TXT += $\(MAN3:%.3=%.txt)
DISTCLEANFILES = $\(MAN_DOC)
dist-hook : $\(MAN_DOC)
SUFFIXES=.txt .adoc .xml .xml7 .1 .3 .7
\.txt.xml:
\tasciidoc -d manpage -b docbook -f $\(srcdir)/asciidoc.conf \\
-a$(project.name)_version=@PACKAGE_VERSION@ -o$@ $<
\.xml.1:
\txmlto -o $\(@D) man $<
\.xml.3:
\txmlto -o $\(@D) man $<
# Special handling for project overview whose basename may collide
# with a main or class name
\.adoc.xml7:
\tasciidoc -d manpage -b docbook -f $\(srcdir)/asciidoc.conf \\
-a$(project.name)_version=@PACKAGE_VERSION@ -o$@ $<
\.xml7.7:
\txmlto -o $\(@D) man $<
# List of *.txt and *.doc files generated during build from comments
# in project program source files and further processed into manpages.
GENERATED_DOCS =
# No-op, docs and texts are generated by mkman in one shot - just
# make a dependency that can not parallelize and break stuff.
# Also, to be validly processed, the dependency must have SOME payload
\.txt.doc:
\t@true
.for project.class where scope = "public"
GENERATED_DOCS += $(name:c).txt $(name:c).doc
. if file.exists ("src/$(name:$(project.filename_prettyprint)).$(project.source_ext)")
$(name:c).txt: $\(top_srcdir)/src/$(name:$(project.filename_prettyprint)).$(project.source_ext)
. else
$(name:c).txt: $\(top_srcdir)/src/$(name:$(project.filename_prettyprint)).c
. endif
\t"$\(srcdir)/mkman" "$(name:$(project.filename_prettyprint))" "$\(builddir)/$(name:c).txt" "$\(srcdir)/.."
.endfor
### Note: for mains, we keep the source name rather than flattened name:c
### so that the manpages for binary programs match their name, at expense
### of perhaps being built in a subdirectory under doc/.
.for project.main where scope = "public"
GENERATED_DOCS += $(name).txt $(name).doc
. if file.exists ("src/$(name:$(project.filename_prettyprint)).$(project.source_ext)")
$(name).txt: $\(top_srcdir)/src/$(name:$(project.filename_prettyprint)).$(project.source_ext)
. else
$(name).txt: $\(top_srcdir)/src/$(name:$(project.filename_prettyprint)).c
. endif
\tmkdir -p "$\(builddir)/$\(@D)"
\t"$\(srcdir)/mkman" "$(name:$(project.filename_prettyprint))" "$\(builddir)/$(name).txt" "$\(srcdir)/.."
.endfor
clean-local:
\trm -f *.1 *.3 *.7 $\(GENERATED_DOCS)
doc: $\(GENERATED_DOCS)
else
doc:
\t@echo "SKIPPING documentation generation and formatting (BUILD_DOC was not required and/or tools are missing)" >&2
endif
EXTRA_DIST += $\(MAN_TXT)
$(project.GENERATED_WARNING_HEADER:)
.output "doc/.gitignore"
$(project.GENERATED_WARNING_HEADER:)
# Ignore the generated manpages and intermediate files
*.1
*.3
*.7
*.xml
*.xml7
# Ignore the source doc texts generated from program sources
.for project.class where scope = "public"
$(name:c).txt
$(name:c).doc
.endfor
.for project.main where scope = "public"
$(name).txt
$(name).doc
.endfor
# Make sure to track the manually maintained project description
\!*.adoc
$(project.GENERATED_WARNING_HEADER:)
.output "doc/asciidoc.conf"
$(project.GENERATED_WARNING_HEADER:)
[paradef-default]
literal-style=template="literalparagraph"
[macros]
(?su)[\\\\]?(?P<name>link$(project.name:c)):(?P<target>\\S*?)\\[(?P<attrlist>.*?)\\]=
ifdef::backend-docbook[]
[link$(project.name:c)-inlinemacro]
{0%{target}}
{0#<citerefentry>}
{0#<refentrytitle>{target}</refentrytitle><manvolnum>{0}</manvolnum>}
{0#</citerefentry>}
endif::backend-docbook[]
ifdef::backend-xhtml11[]
[link$(project.name:c)-inlinemacro]
<a href="{target}.html">{target}{0?({0})}</a>
endif::backend-xhtml11[]
ifdef::doctype-manpage[]
ifdef::backend-docbook[]
[header]
template::[header-declarations]
<refentry>
<refmeta>
<refentrytitle>{mantitle}</refentrytitle>
<manvolnum>{manvolnum}</manvolnum>
<refmiscinfo class="source">$(project.name:Pascal)</refmiscinfo>
<refmiscinfo class="version">{$(project.name:c)_version}</refmiscinfo>
<refmiscinfo class="manual">$(project.name:Pascal) Manual</refmiscinfo>
</refmeta>
<refnamediv>
<refname>{manname}</refname>
<refpurpose>{manpurpose}</refpurpose>
</refnamediv>
[footer]
<refsect1 id="_authors">
<title>AUTHORS</title>
<simpara>The $(project.name) manual was written by the authors in the AUTHORS file.</simpara>
</refsect1>
<refsect1 id="_resources">
<title>RESOURCES</title>
<simpara>Main web site: <ulink url=""></ulink></simpara>
<simpara>Report bugs to the email &lt;<ulink url="mailto:$(project.email)">$(project.email)</ulink>&gt;</simpara>
</refsect1>
<refsect1 id="_copyright">
<title>COPYRIGHT</title>
<simpara>$(project->license.) <literal>LICENSE</literal> included with the $(project.name) distribution.</simpara>
</refsect1>
</refentry>
endif::backend-docbook[]
endif::doctype-manpage[]
.if !file.exists ("doc/$(project.name).adoc")
.output "doc/$(project.name).adoc"
Name(7)
=======
NAME
----
$(project.name) - Overview of $(project.description:)
SYNOPSIS
--------
Project $(project.name) aims to ... (short marketing pitch)
It delivers several programs with their respective man pages:
$(man1:no)
and public classes in a shared library:
$(man3:no)
Generally you can compile and link against it like this:
----
#include <$(project.header:)>
cc ['flags'] 'files' -l$(project.linkname) ['libraries']
----
DESCRIPTION
-----------
This is a skeleton document created by zproject, which will not be
regenerated automatically (by Makefiles nor project.xml re-parsing).
You should add hand-written text here to detail whatever applies to
Linux standard manpage Section 7 (note that other OSes may follow
a different standard with similar concepts, and extend the recipes
to package this document into a different section number):
----
7 Overview, conventions, and miscellaneous :
Overviews or descriptions of various topics, conventions
and protocols, character set standards, the standard
filesystem layout, and miscellaneous other things.
----
Classes
~~~~~~~
Something for developers to consider. Note there are separate man
pages generated for public classes during build with contents taken
from source code comments.
. echo "Do not forget to manually update and SCM-track the doc/$(project.name).adoc project overview document"
. if file.exists("doc/$(project.name).txt")
. echo "WARNING: a doc/$(project.name).txt exists - this may be an old name for this MAN7 page! (review and perhaps 'git mv doc/$(project.name).txt doc/$(project.name).adoc')"
. endif
.else
. echo "NOT regenerating an existing doc/$(project.name).adoc boilerplate file; but you probably should not care"
.endif
.endmacro
function target_autotools
directory.create ("src")
directory.create ("doc")
generate_autoconf_files ()
generate_automake_files ()
if count (class)
generate_libtool_files ()
endif
generate_mkman ()
generate_man_pages ()
endfunction