diff --git a/SConstruct b/SConstruct index d5b9a15b8..3cde6c21f 100644 --- a/SConstruct +++ b/SConstruct @@ -105,28 +105,28 @@ pretty_dep_names = { # Core plugin build configuration # opts.AddVariables still hardcoded however... PLUGINS = { # plugins with external dependencies - # configured by calling project, hence 'path':None - 'postgis': {'default':True,'path':None,'inc':'libpq-fe.h','lib':'pq','lang':'C'}, - 'pgraster': {'default':True,'path':None,'inc':'libpq-fe.h','lib':'pq','lang':'C'}, - 'gdal': {'default':True,'path':None,'inc':'gdal_priv.h','lib':'gdal','lang':'C++'}, - 'ogr': {'default':True,'path':None,'inc':'ogrsf_frmts.h','lib':'gdal','lang':'C++'}, - 'sqlite': {'default':True,'path':'SQLITE','inc':'sqlite3.h','lib':'sqlite3','lang':'C'}, - # plugins without external dependencies requiring CheckLibWithHeader... - 'shape': {'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'}, - 'csv': {'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'}, - 'raster': {'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'}, - 'geojson': {'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'}, - 'topojson':{'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'} - } + # configured by calling project, hence 'path':None + 'postgis': {'default':True,'path':None,'inc':'libpq-fe.h','lib':'pq','lang':'C'}, + 'pgraster': {'default':True,'path':None,'inc':'libpq-fe.h','lib':'pq','lang':'C'}, + 'gdal': {'default':True,'path':None,'inc':'gdal_priv.h','lib':'gdal','lang':'C++'}, + 'ogr': {'default':True,'path':None,'inc':'ogrsf_frmts.h','lib':'gdal','lang':'C++'}, + 'sqlite': {'default':True,'path':'SQLITE','inc':'sqlite3.h','lib':'sqlite3','lang':'C'}, + # plugins without external dependencies requiring CheckLibWithHeader... + 'shape': {'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'}, + 'csv': {'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'}, + 'raster': {'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'}, + 'geojson': {'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'}, + 'topojson':{'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'} + } def init_environment(env): env.Decider('MD5-timestamp') env.SourceCode(".", None) if os.environ.get('RANLIB'): - env['RANLIB'] = os.environ['RANLIB'] + env['RANLIB'] = os.environ['RANLIB'] if os.environ.get('AR'): - env['AR'] = os.environ['AR'] + env['AR'] = os.environ['AR'] #### SCons build options and initial setup #### env = Environment(ENV=os.environ) @@ -142,58 +142,58 @@ def color_print(color,text,newline=True): # 4 - blue text = "\033[9%sm%s\033[0m" % (color,text) if not newline: - print text, + print text, else: - print text + print text def regular_print(color,text,newline=True): if not newline: - print text, + print text, else: - print text + print text def call(cmd, silent=False): stdin, stderr = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE).communicate() if not stderr: - return stdin.strip() + return stdin.strip() elif not silent: - color_print(1,'Problem encounted with SCons scripts, please post bug report to: https://github.com/mapnik/mapnik/issues \nError was: %s' % stderr) + color_print(1,'Problem encounted with SCons scripts, please post bug report to: https://github.com/mapnik/mapnik/issues \nError was: %s' % stderr) def strip_first(string,find,replace=''): if string.startswith(find): - return string.replace(find,replace,1) + return string.replace(find,replace,1) return string # http://www.scons.org/wiki/InstallTargets def create_uninstall_target(env, path, is_glob=False): if 'uninstall' in COMMAND_LINE_TARGETS: - if is_glob: - all_files = Glob(path,strings=True) - for filei in all_files: - env.Command( "uninstall-"+filei, filei, - [ - Delete("$SOURCE"), - ]) - env.Alias("uninstall", "uninstall-"+filei) - else: - if os.path.exists(path): - env.Command( "uninstall-"+path, path, - [ - Delete("$SOURCE"), - ]) - env.Alias("uninstall", "uninstall-"+path) + if is_glob: + all_files = Glob(path,strings=True) + for filei in all_files: + env.Command( "uninstall-"+filei, filei, + [ + Delete("$SOURCE"), + ]) + env.Alias("uninstall", "uninstall-"+filei) + else: + if os.path.exists(path): + env.Command( "uninstall-"+path, path, + [ + Delete("$SOURCE"), + ]) + env.Alias("uninstall", "uninstall-"+path) def shortest_name(libs): name = '-'*200 for lib in libs: - if len(name) > len(lib): - name = lib + if len(name) > len(lib): + name = lib return name def rm_path(item,set,_env): for i in _env[set]: - if i.startswith(item): - _env[set].remove(i) + if i.startswith(item): + _env[set].remove(i) def sort_paths(items,priority): """Sort paths such that compiling and linking will globally prefer custom or local libs @@ -217,57 +217,57 @@ def sort_paths(items,priority): # parse types of paths into logical/meaningful groups # based on commonly encountered lib directories on linux and osx for i in items: - # internal paths for code kept inside - # the mapnik sources - if i.startswith('#'): - path_types['internal'].append(i) - # Mac OS X user installed frameworks - elif '/Library/Frameworks' in i: - path_types['frameworks'].append(i) - # various 'local' installs like /usr/local or /opt/local - elif 'local' in i or '/sw' in i: - if '/usr/local' in i: - path_types['user'].insert(0,i) - else: - path_types['user'].append(i) - # key system libs (likely others will fall into 'other') - elif '/usr/' in i or '/System' in i or i.startswith('/lib'): - path_types['system'].append(i) - # anything not yet matched... - # likely a combo of rare system lib paths and - # very custom user paths that should ideally be - # in 'user' - else: - path_types['other'].append(i) + # internal paths for code kept inside + # the mapnik sources + if i.startswith('#'): + path_types['internal'].append(i) + # Mac OS X user installed frameworks + elif '/Library/Frameworks' in i: + path_types['frameworks'].append(i) + # various 'local' installs like /usr/local or /opt/local + elif 'local' in i or '/sw' in i: + if '/usr/local' in i: + path_types['user'].insert(0,i) + else: + path_types['user'].append(i) + # key system libs (likely others will fall into 'other') + elif '/usr/' in i or '/System' in i or i.startswith('/lib'): + path_types['system'].append(i) + # anything not yet matched... + # likely a combo of rare system lib paths and + # very custom user paths that should ideally be + # in 'user' + else: + path_types['other'].append(i) # build up new list based on priority list for path in priority: - if path_types.has_key(path): - dirs = path_types[path] - new.extend(dirs) - path_types.pop(path) - else: - color_print(1,'\nSorry, "%s" is NOT a valid value for option "LINK_PRIORITY": values include: %s' % (path,','.join(path_types.keys()))) - color_print(1,'\tinternal: the local directory of the Mapnik sources (prefix #) (eg. used to link internal agg)') - color_print(1,'\tframeworks: on osx the /Library/Frameworks directory') - color_print(1,'\tuser: any path with "local" or "/sw" inside it') - color_print(1,'\tsystem: any path not yet matched with "/usr/","/lib", or "/System" (osx) inside it') - color_print(1,'\tother: any paths you specified not matched by criteria used to parse the others') - color_print(1,'\tother: any paths you specified not matched by criteria used to parse the others') - color_print(1,'The Default priority is: %s' % ','.join(DEFAULT_LINK_PRIORITY)) - color_print(1,'Any priority groups not listed will be appended to the list at the end') - Exit(1) + if path_types.has_key(path): + dirs = path_types[path] + new.extend(dirs) + path_types.pop(path) + else: + color_print(1,'\nSorry, "%s" is NOT a valid value for option "LINK_PRIORITY": values include: %s' % (path,','.join(path_types.keys()))) + color_print(1,'\tinternal: the local directory of the Mapnik sources (prefix #) (eg. used to link internal agg)') + color_print(1,'\tframeworks: on osx the /Library/Frameworks directory') + color_print(1,'\tuser: any path with "local" or "/sw" inside it') + color_print(1,'\tsystem: any path not yet matched with "/usr/","/lib", or "/System" (osx) inside it') + color_print(1,'\tother: any paths you specified not matched by criteria used to parse the others') + color_print(1,'\tother: any paths you specified not matched by criteria used to parse the others') + color_print(1,'The Default priority is: %s' % ','.join(DEFAULT_LINK_PRIORITY)) + color_print(1,'Any priority groups not listed will be appended to the list at the end') + Exit(1) # append remaining paths potentially not requested # by any custom priority list defined by user for k,v in path_types.items(): - new.extend(v) + new.extend(v) return new def pretty_dep(dep): pretty = pretty_dep_names.get(dep) if pretty: - return '%s (%s)' % (dep,pretty) + return '%s (%s)' % (dep,pretty) elif 'boost' in dep: - return '%s (%s)' % (dep,'more info see: https://github.com/mapnik/mapnik/wiki/Mapnik-Installation & http://www.boost.org') + return '%s (%s)' % (dep,'more info see: https://github.com/mapnik/mapnik/wiki/Mapnik-Installation & http://www.boost.org') return dep @@ -400,6 +400,7 @@ opts.AddVariables( BoolVariable('DEMO', 'Compile demo c++ application', 'True'), BoolVariable('PGSQL2SQLITE', 'Compile and install a utility to convert postgres tables to sqlite', 'False'), BoolVariable('SHAPEINDEX', 'Compile and install a utility to generate shapefile indexes in the custom format (.index) Mapnik supports', 'True'), + BoolVariable('CSVINDEX', 'Compile and install a utility to generate CSV file indexes in the custom format (.index) Mapnik supports', 'True'), BoolVariable('SVG2PNG', 'Compile and install a utility to generate render an svg file to a png on the command line', 'False'), BoolVariable('NIK2IMG', 'Compile and install a utility to generate render a map to an image', 'True'), BoolVariable('COLOR_PRINT', 'Print build status information in color', 'True'), @@ -410,74 +411,74 @@ opts.AddVariables( # these include all scons core variables as well as custom # env variables needed in SConscript files pickle_store = [# Scons internal variables - 'CC', # compiler user to check if c deps compile during configure - 'CXX', # C++ compiler to compile mapnik - 'CFLAGS', - 'CPPDEFINES', - 'CPPFLAGS', # c preprocessor flags - 'CPPPATH', - 'CXXFLAGS', # C++ flags built up during configure - 'LIBPATH', - 'LIBS', - 'LINKFLAGS', - 'CUSTOM_LDFLAGS', # user submitted - 'CUSTOM_DEFINES', # user submitted - 'CUSTOM_CXXFLAGS', # user submitted - 'CUSTOM_CFLAGS', # user submitted - 'MAPNIK_LIB_NAME', - 'LINK', - 'RUNTIME_LINK', - # Mapnik's SConstruct build variables - 'PLUGINS', - 'ABI_VERSION', - 'MAPNIK_VERSION_STRING', - 'MAPNIK_VERSION', - 'PLATFORM', - 'BOOST_ABI', - 'BOOST_APPEND', - 'LIBDIR_SCHEMA', - 'REQUESTED_PLUGINS', - 'COLOR_PRINT', - 'HAS_CAIRO', - 'MAPNIK_HAS_DLFCN', - 'HAS_PYCAIRO', - 'PYCAIRO_PATHS', - 'HAS_LIBXML2', - 'PKG_CONFIG_PATH', - 'PATH', - 'PATH_REMOVE', - 'PATH_REPLACE', - 'MAPNIK_LIB_DIR', - 'MAPNIK_LIB_DIR_DEST', - 'INSTALL_PREFIX', - 'MAPNIK_INPUT_PLUGINS', - 'MAPNIK_INPUT_PLUGINS_DEST', - 'MAPNIK_FONTS', - 'MAPNIK_FONTS_DEST', - 'MAPNIK_BUNDLED_SHARE_DIRECTORY', - 'MAPNIK_LIB_BASE', - 'MAPNIK_LIB_BASE_DEST', - 'EXTRA_FREETYPE_LIBS', - 'LIBMAPNIK_CPPATHS', - 'LIBMAPNIK_DEFINES', - 'LIBMAPNIK_CXXFLAGS', - 'CAIRO_LIBPATHS', - 'CAIRO_ALL_LIBS', - 'CAIRO_CPPPATHS', - 'GRID_RENDERER', - 'SVG_RENDERER', - 'SQLITE_LINKFLAGS', - 'BOOST_LIB_VERSION_FROM_HEADER', - 'BIGINT', - 'HOST' - ] + 'CC', # compiler user to check if c deps compile during configure + 'CXX', # C++ compiler to compile mapnik + 'CFLAGS', + 'CPPDEFINES', + 'CPPFLAGS', # c preprocessor flags + 'CPPPATH', + 'CXXFLAGS', # C++ flags built up during configure + 'LIBPATH', + 'LIBS', + 'LINKFLAGS', + 'CUSTOM_LDFLAGS', # user submitted + 'CUSTOM_DEFINES', # user submitted + 'CUSTOM_CXXFLAGS', # user submitted + 'CUSTOM_CFLAGS', # user submitted + 'MAPNIK_LIB_NAME', + 'LINK', + 'RUNTIME_LINK', + # Mapnik's SConstruct build variables + 'PLUGINS', + 'ABI_VERSION', + 'MAPNIK_VERSION_STRING', + 'MAPNIK_VERSION', + 'PLATFORM', + 'BOOST_ABI', + 'BOOST_APPEND', + 'LIBDIR_SCHEMA', + 'REQUESTED_PLUGINS', + 'COLOR_PRINT', + 'HAS_CAIRO', + 'MAPNIK_HAS_DLFCN', + 'HAS_PYCAIRO', + 'PYCAIRO_PATHS', + 'HAS_LIBXML2', + 'PKG_CONFIG_PATH', + 'PATH', + 'PATH_REMOVE', + 'PATH_REPLACE', + 'MAPNIK_LIB_DIR', + 'MAPNIK_LIB_DIR_DEST', + 'INSTALL_PREFIX', + 'MAPNIK_INPUT_PLUGINS', + 'MAPNIK_INPUT_PLUGINS_DEST', + 'MAPNIK_FONTS', + 'MAPNIK_FONTS_DEST', + 'MAPNIK_BUNDLED_SHARE_DIRECTORY', + 'MAPNIK_LIB_BASE', + 'MAPNIK_LIB_BASE_DEST', + 'EXTRA_FREETYPE_LIBS', + 'LIBMAPNIK_CPPATHS', + 'LIBMAPNIK_DEFINES', + 'LIBMAPNIK_CXXFLAGS', + 'CAIRO_LIBPATHS', + 'CAIRO_ALL_LIBS', + 'CAIRO_CPPPATHS', + 'GRID_RENDERER', + 'SVG_RENDERER', + 'SQLITE_LINKFLAGS', + 'BOOST_LIB_VERSION_FROM_HEADER', + 'BIGINT', + 'HOST' + ] # Add all other user configurable options to pickle pickle_store # We add here more options than are needed for the build stage # but helpful so that scons -h shows the exact cached options for opt in opts.options: if opt.key not in pickle_store: - pickle_store.append(opt.key) + pickle_store.append(opt.key) # Method of adding configure behavior to Scons adapted from: # http://freeorion.svn.sourceforge.net/svnroot/freeorion/trunk/FreeOrion/SConstruct @@ -509,24 +510,24 @@ opts.Update(env) # if we are not configuring overwrite environment with pickled settings if not force_configure: if os.path.exists(SCONS_CONFIGURE_CACHE): - try: - pickled_environment = open(SCONS_CONFIGURE_CACHE, 'r') - pickled_values = pickle.load(pickled_environment) - for key, value in pickled_values.items(): - env[key] = value - preconfigured = True - except: - preconfigured = False + try: + pickled_environment = open(SCONS_CONFIGURE_CACHE, 'r') + pickled_values = pickle.load(pickled_environment) + for key, value in pickled_values.items(): + env[key] = value + preconfigured = True + except: + preconfigured = False else: - preconfigured = False + preconfigured = False # check for missing keys in pickled settings # which can occur when keys are added or changed between # rebuilds, e.g. for folks following trunk for opt in pickle_store: if not opt in env: - #print 'missing opt', opt - preconfigured = False + #print 'missing opt', opt + preconfigured = False # if custom arguments are supplied make sure to accept them if opts.args: @@ -539,8 +540,8 @@ if opts.args: elif preconfigured: if not HELP_REQUESTED: - color_print(4,'Using previous successful configuration...') - color_print(4,'Re-configure by running "python scons/scons.py configure".') + color_print(4,'Using previous successful configuration...') + color_print(4,'Re-configure by running "python scons/scons.py configure".') if env.has_key('COLOR_PRINT') and env['COLOR_PRINT'] == False: color_print = regular_print @@ -556,11 +557,11 @@ def prioritize_paths(context,silent=True): env = context.env prefs = env['LINK_PRIORITY'].split(',') if not silent: - context.Message( 'Sorting lib and inc compiler paths...') + context.Message( 'Sorting lib and inc compiler paths...') env['LIBPATH'] = sort_paths(env['LIBPATH'],prefs) env['CPPPATH'] = sort_paths(env['CPPPATH'],prefs) if silent: - context.did_show_result=1 + context.did_show_result=1 ret = context.Result( True ) return ret @@ -587,42 +588,42 @@ def parse_config(context, config, checks='--libs --cflags'): tool = config.lower().replace('_','-') toolname = tool if config in ('GDAL_CONFIG'): - toolname += ' %s' % checks + toolname += ' %s' % checks context.Message( 'Checking for %s... ' % toolname) cmd = '%s %s' % (env[config],checks) ret = context.TryAction(cmd)[0] parsed = False if ret: - try: - if 'gdal-config' in cmd: - env.ParseConfig(cmd) - # hack for potential -framework GDAL syntax - # which will not end up being added to env['LIBS'] - # and thus breaks knowledge below that gdal worked - # TODO - upgrade our scons logic to support Framework linking - if env['PLATFORM'] == 'Darwin': - value = call(cmd,silent=True) - if value and '-framework GDAL' in value: - env['LIBS'].append('gdal') - if os.path.exists('/Library/Frameworks/GDAL.framework/unix/lib'): - env['LIBPATH'].insert(0,'/Library/Frameworks/GDAL.framework/unix/lib') - if 'GDAL' in env.get('FRAMEWORKS',[]): - env["FRAMEWORKS"].remove("GDAL") - else: - env.ParseConfig(cmd) - parsed = True - except OSError, e: - ret = False - print ' (xml2-config not found!)' + try: + if 'gdal-config' in cmd: + env.ParseConfig(cmd) + # hack for potential -framework GDAL syntax + # which will not end up being added to env['LIBS'] + # and thus breaks knowledge below that gdal worked + # TODO - upgrade our scons logic to support Framework linking + if env['PLATFORM'] == 'Darwin': + value = call(cmd,silent=True) + if value and '-framework GDAL' in value: + env['LIBS'].append('gdal') + if os.path.exists('/Library/Frameworks/GDAL.framework/unix/lib'): + env['LIBPATH'].insert(0,'/Library/Frameworks/GDAL.framework/unix/lib') + if 'GDAL' in env.get('FRAMEWORKS',[]): + env["FRAMEWORKS"].remove("GDAL") + else: + env.ParseConfig(cmd) + parsed = True + except OSError, e: + ret = False + print ' (xml2-config not found!)' if not parsed: - if config in ('GDAL_CONFIG'): - # optional deps... - if tool not in env['SKIPPED_DEPS']: - env['SKIPPED_DEPS'].append(tool) - conf.rollback_option(config) - else: # freetype and libxml2, not optional - if tool not in env['MISSING_DEPS']: - env['MISSING_DEPS'].append(tool) + if config in ('GDAL_CONFIG'): + # optional deps... + if tool not in env['SKIPPED_DEPS']: + env['SKIPPED_DEPS'].append(tool) + conf.rollback_option(config) + else: # freetype and libxml2, not optional + if tool not in env['MISSING_DEPS']: + env['MISSING_DEPS'].append(tool) context.Result( ret ) return ret @@ -635,22 +636,22 @@ def get_pkg_lib(context, config, lib): ret = context.TryAction(cmd)[0] parsed = False if ret: - try: - value = call(cmd,silent=True) - if ' ' in value: - parts = value.split(' ') - if len(parts) > 1: - value = parts[1] - libnames = re.findall(libpattern,value) - if libnames: - libname = libnames[0] - else: - # osx 1.8 install gives '-framework GDAL' - libname = 'gdal' - except Exception, e: - ret = False - print ' unable to determine library name:'# %s' % str(e) - return None + try: + value = call(cmd,silent=True) + if ' ' in value: + parts = value.split(' ') + if len(parts) > 1: + value = parts[1] + libnames = re.findall(libpattern,value) + if libnames: + libname = libnames[0] + else: + # osx 1.8 install gives '-framework GDAL' + libname = 'gdal' + except Exception, e: + ret = False + print ' unable to determine library name:'# %s' % str(e) + return None context.Result( libname ) return libname @@ -661,15 +662,15 @@ def parse_pg_config(context, config): context.Message( 'Checking for %s... ' % tool) ret = context.TryAction(env[config])[0] if ret: - lib_path = call('%s --libdir' % env[config]) - inc_path = call('%s --includedir' % env[config]) - env.AppendUnique(CPPPATH = fix_path(inc_path)) - env.AppendUnique(LIBPATH = fix_path(lib_path)) - lpq = env['PLUGINS']['postgis']['lib'] - env.Append(LIBS = lpq) + lib_path = call('%s --libdir' % env[config]) + inc_path = call('%s --includedir' % env[config]) + env.AppendUnique(CPPPATH = fix_path(inc_path)) + env.AppendUnique(LIBPATH = fix_path(lib_path)) + lpq = env['PLUGINS']['postgis']['lib'] + env.Append(LIBS = lpq) else: - env['SKIPPED_DEPS'].append(tool) - conf.rollback_option(config) + env['SKIPPED_DEPS'].append(tool) + conf.rollback_option(config) context.Result( ret ) return ret @@ -678,8 +679,8 @@ def ogr_enabled(context): context.Message( 'Checking if gdal is ogr enabled... ') ret = context.TryAction('%s --ogr-enabled' % env['GDAL_CONFIG'])[0] if not ret: - if 'ogr' not in env['SKIPPED_DEPS']: - env['SKIPPED_DEPS'].append('ogr') + if 'ogr' not in env['SKIPPED_DEPS']: + env['SKIPPED_DEPS'].append('ogr') context.Result( ret ) return ret @@ -687,8 +688,8 @@ def rollback_option(context,variable): global opts env = context.env for item in opts.options: - if item.key == variable: - env[variable] = item.default + if item.key == variable: + env[variable] = item.default def FindBoost(context, prefixes, thread_flag): """Routine to auto-find boost header dir, lib dir, and library naming structure. @@ -703,72 +704,72 @@ def FindBoost(context, prefixes, thread_flag): env['BOOST_APPEND'] = str() if env['THREADING'] == 'multi': - search_lib = 'libboost_thread' + search_lib = 'libboost_thread' else: - search_lib = 'libboost_filesystem' + search_lib = 'libboost_filesystem' # note: must call normpath to strip trailing slash otherwise dirname # does not remove 'lib' and 'include' prefixes.insert(0,os.path.dirname(os.path.normpath(env['BOOST_INCLUDES']))) prefixes.insert(0,os.path.dirname(os.path.normpath(env['BOOST_LIBS']))) for searchDir in prefixes: - libItems = glob(os.path.join(searchDir, env['LIBDIR_SCHEMA'], '%s*.*' % search_lib)) - if not libItems: - libItems = glob(os.path.join(searchDir, 'lib/%s*.*' % search_lib)) - incItems = glob(os.path.join(searchDir, 'include/boost*/')) - if len(libItems) >= 1 and len(incItems) >= 1: - BOOST_LIB_DIR = os.path.dirname(libItems[0]) - BOOST_INCLUDE_DIR = incItems[0].rstrip('boost/') - shortest_lib_name = shortest_name(libItems) - match = re.search(r'%s(.*)\..*' % search_lib, shortest_lib_name) - if hasattr(match,'groups'): - BOOST_APPEND = match.groups()[0] - break + libItems = glob(os.path.join(searchDir, env['LIBDIR_SCHEMA'], '%s*.*' % search_lib)) + if not libItems: + libItems = glob(os.path.join(searchDir, 'lib/%s*.*' % search_lib)) + incItems = glob(os.path.join(searchDir, 'include/boost*/')) + if len(libItems) >= 1 and len(incItems) >= 1: + BOOST_LIB_DIR = os.path.dirname(libItems[0]) + BOOST_INCLUDE_DIR = incItems[0].rstrip('boost/') + shortest_lib_name = shortest_name(libItems) + match = re.search(r'%s(.*)\..*' % search_lib, shortest_lib_name) + if hasattr(match,'groups'): + BOOST_APPEND = match.groups()[0] + break msg = str() if BOOST_LIB_DIR: - msg += '\nFound boost libs: %s' % BOOST_LIB_DIR - env['BOOST_LIBS'] = BOOST_LIB_DIR + msg += '\nFound boost libs: %s' % BOOST_LIB_DIR + env['BOOST_LIBS'] = BOOST_LIB_DIR elif not env['BOOST_LIBS']: - env['BOOST_LIBS'] = '/usr/' + env['LIBDIR_SCHEMA'] - msg += '\nUsing default boost lib dir: %s' % env['BOOST_LIBS'] + env['BOOST_LIBS'] = '/usr/' + env['LIBDIR_SCHEMA'] + msg += '\nUsing default boost lib dir: %s' % env['BOOST_LIBS'] else: - msg += '\nUsing boost lib dir: %s' % env['BOOST_LIBS'] + msg += '\nUsing boost lib dir: %s' % env['BOOST_LIBS'] if BOOST_INCLUDE_DIR: - msg += '\nFound boost headers: %s' % BOOST_INCLUDE_DIR - env['BOOST_INCLUDES'] = BOOST_INCLUDE_DIR + msg += '\nFound boost headers: %s' % BOOST_INCLUDE_DIR + env['BOOST_INCLUDES'] = BOOST_INCLUDE_DIR elif not env['BOOST_INCLUDES']: - env['BOOST_INCLUDES'] = '/usr/include' - msg += '\nUsing default boost include dir: %s' % env['BOOST_INCLUDES'] + env['BOOST_INCLUDES'] = '/usr/include' + msg += '\nUsing default boost include dir: %s' % env['BOOST_INCLUDES'] else: - msg += '\nUsing boost include dir: %s' % env['BOOST_INCLUDES'] + msg += '\nUsing boost include dir: %s' % env['BOOST_INCLUDES'] if not env['BOOST_TOOLKIT'] and not env['BOOST_ABI'] and not env['BOOST_VERSION']: - if BOOST_APPEND: - msg += '\nFound boost lib name extension: %s' % BOOST_APPEND - env['BOOST_APPEND'] = BOOST_APPEND + if BOOST_APPEND: + msg += '\nFound boost lib name extension: %s' % BOOST_APPEND + env['BOOST_APPEND'] = BOOST_APPEND else: - # Creating BOOST_APPEND according to the Boost library naming order, - # which goes ---. See: - # http://www.boost.org/doc/libs/1_35_0/more/getting_started/unix-variants.html#library-naming - append_params = [''] - if env['BOOST_TOOLKIT']: append_params.append(env['BOOST_TOOLKIT']) - if thread_flag: append_params.append(thread_flag) - if env['BOOST_ABI']: append_params.append(env['BOOST_ABI']) - if env['BOOST_VERSION']: append_params.append(env['BOOST_VERSION']) + # Creating BOOST_APPEND according to the Boost library naming order, + # which goes ---. See: + # http://www.boost.org/doc/libs/1_35_0/more/getting_started/unix-variants.html#library-naming + append_params = [''] + if env['BOOST_TOOLKIT']: append_params.append(env['BOOST_TOOLKIT']) + if thread_flag: append_params.append(thread_flag) + if env['BOOST_ABI']: append_params.append(env['BOOST_ABI']) + if env['BOOST_VERSION']: append_params.append(env['BOOST_VERSION']) - # Constructing the BOOST_APPEND setting that will be used to find the - # Boost libraries. - if len(append_params) > 1: - env['BOOST_APPEND'] = '-'.join(append_params) - msg += '\nFound boost lib name extension: %s' % env['BOOST_APPEND'] + # Constructing the BOOST_APPEND setting that will be used to find the + # Boost libraries. + if len(append_params) > 1: + env['BOOST_APPEND'] = '-'.join(append_params) + msg += '\nFound boost lib name extension: %s' % env['BOOST_APPEND'] env.AppendUnique(CPPPATH = fix_path(env['BOOST_INCLUDES'])) env.AppendUnique(LIBPATH = fix_path(env['BOOST_LIBS'])) if env['COLOR_PRINT']: - msg = "\033[94m%s\033[0m" % (msg) + msg = "\033[94m%s\033[0m" % (msg) ret = context.Result(msg) return ret @@ -777,14 +778,14 @@ def CheckBoost(context, version, silent=False): v_arr = version.split(".") version_n = 0 if len(v_arr) > 0: - version_n += int(v_arr[0])*100000 + version_n += int(v_arr[0])*100000 if len(v_arr) > 1: - version_n += int(v_arr[1])*100 + version_n += int(v_arr[1])*100 if len(v_arr) > 2: - version_n += int(v_arr[2]) + version_n += int(v_arr[2]) if not silent: - context.Message('Checking for Boost version >= %s... ' % (version)) + context.Message('Checking for Boost version >= %s... ' % (version)) ret = context.TryRun(""" #include @@ -796,13 +797,13 @@ int main() """ % version_n, '.cpp')[0] if silent: - context.did_show_result=1 + context.did_show_result=1 context.Result(ret) return ret def CheckCairoHasFreetype(context, silent=False): if not silent: - context.Message('Checking for cairo freetype font support ... ') + context.Message('Checking for cairo freetype font support ... ') context.env.AppendUnique(CPPPATH=copy(env['CAIRO_CPPPATHS'])) ret = context.TryRun(""" @@ -820,15 +821,15 @@ int main() """, '.cpp')[0] if silent: - context.did_show_result=1 + context.did_show_result=1 context.Result(ret) for item in env['CAIRO_CPPPATHS']: - rm_path(item,'CPPPATH',context.env) + rm_path(item,'CPPPATH',context.env) return ret def CheckHasDlfcn(context, silent=False): if not silent: - context.Message('Checking for dlfcn.h support ... ') + context.Message('Checking for dlfcn.h support ... ') ret = context.TryCompile(""" #include @@ -840,7 +841,7 @@ int main() """, '.cpp') if silent: - context.did_show_result=1 + context.did_show_result=1 context.Result(ret) return ret @@ -865,7 +866,7 @@ return 0; def CheckBoostScopedEnum(context, silent=False): if not silent: - context.Message('Checking whether Boost was compiled with C++11 scoped enums ... ') + context.Message('Checking whether Boost was compiled with C++11 scoped enums ... ') ret = context.TryLink(""" #include @@ -877,7 +878,7 @@ int main() } """, '.cpp') if silent: - context.did_show_result=1 + context.did_show_result=1 context.Result(ret) return ret @@ -899,13 +900,13 @@ int main() context.did_show_result=1 result = ret[1].strip() if not result: - context.Result('error, could not get major and minor version from unicode/uversion.h') - return False + context.Result('error, could not get major and minor version from unicode/uversion.h') + return False major, minor = map(int,result.split('.')) if major >= 4 and minor >= 0: - color_print(4,'found: icu %s' % result) - return True + color_print(4,'found: icu %s' % result) + return True color_print(1,'\nFound insufficient icu version... %s' % result) return False @@ -928,24 +929,24 @@ int main() context.did_show_result=1 result = ret[1].strip() if not result: - context.Result('error, could not get version from hb.h') - return False + context.Result('error, could not get version from hb.h') + return False items = result.split(';') if items[0] == '1': - color_print(4,'found: HarfBuzz %s' % items[1]) - return True + color_print(4,'found: HarfBuzz %s' % items[1]) + return True color_print(1,'\nHarfbuzz >= %s required but found ... %s' % (HARFBUZZ_MIN_VERSION_STRING,items[1])) return False def boost_regex_has_icu(context): if env['RUNTIME_LINK'] == 'static': - # re-order icu libs to ensure linux linker is happy - for lib_name in ['icui18n',env['ICU_LIB_NAME'],'icudata']: - if lib_name in context.env['LIBS']: - context.env['LIBS'].remove(lib_name) - context.env.Append(LIBS=lib_name) + # re-order icu libs to ensure linux linker is happy + for lib_name in ['icui18n',env['ICU_LIB_NAME'],'icudata']: + if lib_name in context.env['LIBS']: + context.env['LIBS'].remove(lib_name) + context.env.Append(LIBS=lib_name) ret = context.TryRun(""" #include @@ -955,12 +956,12 @@ int main() { U_NAMESPACE_QUALIFIER UnicodeString ustr; try { - boost::u32regex pattern = boost::make_u32regex(ustr); + boost::u32regex pattern = boost::make_u32regex(ustr); } // an exception is fine, still indicates support is // likely compiled into regex catch (...) { - return 0; + return 0; } return 0; } @@ -969,7 +970,7 @@ int main() context.Message('Checking if boost_regex was built with ICU unicode support... ') context.Result(ret[0]) if ret[0]: - return True + return True return False def sqlite_has_rtree(context, silent=False): @@ -991,20 +992,20 @@ int main() rc = sqlite3_open(":memory:", &db); if (rc != SQLITE_OK) { - printf("error 1: %s\\n", sqlite3_errmsg(db)); + printf("error 1: %s\\n", sqlite3_errmsg(db)); } const char * sql = "create virtual table foo using rtree(pkid, xmin, xmax, ymin, ymax)"; rc = sqlite3_exec(db, sql, 0, 0, 0); if (rc != SQLITE_OK) { - printf("error 2: %s\\n", sqlite3_errmsg(db)); - sqlite3_close(db); + printf("error 2: %s\\n", sqlite3_errmsg(db)); + sqlite3_close(db); } else { - printf("yes, has rtree!\\n"); - sqlite3_close(db); - return 0; + printf("yes, has rtree!\\n"); + sqlite3_close(db); + return 0; } return -1; @@ -1012,12 +1013,12 @@ int main() """, '.c') if not silent: - context.Message('Checking if SQLite supports RTREE... ') + context.Message('Checking if SQLite supports RTREE... ') if silent: - context.did_show_result=1 + context.did_show_result=1 context.Result(ret[0]) if ret[0]: - return True + return True return False def supports_cxx11(context,silent=False): @@ -1034,54 +1035,54 @@ int main() """, '.cpp') if not silent: - context.Message('Checking if compiler (%s) supports -std=c++11 flag... ' % context.env.get('CXX','CXX')) + context.Message('Checking if compiler (%s) supports -std=c++11 flag... ' % context.env.get('CXX','CXX')) if silent: - context.did_show_result=1 + context.did_show_result=1 context.Result(ret[0]) if ret[0]: - return True + return True return False conf_tests = { 'prioritize_paths' : prioritize_paths, - 'CheckPKGConfig' : CheckPKGConfig, - 'CheckPKG' : CheckPKG, - 'CheckPKGVersion' : CheckPKGVersion, - 'FindBoost' : FindBoost, - 'CheckBoost' : CheckBoost, - 'CheckCairoHasFreetype' : CheckCairoHasFreetype, - 'CheckHasDlfcn' : CheckHasDlfcn, - 'GetBoostLibVersion' : GetBoostLibVersion, - 'parse_config' : parse_config, - 'parse_pg_config' : parse_pg_config, - 'ogr_enabled' : ogr_enabled, - 'get_pkg_lib' : get_pkg_lib, - 'rollback_option' : rollback_option, - 'icu_at_least_four_two' : icu_at_least_four_two, - 'harfbuzz_version' : harfbuzz_version, - 'boost_regex_has_icu' : boost_regex_has_icu, - 'sqlite_has_rtree' : sqlite_has_rtree, - 'supports_cxx11' : supports_cxx11, - 'CheckBoostScopedEnum' : CheckBoostScopedEnum, - } + 'CheckPKGConfig' : CheckPKGConfig, + 'CheckPKG' : CheckPKG, + 'CheckPKGVersion' : CheckPKGVersion, + 'FindBoost' : FindBoost, + 'CheckBoost' : CheckBoost, + 'CheckCairoHasFreetype' : CheckCairoHasFreetype, + 'CheckHasDlfcn' : CheckHasDlfcn, + 'GetBoostLibVersion' : GetBoostLibVersion, + 'parse_config' : parse_config, + 'parse_pg_config' : parse_pg_config, + 'ogr_enabled' : ogr_enabled, + 'get_pkg_lib' : get_pkg_lib, + 'rollback_option' : rollback_option, + 'icu_at_least_four_two' : icu_at_least_four_two, + 'harfbuzz_version' : harfbuzz_version, + 'boost_regex_has_icu' : boost_regex_has_icu, + 'sqlite_has_rtree' : sqlite_has_rtree, + 'supports_cxx11' : supports_cxx11, + 'CheckBoostScopedEnum' : CheckBoostScopedEnum, + } def GetMapnikLibVersion(): ver = [] is_pre = False for line in open('include/mapnik/version.hpp').readlines(): - if line.startswith('#define MAPNIK_MAJOR_VERSION'): - ver.append(line.split(' ')[2].strip()) - if line.startswith('#define MAPNIK_MINOR_VERSION'): - ver.append(line.split(' ')[2].strip()) - if line.startswith('#define MAPNIK_PATCH_VERSION'): - ver.append(line.split(' ')[2].strip()) - if line.startswith('#define MAPNIK_VERSION_IS_RELEASE'): - if line.split(' ')[2].strip() == "0": - is_pre = True + if line.startswith('#define MAPNIK_MAJOR_VERSION'): + ver.append(line.split(' ')[2].strip()) + if line.startswith('#define MAPNIK_MINOR_VERSION'): + ver.append(line.split(' ')[2].strip()) + if line.startswith('#define MAPNIK_PATCH_VERSION'): + ver.append(line.split(' ')[2].strip()) + if line.startswith('#define MAPNIK_VERSION_IS_RELEASE'): + if line.split(' ')[2].strip() == "0": + is_pre = True version_string = ".".join(ver) if is_pre: - version_string += '-pre' + version_string += '-pre' return version_string if not preconfigured: @@ -1089,40 +1090,40 @@ if not preconfigured: color_print(4,'Configuring build environment...') if not env['FAST']: - SetCacheMode('force') + SetCacheMode('force') if env['USE_CONFIG']: - if not env['CONFIG'].endswith('.py'): - color_print(1,'SCons CONFIG file specified is not a python file, will not be read...') - else: - # Accept more than one file as comma-delimited list - user_confs = env['CONFIG'].split(',') - # If they exist add the files to the existing `opts` - for conf in user_confs: - if os.path.exists(conf): - opts.files.append(conf) - color_print(4,"SCons CONFIG found: '%s', variables will be inherited..." % conf) - optfile = file(conf) - #print optfile.read().replace("\n", " ").replace("'","").replace(" = ","=") - optfile.close() + if not env['CONFIG'].endswith('.py'): + color_print(1,'SCons CONFIG file specified is not a python file, will not be read...') + else: + # Accept more than one file as comma-delimited list + user_confs = env['CONFIG'].split(',') + # If they exist add the files to the existing `opts` + for conf in user_confs: + if os.path.exists(conf): + opts.files.append(conf) + color_print(4,"SCons CONFIG found: '%s', variables will be inherited..." % conf) + optfile = file(conf) + #print optfile.read().replace("\n", " ").replace("'","").replace(" = ","=") + optfile.close() - elif not conf == SCONS_LOCAL_CONFIG: - # if default missing, no worries - # but if the default is overridden and the file is not found, give warning - color_print(1,"SCons CONFIG not found: '%s'" % conf) - # Recreate the base environment using modified `opts` - env = Environment(ENV=os.environ,options=opts) - init_environment(env) - env['USE_CONFIG'] = True + elif not conf == SCONS_LOCAL_CONFIG: + # if default missing, no worries + # but if the default is overridden and the file is not found, give warning + color_print(1,"SCons CONFIG not found: '%s'" % conf) + # Recreate the base environment using modified `opts` + env = Environment(ENV=os.environ,options=opts) + init_environment(env) + env['USE_CONFIG'] = True else: - color_print(4,'SCons USE_CONFIG specified as false, will not inherit variables python config file...') + color_print(4,'SCons USE_CONFIG specified as false, will not inherit variables python config file...') conf = Configure(env, custom_tests = conf_tests) if env['DEBUG']: - mode = 'debug mode' + mode = 'debug mode' else: - mode = 'release mode' + mode = 'release mode' env['PLATFORM'] = platform.uname()[0] color_print(4,"Configuring on %s in *%s*..." % (env['PLATFORM'],mode)) @@ -1147,7 +1148,7 @@ if not preconfigured: # previously a leading / was expected for LIB_DIR_NAME # now strip it to ensure expected behavior if env['LIB_DIR_NAME'].startswith(os.path.sep): - env['LIB_DIR_NAME'] = strip_first(env['LIB_DIR_NAME'],os.path.sep) + env['LIB_DIR_NAME'] = strip_first(env['LIB_DIR_NAME'],os.path.sep) # base install location env['MAPNIK_LIB_BASE'] = os.path.join(env['PREFIX'],env['LIBDIR_SCHEMA']) @@ -1157,9 +1158,9 @@ if not preconfigured: env['MAPNIK_INPUT_PLUGINS'] = os.path.join(env['MAPNIK_LIB_DIR'],'input') # fonts sub directory if env['SYSTEM_FONTS']: - env['MAPNIK_FONTS'] = os.path.normpath(env['SYSTEM_FONTS']) + env['MAPNIK_FONTS'] = os.path.normpath(env['SYSTEM_FONTS']) else: - env['MAPNIK_FONTS'] = os.path.join(env['MAPNIK_LIB_DIR'],'fonts') + env['MAPNIK_FONTS'] = os.path.join(env['MAPNIK_LIB_DIR'],'fonts') # install prefix is a pre-pended base location to # re-route the install and only intended for package building @@ -1172,9 +1173,9 @@ if not preconfigured: env['MAPNIK_LIB_DIR_DEST'] = os.path.join(env['MAPNIK_LIB_BASE_DEST'],env['LIB_DIR_NAME']) env['MAPNIK_INPUT_PLUGINS_DEST'] = os.path.join(env['MAPNIK_LIB_DIR_DEST'],'input') if env['SYSTEM_FONTS']: - env['MAPNIK_FONTS_DEST'] = os.path.normpath(env['SYSTEM_FONTS']) + env['MAPNIK_FONTS_DEST'] = os.path.normpath(env['SYSTEM_FONTS']) else: - env['MAPNIK_FONTS_DEST'] = os.path.join(env['MAPNIK_LIB_DIR_DEST'],'fonts') + env['MAPNIK_FONTS_DEST'] = os.path.join(env['MAPNIK_LIB_DIR_DEST'],'fonts') if env['LINKING'] == 'static': env['MAPNIK_LIB_NAME'] = '${LIBPREFIX}${MAPNIK_NAME}${LIBSUFFIX}' @@ -1182,15 +1183,15 @@ if not preconfigured: env['MAPNIK_LIB_NAME'] = '${SHLIBPREFIX}${MAPNIK_NAME}${SHLIBSUFFIX}' if env['PKG_CONFIG_PATH']: - env['ENV']['PKG_CONFIG_PATH'] = fix_path(env['PKG_CONFIG_PATH']) - # otherwise this variable == os.environ["PKG_CONFIG_PATH"] + env['ENV']['PKG_CONFIG_PATH'] = fix_path(env['PKG_CONFIG_PATH']) + # otherwise this variable == os.environ["PKG_CONFIG_PATH"] if env['PATH']: - env['ENV']['PATH'] = fix_path(env['PATH']) + ':' + env['ENV']['PATH'] + env['ENV']['PATH'] = fix_path(env['PATH']) + ':' + env['ENV']['PATH'] if env['SYSTEM_FONTS']: - if not os.path.isdir(env['SYSTEM_FONTS']): - color_print(1,'Warning: Directory specified for SYSTEM_FONTS does not exist!') + if not os.path.isdir(env['SYSTEM_FONTS']): + color_print(1,'Warning: Directory specified for SYSTEM_FONTS does not exist!') # Set up for libraries and headers dependency checks env['CPPPATH'] = ['#include'] @@ -1198,8 +1199,8 @@ if not preconfigured: # set any custom cxxflags and ldflags to come first if sys.platform == 'darwin' and not env['HOST']: - DEFAULT_CXX11_CXXFLAGS += ' -stdlib=libc++' - DEFAULT_CXX11_LINKFLAGS = ' -stdlib=libc++' + DEFAULT_CXX11_CXXFLAGS += ' -stdlib=libc++' + DEFAULT_CXX11_LINKFLAGS = ' -stdlib=libc++' env.Append(CPPDEFINES = env['CUSTOM_DEFINES']) env.Append(CXXFLAGS = DEFAULT_CXX11_CXXFLAGS) env.Append(CXXFLAGS = env['CUSTOM_CXXFLAGS']) @@ -1211,11 +1212,11 @@ if not preconfigured: thread_suffix = 'mt' if env['PLATFORM'] == 'FreeBSD': - thread_suffix = '' - env.Append(LIBS = 'pthread') + thread_suffix = '' + env.Append(LIBS = 'pthread') if env['SHAPE_MEMORY_MAPPED_FILE']: - env.Append(CPPDEFINES = '-DSHAPE_MEMORY_MAPPED_FILE') + env.Append(CPPDEFINES = '-DSHAPE_MEMORY_MAPPED_FILE') # allow for mac osx /usr/lib/libicucore.dylib compatibility # requires custom supplied headers since Apple does not include them @@ -1224,365 +1225,365 @@ if not preconfigured: # http://www.opensource.apple.com/tarballs/ICU/ # then copy the headers to a location that mapnik will find if 'core' in env['ICU_LIB_NAME']: - env.Append(CPPDEFINES = '-DU_HIDE_DRAFT_API') - env.Append(CPPDEFINES = '-DUDISABLE_RENAMING') - if os.path.exists(env['ICU_LIB_NAME']): - #-sICU_LINK=" -L/usr/lib -licucore - env['ICU_LIB_NAME'] = os.path.basename(env['ICU_LIB_NAME']).replace('.dylib','').replace('lib','') + env.Append(CPPDEFINES = '-DU_HIDE_DRAFT_API') + env.Append(CPPDEFINES = '-DUDISABLE_RENAMING') + if os.path.exists(env['ICU_LIB_NAME']): + #-sICU_LINK=" -L/usr/lib -licucore + env['ICU_LIB_NAME'] = os.path.basename(env['ICU_LIB_NAME']).replace('.dylib','').replace('lib','') # Adding the required prerequisite library directories to the include path for # compiling and the library path for linking, respectively. for required in ('ICU', 'SQLITE', 'HB'): - inc_path = env['%s_INCLUDES' % required] - lib_path = env['%s_LIBS' % required] - env.AppendUnique(CPPPATH = fix_path(inc_path)) - env.AppendUnique(LIBPATH = fix_path(lib_path)) + inc_path = env['%s_INCLUDES' % required] + lib_path = env['%s_LIBS' % required] + env.AppendUnique(CPPPATH = fix_path(inc_path)) + env.AppendUnique(LIBPATH = fix_path(lib_path)) REQUIRED_LIBSHEADERS = [ - ['z', 'zlib.h', True,'C'], - [env['ICU_LIB_NAME'],'unicode/unistr.h',True,'C++'], - ['harfbuzz', 'harfbuzz/hb.h',True,'C++'] + ['z', 'zlib.h', True,'C'], + [env['ICU_LIB_NAME'],'unicode/unistr.h',True,'C++'], + ['harfbuzz', 'harfbuzz/hb.h',True,'C++'] ] if env.get('FREETYPE_LIBS') or env.get('FREETYPE_INCLUDES'): - REQUIRED_LIBSHEADERS.insert(0,['freetype','ft2build.h',True,'C']) - if env.get('FREETYPE_INCLUDES'): - inc_path = env['FREETYPE_INCLUDES'] - env.AppendUnique(CPPPATH = fix_path(inc_path)) - if env.get('FREETYPE_LIBS'): - lib_path = env['FREETYPE_LIBS'] - env.AppendUnique(LIBPATH = fix_path(lib_path)) + REQUIRED_LIBSHEADERS.insert(0,['freetype','ft2build.h',True,'C']) + if env.get('FREETYPE_INCLUDES'): + inc_path = env['FREETYPE_INCLUDES'] + env.AppendUnique(CPPPATH = fix_path(inc_path)) + if env.get('FREETYPE_LIBS'): + lib_path = env['FREETYPE_LIBS'] + env.AppendUnique(LIBPATH = fix_path(lib_path)) elif conf.parse_config('FREETYPE_CONFIG'): - # check if freetype links to bz2 - if env['RUNTIME_LINK'] == 'static': - temp_env = env.Clone() - temp_env['LIBS'] = [] - try: - # TODO - freetype-config accepts --static as of v2.5.3 - temp_env.ParseConfig('%s --libs' % env['FREETYPE_CONFIG']) - if 'bz2' in temp_env['LIBS']: - env['EXTRA_FREETYPE_LIBS'].append('bz2') - except OSError,e: - pass + # check if freetype links to bz2 + if env['RUNTIME_LINK'] == 'static': + temp_env = env.Clone() + temp_env['LIBS'] = [] + try: + # TODO - freetype-config accepts --static as of v2.5.3 + temp_env.ParseConfig('%s --libs' % env['FREETYPE_CONFIG']) + if 'bz2' in temp_env['LIBS']: + env['EXTRA_FREETYPE_LIBS'].append('bz2') + except OSError,e: + pass # libxml2 should be optional but is currently not # https://github.com/mapnik/mapnik/issues/913 if env.get('XMLPARSER') and env['XMLPARSER'] == 'libxml2': - if env.get('XML2_LIBS') or env.get('XML2_INCLUDES'): - OPTIONAL_LIBSHEADERS.insert(0,['libxml2','libxml/parser.h',True,'C']) - if env.get('XML2_INCLUDES'): - inc_path = env['XML2_INCLUDES'] - env.AppendUnique(CPPPATH = fix_path(inc_path)) - if env.get('XML2_LIBS'): - lib_path = env['XML2_LIBS'] - env.AppendUnique(LIBPATH = fix_path(lib_path)) - elif conf.parse_config('XML2_CONFIG',checks='--cflags'): - env['HAS_LIBXML2'] = True - else: - env['MISSING_DEPS'].append('libxml2') + if env.get('XML2_LIBS') or env.get('XML2_INCLUDES'): + OPTIONAL_LIBSHEADERS.insert(0,['libxml2','libxml/parser.h',True,'C']) + if env.get('XML2_INCLUDES'): + inc_path = env['XML2_INCLUDES'] + env.AppendUnique(CPPPATH = fix_path(inc_path)) + if env.get('XML2_LIBS'): + lib_path = env['XML2_LIBS'] + env.AppendUnique(LIBPATH = fix_path(lib_path)) + elif conf.parse_config('XML2_CONFIG',checks='--cflags'): + env['HAS_LIBXML2'] = True + else: + env['MISSING_DEPS'].append('libxml2') if not env['HOST']: - if conf.CheckHasDlfcn(): - env.Append(CPPDEFINES = '-DMAPNIK_HAS_DLCFN') - else: - env['SKIPPED_DEPS'].extend(['dlfcn']) + if conf.CheckHasDlfcn(): + env.Append(CPPDEFINES = '-DMAPNIK_HAS_DLCFN') + else: + env['SKIPPED_DEPS'].extend(['dlfcn']) OPTIONAL_LIBSHEADERS = [] if env['JPEG']: - OPTIONAL_LIBSHEADERS.append(['jpeg', ['stdio.h', 'jpeglib.h'], False,'C','-DHAVE_JPEG']) - inc_path = env['%s_INCLUDES' % 'JPEG'] - lib_path = env['%s_LIBS' % 'JPEG'] - env.AppendUnique(CPPPATH = fix_path(inc_path)) - env.AppendUnique(LIBPATH = fix_path(lib_path)) + OPTIONAL_LIBSHEADERS.append(['jpeg', ['stdio.h', 'jpeglib.h'], False,'C','-DHAVE_JPEG']) + inc_path = env['%s_INCLUDES' % 'JPEG'] + lib_path = env['%s_LIBS' % 'JPEG'] + env.AppendUnique(CPPPATH = fix_path(inc_path)) + env.AppendUnique(LIBPATH = fix_path(lib_path)) else: - env['SKIPPED_DEPS'].extend(['jpeg']) + env['SKIPPED_DEPS'].extend(['jpeg']) if env['PROJ']: - OPTIONAL_LIBSHEADERS.append(['proj', 'proj_api.h', False,'C','-DMAPNIK_USE_PROJ4']) - inc_path = env['%s_INCLUDES' % 'PROJ'] - lib_path = env['%s_LIBS' % 'PROJ'] - env.AppendUnique(CPPPATH = fix_path(inc_path)) - env.AppendUnique(LIBPATH = fix_path(lib_path)) + OPTIONAL_LIBSHEADERS.append(['proj', 'proj_api.h', False,'C','-DMAPNIK_USE_PROJ4']) + inc_path = env['%s_INCLUDES' % 'PROJ'] + lib_path = env['%s_LIBS' % 'PROJ'] + env.AppendUnique(CPPPATH = fix_path(inc_path)) + env.AppendUnique(LIBPATH = fix_path(lib_path)) else: - env['SKIPPED_DEPS'].extend(['proj']) + env['SKIPPED_DEPS'].extend(['proj']) if env['PNG']: - OPTIONAL_LIBSHEADERS.append(['png', 'png.h', False,'C','-DHAVE_PNG']) - inc_path = env['%s_INCLUDES' % 'PNG'] - lib_path = env['%s_LIBS' % 'PNG'] - env.AppendUnique(CPPPATH = fix_path(inc_path)) - env.AppendUnique(LIBPATH = fix_path(lib_path)) + OPTIONAL_LIBSHEADERS.append(['png', 'png.h', False,'C','-DHAVE_PNG']) + inc_path = env['%s_INCLUDES' % 'PNG'] + lib_path = env['%s_LIBS' % 'PNG'] + env.AppendUnique(CPPPATH = fix_path(inc_path)) + env.AppendUnique(LIBPATH = fix_path(lib_path)) else: - env['SKIPPED_DEPS'].extend(['png']) + env['SKIPPED_DEPS'].extend(['png']) if env['WEBP']: - OPTIONAL_LIBSHEADERS.append(['webp', 'webp/decode.h', False,'C','-DHAVE_WEBP']) - inc_path = env['%s_INCLUDES' % 'WEBP'] - lib_path = env['%s_LIBS' % 'WEBP'] - env.AppendUnique(CPPPATH = fix_path(inc_path)) - env.AppendUnique(LIBPATH = fix_path(lib_path)) + OPTIONAL_LIBSHEADERS.append(['webp', 'webp/decode.h', False,'C','-DHAVE_WEBP']) + inc_path = env['%s_INCLUDES' % 'WEBP'] + lib_path = env['%s_LIBS' % 'WEBP'] + env.AppendUnique(CPPPATH = fix_path(inc_path)) + env.AppendUnique(LIBPATH = fix_path(lib_path)) else: - env['SKIPPED_DEPS'].extend(['webp']) + env['SKIPPED_DEPS'].extend(['webp']) if env['TIFF']: - OPTIONAL_LIBSHEADERS.append(['tiff', 'tiff.h', False,'C','-DHAVE_TIFF']) - inc_path = env['%s_INCLUDES' % 'TIFF'] - lib_path = env['%s_LIBS' % 'TIFF'] - env.AppendUnique(CPPPATH = fix_path(inc_path)) - env.AppendUnique(LIBPATH = fix_path(lib_path)) + OPTIONAL_LIBSHEADERS.append(['tiff', 'tiff.h', False,'C','-DHAVE_TIFF']) + inc_path = env['%s_INCLUDES' % 'TIFF'] + lib_path = env['%s_LIBS' % 'TIFF'] + env.AppendUnique(CPPPATH = fix_path(inc_path)) + env.AppendUnique(LIBPATH = fix_path(lib_path)) else: - env['SKIPPED_DEPS'].extend(['tiff']) + env['SKIPPED_DEPS'].extend(['tiff']) # if requested, sort LIBPATH and CPPPATH before running CheckLibWithHeader tests if env['PRIORITIZE_LINKING']: - conf.prioritize_paths(silent=True) + conf.prioritize_paths(silent=True) # test for C++11 support, which is required if not env['HOST'] and not conf.supports_cxx11(): - color_print(1,"C++ compiler does not support C++11 standard (-std=c++11), which is required. Please upgrade your compiler to at least g++ 4.7 (ideally 4.8)") - Exit(1) + color_print(1,"C++ compiler does not support C++11 standard (-std=c++11), which is required. Please upgrade your compiler to at least g++ 4.7 (ideally 4.8)") + Exit(1) if not env['HOST']: - for libname, headers, required, lang in REQUIRED_LIBSHEADERS: - if not conf.CheckLibWithHeader(libname, headers, lang): - if required: - color_print(1, 'Could not find required header or shared library for %s' % libname) - env['MISSING_DEPS'].append(libname) - else: - color_print(4, 'Could not find optional header or shared library for %s' % libname) - env['SKIPPED_DEPS'].append(libname) - else: - if libname == env['ICU_LIB_NAME']: - if env['ICU_LIB_NAME'] not in env['MISSING_DEPS']: - if not conf.icu_at_least_four_two(): - # expression_string.cpp and map.cpp use fromUTF* function only available in >= ICU 4.2 - env['MISSING_DEPS'].append(env['ICU_LIB_NAME']) - elif libname == 'harfbuzz': - if not conf.harfbuzz_version(): - env['SKIPPED_DEPS'].append('harfbuzz-min-version') + for libname, headers, required, lang in REQUIRED_LIBSHEADERS: + if not conf.CheckLibWithHeader(libname, headers, lang): + if required: + color_print(1, 'Could not find required header or shared library for %s' % libname) + env['MISSING_DEPS'].append(libname) + else: + color_print(4, 'Could not find optional header or shared library for %s' % libname) + env['SKIPPED_DEPS'].append(libname) + else: + if libname == env['ICU_LIB_NAME']: + if env['ICU_LIB_NAME'] not in env['MISSING_DEPS']: + if not conf.icu_at_least_four_two(): + # expression_string.cpp and map.cpp use fromUTF* function only available in >= ICU 4.2 + env['MISSING_DEPS'].append(env['ICU_LIB_NAME']) + elif libname == 'harfbuzz': + if not conf.harfbuzz_version(): + env['SKIPPED_DEPS'].append('harfbuzz-min-version') if env['BIGINT']: - env.Append(CPPDEFINES = '-DBIGINT') + env.Append(CPPDEFINES = '-DBIGINT') if env['THREADING'] == 'multi': - thread_flag = thread_suffix + thread_flag = thread_suffix else: - thread_flag = '' + thread_flag = '' conf.FindBoost(BOOST_SEARCH_PREFIXES,thread_flag) has_boost_devel = True if not env['HOST']: - if not conf.CheckHeader(header='boost/version.hpp',language='C++'): - env['MISSING_DEPS'].append('boost development headers') - has_boost_devel = False + if not conf.CheckHeader(header='boost/version.hpp',language='C++'): + env['MISSING_DEPS'].append('boost development headers') + has_boost_devel = False if has_boost_devel: - if not env['HOST']: - env['BOOST_LIB_VERSION_FROM_HEADER'] = conf.GetBoostLibVersion() + if not env['HOST']: + env['BOOST_LIB_VERSION_FROM_HEADER'] = conf.GetBoostLibVersion() - # The other required boost headers. - BOOST_LIBSHEADERS = [ - ['system', 'boost/system/system_error.hpp', True], - ['filesystem', 'boost/filesystem/operations.hpp', True], - ['regex', 'boost/regex.hpp', True], - ['program_options', 'boost/program_options.hpp', False] - ] + # The other required boost headers. + BOOST_LIBSHEADERS = [ + ['system', 'boost/system/system_error.hpp', True], + ['filesystem', 'boost/filesystem/operations.hpp', True], + ['regex', 'boost/regex.hpp', True], + ['program_options', 'boost/program_options.hpp', False] + ] - if env['THREADING'] == 'multi': - BOOST_LIBSHEADERS.append(['thread', 'boost/thread/mutex.hpp', True]) - # on solaris the configure checks for boost_thread - # require the -pthreads flag to be able to check for - # threading support, so we add as a global library instead - # of attaching to cxxflags after configure - if env['PLATFORM'] == 'SunOS': - env.Append(CXXFLAGS = '-pthreads') + if env['THREADING'] == 'multi': + BOOST_LIBSHEADERS.append(['thread', 'boost/thread/mutex.hpp', True]) + # on solaris the configure checks for boost_thread + # require the -pthreads flag to be able to check for + # threading support, so we add as a global library instead + # of attaching to cxxflags after configure + if env['PLATFORM'] == 'SunOS': + env.Append(CXXFLAGS = '-pthreads') - # if requested, sort LIBPATH and CPPPATH before running CheckLibWithHeader tests - if env['PRIORITIZE_LINKING']: - conf.prioritize_paths(silent=True) + # if requested, sort LIBPATH and CPPPATH before running CheckLibWithHeader tests + if env['PRIORITIZE_LINKING']: + conf.prioritize_paths(silent=True) - if not env['HOST']: - # if the user is not setting custom boost configuration - # enforce boost version greater than or equal to BOOST_MIN_VERSION - if not conf.CheckBoost(BOOST_MIN_VERSION): - color_print(4,'Found boost lib version... %s' % env.get('BOOST_LIB_VERSION_FROM_HEADER') ) - color_print(1,'Boost version %s or greater is required' % BOOST_MIN_VERSION) - if not env['BOOST_VERSION']: - env['MISSING_DEPS'].append('boost version >= %s' % BOOST_MIN_VERSION) - else: - color_print(4,'Found boost lib version... %s' % env.get('BOOST_LIB_VERSION_FROM_HEADER') ) + if not env['HOST']: + # if the user is not setting custom boost configuration + # enforce boost version greater than or equal to BOOST_MIN_VERSION + if not conf.CheckBoost(BOOST_MIN_VERSION): + color_print(4,'Found boost lib version... %s' % env.get('BOOST_LIB_VERSION_FROM_HEADER') ) + color_print(1,'Boost version %s or greater is required' % BOOST_MIN_VERSION) + if not env['BOOST_VERSION']: + env['MISSING_DEPS'].append('boost version >= %s' % BOOST_MIN_VERSION) + else: + color_print(4,'Found boost lib version... %s' % env.get('BOOST_LIB_VERSION_FROM_HEADER') ) - if not env['HOST']: - for count, libinfo in enumerate(BOOST_LIBSHEADERS): - if not conf.CheckLibWithHeader('boost_%s%s' % (libinfo[0],env['BOOST_APPEND']), libinfo[1], 'C++'): - if libinfo[2]: - color_print(1,'Could not find required header or shared library for boost %s' % libinfo[0]) - env['MISSING_DEPS'].append('boost ' + libinfo[0]) - else: - color_print(4,'Could not find optional header or shared library for boost %s' % libinfo[0]) - env['SKIPPED_DEPS'].append('boost ' + libinfo[0]) + if not env['HOST']: + for count, libinfo in enumerate(BOOST_LIBSHEADERS): + if not conf.CheckLibWithHeader('boost_%s%s' % (libinfo[0],env['BOOST_APPEND']), libinfo[1], 'C++'): + if libinfo[2]: + color_print(1,'Could not find required header or shared library for boost %s' % libinfo[0]) + env['MISSING_DEPS'].append('boost ' + libinfo[0]) + else: + color_print(4,'Could not find optional header or shared library for boost %s' % libinfo[0]) + env['SKIPPED_DEPS'].append('boost ' + libinfo[0]) - # Boost versions before 1.57 are broken when the system package and - # Mapnik are compiled against different standards. On Ubuntu 14.04 - # using boost 1.54, it breaks scoped enums. It's a bit of a hack to - # just turn it off like this, but seems the only available work- - # around. See https://svn.boost.org/trac/boost/ticket/6779 for more - # details. - boost_version = [int(x) for x in env.get('BOOST_LIB_VERSION_FROM_HEADER').split('_')] - if not conf.CheckBoostScopedEnum(): - if boost_version < [1, 51]: - env.Append(CXXFLAGS = '-DBOOST_NO_SCOPED_ENUMS') - elif boost_version < [1, 57]: - env.Append(CXXFLAGS = '-DBOOST_NO_CXX11_SCOPED_ENUMS') + # Boost versions before 1.57 are broken when the system package and + # Mapnik are compiled against different standards. On Ubuntu 14.04 + # using boost 1.54, it breaks scoped enums. It's a bit of a hack to + # just turn it off like this, but seems the only available work- + # around. See https://svn.boost.org/trac/boost/ticket/6779 for more + # details. + boost_version = [int(x) for x in env.get('BOOST_LIB_VERSION_FROM_HEADER').split('_')] + if not conf.CheckBoostScopedEnum(): + if boost_version < [1, 51]: + env.Append(CXXFLAGS = '-DBOOST_NO_SCOPED_ENUMS') + elif boost_version < [1, 57]: + env.Append(CXXFLAGS = '-DBOOST_NO_CXX11_SCOPED_ENUMS') if not env['HOST'] and env['ICU_LIB_NAME'] not in env['MISSING_DEPS']: - # http://lists.boost.org/Archives/boost/2009/03/150076.php - # we need libicui18n if using static boost libraries, so it is - # important to try this check with the library linked - if conf.boost_regex_has_icu(): - # TODO - should avoid having this be globally defined... - env.Append(CPPDEFINES = '-DBOOST_REGEX_HAS_ICU') - else: - env['SKIPPED_DEPS'].append('boost_regex_icu') + # http://lists.boost.org/Archives/boost/2009/03/150076.php + # we need libicui18n if using static boost libraries, so it is + # important to try this check with the library linked + if conf.boost_regex_has_icu(): + # TODO - should avoid having this be globally defined... + env.Append(CPPDEFINES = '-DBOOST_REGEX_HAS_ICU') + else: + env['SKIPPED_DEPS'].append('boost_regex_icu') - for libname, headers, required, lang, define in OPTIONAL_LIBSHEADERS: - if not env['HOST']: - if not conf.CheckLibWithHeader(libname, headers, lang): - if required: - color_print(1, 'Could not find required header or shared library for %s' % libname) - env['MISSING_DEPS'].append(libname) - else: - color_print(4, 'Could not find optional header or shared library for %s' % libname) - env['SKIPPED_DEPS'].append(libname) - else: - env.Append(CPPDEFINES = define) - else: - env.Append(CPPDEFINES = define) + for libname, headers, required, lang, define in OPTIONAL_LIBSHEADERS: + if not env['HOST']: + if not conf.CheckLibWithHeader(libname, headers, lang): + if required: + color_print(1, 'Could not find required header or shared library for %s' % libname) + env['MISSING_DEPS'].append(libname) + else: + color_print(4, 'Could not find optional header or shared library for %s' % libname) + env['SKIPPED_DEPS'].append(libname) + else: + env.Append(CPPDEFINES = define) + else: + env.Append(CPPDEFINES = define) env['REQUESTED_PLUGINS'] = [ driver.strip() for driver in Split(env['INPUT_PLUGINS'])] SQLITE_HAS_RTREE = None if env['HOST']: - SQLITE_HAS_RTREE = True + SQLITE_HAS_RTREE = True CHECK_PKG_CONFIG = conf.CheckPKGConfig('0.15.0') if len(env['REQUESTED_PLUGINS']): - if env['HOST']: - for plugin in env['REQUESTED_PLUGINS']: - details = env['PLUGINS'][plugin] - if details['lib']: - env.AppendUnique(LIBS=details['lib']) - else: - color_print(4,'Checking for requested plugins dependencies...') - for plugin in env['REQUESTED_PLUGINS']: - details = env['PLUGINS'][plugin] - if plugin == 'gdal': - if conf.parse_config('GDAL_CONFIG',checks='--libs'): - conf.parse_config('GDAL_CONFIG',checks='--cflags') - libname = conf.get_pkg_lib('GDAL_CONFIG','gdal') - if libname: - if not conf.CheckLibWithHeader(libname, details['inc'], details['lang']): - env['SKIPPED_DEPS'].append('gdal') - if libname in env['LIBS']: - env['LIBS'].remove(libname) - else: - details['lib'] = libname - elif plugin == 'postgis' or plugin == 'pgraster': - if env.get('PG_LIBS') or env.get('PG_INCLUDES'): - libname = details['lib'] - if env.get('PG_INCLUDES'): - inc_path = env['PG_INCLUDES'] - env.AppendUnique(CPPPATH = fix_path(inc_path)) - if env.get('PG_LIBS'): - lib_path = env['PG_LIBS'] - env.AppendUnique(LIBPATH = fix_path(lib_path)) - if not conf.CheckLibWithHeader(libname, details['inc'], details['lang']): - env['SKIPPED_DEPS'].append(libname) - if libname in env['LIBS']: - env['LIBS'].remove(libname) - else: - details['lib'] = libname - else: - conf.parse_pg_config('PG_CONFIG') - elif plugin == 'ogr': - if conf.ogr_enabled(): - if conf.parse_config('GDAL_CONFIG',checks='--libs'): - conf.parse_config('GDAL_CONFIG',checks='--cflags') - libname = conf.get_pkg_lib('GDAL_CONFIG','ogr') - if libname: - if not conf.CheckLibWithHeader(libname, details['inc'], details['lang']): - if 'gdal' not in env['SKIPPED_DEPS']: - env['SKIPPED_DEPS'].append('gdal') - if libname in env['LIBS']: - env['LIBS'].remove(libname) - else: - details['lib'] = libname - elif details['path'] and details['lib'] and details['inc']: - backup = env.Clone().Dictionary() - # Note, the 'delete_existing' keyword makes sure that these paths are prepended - # to the beginning of the path list even if they already exist - incpath = env['%s_INCLUDES' % details['path']] - libpath = env['%s_LIBS' % details['path']] - env.PrependUnique(CPPPATH = fix_path(incpath),delete_existing=True) - env.PrependUnique(LIBPATH = fix_path(libpath),delete_existing=True) - if not conf.CheckLibWithHeader(details['lib'], details['inc'], details['lang']): - env.Replace(**backup) - env['SKIPPED_DEPS'].append(details['lib']) - if plugin == 'sqlite': - sqlite_backup = env.Clone().Dictionary() - # if statically linking, on linux we likely - # need to link sqlite to pthreads and dl - if env['RUNTIME_LINK'] == 'static' and not env['PLATFORM'] == 'Darwin': - if CHECK_PKG_CONFIG and conf.CheckPKG('sqlite3'): - sqlite_env = env.Clone() - try: - sqlite_env.ParseConfig('pkg-config --static --libs sqlite3') - for lib in sqlite_env['LIBS']: - if not lib in env['LIBS']: - env["SQLITE_LINKFLAGS"].append(lib) - env.Append(LIBS=lib) - except OSError,e: - for lib in ["sqlite3","dl","pthread"]: - if not lib in env['LIBS']: - env["SQLITE_LINKFLAGS"].append("lib") - env.Append(LIBS=lib) - else: - for lib in ["sqlite3","dl","pthread"]: - if not lib in env['LIBS']: - env["SQLITE_LINKFLAGS"].append("lib") - env.Append(LIBS=lib) - SQLITE_HAS_RTREE = conf.sqlite_has_rtree() - if not SQLITE_HAS_RTREE: - env.Replace(**sqlite_backup) - if details['lib'] in env['LIBS']: - env['LIBS'].remove(details['lib']) - env['SKIPPED_DEPS'].append('sqlite_rtree') - else: - env.Replace(**sqlite_backup) - elif details['lib'] and details['inc']: - if not conf.CheckLibWithHeader(details['lib'], details['inc'], details['lang']): - env['SKIPPED_DEPS'].append(details['lib']) + if env['HOST']: + for plugin in env['REQUESTED_PLUGINS']: + details = env['PLUGINS'][plugin] + if details['lib']: + env.AppendUnique(LIBS=details['lib']) + else: + color_print(4,'Checking for requested plugins dependencies...') + for plugin in env['REQUESTED_PLUGINS']: + details = env['PLUGINS'][plugin] + if plugin == 'gdal': + if conf.parse_config('GDAL_CONFIG',checks='--libs'): + conf.parse_config('GDAL_CONFIG',checks='--cflags') + libname = conf.get_pkg_lib('GDAL_CONFIG','gdal') + if libname: + if not conf.CheckLibWithHeader(libname, details['inc'], details['lang']): + env['SKIPPED_DEPS'].append('gdal') + if libname in env['LIBS']: + env['LIBS'].remove(libname) + else: + details['lib'] = libname + elif plugin == 'postgis' or plugin == 'pgraster': + if env.get('PG_LIBS') or env.get('PG_INCLUDES'): + libname = details['lib'] + if env.get('PG_INCLUDES'): + inc_path = env['PG_INCLUDES'] + env.AppendUnique(CPPPATH = fix_path(inc_path)) + if env.get('PG_LIBS'): + lib_path = env['PG_LIBS'] + env.AppendUnique(LIBPATH = fix_path(lib_path)) + if not conf.CheckLibWithHeader(libname, details['inc'], details['lang']): + env['SKIPPED_DEPS'].append(libname) + if libname in env['LIBS']: + env['LIBS'].remove(libname) + else: + details['lib'] = libname + else: + conf.parse_pg_config('PG_CONFIG') + elif plugin == 'ogr': + if conf.ogr_enabled(): + if conf.parse_config('GDAL_CONFIG',checks='--libs'): + conf.parse_config('GDAL_CONFIG',checks='--cflags') + libname = conf.get_pkg_lib('GDAL_CONFIG','ogr') + if libname: + if not conf.CheckLibWithHeader(libname, details['inc'], details['lang']): + if 'gdal' not in env['SKIPPED_DEPS']: + env['SKIPPED_DEPS'].append('gdal') + if libname in env['LIBS']: + env['LIBS'].remove(libname) + else: + details['lib'] = libname + elif details['path'] and details['lib'] and details['inc']: + backup = env.Clone().Dictionary() + # Note, the 'delete_existing' keyword makes sure that these paths are prepended + # to the beginning of the path list even if they already exist + incpath = env['%s_INCLUDES' % details['path']] + libpath = env['%s_LIBS' % details['path']] + env.PrependUnique(CPPPATH = fix_path(incpath),delete_existing=True) + env.PrependUnique(LIBPATH = fix_path(libpath),delete_existing=True) + if not conf.CheckLibWithHeader(details['lib'], details['inc'], details['lang']): + env.Replace(**backup) + env['SKIPPED_DEPS'].append(details['lib']) + if plugin == 'sqlite': + sqlite_backup = env.Clone().Dictionary() + # if statically linking, on linux we likely + # need to link sqlite to pthreads and dl + if env['RUNTIME_LINK'] == 'static' and not env['PLATFORM'] == 'Darwin': + if CHECK_PKG_CONFIG and conf.CheckPKG('sqlite3'): + sqlite_env = env.Clone() + try: + sqlite_env.ParseConfig('pkg-config --static --libs sqlite3') + for lib in sqlite_env['LIBS']: + if not lib in env['LIBS']: + env["SQLITE_LINKFLAGS"].append(lib) + env.Append(LIBS=lib) + except OSError,e: + for lib in ["sqlite3","dl","pthread"]: + if not lib in env['LIBS']: + env["SQLITE_LINKFLAGS"].append("lib") + env.Append(LIBS=lib) + else: + for lib in ["sqlite3","dl","pthread"]: + if not lib in env['LIBS']: + env["SQLITE_LINKFLAGS"].append("lib") + env.Append(LIBS=lib) + SQLITE_HAS_RTREE = conf.sqlite_has_rtree() + if not SQLITE_HAS_RTREE: + env.Replace(**sqlite_backup) + if details['lib'] in env['LIBS']: + env['LIBS'].remove(details['lib']) + env['SKIPPED_DEPS'].append('sqlite_rtree') + else: + env.Replace(**sqlite_backup) + elif details['lib'] and details['inc']: + if not conf.CheckLibWithHeader(details['lib'], details['inc'], details['lang']): + env['SKIPPED_DEPS'].append(details['lib']) - # re-append the local paths for mapnik sources to the beginning of the list - # to make sure they come before any plugins that were 'prepended' - env.PrependUnique(CPPPATH = '#include', delete_existing=True) - env.PrependUnique(LIBPATH = '#src', delete_existing=True) + # re-append the local paths for mapnik sources to the beginning of the list + # to make sure they come before any plugins that were 'prepended' + env.PrependUnique(CPPPATH = '#include', delete_existing=True) + env.PrependUnique(LIBPATH = '#src', delete_existing=True) if not env['HOST']: - if env['PGSQL2SQLITE']: - if 'sqlite3' not in env['LIBS']: - env.AppendUnique(LIBS='sqlite3') - env.AppendUnique(CPPPATH = fix_path(env['SQLITE_INCLUDES'])) - env.AppendUnique(LIBPATH = fix_path(env['SQLITE_LIBS'])) - if 'pq' not in env['LIBS']: - if not conf.parse_pg_config('PG_CONFIG'): - env['PGSQL2SQLITE'] = False - if not SQLITE_HAS_RTREE: - env['SKIPPED_DEPS'].append('pgsql2sqlite_rtree') - env['PGSQL2SQLITE'] = False + if env['PGSQL2SQLITE']: + if 'sqlite3' not in env['LIBS']: + env.AppendUnique(LIBS='sqlite3') + env.AppendUnique(CPPPATH = fix_path(env['SQLITE_INCLUDES'])) + env.AppendUnique(LIBPATH = fix_path(env['SQLITE_LIBS'])) + if 'pq' not in env['LIBS']: + if not conf.parse_pg_config('PG_CONFIG'): + env['PGSQL2SQLITE'] = False + if not SQLITE_HAS_RTREE: + env['SKIPPED_DEPS'].append('pgsql2sqlite_rtree') + env['PGSQL2SQLITE'] = False # we rely on an internal, patched copy of agg with critical fixes # prepend to make sure we link locally @@ -1592,236 +1593,236 @@ if not preconfigured: env.Prepend(CPPPATH = '#deps') if env['CAIRO']: - if env['CAIRO_LIBS'] or env['CAIRO_INCLUDES']: - c_inc = env['CAIRO_INCLUDES'] - if env['CAIRO_LIBS']: - env["CAIRO_LIBPATHS"].append(fix_path(env['CAIRO_LIBS'])) - if not env['CAIRO_INCLUDES']: - c_inc = env['CAIRO_LIBS'].replace('lib','',1) - if c_inc: - c_inc = os.path.normpath(fix_path(env['CAIRO_INCLUDES'])) - if c_inc.endswith('include'): - c_inc = os.path.dirname(c_inc) - env["CAIRO_CPPPATHS"].extend( - [ - os.path.join(c_inc,'include/cairo'), - os.path.join(c_inc,'include/pixman-1'), - #os.path.join(c_inc,'include/freetype2'), - #os.path.join(c_inc,'include/libpng'), - ] - ) - env["CAIRO_ALL_LIBS"] = ['cairo'] - if env['RUNTIME_LINK'] == 'static': - env["CAIRO_ALL_LIBS"].extend( - ['pixman-1','expat'] - ) - # todo - run actual checkLib? - env['HAS_CAIRO'] = True - else: - if not CHECK_PKG_CONFIG: - env['HAS_CAIRO'] = False - env['SKIPPED_DEPS'].append('pkg-config') - env['SKIPPED_DEPS'].append('cairo') - elif not conf.CheckPKG('cairo'): - env['HAS_CAIRO'] = False - env['SKIPPED_DEPS'].append('cairo') - else: - print 'Checking for cairo lib and include paths... ', - cmd = 'pkg-config --libs --cflags cairo' - if env['RUNTIME_LINK'] == 'static': - cmd += ' --static' - cairo_env = env.Clone() - try: - cairo_env.ParseConfig(cmd) - for lib in cairo_env['LIBS']: - if not lib in env['LIBS']: - env["CAIRO_ALL_LIBS"].append(lib) - for lpath in cairo_env['LIBPATH']: - if not lpath in env['LIBPATH']: - env["CAIRO_LIBPATHS"].append(lpath) - for inc in cairo_env['CPPPATH']: - if not inc in env['CPPPATH']: - env["CAIRO_CPPPATHS"].append(inc) - env['HAS_CAIRO'] = True - print 'yes' - except OSError,e: - color_print(1,'no') - env['SKIPPED_DEPS'].append('cairo') - color_print(1,'pkg-config reported: %s' % e) + if env['CAIRO_LIBS'] or env['CAIRO_INCLUDES']: + c_inc = env['CAIRO_INCLUDES'] + if env['CAIRO_LIBS']: + env["CAIRO_LIBPATHS"].append(fix_path(env['CAIRO_LIBS'])) + if not env['CAIRO_INCLUDES']: + c_inc = env['CAIRO_LIBS'].replace('lib','',1) + if c_inc: + c_inc = os.path.normpath(fix_path(env['CAIRO_INCLUDES'])) + if c_inc.endswith('include'): + c_inc = os.path.dirname(c_inc) + env["CAIRO_CPPPATHS"].extend( + [ + os.path.join(c_inc,'include/cairo'), + os.path.join(c_inc,'include/pixman-1'), + #os.path.join(c_inc,'include/freetype2'), + #os.path.join(c_inc,'include/libpng'), + ] + ) + env["CAIRO_ALL_LIBS"] = ['cairo'] + if env['RUNTIME_LINK'] == 'static': + env["CAIRO_ALL_LIBS"].extend( + ['pixman-1','expat'] + ) + # todo - run actual checkLib? + env['HAS_CAIRO'] = True + else: + if not CHECK_PKG_CONFIG: + env['HAS_CAIRO'] = False + env['SKIPPED_DEPS'].append('pkg-config') + env['SKIPPED_DEPS'].append('cairo') + elif not conf.CheckPKG('cairo'): + env['HAS_CAIRO'] = False + env['SKIPPED_DEPS'].append('cairo') + else: + print 'Checking for cairo lib and include paths... ', + cmd = 'pkg-config --libs --cflags cairo' + if env['RUNTIME_LINK'] == 'static': + cmd += ' --static' + cairo_env = env.Clone() + try: + cairo_env.ParseConfig(cmd) + for lib in cairo_env['LIBS']: + if not lib in env['LIBS']: + env["CAIRO_ALL_LIBS"].append(lib) + for lpath in cairo_env['LIBPATH']: + if not lpath in env['LIBPATH']: + env["CAIRO_LIBPATHS"].append(lpath) + for inc in cairo_env['CPPPATH']: + if not inc in env['CPPPATH']: + env["CAIRO_CPPPATHS"].append(inc) + env['HAS_CAIRO'] = True + print 'yes' + except OSError,e: + color_print(1,'no') + env['SKIPPED_DEPS'].append('cairo') + color_print(1,'pkg-config reported: %s' % e) else: - color_print(4,'Not building with cairo support, pass CAIRO=True to enable') + color_print(4,'Not building with cairo support, pass CAIRO=True to enable') if not env['HOST'] and env['HAS_CAIRO']: - if not conf.CheckCairoHasFreetype(): - env['SKIPPED_DEPS'].append('cairo') - env['HAS_CAIRO'] = False + if not conf.CheckCairoHasFreetype(): + env['SKIPPED_DEPS'].append('cairo') + env['HAS_CAIRO'] = False #### End Config Stage for Required Dependencies #### if env['MISSING_DEPS']: - # if required dependencies are missing, print warnings and then let SCons finish without building or saving local config - color_print(1,'\nExiting... the following required dependencies were not found:\n - %s' % '\n - '.join([pretty_dep(dep) for dep in env['MISSING_DEPS']])) - color_print(1,"\nSee '%s' for details on possible problems." % (fix_path(SCONS_LOCAL_LOG))) - if env['SKIPPED_DEPS']: - color_print(4,'\nAlso, these OPTIONAL dependencies were not found:\n - %s' % '\n - '.join([pretty_dep(dep) for dep in env['SKIPPED_DEPS']])) - color_print(4,"\nSet custom paths to these libraries and header files on the command-line or in a file called '%s'" % SCONS_LOCAL_CONFIG) - color_print(4," ie. $ python scons/scons.py BOOST_INCLUDES=/usr/local/include BOOST_LIBS=/usr/local/lib") - color_print(4, "\nOnce all required dependencies are found a local '%s' will be saved and then install:" % SCONS_LOCAL_CONFIG) - color_print(4," $ sudo python scons/scons.py install") - color_print(4,"\nTo view available path variables:\n $ python scons/scons.py --help or -h") - color_print(4,'\nTo view overall SCons help options:\n $ python scons/scons.py --help-options or -H\n') - color_print(4,'More info: https://github.com/mapnik/mapnik/wiki/Mapnik-Installation') - if not HELP_REQUESTED: - Exit(1) + # if required dependencies are missing, print warnings and then let SCons finish without building or saving local config + color_print(1,'\nExiting... the following required dependencies were not found:\n - %s' % '\n - '.join([pretty_dep(dep) for dep in env['MISSING_DEPS']])) + color_print(1,"\nSee '%s' for details on possible problems." % (fix_path(SCONS_LOCAL_LOG))) + if env['SKIPPED_DEPS']: + color_print(4,'\nAlso, these OPTIONAL dependencies were not found:\n - %s' % '\n - '.join([pretty_dep(dep) for dep in env['SKIPPED_DEPS']])) + color_print(4,"\nSet custom paths to these libraries and header files on the command-line or in a file called '%s'" % SCONS_LOCAL_CONFIG) + color_print(4," ie. $ python scons/scons.py BOOST_INCLUDES=/usr/local/include BOOST_LIBS=/usr/local/lib") + color_print(4, "\nOnce all required dependencies are found a local '%s' will be saved and then install:" % SCONS_LOCAL_CONFIG) + color_print(4," $ sudo python scons/scons.py install") + color_print(4,"\nTo view available path variables:\n $ python scons/scons.py --help or -h") + color_print(4,'\nTo view overall SCons help options:\n $ python scons/scons.py --help-options or -H\n') + color_print(4,'More info: https://github.com/mapnik/mapnik/wiki/Mapnik-Installation') + if not HELP_REQUESTED: + Exit(1) else: - # Save the custom variables in a SCONS_LOCAL_CONFIG - # that will be reloaded to allow for `install` without re-specifying custom variables - color_print(4,"\nAll Required dependencies found!\n") - if env['USE_CONFIG']: - if os.path.exists(SCONS_LOCAL_CONFIG): - action = 'Overwriting and re-saving' - os.unlink(SCONS_LOCAL_CONFIG) - else: - action = 'Saving new' - color_print(4,"%s file '%s'..." % (action,SCONS_LOCAL_CONFIG)) - color_print(4,"Will hold custom path variables from commandline and python config file(s)...") - opts.Save(SCONS_LOCAL_CONFIG,env) - else: - color_print(4,"Did not use user config file, no custom path variables will be saved...") + # Save the custom variables in a SCONS_LOCAL_CONFIG + # that will be reloaded to allow for `install` without re-specifying custom variables + color_print(4,"\nAll Required dependencies found!\n") + if env['USE_CONFIG']: + if os.path.exists(SCONS_LOCAL_CONFIG): + action = 'Overwriting and re-saving' + os.unlink(SCONS_LOCAL_CONFIG) + else: + action = 'Saving new' + color_print(4,"%s file '%s'..." % (action,SCONS_LOCAL_CONFIG)) + color_print(4,"Will hold custom path variables from commandline and python config file(s)...") + opts.Save(SCONS_LOCAL_CONFIG,env) + else: + color_print(4,"Did not use user config file, no custom path variables will be saved...") - if env['SKIPPED_DEPS']: - color_print(4,'\nNote: will build without these OPTIONAL dependencies:\n - %s' % '\n - '.join([pretty_dep(dep) for dep in env['SKIPPED_DEPS']])) - print + if env['SKIPPED_DEPS']: + color_print(4,'\nNote: will build without these OPTIONAL dependencies:\n - %s' % '\n - '.join([pretty_dep(dep) for dep in env['SKIPPED_DEPS']])) + print - # fetch the mapnik version header in order to set the - # ABI version used to build libmapnik.so on linux in src/build.py - abi = GetMapnikLibVersion() - abi_no_pre = abi.replace('-pre','').split('.') - env['ABI_VERSION'] = abi_no_pre - env['MAPNIK_VERSION_STRING'] = abi - env['MAPNIK_VERSION'] = str(int(abi_no_pre[0])*100000+int(abi_no_pre[1])*100+int(abi_no_pre[2])) + # fetch the mapnik version header in order to set the + # ABI version used to build libmapnik.so on linux in src/build.py + abi = GetMapnikLibVersion() + abi_no_pre = abi.replace('-pre','').split('.') + env['ABI_VERSION'] = abi_no_pre + env['MAPNIK_VERSION_STRING'] = abi + env['MAPNIK_VERSION'] = str(int(abi_no_pre[0])*100000+int(abi_no_pre[1])*100+int(abi_no_pre[2])) - # Common DEFINES. - env.Append(CPPDEFINES = '-D%s' % env['PLATFORM'].upper()) - if env['THREADING'] == 'multi': - env.Append(CPPDEFINES = '-DMAPNIK_THREADSAFE') + # Common DEFINES. + env.Append(CPPDEFINES = '-D%s' % env['PLATFORM'].upper()) + if env['THREADING'] == 'multi': + env.Append(CPPDEFINES = '-DMAPNIK_THREADSAFE') - if env['NO_ATEXIT']: - env.Append(CPPDEFINES = '-DMAPNIK_NO_ATEXIT') + if env['NO_ATEXIT']: + env.Append(CPPDEFINES = '-DMAPNIK_NO_ATEXIT') - # Mac OSX (Darwin) special settings - if env['PLATFORM'] == 'Darwin': - pthread = '' - else: - pthread = '-pthread' + # Mac OSX (Darwin) special settings + if env['PLATFORM'] == 'Darwin': + pthread = '' + else: + pthread = '-pthread' - # Common debugging flags. - # http://lists.fedoraproject.org/pipermail/devel/2010-November/144952.html - debug_flags = ['-g', '-fno-omit-frame-pointer'] - debug_defines = ['-DDEBUG', '-DMAPNIK_DEBUG'] - ndebug_defines = ['-DNDEBUG'] + # Common debugging flags. + # http://lists.fedoraproject.org/pipermail/devel/2010-November/144952.html + debug_flags = ['-g', '-fno-omit-frame-pointer'] + debug_defines = ['-DDEBUG', '-DMAPNIK_DEBUG'] + ndebug_defines = ['-DNDEBUG'] - # faster compile - # http://www.boost.org/doc/libs/1_47_0/libs/spirit/doc/html/spirit/what_s_new/spirit_2_5.html#spirit.what_s_new.spirit_2_5.breaking_changes - env.Append(CPPDEFINES = '-DBOOST_SPIRIT_NO_PREDEFINED_TERMINALS=1') - env.Append(CPPDEFINES = '-DBOOST_PHOENIX_NO_PREDEFINED_TERMINALS=1') - # c++11 support / https://github.com/mapnik/mapnik/issues/1683 - # - upgrade to PHOENIX_V3 since that is needed for c++11 compile - env.Append(CPPDEFINES = '-DBOOST_SPIRIT_USE_PHOENIX_V3=1') + # faster compile + # http://www.boost.org/doc/libs/1_47_0/libs/spirit/doc/html/spirit/what_s_new/spirit_2_5.html#spirit.what_s_new.spirit_2_5.breaking_changes + env.Append(CPPDEFINES = '-DBOOST_SPIRIT_NO_PREDEFINED_TERMINALS=1') + env.Append(CPPDEFINES = '-DBOOST_PHOENIX_NO_PREDEFINED_TERMINALS=1') + # c++11 support / https://github.com/mapnik/mapnik/issues/1683 + # - upgrade to PHOENIX_V3 since that is needed for c++11 compile + env.Append(CPPDEFINES = '-DBOOST_SPIRIT_USE_PHOENIX_V3=1') - # Enable logging in debug mode (always) and release mode (when specified) - if env['DEFAULT_LOG_SEVERITY']: - if env['DEFAULT_LOG_SEVERITY'] not in severities: - severities_list = ', '.join(["'%s'" % s for s in severities]) - color_print(1,"Cannot set default logger severity to '%s', available options are %s." % (env['DEFAULT_LOG_SEVERITY'], severities_list)) - Exit(1) - else: - log_severity = severities.index(env['DEFAULT_LOG_SEVERITY']) - else: - severities_list = ', '.join(["'%s'" % s for s in severities]) - color_print(1,"No logger severity specified, available options are %s." % severities_list) - Exit(1) + # Enable logging in debug mode (always) and release mode (when specified) + if env['DEFAULT_LOG_SEVERITY']: + if env['DEFAULT_LOG_SEVERITY'] not in severities: + severities_list = ', '.join(["'%s'" % s for s in severities]) + color_print(1,"Cannot set default logger severity to '%s', available options are %s." % (env['DEFAULT_LOG_SEVERITY'], severities_list)) + Exit(1) + else: + log_severity = severities.index(env['DEFAULT_LOG_SEVERITY']) + else: + severities_list = ', '.join(["'%s'" % s for s in severities]) + color_print(1,"No logger severity specified, available options are %s." % severities_list) + Exit(1) - log_enabled = ['-DMAPNIK_LOG', '-DMAPNIK_DEFAULT_LOG_SEVERITY=%d' % log_severity] + log_enabled = ['-DMAPNIK_LOG', '-DMAPNIK_DEFAULT_LOG_SEVERITY=%d' % log_severity] - if env['DEBUG']: - debug_defines += log_enabled - else: - if env['ENABLE_LOG']: - ndebug_defines += log_enabled + if env['DEBUG']: + debug_defines += log_enabled + else: + if env['ENABLE_LOG']: + ndebug_defines += log_enabled - # Enable statistics reporting - if env['ENABLE_STATS']: - debug_defines.append('-DMAPNIK_STATS') - ndebug_defines.append('-DMAPNIK_STATS') + # Enable statistics reporting + if env['ENABLE_STATS']: + debug_defines.append('-DMAPNIK_STATS') + ndebug_defines.append('-DMAPNIK_STATS') - # Add rdynamic to allow using statics between application and plugins - # http://stackoverflow.com/questions/8623657/multiple-instances-of-singleton-across-shared-libraries-on-linux - if env['PLATFORM'] != 'Darwin' and env['CXX'] == 'g++': - env.MergeFlags('-rdynamic') + # Add rdynamic to allow using statics between application and plugins + # http://stackoverflow.com/questions/8623657/multiple-instances-of-singleton-across-shared-libraries-on-linux + if env['PLATFORM'] != 'Darwin' and env['CXX'] == 'g++': + env.MergeFlags('-rdynamic') - if env['DEBUG']: - env.Append(CXXFLAGS = debug_flags) - env.Append(CPPDEFINES = debug_defines) - else: - env.Append(CPPDEFINES = ndebug_defines) + if env['DEBUG']: + env.Append(CXXFLAGS = debug_flags) + env.Append(CPPDEFINES = debug_defines) + else: + env.Append(CPPDEFINES = ndebug_defines) - # Common flags for g++/clang++ CXX compiler. - # TODO: clean up code more to make -Wextra -Wsign-compare -Wsign-conversion -Wconversion viable - common_cxx_flags = '-Wall %s %s -ftemplate-depth-300 -Wsign-compare -Wshadow ' % (env['WARNING_CXXFLAGS'], pthread) + # Common flags for g++/clang++ CXX compiler. + # TODO: clean up code more to make -Wextra -Wsign-compare -Wsign-conversion -Wconversion viable + common_cxx_flags = '-Wall %s %s -ftemplate-depth-300 -Wsign-compare -Wshadow ' % (env['WARNING_CXXFLAGS'], pthread) - if 'clang++' in env['CXX']: - common_cxx_flags += ' -Wno-unknown-pragmas -Wno-unsequenced ' - elif 'g++' in env['CXX']: - common_cxx_flags += ' -Wno-pragmas ' + if 'clang++' in env['CXX']: + common_cxx_flags += ' -Wno-unknown-pragmas -Wno-unsequenced ' + elif 'g++' in env['CXX']: + common_cxx_flags += ' -Wno-pragmas ' - if env['DEBUG']: - env.Append(CXXFLAGS = common_cxx_flags + '-O0') - else: - # TODO - add back -fvisibility-inlines-hidden - # https://github.com/mapnik/mapnik/issues/1863 - env.Append(CXXFLAGS = common_cxx_flags + '-O%s' % (env['OPTIMIZATION'])) - if env['DEBUG_UNDEFINED']: - env.Append(CXXFLAGS = '-fsanitize=undefined-trap -fsanitize-undefined-trap-on-error -ftrapv -fwrapv') + if env['DEBUG']: + env.Append(CXXFLAGS = common_cxx_flags + '-O0') + else: + # TODO - add back -fvisibility-inlines-hidden + # https://github.com/mapnik/mapnik/issues/1863 + env.Append(CXXFLAGS = common_cxx_flags + '-O%s' % (env['OPTIMIZATION'])) + if env['DEBUG_UNDEFINED']: + env.Append(CXXFLAGS = '-fsanitize=undefined-trap -fsanitize-undefined-trap-on-error -ftrapv -fwrapv') - # if requested, sort LIBPATH and CPPPATH one last time before saving... - if env['PRIORITIZE_LINKING']: - conf.prioritize_paths(silent=True) + # if requested, sort LIBPATH and CPPPATH one last time before saving... + if env['PRIORITIZE_LINKING']: + conf.prioritize_paths(silent=True) - # finish config stage and pickle results - env = conf.Finish() - env_cache = open(SCONS_CONFIGURE_CACHE, 'w') - pickle_dict = {} - for i in pickle_store: - pickle_dict[i] = env.get(i) - pickle.dump(pickle_dict,env_cache) - env_cache.close() - # fix up permissions on configure outputs - # this is hackish but avoids potential problems - # with a non-root configure following a root install - # that also triggered a re-configure - try: - os.chmod(SCONS_CONFIGURE_CACHE,0666) - except: pass - try: - os.chmod(SCONS_LOCAL_CONFIG,0666) - except: pass - try: - os.chmod('.sconsign.dblite',0666) - except: pass - try: - os.chmod(SCONS_LOCAL_LOG,0666) - except: pass - try: - for item in glob('%s/*' % SCONF_TEMP_DIR): - os.chmod(item,0666) - except: pass + # finish config stage and pickle results + env = conf.Finish() + env_cache = open(SCONS_CONFIGURE_CACHE, 'w') + pickle_dict = {} + for i in pickle_store: + pickle_dict[i] = env.get(i) + pickle.dump(pickle_dict,env_cache) + env_cache.close() + # fix up permissions on configure outputs + # this is hackish but avoids potential problems + # with a non-root configure following a root install + # that also triggered a re-configure + try: + os.chmod(SCONS_CONFIGURE_CACHE,0666) + except: pass + try: + os.chmod(SCONS_LOCAL_CONFIG,0666) + except: pass + try: + os.chmod('.sconsign.dblite',0666) + except: pass + try: + os.chmod(SCONS_LOCAL_LOG,0666) + except: pass + try: + for item in glob('%s/*' % SCONF_TEMP_DIR): + os.chmod(item,0666) + except: pass - if 'configure' in command_line_args: - color_print(4,'\nConfigure completed: run `make` to build or `make install`') - if not HELP_REQUESTED: - Exit(0) + if 'configure' in command_line_args: + color_print(4,'\nConfigure completed: run `make` to build or `make install`') + if not HELP_REQUESTED: + Exit(0) # autogenerate help on default/current SCons options Help(opts.GenerateHelpText(env)) @@ -1830,43 +1831,43 @@ Help(opts.GenerateHelpText(env)) if not HELP_REQUESTED: if 'uninstall' in COMMAND_LINE_TARGETS: - # dummy action in case there is nothing to uninstall, to avoid phony error.. - env.Alias("uninstall", "") + # dummy action in case there is nothing to uninstall, to avoid phony error.. + env.Alias("uninstall", "") env['create_uninstall_target'] = create_uninstall_target if env['PKG_CONFIG_PATH']: - env['ENV']['PKG_CONFIG_PATH'] = fix_path(env['PKG_CONFIG_PATH']) - # otherwise this variable == os.environ["PKG_CONFIG_PATH"] + env['ENV']['PKG_CONFIG_PATH'] = fix_path(env['PKG_CONFIG_PATH']) + # otherwise this variable == os.environ["PKG_CONFIG_PATH"] if env['PATH']: - env['ENV']['PATH'] = fix_path(env['PATH']) + ':' + env['ENV']['PATH'] + env['ENV']['PATH'] = fix_path(env['PATH']) + ':' + env['ENV']['PATH'] if env['PATH_REMOVE']: - for p in env['PATH_REMOVE'].split(':'): - if p in env['ENV']['PATH']: - env['ENV']['PATH'].replace(p,'') - rm_path(p,'LIBPATH',env) - rm_path(p,'CPPPATH',env) - rm_path(p,'CXXFLAGS',env) - rm_path(p,'CAIRO_LIBPATHS',env) - rm_path(p,'CAIRO_CPPPATHS',env) + for p in env['PATH_REMOVE'].split(':'): + if p in env['ENV']['PATH']: + env['ENV']['PATH'].replace(p,'') + rm_path(p,'LIBPATH',env) + rm_path(p,'CPPPATH',env) + rm_path(p,'CXXFLAGS',env) + rm_path(p,'CAIRO_LIBPATHS',env) + rm_path(p,'CAIRO_CPPPATHS',env) if env['PATH_REPLACE']: - searches,replace = env['PATH_REPLACE'].split(':') - for search in searches.split(','): - if search in env['ENV']['PATH']: - env['ENV']['PATH'] = os.path.abspath(env['ENV']['PATH'].replace(search,replace)) - def replace_path(set,s,r): - idx = 0 - for i in env[set]: - if s in i: - env[set][idx] = os.path.abspath(env[set][idx].replace(s,r)) - idx +=1 - replace_path('LIBPATH',search,replace) - replace_path('CPPPATH',search,replace) - replace_path('CXXFLAGS',search,replace) - replace_path('CAIRO_LIBPATHS',search,replace) - replace_path('CAIRO_CPPPATHS',search,replace) + searches,replace = env['PATH_REPLACE'].split(':') + for search in searches.split(','): + if search in env['ENV']['PATH']: + env['ENV']['PATH'] = os.path.abspath(env['ENV']['PATH'].replace(search,replace)) + def replace_path(set,s,r): + idx = 0 + for i in env[set]: + if s in i: + env[set][idx] = os.path.abspath(env[set][idx].replace(s,r)) + idx +=1 + replace_path('LIBPATH',search,replace) + replace_path('CPPPATH',search,replace) + replace_path('CXXFLAGS',search,replace) + replace_path('CAIRO_LIBPATHS',search,replace) + replace_path('CAIRO_CPPPATHS',search,replace) # export env so it is available in build.py files Export('env') @@ -1876,15 +1877,15 @@ if not HELP_REQUESTED: Export('plugin_base') if env['FAST']: - # caching is 'auto' by default in SCons - # But let's also cache implicit deps... - EnsureSConsVersion(0,98) - SetOption('implicit_cache', 1) - SetOption('max_drift', 1) + # caching is 'auto' by default in SCons + # But let's also cache implicit deps... + EnsureSConsVersion(0,98) + SetOption('implicit_cache', 1) + SetOption('max_drift', 1) # Build agg first, doesn't need anything special if env['RUNTIME_LINK'] == 'shared': - SConscript('deps/agg/build.py') + SConscript('deps/agg/build.py') # Build spirit grammars SConscript('src/json/build.py') @@ -1905,76 +1906,78 @@ if not HELP_REQUESTED: POSTGIS_BUILT = False PGRASTER_BUILT = False for plugin in env['PLUGINS']: - if env['PLUGIN_LINKING'] == 'static' or plugin not in env['REQUESTED_PLUGINS']: - if os.path.exists('plugins/input/%s.input' % plugin): - os.unlink('plugins/input/%s.input' % plugin) - elif plugin in env['REQUESTED_PLUGINS']: - details = env['PLUGINS'][plugin] - if details['lib'] in env['LIBS']: - if env['PLUGIN_LINKING'] == 'shared': - SConscript('plugins/input/%s/build.py' % plugin) - # hack to avoid breaking on plugins with the same dep - if plugin == 'ogr': OGR_BUILT = True - if plugin == 'gdal': GDAL_BUILT = True - if plugin == 'postgis': POSTGIS_BUILT = True - if plugin == 'pgraster': PGRASTER_BUILT = True - if plugin == 'ogr' or plugin == 'gdal': - if GDAL_BUILT and OGR_BUILT: - env['LIBS'].remove(details['lib']) - elif plugin == 'postgis' or plugin == 'pgraster': - if POSTGIS_BUILT and PGRASTER_BUILT: - env['LIBS'].remove(details['lib']) - else: - env['LIBS'].remove(details['lib']) - elif not details['lib']: - if env['PLUGIN_LINKING'] == 'shared': - # build internal datasource input plugins - SConscript('plugins/input/%s/build.py' % plugin) - else: - color_print(1,"Notice: dependencies not met for plugin '%s', not building..." % plugin) - if os.path.exists('plugins/input/%s.input' % plugin): - os.unlink('plugins/input/%s.input' % plugin) + if env['PLUGIN_LINKING'] == 'static' or plugin not in env['REQUESTED_PLUGINS']: + if os.path.exists('plugins/input/%s.input' % plugin): + os.unlink('plugins/input/%s.input' % plugin) + elif plugin in env['REQUESTED_PLUGINS']: + details = env['PLUGINS'][plugin] + if details['lib'] in env['LIBS']: + if env['PLUGIN_LINKING'] == 'shared': + SConscript('plugins/input/%s/build.py' % plugin) + # hack to avoid breaking on plugins with the same dep + if plugin == 'ogr': OGR_BUILT = True + if plugin == 'gdal': GDAL_BUILT = True + if plugin == 'postgis': POSTGIS_BUILT = True + if plugin == 'pgraster': PGRASTER_BUILT = True + if plugin == 'ogr' or plugin == 'gdal': + if GDAL_BUILT and OGR_BUILT: + env['LIBS'].remove(details['lib']) + elif plugin == 'postgis' or plugin == 'pgraster': + if POSTGIS_BUILT and PGRASTER_BUILT: + env['LIBS'].remove(details['lib']) + else: + env['LIBS'].remove(details['lib']) + elif not details['lib']: + if env['PLUGIN_LINKING'] == 'shared': + # build internal datasource input plugins + SConscript('plugins/input/%s/build.py' % plugin) + else: + color_print(1,"Notice: dependencies not met for plugin '%s', not building..." % plugin) + if os.path.exists('plugins/input/%s.input' % plugin): + os.unlink('plugins/input/%s.input' % plugin) create_uninstall_target(env, env['MAPNIK_LIB_DIR_DEST'], False) create_uninstall_target(env, env['MAPNIK_INPUT_PLUGINS_DEST'] , False) if 'install' in COMMAND_LINE_TARGETS: - # if statically linking plugins still make sure - # to create the dynamic plugins directory - if env['PLUGIN_LINKING'] == 'static': - if not os.path.exists(env['MAPNIK_INPUT_PLUGINS_DEST']): - os.makedirs(env['MAPNIK_INPUT_PLUGINS_DEST']) - # before installing plugins, wipe out any previously - # installed plugins that we are no longer building - for plugin in PLUGINS.keys(): - plugin_path = os.path.join(env['MAPNIK_INPUT_PLUGINS_DEST'],'%s.input' % plugin) - if os.path.exists(plugin_path): - if plugin not in env['REQUESTED_PLUGINS'] or env['PLUGIN_LINKING'] == 'static': - color_print(4,"Notice: removing out of date plugin: '%s'" % plugin_path) - os.unlink(plugin_path) + # if statically linking plugins still make sure + # to create the dynamic plugins directory + if env['PLUGIN_LINKING'] == 'static': + if not os.path.exists(env['MAPNIK_INPUT_PLUGINS_DEST']): + os.makedirs(env['MAPNIK_INPUT_PLUGINS_DEST']) + # before installing plugins, wipe out any previously + # installed plugins that we are no longer building + for plugin in PLUGINS.keys(): + plugin_path = os.path.join(env['MAPNIK_INPUT_PLUGINS_DEST'],'%s.input' % plugin) + if os.path.exists(plugin_path): + if plugin not in env['REQUESTED_PLUGINS'] or env['PLUGIN_LINKING'] == 'static': + color_print(4,"Notice: removing out of date plugin: '%s'" % plugin_path) + os.unlink(plugin_path) # Build the c++ rundemo app if requested if not env['HOST']: - if env['DEMO']: - SConscript('demo/c++/build.py') + if env['DEMO']: + SConscript('demo/c++/build.py') # Build shapeindex and remove its dependency from the LIBS if not env['HOST']: - if 'boost_program_options%s' % env['BOOST_APPEND'] in env['LIBS']: - if env['SHAPEINDEX']: - SConscript('utils/shapeindex/build.py') - # Build the pgsql2psqlite app if requested - if env['PGSQL2SQLITE']: - SConscript('utils/pgsql2sqlite/build.py') - if env['SVG2PNG']: - SConscript('utils/svg2png/build.py') - if env['NIK2IMG']: - SConscript('utils/nik2img/build.py') - # devtools not ready for public - #SConscript('utils/ogrindex/build.py') - env['LIBS'].remove('boost_program_options%s' % env['BOOST_APPEND']) - else : - color_print(1,"WARNING: Cannot find boost_program_options. 'shapeindex' and other command line programs will not be available") + if 'boost_program_options%s' % env['BOOST_APPEND'] in env['LIBS']: + if env['SHAPEINDEX']: + SConscript('utils/shapeindex/build.py') + if env['CSVINDEX']: + SConscript('utils/csvindex/build.py') + # Build the pgsql2psqlite app if requested + if env['PGSQL2SQLITE']: + SConscript('utils/pgsql2sqlite/build.py') + if env['SVG2PNG']: + SConscript('utils/svg2png/build.py') + if env['NIK2IMG']: + SConscript('utils/nik2img/build.py') + # devtools not ready for public + #SConscript('utils/ogrindex/build.py') + env['LIBS'].remove('boost_program_options%s' % env['BOOST_APPEND']) + else : + color_print(1,"WARNING: Cannot find boost_program_options. 'shapeindex' and other command line programs will not be available") # Configure fonts and if requested install the bundled DejaVu fonts SConscript('fonts/build.py') @@ -1983,10 +1986,10 @@ if not HELP_REQUESTED: SConscript('test/build.py') if env['BENCHMARK']: - SConscript('benchmark/build.py') + SConscript('benchmark/build.py') if os.path.exists('./bindings/python/build.py'): - SConscript('./bindings/python/build.py') + SConscript('./bindings/python/build.py') # install mapnik-config script SConscript('utils/mapnik-config/build.py')