Skip to content

Commit

Permalink
Merge pull request ruby-llvm#31 from whitequark/llvm-3.3
Browse files Browse the repository at this point in the history
Update for LLVM 3.3.
  • Loading branch information
whitequark committed May 29, 2013
2 parents d09c1a3 + c618712 commit 847292f
Show file tree
Hide file tree
Showing 48 changed files with 547 additions and 419 deletions.
20 changes: 1 addition & 19 deletions README.md
Expand Up @@ -9,7 +9,7 @@ computationally intensive algorithms on the fly.

Requirements
------------
* LLVM 3.2, including libLLVM-3.2 (compile LLVM with --enable-shared).
* LLVM 3.3, including libLLVM-3.3 (compile LLVM with --enable-shared).
* In order to ensure the usability of JIT features (i.e. create_jit_compiler), compile LLVM with --enable-jit as well.

About version numbers
Expand All @@ -24,24 +24,6 @@ Homebrew
--------
LLVM can be installed with Homebrew by executing `brew install llvm --shared`

Caveats:

LLVM 3.2 ships with an unresolved
[bug](http://llvm.org/bugs/show_bug.cgi?id=14715) in which its version string is
"3.2svn" rather than "3.2". Some package maintainers have patched the version
string before building LLVM. The Homebrew maintainers, however, have decided not
to maintain a patch set (see this
[thread](https://github.com/mxcl/homebrew/issues/17034).) Unfortunately, the bug
breaks ruby-llvm's FFI bindings.

A patched formula for LLVM has been created by
[thoughtpolice](https://github.com/thoughtpolice). This formula is unsupported,
but if you would like to give it a shot, use the following command.

```bash
brew install https://raw.github.com/ruby-llvm/ruby-llvm/master/misc/homebrew/llvm.rb --shared --with-clang
```

See Also
--------
* [The LLVM project](http://llvm.org)
Expand Down
29 changes: 12 additions & 17 deletions Rakefile
@@ -1,21 +1,19 @@
require 'rubygems'
require 'bundler/setup'

require 'rake/testtask'
require_relative 'lib/llvm/version.rb'
require 'yard'

begin
require 'yard'
require 'llvm/version'
require 'llvm/config'

YARD::Rake::YardocTask.new do |t|
yardlib = File.join(File.dirname(__FILE__), "yardlib/llvm.rb")
t.options = %W[-e #{yardlib} --no-private]
t.files = Dir['lib/**/*.rb']
end
rescue LoadError
warn "Yard is not installed. `gem install yard' to build documentation."
YARD::Rake::YardocTask.new do |t|
yardlib = File.join(File.dirname(__FILE__), "yardlib/llvm.rb")
t.options = %W[-e #{yardlib} --no-private]
t.files = Dir['lib/**/*.rb']
end

Rake::TestTask.new do |t|
t.libs << "test"
t.libs = %w(test)
t.test_files = FileList["test/**/*_test.rb"]
end

Expand Down Expand Up @@ -43,13 +41,10 @@ task :generate_ffi do
mappings.each do |ruby_file, headers|
FFIGen.generate(
module_name: 'LLVM::C',
ffi_lib: 'LLVM-3.2',
ffi_lib: 'LLVM-3.3',
headers: headers.map { |header| "llvm-c/#{header}" },
cflags: `#{LLVM::LLVM_CONFIG} --cflags`.split,
cflags: LLVM::CONFIG::CFLAGS.split(/\s/),
prefixes: %w(LLVM),
blacklist: %w(LLVMGetMDNodeNumOperands LLVMGetMDNodeOperand
LLVMInitializeAllTargetInfos LLVMInitializeAllTargets
LLVMInitializeNativeTarget),
output: "lib/llvm/#{ruby_file}"
)
end
Expand Down
65 changes: 47 additions & 18 deletions ext/ruby-llvm-support/Rakefile
Expand Up @@ -5,29 +5,54 @@ require 'ffi'
require File.expand_path('../../lib/llvm/version', File.dirname(__FILE__))
include LLVM

def check_llvm_config(name)
actual_version = `#{name} --version`
actual_version.strip == LLVM_VERSION
rescue Errno::ENOENT
false
def check_for(what, variants, env_var)
variants = [ ENV[env_var], *variants ] if ENV.include?(env_var)

$stdout.print("checking for #{what}... ")
$stdout.flush

result = variants.find do |variant|
if yield(variant)
$stdout.puts(variant)
true
end
end

if result
result
else
raise RuntimeError, "Cannot find #{what}: tried #{variants}"
end
end

def invoke_llvm_config(options)
variants = %W(llvm-config-#{LLVM_VERSION} llvm-config)
def find_llvm_config
check_for('llvm-config',
%W(llvm-config-#{LLVM_VERSION} llvm-config),
'LLVM_CONFIG') do |llvm_config|

variants.each do |name|
if check_llvm_config(name)
return `#{name} #{options}`.gsub("\n", " ")
begin
actual_version = `#{llvm_config} --version`.strip

actual_version == LLVM_VERSION
rescue Errno::ENOENT
false
end
end
end

raise RuntimeError, "No valid llvm-config found. Tried: #{variants}"
def find_cxx
check_for('C++ compiler', %W(clang++ g++), 'CXX') do |cxx|
system(cxx, "--version", out: :close, err: :close)
$?.success?
end
end

LLVM_CONFIG = invoke_llvm_config('--cxxflags --ldflags')
LLVM_CONFIG = find_llvm_config
CXX = find_cxx

CXX = "g++"
SRC = "support.cpp"
def invoke_llvm_config(options)
`#{LLVM_CONFIG} #{options}`.gsub("\n", " ")
end

SUPPORT_LIB = FFI.map_library_name("RubyLLVMSupport-#{LLVM_VERSION}")
CONFIG_MOD = File.expand_path('../../lib/llvm/config.rb', File.dirname(__FILE__))
Expand All @@ -37,15 +62,17 @@ CLEAN.include(SUPPORT_LIB, CONFIG_MOD)
desc "Build the shared library and config module"
task :default => [SUPPORT_LIB, CONFIG_MOD]

file SUPPORT_LIB => [SRC] do
sh "#{CXX} -shared -lLLVM-#{LLVM_VERSION} #{SRC} #{LLVM_CONFIG} -o #{SUPPORT_LIB}"
file SUPPORT_LIB => %w(support.cpp) do |task|
sh "#{CXX} -shared -lLLVM-#{LLVM_VERSION} #{task.prerequisites.join(' ')} " \
"#{invoke_llvm_config('--cxxflags --ldflags')} -o #{SUPPORT_LIB}"
end

LLVM_CONFIG_OPTS = [
['COMPONENTS', :array, '--components'],
['TARGETS_BUILT', :array, '--targets-built'],
['HOST_TARGET', :string, '--host-target'],
['BUILD_MODE', :string, '--build-mode'],
['CFLAGS', :string, '--cflags'],
]

file CONFIG_MOD do
Expand All @@ -57,10 +84,12 @@ file CONFIG_MOD do
LLVM_CONFIG_OPTS.each do |(const, fmt, flag)|
case fmt
when :string
f.puts ' ' << const << ' = ' << invoke_llvm_config(flag).strip.inspect
value = invoke_llvm_config(flag)
when :array
f.puts ' ' << const << ' = ' << invoke_llvm_config(flag).strip.split.inspect
value = invoke_llvm_config(flag).split
end

f.puts " #{const} = #{value.inspect}"
end

f.puts ' end'
Expand Down
7 changes: 4 additions & 3 deletions ext/ruby-llvm-support/support.cpp
Expand Up @@ -3,8 +3,9 @@
*/

#include <llvm-c/Core.h>
#include <llvm/Type.h>
#include <llvm/GlobalValue.h>
#include <llvm/IR/Type.h>
#include <llvm/IR/Module.h>
#include <llvm/IR/GlobalValue.h>
#include <llvm/Support/DynamicLibrary.h>
#include <llvm/Support/TargetSelect.h>
#include <llvm/Support/raw_ostream.h>
Expand All @@ -28,7 +29,7 @@ extern "C" {
unwrap<Type>(type)->dump();
}

int LLVMPrintModuleToFD(LLVMModuleRef module, int fd, LLVMBool shouldClose, LLVMBool unbuffered) {
void LLVMPrintModuleToFD(LLVMModuleRef module, int fd, LLVMBool shouldClose, LLVMBool unbuffered) {
raw_fd_ostream os(fd, shouldClose, unbuffered);
unwrap(module)->print(os, 0);
}
Expand Down
4 changes: 2 additions & 2 deletions lib/llvm.rb
@@ -1,13 +1,13 @@
require 'rubygems'
require 'ffi'

module LLVM
require 'llvm/version'
require 'llvm/support'

# @private
module C
extend ::FFI::Library
ffi_lib ['LLVM-3.2']
ffi_lib ["LLVM-#{LLVM_VERSION}"]
end

module PointerIdentity
Expand Down
2 changes: 1 addition & 1 deletion lib/llvm/analysis_ffi.rb
Expand Up @@ -4,7 +4,7 @@

module LLVM::C
extend FFI::Library
ffi_lib 'LLVM-3.2'
ffi_lib 'LLVM-3.3'

def self.attach_function(name, *_)
begin; super; rescue FFI::NotFoundError => e
Expand Down
2 changes: 1 addition & 1 deletion lib/llvm/core/bitcode_ffi.rb
Expand Up @@ -4,7 +4,7 @@

module LLVM::C
extend FFI::Library
ffi_lib 'LLVM-3.2'
ffi_lib 'LLVM-3.3'

def self.attach_function(name, *_)
begin; super; rescue FFI::NotFoundError => e
Expand Down

0 comments on commit 847292f

Please sign in to comment.