1import sys 2import os 3import imp 4from glob import glob 5 6####################################################### 7# reusable functions and data structures 8####################################################### 9def LoadTool(name, env, **kw): 10 config_path = GetBuildPath('#/Build/Tools/SCons') 11 file, path, desc = imp.find_module(name, [config_path]) 12 module = imp.load_module(name, file, path, desc) 13 module.generate(env, **kw) 14 15def MergeListUnique(item_list, items): 16 for item in items: 17 if not item in item_list: item_list.append(item) 18 19def MergeItemUnique(item_list, item): 20 if not item in item_list: item_list.append(item) 21 22def GlobSources(drct, patterns, excluded_files=[]): 23 root = GetBuildPath('#'+drct) 24 files = [] 25 for pattern in Split(patterns): 26 files += glob(root+'/'+pattern) 27 return [drct+'/'+os.path.basename(x) for x in files if os.path.basename(x) not in excluded_files] 28 29def GetDirPath(dir): 30 return '#/'+dir 31 32def DeclareBuildDir(dir): 33 env.VariantDir(dir, GetDirPath(dir), duplicate=0) 34 35def GetIncludeDirs(modules, exclude=None): 36 dirs = [] 37 for module in Split(modules): 38 if Modules.has_key(module) and not module == exclude: 39 dirs += Modules[module].GetIncludeDirs() 40 else: 41 dirs += [GetDirPath(module)] 42 return dirs 43 44def GetLibraries(modules): 45 libs = [] 46 for module in Split(modules): 47 if Modules.has_key(module): 48 libs += Modules[module].GetLibraries() 49 else: 50 libs += [module] 51 return libs 52 53Modules = {} 54class Module: 55 def __init__(self, name, included_modules = [], linked_modules = []): 56 self.name = name 57 self.included_modules = included_modules 58 self.linked_modules = linked_modules 59 self.product = [] 60 61 def GetLibraries(self): 62 return self.product+GetLibraries(self.linked_modules) 63 64 def GetIncludeDirs(self): 65 return GetIncludeDirs(self.included_modules+self.build_include_dirs, self.name) 66 67class LibraryModule(Module): 68 def __init__(self, name, 69 build_source_dirs = ['.'], 70 build_source_files = {}, 71 source_root = 'Source', 72 build_source_pattern = ['*.c', '*.cpp'], 73 build_include_dirs = [], 74 included_modules = [], 75 included_only_modules = [], 76 linked_modules = [], 77 environment = None, 78 excluded_files = [], 79 extra_cpp_defines = [], 80 shared = False, 81 install = False) : 82 build_source_dirs = [source_root+'/'+drct for drct in build_source_dirs] 83 Module.__init__(self, 84 name, 85 Split(included_modules)+Split(included_only_modules)+Split(build_source_dirs), 86 Split(linked_modules)+Split(included_modules)) 87 self.build_include_dirs = build_include_dirs 88 if environment is None: 89 self.env = env.Clone() 90 else: 91 self.env = environment.Clone() 92 self.env.AppendUnique(CPPDEFINES = extra_cpp_defines) 93 94 # store this new object in the module dictionary 95 Modules[name] = self 96 97 # for each source drct to build, create a VariantDir 98 # to say where we want the object files to be built, 99 # and compute the list of source files to build 100 sources = [] 101 for drct in Split(build_source_dirs): 102 DeclareBuildDir(drct) 103 sources += GlobSources(drct, build_source_pattern, excluded_files) 104 105 # add cherry-picked files 106 for drct in build_source_files.keys(): 107 pattern = build_source_files[drct] 108 drct_path = source_root+'/'+drct 109 DeclareBuildDir(drct_path) 110 sources += GlobSources(drct_path, pattern) 111 112 # calculate our build include path 113 cpp_path = GetIncludeDirs(Split(self.build_include_dirs) + Split(build_source_dirs) + self.included_modules + self.linked_modules) 114 115 # the product is a library 116 self.env.AppendUnique(CPPPATH=cpp_path) 117 if shared is False: 118 self.product = self.env.Library(target=name, source=sources) 119 else: 120 libs = GetLibraries(Split(linked_modules)) 121 self.product = self.env.SharedLibrary(target=name, LIBS=libs, source=sources) 122 self.env.Alias(name, self.product) 123 124 # copy to Targets folder 125 if install is True: 126 inst = env.Install(dir=env.GetBuildPath('#/Targets/'+env['target']+'/'+env['build_config']), source=self.product) 127 if env['build_config'] == 'Release' and env.has_key('STRIP'): 128 env.AddPostAction(inst, env['STRIP']+' $TARGETS'); 129 130def Application(name, dir, deps, install = False): 131 DeclareBuildDir(dir) 132 libs = GetLibraries(deps) 133 cpp_path = GetIncludeDirs(deps) 134 135 prog = env.Program(name, 136 GlobSources(dir, ['*.c', '*.cpp']) + env['NPT_EXTRA_EXECUTABLE_OBJECTS'], 137 LIBS=libs, CPPPATH=cpp_path) 138 #env.Alias(name, prog) 139 if env.has_key('NPT_EXECUTABLE_POST_PROCESSOR'): 140 env.AddPostAction(prog, env['NPT_EXECUTABLE_POST_PROCESSOR']) 141 142 # copy to Targets folder 143 if install is True: 144 inst = env.Install(dir=env.GetBuildPath('#/Targets/'+env['target']+'/'+env['build_config']), source=prog) 145 if env['build_config'] == 'Release' and env.has_key('STRIP'): 146 env.AddPostAction(inst, env['STRIP']+' $TARGETS'); 147 148####################################################### 149# Main Build 150####################################################### 151Import("env") 152 153### defaults 154env['NPT_EXTRA_LIBS'] = [] 155env['NPT_EXTRA_EXECUTABLE_OBJECTS'] = [] 156 157if (env['build_config'] == 'Debug'): 158 env.AppendUnique(CPPDEFINES=['NPT_DEBUG', 'NPT_CONFIG_ENABLE_LOGGING', 'PLATINUM_UPNP_SPECS_STRICT']) 159else: 160 env.AppendUnique(CPPDEFINES=['NDEBUG', 'NPT_CONFIG_ENABLE_LOGGING', 'PLATINUM_UPNP_SPECS_STRICT']) 161 162### try to read in any target specific configuration 163target_config_file = env.GetBuildPath('#/Build/Targets/'+env['target']+'/Config.scons') 164if os.path.exists(target_config_file): 165 # Load the target-specific config file 166 execfile(target_config_file) 167 168####################################################### 169# modules 170# 171# Usage: 172# 173# The LibraryModule() function declares a code module 174# The included_modules parameter is a list of all the modules and/or directories 175# that will be added to the include path when building this module AND to 176# the include path of any other module that depends on this one. 177# The linked_modules parameter is a list of all the modules and/or directories 178# that are necessary to build this module. These modules will be added to 179# the include path of this module, but not to that of the modules that depend 180# on this module. The modules that depend on this module, however, will 181# automatically link with the linked_modules. 182# Note that the included_modules list is automatically added to the 183# linked_modules list, so that you do not need to list in linked_modules 184# the modules that are already listed in included_modules. 185# If a module needs to export an include path to its dependents that 186# is not a module that the dependent can link with (ex: an include dir), 187# list it in the included_only_modules. 188# To summarize: included_modules should list all the modules that users 189# of the public interface should depend on; linked_modules should list 190# all the modules not listed in included_modules that are used by the 191# module's implementation only. 192####################################################### 193# Neptune 194NPT_SOURCE_ROOT = 'ThirdParty/Neptune' 195 196extra_cpp_flags = [] 197neptune_extra_linked_modules = [] 198if not env.has_key('NPT_CONFIG_NO_ZIP'): 199 extra_cpp_flags = ['NPT_CONFIG_ENABLE_ZIP'] 200 neptune_extra_linked_modules += ['Zlib'] 201 202 LibraryModule(name = 'Zlib', 203 source_root = NPT_SOURCE_ROOT, 204 build_source_dirs = ['ThirdParty/zlib-1.2.3']) 205 206if not env.has_key('NPT_CONFIG_NO_SSL'): 207 extra_cpp_flags += ['NPT_CONFIG_ENABLE_TLS'] 208 tls_data_dirs = ['Data/TLS'] 209 tls_tests = ['Tls1'] 210 neptune_extra_linked_modules += ['axTLS'] 211 212 LibraryModule(name = 'axTLS', 213 source_root = NPT_SOURCE_ROOT, 214 build_source_dirs = ['ThirdParty/axTLS/crypto', 'ThirdParty/axTLS/ssl', 'ThirdParty/axTLS/config/Generic']) 215else: 216 tls_data_dirs = [] 217 tls_tests = [] 218 219if not env.has_key('NPT_CONFIG_NO_CRYPTO'): 220 extra_cpp_flags += ['NPT_CONFIG_ENABLE_CRYPTO'] 221 neptune_excluded_files = [] 222else: 223 neptune_excluded_files = ['NptCrypto.cpp', 'NptDigest.cpp'] 224 225LibraryModule(name = 'Neptune', 226 build_source_dirs = ['Core']+tls_data_dirs, 227 build_source_files = env['NPT_SYSTEM_SOURCES'], 228 excluded_files = neptune_excluded_files, 229 extra_cpp_defines = extra_cpp_flags, 230 linked_modules = env['NPT_EXTRA_LIBS']+neptune_extra_linked_modules, 231 source_root = NPT_SOURCE_ROOT + '/Source') 232 233# Platinum 234LibraryModule(name = 'Platinum', 235 build_source_dirs = ['Core', 'Extras'], 236 build_include_dirs = ['Source/Platinum'], 237 extra_cpp_defines = extra_cpp_flags, 238 included_modules = ['Neptune']) 239 240# Platinum MediaServer 241LibraryModule(name = 'PltMediaServer', 242 build_source_dirs = ['MediaServer'], 243 included_modules = ['Platinum'], 244 source_root = 'Source/Devices') 245 246# Platinum MediaRenderer 247LibraryModule(name = 'PltMediaRenderer', 248 build_source_dirs = ['MediaRenderer'], 249 included_modules = ['Platinum', 'PltMediaServer'], 250 source_root = 'Source/Devices') 251 252# Platinum MediaConnect 253LibraryModule(name = 'PltMediaConnect', 254 build_source_dirs = ['MediaConnect'], 255 included_modules = ['Platinum', 'PltMediaServer', 'PltMediaRenderer'], 256 excluded_files = ['MACFromIP.cpp'], 257 source_root = 'Source/Devices') 258 259for app in ['MicroMediaController', 'MediaCrawler', 'MediaConnect', 'FrameStreamer']: 260 Application(name = app, 261 dir = 'Source/Apps/' + app, 262 deps = ['Platinum', 'PltMediaServer', 'PltMediaRenderer', 'PltMediaConnect'], 263 install = True) 264 265for test in ['FileMediaServer', 'MediaRenderer', 'LightSample', 'Http', 'Time']: 266 Application(name = test+'Test', 267 dir = 'Source/Tests/' + test, 268 deps = ['Platinum', 'PltMediaServer', 'PltMediaRenderer', 'PltMediaConnect'], 269 install = True) 270 271for tool in ['TextToHeader']: 272 Application(name = tool, 273 dir = 'Source/Tools/' + tool, 274 deps = ['Platinum'], 275 install = True) 276