11 ('.', 'serf_bucket_types'),
12 ('.', 'serf_bucket_util'),
13 ('.', 'serf_declare'),
19 ('buckets', 'aggregate_buckets'),
20 ('buckets', 'request_buckets'),
21 ('buckets', 'buckets'),
22 ('buckets', 'simple_buckets'),
23 ('buckets', 'file_buckets'),
24 ('buckets', 'mmap_buckets'),
25 ('buckets', 'socket_buckets'),
26 ('buckets', 'response_buckets'),
27 ('buckets', 'headers_buckets'),
28 ('buckets', 'allocator'),
29 ('buckets', 'dechunk_buckets'),
30 ('buckets', 'deflate_buckets'),
31 ('buckets', 'limit_buckets'),
32 ('buckets', 'ssl_buckets'),
33 ('buckets', 'barrier_buckets'),
34 ('buckets', 'chunk_buckets'),
39 ('test', 'serf_response'),
40 ('test', 'serf_request'),
41 ('test', 'serf_spider'),
45 ('test/testcases', 'simple.response'),
46 ('test/testcases', 'chunked-empty.response'),
47 ('test/testcases', 'chunked.response'),
48 ('test/testcases', 'chunked-trailers.response'),
49 ('test/testcases', 'deflate.response'),
61 start = i.rfind('-', 0, idx)
63 params[i[start+1:idx]] = i[idx+1:].strip()
70 func = globals().get('cmd_' + cmd)
72 print 'ERROR: no such command:', cmd
84 print 'serfmake [cmd] [options]'
86 print '\tbuild\tBuilds (default)'
87 print '\tcheck\tRuns test cases'
88 print '\tinstall\tInstalls serf into PREFIX'
89 print '\tclean\tCleans'
91 print '\t--with-apr=PATH\tprefix for installed APR and APR-util'
92 print '\t\t\t(needs apr-1-config and apu-1-config; will look in PATH)'
93 print '\t--prefix=PATH\tinstall serf into PATH (default: /usr/local)'
95 print '\tserfmake --prefix=/usr/local/serf --with-apr=/usr/local/apr install'
100 builder = Builder(param)
101 builder.build_target(File('.', 'libserf-0', 'la'), False)
104 def cmd_install(param):
105 builder = Builder(param)
106 builder.install_target(File('.', 'libserf-0', 'la'), False)
109 def cmd_check(param):
110 builder = Builder(param)
111 builder.build_target(File('test', 'serf_response', None), False)
113 for dirpath, fname in TESTCASES:
114 case = os.path.join(dirpath, fname)
115 print '== Testing %s ==' % case
116 result = os.system('%s %s' % (os.path.join('test', 'serf_response'), case))
118 raise TestError(case, result)
121 def cmd_clean(param):
122 clean = [File(dirpath, fname, 'o') for dirpath, fname in LIB_FILES]
123 clean += [File(dirpath, fname, 'lo') for dirpath, fname in LIB_FILES]
124 clean += [File('.', 'libserf-0', 'la')]
125 clean += [File(dirpath, fname, 'o') for dirpath, fname in TEST_FILES]
126 clean += [File(dirpath, fname, 'lo') for dirpath, fname in TEST_FILES]
127 clean += [File(dirpath, fname, None) for dirpath, fname in TEST_FILES]
133 def __init__(self, params):
135 self.apr = APRConfig(params['apr'])
136 self.apu = APUConfig(params['apr'])
138 self.apr = APRConfig(None)
139 self.apu = APUConfig(None)
142 self.libdir = os.path.join(params['prefix'], 'lib')
143 self.includedir = os.path.join(params['prefix'], 'include', 'serf-0')
145 self.libdir = '/usr/local/lib'
146 self.includedir = '/usr/local/include/serf-0'
152 self.CC = self.apr.get_value('CC', '--cc')
153 self.CFLAGS = self.apr.get_value('CFLAGS', '--cflags')
154 self.CPPFLAGS = self.apr.get_value('CPPFLAGS', '--cppflags')
155 self.LIBTOOL = self.apr.get_value('LIBTOOL', '--apr-libtool')
156 self.LDFLAGS = self.apr.get_value('LDFLAGS', '--ldflags') \
157 + ' ' + self.apu.get_value('LDFLAGS', '--ldflags')
159 self.INCLUDES = '-I%s -I%s -I%s' % (
161 self.apr.get_value(None, '--includedir'),
162 self.apu.get_value(None, '--includedir'),
164 if os.getenv('EXTRA_INCLUDES'):
165 self.INCLUDES += ' -I' + os.getenv('EXTRA_INCLUDES')
167 self.LIBS = self.apu.get_value(None, '--link-libtool') \
168 + ' ' + self.apu.get_value(None, '--libs') \
169 + ' ' + self.apr.get_value(None, '--link-libtool') \
170 + ' ' + self.apr.get_value(None, '--libs') \
171 + ' -lz -lssl -lcrypto'
178 hdrs = [File(dirpath, fname, 'h') for dirpath, fname in FILES_HDR]
179 libfiles = [File(dirpath, fname, 'c') for dirpath, fname in LIB_FILES]
180 libobjs = [File(dirpath, fname, 'lo') for dirpath, fname in LIB_FILES]
181 for src, obj in zip(libfiles, libobjs):
182 self._add_compile(src, obj, hdrs)
186 lib = File('.', 'libserf-0', 'la')
187 cmd = '%s --silent --mode=link %s %s -rpath %s -o %s %s %s' % (
188 self.LIBTOOL, self.CC, self.LDFLAGS, self.libdir,
189 lib.fname, ' '.join([l.fname for l in libobjs]), self.LIBS)
190 self._add_dep(lib, libobjs, cmd)
192 # load the test program dependencies now
193 for dirpath, fname in TEST_FILES:
194 src = File(dirpath, fname, 'c')
195 obj = File(dirpath, fname, 'lo')
196 prog = File(dirpath, fname, None)
198 self._add_compile(src, obj, hdrs)
200 cmd = '%s --silent --mode=link %s %s -static -o %s %s %s %s' % (
201 self.LIBTOOL, self.CC, self.LDFLAGS,
202 prog.fname, lib.fname, obj.fname, self.LIBS)
203 self._add_dep(prog, [lib, obj], cmd)
205 def _add_compile(self, src, obj, hdrs):
206 cmd = '%s --silent --mode=compile %s %s %s %s -c -o %s %s' % (
207 self.LIBTOOL, self.CC, self.CFLAGS, self.CPPFLAGS, self.INCLUDES,
208 obj.fname, src.fname)
209 self._add_dep(obj, [src] + hdrs, cmd)
211 def _add_dep(self, target, deps, cmd):
214 if self.deps.has_key(dep) \
215 or (dep.mtime and dep.mtime > target.mtime):
216 # a dep is newer. this needs to be rebuilt.
219 # this is up to date. don't add it to the deps[] structure.
221 # else non-existent, so it must be rebuilt.
223 # register the dependency so this will get built
224 self.deps[target] = deps, cmd
226 def build_target(self, target, dry_run):
227 dep = self.deps.get(target)
229 # it's already up to date. all done.
233 subdep = self.deps.get(f)
235 self.build_target(f, dry_run)
237 # build the target now
240 result = os.system(dep[1])
242 raise BuildError(dep[1], result)
245 # it's a dry run. pretend we built the target.
246 del self.deps[target]
249 def install_target(self, target, dry_run):
250 self.build_target(target, dry_run)
252 # install the target now
256 os.makedirs(self.includedir)
257 os.makedirs(self.libdir)
262 shutil.copy(f.fname, self.includedir)
264 cmd = '%s --silent --mode=install %s -c -m %d %s %s' % (
265 self.LIBTOOL, '/usr/bin/install', self.MODE, target.fname,
268 result = os.system(cmd)
270 raise BuildError(cmd, result)
276 class ConfigScript(object):
281 '/usr/local/apache2/bin',
284 def __init__(self, search_dir):
286 self.locations.append(search_dir)
287 self.locations.append(os.path.join(search_dir, 'bin'))
288 for dirname in self.locations:
289 bin = os.path.join(dirname, self.script_name)
290 if os.access(bin, os.X_OK):
294 raise ConfigScriptNotFound(self.script_name)
296 def get_value(self, env_name, switch):
297 if env_name and os.getenv(env_name):
298 return os.getenv(env_name)
299 return os.popen('%s %s' % (self.bin, switch), 'r').read().strip()
302 class APRConfig(ConfigScript):
303 script_name = 'apr-1-config'
306 class APUConfig(ConfigScript):
307 script_name = 'apu-1-config'
311 def __init__(self, dirpath, fname, ext):
313 self.fname = os.path.join(dirpath, fname + '.' + ext)
315 self.fname = os.path.join(dirpath, fname)
318 s = os.stat(self.fname)
322 self.mtime = s[stat.ST_MTIME]
324 def __cmp__(self, other):
325 return cmp(self.fname, other.fname)
328 return hash(self.fname)
331 class BuildError(Exception):
332 "An error occurred while building a target."
333 class TestError(Exception):
334 "An error occurred while running a unit test."
335 class ConfigScriptNotFound(Exception):
336 def __init__(self, value):
337 self.value = "ERROR: A configuration script was not found: " + value
342 if __name__ == '__main__':