|
1 | | -require 'mkmf' |
2 | | -require 'open3' |
| 1 | +require 'rbconfig' |
3 | 2 | require File.expand_path '../compiler/generic_compiler', __FILE__ |
4 | 3 | require File.expand_path '../compiler/gcc', __FILE__ |
5 | 4 | require File.expand_path '../compiler/clang', __FILE__ |
| 5 | +require File.expand_path '../compiler/apple_llvm', __FILE__ |
6 | 6 |
|
7 | 7 | module Libv8 |
8 | 8 | module Compiler |
9 | | - KNOWN_COMPILERS = [ |
10 | | - 'c++', |
11 | | - 'g++48', 'g++46', 'g++44', 'g++', |
12 | | - 'clang++', |
13 | | - ] |
14 | | - |
15 | 9 | module_function |
16 | 10 |
|
17 | | - def system_compilers |
18 | | - available_compilers *Compiler::KNOWN_COMPILERS |
| 11 | + def well_known_compilers |
| 12 | + compilers = [] |
| 13 | + |
| 14 | + # The default system compiler |
| 15 | + compilers << 'c++' |
| 16 | + |
| 17 | + # FreeBSD GCC command names |
| 18 | + compilers += ['g++48', 'g++49', 'g++5', 'g++6', 'g++7'] |
| 19 | + |
| 20 | + # Default compiler names |
| 21 | + compilers += ['clang++', 'g++'] |
| 22 | + |
| 23 | + compilers.uniq |
19 | 24 | end |
20 | 25 |
|
21 | 26 | def available_compilers(*compiler_names) |
22 | | - compiler_paths = compiler_names.map { |name| find name }.reject &:nil? |
| 27 | + available = compiler_names.select { |compiler_name| available? compiler_name } |
| 28 | + available.map { |compiler_name| type_of(compiler_name).new compiler_name } |
23 | 29 | end |
24 | 30 |
|
25 | | - def find(name) |
26 | | - return nil if name.empty? |
27 | | - path, _, status = Open3.capture3 "which #{name}" |
28 | | - path.chomp! |
29 | | - determine_type(path).new(path) if status.success? |
| 31 | + def type_of(compiler_name) |
| 32 | + case version_string_of(compiler_name) |
| 33 | + when /^Apple LLVM\b/ then AppleLLVM |
| 34 | + when /\bclang\b/i then Clang |
| 35 | + when /^gcc/i then GCC |
| 36 | + else GenericCompiler |
| 37 | + end |
30 | 38 | end |
31 | 39 |
|
32 | | - def determine_type(compiler_path) |
33 | | - compiler_version = Open3.capture3("#{compiler_path} -v")[0..1].join |
| 40 | + def version_string_of(compiler_name) |
| 41 | + command_result = execute_command "#{compiler_name} -v 2>&1" |
34 | 42 |
|
35 | | - case compiler_version |
36 | | - when /\bclang\b/i then Clang |
37 | | - when /^gcc/i then GCC |
38 | | - else GenericCompiler |
| 43 | + unless command_result.status.success? |
| 44 | + raise "Could not get version string of compiler #{compiler_name}" |
39 | 45 | end |
| 46 | + |
| 47 | + command_result.output |
| 48 | + end |
| 49 | + |
| 50 | + def available?(command) |
| 51 | + execute_command("which #{command} 2>&1").status.success? |
| 52 | + end |
| 53 | + |
| 54 | + def execute_command(command) |
| 55 | + output = `env LC_ALL=C LANG=C #{command}` |
| 56 | + status = $? |
| 57 | + ExecutionResult.new output, status |
| 58 | + end |
| 59 | + |
| 60 | + class ExecutionResult < Struct.new(:output, :status) |
40 | 61 | end |
41 | 62 | end |
42 | 63 | end |
0 commit comments