Skip to content
This repository was archived by the owner on Jun 15, 2023. It is now read-only.

Commit 1992ab6

Browse files
committed
enhance write_fake_manifest.py
Add an option to write_fake_manifest.py to generate sources expected by the manifest. Also slightly adapt command lines to the called commands. Together these changes mean that generated manifest can actually be executed successfully on Linux and OSX. Also add command line options to to change the number of targets being generated and the seed for the random number generator. Example usage: # create build directory in fake/build, sources in fake/src $ python misc/write_fake_manifest.py -s ../src fake/build # execute build in fake/build $ ninja -C fake/build
1 parent 5739c14 commit 1992ab6

File tree

1 file changed

+71
-18
lines changed

1 file changed

+71
-18
lines changed

misc/write_fake_manifests.py

+71-18
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,10 @@ def moar(avg_options, p_suffix):
5050

5151

5252
class GenRandom(object):
53-
def __init__(self):
53+
def __init__(self, src_dir):
5454
self.seen_names = set([None])
5555
self.seen_defines = set([None])
56+
self.src_dir = src_dir
5657

5758
def _unique_string(self, seen, avg_options=1.3, p_suffix=0.1):
5859
s = None
@@ -76,7 +77,7 @@ def path(self):
7677

7778
def src_obj_pairs(self, path, name):
7879
num_sources = paretoint(55, alpha=2) + 1
79-
return [(os.path.join('..', '..', path, s + '.cc'),
80+
return [(os.path.join(self.src_dir, path, s + '.cc'),
8081
os.path.join('obj', path, '%s.%s.o' % (name, s)))
8182
for s in self._n_unique_strings(num_sources)]
8283

@@ -103,12 +104,8 @@ def __init__(self, gen, kind):
103104
self.kind = kind
104105
self.has_compile_depends = random.random() < 0.4
105106

106-
@property
107-
def includes(self):
108-
return ['-I' + dep.dir_path for dep in self.deps]
109107

110-
111-
def write_target_ninja(ninja, target):
108+
def write_target_ninja(ninja, target, src_dir):
112109
compile_depends = None
113110
if target.has_compile_depends:
114111
compile_depends = os.path.join(
@@ -117,8 +114,7 @@ def write_target_ninja(ninja, target):
117114
ninja.newline()
118115

119116
ninja.variable('defines', target.defines)
120-
if target.deps:
121-
ninja.variable('includes', target.includes)
117+
ninja.variable('includes', '-I' + src_dir)
122118
ninja.variable('cflags', ['-Wall', '-fno-rtti', '-fno-exceptions'])
123119
ninja.newline()
124120

@@ -129,17 +125,63 @@ def write_target_ninja(ninja, target):
129125
deps = [dep.output for dep in target.deps]
130126
libs = [dep.output for dep in target.deps if dep.kind == LIB]
131127
if target.kind == EXE:
132-
ninja.variable('ldflags', '-Wl,pie')
133128
ninja.variable('libs', libs)
129+
if sys.platform == "darwin":
130+
ninja.variable('ldflags', '-Wl,-pie')
134131
link = { LIB: 'alink', EXE: 'link'}[target.kind]
135132
ninja.build(target.output, link, [obj for _, obj in target.src_obj_pairs],
136133
implicit=deps)
137134

138135

136+
def write_sources(target, root_dir):
137+
need_main = target.kind == EXE
138+
139+
includes = []
140+
141+
# Include siblings.
142+
for cc_filename, _ in target.src_obj_pairs:
143+
h_filename = os.path.basename(os.path.splitext(cc_filename)[0] + '.h')
144+
includes.append(h_filename)
145+
146+
# Include deps.
147+
for dep in target.deps:
148+
for cc_filename, _ in dep.src_obj_pairs:
149+
h_filename = os.path.basename(
150+
os.path.splitext(cc_filename)[0] + '.h')
151+
includes.append("%s/%s" % (dep.dir_path, h_filename))
152+
153+
for cc_filename, _ in target.src_obj_pairs:
154+
cc_path = os.path.join(root_dir, cc_filename)
155+
h_path = os.path.splitext(cc_path)[0] + '.h'
156+
namespace = os.path.basename(target.dir_path)
157+
class_ = os.path.splitext(os.path.basename(cc_filename))[0]
158+
try:
159+
os.makedirs(os.path.dirname(cc_path))
160+
except OSError:
161+
pass
162+
163+
with open(h_path, 'w') as f:
164+
f.write('namespace %s { struct %s { %s(); }; }' % (namespace,
165+
class_, class_))
166+
with open(cc_path, 'w') as f:
167+
for include in includes:
168+
f.write('#include "%s"\n' % include)
169+
f.write('\n')
170+
f.write('namespace %s { %s::%s() {} }' % (namespace,
171+
class_, class_))
172+
173+
if need_main:
174+
f.write('int main(int argc, char **argv) {}\n')
175+
need_main = False
176+
139177
def write_master_ninja(master_ninja, targets):
140178
"""Writes master build.ninja file, referencing all given subninjas."""
141179
master_ninja.variable('cxx', 'c++')
142180
master_ninja.variable('ld', '$cxx')
181+
if sys.platform == 'darwin':
182+
master_ninja.variable('alink', 'libtool -static')
183+
else:
184+
master_ninja.variable('alink', 'ar rcs')
143185
master_ninja.newline()
144186

145187
master_ninja.pool('link_pool', depth=4)
@@ -148,8 +190,8 @@ def write_master_ninja(master_ninja, targets):
148190
master_ninja.rule('cxx', description='CXX $out',
149191
command='$cxx -MMD -MF $out.d $defines $includes $cflags -c $in -o $out',
150192
depfile='$out.d', deps='gcc')
151-
master_ninja.rule('alink', description='LIBTOOL-STATIC $out',
152-
command='rm -f $out && libtool -static -o $out $in')
193+
master_ninja.rule('alink', description='ARCHIVE $out',
194+
command='rm -f $out && $alink -o $out $in')
153195
master_ninja.rule('link', description='LINK $out', pool='link_pool',
154196
command='$ld $ldflags -o $out $in $libs')
155197
master_ninja.rule('stamp', description='STAMP $out', command='touch $out')
@@ -181,9 +223,8 @@ def FileWriter(path):
181223
f.close()
182224

183225

184-
def random_targets():
185-
num_targets = 1500
186-
gen = GenRandom()
226+
def random_targets(num_targets, src_dir):
227+
gen = GenRandom(src_dir)
187228

188229
# N-1 static libraries, and 1 executable depending on all of them.
189230
targets = [Target(gen, LIB) for i in xrange(num_targets - 1)]
@@ -199,16 +240,28 @@ def random_targets():
199240

200241
def main():
201242
parser = argparse.ArgumentParser()
243+
parser.add_argument('-s', '--sources', nargs="?", const="src",
244+
help='write sources to directory (relative to output directory)')
245+
parser.add_argument('-t', '--targets', type=int, default=1500)
246+
help='number of targets (default: 1500)',
247+
parser.add_argument('-S', '--seed', type=int, help='random seed',
248+
default=12345)
202249
parser.add_argument('outdir', help='output directory')
203250
args = parser.parse_args()
204251
root_dir = args.outdir
205252

206-
random.seed(12345)
253+
random.seed(args.seed)
207254

208-
targets = random_targets()
255+
do_write_sources = args.sources is not None
256+
src_dir = args.sources if do_write_sources else "src"
257+
258+
targets = random_targets(args.targets, src_dir)
209259
for target in targets:
210260
with FileWriter(os.path.join(root_dir, target.ninja_file_path)) as n:
211-
write_target_ninja(n, target)
261+
write_target_ninja(n, target, src_dir)
262+
263+
if do_write_sources:
264+
write_sources(target, root_dir)
212265

213266
with FileWriter(os.path.join(root_dir, 'build.ninja')) as master_ninja:
214267
master_ninja.width = 120

0 commit comments

Comments
 (0)