waf

FORK: waf with some random patches
git clone https://git.neptards.moe/neptards/waf.git
Log | Files | Refs | README

winres.py (3205B)


      1 #!/usr/bin/env python
      2 # encoding: utf-8
      3 # Brant Young, 2007
      4 
      5 "Process *.rc* files for C/C++: X{.rc -> [.res|.rc.o]}"
      6 
      7 import os
      8 import re
      9 from waflib import Task
     10 from waflib.TaskGen import extension
     11 from waflib.Tools import c_preproc
     12 from waflib import Utils
     13 
     14 @extension('.rc')
     15 def rc_file(self, node):
     16 	"""
     17 	Binds the .rc extension to a winrc task
     18 	"""
     19 	obj_ext = '.rc.o'
     20 	if self.env.WINRC_TGT_F == '/fo':
     21 		obj_ext = '.res'
     22 	rctask = self.create_task('winrc', node, node.change_ext(obj_ext))
     23 	try:
     24 		self.compiled_tasks.append(rctask)
     25 	except AttributeError:
     26 		self.compiled_tasks = [rctask]
     27 
     28 re_lines = re.compile(
     29 	r'(?:^[ \t]*(#|%:)[ \t]*(ifdef|ifndef|if|else|elif|endif|include|import|define|undef|pragma)[ \t]*(.*?)\s*$)|'\
     30 	r'(?:^\w+[ \t]*(ICON|BITMAP|CURSOR|HTML|FONT|MESSAGETABLE|TYPELIB|REGISTRY|D3DFX)[ \t]*(.*?)\s*$)',
     31 	re.IGNORECASE | re.MULTILINE)
     32 
     33 class rc_parser(c_preproc.c_parser):
     34 	"""
     35 	Calculates dependencies in .rc files
     36 	"""
     37 	def filter_comments(self, node):
     38 		"""
     39 		Overrides :py:meth:`waflib.Tools.c_preproc.c_parser.filter_comments`
     40 		"""
     41 		code = node.read()
     42 		if c_preproc.use_trigraphs:
     43 			for (a, b) in c_preproc.trig_def:
     44 				code = code.split(a).join(b)
     45 		code = c_preproc.re_nl.sub('', code)
     46 		code = c_preproc.re_cpp.sub(c_preproc.repl, code)
     47 		ret = []
     48 		for m in re.finditer(re_lines, code):
     49 			if m.group(2):
     50 				ret.append((m.group(2), m.group(3)))
     51 			else:
     52 				ret.append(('include', m.group(5)))
     53 		return ret
     54 
     55 class winrc(Task.Task):
     56 	"""
     57 	Compiles resource files
     58 	"""
     59 	run_str = '${WINRC} ${WINRCFLAGS} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${WINRC_TGT_F} ${TGT} ${WINRC_SRC_F} ${SRC}'
     60 	color   = 'BLUE'
     61 	def scan(self):
     62 		tmp = rc_parser(self.generator.includes_nodes)
     63 		tmp.start(self.inputs[0], self.env)
     64 		return (tmp.nodes, tmp.names)
     65 
     66 	def exec_command(self, cmd, **kw):
     67 		if self.env.WINRC_TGT_F == '/fo':
     68 			# Since winres include paths may contain spaces, they do not fit in
     69 			# response files and are best passed as environment variables
     70 			replace_cmd = []
     71 			incpaths = []
     72 			while cmd:
     73 				# filter include path flags
     74 				flag = cmd.pop(0)
     75 				if flag.upper().startswith('/I'):
     76 					if len(flag) == 2:
     77 						incpaths.append(cmd.pop(0))
     78 					else:
     79 						incpaths.append(flag[2:])
     80 				else:
     81 					replace_cmd.append(flag)
     82 			cmd = replace_cmd
     83 			if incpaths:
     84 				# append to existing environment variables in INCLUDE
     85 				env = kw['env'] = dict(kw.get('env') or self.env.env or os.environ)
     86 				pre_includes = env.get('INCLUDE', '')
     87 				env['INCLUDE'] = pre_includes + os.pathsep + os.pathsep.join(incpaths)
     88 
     89 		return super(winrc, self).exec_command(cmd, **kw)
     90 
     91 	def quote_flag(self, flag):
     92 		if self.env.WINRC_TGT_F == '/fo':
     93 			# winres does not support quotes around flags in response files
     94 			return flag
     95 
     96 		return super(winrc, self).quote_flag(flag)
     97 
     98 
     99 def configure(conf):
    100 	"""
    101 	Detects the programs RC or windres, depending on the C/C++ compiler in use
    102 	"""
    103 	v = conf.env
    104 	if not v.WINRC:
    105 		if v.CC_NAME == 'msvc':
    106 			conf.find_program('RC', var='WINRC', path_list=v.PATH)
    107 			v.WINRC_TGT_F = '/fo'
    108 			v.WINRC_SRC_F = ''
    109 		else:
    110 			conf.find_program('windres', var='WINRC', path_list=v.PATH)
    111 			v.WINRC_TGT_F = '-o'
    112 			v.WINRC_SRC_F = '-i'
    113