mirror of
https://github.com/kp2pml30/ya-build.git
synced 2026-02-17 00:14:42 +04:00
become more close to actual ninja
This commit is contained in:
parent
b44e5373ed
commit
1ece0617dc
1 changed files with 327 additions and 270 deletions
597
ya-build
597
ya-build
|
|
@ -66,213 +66,211 @@ class OpenStruct
|
|||
end
|
||||
end
|
||||
|
||||
def escape_args_to(buf, args)
|
||||
args.each { |a|
|
||||
buf << ' '
|
||||
buf << Shellwords.escape(a).gsub(/\\=/, '=')
|
||||
}
|
||||
class NinjaPiece
|
||||
protected def dump_ninja(buf)
|
||||
raise "abstract"
|
||||
end
|
||||
end
|
||||
|
||||
class Target
|
||||
attr_reader :trg_name, :meta, :outputs
|
||||
class NinjaPieceRaw
|
||||
def initialize(data)
|
||||
@data = data
|
||||
end
|
||||
def dump_ninja(buf)
|
||||
buf << @data << "\n\n"
|
||||
end
|
||||
end
|
||||
|
||||
class Target < NinjaPiece
|
||||
attr_reader :meta, :outputs, :inputs, :implicit_inputs, :implicit_outputs, :rule
|
||||
|
||||
def initialize(outputs:, inputs:, rule:, implicit_inputs: [], implicit_outputs: [])
|
||||
raise "invalid param" if not outputs.kind_of?(Array)
|
||||
raise "invalid param" if not inputs.kind_of?(Array)
|
||||
raise "invalid param" if not implicit_inputs.kind_of?(Array)
|
||||
raise "invalid param" if not implicit_outputs.kind_of?(Array)
|
||||
raise "rule must be a string" if not rule.kind_of?(String)
|
||||
|
||||
def initialize(trg_name, dependencies)
|
||||
@meta = OpenStruct.new
|
||||
if dependencies.nil?
|
||||
raise "dependencies can't be nil"
|
||||
@implicit_inputs = implicit_inputs
|
||||
@implicit_outputs = implicit_outputs
|
||||
@inputs = inputs.clone
|
||||
@outputs = outputs.clone
|
||||
@rule = rule
|
||||
end
|
||||
|
||||
def dump_ninja(buf)
|
||||
raise "no output" if outputs.size == 0
|
||||
buf << "build"
|
||||
DefaultTargets::escape_args_to(buf, outputs)
|
||||
if implicit_outputs.size > 0
|
||||
buf << " |"
|
||||
DefaultTargets::escape_args_to(buf, implicit_outputs)
|
||||
end
|
||||
@trg_name = trg_name
|
||||
if @trg_name.kind_of?(Pathname)
|
||||
@trg_name = @trg_name.to_s
|
||||
buf << " : #{rule}"
|
||||
DefaultTargets::escape_args_to(buf, inputs)
|
||||
if implicit_inputs.size > 0
|
||||
buf << " |"
|
||||
DefaultTargets::escape_args_to(buf, implicit_inputs)
|
||||
end
|
||||
@outputs = [trg_name]
|
||||
raise "target name is not a string (got `#{@trg_name}`)" if not @trg_name.kind_of?(String)
|
||||
@dependencies = dependencies
|
||||
buf << "\n"
|
||||
cb = Proc.new { |k, v|
|
||||
buf << " " << k << " = " << v << "\n"
|
||||
}
|
||||
dump_vars cb
|
||||
buf << "\n"
|
||||
end
|
||||
|
||||
def add_deps(*deps)
|
||||
@dependencies.concat(deps.flatten)
|
||||
protected def dump_vars(cb)
|
||||
raise "abstract for #{self}"
|
||||
end
|
||||
end
|
||||
|
||||
def inspect
|
||||
"<#{self.class.name}:#{@trg_name}>"
|
||||
end
|
||||
module DefaultTargets
|
||||
|
||||
def dump_rules(buf)
|
||||
buf << "build "
|
||||
escape_args_to(buf, outputs)
|
||||
buf << ": #{mode}"
|
||||
@dependencies.each { |d|
|
||||
buf << ' '
|
||||
if d.kind_of?(Target)
|
||||
buf << d.trg_name
|
||||
elsif d.kind_of?(Pathname)
|
||||
buf << d.to_s
|
||||
elsif d.kind_of?(String)
|
||||
buf << d
|
||||
def self.escape_args_to(buf, args)
|
||||
raise "buf can't be nil" if buf.nil?
|
||||
dump_args = args.flat_map { |arg|
|
||||
if arg.kind_of?(Target)
|
||||
arg.outputs + arg.implicit_outputs
|
||||
elsif arg.kind_of?(Pathname)
|
||||
[arg.to_s]
|
||||
elsif arg.kind_of?(String)
|
||||
[arg]
|
||||
else
|
||||
raise "Invalid dependency #{d} : #{d.class} for #{self}"
|
||||
raise "unsupported type #{arg.class} of #{arg}"
|
||||
end
|
||||
}
|
||||
buf << "\n"
|
||||
dump_rules_impl(buf)
|
||||
buf << "\n\n"
|
||||
|
||||
dump_args.each { |a|
|
||||
buf << ' '
|
||||
buf << Shellwords.escape(a).gsub(/\\=/, '=')
|
||||
}
|
||||
end
|
||||
|
||||
def mode
|
||||
raise "abstract"
|
||||
class Phony < Target
|
||||
attr_reader :name
|
||||
def initialize(name:, inputs:, implicit_inputs: [])
|
||||
super(outputs: [name].freeze, inputs: inputs, implicit_inputs: implicit_inputs, implicit_outputs: [].freeze, rule: "phony")
|
||||
@name = name
|
||||
end
|
||||
|
||||
protected def dump_vars(cb)
|
||||
end
|
||||
end
|
||||
|
||||
protected def dump_rules_impl(buf)
|
||||
raise "abstract"
|
||||
end
|
||||
end
|
||||
class Command < Target
|
||||
attr_reader :output_file
|
||||
def initialize(output_file, dependencies, cwd, commands, depfile, pool, env)
|
||||
super(outputs: [output_file], inputs: dependencies, rule: 'CUSTOM_COMMAND')
|
||||
@env = env
|
||||
@depfile = depfile
|
||||
@output_file = output_file
|
||||
@cwd = cwd
|
||||
@commands = commands
|
||||
@pool = pool
|
||||
end
|
||||
|
||||
class CommandTarget < Target
|
||||
attr_reader :output_file
|
||||
def initialize(output_file, dependencies, cwd, commands, depfile, pool, env)
|
||||
super(output_file, dependencies)
|
||||
@env = env
|
||||
@depfile = depfile
|
||||
@output_file = output_file
|
||||
@cwd = cwd
|
||||
@commands = commands
|
||||
@pool = pool
|
||||
end
|
||||
|
||||
protected def dump_rules_impl(buf)
|
||||
if @env.size > 0
|
||||
buf << " ENV = env"
|
||||
@env.each { |k, v|
|
||||
buf << ' ' << k << '=' << Shellwords.escape(v).gsub(/\\=/, '=')
|
||||
protected def dump_vars(cb)
|
||||
if @env.size > 0
|
||||
buf = String.new
|
||||
buf << "env"
|
||||
@env.each { |k, v|
|
||||
buf << ' ' << k << '=' << Shellwords.escape(v).gsub(/\\=/, '=')
|
||||
}
|
||||
cb.('ENV', buf)
|
||||
end
|
||||
if not @pool.nil?
|
||||
cb.('pool', @pool)
|
||||
end
|
||||
if not @cwd.nil?
|
||||
cb.('CWD', Shellwords.escape(@cwd))
|
||||
end
|
||||
if not @depfile.nil?
|
||||
cb.('depfile', Shellwords.escape(@depfile))
|
||||
end
|
||||
cmd = String.new
|
||||
@commands.each_with_index { |c, i|
|
||||
if i != 0
|
||||
cmd << " &&"
|
||||
end
|
||||
DefaultTargets::escape_args_to(cmd, c)
|
||||
}
|
||||
buf << "\n"
|
||||
cb.('COMMAND', cmd)
|
||||
end
|
||||
if not @pool.nil?
|
||||
buf << " pool = #{@pool}\n"
|
||||
end
|
||||
|
||||
class ConfigureGenerated < Target
|
||||
def initialize(configurator)
|
||||
@configurator = configurator
|
||||
super(outputs: [], inputs: [], rule: 'RERUN_YA_BUILD')
|
||||
end
|
||||
if not @cwd.nil?
|
||||
buf << " WD = #{Shellwords.escape @cwd}\n"
|
||||
|
||||
def dump_vars(cb)
|
||||
cb.('pool', 'console')
|
||||
end
|
||||
if not @depfile.nil?
|
||||
buf << " depfile = #{@depfile}\n"
|
||||
end
|
||||
|
||||
class C < Target
|
||||
attr_reader :output_file
|
||||
def initialize(output:, inputs:, flags:, cc:, rule:, root_dir: nil)
|
||||
super(outputs: [output].freeze, inputs: inputs, rule: rule)
|
||||
@root_dir = root_dir
|
||||
@output_file = output
|
||||
@flags = flags
|
||||
@cc = cc
|
||||
end
|
||||
buf << " COMMAND ="
|
||||
@commands.each_with_index { |c, i|
|
||||
if i != 0
|
||||
buf << " &&"
|
||||
|
||||
protected def dump_vars(cb)
|
||||
if not @cc.nil?
|
||||
cb.('CC', Shellwords.escape(@cc))
|
||||
end
|
||||
if not @root_dir.nil?
|
||||
cb.('ROOT_DIR', Shellwords.escape(@root_dir))
|
||||
end
|
||||
if not @flags.nil? and not @flags.empty?
|
||||
cflags = String.new
|
||||
DefaultTargets::escape_args_to(cflags, @flags)
|
||||
cb.('cflags', cflags)
|
||||
end
|
||||
escape_args_to(buf, c)
|
||||
}
|
||||
buf << "\n"
|
||||
end
|
||||
|
||||
def mode
|
||||
"CUSTOM_COMMAND"
|
||||
end
|
||||
end
|
||||
|
||||
class ConfigureGeneratedTarget < Target
|
||||
def initialize(configurator, output_file)
|
||||
@configurator = configurator
|
||||
super(output_file, [])
|
||||
end
|
||||
def dump_rules_impl(buf)
|
||||
buf << " pool = console\n"
|
||||
end
|
||||
def mode
|
||||
"RERUN_YA_BUILD"
|
||||
end
|
||||
end
|
||||
|
||||
class CTarget < Target
|
||||
attr_reader :output_file
|
||||
def initialize(output_file, mode, dependencies, flags, cc, root_dir)
|
||||
super(output_file, dependencies)
|
||||
@root_dir = root_dir
|
||||
@mode = mode
|
||||
@output_file = output_file
|
||||
@flags = flags
|
||||
@cc = cc
|
||||
end
|
||||
|
||||
protected def dump_rules_impl(buf)
|
||||
if @mode != "link"
|
||||
buf << " ROOT_DIR = #{Shellwords.escape @root_dir}/\n"
|
||||
end
|
||||
if not @cc.nil?
|
||||
buf << " CC = #{@cc}\n"
|
||||
end
|
||||
if not @flags.nil? and not @flags.empty?
|
||||
buf << " cflags ="
|
||||
escape_args_to(buf, @flags)
|
||||
buf << "\n"
|
||||
end
|
||||
end
|
||||
|
||||
def mode()
|
||||
case @mode
|
||||
when "compile"
|
||||
"COMPILE_C"
|
||||
when "link"
|
||||
"LINK_C"
|
||||
else
|
||||
raise "unknown mode #{@mode}"
|
||||
class Copy < Target
|
||||
def initialize(dest, src)
|
||||
super(outputs: [dest].freeze, inputs: src, rule: "COPY")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class AliasTarget < Target
|
||||
def initialize(name, dependencies)
|
||||
super(name, dependencies)
|
||||
end
|
||||
|
||||
protected def dump_rules_impl(buf)
|
||||
end
|
||||
|
||||
def mode()
|
||||
"phony"
|
||||
end
|
||||
end
|
||||
|
||||
class CopyTarget < Target
|
||||
def initialize(dest, src)
|
||||
super(dest, [src])
|
||||
end
|
||||
|
||||
protected def dump_rules_impl(buf)
|
||||
end
|
||||
|
||||
def mode()
|
||||
"COPY"
|
||||
protected def dump_vars(buf)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Configurator
|
||||
attr_reader :root_src, :root_build, :config, :logger
|
||||
attr_reader :root_src, :root_build, :config, :logger, :ninja_path, :ninja_files_parts
|
||||
|
||||
private def get_tag_target(tag)
|
||||
ret = @tags[tag]
|
||||
return ret if not ret.nil?
|
||||
ret = AliasTarget.new("tags/#{tag}", [])
|
||||
ret = DefaultTargets::Phony.new(name: "tags/#{tag}", inputs: [])
|
||||
@tags[tag] = ret
|
||||
register_target(ret)
|
||||
ret
|
||||
end
|
||||
|
||||
def initialize(src, build, preloads)
|
||||
@rules = []
|
||||
@root_src = Pathname.new(src).realpath
|
||||
@root_build = Pathname.new(build)
|
||||
@root_build.mkpath()
|
||||
@root_build = @root_build.realpath
|
||||
|
||||
@trivial_targets = String.new
|
||||
@ninja_files_parts = Hash.new
|
||||
@ninja_files_parts[''] = []
|
||||
|
||||
@tags = {}
|
||||
|
||||
@config_target = ConfigureGeneratedTarget.new(self, 'build.ninja')
|
||||
@targets = [@config_target]
|
||||
@config_target = DefaultTargets::ConfigureGenerated.new(self)
|
||||
@named_targets = []
|
||||
|
||||
@stack = []
|
||||
|
||||
|
|
@ -285,18 +283,80 @@ class Configurator
|
|||
end
|
||||
|
||||
@config = OpenStruct.new
|
||||
@config.tools = OpenStruct.new
|
||||
cnf = root_src.join('yabuild-default-conf.rb')
|
||||
if cnf.exist?
|
||||
@config_target.add_deps(cnf)
|
||||
@config = self.instance_eval(cnf.read, cnf.to_s)
|
||||
@config_target.inputs.push(cnf)
|
||||
self.instance_eval(cnf.read, cnf.to_s)
|
||||
end
|
||||
|
||||
preloads.each { |preload|
|
||||
preload = Pathname.new(preload).realpath
|
||||
@config_target.add_deps(preload)
|
||||
contents = preload.read
|
||||
self.instance_eval(contents, preload.to_s)
|
||||
@config_target.inputs.push(preload)
|
||||
self.instance_eval(preload.read, preload.to_s)
|
||||
}
|
||||
|
||||
@ninja_path = find_executable('ninja', critical: true)
|
||||
|
||||
fill_default_ninja
|
||||
register_target(@config_target)
|
||||
end
|
||||
|
||||
private def fill_default_ninja
|
||||
default_pieces = []
|
||||
@ninja_files_parts['default-rules'] = default_pieces
|
||||
|
||||
@ninja_files_parts[''] << NinjaPieceRaw.new(<<-EOF
|
||||
# ya-build generated, do not edit
|
||||
# src: #{root_src}
|
||||
ninja_required_version = 1.5
|
||||
ya_ninja_workdir = #{root_build}
|
||||
include default-rules.ninja
|
||||
|
||||
build clean: CLEAN
|
||||
|
||||
build help: HELP
|
||||
|
||||
EOF
|
||||
)
|
||||
|
||||
default_pieces << NinjaPieceRaw.new(<<-EOF
|
||||
# ya-build generated, do not edit
|
||||
|
||||
CC = clang
|
||||
|
||||
rule RERUN_YA_BUILD
|
||||
command = cd #{Shellwords.escape Dir.getwd} && #{SELF_COMMAND.map { |x| Shellwords.escape x }.join(' ')}
|
||||
description = rerunning ya-build
|
||||
|
||||
rule CLEAN
|
||||
command = #{Shellwords.escape ninja_path} $FILE_ARG -t clean $TARGETS
|
||||
description = Cleaning all built files...
|
||||
|
||||
rule HELP
|
||||
command = #{Shellwords.escape ninja_path} -t targets rule phony rule CLEAN rule HELP
|
||||
description = All primary targets available
|
||||
|
||||
rule CUSTOM_COMMAND
|
||||
command = cd $CWD && $ENV $COMMAND
|
||||
description = $DESC
|
||||
|
||||
rule C_COMPILE
|
||||
depfile = $out.d
|
||||
command = $CC \
|
||||
-MD -MF $out.d \
|
||||
-c $cflags \
|
||||
-o $out \
|
||||
$in
|
||||
|
||||
rule C_LINK
|
||||
command = $CC $cflags -o $out $in
|
||||
|
||||
rule COPY
|
||||
command = cp $in $out
|
||||
|
||||
EOF
|
||||
)
|
||||
end
|
||||
|
||||
private def extend_config_impl(l, r)
|
||||
|
|
@ -347,65 +407,21 @@ class Configurator
|
|||
end
|
||||
|
||||
def eval_script(path)
|
||||
script_path = cur_src.join(@stack[-1].path.join(path))
|
||||
@config_target.add_deps(script_path)
|
||||
script_path = cur_src.join(path)
|
||||
contents = script_path.read
|
||||
@config_target.inputs.push script_path
|
||||
self.instance_eval(contents, script_path.to_s)
|
||||
end
|
||||
|
||||
private def run_last_stack()
|
||||
path = @stack[-1].path
|
||||
@logger.info("configuring #{path}")
|
||||
@logger.info("entering #{path}")
|
||||
script_path = root_src.join(path, 'yabuild.rb')
|
||||
@config_target.add_deps(script_path)
|
||||
@config_target.inputs.push(script_path)
|
||||
contents = script_path.read
|
||||
self.instance_eval(contents, script_path.to_s)
|
||||
end
|
||||
|
||||
def add_rule(rule)
|
||||
@rules.push(rule)
|
||||
end
|
||||
|
||||
private def rules_str()
|
||||
beg = [<<-EOF
|
||||
# ya-build generated, do not edit
|
||||
|
||||
CC = clang
|
||||
|
||||
rule RERUN_YA_BUILD
|
||||
command = cd #{Shellwords.escape Dir.getwd} && #{SELF_COMMAND.map { |x| Shellwords.escape x }.join(' ')}
|
||||
description = rerunning ya-build
|
||||
|
||||
rule CLEAN
|
||||
command = /usr/bin/ninja $FILE_ARG -t clean $TARGETS
|
||||
description = Cleaning all built files...
|
||||
|
||||
rule HELP
|
||||
command = /usr/bin/ninja -t targets rule phony rule CLEAN rule HELP
|
||||
description = All primary targets available
|
||||
|
||||
rule CUSTOM_COMMAND
|
||||
command = cd $WD && $ENV $COMMAND
|
||||
description = $DESC
|
||||
|
||||
rule COMPILE_C
|
||||
depfile = $out.d
|
||||
command = cd $ROOT_DIR && \
|
||||
$CC -MD -MF $out.d $cflags -o $out "$$(#{[RbConfig.ruby, Pathname.new(__FILE__).realpath, '__realpath_to_from'].map(&Shellwords.method(:escape)).join(' ')} "$in" "$ROOT_DIR")" && \
|
||||
#{[RbConfig.ruby, Pathname.new(__FILE__).realpath, '__patch_dep'].map(&Shellwords.method(:escape)).join(' ')} $ROOT_DIR $out.d
|
||||
|
||||
rule LINK_C
|
||||
command = $CC $cflags -o $out $in
|
||||
|
||||
rule COPY
|
||||
command = cp $in $out
|
||||
|
||||
EOF
|
||||
]
|
||||
beg += @rules
|
||||
beg.join("\n\n")
|
||||
end
|
||||
|
||||
def run()
|
||||
@stack = [
|
||||
OpenStruct.new(
|
||||
|
|
@ -418,44 +434,49 @@ EOF
|
|||
|
||||
File.write(root_build.join('config.json'), @config.to_json)
|
||||
|
||||
File.write(root_build.join('rules.ninja'), rules_str)
|
||||
|
||||
build_str = String.new()
|
||||
build_str << <<-EOF
|
||||
# ya-build generated, do not edit
|
||||
# src: #{root_src}
|
||||
ninja_required_version = 1.5
|
||||
ya_ninja_workdir = #{root_build}
|
||||
include rules.ninja
|
||||
|
||||
build clean: CLEAN
|
||||
|
||||
build help: HELP
|
||||
|
||||
EOF
|
||||
@targets.each { |t|
|
||||
t.dump_rules(build_str)
|
||||
ninja_files_parts.each { |k, v|
|
||||
@config_target.outputs << "#{if k == "" then "build" else k end}.ninja"
|
||||
}
|
||||
|
||||
ninja_files_parts.each { |k, v|
|
||||
if k == ''
|
||||
k = 'build'
|
||||
end
|
||||
fname = root_build.join("#{k}.ninja")
|
||||
buf = String.new
|
||||
buf << "# ya-build generated, do not edit\n"
|
||||
v.each do |v|
|
||||
v.dump_ninja buf
|
||||
rescue => e
|
||||
logger.error("can't dump #{v.inspect}")
|
||||
raise
|
||||
end
|
||||
if k == 'build'
|
||||
buf << "default tags/all\n"
|
||||
end
|
||||
File.write fname, buf
|
||||
}
|
||||
build_str << "default tags/all\n"
|
||||
File.write(root_build.join('build.ninja'), build_str)
|
||||
end
|
||||
|
||||
def find_target(name)
|
||||
suitable = @targets.filter { |trg|
|
||||
trg.trg_name.match?(name)
|
||||
suitable = @named_targets.filter { |trg|
|
||||
trg.name.match?(name)
|
||||
}
|
||||
raise "couldn't find target by name #{name} ; suitable: #{suitable}" if suitable.size() != 1
|
||||
suitable[0]
|
||||
end
|
||||
|
||||
private def register_target(trg)
|
||||
@targets.push(trg)
|
||||
private def register_target(trg, to: '')
|
||||
@ninja_files_parts[to] << trg
|
||||
if trg.kind_of?(DefaultTargets::Phony)
|
||||
@named_targets.push(trg)
|
||||
end
|
||||
end
|
||||
|
||||
private def return_target(trg, tags: [], &block)
|
||||
register_target(trg)
|
||||
tags.map { |t| get_tag_target(t) }.each { |t|
|
||||
t.add_deps trg
|
||||
t.inputs.push trg
|
||||
}
|
||||
if not block.nil?
|
||||
trg.instance_eval(&block)
|
||||
|
|
@ -486,27 +507,68 @@ EOF
|
|||
root_src.join(@stack[-1].path)
|
||||
end
|
||||
|
||||
def find_executable(name, critical: false)
|
||||
paths = ENV['PATH'].split(':')
|
||||
paths << '/usr/bin'
|
||||
paths << '/bin'
|
||||
paths << "#{ENV['HOME']}/.local/bin"
|
||||
paths << "#{ENV['HOME']}/.cargo/bin"
|
||||
paths.each { |p|
|
||||
check = ['', '.elf', '.exe']
|
||||
check.each { |c|
|
||||
cur_p = Pathname.new(p).join("#{name}#{c}")
|
||||
if cur_p.exist?()
|
||||
logger.info("checking for #{name}... located at #{cur_p}")
|
||||
return cur_p
|
||||
def find_executable(name, critical: false, check_first: [], check_path: true, check_last: [], &blk)
|
||||
chck = Proc.new { |path|
|
||||
if path.nil?
|
||||
next false
|
||||
end
|
||||
if not path.exist?
|
||||
next false
|
||||
end
|
||||
logger.debug("executable #{name} found at #{path}")
|
||||
if blk.nil?
|
||||
next true
|
||||
end
|
||||
|
||||
begin
|
||||
res = blk.(path)
|
||||
if not res
|
||||
logger.info("executable #{name} found at #{path} does not work (check failed)")
|
||||
end
|
||||
res
|
||||
rescue => e
|
||||
logger.info("executable #{name} found at #{path} does not work\n#{e}")
|
||||
false
|
||||
end
|
||||
}
|
||||
|
||||
override = config.tools.send(name)
|
||||
if not override.nil?
|
||||
res = chck.(override)
|
||||
if res.nil? and critical
|
||||
logger.error("executable #{name} not found for override #{override}")
|
||||
raise "#{name} not found"
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
check_first.each { |p|
|
||||
path = Pathname.new(p).join(name)
|
||||
if chck.(path)
|
||||
return path
|
||||
end
|
||||
}
|
||||
if check_path
|
||||
paths = ENV['PATH'].split(':')
|
||||
paths.each { |p|
|
||||
path = Pathname.new(p).join(name)
|
||||
if chck.(path)
|
||||
return path
|
||||
end
|
||||
}
|
||||
}
|
||||
if critical
|
||||
logger.error("checking for #{name}... not found")
|
||||
raise "#{name} not found in path"
|
||||
end
|
||||
logger.info("checking for #{name}... not found")
|
||||
check_last.each { |p|
|
||||
path = Pathname.new(p).join(name)
|
||||
if chck.(path)
|
||||
return path
|
||||
end
|
||||
}
|
||||
|
||||
if critical
|
||||
logger.error("executable #{name} not found")
|
||||
raise "#{name} not found"
|
||||
end
|
||||
logger.info("executable #{name} not found")
|
||||
return nil
|
||||
end
|
||||
|
||||
|
|
@ -523,7 +585,7 @@ EOF
|
|||
&blk
|
||||
)
|
||||
if commands.nil? == command.nil?
|
||||
raise "exectly one of command or commands must be specified"
|
||||
raise "exactly one of command or commands must be specified"
|
||||
end
|
||||
if commands.nil?
|
||||
commands = [command]
|
||||
|
|
@ -533,29 +595,24 @@ EOF
|
|||
cwd = cur_src
|
||||
end
|
||||
|
||||
trg = CommandTarget.new(output_file, dependencies, cwd, commands, depfile, pool, env)
|
||||
trg = DefaultTargets::Command.new(output_file, dependencies, cwd, commands, depfile, pool, env)
|
||||
return_target(trg, **kwargs, &blk)
|
||||
end
|
||||
|
||||
def target_copy(dest:, src:, **kwargs, &blk)
|
||||
trg = CopyTarget.new(dest, src)
|
||||
trg = DefaultTargets::Copy.new(dest, src)
|
||||
return_target(trg, **kwargs, &blk)
|
||||
end
|
||||
|
||||
def target_c(output_file:, mode:, root_dir: nil, file: nil, objs: nil, flags: nil, cc: nil, **kwargs, &blk)
|
||||
if (mode == "compile") == file.nil?
|
||||
raise "file must be provided only for compile"
|
||||
end
|
||||
if (mode == "link") == objs.nil?
|
||||
raise "objs must be provided only for link"
|
||||
end
|
||||
if root_dir.nil?
|
||||
root_dir = cur_src
|
||||
end
|
||||
deps = if objs.nil? then [
|
||||
root_dir.join(file)
|
||||
] else objs end
|
||||
trg = CTarget.new(output_file, mode, deps, flags, cc, root_dir)
|
||||
def target_c_compile(output_file:, file:, flags: nil, cc: nil, **kwargs, &blk)
|
||||
real_out = output_file.relative_path_from(root_build)
|
||||
real_file = file.relative_path_from(root_build)
|
||||
trg = DefaultTargets::C.new(output: real_out.to_s, inputs: [real_file.to_s], flags: flags, cc: cc, rule: "C_COMPILE")
|
||||
return_target(trg, **kwargs, &blk)
|
||||
end
|
||||
|
||||
def target_c_link(output_file:, objs:, flags: nil, cc: nil, **kwargs, &blk)
|
||||
trg = DefaultTargets::C.new(output: output_file, inputs: objs, flags: flags, cc: cc, rule: "C_LINK")
|
||||
return_target(trg, **kwargs, &blk)
|
||||
end
|
||||
|
||||
|
|
@ -565,7 +622,7 @@ EOF
|
|||
name_full += "/"
|
||||
end
|
||||
name_full += name
|
||||
trg = AliasTarget.new(name_full, dependencies)
|
||||
trg = DefaultTargets::Phony.new(name: name_full, inputs: dependencies)
|
||||
if dependencies.size() != 1 and inherit_meta.size() != 0
|
||||
raise "Can inherit meta only for single dependency alias"
|
||||
end
|
||||
|
|
@ -576,11 +633,11 @@ EOF
|
|||
end
|
||||
|
||||
def mark_as_config_generated(file)
|
||||
@config_target.outputs.push file
|
||||
@config_target.implicit_outputs.push file
|
||||
end
|
||||
|
||||
def reconfigure_on_change(file)
|
||||
@config_target.add_deps file
|
||||
@config_target.inputs.push file
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue