~ubuntu-branches/ubuntu/trusty/mapnik/trusty-proposed

« back to all changes in this revision

Viewing changes to SConstruct

  • Committer: Bazaar Package Importer
  • Author(s): Christophe Sauthier
  • Date: 2009-08-27 00:28:37 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20090827002837-ztqzfg2rmclfh4i9
Tags: 0.6.1-0ubuntu1
* New upstream release.
* Change usr/lib to usr/lib* to enable build on 64 bits systems due to new
  configuration in SConstruct in :
  - debian/libmapnik-dev.install
  - debian/libmapnik0.6.install
  - debian/mapnik-plugin-base

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
# License along with this library; if not, write to the Free Software
17
17
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
18
#
19
 
# $Id: SConstruct 1066 2009-04-01 15:12:18Z dane $
 
19
# $Id: SConstruct 1230 2009-07-09 01:16:52Z dane $
20
20
 
21
21
 
22
22
import os
33
33
    HAS_DISTUTILS = True
34
34
except:
35
35
    HAS_DISTUTILS = False
36
 
                  
 
36
 
 
37
#### SCons build options and initial setup ####
 
38
env = Environment(ENV=os.environ)
 
39
 
37
40
def color_print(color,text,newline=True):
38
41
    # 1 - red
39
42
    # 2 - green
45
48
    else:
46
49
        print text
47
50
 
 
51
def regular_print(color,text,newline=True):
 
52
    if not newline:
 
53
        print text,
 
54
    else:
 
55
        print text
 
56
 
48
57
def call(cmd):
49
58
    stdin, stderr = Popen(cmd,shell=True,stdout=PIPE,stderr=PIPE).communicate()
50
59
    if not stderr:
52
61
    else:
53
62
        color_print(1,'Problem encounted with SCons scripts, please post bug report to: http://trac.mapnik.org\nError was: %s' % stderr)
54
63
 
 
64
def shortest_name(libs):
 
65
    name = '-'*200
 
66
    for lib in libs:
 
67
        if len(name) > len(lib):
 
68
            name = lib
 
69
    return name
 
70
 
55
71
if platform.uname()[4] == 'x86_64':
56
 
    LIBDIR_SCHEMA='lib' 
 
72
    LIBDIR_SCHEMA='lib64' 
57
73
elif platform.uname()[4] == 'ppc64':
58
74
    LIBDIR_SCHEMA='lib64'
59
75
else:
65
81
SCONS_CONFIGURE_CACHE = 'config.cache'
66
82
# directory SCons uses to stash build tests
67
83
SCONF_TEMP_DIR = '.sconf_temp'
 
84
# auto-search directories for boost libs/headers
 
85
BOOST_SEARCH_PREFIXES = ['/usr/local','/opt/local','/sw','/usr',]
 
86
 
68
87
 
69
88
# Core plugin build configuration
70
89
# opts.AddVariables still hardcoded however...
80
99
            'osm':     {'default':False,'path':None,'inc':None,'lib':None,'lang':'C++'},
81
100
            'shape':   {'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'},
82
101
            'raster':  {'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'},
 
102
            'kismet':  {'default':False,'path':None,'inc':None,'lib':None,'lang':'C++'},
83
103
            }
84
104
 
85
105
DEFAULT_PLUGINS = []
87
107
   if v['default']:
88
108
       DEFAULT_PLUGINS.append(k)
89
109
 
90
 
#### SCons build options and initial setup ####
91
 
color_print(4,'\nWelcome to Mapnik...\n')
92
 
