#!/usr/bin/ruby #I'll put this in here as an example # #should maybe use environment variables for these $CC="g++" CFLAGS="-O2 -march=native -std=c++17" $EFLAGS = "" #extra flags SRCDIR="src" BUILDDIR="build" INCLUDE="" LIB="" EXT=".cpp" #extension of source file #should maybe use environment variables for these #standalone funcs if __FILE__ == $0 ANSI_RED = "\e[31m" ANSI_CLEAR = "\e[0m" RUB = "#{ANSI_RED}RUB#{ANSI_CLEAR}" def error(msg) puts "#{RUB}: error: #{msg}" exit 1 end def message(msg) puts "#{RUB}: #{msg}" end end #handle argument parsing yourself def parse(arg) case arg when "clean" `rm build/*` `rm #{APPNAME}` exit(0) when "debug" $EFLAGS = "-DDEBUG" main else #error "unknown argument: #{arg}" end case arg.split("=")[0] when "cc" $CC = arg.split("=")[1] main end end #same as above def args case ARGV.count when 0 main when 1 parse(ARGV[0]) else puts "too many arguments" end end #main build function def main error("src directory empty") if Dir.children(SRCDIR).count == 0 #create a thread for each compilation unit threads = [] Dir.each_child(SRCDIR) {|x| threads << Thread.new { system("#{$CC} #{INCLUDE} #{CFLAGS} #{$EFLAGS} -c #{SRCDIR}/#{x} -o #{BUILDDIR}/#{File.basename(x, ".*") + ".o"}") if x.end_with?(EXT) message "compiled: #{x}\n" if x.end_with?(EXT) } } threads.each{ |t| t.join } #wait for each thread to finish until threads.map { |t| t.alive? }.include?(false) end #link build = Dir.each_child(BUILDDIR) o_files = [] build.each { |s| o_files.append("#{BUILDDIR}/#{s}") } `#{$CC} #{CFLAGS} #{$EFLAGS} #{o_files.join(" ")} -o #{APPNAME} #{LIB}` exit(0) end #run some functions args