|
1 #! /usr/bin/env python |
|
2 # Copyright (C) 2005, Giovanni Bajo |
|
3 # Based on previous work under copyright (c) 2002 McMillan Enterprises, Inc. |
|
4 # |
|
5 # This program is free software; you can redistribute it and/or |
|
6 # modify it under the terms of the GNU General Public License |
|
7 # as published by the Free Software Foundation; either version 2 |
|
8 # of the License, or (at your option) any later version. |
|
9 # |
|
10 # This program is distributed in the hope that it will be useful, |
|
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
13 # GNU General Public License for more details. |
|
14 # |
|
15 # You should have received a copy of the GNU General Public License |
|
16 # along with this program; if not, write to the Free Software |
|
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
|
18 |
|
19 """ Make.py |
|
20 |
|
21 -h help |
|
22 -n use separate archive / executable (nonELF) |
|
23 -e use concatenated executable / archive (ELF) |
|
24 -p prefix |
|
25 -P execprefix |
|
26 """ |
|
27 import sys |
|
28 import os |
|
29 import getopt |
|
30 import string |
|
31 import marshal |
|
32 import bkfile |
|
33 import makemakefile |
|
34 import pprint |
|
35 |
|
36 try: |
|
37 from distutils import sysconfig |
|
38 except: |
|
39 print "ERROR: distutils with sysconfig required" |
|
40 sys.exit(1) |
|
41 |
|
42 |
|
43 |
|
44 def main(): |
|
45 dirnm = os.path.dirname(sys.argv[0]) |
|
46 if dirnm not in ('', '.'): |
|
47 os.chdir(dirnm) |
|
48 # overridable context |
|
49 prefix = None # settable with -p option |
|
50 exec_prefix = None # settable with -P option |
|
51 non_elf = 1 # settable with -e option |
|
52 if ( sys.platform[:5] == 'linux' or |
|
53 sys.platform[:3] == 'win' or |
|
54 sys.platform[:7] in ['freebsd','darwin'] or |
|
55 sys.platform[:6] == 'cygwin' ): |
|
56 non_elf = 0 # settable with -n option |
|
57 |
|
58 try: |
|
59 opts, args = getopt.getopt(sys.argv[1:], 'hneo:p:P:') |
|
60 except getopt.error, msg: |
|
61 usage('getopt error: ' + str(msg)) |
|
62 |
|
63 # proces option arguments |
|
64 for o, a in opts: |
|
65 if o == '-h': |
|
66 print __doc__ |
|
67 return |
|
68 if o == '-p': |
|
69 prefix = a |
|
70 if o == '-P': |
|
71 exec_prefix = a |
|
72 if o == '-n': |
|
73 non_elf = 1 |
|
74 if o == '-e': |
|
75 non_elf = 0 |
|
76 # default prefix and exec_prefix |
|
77 if not exec_prefix: |
|
78 if prefix: |
|
79 exec_prefix = prefix |
|
80 else: |
|
81 exec_prefix = sysconfig.EXEC_PREFIX |
|
82 if not prefix: |
|
83 prefix = sysconfig.PREFIX |
|
84 |
|
85 # determine whether -p points to the Python source tree |
|
86 ishome = os.path.exists(os.path.join(prefix, 'Python', 'ceval.c')) |
|
87 |
|
88 cygwin = sys.platform == 'cygwin' |
|
89 darwin = sys.platform[:7] == 'darwin' |
|
90 |
|
91 if ishome: |
|
92 print "(Using Python source directory)" |
|
93 binlib = exec_prefix |
|
94 incldir = os.path.join(prefix, 'Include') |
|
95 config_h_dir = exec_prefix |
|
96 makefile_in = os.path.join(exec_prefix, 'Modules', 'Makefile') |
|
97 else: |
|
98 # binlib = os.path.join (sysconfig.get_python_lib(True, True, exec_prefix), 'config') |
|
99 binlib = sysconfig.get_config_vars('LIBDIR')[0] |
|
100 # TODO: Is it possible to have more than one path returned? if so fix "includes" list |
|
101 incldir_list = sysconfig.get_config_vars('INCLUDEDIR') |
|
102 includes = [] |
|
103 for dir in incldir_list: |
|
104 if dir != None: |
|
105 includes.append('-I' + dir) |
|
106 config_h_dir = os.path.join (sysconfig.get_python_inc(True,exec_prefix)) |
|
107 includes.append('-I' + config_h_dir) |
|
108 makefile_in = sysconfig.get_makefile_filename() |
|
109 |
|
110 # salt config.dat with the exe type |
|
111 try: |
|
112 config = eval(open('../../config.dat', 'r').read()) |
|
113 except IOError: |
|
114 config = {} |
|
115 config['useELFEXE'] = not non_elf |
|
116 configf = open('../../config.dat', 'w') |
|
117 pprint.pprint(config, configf) |
|
118 configf.close() |
|
119 |
|
120 targets = [None, None] |
|
121 targets[0] = os.path.join('../../support/loader/', 'run') |
|
122 targets[1] = os.path.join('../../support/loader/', 'run_d') |
|
123 |
|
124 # include local 'common' dir |
|
125 includes.append('-I../common') |
|
126 |
|
127 have_warnings = 0 |
|
128 import exceptions |
|
129 if not hasattr(exceptions, '__file__'): |
|
130 freeze_exceptions = 0 |
|
131 files = ['main.c', '../common/launch.c'] |
|
132 if hasattr(exceptions, 'Warning'): |
|
133 have_warnings = 1 |
|
134 else: |
|
135 freeze_exceptions = 1 |
|
136 import exceptions |
|
137 print "reading exceptions from", exceptions.__file__ |
|
138 inf = open(exceptions.__file__, 'rb') |
|
139 inf.seek(8) |
|
140 code = inf.read() |
|
141 codelen = len(code) |
|
142 outfp = bkfile.open('M_exceptions.c', 'w') |
|
143 files = ['M_exceptions.c', 'main.c', '../common/launch.c'] |
|
144 outfp.write('unsigned char M_exceptions[] = {') |
|
145 for i in range(0, len(code), 16): |
|
146 outfp.write('\n\t') |
|
147 for c in code[i:i+16]: |
|
148 outfp.write('%d,' % ord(c)) |
|
149 outfp.write('\n};\n') |
|
150 outfp.close() |
|
151 |
|
152 includes.append('$(OPT)') |
|
153 cflags = includes |
|
154 cflags.append(sysconfig.get_config_vars('CFLAGS')[0]) #save sysconfig CFLAGS |
|
155 |
|
156 if have_warnings: |
|
157 cflags.append('-DHAVE_WARNINGS') |
|
158 if freeze_exceptions: |
|
159 cflags.append('-DFREEZE_EXCEPTIONS') |
|
160 cflags.append('-DEXCEPTIONS_LEN=%d' % codelen) |
|
161 if non_elf: |
|
162 cflags.append('-DNONELF') |
|
163 |
|
164 libs = [os.path.join(sysconfig.get_config_vars('LIBPL')[0], sysconfig.get_config_vars('LIBRARY')[0])] |
|
165 if not os.path.isfile(libs[0]): |
|
166 print "WARNING: could not find Python static library at:", libs[0] |
|
167 |
|
168 somevars = {} |
|
169 if os.path.exists(makefile_in): |
|
170 makevars = sysconfig.parse_makefile(makefile_in) |
|
171 else: |
|
172 raise ValueError, "Makefile '%s' not found" % makefile_in |
|
173 for key in makevars.keys(): |
|
174 somevars[key] = makevars[key] |
|
175 |
|
176 somevars['CFLAGS'] = string.join(cflags) # override |
|
177 files = ['$(OPT)', '$(LDFLAGS)', '$(LINKFORSHARED)', 'getpath.c'] + \ |
|
178 files + libs + \ |
|
179 ['$(MODLIBS)', '$(LIBS)', '$(SYSLIBS)', '-lz'] # XXX zlib not always -lz |
|
180 |
|
181 outfp = bkfile.open('Makefile', 'w') |
|
182 try: |
|
183 makemakefile.writevars(outfp, somevars, string.join(targets)) |
|
184 makemakefile.writerules(outfp, files[:], '', '', targets[0]) |
|
185 makemakefile.writerules(outfp, files[:], '_d', '-D_DEBUG -DLAUNCH_DEBUG', targets[1]) |
|
186 finally: |
|
187 outfp.close() |
|
188 |
|
189 # Done! |
|
190 |
|
191 print 'Now run "make" to build the targets:', string.join(targets) |
|
192 |
|
193 |
|
194 def usage(msg): |
|
195 sys.stdout = sys.stderr |
|
196 print "Error:", msg |
|
197 print "Use ``%s -h'' for help" % sys.argv[0] |
|
198 sys.exit(2) |
|
199 |
|
200 |
|
201 main() |