env = Environment(ENV=os.environ)
93
 
 
94
110
# All of the following options may be modified at the command-line, for example:
95
111
# `python scons/scons.py PREFIX=/opt`
96
112
opts = Variables()
98
114
opts.AddVariables(
99
115
    # Compiler options
100
116
    ('CXX', 'The C++ compiler to use (defaults to g++).', 'g++'),
101
 
    EnumVariable('OPTIMIZATION','Set g++ optimization level','2', ['0','1','2','3']),
 
117
    EnumVariable('OPTIMIZATION','Set g++ optimization level','2', ['0','1','2','3','4']),
102
118
    # Note: setting DEBUG=True will override any custom OPTIMIZATION level
103
119
    BoolVariable('DEBUG', 'Compile a debug version of Mapnik', 'False'),
104
120
    BoolVariable('XML_DEBUG', 'Compile a XML verbose debug version of mapnik', 'False'),
115
131
    ('DESTDIR', 'The root directory to install into. Useful mainly for binary package building', '/'),
116
132
    
117
133
    # Boost variables
118
 
    PathVariable('BOOST_INCLUDES', 'Search path for boost include files', '/usr/include', PathVariable.PathAccept),
119
 
    PathVariable('BOOST_LIBS', 'Search path for boost library files', '/usr/' + LIBDIR_SCHEMA, PathVariable.PathAccept),
 
134
    # default is '/usr/include', see FindBoost method below
 
135
    ('BOOST_INCLUDES', 'Search path for boost include files', '',False),
 
136
    # default is '/usr/' + LIBDIR_SCHEMA, see FindBoost method below
 
137
    ('BOOST_LIBS', 'Search path for boost library files', '',False),
120
138
    ('BOOST_TOOLKIT','Specify boost toolkit, e.g., gcc41.','',False),
121
139
    ('BOOST_ABI', 'Specify boost ABI, e.g., d.','',False),
122
140
    ('BOOST_VERSION','Specify boost version, e.g., 1_35.','',False),
134
152
    PathVariable('TIFF_LIBS', 'Search path for libtiff library files', '/usr/' + LIBDIR_SCHEMA, PathVariable.PathAccept),
135
153
    PathVariable('PROJ_INCLUDES', 'Search path for PROJ.4 include files', '/usr/local/include', PathVariable.PathAccept),
136
154
    PathVariable('PROJ_LIBS', 'Search path for PROJ.4 library files', '/usr/local/' + LIBDIR_SCHEMA, PathVariable.PathAccept),
 
155
    ('PKG_CONFIG_PATH', 'Use this path to point pkg-config to .pc files instead of the PKG_CONFIG_PATH environment setting',''),
137
156
    
138
157
    # Variables affecting rendering back-ends
139
158
    BoolVariable('INTERNAL_LIBAGG', 'Use provided libagg', 'True'),
150
169
    PathVariable('SQLITE_LIBS', 'Search path for SQLITE library files', '/usr/' + LIBDIR_SCHEMA, PathVariable.PathAccept),
151
170
    
152
171
    # Other variables
 
172
    BoolVariable('SHAPE_MEMORY_MAPPED_FILE', 'Utilize memory-mapped files in Shapefile Plugin (higher memory usage, better performance)', 'True'),
153
173
    ('SYSTEM_FONTS','Provide location for python bindings to register fonts (if given aborts installation of bundled DejaVu fonts)',''),
154
 
    ('LIB_DIR_NAME','Name to use for lib folder where fonts and plugins are installed','/mapnik/'),
 
174
    ('LIB_DIR_NAME','Name to use for the "lib" folder where fonts and plugins are installed','/mapnik/'),
155
175
    PathVariable('PYTHON','Full path to Python executable used to build bindings', sys.executable),
156
 
    BoolVariable('FRAMEWORK_PYTHON', 'Link against Framework Python on Mac OSX', 'True'),
 
176
    BoolVariable('FRAMEWORK_PYTHON', 'Link against Framework Python on Mac OS X', 'True'),
 
177
    PathVariable('FRAMEWORK_SEARCH_PATH','Top framework search path on Mac OS X', '/'),
 
178
    BoolVariable('FULL_LIB_PATH', 'Use the full path for the libmapnik.dylib "install_name" when linking on Mac OS X', 'True'),
157
179
    ListVariable('BINDINGS','Language bindings to build','all',['python']),
158
180
    EnumVariable('THREADING','Set threading support','multi', ['multi','single']),
159
181
    EnumVariable('XMLPARSER','Set xml parser ','libxml2', ['tinyxml','spirit','libxml2']),
160
182
    ('JOBS', 'Set the number of parallel compilations', "1", lambda key, value, env: int(value), int),
161
183
    BoolVariable('DEMO', 'Compile demo c++ application', 'False'),
162
184
    BoolVariable('PGSQL2SQLITE', 'Compile and install a utility to convert postgres tables to sqlite', 'False'),
 
185
    BoolVariable('COLOR_PRINT', 'Print build status information in color', 'True'),
163
186
    )
