Class: Rubycc::Driver
- Inherits:
-
Object
- Object
- Rubycc::Driver
- Defined in:
- lib/rubycc/driver.rb
Overview
The gcc-compatible command-line driver: it reads the same option and input
vocabulary a compiler driver is invoked with (rubycc -c -fPIC -Iinc -o x.o x.c, rubycc -shared -o x.so a.o b.o -Llib -lz, rubycc -o prog main.c util.c) and drives the existing compiler and linker components to satisfy
it. It owns no compilation or linking logic of its own — it classifies the
inputs, picks the output mode gcc's flag precedence dictates, and hands the
work to Compiler, SharedLinker, ExecutableLinker and LibraryResolver.
Three modes are selected exactly as gcc selects them: -c compiles each
source to an object without linking; -shared links every input into a
shared object; the absence of a mode flag links into an executable. A
one-shot invocation (-c absent, a .c given) compiles each source in
memory and feeds the resulting object bytes straight to the linker, so no
intermediate .o is ever written to disk. -E runs the preprocessor only.
Unknown options are handled the tolerant way a build driver must (R6): a
documented-but-unmodelled flag family (-O*, -g*, -W*, most -f*, -m*,
-std=…, and friends) is accepted and ignored silently, and any other
--prefixed token draws a warning and is ignored, so an environment-specific
flag mkmf passes never derails a build. A genuine mistake with a definite
meaning — a missing -o operand — is still an error.
Defined Under Namespace
Classes: UsageError
Constant Summary collapse
- PROG =
"rubycc"- CPP_INPUT_EXTENSIONS =
C++ is outside rubycc's supported language scope (DESIGN §3.3). Keep the list in step with the corpus census gate so a C++ file passed directly to the driver is diagnosed instead of falling through as an object input.
%w[.cpp .cc .cxx .c++ .hpp .hxx .hh].freeze
- ARG_CONSUMING_IGNORED =
Options that take a separate operand this driver does not act on. They are recognized only so the operand is not mistaken for an input file; both the option and its argument are skipped. (
-isystemand friends are handled separately, as header search directories.) %w[-Xlinker -z -u -T -MF -MT -MQ -include -isysroot -aux-info -Xassembler -Xpreprocessor].freeze
- SILENT_IGNORE_EXACT =
Bare flags accepted and ignored: linking/codegen switches whose effect this minimal toolchain does not model but whose presence must not be an error.
%w[-pipe -pthread -no-pie -pie -rdynamic -static -s -nostdlib -nostartfiles -shared-libgcc -static-libgcc -symbolic -fsyntax-only].freeze
Class Method Summary collapse
-
.run(argv, stdout: $stdout, stderr: $stderr) ⇒ Object
Runs the driver for
argvand returns the process exit status (0 on success, 1 on any diagnosed failure).
Instance Method Summary collapse
-
#initialize(argv, stdout: $stdout, stderr: $stderr) ⇒ Driver
constructor
A new instance of Driver.
- #run ⇒ Object
Constructor Details
#initialize(argv, stdout: $stdout, stderr: $stderr) ⇒ Driver
Returns a new instance of Driver.
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/rubycc/driver.rb', line 69 def initialize(argv, stdout: $stdout, stderr: $stderr) @argv = argv @out = stdout @err = stderr @inputs = [] # [{ path:, kind: }] in command-line order @output = nil @mode_flag = nil # :compile / :shared / :preprocess (nil => executable) @include_paths = [] @defines = [] # ordered [:define, "NAME[=VAL]"] / [:undef, "NAME"] @libraries = [] # -l request strings, in order @lib_dirs = [] # -L directories, in order @pic = false @default_visibility = :default @soname = nil @system_includes = true # -nostdinc clears this @default_libs = true # -nodefaultlibs clears this @target = nil # -target/--target; defaults to the host CPU end |
Class Method Details
.run(argv, stdout: $stdout, stderr: $stderr) ⇒ Object
Runs the driver for argv and returns the process exit status (0 on
success, 1 on any diagnosed failure). stdout/stderr are injectable so
a test can drive the driver in-process and capture its streams.
64 65 66 |
# File 'lib/rubycc/driver.rb', line 64 def run(argv, stdout: $stdout, stderr: $stderr) new(argv, stdout: stdout, stderr: stderr).run end |
Instance Method Details
#run ⇒ Object
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/rubycc/driver.rb', line 88 def run return print_version if version_requested? parse dispatch 0 rescue UsageError => e @err.puts "#{PROG}: error: #{e.}" 1 rescue CompileError => e # A compiler diagnostic already carries its gcc-style file:line:col header # and caret, so it is printed verbatim. @err.puts e. 1 rescue Backend::UnsupportedError => e # A construct the selected backend cannot lower yet: valid C the target is # not ready for, reported as a diagnostic rather than a Ruby crash. @err.puts "#{PROG}: error: #{e.}" 1 rescue Link::LinkError => e @err.puts "#{PROG}: error: #{e.}" 1 rescue Errno::ENOENT => e @err.puts "#{PROG}: error: #{e.}" 1 end |