From a3086c06a5f01ee30c078513b4072c337fa08643 Mon Sep 17 00:00:00 2001 From: Mickey Rose Date: Mon, 16 Sep 2019 23:17:09 +0200 Subject: [PATCH] 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 --- utils/mapnik-config/build.py | 130 ++++++------------ utils/mapnik-config/mapnik-config.template.sh | 94 ++++++++----- 2 files changed, 104 insertions(+), 120 deletions(-) diff --git a/utils/mapnik-config/build.py b/utils/mapnik-config/build.py index 141f354fd..f55d88896 100644 --- a/utils/mapnik-config/build.py +++ b/utils/mapnik-config/build.py @@ -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) diff --git a/utils/mapnik-config/mapnik-config.template.sh b/utils/mapnik-config/mapnik-config.template.sh index a1ef44b60..c201abe0f 100755 --- a/utils/mapnik-config/mapnik-config.template.sh +++ b/utils/mapnik-config/mapnik-config.template.sh @@ -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