164
187
# variables to pickle after successful configure step
165
188
# these include all scons core variables as well as custom
187
210
        'PYTHON_VERSION',
188
211
        'PYTHON_INCLUDES',
189
212
        'PYTHON_INSTALL_LOCATION',
 
213
        'COLOR_PRINT',
 
214
        'BOOST_SYSTEM_REQUIRED',
190
215
        ]
191
216
 
192
217
# Add all other user configurable options to pickle pickle_store
210
235
# initially populate environment with defaults and any possible custom arguments
211
236
opts.Update(env)
212
237
 
 
238
if env.has_key('COLOR_PRINT') and env['COLOR_PRINT'] == False:
 
239
    color_print = regular_print
 
240
 
 
241
color_print(4,'\nWelcome to Mapnik...\n')
 
242
 
213
243
# if we are not configuring overwrite environment with pickled settings
214
244
if not force_configure:
215
245
    if os.path.exists(SCONS_CONFIGURE_CACHE):
331
361
        if item.key == variable:
332
362
            env[variable] = item.default
333
363
 
 
364
def FindBoost(context, prefixes):
 
365
    """Routine to auto-find boost header dir, lib dir, and library naming structure.
 
366
    
 
367
    """
 
368
    context.Message( 'Searching for boost libs and headers... ' )
 
369
    env = context.env
 
370
     
 
371
    BOOST_LIB_DIR = None
 
372
    BOOST_INCLUDE_DIR = None
 
373
    BOOST_APPEND = None
 
374
    env['BOOST_APPEND'] = str()
 
375
 
 
376
    for searchDir in prefixes:
 
377
        libItems = glob(os.path.join(searchDir, LIBDIR_SCHEMA, 'libboost_filesystem*-*.*'))
 
378
        if not libItems:
 
379
            libItems = glob(os.path.join(searchDir, 'lib/libboost_filesystem*-*.*'))
 
380
        incItems = glob(os.path.join(searchDir, 'include/boost*/'))
 
381
        if len(libItems) >= 1 and len(incItems) >= 1:
 
382
            BOOST_LIB_DIR = os.path.dirname(libItems[0])
 
383
            BOOST_INCLUDE_DIR = incItems[0].rstrip('boost/')
 
384
            shortest_lib_name = shortest_name(libItems)
 
385
            match = re.search(r'libboost_filesystem-(.*)\..*', shortest_lib_name)
 
386
            if hasattr(match,'groups'):
 
387
                BOOST_APPEND = match.groups()[0]
 
388
            break
 
389
    
 
390
    msg = str()
 
391
    
 
392
    if not env['BOOST_LIBS']:
 
393
        if BOOST_LIB_DIR:
 
394
            msg += '\n  *libs found: %s' % BOOST_LIB_DIR
 
395
            env['BOOST_LIBS'] = BOOST_LIB_DIR
 
396
        else:
 
397
            env['BOOST_LIBS'] = '/usr' + LIBDIR_SCHEMA
 
398
    else:
 
399
        msg += '\n  *using boost lib dir: %s' % env['BOOST_LIBS']
 
400
           
 
401
    if not env['BOOST_INCLUDES']:
 
402
        if BOOST_INCLUDE_DIR:
 
403
            msg += '\n  *headers found: %s' % BOOST_INCLUDE_DIR
 
404
            env['BOOST_INCLUDES'] = BOOST_INCLUDE_DIR
 
