📄 compile.py
字号:
# # ***** BEGIN LICENSE BLOCK *****# Source last modified: $Id: compile.py,v 1.10 2004/10/19 19:38:11 hubbe Exp $# # Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.# # The contents of this file, and the files included with this file,# are subject to the current version of the RealNetworks Public# Source License (the "RPSL") available at# http://www.helixcommunity.org/content/rpsl unless you have licensed# the file under the current version of the RealNetworks Community# Source License (the "RCSL") available at# http://www.helixcommunity.org/content/rcsl, in which case the RCSL# will apply. You may also obtain the license terms directly from# RealNetworks. You may not use this file except in compliance with# the RPSL or, if you have a valid RCSL with RealNetworks applicable# to this file, the RCSL. Please see the applicable RPSL or RCSL for# the rights, obligations and limitations governing use of the# contents of the file.# # Alternatively, the contents of this file may be used under the# terms of the GNU General Public License Version 2 or later (the# "GPL") in which case the provisions of the GPL are applicable# instead of those above. If you wish to allow use of your version of# this file only under the terms of the GPL, and not to allow others# to use your version of this file under the terms of either the RPSL# or RCSL, indicate your decision by deleting the provisions above# and replace them with the notice and other provisions required by# the GPL. If you do not delete the provisions above, a recipient may# use your version of this file under the terms of any one of the# RPSL, the RCSL or the GPL.# # This file is part of the Helix DNA Technology. RealNetworks is the# developer of the Original Code and owns the copyrights in the# portions it created.# # This file, and the files included with this file, is distributed# and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY# KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS# ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET# ENJOYMENT OR NON-INFRINGEMENT.# # Technology Compatibility Kit Test Suite(s) Location:# http://www.helixcommunity.org/content/tck# # Contributor(s):# # ***** END LICENSE BLOCK *****# """Sub-class of the Collate class from collate.py. Implements a handler forsource code modules. It runs Umake to generate a Makefile, then runsmake, nmake, or the generated AppleScript Makefile depending on theplatform."""import osimport sysimport stringimport tracebackimport errimport ascriptimport sysinfoimport shellimport outmsgimport timefrom collate import Collatetry: import macfsexcept: passclass Compile(Collate): """Base compiler class, implements compile functionality common to all platforms.""" def lcb(self, text): l = len(text) if l and text[l-1] == '\n': l = l - 1 if l and text[l-1] == '\r': l = l - 1 outmsg.verbose(text[:l]) def run_cmd(self, cmd): outmsg.verbose(cmd) t = time.time() try: ret=shell.run(cmd, self.lcb) except shell.error, se: e = err.Error() e.Set(str(se)) raise err.error, e outmsg.verbose("Time used: %.2f seconds" % (time.time() - t)) return ret; def run(self): if not os.path.isfile("Umakefil") and \ not os.path.isfile("umakefil"): self.error("Umakefil not found.") else: self.build() def build(self): ## Makefile Generation: run umake if there is no Makefile ## under the "no_umake_mode_flag", if (self.settings.get("no_umake_mode_flag") and \ not os.path.isfile("Makefile")) or \ not self.settings.get("no_umake_mode_flag"): self.umake() if not self.settings.get("umake_only_flag"): self.build_common() def build_common(self): ## make clean ## under fast builds, we don't want to make clean ## don't do a make clean when doing a clean build if self.settings.get('clean_mode_flag'): status, text = self.make_clean() ## make depend -- do not check status, it's okay ## if this command fails because makedepend is broken ## and too many developers can't figure it out if not self.settings.get('no_make_depend_flag'): status, text = self.make_depend() ## make all status, text = self.make_all() if status: e = err.Error() e.Set("Make failed.") self.error(e.text) raise err.error, e ## make copy if not self.settings.get('no_make_copy_flag'): status, text = self.make_copy() def umake(self): self.output("generating makefiles") ## make a unique build_options list build_options = self.settings["build_options"][:] ## set static flag for build if self.module.build_static_flag: build_options.append("static") if self.module.build_static_only_flag: build_options.append("static_only") ## save current working directory because we don't ## know where we are going to be left after the call to Umake old_dir = os.getcwd() try: self.run_umake(build_options) except err.error, e: os.chdir(old_dir) raise else: os.chdir(old_dir) def run_umake(self, build_options): ## attempt to clear the NS/Working space of Umake import umake reload(umake) t = time.time() try: result = umake.Umake(build_options) except err.error, e: self.error(e.text) raise err.error, e if result and len(result): e = err.Error() e.Set("umake error=\"%s\"" % (result)) raise err.error, e outmsg.verbose("Time used: %.2f seconds" % (time.time() - t)) def make(self, arg = ""): self.error('make needs to be implemented in a subclass') def make_clean(self): ## don't do a make clean when doing a clobber build if self.settings.get('clobber_mode_flag'): return 0, "" self.output("making clean") (status, text) = self.make("clean") return status, text def make_depend(self): self.output("making depend") (status, text) = self.make("depend") return status, text def make_all(self): self.output("making all") (status, text) = self.make("") return status, text def make_copy(self): self.output("making copy") (status, text) = self.make("copy") return status, textclass UNIXCompile(Compile): """UNIX version of the Compile class. Runs GNU make.""" def make(self, arg = ''): if self.settings.has_key("make_jobs"): cmd = "make -j %s %s " % (self.settings["make_jobs"], arg) else: cmd = "make %s" % (arg) return self.run_cmd(cmd)class WinCompile(Compile): """Windows version of the Compile class. It runs nmake.""" def make(self, arg = ""): cmd = "nmake /nologo %s" % (arg) return self.run_cmd(cmd)class MacintoshCompile(Compile): """Macintosh version of the Compile class. It creates a small AppleScript in memory to execute the all() function that exists in the Umake generated AppleScript Makefile.""" def make_depend(self): return 0, "" def make_clean(self): return 0, "" ## Kluge, do drmsigning here!! ## Extra kluge: Copied code from the drmsign command def make_copy(self): path = macfs.FSSpec('Makefile').as_pathname() dirs=[ os.path.dirname(path) ] for dir in dirs: for file in os.listdir(dir): file = os.path.join(dir, file) if os.path.isdir(file): dirs.append(file) if file[-9:] == "--drmsign": component_path = file[:-9] import signclient try: drmsign_host = os.environ["DRMSIGN_HOST"] except KeyError: print "[ERROR] set DRMSIGN_HOST." continue try: component = open(component_path, "rb").read() except IOError: print "[ERROR]: cannot read file=\"%s\"" % (component_path) continue sc = signclient.SignClient(drmsign_host, "", "") result_status, result_component = sc.GetSignedComponent(component) ## check status if result_status != 0: print "[ERROR]: exit status=\"%s\"" % (str(result_status)) continue opath=os.path.join(self.settings.get("copy_path"), os.path.basename(component_path)) ## write signed component ## Make sure we do not zap resource fork! try: open(component_path, "wb").write(result_component) open(opath, "wb").write(result_component) except IOError: print "[ERROR]: cannot write file=\"%s\"" % (component_path) continue return 0, "" def make(self, arg = ''): old_dir = os.getcwd() status = 0 result = '' path = macfs.FSSpec('Makefile').as_pathname() ## ALL if arg == '': script = ascript.CreateAppleScript( 'set errtext to ""', 'set scriptobj to (load script file "%s")' % (path), 'tell scriptobj', ' with timeout of 99999 seconds', ' run', ' set errtext to the result', ' end timeout', 'end tell', 'return errtext') result = script.CompileAndExecute() else: self.error('unsupported MAKE argument') ## so that it doesn't equal None if result == None: result = '' ## process output from AppleScript result = string.translate(result, string.maketrans('\r', '\n')) result = string.strip(result) result = string.replace(result,"\n\n","\n") ## strip off the stupid quotes if len(result) >= 1: if result[0] == '"' and result[-1] == '"': result = string.strip(result[1:-1]) outmsg.verbose(result) ## Scan the output for error messages for line in string.split(result,"\n"): if not line: ## empty line continue words=string.split(line) if words[1] == "Warning": ## Warning continue ## Anything else is an error status = 1 self.error('failed make') os.chdir(old_dir) return status, resultclass UNIXNoStopOnErrorCompile(Compile): """Just like the UNIXCompile class, except GNU make is launched with the "-k" argument to ignore errors. This was put in so source code drops containing only objects, where the targets may not build, could be created and sent to companies. The idea was (hopefully) someone would check to see that all the source files which are deleted before the code leaves the company would at least produce object files, and the company receiving the source/object drop could then use those objects to do their build.""" def make(self, arg = ''): cmd = 'make -k %s' % (arg) return self.run_cmd(cmd)class WinNoStopOnErrorCompile(WinCompile): """Same as UNIXNoStopOnErrorCompile, for Windows.""" def make(self, arg = ''): cmd = 'nmake /nologo /i %s' % (arg) return self.run_cmd(cmd)def get_umake_backend(): """Return the proper umake backend, this must of course match up with the proper collate class below""" if os.name == "mac": if os.environ.get('BUILD_ON_PLATFORM','') == 'MacOSX': generator = "umake_cwxml_ascript" ## XML codewarrior else: generator = "umake_ascript" ## Applescript codewarrior elif 'win' in sysinfo.family_list: if 'win-vc7' in sysinfo.family_list: generator = "umake_win_vc7_makefile" else: generator = "umake_win_makefile" elif 'mac-pb' in sysinfo.family_list: generator = "umake_pb" ## project builder else: generator = "umake_makefile" #print "generator = %s" % repr(generator) return generator def get_collate_class(): """Returns the proper Compiler class for the platform. There's quite a bit of platform-specific crap in here.""" if sysinfo.id == 'vxworks': return UNIXCompile elif sysinfo.id == 'procnto-2.00-i386': return UNIXNoStopOnErrorCompile elif sysinfo.id == 'linux-2.2-libc6-kerbango-powerpc': return UNIXNoStopOnErrorCompile elif sysinfo.id == 'ics-2.0-i386': return WinNoStopOnErrorCompile elif 'win' in sysinfo.family_list: return WinCompile elif os.name == 'posix': return UNIXCompile elif os.name == 'nt' or os.name == 'dos': return WinCompile elif os.name == 'mac': if 'mac-pb' in sysinfo.family_list: return UNIXCompile return MacintoshCompile
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -