def make_symlink( w, dst, src, deps=None, src_is_symlink=False, ignore_src_dep=False ): if deps: assert type( deps ) == list, 'Expecting deps to be of type list' deps.sort(); # Sort dep list for better debuggability. # $1 -- dst # $2 -- src # $3 -- stamp template_str = '{target}: {deps}\n' template_str += ' $(call {rule},{dst_dir},{dst},{src},{stamp})\n' # Stamp files dst_dir = os.path.dirname( dst ) dst_base = os.path.basename( dst ) dst_stamp = stamp( dst ) # Relative paths for symlinking after changing directories src_relative = os.path.relpath( src, dst_dir ) dst_relative = dst_base dst_stamp_relative = os.path.basename( dst_stamp ) # Depend on src stamp if src is also a symlink if src_is_symlink: src_stamp = stamp( src ) inputs = src_stamp else: inputs = src # Make target = dst_stamp if not ignore_src_dep: deps.append( inputs ) deps = ' '.join( deps ) else: deps = ' '.join( deps ) if deps == None: deps = '' w.write( template_str.format( target = target, deps = deps, rule = 'symlink', dst_dir = dst_dir, dst = dst_relative, src = src_relative, stamp = dst_stamp_relative, ) ) return target
def make_stamp( w, f, deps=None, f_is_dep=True ): if deps: assert type( deps ) == list, 'Expecting deps to be of type list' deps.sort(); # Sort dep list for better debuggability. f_stamp = stamp( f ) # $1 -- stamp template_str = '{target}: {deps}\n' template_str += ' $(call {rule},{stamp})\n' if deps and f_is_dep: deps = ' '.join( [ f ] + deps ) else: deps = ' '.join( deps ) if deps == None: deps = '' w.write( template_str.format( target = f_stamp, deps = deps, rule = 'stamp', stamp = f_stamp, ) ) w.newline() return f_stamp
def ninja_symlink( w, dst, src, deps=None, src_is_symlink=False ): if deps: assert type( deps ) == list, 'Expecting deps to be of type list' # Stamp files dst_dir = os.path.dirname( dst ) dst_base = os.path.basename( dst ) dst_stamp = stamp( dst ) # Relative paths for symlinking after changing directories src_relative = os.path.relpath( src, dst_dir ) dst_relative = dst_base dst_stamp_relative = os.path.basename( dst_stamp ) # Depend on src stamp if src is also a symlink if src_is_symlink: src_stamp = stamp( src ) inputs = src_stamp else: inputs = src # Ninja target = dst_stamp w.build( outputs = target, implicit = [ inputs ] + deps, rule = 'symlink', variables = { 'dst_dir' : dst_dir, 'dst' : dst_relative, 'src' : src_relative, 'stamp' : dst_stamp_relative }, ) return target
def ninja_stamp( w, f, deps=None ): if deps: assert type( deps ) == list, 'Expecting deps to be of type list' f_stamp = stamp( f ) w.build( outputs = f_stamp, implicit = [ f ] + deps, rule = 'stamp', variables = { 'stamp' : f_stamp }, ) w.newline() return f_stamp
def gen_step_execute( s, outputs, command, deps, extra_deps, phony=False ): all_deps = deps + extra_deps # Extract the build directory from the command so we can create a # unique rule name tokens = command.split() cd_idx = tokens.index( 'cd' ) build_dir = tokens[ cd_idx + 1 ] rule = build_dir + '-commands-rule' rule = rule.replace( '-', '_' ) # Stamp all outputs from execute outputs = [ stamp( o, '.execstamp.' ) for o in outputs ] # Update timestamps for pre-existing outputs so timestamp-based # dependency checking works command = 'mkdir -p ' + build_dir + '/outputs && ' + \ command + ' && touch -c ' + build_dir + '/outputs/*' # Stamp the build directory outputs.insert( 0, build_dir + '/.execstamp' ) # Rules targets = make_execute( w = s.w, outputs = outputs, rule = rule, command = command, deps = all_deps, touch_target = not phony, ) return targets
def gen_step_execute(s, outputs, command, deps, extra_deps, phony=False): all_deps = deps + extra_deps # Extract the build directory from the command so we can create a # unique rule name tokens = command.split() cd_idx = tokens.index('cd') build_dir = tokens[cd_idx + 1] #..................................................................... # Built-in toggle for enabling/disabling this rule #..................................................................... # This is a hack -- Add a knob for Makefiles to enable/disable this # rule. The goal and primary use case in mind here is to allow users # to copy in pre-built steps and have the build system think its # dependencies have all already been satisfied. We cannot just "touch" # files from earlier steps to make it seem like they are done, since # downstream steps may need those files. The only way we see to make # pre-built steps always look "done" without impacting earlier steps # is to break the dependency. Specifically, if the "directory" and # "collect-inputs" substeps are removed, then a pre-built step will # always look "done". So we add a knob here that checks if the step # build directory has a ".prebuilt" file and if so, ignores this rule. dst_dir = build_dir s.w.write('ifeq ("$(wildcard {}/.prebuilt)","")'.format(dst_dir)) s.w.newline() s.w.newline() #..................................................................... rule = build_dir + '-commands-rule' rule = rule.replace('-', '_') # Stamp all outputs from execute outputs = [stamp(o, '.execstamp.') for o in outputs] # Update timestamps for pre-existing outputs so timestamp-based # dependency checking works command = 'mkdir -p ' + build_dir + '/outputs && ' + \ command + ' && touch -c ' + build_dir + '/outputs/*' # Stamp the build directory outputs.insert(0, build_dir + '/.execstamp') # Rules targets = make_execute( w=s.w, outputs=outputs, rule=rule, command=command, deps=all_deps, touch_target=not phony, ) #..................................................................... # Built-in toggle for enabling/disabling this rule #..................................................................... # Clean up from the above s.w.write('endif') s.w.newline() s.w.newline() #..................................................................... return targets