405
        else:
 
406
            env['BOOST_INCLUDES'] = '/usr/include'
 
407
    else:
 
408
        msg += '\n  *using boost include dir: %s' % env['BOOST_INCLUDES']    
 
409
               
 
410
    if not env['BOOST_TOOLKIT'] and not env['BOOST_ABI'] and not env['BOOST_VERSION']:
 
411
        if BOOST_APPEND:
 
412
            msg += '\n  *lib naming extension found: %s' % BOOST_APPEND
 
413
            env['BOOST_APPEND'] = '-' + BOOST_APPEND
 
414
        else:
 
415
            msg += '\n  *no lib naming extension found'
 
416
    else:
 
417
        # Creating BOOST_APPEND according to the Boost library naming order,
 
418
        # which goes <toolset>-<threading>-<abi>-<version>. See:
 
419
        #  http://www.boost.org/doc/libs/1_35_0/more/getting_started/unix-variants.html#library-naming
 
420
        append_params = ['']
 
421
        if env['BOOST_TOOLKIT']: append_params.append(env['BOOST_TOOLKIT'])
 
422
        if thread_flag: append_params.append(thread_flag)
 
423
        if env['BOOST_ABI']: append_params.append(env['BOOST_ABI'])
 
424
        if env['BOOST_VERSION']: append_params.append(env['BOOST_VERSION'])
 
425
 
 
426
        # Constructing the BOOST_APPEND setting that will be used to find the
 
427
        # Boost libraries.
 
428
        if len(append_params) > 1: 
 
429
            env['BOOST_APPEND'] = '-'.join(append_params)
 
430
        msg += '\n  *using boost lib naming: %s' % env['BOOST_APPEND']
 
431
 
 
432
    env.AppendUnique(CPPPATH = env['BOOST_INCLUDES'])
 
433
    env.AppendUnique(LIBPATH = env['BOOST_LIBS'])    
 
434
    if env['COLOR_PRINT']:
 
435
        msg = "\033[94m%s\033[0m" % (msg)
 
436
    ret = context.Result(msg)
 
437
    return ret
 
438
 
334
439
def CheckBoost(context, version, silent=False):
335
440
    # Boost versions are in format major.minor.subminor
336
441
    v_arr = version.split(".")
404
509
 
405
510
conf_tests = { 'CheckPKGConfig' : CheckPKGConfig,
406
511
               'CheckPKG' : CheckPKG,
 
512
               'FindBoost' : FindBoost,
407
513
               'CheckBoost' : CheckBoost,
408
514
               'GetBoostLibVersion' : GetBoostLibVersion,
409
515
               'GetMapnikLibVersion' : GetMapnikLibVersion,
479
585
    if env['JOBS'] > 1:
480
586
        SetOption("num_jobs", env['JOBS'])  
481
587
    
 
588
    if env['PKG_CONFIG_PATH']:
 
589
        env['ENV']['PKG_CONFIG_PATH'] = env['PKG_CONFIG_PATH']
 
590
        # otherwise this variable == os.environ["PKG_CONFIG_PATH"]
 
591
 
482
592
    thread_suffix = 'mt'
483
593
    if env['PLATFORM'] == 'FreeBSD':
484
594
        thread_suffix = ''
513
623
        env['CXX'] = 'CC -library=stlport4'
514
624
        if env['THREADING'] == 'multi':
515
625
            env['CXXFLAGS'] = ['-mt']
516
 
    
 
626
        
517
627
    # Adding the required prerequisite library directories to the include path for
518
628
    # compiling and the library path for linking, respectively.
519
 
    for required in ('BOOST', 'PNG', 'JPEG', 'TIFF','PROJ','ICU'):
 
629
    for required in ('PNG', 'JPEG', 'TIFF','PROJ','ICU'):
520
630
        inc_path = env['%s_INCLUDES' % required]
521
631
        lib_path = env['%s_LIBS' % required]
522
632
        env.AppendUnique(CPPPATH = inc_path)
549
659
        ['icudata','unicode/utypes.h' , True,'C++'],
550
660
    ]
