add post-build hooks - close #14

This commit is contained in:
Josh Holtrop 2014-09-19 12:36:57 -04:00
parent dee2b98f6e
commit 453295a49b
2 changed files with 64 additions and 13 deletions

View File

@ -42,7 +42,7 @@ module Rscons
@user_deps = {} @user_deps = {}
@builders = {} @builders = {}
@build_dirs = [] @build_dirs = []
@build_hooks = [] @build_hooks = {pre: [], post: []}
unless options[:exclude_builders] unless options[:exclude_builders]
DEFAULT_BUILDERS.each do |builder_class_name| DEFAULT_BUILDERS.each do |builder_class_name|
builder_class = Builders.const_get(builder_class_name) builder_class = Builders.const_get(builder_class_name)
@ -103,9 +103,12 @@ module Rscons
end end
end end
if clone.include?(:build_hooks) if clone.include?(:build_hooks)
@build_hooks.each do |build_hook_block| @build_hooks[:pre].each do |build_hook_block|
env.add_build_hook(&build_hook_block) env.add_build_hook(&build_hook_block)
end end
@build_hooks[:post].each do |build_hook_block|
env.add_post_build_hook(&build_hook_block)
end
end end
if block_given? if block_given?
@ -132,6 +135,12 @@ module Rscons
# Add a build hook to the Environment. # Add a build hook to the Environment.
# #
# Build hooks are Ruby blocks which are invoked immediately before a
# build operation takes place. Build hooks have an opportunity to modify
# the construction variables in use for the build operation based on the
# builder in use, target file name, or sources. Build hooks can also
# register new build targets.
#
# @yield [build_op] # @yield [build_op]
# Invoke the given block with the current build operation. # Invoke the given block with the current build operation.
# @yieldparam build_op [Hash] # @yieldparam build_op [Hash]
@ -144,7 +153,29 @@ module Rscons
# #
# @return [void] # @return [void]
def add_build_hook(&block) def add_build_hook(&block)
@build_hooks << block @build_hooks[:pre] << block
end
# Add a post build hook to the Environment.
#
# Post-build hooks are Ruby blocks which are invoked immediately after a
# build operation takes place. Post-build hooks are only invoked if the
# build operation succeeded. Post-build hooks can register new build
# targets.
#
# @yield [build_op]
# Invoke the given block with the current build operation.
# @yieldparam build_op [Hash]
# Hash with keys:
# - :builder - The builder object in use.
# - :target - Target file name.
# - :sources - List of source file(s).
# - :vars - Set of construction variable values in use.
# - :env - The Environment invoking the builder.
#
# @return [void]
def add_post_build_hook(&block)
@build_hooks[:post] << block
end end
# Specify a build directory for this Environment. # Specify a build directory for this Environment.
@ -412,17 +443,22 @@ module Rscons
# @return [String,false] Return value from the {Builder}'s +run+ method. # @return [String,false] Return value from the {Builder}'s +run+ method.
def run_builder(builder, target, sources, cache, vars) def run_builder(builder, target, sources, cache, vars)
vars = @varset.merge(vars) vars = @varset.merge(vars)
@build_hooks.each do |build_hook_block| call_build_hooks = lambda do |sec|
build_operation = { @build_hooks[sec].each do |build_hook_block|
builder: builder, build_operation = {
target: target, builder: builder,
sources: sources, target: target,
vars: vars, sources: sources,
env: self, vars: vars,
} env: self,
build_hook_block.call(build_operation) }
build_hook_block.call(build_operation)
end
end end
builder.run(target, sources, cache, self, vars) call_build_hooks[:pre]
rv = builder.run(target, sources, cache, self, vars)
call_build_hooks[:post] if rv
rv
end end
# Expand a path to be relative to the Environment's build root. # Expand a path to be relative to the Environment's build root.

View File

@ -591,4 +591,19 @@ EOF
expect(`./simple`).to eq "This is a simple C program\n" expect(`./simple`).to eq "This is a simple C program\n"
end end
it "supports post-build hooks" do
test_dir("simple")
built_targets = []
env = Rscons::Environment.new do |env|
env.Program("simple", Dir["*.c"])
env.add_post_build_hook do |build_op|
built_targets << build_op[:target]
expect(File.exists?(build_op[:target])).to be_truthy
end
end
expect(File.exists?("simple.o")).to be_truthy
expect(`./simple`).to eq "This is a simple C program\n"
expect(built_targets).to eq ["simple.o", "simple#{env["PROGSUFFIX"]}"]
end
end end