/[ascend]/trunk/scons/nsis.py
ViewVC logotype

Contents of /trunk/scons/nsis.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1618 - (show annotations) (download) (as text)
Wed Sep 5 00:36:01 2007 UTC (12 years, 5 months ago) by jpye
File MIME type: text/x-python
File size: 5947 byte(s)
Removed deprecated 'import SCons.Sig' from nsis.py
1 # NSIS Support for SCons
2 # Written by Mike Elkins, January 2004
3 # Provided 'as-is', it works for me!
4
5
6 """
7 This tool provides SCons support for the Nullsoft Scriptable Install System
8 a windows installer builder available at http://nsis.sourceforge.net/home
9
10
11 To use it you must copy this file into the scons/SCons/Tools directory or use
12 the tooldir arg in the Tool function and put a line like 'env.Tool("NSIS")'
13 into your file. Then you can do 'env.Installer("foobar")' which will read foobar.nsi and
14 create dependencies on all the files you put into your installer, so that if
15 anything changes your installer will be rebuilt. It also makes the target
16 equal to the filename you specified in foobar.nsi. Wildcards are handled correctly.
17
18 In addition, if you set NSISDEFINES to a dictionary, those variables will be passed
19 to NSIS.
20 """
21
22
23
24 import SCons.Builder
25 import SCons.Util
26 import SCons.Scanner
27 import os.path
28 import glob
29
30
31 def nsis_parse( sources, keyword, multiple ):
32 """
33 A function that knows how to read a .nsi file and figure
34 out what files are referenced, or find the 'OutFile' line.
35
36
37 sources is a list of nsi files.
38 keyword is the command ('File' or 'OutFile') to look for
39 multiple is true if you want all the args as a list, false if you
40 just want the first one.
41 """
42 stuff = []
43 for s in sources:
44 c = s.get_contents()
45 for l in c.split('\n'):
46 semi = l.find(';')
47 if (semi != -1):
48 l = l[:semi]
49 hash = l.find('#')
50 if (hash != -1):
51 l = l[:hash]
52 # Look for the keyword
53 l = l.strip()
54 spl = l.split(None,1)
55 if len(spl) > 1:
56 if spl[0].capitalize() == keyword.capitalize():
57 arg = spl[1]
58 if arg.startswith('"') and arg.endswith('"'):
59 arg = arg[1:-1]
60 if multiple:
61 stuff += [ arg ]
62 else:
63 return arg
64 return stuff
65
66
67 def nsis_path( filename, nsisdefines, rootdir ):
68 """
69 Do environment replacement, and prepend with the SCons root dir if
70 necessary
71 """
72 # We can't do variables defined by NSIS itself (like $INSTDIR),
73 # only user supplied ones (like ${FOO})
74 varPos = filename.find('${')
75 while varPos != -1:
76 endpos = filename.find('}',varPos)
77 assert endpos != -1
78 if not nsisdefines.has_key(filename[varPos+2:endpos]):
79 raise KeyError ("Could not find %s in NSISDEFINES" % filename[varPos+2:endpos])
80 val = nsisdefines[filename[varPos+2:endpos]]
81 if type(val) == list:
82 if varPos != 0 or endpos+1 != len(filename):
83 raise Exception("Can't use lists on variables that aren't complete filenames")
84 return val
85 filename = filename[0:varPos] + val + filename[endpos+1:]
86 varPos = filename.find('${')
87 return filename
88
89
90 def nsis_scanner( node, env, path ):
91 """
92 The scanner that looks through the source .nsi files and finds all lines
93 that are the 'File' command, fixes the directories etc, and returns them.
94 """
95 nodes = node.rfile()
96 if not node.exists():
97 return []
98 nodes = []
99 source_dir = node.get_dir()
100 for include in nsis_parse([node],'file',1):
101 exp = nsis_path(include,env['NSISDEFINES'],source_dir)
102 if type(exp) != list:
103 exp = [exp]
104 for p in exp:
105 for filename in glob.glob( os.path.abspath(
106 os.path.join(str(source_dir),p))):
107 # Why absolute path? Cause it breaks mysteriously without it :(
108 nodes.append(filename)
109 return nodes
110
111
112 def nsis_emitter( source, target, env ):
113 """
114 The emitter changes the target name to match what the command actually will
115 output, which is the argument to the OutFile command.
116 """
117 nsp = nsis_parse(source,'outfile',0)
118 if not nsp:
119 return (target,source)
120 x = (
121 nsis_path(nsp,env['NSISDEFINES'],''),
122 source)
123 return x
124
125 def quoteIfSpaced(text):
126 if ' ' in text:
127 return '"'+text+'"'
128 else:
129 return text
130
131 def toString(item,env):
132 if type(item) == list:
133 ret = ''
134 for i in item:
135 if ret:
136 ret += ' '
137 val = toString(i,env)
138 if ' ' in val:
139 val = "'"+val+"'"
140 ret += val
141 return ret
142 else:
143 # For convienence, handle #s here
144 if str(item).startswith('#'):
145 item = env.File(item).get_abspath()
146 return str(item)
147
148 def runNSIS(source,target,env,for_signature):
149 ret = env['NSIS']+" "
150 if env.has_key('NSISFLAGS'):
151 for flag in env['NSISFLAGS']:
152 ret += flag
153 ret += ' '
154 if env.has_key('NSISDEFINES'):
155 for d in env['NSISDEFINES']:
156 ret += '/D'+d
157 if env['NSISDEFINES'][d]:
158 ret +='='+quoteIfSpaced(toString(env['NSISDEFINES'][d],env))
159 ret += ' '
160 for s in source:
161 ret += quoteIfSpaced(str(s))
162 return ret
163
164 def generate(env):
165 """
166 This function adds NSIS support to your environment.
167 """
168 env['BUILDERS']['Installer'] = SCons.Builder.Builder(generator=runNSIS,
169 src_suffix='.nsi',
170 emitter=nsis_emitter)
171 env.Append(SCANNERS = SCons.Scanner.Scanner( function = nsis_scanner,
172 skeys = ['.nsi']))
173 if not env.has_key('NSISDEFINES'):
174 env['NSISDEFINES'] = {}
175 env['NSIS'] = find_nsis(env)
176
177 def find_nsis(env):
178 """
179 Try and figure out if NSIS is installed on this machine, and if so,
180 where.
181 """
182 if SCons.Util.can_read_reg:
183 # If we can read the registry, get the NSIS command from it
184 try:
185 k = SCons.Util.RegOpenKeyEx(SCons.Util.hkey_mod.HKEY_LOCAL_MACHINE,
186 'SOFTWARE\\NSIS')
187 val, tok = SCons.Util.RegQueryValueEx(k,None)
188 ret = val + os.path.sep + 'makensis.exe'
189 if os.path.exists(ret):
190 return '"' + ret + '"'
191 else:
192 return None
193 except:
194 pass # Couldn't find the key, just act like we can't read the registry
195 # Hope it's on the path
196 return env.WhereIs('makensis.exe')
197
198 def exists(env):
199 """
200 Is NSIS findable on this machine?
201 """
202 if find_nsis(env) != None:
203 return 1
204 return 0

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22