From f08c0939608f5ed95652d71778400efc3fd92c32 Mon Sep 17 00:00:00 2001 From: Nat Lasseter Date: Fri, 24 May 2024 15:10:08 +0100 Subject: Initial commit, currently broken because recursion. --- README | 1 + rubymake.rb | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ test/make.rb | 21 ++++++++++++++ test/testprog.c | 6 ++++ 4 files changed, 116 insertions(+) create mode 100644 README create mode 100644 rubymake.rb create mode 100755 test/make.rb create mode 100644 test/testprog.c diff --git a/README b/README new file mode 100644 index 0000000..f4a4f2b --- /dev/null +++ b/README @@ -0,0 +1 @@ +Terrible Make like thing that's nothing like Make. diff --git a/rubymake.rb b/rubymake.rb new file mode 100644 index 0000000..e8349e9 --- /dev/null +++ b/rubymake.rb @@ -0,0 +1,88 @@ +$makes = [] +$default = nil + +class Make + def initialize(target, froms, args, block) + @target = target + @froms = froms + @args = args + @block = block + end + + def string_target? + @target.class == String + end + + def match?(target) + if string_target? + @target == target + else + @target.match?(target) + end + end + + def try_build(target) + reified_froms = string_target? ? @froms : reify_froms(target) + + reified_froms.each do |from| + Make.make!(from) + end + + if !!@args[:phony] || + !File.exist?(target) || + reified_froms.any? { |from| File.mtime(target) < File.mtime(from) } + @block.call(target, reified_froms, @args) + end + end + + def reify_froms(target) + match = @target.match(target) + + @froms.map do |from| + if match.names.empty? + from.gsub(/\$(\d+)/) {|m| match[m[1..].to_i]} + else + from.gsub(/\$#{match.names.join(?|)}/) {|m| match[m[1..]]} + end + end + end + + def self.make!(target = nil) + print "Making: " + pp target + + if target.nil? + target = ARGV.shift + if target.nil? + if $default.nil? + puts "No target given and no default set" + exit 1 + else + target = $default + puts "Using default target: #{target}" + end + end + end + + makes = $makes.select { |make| make.match?(target) } + + if makes.empty? + puts "No valid target" + else + string_makes = makes.select(&:string_target?) + if string_makes.empty? + makes.first.try_build(target) + else + string_makes.first.try_build(target) + end + end + end +end + +def to(target, *froms, **args, &block) + $makes << Make.new(target, froms, args, block) +end + +def default(target) + $default = target +end diff --git a/test/make.rb b/test/make.rb new file mode 100755 index 0000000..e1a6fff --- /dev/null +++ b/test/make.rb @@ -0,0 +1,21 @@ +#!/usr/bin/env ruby + +require '../rubymake' + +to(/test(.*).h/, "make.rb") do |target| + File.open(target, ?w) do |f| + f.puts "#define STRING \"This is a string\"" + end +end + +to(/test(.*)(?!\.c)/, "test$1.c", "test$1.h") do |target, froms| + `gcc -o #{target} #{froms[0]}` +end + +to("clean", phony: true) do |target| + `rm -f testprog testprog.h` +end + +default "testprog" + +Make.make! diff --git a/test/testprog.c b/test/testprog.c new file mode 100644 index 0000000..cfeb3d6 --- /dev/null +++ b/test/testprog.c @@ -0,0 +1,6 @@ +#include +#include "testprog.h" + +void main() { + printf(STRING "\n"); +} -- cgit v1.2.1