-
Notifications
You must be signed in to change notification settings - Fork 9
/
bootstrap.py
executable file
·122 lines (91 loc) · 3.16 KB
/
bootstrap.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#!/usr/bin/python
import ninja_syntax
import itertools
import os
import fnmatch
import re
import sys
import argparse
# --- util functions
def flags(*iterables):
return ' '.join(itertools.chain(*iterables))
def include(d):
return '-I' + d;
def dependency_include(d):
return '-isystem' + os.path.join('deps', d, 'include');
def get_files(root, pattern):
pattern = fnmatch.translate(pattern)
for dir, dirs, files in os.walk(root):
for f in files:
if re.match(pattern, f):
yield os.path.join(dir, f)
def object_file(fn):
return os.path.join('obj', re.sub(r'\.c\+\+', '.o', fn))
# --- variables
dependencies = ['catch']
include_flags = flags([include('include')], map(dependency_include, dependencies))
cxx_flags = flags(['-Wall', '-Wextra', '-Wfatal-errors', '-Werror', '-std=c++11', '-O3'])
ld_flags = flags(['-flto'])
parser = argparse.ArgumentParser()
parser.add_argument('--cxx', default='g++', metavar='executable', help='compiler name to use (default: g++)')
parser.add_argument('--teamcity', action='store_true', default=False, help='prepares a build to run on TeamCity (default: no)')
args = parser.parse_args()
# ---
ninja = ninja_syntax.Writer(open('build.ninja', 'w'))
ninja.variable('ninja_required_version', '1.3')
ninja.variable('builddir', 'obj')
# --- rules
ninja.rule('bootstrap',
command = ' '.join(sys.argv),
generator = True,
description = 'BOOTSTRAP')
ninja.rule('cxx',
command = args.cxx + ' -MMD -MF $out.d -c ' + cxx_flags + ' ' + include_flags + ' $in -o $out',
deps = 'gcc',
depfile = '$out.d',
description = 'C++ $in')
ninja.rule('link',
command = args.cxx + ' ' + cxx_flags + ' ' + ld_flags + ' $in -o $out',
description = 'LINK $in')
ninja.rule('lib',
command = 'ar rc $out $in && ranlib $out',
description = 'AR $in')
test_runner = 'bin/test'
ninja.rule('test',
command = test_runner + (' -r teamcity' if args.teamcity else ''),
description = 'TEST')
ninja.rule('dist',
command = 'tar cjf $out $in',
description = 'TAR $in')
# --- build edges
ninja.build('build.ninja', 'bootstrap',
implicit = sys.argv[0])
hdr_files = list(get_files('include', '*.h++'))
src_files = list(get_files('src', '*.c++'))
obj_files = [object_file(fn) for fn in src_files]
for fn in src_files:
ninja.build(object_file(fn), 'cxx',
inputs = fn)
libwheels = 'bin/libwheels.a'
ninja.build(libwheels, 'lib',
inputs = obj_files)
test_src_files = list(get_files('test', '*.c++'))
test_obj_files = [object_file(fn) for fn in test_src_files]
for fn in test_src_files:
ninja.build(object_file(fn), 'cxx',
inputs = fn)
ninja.build(test_runner, 'link',
inputs = test_obj_files + [libwheels])
ninja.build('runtests', 'test',
implicit = test_runner)
ninja.build('test', 'phony',
inputs = 'runtests')
ninja.build('lib', 'phony',
inputs = libwheels)
tar = 'dist/wheels.tar.bz2'
ninja.build(tar, 'dist',
inputs = hdr_files + ([libwheels] if src_files else []))
ninja.build('dist', 'phony',
inputs = tar)
# --- default targets
ninja.default('lib')