implement install and uninstall operations - close #82
add "prefix" construction variable - close #99 add InstallDirectory builder - close #100
This commit is contained in:
1 parent
328babe1f4
commit
fd054a07c4
8 files changed
+299
-133
No files matched your search
+41
-19
@@ -1,3 +1,5 @@
|
||||
require "set"
|
||||
|
||||
module Rscons
|
||||
|
||||
# Functionality for an instance of the rscons application invocation.
|
||||
@@ -23,6 +25,18 @@ module Rscons
|
||||
def initialize
|
||||
@n_threads = Util.determine_n_threads
|
||||
@vars = VarSet.new
|
||||
@operations = Set.new
|
||||
end
|
||||
|
||||
# Check whether a requested operation is active.
|
||||
#
|
||||
# @param op [String]
|
||||
# Operation name.
|
||||
#
|
||||
# @return [Boolean]
|
||||
# Whether the requested operation is active.
|
||||
def operation(op)
|
||||
@operations.include?(op)
|
||||
end
|
||||
|
||||
# Run the specified operation.
|
||||
@@ -37,6 +51,7 @@ module Rscons
|
||||
# @return [Integer]
|
||||
# Process exit code (0 on success).
|
||||
def run(operation, script, operation_options)
|
||||
@operations << operation
|
||||
@script = script
|
||||
case operation
|
||||
when "build"
|
||||
@@ -58,6 +73,10 @@ module Rscons
|
||||
configure(operation_options)
|
||||
when "distclean"
|
||||
distclean
|
||||
when "install"
|
||||
run("build", script, operation_options)
|
||||
when "uninstall"
|
||||
uninstall
|
||||
else
|
||||
$stderr.puts "Unknown operation: #{operation}"
|
||||
1
|
||||
@@ -129,34 +148,37 @@ module Rscons
|
||||
# @return [Integer]
|
||||
# Exit code.
|
||||
def configure(options)
|
||||
# Default options.
|
||||
options[:build_dir] ||= "build"
|
||||
options[:prefix] ||= "/usr/local"
|
||||
cache = Cache.instance
|
||||
cache["failed_commands"] = []
|
||||
cache["configuration_data"] = {}
|
||||
if project_name = @script.project_name
|
||||
Ansi.write($stdout, "Configuring ", :cyan, project_name, :reset, "...\n")
|
||||
else
|
||||
$stdout.puts "Configuring project..."
|
||||
end
|
||||
Ansi.write($stdout, "Setting build directory... ", :green, options[:build_dir], :reset, "\n")
|
||||
Ansi.write($stdout, "Setting prefix... ", :green, options[:prefix], :reset, "\n")
|
||||
rv = 0
|
||||
co = ConfigureOp.new("#{options[:build_dir]}/configure")
|
||||
options = options.merge(project_name: @script.project_name)
|
||||
co = ConfigureOp.new(options)
|
||||
begin
|
||||
@script.configure(co)
|
||||
rescue ConfigureOp::ConfigureFailure
|
||||
rv = 1
|
||||
end
|
||||
co.close
|
||||
cache["configuration_data"]["build_dir"] = options[:build_dir]
|
||||
cache["configuration_data"]["prefix"] = options[:prefix]
|
||||
cache["configuration_data"]["configured"] = rv == 0
|
||||
cache.write
|
||||
co.close(rv == 0)
|
||||
rv
|
||||
end
|
||||
|
||||
# Remove installed files.
|
||||
#
|
||||
# @return [Integer]
|
||||
# Exit code.
|
||||
def uninstall
|
||||
cache = Cache.instance
|
||||
cache.targets(true).each do |target|
|
||||
FileUtils.rm_f(target)
|
||||
end
|
||||
# remove all created directories if they are empty
|
||||
cache.directories(true).sort {|a, b| b.size <=> a.size}.each do |directory|
|
||||
next unless File.directory?(directory)
|
||||
if (Dir.entries(directory) - ['.', '..']).empty?
|
||||
Dir.rmdir(directory) rescue nil
|
||||
end
|
||||
end
|
||||
0
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,60 @@
|
||||
require "pathname"
|
||||
|
||||
module Rscons
|
||||
module Builders
|
||||
# The Copy builder copies files/directories to new locations.
|
||||
class Copy < Builder
|
||||
|
||||
# Run the builder to produce a build target.
|
||||
def run(options)
|
||||
install_builder = self.class.name == "Install"
|
||||
if (not install_builder) or Rscons.application.operation("install")
|
||||
target_is_dir = (@sources.length > 1) ||
|
||||
Dir.exists?(@sources.first) ||
|
||||
Dir.exists?(@target)
|
||||
outdir = target_is_dir ? @target : File.dirname(@target)
|
||||
# Collect the list of files to copy over.
|
||||
file_map = {}
|
||||
if target_is_dir
|
||||
@sources.each do |src|
|
||||
if Dir.exists? src
|
||||
Dir.glob("#{src}/**/*", File::FNM_DOTMATCH).select do |f|
|
||||
File.file?(f)
|
||||
end.each do |subfile|
|
||||
subpath = Pathname.new(subfile).relative_path_from(Pathname.new(src)).to_s
|
||||
file_map[subfile] = "#{outdir}/#{subpath}"
|
||||
end
|
||||
else
|
||||
file_map[src] = "#{outdir}/#{File.basename(src)}"
|
||||
end
|
||||
end
|
||||
else
|
||||
file_map[sources.first] = target
|
||||
end
|
||||
printed_message = false
|
||||
file_map.each do |src, dest|
|
||||
# Check the cache and copy if necessary
|
||||
unless @cache.up_to_date?(dest, :Copy, [src], @env)
|
||||
unless printed_message
|
||||
message = "#{name} #{Util.short_format_paths(@sources)} => #{@target}"
|
||||
print_run_message(message, nil)
|
||||
printed_message = true
|
||||
end
|
||||
@cache.mkdir_p(File.dirname(dest), install: install_builder)
|
||||
FileUtils.cp(src, dest, :preserve => true)
|
||||
end
|
||||
@cache.register_build(dest, :Copy, [src], @env, install: install_builder)
|
||||
end
|
||||
(target_is_dir ? Dir.exists?(@target) : File.exists?(@target)) ? true : false
|
||||
else
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# The Install builder is identical to the Copy builder.
|
||||
class Install < Copy; end
|
||||
|
||||
end
|
||||
end
|
||||
@@ -1,22 +1,33 @@
|
||||
module Rscons
|
||||
module Builders
|
||||
|
||||
# The Directory builder creates a directory.
|
||||
class Directory < Builder
|
||||
|
||||
# Run the builder to produce a build target.
|
||||
def run(options)
|
||||
if File.directory?(@target)
|
||||
true
|
||||
elsif File.exists?(@target)
|
||||
Ansi.write($stderr, :red, "Error: `#{@target}' already exists and is not a directory", :reset, "\n")
|
||||
false
|
||||
install_builder = self.class.name == "InstallDirectory"
|
||||
if (not install_builder) or Rscons.application.operation("install")
|
||||
if File.directory?(@target)
|
||||
true
|
||||
elsif File.exists?(@target)
|
||||
Ansi.write($stderr, :red, "Error: `#{@target}' already exists and is not a directory", :reset, "\n")
|
||||
false
|
||||
else
|
||||
print_run_message("Creating directory => #{@target}", nil)
|
||||
@cache.mkdir_p(@target, install: install_builder)
|
||||
true
|
||||
end
|
||||
else
|
||||
print_run_message("Creating directory => #{@target}", nil)
|
||||
@cache.mkdir_p(@target)
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# The InstallDirectory class is identical to Directory but only performs
|
||||
# an action for an "install" operation.
|
||||
class InstallDirectory < Directory; end
|
||||
|
||||
end
|
||||
end
|
||||
@@ -1,55 +0,0 @@
|
||||
require "pathname"
|
||||
|
||||
module Rscons
|
||||
module Builders
|
||||
# The Install builder copies files/directories to new locations.
|
||||
class Install < Builder
|
||||
|
||||
# Run the builder to produce a build target.
|
||||
def run(options)
|
||||
target_is_dir = (@sources.length > 1) ||
|
||||
Dir.exists?(@sources.first) ||
|
||||
Dir.exists?(@target)
|
||||
outdir = target_is_dir ? @target : File.dirname(@target)
|
||||
# Collect the list of files to copy over.
|
||||
file_map = {}
|
||||
if target_is_dir
|
||||
@sources.each do |src|
|
||||
if Dir.exists? src
|
||||
Dir.glob("#{src}/**/*", File::FNM_DOTMATCH).select do |f|
|
||||
File.file?(f)
|
||||
end.each do |subfile|
|
||||
subpath = Pathname.new(subfile).relative_path_from(Pathname.new(src)).to_s
|
||||
file_map[subfile] = "#{outdir}/#{subpath}"
|
||||
end
|
||||
else
|
||||
file_map[src] = "#{outdir}/#{File.basename(src)}"
|
||||
end
|
||||
end
|
||||
else
|
||||
file_map[sources.first] = target
|
||||
end
|
||||
printed_message = false
|
||||
file_map.each do |src, dest|
|
||||
# Check the cache and copy if necessary
|
||||
unless @cache.up_to_date?(dest, :Copy, [src], @env)
|
||||
unless printed_message
|
||||
message = "#{name} #{Util.short_format_paths(@sources)} => #{@target}"
|
||||
print_run_message(message, nil)
|
||||
printed_message = true
|
||||
end
|
||||
@cache.mkdir_p(File.dirname(dest))
|
||||
FileUtils.cp(src, dest, :preserve => true)
|
||||
end
|
||||
@cache.register_build(dest, :Copy, [src], @env)
|
||||
end
|
||||
(target_is_dir ? Dir.exists?(@target) : File.exists?(@target)) ? true : false
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# The Copy builder is identical to the Install builder.
|
||||
class Copy < Install; end
|
||||
|
||||
end
|
||||
end
|
||||
@@ -10,20 +10,48 @@ module Rscons
|
||||
|
||||
# Create a ConfigureOp.
|
||||
#
|
||||
# @param work_dir [String]
|
||||
# Work directory for configure operation.
|
||||
def initialize(work_dir)
|
||||
@work_dir = work_dir
|
||||
# @param options [Hash]
|
||||
# Optional parameters.
|
||||
# @param build_dir [String]
|
||||
# Build directory.
|
||||
# @param prefix [String]
|
||||
# Install prefix.
|
||||
# @param project_name [String]
|
||||
# Project name.
|
||||
def initialize(options)
|
||||
# Default options.
|
||||
options[:build_dir] ||= "build"
|
||||
options[:prefix] ||= "/usr/local"
|
||||
@work_dir = "#{options[:build_dir]}/configure"
|
||||
FileUtils.mkdir_p(@work_dir)
|
||||
@log_fh = File.open("#{@work_dir}/config.log", "wb")
|
||||
cache = Cache.instance
|
||||
cache["failed_commands"] = []
|
||||
cache["configuration_data"] = {}
|
||||
cache["configuration_data"]["build_dir"] = options[:build_dir]
|
||||
cache["configuration_data"]["prefix"] = options[:prefix]
|
||||
if project_name = options[:project_name]
|
||||
Ansi.write($stdout, "Configuring ", :cyan, project_name, :reset, "...\n")
|
||||
else
|
||||
$stdout.puts "Configuring project..."
|
||||
end
|
||||
Ansi.write($stdout, "Setting build directory... ", :green, options[:build_dir], :reset, "\n")
|
||||
Ansi.write($stdout, "Setting prefix... ", :green, options[:prefix], :reset, "\n")
|
||||
store_merge("prefix" => options[:prefix])
|
||||
end
|
||||
|
||||
# Close the log file handle.
|
||||
#
|
||||
# @param success [Boolean]
|
||||
# Whether all configure operations were successful.
|
||||
#
|
||||
# @return [void]
|
||||
def close
|
||||
def close(success)
|
||||
@log_fh.close
|
||||
@log_fh = nil
|
||||
cache = Cache.instance
|
||||
cache["configuration_data"]["configured"] = success
|
||||
cache.write
|
||||
end
|
||||
|
||||
# Check for a working C compiler.
|
||||
|
||||
Reference in new issue
Block a user