|
2 | 2 |
|
3 | 3 | require_relative "compiler/generator" |
4 | 4 | require_relative "compiler/assembler" |
| 5 | +require_relative "compiler/linker" |
5 | 6 |
|
6 | 7 | class Vaporware::Compiler |
7 | 8 | def self.compile(source, compiler: "gcc", dest: "tmp", debug: false, compiler_options: ["-O0"], shared: false) |
8 | | - _precompile = "#{dest}.s" |
9 | | - s = new(input: source, output: _precompile, debug:, shared:) |
| 9 | + s = new(input: source, output: dest, debug:, shared:) |
10 | 10 | s.compile(compiler_options:) |
11 | | - obj_file = s.assemble(input: _precompile, assembler: "as", debug:) |
12 | | - output = File.basename(obj_file, ".o") |
13 | | - output = "lib#{output}.so" if shared && output !~ /^lib.+\.so$/ |
14 | | - s.link(input: obj_file, output:, shared:) |
15 | | - File.delete(obj_file) unless debug |
16 | | - File.delete(_precompile) unless debug |
17 | | - end |
18 | | - |
19 | | - def initialize(input:, output: File.basename(input, ".*") + ".s", debug: false, shared: false) |
20 | | - @generator = Vaporware::Compiler::Generator.new(input:, output:, debug:, shared:) |
21 | | - @assembler = Vaporware::Compiler::Assembler.new(input: @generator.precompile, debug:,) |
22 | | - end |
23 | | - |
24 | | - def assemble(input:, output: File.basename(input, ".*") + ".o", assembler: "as", assembler_options: [], debug: false) |
25 | | - if ["gcc", "as"].include?(assembler) |
26 | | - assemble = [assembler, *assembler_options, "-o", output, input].compact |
27 | | - call_command(assemble) |
28 | | - else |
29 | | - @assembler.assemble(input:, output:) |
30 | | - end |
31 | | - output |
| 11 | + s.assemble(input: dest.to_s + ".s", assembler: "as", debug:) |
| 12 | + s.link |
32 | 13 | end |
33 | 14 |
|
34 | | - def link(input:, output: File.basename(input, ".*"), linker: "ld", linker_options: [], dyn_ld_path: ["-dynamic-linker", "/lib64/ld-linux-x86-64.so.2"], ld_path: ["/lib64/libc.so.6", "/usr/lib64/crt1.o"], shared: false) |
35 | | - if shared |
36 | | - dyn_ld_path = [] |
37 | | - ld_path = ["/usr/lib64/crti.o", "/usr/lib/gcc/x86_64-pc-linux-gnu/13/crtbeginS.o", "/usr/lib/gcc/x86_64-pc-linux-gnu/13/crtendS.o", "/usr/lib64/crtn.o",] |
38 | | - |
39 | | - linker_options = ["-shared"] |
40 | | - end |
41 | | - linker_commands = [linker, *linker_options, *dyn_ld_path, "-o", output, *ld_path, input].compact |
42 | | - call_command(linker_commands) |
| 15 | + def initialize(input:, output: File.basename(input, ".*"), linker: "ld", assembler: "as", debug: false, shared: false) |
| 16 | + @generator = Vaporware::Compiler::Generator.new(input:, output: output + ".s", debug:, shared:) |
| 17 | + @assembler = Vaporware::Compiler::Assembler.new(input: @generator.precompile, output: output + ".o", assembler:, debug:) |
| 18 | + output = "lib#{output}.so" if shared && output !~ /^lib.+\.so$/ |
| 19 | + @linker = Vaporware::Compiler::Linker.new(input: @assembler.obj_file, output:, linker:, debug:, shared:) |
43 | 20 | end |
44 | 21 |
|
45 | | - def call_command(commands) = IO.popen(commands.join(" ")).close |
46 | | - |
| 22 | + def assemble(input:, output: File.basename(input, ".*") + ".o", assembler: "as", assembler_options: [], debug: false) = @assembler.assemble(input:, output:, assembler:, assembler_options:, debug:) |
| 23 | + def link = @linker.link |
47 | 24 | def compile(compiler_options: ["-O0"]) = @generator.compile |
48 | 25 | end |
0 commit comments