551
661
    
 
662
    
 
663
    for libinfo in LIBSHEADERS:
 
664
        if not conf.CheckLibWithHeader(libinfo[0], libinfo[1], libinfo[3]):
 
665
            if libinfo[2]:
 
666
                color_print (1,'Could not find required header or shared library for %s' % libinfo[0])
 
667
                env['MISSING_DEPS'].append(libinfo[0])
 
668
            else:
 
669
                color_print(4,'Could not find optional header or shared library for %s' % libinfo[0])
 
670
                env['SKIPPED_DEPS'].append(libinfo[0])            
 
671
 
 
672
    if env['THREADING'] == 'multi':
 
673
        thread_flag = thread_suffix
 
674
    else:
 
675
        thread_flag = ''
 
676
        
 
677
    conf.FindBoost(BOOST_SEARCH_PREFIXES)
 
678
    
552
679
    # get boost version from boost headers rather than previous approach
553
680
    # of fetching from the user provided INCLUDE path
554
681
    boost_system_required = False
557
684
        boost_version_from_header = int(boost_lib_version_from_header.split('_')[1])
558
685
        if boost_version_from_header >= 35 and env['PLATFORM'] == 'Darwin':
559
686
            boost_system_required = True
 
687
            env['BOOST_SYSTEM_REQUIRED'] = True
560
688
        else:
561
689
            boost_system_required = False
 
690
            env['BOOST_SYSTEM_REQUIRED'] = False
562
691
    
563
692
    # The other required boost headers.
