1 """ 2 Notes: 3 - shared library support is buggy: it assumes that a static and dynamic library can be build from the same object files. This is not true on many platforms. For this reason it is only enabled on linux-gcc at the current time. 4 5 To add a platform: 6 - add its name in options allowed_values below 7 - add tool initialization for this platform. Search for "if platform == 'suncc'" as an example. 8 """ 9 10 import os 11 import os.path 12 import sys 13 14 JSONCPP_VERSION = open(File('#version').abspath,'rt').read().strip() 15 DIST_DIR = '#dist' 16 17 options = Variables() 18 options.Add( EnumVariable('platform', 19 'Platform (compiler/stl) used to build the project', 20 'msvc71', 21 allowed_values='suncc vacpp mingw msvc6 msvc7 msvc71 msvc80 msvc90 linux-gcc'.split(), 22 ignorecase=2) ) 23 24 try: 25 platform = ARGUMENTS['platform'] 26 if platform == 'linux-gcc': 27 CXX = 'g++' # not quite right, but env is not yet available. 28 import commands 29 version = commands.getoutput('%s -dumpversion' %CXX) 30 platform = 'linux-gcc-%s' %version 31 print "Using platform '%s'" %platform 32 LD_LIBRARY_PATH = os.environ.get('LD_LIBRARY_PATH', '') 33 LD_LIBRARY_PATH = "%s:libs/%s" %(LD_LIBRARY_PATH, platform) 34 os.environ['LD_LIBRARY_PATH'] = LD_LIBRARY_PATH 35 print "LD_LIBRARY_PATH =", LD_LIBRARY_PATH 36 except KeyError: 37 print 'You must specify a "platform"' 38 sys.exit(2) 39 40 print "Building using PLATFORM =", platform 41 42 rootbuild_dir = Dir('#buildscons') 43 build_dir = os.path.join( '#buildscons', platform ) 44 bin_dir = os.path.join( '#bin', platform ) 45 lib_dir = os.path.join( '#libs', platform ) 46 sconsign_dir_path = Dir(build_dir).abspath 47 sconsign_path = os.path.join( sconsign_dir_path, '.sconsign.dbm' ) 48 49 # Ensure build directory exist (SConsignFile fail otherwise!) 50 if not os.path.exists( sconsign_dir_path ): 51 os.makedirs( sconsign_dir_path ) 52 53 # Store all dependencies signature in a database 54 SConsignFile( sconsign_path ) 55 56 def make_environ_vars(): 57 """Returns a dictionnary with environment variable to use when compiling.""" 58 # PATH is required to find the compiler 59 # TEMP is required for at least mingw 60 # LD_LIBRARY_PATH & co is required on some system for the compiler 61 vars = {} 62 for name in ('PATH', 'TEMP', 'TMP', 'LD_LIBRARY_PATH', 'LIBRARY_PATH'): 63 if name in os.environ: 64 vars[name] = os.environ[name] 65 return vars 66 67 68 env = Environment( ENV = make_environ_vars(), 69 toolpath = ['scons-tools'], 70 tools=[] ) #, tools=['default'] ) 71 72 if platform == 'suncc': 73 env.Tool( 'sunc++' ) 74 env.Tool( 'sunlink' ) 75 env.Tool( 'sunar' ) 76 env.Append( CCFLAGS = ['-mt'] ) 77 elif platform == 'vacpp': 78 env.Tool( 'default' ) 79 env.Tool( 'aixcc' ) 80 env['CXX'] = 'xlC_r' #scons does not pick-up the correct one ! 81 # using xlC_r ensure multi-threading is enabled: 82 # http://publib.boulder.ibm.com/infocenter/pseries/index.jsp?topic=/com.ibm.vacpp7a.doc/compiler/ref/cuselect.htm 83 env.Append( CCFLAGS = '-qrtti=all', 84 LINKFLAGS='-bh:5' ) # -bh:5 remove duplicate symbol warning 85 elif platform == 'msvc6': 86 env['MSVS_VERSION']='6.0' 87 for tool in ['msvc', 'msvs', 'mslink', 'masm', 'mslib']: 88 env.Tool( tool ) 89 env['CXXFLAGS']='-GR -GX /nologo /MT' 90 elif platform == 'msvc70': 91 env['MSVS_VERSION']='7.0' 92 for tool in ['msvc', 'msvs', 'mslink', 'masm', 'mslib']: 93 env.Tool( tool ) 94 env['CXXFLAGS']='-GR -GX /nologo /MT' 95 elif platform == 'msvc71': 96 env['MSVS_VERSION']='7.1' 97 for tool in ['msvc', 'msvs', 'mslink', 'masm', 'mslib']: 98 env.Tool( tool ) 99 env['CXXFLAGS']='-GR -GX /nologo /MT' 100 elif platform == 'msvc80': 101 env['MSVS_VERSION']='8.0' 102 for tool in ['msvc', 'msvs', 'mslink', 'masm', 'mslib']: 103 env.Tool( tool ) 104 env['CXXFLAGS']='-GR -EHsc /nologo /MT' 105 elif platform == 'msvc90': 106 env['MSVS_VERSION']='9.0' 107 # Scons 1.2 fails to detect the correct location of the platform SDK. 108 # So we propagate those from the environment. This requires that the 109 # user run vcvars32.bat before compiling. 110 if 'INCLUDE' in os.environ: 111 env['ENV']['INCLUDE'] = os.environ['INCLUDE'] 112 if 'LIB' in os.environ: 113 env['ENV']['LIB'] = os.environ['LIB'] 114 for tool in ['msvc', 'msvs', 'mslink', 'masm', 'mslib']: 115 env.Tool( tool ) 116 env['CXXFLAGS']='-GR -EHsc /nologo /MT' 117 elif platform == 'mingw': 118 env.Tool( 'mingw' ) 119 env.Append( CPPDEFINES=[ "WIN32", "NDEBUG", "_MT" ] ) 120 elif platform.startswith('linux-gcc'): 121 env.Tool( 'default' ) 122 env.Append( LIBS = ['pthread'], CCFLAGS = os.environ.get("CXXFLAGS", "-Wall"), LINKFLAGS=os.environ.get("LDFLAGS", "") ) 123 env['SHARED_LIB_ENABLED'] = True 124 else: 125 print "UNSUPPORTED PLATFORM." 126 env.Exit(1) 127 128 env.Tool('targz') 129 env.Tool('srcdist') 130 env.Tool('globtool') 131 132 env.Append( CPPPATH = ['#include'], 133 LIBPATH = lib_dir ) 134 short_platform = platform 135 if short_platform.startswith('msvc'): 136 short_platform = short_platform[2:] 137 # Notes: on Windows you need to rebuild the source for each variant 138 # Build script does not support that yet so we only build static libraries. 139 # This also fails on AIX because both dynamic and static library ends with 140 # extension .a. 141 env['SHARED_LIB_ENABLED'] = env.get('SHARED_LIB_ENABLED', False) 142 env['LIB_PLATFORM'] = short_platform 143 env['LIB_LINK_TYPE'] = 'lib' # static 144 env['LIB_CRUNTIME'] = 'mt' 145 env['LIB_NAME_SUFFIX'] = '${LIB_PLATFORM}_${LIB_LINK_TYPE}${LIB_CRUNTIME}' # must match autolink naming convention 146 env['JSONCPP_VERSION'] = JSONCPP_VERSION 147 env['BUILD_DIR'] = env.Dir(build_dir) 148 env['ROOTBUILD_DIR'] = env.Dir(rootbuild_dir) 149 env['DIST_DIR'] = DIST_DIR 150 if 'TarGz' in env['BUILDERS']: 151 class SrcDistAdder: 152 def __init__( self, env ): 153 self.env = env 154 def __call__( self, *args, **kw ): 155 apply( self.env.SrcDist, (self.env['SRCDIST_TARGET'],) + args, kw ) 156 env['SRCDIST_BUILDER'] = env.TarGz 157 else: # If tarfile module is missing 158 class SrcDistAdder: 159 def __init__( self, env ): 160 pass 161 def __call__( self, *args, **kw ): 162 pass 163 env['SRCDIST_ADD'] = SrcDistAdder( env ) 164 env['SRCDIST_TARGET'] = os.path.join( DIST_DIR, 'jsoncpp-src-%s.tar.gz' % env['JSONCPP_VERSION'] ) 165 166 env_testing = env.Clone( ) 167 env_testing.Append( LIBS = ['json_${LIB_NAME_SUFFIX}'] ) 168 169 def buildJSONExample( env, target_sources, target_name ): 170 env = env.Clone() 171 env.Append( CPPPATH = ['#'] ) 172 exe = env.Program( target=target_name, 173 source=target_sources ) 174 env['SRCDIST_ADD']( source=[target_sources] ) 175 global bin_dir 176 return env.Install( bin_dir, exe ) 177 178 def buildJSONTests( env, target_sources, target_name ): 179 jsontests_node = buildJSONExample( env, target_sources, target_name ) 180 check_alias_target = env.Alias( 'check', jsontests_node, RunJSONTests( jsontests_node, jsontests_node ) ) 181 env.AlwaysBuild( check_alias_target ) 182 183 def buildUnitTests( env, target_sources, target_name ): 184 jsontests_node = buildJSONExample( env, target_sources, target_name ) 185 check_alias_target = env.Alias( 'check', jsontests_node, 186 RunUnitTests( jsontests_node, jsontests_node ) ) 187 env.AlwaysBuild( check_alias_target ) 188 189 def buildLibrary( env, target_sources, target_name ): 190 static_lib = env.StaticLibrary( target=target_name + '_${LIB_NAME_SUFFIX}', 191 source=target_sources ) 192 global lib_dir 193 env.Install( lib_dir, static_lib ) 194 if env['SHARED_LIB_ENABLED']: 195 shared_lib = env.SharedLibrary( target=target_name + '_${LIB_NAME_SUFFIX}', 196 source=target_sources ) 197 env.Install( lib_dir, shared_lib ) 198 env['SRCDIST_ADD']( source=[target_sources] ) 199 200 Export( 'env env_testing buildJSONExample buildLibrary buildJSONTests buildUnitTests' ) 201 202 def buildProjectInDirectory( target_directory ): 203 global build_dir 204 target_build_dir = os.path.join( build_dir, target_directory ) 205 target = os.path.join( target_directory, 'sconscript' ) 206 SConscript( target, build_dir=target_build_dir, duplicate=0 ) 207 env['SRCDIST_ADD']( source=[target] ) 208 209 210 def runJSONTests_action( target, source = None, env = None ): 211 # Add test scripts to python path 212 jsontest_path = Dir( '#test' ).abspath 213 sys.path.insert( 0, jsontest_path ) 214 data_path = os.path.join( jsontest_path, 'data' ) 215 import runjsontests 216 return runjsontests.runAllTests( os.path.abspath(source[0].path), data_path ) 217 218 def runJSONTests_string( target, source = None, env = None ): 219 return 'RunJSONTests("%s")' % source[0] 220 221 import SCons.Action 222 ActionFactory = SCons.Action.ActionFactory 223 RunJSONTests = ActionFactory(runJSONTests_action, runJSONTests_string ) 224 225 def runUnitTests_action( target, source = None, env = None ): 226 # Add test scripts to python path 227 jsontest_path = Dir( '#test' ).abspath 228 sys.path.insert( 0, jsontest_path ) 229 import rununittests 230 return rununittests.runAllTests( os.path.abspath(source[0].path) ) 231 232 def runUnitTests_string( target, source = None, env = None ): 233 return 'RunUnitTests("%s")' % source[0] 234 235 RunUnitTests = ActionFactory(runUnitTests_action, runUnitTests_string ) 236 237 env.Alias( 'check' ) 238 239 srcdist_cmd = env['SRCDIST_ADD']( source = """ 240 AUTHORS README.txt SConstruct 241 """.split() ) 242 env.Alias( 'src-dist', srcdist_cmd ) 243 244 buildProjectInDirectory( 'src/jsontestrunner' ) 245 buildProjectInDirectory( 'src/lib_json' ) 246 buildProjectInDirectory( 'src/test_lib_json' ) 247 #print env.Dump() 248 249