mapnik-config: improve mapnik-config.template.sh

- move template text from build.py into mapnik-config.template.sh,
  so that the resulting script is simply that template file after
  substitutions, instead of concatenation of two parts

- substitute using re.sub matching particular variables, instead of
  format % dict; this allows putting default values in the template
This commit is contained in:
Mickey Rose 2019-09-16 23:17:09 +02:00
parent c61d0d541d
commit a3086c06a5
2 changed files with 104 additions and 120 deletions

View file

@ -24,6 +24,7 @@ import os
import sys
from copy import copy
from subprocess import Popen, PIPE
from SCons.Environment import OverrideEnvironment
Import('env')
@ -46,51 +47,45 @@ if (GetMapnikLibVersion() != config_env['MAPNIK_VERSION_STRING']):
print ('Error: version.hpp mismatch (%s) to cached value (%s): please reconfigure mapnik' % (GetMapnikLibVersion(),config_env['MAPNIK_VERSION_STRING']))
Exit(1)
config_variables = '''#!/usr/bin/env bash
## variables
CONFIG_PREFIX="$( cd "$( dirname $( dirname "$0" ))" && pwd )"
CONFIG_MAPNIK_VERSION_STRING='%(version_string)s'
CONFIG_MAPNIK_VERSION='%(version)s'
CONFIG_GIT_REVISION='%(git_revision)s'
CONFIG_GIT_DESCRIBE='%(git_describe)s'
CONFIG_FONTS="%(fonts)s"
CONFIG_INPUT_PLUGINS="%(input_plugins)s"
CONFIG_MAPNIK_DEFINES='%(defines)s'
CONFIG_MAPNIK_LIBNAME='%(mapnik_libname)s'
CONFIG_MAPNIK_LIBPATH="%(mapnik_libpath)s"
CONFIG_DEP_LIBS='%(dep_libs)s'
CONFIG_MAPNIK_LDFLAGS="%(ldflags)s"
CONFIG_MAPNIK_INCLUDE="${CONFIG_PREFIX}/include -I${CONFIG_PREFIX}/include/mapnik/agg -I${CONFIG_PREFIX}/include/mapnik"
CONFIG_DEP_INCLUDES="%(dep_includes)s"
CONFIG_CXXFLAGS="%(cxxflags)s"
CONFIG_CXX='%(cxx)s'
CONFIG_MAPNIK_GDAL_DATA='%(found_gdal_data)s'
CONFIG_MAPNIK_PROJ_LIB='%(found_proj_data)s'
CONFIG_MAPNIK_ICU_DATA='%(found_icu_data)s'
'''
def write_config(configuration,template,config_file):
template = open(template,'r').read()
open(config_file,'w').write(config_variables % configuration + template)
def write_config(env, template_filename, config_filename):
"""
Load shell script `template_filename`, replace values in variable
assignments of the form `CONFIG_key='default'` with corresponding
value `env['key']`, and save the result as `config_filename`.
"""
with open(template_filename, 'r') as template_file:
template = template_file.read()
with open(config_filename, 'w') as config_file:
escape = env['ESCAPE']
def subst(matchobj):
key = matchobj.group(1)
val = env.get(key)
if val is None:
return matchobj.group(0)
else:
return 'CONFIG_%s=%s' % (key, escape(str(val)))
config = re.sub(r'^CONFIG_(\w+)=.*', subst, template, flags=re.M)
config_file.write(config)
try:
os.chmod(config_file,0o755)
os.chmod(config_filename, 0o755)
except: pass
cxxflags_raw = config_env['LIBMAPNIK_CXXFLAGS'];
template_env = OverrideEnvironment(config_env, {})
# strip any -Warning flags
cxxflags_cleaned = [x for x in config_env['LIBMAPNIK_CXXFLAGS']
if x.startswith('-Wp,') or not x.startswith('-W')]
# strip clang specific flags to avoid breaking gcc
# while it is not recommended to mix compilers, this nevertheless
# makes it easier to compile apps with gcc and mapnik-config against mapnik built with clang
to_remove = ['-Wno-unsequenced','-Wno-unknown-warning-option','-Wtautological-compare','-Wheader-hygiene']
cxxflags_cleaned = [item for item in config_env['LIBMAPNIK_CXXFLAGS'] if item not in to_remove];
cxxflags_cleaned = [x for x in cxxflags_cleaned if x != '-Qunused-arguments']
cxx_cleaned = config_env['CXX'].replace(' -Qunused-arguments', '')
cxxflags = ' '.join(cxxflags_cleaned)
template_env['CXXFLAGS'] = ' '.join(cxxflags_cleaned)
template_env['CXX'] = re.sub(r'^ccache +', '', cxx_cleaned)
defines = ' '.join(config_env['LIBMAPNIK_DEFINES'])
template_env['DEFINES'] = ' '.join(config_env['LIBMAPNIK_DEFINES'])
dep_includes = ''.join([' -I%s' % i for i in config_env['CPPPATH'] if not i.startswith('#')])
@ -98,77 +93,42 @@ dep_includes += ' '
if config_env['HAS_CAIRO']:
dep_includes += ''.join([' -I%s' % i for i in env['CAIRO_CPPPATHS'] if not i.startswith('#')])
template_env['DEP_INCLUDES'] = dep_includes
ldflags = ''.join([' -L%s' % i for i in config_env['LIBPATH'] if not i.startswith('#')])
ldflags += config_env['LIBMAPNIK_LINKFLAGS']
template_env['LDFLAGS'] = ldflags
dep_libs = ''.join([' -l%s' % i for i in env['LIBMAPNIK_LIBS']])
# remove local agg from public linking
dep_libs = dep_libs.replace('-lagg','')
git_revision = 'N/A'
git_describe = config_env['MAPNIK_VERSION_STRING']
template_env['DEP_LIBS'] = dep_libs
try:
git_cmd = "git rev-list --max-count=1 HEAD"
stdin, stderr = Popen(git_cmd, shell=True, stdout=PIPE, stderr=PIPE).communicate()
stdin, stderr = Popen("git rev-list --max-count=1 HEAD",
shell=True, universal_newlines=True,
stdout=PIPE, stderr=PIPE).communicate()
if not stderr:
git_revision = stdin.strip()
template_env["GIT_REVISION"] = stdin.strip()
git_cmd = "git describe"
stdin, stderr = Popen(git_cmd, shell=True, stdout=PIPE, stderr=PIPE).communicate()
stdin, stderr = Popen("git describe",
shell=True, universal_newlines=True,
stdout=PIPE, stderr=PIPE).communicate()
if not stderr:
git_describe = stdin.strip()
template_env["GIT_DESCRIBE"] = stdin.strip()
except:
pass
# for fonts and input plugins we should try
# to store the relative path, if feasible
fontspath = config_env['MAPNIK_FONTS']
lib_root = os.path.join(config_env['PREFIX'], config_env['LIBDIR_SCHEMA'])
if lib_root in fontspath:
fontspath = "${CONFIG_PREFIX}/" + os.path.relpath(fontspath,config_env['PREFIX'])
inputpluginspath = config_env['MAPNIK_INPUT_PLUGINS']
if lib_root in inputpluginspath:
inputpluginspath = "${CONFIG_PREFIX}/" + os.path.relpath(inputpluginspath,config_env['PREFIX'])
lib_path = "${CONFIG_PREFIX}/" + config_env['LIBDIR_SCHEMA']
found_gdal_data = config_env['QUERIED_GDAL_DATA']
found_proj_data = config_env['QUERIED_PROJ_LIB']
found_icu_data = config_env['QUERIED_ICU_DATA']
configuration = {
"git_revision": git_revision,
"git_describe": git_describe,
"version_string": config_env['MAPNIK_VERSION_STRING'],
"version": config_env['MAPNIK_VERSION'],
"mapnik_libname": env['MAPNIK_NAME'],
"mapnik_libpath": lib_path,
"ldflags": ldflags,
"dep_libs": dep_libs,
"dep_includes": dep_includes,
"fonts": fontspath,
"input_plugins": inputpluginspath,
"defines":defines,
"cxxflags":cxxflags,
"cxx":env['CXX'],
"found_gdal_data":found_gdal_data,
"found_proj_data":found_proj_data,
"found_icu_data":found_icu_data,
}
## if we are statically linking dependencies
## then they do not need to be reported in ldflags
#if env['RUNTIME_LINK'] == 'static':
# configuration['ldflags'] = ''
# configuration['dep_libs'] = ''
# template_env['LDFLAGS'] = ''
# template_env['DEP_LIBS'] = ''
template = 'mapnik-config.template.sh'
config_file = 'mapnik-config'
source = config_file
write_config(configuration,template,config_file)
write_config(template_env, template, config_file)
target_path = os.path.normpath(os.path.join(config_env['INSTALL_PREFIX'],'bin'))
full_target = os.path.join(target_path,config_file)

