|
3 | 3 | require "vaporware" |
4 | 4 | require "optparse" |
5 | 5 | opt = OptionParser.new |
6 | | -options = {} |
7 | | -opt.on("-c", "--compiler[=VAL]", "this option is selecting compiler precompiled file, default: \"self\"") { |v| options[:compiler] = v } |
8 | | -opt.on("-a", "--assembler[=VAL]", "this option is selecting assembler assembler file, default: \"as\"") { |v| options[:assembler] = v } |
9 | | -opt.on("-D", "--debug") { |v| options[:debug] = v } |
10 | | -opt.on("-o", "--objects[=VAL]") { |v| options[:dest] = v } |
11 | | -opt.on("--compiler-options[=VAL]", "compiler options") { |v| options[:compiler_options] = v.split(",") } |
12 | | -opt.on("-s", "--shared-library") { |v| options[:shared] = v } |
13 | | -opt.on("-l", "--linker[=VAL]", "selecting linker: gold, lld, and mold, default: \"gold\".") { |v| options[:linker] = v } |
| 6 | +options = { |
| 7 | + compile: true, |
| 8 | + assemble: true, |
| 9 | + link: true, |
| 10 | +} |
| 11 | + |
| 12 | +subcommands = Hash.new do |hash, key| |
| 13 | + $stderr.puts "no such subcommand: #{key}" |
| 14 | + exit 1 |
| 15 | +end |
| 16 | + |
| 17 | +subcommands["compile"] = OptionParser.new do |opt| |
| 18 | + opt.on("-o", "--output=FILE", "Output file name") { |v| options[:output] = v } |
| 19 | + opt.on("-c", "--assemble-only", "Assembly only, do not link") { options[:link] = false } |
| 20 | + opt.on("-S", "--compile-only", "Compile only, do not assemble") do |
| 21 | + options[:assemble] = false |
| 22 | + options[:link] = false |
| 23 | + end |
| 24 | + opt.on("-a", "--assembler=ASSEMBLER", "Specify the assembler to use (e.g., as, gas)") { |v| options[:assembler] = v } |
| 25 | + opt.on("-l", "--linker=LINKER", "Specify the linker to use (e.g., gold, lld, mold)") { |v| options[:linker] = v } |
| 26 | + |
| 27 | + opt.on("-s", "--shared", "Compile as shared object") { options[:shared] = true } |
| 28 | + opt.on("-d", "--debug", "Compile with debug information") { options[:debug] = true } |
| 29 | +end |
| 30 | + |
| 31 | +subcommands["assemble"] = OptionParser.new do |opt| |
| 32 | + opt.on("-o", "--output=FILE", "Output file name") { |v| options[:output] = v } |
| 33 | + opt.on("-a", "--assembler=ASSEMBLER", "Specify the assembler to use (e.g., as, gas)") { |v| options[:assembler] = v } |
| 34 | + opt.on("-c", "--assemble-only", "Assemble only, do not link") { options[:link] = false } |
| 35 | + |
| 36 | + opt.on("-s", "--shared", "Compile as shared object") { options[:shared] = true } |
| 37 | + opt.on("-d", "--debug", "Compile with debug information") { options[:debug] = true } |
| 38 | +end |
| 39 | + |
| 40 | +subcommands["link"] = OptionParser.new do |opt| |
| 41 | + opt.on("-o", "--output=FILE", "Output file name") { |v| options[:output] = v } |
| 42 | + opt.on("-l", "--linker=LINKER", "Specify the linker to use (e.g., gold, lld, mold)") { |v| options[:linker] = v } |
| 43 | + |
| 44 | + opt.on("-s", "--shared", "Compile as shared object") { options[:shared] = true } |
| 45 | + opt.on("-d", "--debug", "Compile with debug information") { options[:debug] = true } |
| 46 | +end |
14 | 47 |
|
15 | 48 | begin |
16 | | - opt.parse!(ARGV) |
| 49 | + subcommands[ARGV.shift].parse!(ARGV) if ARGV.any? |
17 | 50 | raise "please compile target file" if ARGV.empty? |
18 | 51 | rescue => e |
19 | 52 | STDERR.puts(e.message) |
20 | 53 | exit 1 |
21 | 54 | end |
22 | 55 |
|
23 | | -Vaporware::Compiler.compile!(input: ARGV.shift, **options) |
| 56 | +assembler, linker = nil, nil |
| 57 | +assembler = options[:assembler] || "self" |
| 58 | +linker = options[:linker] || "mold" |
| 59 | +debug = options[:debug] || false |
| 60 | +output = options[:output] || "a.out" |
| 61 | +input = ARGV.first |
| 62 | +shared = options[:shared] || false |
| 63 | + |
| 64 | +if File.extname(input) == ".s" |
| 65 | + options[:assemble] = true |
| 66 | + options[:compile] = false |
| 67 | +end |
| 68 | + |
| 69 | +basename = File.expand_path(File.basename(input, ".*")) |
| 70 | +extname = File.extname(output) == ".so" |
| 71 | + |
| 72 | +output = basename + ".s" |
| 73 | +Vaporware.compile(input:, output:, debug:) if options[:compile] |
| 74 | +input, output = output, basename + ".o" |
| 75 | +if options[:assemble] |
| 76 | + input = ARGV.first unless options[:compile] |
| 77 | + Vaporware.assemble(input:, output:, assembler:, debug:) |
| 78 | + File.delete(input) if File.exist?(input) && !debug && File.extname(input) != ".s" |
| 79 | +end |
| 80 | +if options[:link] |
| 81 | + input, output = output, basename |
| 82 | + output = options[:output] || output |
| 83 | + output += ".so" if options[:shared] && !extname |
| 84 | + Vaporware.link(input:, output:, debug:, shared:, linker:) if options[:link] |
| 85 | + File.delete(input) if File.exist?(input) && !debug && File.extname(input) != ".o" |
| 86 | +end |
0 commit comments