#!/bin/env python # sim-build -- build the cactus distribution # # Michael Thomas # Center for Computation & Technology # Louisiana State University # import sys, os, shutil ############################################ ## APP SPECIFIC DEFINES ## # # Usage when (-h, --help) is used, this is the first line showing how to call the app # optionGroups which option groups from etc/options to import. common is always imported. App = "sim-build.py" Usage = "usage: %prog [--remotemachine] [options] ..." optionGroups = ['sim-build'] Purpose = "build cactus either locally or remotely" ############################################ ############################################ ## INIT ## if os.path.basename(sys.argv[0]) == App: rp = os.path.realpath(__file__) paths = rp.split(os.sep) paths.pop() paths.pop() global BASE_PATH BASE_PATH = os.sep.join(paths) sys.path.append(BASE_PATH) from lib import * ## FUNCTIONS ## def GetOptions(): return None def BuildUsageString(): return None def PrepConfiguration(configName): global SimEnvironment global SimLib global ConfigurationDatabase build_debug = OptionsManager.GetOption("debug") build_optimise = OptionsManager.GetOption("optimise") build_unsafe = OptionsManager.GetOption("unsafe") build_profile = OptionsManager.GetOption("profile") build_reconfig = OptionsManager.GetOption("reconfig") build_clean = OptionsManager.GetOption("clean") build_optimise = not(build_debug) machineName = self.SimEnvironment.LocalMachine machineEntry = self.SimEnvironment.LocalMachineEntry make = DefineDatabase.SubAll(machineEntry.GetKey('make')) subfolders = ['bindings', 'build', 'config-data', 'lib', 'scratch'] configBase = SimLib.BuildPath([SimEnvironment.CONFIGS_PATH, configName]) if not(os.path.exists(configBase)): try: os.mkdir(configBase) except OSError: pass SimLib.ExecuteCommand("mkdir %s" % configBase) for sub in subfolders: sf = SimLib.BuildPath([configBase, sub]) SimLib.ExecuteCommand("mkdir %s" % sf) storedOptions = SimLib.BuildPath([configBase, "OptionList"]) hasStoredOptions = os.path.exists(storedOptions) cctkConfigPath = SimLib.BuildPath([configBase, "config-data", "cctk_Config.h"]) hasCompleteConfig = os.path.exists(cctkConfigPath) if hasStoredOptions: storedOptionSettings = SimLib.GetFileContents(storedOptions) else: storedOptionSettings = None print "HasStoredOptions: %s" % hasStoredOptions removeConfig = False needOptionList = False if not(hasStoredOptions) or build_reconfig or not(hasCompleteConfig): needOptionList = True optionlist = SimLib.GetOptionsList(needOptionList) print "optionlist: %s, required = %s" % (optionlist, needOptionList) optionSettings = SimLib.GetFileContents(optionlist) DefineDatabase.Set("DEBUG", SimLib.BoolToYesNo(build_debug)) DefineDatabase.Set("OPTIMISE", SimLib.BoolToYesNo(build_optimise)) DefineDatabase.Set("UNSAFE", SimLib.BoolToYesNo(build_unsafe)) DefineDatabase.Set("PROFILE", SimLib.BoolToYesNo(build_profile)) DefineDatabase.SubAll(optionSettings) if not(hasCompleteConfig) or storedOptionSettings == None or storedOptionSettings != optionSettings: hasOutdatedConfig = True else: hasOutdatedConfig = False print "hasOutdatedConfig: %s" % hasOutdatedConfig if hasOutdatedConfig or build_reconfig: oldVersion = "0000-00-00" if storedOptionSettings != None: oldVersion = SimLib.GetVersion(storedOptionSettings) newVersion = SimLib.GetVersion(optionSettings) print "oldVersion %s, newVersion %s" % (oldVersion, newVersion) if newVersion != oldVersion: removeConfig = True print "Reconfiguring %s" % configName SimLib.RemoveFile("%s.old" % storedOptions) SimLib.RenameFile(storedOptions, "%s.old" % storedOptions) print "Writing configuration to: %s" % storedOptions SimLib.WriteContents(storedOptions, optionSettings) #"echo yes | { $make $configuration_name-config options=configs/$configuration_name/OptionList; }"; cmd = "echo yes | { %s %s-config options=%s; }" % (make, configName, storedOptions) SimLib.ExecuteCommand(cmd) #force a rebuild SimLib.RemoveFile(SimLib.BuildPath([configBase, 'config-data', 'make.thornlist'])) #remove the old config if necessary if removeConfig: print "Complete rebuild required" else: if not(hasStoredOptions): print "Configuration %s has no option list, and no option list was specified." % configName sys.exit(1) if build_clean or removeConfig: print "Cleaning %s" % configName SimLib.ExecuteCommand("%s %s-realclean" % (make, configName)) ## deal with submit script now storedSubmitScript = SimLib.BuildPath([configBase, "SubmitScript"]) hasStoredSubmitScript = os.path.exists(storedSubmitScript) needSubmitScript = False if not(hasStoredSubmitScript) or build_reconfig: needSubmitScript = True submitscript = SimLib.GetSubmitScript(needSubmitScript) sContents = SimLib.GetFileContents(submitscript) ssContents = SimLib.GetFileContents(storedSubmitScript) submitScriptOutdated = False if submitscript != None: if not(hasStoredSubmitScript) or (sContents != ssContents): submitScriptOutdated = True if submitScriptOutdated or build_reconfig: print "Updated script file for configuration %s" % configName SimLib.RemoveFile("%s.old" % storedSubmitScript) SimLib.RenameFile(storedSubmitScript, "%s.old" % storedSubmitScript) shutil.copyfile(submitscript, storedSubmitScript) else: if not(hasStoredSubmitScript): print "Configuration %s has no submit script, and no script file was specified" % configName sys.exit(1) ## deal with thornlist now storedThornList = SimLib.BuildPath([configBase, "ThornList"]) hasStoredThornList = os.path.exists(storedThornList) needThornList = False if not(hasStoredThornList) or build_reconfig: needThornList = True thornlist = SimLib.GetThornList(needThornList) tContents = SimLib.GetFileContents(thornlist) ttContents = SimLib.GetFileContents(storedThornList) thornFileOutdated = False if thornlist != None: if not(hasStoredThornList) or (tContents != ttContents): thornFileOutdated = True if thornFileOutdated or build_reconfig: print "Updated thorn list for configuration %s" % configName SimLib.RemoveFile("%s.old" % storedThornList) SimLib.RenameFile(storedThornList, "%s.old" % storedThornList) shutil.copyfile(thornlist, storedThornList) else: if not(hasStoredThornList): print "Configuration %s has no thorn list, and no thorn list file was specified" % configName sys.exit(1) def BuildConfiguration(configName): global SimEnvironment global SimLib global ConfigurationDatabase machineName = self.SimEnvironment.LocalMachine machineEntry = self.SimEnvironment.LocalMachineEntry make = DefineDatabase.SubAll(machineEntry.GetKey('make')) print "Building %s" % configName SimLib.ExecuteCommand("%s %s" % (make, configName)) print "Building utilities for %s" % configName SimLib.ExecuteCommand("%s %s-utils" % (make, configName)) def RemoteBuild(machineName): global SimEnvironment RemoteEnvironment = simremote.RemoteEnvironment(SimEnvironment) RemoteEnvironment.init(machineName) RemoteEnvironment.ExecuteSameCommand(parrotArguments=True, stripArguments=['remotemachine']) ############################### MAIN ############################### def main(env): global OptionsManager global ConfigurationDatabase global SimLib global DefineDatabase global SimEnvironment SimEnvironment = env OptionsManager = SimEnvironment.OptionsManager ConfigurationDatabase = SimEnvironment.ConfigurationDatabase SimLib = SimEnvironment.SimLib DefineDatabase = SimEnvironment.DefineDatabase ############################################ if os.path.basename(SimEnvironment.EXECUTABLE) == App: print "sim-build: build cactus with the specified configuration name(s)\n" print "mdb: %s" % SimEnvironment.mdb print "cdb: %s" % SimEnvironment.cdb if SimEnvironment.udb != None: print "udb: %s" % SimEnvironment.udb print # make sure our configs directory is created try: os.mkdir(SimEnvironment.CONFIGS_PATH) except OSError: pass if OptionsManager.HasOption("remotemachine"): remoteMachine = OptionsManager.GetOption("remotemachine") print "Building for remote machine: %s" % remoteMachine RemoteBuild(remoteMachine) return # get our modes of compilation build_debug = OptionsManager.GetOption("debug") build_optimise = OptionsManager.GetOption("optimise") build_unsafe = OptionsManager.GetOption("unsafe") build_profile = OptionsManager.GetOption("profile") build_optimise = not(build_debug) configList = OptionsManager.args if len(configList) == 0: configList = [SimLib.GetDefaultConfiguration()] for config in configList: print "Using configuration: %s" % config machineName = self.SimEnvironment.LocalMachine machineEntry = self.SimEnvironment.LocalMachineEntry req_keys = ['user', 'email', 'make'] SimLib.VerifyKeys(machineEntry, req_keys) user = machineEntry.GetKey("user") email = machineEntry.GetKey("email") DefineDatabase.Set('USER', user) DefineDatabase.Set('EMAIL', email) make = DefineDatabase.SubAll(machineEntry.GetKey('make')) simpath = SimEnvironment.BASE_PATH cactusDir = SimEnvironment.CACTUS_PATH print "Cactus Directory: %s" % cactusDir if os.getcwd() != cactusDir: print "Current Working directory does not match Cactus sourcetree, changing to %s" % cactusDir # make sure we're in the Cactus source directory, otherwise all of this will blow way up. os.chdir(cactusDir) for config in configList: PrepConfiguration(config) BuildConfiguration(config) # only run if you are App if os.path.basename(sys.argv[0]) == App: global SimEnvironment SimEnvironment = simenv.SimEnvironment(BASE_PATH, os.path.realpath(sys.argv[0])) SimEnvironment.initApp(usageString=Usage, optionGroups=optionGroups) main(SimEnvironment)