564
693
    BOOST_LIBSHEADERS = [
571
700
        
572
701
    if env['THREADING'] == 'multi':
573
702
        BOOST_LIBSHEADERS.append(['thread', 'boost/thread/mutex.hpp', True])
574
 
        thread_flag = thread_suffix
575
 
    else:
576
 
        thread_flag = ''
577
 
    
578
 
    for libinfo in LIBSHEADERS:
579
 
        if not conf.CheckLibWithHeader(libinfo[0], libinfo[1], libinfo[3]):
580
 
            if libinfo[2]:
581
 
                color_print (1,'Could not find required header or shared library for %s' % libinfo[0])
582
 
                env['MISSING_DEPS'].append(libinfo[0])
583
 
            else:
584
 
                color_print(4,'Could not find optional header or shared library for %s' % libinfo[0])
585
 
                env['SKIPPED_DEPS'].append(libinfo[0])            
586
 
    
587
 
    # Creating BOOST_APPEND according to the Boost library naming order,
588
 
    # which goes <toolset>-<threading>-<abi>-<version>. See:
589
 
    #  http://www.boost.org/doc/libs/1_35_0/more/getting_started/unix-variants.html#library-naming
590
 
    append_params = ['']
591
 
    if env['BOOST_TOOLKIT']: append_params.append(env['BOOST_TOOLKIT'])
592
 
    if thread_flag: append_params.append(thread_flag)
593
 
    if env['BOOST_ABI']: append_params.append(env['BOOST_ABI'])
594
 
    if env['BOOST_VERSION']: append_params.append(env['BOOST_VERSION'])
595
 
    
 
703
                
596
704
    # if the user is not setting custom boost configuration
597
 
    # enforce boost version greater than or equal to 1.33
598
 
    if not conf.CheckBoost('1.33'):
599
 
        color_print (1,'Boost version 1.33 or greater is requred') 
 
705
    # enforce boost version greater than or equal to 1.34
 
706
    if not conf.CheckBoost('1.34'):
 
707
        color_print (1,'Boost version 1.34 or greater is requred') 
600
708
        if not env['BOOST_VERSION']:
601
 
            env['MISSING_DEPS'].append('boost version >=1.33')
 
709
            env['MISSING_DEPS'].append('boost version >=1.34')
602
710
    else:
603
711
        color_print (4,'Found boost lib version... %s' % boost_lib_version_from_header )
604
712
    
605
 
    # Constructing the BOOST_APPEND setting that will be used to find the
606
 
    # Boost libraries.
607
 
    if len(append_params) > 1: 
608
 
        env['BOOST_APPEND'] = '-'.join(append_params)
609
 
    else: 
610
 
        env['BOOST_APPEND'] = ''
611
 
    
612
713
    for count, libinfo in enumerate(BOOST_LIBSHEADERS):
613
714
        if not conf.CheckLibWithHeader('boost_%s%s' % (libinfo[0],env['BOOST_APPEND']), libinfo[1], 'C++'):
614
715
            if libinfo[2]:
710
811
          color_print(4,"Did not use user config file, no custom path variables will be saved...")
711
812
 
712
813
        if env['SKIPPED_DEPS']:
713
 
            color_print(1,'\nHowever, these optional dependencies were not found:\n   - %s' % '\n   - '.join(env['SKIPPED_DEPS']))
 
814
            color_print(3,'\nNote: will build without these optional dependencies:\n   - %s' % '\n   - '.join(env['SKIPPED_DEPS']))
714
815
            print
715
816
 
716
817
        # fetch the mapnik version header in order to set the
717
818
        # ABI version used to build libmapnik.so on linux in src/SConscript
718
819
        abi = conf.GetMapnikLibVersion()
719
 
        abi_fallback = [0,6,0]
 
820
        abi_fallback = [0,6,1]
720
821
        if not abi:
721
822
            color_print(1,'Problem encountered parsing mapnik version, falling back to %s' % abi_fallback)
722
823
            env['ABI_VERSION'] = abi_fallback
847
948
# Build the core library
848
949
SConscript('src/SConscript')
849
950
 
850
 
# Build the c++ rundemo app if requested
851
 
if env['DEMO']:
852
 
    SConscript('demo/c++/SConscript')
853
 
 
854
 
# Build the pgsql2psqlite app if requested
855
 
if env['PGSQL2SQLITE']:
856
 
    SConscript('utils/pgsql2sqlite/SConscript')
857
 
 
858
 
# Build shapeindex and remove its dependency from the LIBS
859
 
if 'boost_program_options%s' % env['BOOST_APPEND'] in env['LIBS']:
860
 
    SConscript('utils/shapeindex/SConscript')
861
 
    env['LIBS'].remove('boost_program_options%s' % env['BOOST_APPEND'])
862
 
else :
863
 
    color_print(1,"WARNING: Cannot find boost_program_options. 'shapeindex' won't be available")
864
 
 
 
951
# Build the requested and able-to-be-compiled input plug-ins
865
952
GDAL_BUILT = False
866
953
OGR_BUILT = False
867
 
# Build the requested and able-to-be-compiled input plug-ins
868
954
for plugin in env['REQUESTED_PLUGINS']:
869
955
    details = env['PLUGINS'][plugin]
870
956
    if details['lib'] in env['LIBS']:
879
965
    elif not details['lib']:
880
966
        # build internal shape and raster plugins
881
967
        SConscript('plugins/input/%s/SConscript' % plugin)
 
968
 
 
969
# Build the c++ rundemo app if requested
 
970
if env['DEMO']:
 
971
    SConscript('demo/c++/SConscript')
 
972
 
 
973
# Build the pgsql2psqlite app if requested
 
974
if env['PGSQL2SQLITE']:
 
975
    SConscript('utils/pgsql2sqlite/SConscript')
 
976
    
 
977
# Build shapeindex and remove its dependency from the LIBS
 
978
if 'boost_program_options%s' % env['BOOST_APPEND'] in env['LIBS']:
 
979
    SConscript('utils/shapeindex/SConscript')
 
980
    env['LIBS'].remove('boost_program_options%s' % env['BOOST_APPEND'])
 
981
else :
 
982
    color_print(1,"WARNING: Cannot find boost_program_options. 'shapeindex' won't be available")
882
983
    
883
984
# Build the Python bindings
884
985
if 'python' in env['BINDINGS']: