mirror of
https://github.com/rubyjs/libv8
synced 2023-03-27 23:21:48 -04:00
Refactor the compiler detection module
This commit is contained in:
parent
3034f80c51
commit
80a8dc04f3
3 changed files with 129 additions and 12 deletions
|
@ -19,24 +19,39 @@ module Libv8
|
|||
end
|
||||
|
||||
def available_compilers(*compiler_names)
|
||||
compiler_names.map { |name| find name }.reject(&:nil?)
|
||||
available = compiler_names.select { |compiler_name| available? compiler_name }
|
||||
available.map { |compiler_name| type_of(compiler_name).new compiler_name }
|
||||
end
|
||||
|
||||
def find(name)
|
||||
return nil if name.empty?
|
||||
path, _, status = Open3.capture3 "which #{name}"
|
||||
path.chomp!
|
||||
determine_type(path).new(path) if status.success?
|
||||
end
|
||||
|
||||
def determine_type(compiler_path)
|
||||
compiler_version = Open3.capture3("#{compiler_path} -v")[0..1].join
|
||||
|
||||
case compiler_version
|
||||
def type_of(compiler_name)
|
||||
case version_string_of(compiler_name)
|
||||
when /\bclang\b/i then Clang
|
||||
when /^gcc/i then GCC
|
||||
else GenericCompiler
|
||||
end
|
||||
end
|
||||
|
||||
def version_string_of(compiler_name)
|
||||
command_result = execute_command "#{compiler_name} -v 2>&1"
|
||||
|
||||
unless command_result.status.success?
|
||||
raise "Could not get version string of compiler #{compiler_name}"
|
||||
end
|
||||
|
||||
command_result.output
|
||||
end
|
||||
|
||||
def available?(command)
|
||||
execute_command("which #{command} 2>&1").status.success?
|
||||
end
|
||||
|
||||
def execute_command(command)
|
||||
output = `#{command}`
|
||||
status = $?
|
||||
ExecutionResult.new output, status
|
||||
end
|
||||
|
||||
class ExecutionResult < Struct.new(:output, :status)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
64
spec/compiler_spec.rb
Normal file
64
spec/compiler_spec.rb
Normal file
|
@ -0,0 +1,64 @@
|
|||
$:.unshift File.expand_path '../../ext/libv8', __FILE__
|
||||
|
||||
require 'spec_helper'
|
||||
require 'compiler'
|
||||
|
||||
RSpec.configure do |c|
|
||||
c.include CompilerHelpers
|
||||
end
|
||||
|
||||
module Libv8
|
||||
describe Compiler do
|
||||
describe '::type_of' do
|
||||
it 'returns a GCC class for GCC 4.9.0' do
|
||||
stub_as_available 'c++', :gcc, '4.9.0'
|
||||
Compiler.available_compilers('c++').first.should be_a Compiler::GCC
|
||||
end
|
||||
|
||||
it 'returns a Clang class for Clang 3.4.1' do
|
||||
stub_as_available 'c++', :clang, '3.4.1'
|
||||
Compiler.available_compilers('c++').first.should be_a Compiler::Clang
|
||||
end
|
||||
end
|
||||
|
||||
describe '::available_compilers' do
|
||||
it 'returns instances of the available compilers' do
|
||||
stub_as_available 'c++', :clang, '3.4.1'
|
||||
stub_as_unavailable 'g++'
|
||||
stub_as_available 'clang++', :clang, '3.4.1'
|
||||
|
||||
available_compilers = Compiler.available_compilers 'c++', 'g++', 'clang++'
|
||||
available_compilers.map(&:class).should have(2).items
|
||||
available_compilers.all? { |compiler| compiler.should be_a Compiler::Clang }
|
||||
end
|
||||
end
|
||||
|
||||
describe '::version_string_of' do
|
||||
context 'when calling the compiler command succedes' do
|
||||
it 'returns the version string of the compiler' do
|
||||
stub_as_available 'c++', :clang, '3.4.1'
|
||||
Compiler.version_string_of('c++').should eq version_output_of(:clang, '3.4.1')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when calling the compiler command fails' do
|
||||
it 'raises an exception' do
|
||||
stub_as_unavailable 'c++'
|
||||
expect { Compiler.version_string_of('c++') }.to raise_exception
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '::available?' do
|
||||
it 'returns true when the command is available' do
|
||||
stub_as_available 'c++', :clang, '3.4.1'
|
||||
Compiler::available?('c++').should be_true
|
||||
end
|
||||
|
||||
it 'returns false when the command cannot be found ' do
|
||||
stub_as_unavailable 'c++'
|
||||
Compiler::available?('c++').should be_false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -2,3 +2,41 @@ $:.unshift File.expand_path '../../lib', __FILE__
|
|||
require 'rspec'
|
||||
require 'rspec-spies'
|
||||
require 'libv8'
|
||||
|
||||
module CompilerHelpers
|
||||
VERSION_OUTPUTS = {
|
||||
:gcc => {
|
||||
"4.9.0" => %Q{Using built-in specs.\nCOLLECT_GCC=c++\nCOLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/lto-wrapper\nTarget: x86_64-unknown-linux-gnu\nConfigured with: /build/gcc-multilib/src/gcc-4.9-20140604/configure --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/ --enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++ --enable-shared --enable-threads=posix --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-clocale=gnu --disable-libstdcxx-pch --disable-libssp --enable-gnu-unique-object --enable-linker-build-id --enable-cloog-backend=isl --disable-cloog-version-check --enable-lto --enable-plugin --enable-install-libiberty --with-linker-hash-style=gnu --enable-multilib --disable-werror --enable-checking=release\nThread model: posix\ngcc version 4.9.0 20140604 (prerelease) (GCC)\n}
|
||||
},
|
||||
:clang => {
|
||||
"3.4.1" => %Q{clang version 3.4.1 (tags/RELEASE_34/dot1-final)\nTarget: x86_64-unknown-linux-gnu\nThread model: posix\nFound candidate GCC installation: /usr/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.9.0\nFound candidate GCC installation: /usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.9.0\nFound candidate GCC installation: /usr/lib/gcc/x86_64-unknown-linux-gnu/4.9.0\nFound candidate GCC installation: /usr/lib64/gcc/x86_64-unknown-linux-gnu/4.9.0\nSelected GCC installation: /usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.9.0\n}
|
||||
}
|
||||
}
|
||||
|
||||
def version_output_of(name, version)
|
||||
VERSION_OUTPUTS[name][version]
|
||||
end
|
||||
|
||||
def success_status
|
||||
double success?: true
|
||||
end
|
||||
|
||||
def failure_status
|
||||
double success?: false
|
||||
end
|
||||
|
||||
def stub_shell_command(command, output, status)
|
||||
allow(Libv8::Compiler).to receive(:execute_command).with(command) do
|
||||
double output: output, status: status
|
||||
end
|
||||
end
|
||||
|
||||
def stub_as_available(command, name, version)
|
||||
stub_shell_command "which #{command} 2>&1", '', success_status
|
||||
stub_shell_command "#{command} -v 2>&1", version_output_of(name, version), success_status
|
||||
end
|
||||
|
||||
def stub_as_unavailable(command)
|
||||
stub_shell_command "which #{command} 2>&1", '', failure_status
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Reference in a new issue