View file

@ -1,3 +1,40 @@
#! /usr/bin/env bash
set -eu
RUNTIME_PREFIX=$(cd -- "${BASH_SOURCE%"${BASH_SOURCE##*/}"}.." && pwd)
## CONFIG variables substituted from build script
CONFIG_MAPNIK_NAME="mapnik"
CONFIG_MAPNIK_VERSION="unknown"
CONFIG_MAPNIK_VERSION_STRING="unknown"
CONFIG_GIT_REVISION="N/A"
CONFIG_GIT_DESCRIBE="${CONFIG_MAPNIK_VERSION_STRING}"
CONFIG_PREFIX="/usr/local"
CONFIG_LIBDIR_SCHEMA="lib"
CONFIG_LIB_DIR_NAME="mapnik"
CONFIG_MAPNIK_LIB_BASE="${CONFIG_PREFIX}/${CONFIG_LIBDIR_SCHEMA}"
CONFIG_MAPNIK_LIB_DIR="${CONFIG_MAPNIK_LIB_BASE}/${CONFIG_LIB_DIR_NAME}"
CONFIG_MAPNIK_INPUT_PLUGINS="${CONFIG_MAPNIK_LIB_DIR}/input"
CONFIG_MAPNIK_FONTS="${CONFIG_MAPNIK_LIB_DIR}/fonts"
CONFIG_CXX="c++"
CONFIG_CXXFLAGS=
CONFIG_DEFINES=
CONFIG_LDFLAGS=
CONFIG_DEP_INCLUDES=
CONFIG_DEP_LIBS=
CONFIG_QUERIED_GDAL_DATA=
CONFIG_QUERIED_PROJ_LIB=
CONFIG_QUERIED_ICU_DATA=
## D.R.Y. variables
DRY_INCLUDES="-I${RUNTIME_PREFIX}/include -I${RUNTIME_PREFIX}/include/mapnik/agg -I${RUNTIME_PREFIX}/include/mapnik"
DRY_CFLAGS="${DRY_INCLUDES} ${CONFIG_DEP_INCLUDES} ${CONFIG_DEFINES} ${CONFIG_CXXFLAGS}"
DRY_LIBS="-L${RUNTIME_PREFIX}/${CONFIG_LIBDIR_SCHEMA} -l${CONFIG_MAPNIK_NAME}"
## program below
@ -35,31 +72,18 @@ EOF
exit $1
}
echoerr() { echo "$@" 1>&2; }
if test $# -eq 0; then
usage 1
fi
while test $# -gt 0; do
case "$1" in
esac
case "$1" in
--help)
-h| --help)
usage 0
;;
-h)
usage 0
;;
-v)
echo ${CONFIG_MAPNIK_VERSION_STRING}
;;
--version)
-v| --version)
echo ${CONFIG_MAPNIK_VERSION_STRING}
;;
@ -76,77 +100,77 @@ while test $# -gt 0; do
;;
--fonts)
echo ${CONFIG_FONTS}
printf '%s\n' "${CONFIG_MAPNIK_FONTS/#"$CONFIG_PREFIX"/$RUNTIME_PREFIX}"
;;
--input-plugins)
echo ${CONFIG_INPUT_PLUGINS}
printf '%s\n' "${CONFIG_MAPNIK_INPUT_PLUGINS/#"$CONFIG_PREFIX"/$RUNTIME_PREFIX}"
;;
--defines)
echo ${CONFIG_MAPNIK_DEFINES}
printf '%s\n' "${CONFIG_DEFINES}"
;;
--prefix)
echo ${CONFIG_PREFIX}
printf '%s\n' "${RUNTIME_PREFIX}"
;;
--lib-name)
echo ${CONFIG_MAPNIK_LIBNAME}
printf '%s\n' "${CONFIG_MAPNIK_NAME}"
;;
--libs)
echo -L${CONFIG_MAPNIK_LIBPATH} -l${CONFIG_MAPNIK_LIBNAME}
printf '%s\n' "${DRY_LIBS}"
;;
--dep-libs)
echo ${CONFIG_DEP_LIBS}
printf '%s\n' "${CONFIG_DEP_LIBS}"
;;
--ldflags)
echo ${CONFIG_MAPNIK_LDFLAGS}
printf '%s\n' "${CONFIG_LDFLAGS}"
;;
--includes)
echo -I${CONFIG_MAPNIK_INCLUDE}
printf '%s\n' "${DRY_INCLUDES}"
;;
--dep-includes)
echo ${CONFIG_DEP_INCLUDES}
printf '%s\n' "${CONFIG_DEP_INCLUDES}"
;;
--cxxflags)
echo ${CONFIG_CXXFLAGS}
printf '%s\n' "${CONFIG_CXXFLAGS}"
;;
--cflags)
echo -I${CONFIG_MAPNIK_INCLUDE} ${CONFIG_DEP_INCLUDES} ${CONFIG_MAPNIK_DEFINES} ${CONFIG_CXXFLAGS}
printf '%s\n' "${DRY_CFLAGS}"
;;
--cxx)
echo ${CONFIG_CXX}
printf '%s\n' "${CONFIG_CXX}"
;;
--all-flags)
echo -I${CONFIG_MAPNIK_INCLUDE} ${CONFIG_DEP_INCLUDES} ${CONFIG_MAPNIK_DEFINES} ${CONFIG_CXXFLAGS} -L${CONFIG_MAPNIK_LIBPATH} -l${CONFIG_MAPNIK_LIBNAME} ${CONFIG_MAPNIK_LDFLAGS} ${CONFIG_DEP_LIBS}
printf '%s\n' "${DRY_CFLAGS} ${DRY_LIBS} ${CONFIG_LDFLAGS} ${CONFIG_DEP_LIBS}"
;;
--gdal-data)
if [[ ${CONFIG_MAPNIK_GDAL_DATA:-unset} != "unset" ]]; then echo ${CONFIG_MAPNIK_GDAL_DATA}; fi;
printf "%s${CONFIG_QUERIED_GDAL_DATA:+\\n}" "${CONFIG_QUERIED_GDAL_DATA}"
;;
--proj-lib)
if [[ ${CONFIG_MAPNIK_PROJ_LIB:-unset} != "unset" ]]; then echo ${CONFIG_MAPNIK_PROJ_LIB}; fi;
printf "%s${CONFIG_QUERIED_PROJ_LIB:+\\n}" "${CONFIG_QUERIED_PROJ_LIB}"
;;
--icu-data)
if [[ ${CONFIG_MAPNIK_ICU_DATA:-unset} != "unset" ]]; then echo ${CONFIG_MAPNIK_ICU_DATA}; fi;
printf "%s${CONFIG_QUERIED_ICU_DATA:+\\n}" "${CONFIG_QUERIED_ICU_DATA}"
;;
*)
# push to stderr any invalid options
echo "unknown option $1" 1>&2;
;;
# push to stderr any invalid options
echo "unknown option $1" >&2
;;
esac
shift
done