diff options
-rwxr-xr-x | configure | 7 | ||||
-rw-r--r-- | mconfig.py | 73 |
2 files changed, 57 insertions, 23 deletions
@@ -30,6 +30,11 @@ emitter = settings.emitter balco = lambda *args, **kwargs: mconfig.build_and_link_c_objs(emitter, settings.host_machine(), settings, *args, **kwargs) +def cb(fn): + if fn.endswith('/objc.c'): + return settings.specialize(obj_ldflag_sets=[('-lobjc',)]) + return settings + # Note: the order of darwin-inject-asm.o is significant. Per man page, ld is # guaranteed to link objects in order, which is necessary because # darwin-inject-asm.S does not itself ensure there is at least 0x4000 bytes of @@ -58,7 +63,7 @@ balco( '(src)/lib/hook-functions.c', '(src)/lib/strerror.c', ], - #settings_cb=lambda fn: settings.specialize(override_is_cxx=True) + settings_cb=cb ) #for name, arch_flag, opts in [ @@ -602,7 +602,7 @@ class XcodeToolchain(object): def get_archs(self, arch, tarch): if arch: - return re.sub('\s', '', val).split(',') + return re.sub('\s', '', arch).split(',') if tarch: # we need to validate it sod, sed, code = run_command(['/usr/bin/xcrun', '--sdk', self.sdk, 'ld', '-arch', tarch]) @@ -717,8 +717,8 @@ def clean_files(fns, settings): for fn in fns: if not os.path.exists(fn) or os.path.isdir(fn): continue - if not settings.allow_autoclean_outside_out and within_dirtree(ro, os.path.realpath(fn)): - log('* Would clean %r as previous build leftover, but it isn\'t in settings.out (%r) so keeping it for safety.\n' % (fn, ro)) + if not settings.allow_autoclean_outside_out and not within_dirtree(ro, os.path.realpath(fn)): + log("* Would clean %r as previous build leftover, but it isn't in settings.out (%r) so keeping it for safety.\n" % (fn, ro)) continue config_log.write('Removing %r\n' % (fn,)) os.remove(fn) @@ -731,9 +731,13 @@ def list_mconfig_scripts(settings): res.append(mod.__file__) return res +def write_file_loudly(fn, data): + log('Writing %s\n' % (fn,)) + with open(fn, 'w') as fp: + fp.write(data) + class Emitter(object): def __init__(self, settings): - self.add_deps_on_config_scripts = settings.add_deps_on_config_scripts self.settings = settings def pre_output(self): assert not hasattr(self, 'did_output') @@ -747,22 +751,17 @@ class Emitter(object): argvs = [expand_argv(x, settings) for x in argvs] if 'expand' in kwargs: del kwargs['expand'] - if self.add_deps_on_config_scripts: - ins.append('int-mconfig-scripts-phony') if settings.enable_rule_hashing: sha = hashlib.sha1(json.dumps((outs, ins, argvs))).hexdigest() if sha not in prev_rule_hashes: clean_files(outs, settings) cur_rule_hashes.add(sha) return self.add_command_raw(outs, ins, argvs, *args, **kwargs) - def emit(self, fn): - if self.add_deps_on_config_scripts: - self.add_command(self.settings, ['int-mconfig-scripts-phony'], list_mconfig_scripts(self.settings), [], phony=True) + def emit(self, fn=None): + if fn is None: + fn = self.settings.emit_fn output = self.output() - log('Writing %s\n' % (fn,)) - fp = open(fn, 'w') - fp.write(output) - fp.close() + write_file_loudly(fn, output) # In the future it may be desirable to use make variables and nontrivial ninja rules for efficiency. @@ -770,7 +769,11 @@ class Emitter(object): class MakefileEmitter(Emitter): def __init__(self, settings): Emitter.__init__(self, settings) - self.makefile_bits = [] + self.banner = '# Generated by mconfig.py' + self.makefile_bits = [self.banner] + self.main_mk = settings.get('main_mk') + if self.main_mk is None: + self.main_mk = lambda: os.path.join(os.path.dirname(settings.emit_fn), 'main.mk') def add_all_and_clean(self): if hasattr(self, 'default_rule'): @@ -812,6 +815,27 @@ class MakefileEmitter(Emitter): self.add_all_and_clean() return '\n'.join(self.makefile_bits) + def emit(self): + makefile = self.settings.emit_fn + main_mk = self.main_mk() + self.add_command_raw([makefile], list_mconfig_scripts(self.settings), [['./config.status']]) + Emitter.emit(self, main_mk) + # Write the stub + # TODO is there something better than shell? + # TODO avoid deleting partial output? + stub = ''' +%(banner)s +_ := $(shell "$(MAKE_COMMAND)" -f %(main_mk_arg)s %(makefile_arg)s) +include %(main_mk)s +'''.lstrip() \ + % { + 'makefile_arg': argv_to_shell([makefile]), + 'main_mk_arg': argv_to_shell([main_mk]), + 'main_mk': self.filename_rel_and_escape(main_mk), + 'banner': self.banner, + } + write_file_loudly(makefile, stub) + def default_outfile(self): return 'Makefile' @@ -876,7 +900,7 @@ def add_emitter_option(): settings_root.add_setting_option('emit_fn', '--outfile', 'Output file. Default: depends on type', section=output_section, default=lambda: settings_root.emitter.default_outfile()) def finish_and_emit(): - settings_root.emitter.emit(settings_root.emit_fn) + settings_root.emitter.emit() if settings_root.enable_rule_hashing: emit_rule_hashes() @@ -927,6 +951,7 @@ def build_c_objs(emitter, machine, settings, sources, headers=[], settings_cb=No tools = machine.c_tools() any_was_cxx = False obj_fns = [] + ldflag_sets = set() _expand = globals()['expand'] for fn in sources: if expand: @@ -951,11 +976,14 @@ def build_c_objs(emitter, machine, settings, sources, headers=[], settings_cb=No cmd = cc + dbg + cflags + ['-c', '-o', obj_fn, '-MMD', '-MF', dep_fn, fn] emitter.add_command(my_settings, [obj_fn], [fn] + extra_deps, [mkdir_cmd, cmd], depfile=('makefile', dep_fn), expand=False) + + for lset in my_settings.get('obj_ldflag_sets', ()): + ldflag_sets.add(tuple(lset)) obj_fns.append(obj_fn) - return obj_fns, any_was_cxx + return obj_fns, any_was_cxx, ldflag_sets -def link_c_objs(emitter, machine, settings, link_type, link_out, objs, link_with_cxx=None, force_cli=False, expand=True, extra_deps=[]): +def link_c_objs(emitter, machine, settings, link_type, link_out, objs, link_with_cxx=None, force_cli=False, expand=True, extra_deps=[], extra_ldflags=[]): if expand: _expand = globals()['expand'] link_out = _expand(link_out, settings) @@ -969,19 +997,20 @@ def link_c_objs(emitter, machine, settings, link_type, link_out, objs, link_with typeflag = ['-dynamiclib'] if machine.is_darwin() else ['-shared'] else: typeflag = [] - cmds = [cc_for_link + typeflag + settings.ldflags + ['-o', link_out] + objs] + cmds = [cc_for_link + typeflag + settings.ldflags + extra_ldflags + ['-o', link_out] + objs] if machine.is_darwin() and settings.debug_info: cmds.append(tools.dsymutil.argv() + [link_out]) elif link_type == 'staticlib': cmds = [tools.ar.argv() + ['rcs'] + objs] elif link_type == 'obj': cmds = [tools.cc.argv() + ['-Wl,-r', '-nostdlib', '-o', link_out] + objs] - cmds.append(['mkdir', '-p', os.path.dirname(link_out)]) + cmds.insert(0, ['mkdir', '-p', os.path.dirname(link_out)]) emitter.add_command(settings, [link_out], objs + extra_deps, cmds, expand=False) -def build_and_link_c_objs(emitter, machine, settings, link_type, link_out, sources, headers=[], objs=[], settings_cb=None, force_cli=False, expand=True, extra_deps=[]): - more_objs, link_with_cxx = build_c_objs(emitter, machine, settings, sources, headers, settings_cb, force_cli, expand) - link_c_objs(emitter, machine, settings, link_type, link_out, objs + more_objs, link_with_cxx, force_cli, expand, extra_deps) +def build_and_link_c_objs(emitter, machine, settings, link_type, link_out, sources, headers=[], objs=[], settings_cb=None, force_cli=False, expand=True, extra_deps=[], extra_ldflags=[]): + more_objs, link_with_cxx, ldflag_sets = build_c_objs(emitter, machine, settings, sources, headers, settings_cb, force_cli, expand) + extra_ldflags = [flag for lset in ldflag_sets for flag in lset] + extra_ldflags + link_c_objs(emitter, machine, settings, link_type, link_out, objs + more_objs, link_with_cxx, force_cli, expand, extra_deps, extra_ldflags) def guess_obj_fn(fn, settings): rel = os.path.relpath(fn, settings.src) |