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

Annotation of /trunk/scons/nsis.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1618 - (hide annotations) (download) (as text)
Wed Sep 5 00:36:01 2007 UTC (16 years ago) by jpye
File MIME type: text/x-python
File size: 5947 byte(s)
Removed deprecated 'import SCons.Sig' from nsis.py
1 jpye 1408 # 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 johnpye 913 return 0

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