Skip to content
Open
103 changes: 99 additions & 4 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
require 'rake/gempackagetask'
require 'rubygems/package_task'
require 'rake/testtask'

LLVM_TARGET_VERSION = '2.9'

begin
require 'rcov/rcovtask'

Expand Down Expand Up @@ -37,21 +39,114 @@ def spec
s.files = Dir['lib/**/*rb']
s.require_path = 'lib'

s.has_rdoc = true
s.extra_rdoc_files = 'README.rdoc'

s.extensions << 'ext/LLVM-EB/extconf.rb'

s.author = "Jeremy Voorhis"
s.email = "jvoorhis@gmail.com"
s.homepage = "http://github.com/jvoorhis/ruby-llvm"
end
end

Rake::GemPackageTask.new(spec) do |t|
end
Gem::PackageTask.new(spec)

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

task :check_bindings, :verbose do |t, args|
(args = args.to_hash)[:verbose] = if args[:verbose] == 'true' then true else false end

require 'lib/llvm/bindings'

# Check for objdump.
if not (bin = `which objdump`.chomp)[0,1] == '/'
puts 'objdump binary not found.'
return
end

# Locate the LLVM shared library.
lib_path = nil

paths = ENV['LD_LIBRARY_PATH'].split(/:/).uniq
paths << '/usr/lib/'
paths << '/usr/lib64/'

paths.each do |path|
test_path = File.join(path, "libLLVM-#{LLVM_TARGET_VERSION}.so")
if File.exists?(test_path)
lib_path = test_path
end
end

if not lib_path
puts "libLLVM-#{LLVM_TARGET_VERSION}.so not found."
return
end

# Grab libLLVM symbols.
lines = `#{bin} -t #{lib_path}`

lsyms = lines.map do |l|
md = l.match(/\s(LLVM\w+)/)
if md then md[1] else nil end
end.compact.uniq

# Grab libLLVM-EB symbols.
lib_path = "ext/libLLVM-EB-#{LLVM_TARGET_VERSION}.so"

if not File.exists?(lib_path)
puts 'Extending Bindings shared library not present.'
return
end

lines = `#{bin} -t #{lib_path}`

lsyms |= lsyms = lines.map do |l|
md = l.match(/\s(LLVM\w+)/)
if md then md[1] else nil end
end.compact.uniq

# Defined symbols.
dsyms = Symbol.all_symbols.map do |sym|
sym = sym.to_s
if sym.match(/^LLVM[a-zA-Z]+/) then sym else nil end
end.compact

# Sort the symbols.
bound = Array.new
unbound = Array.new
unbinds = Array.new

lsyms.each do |sym|
if dsyms.include?(sym) then bound else unbound end << sym
end

dsyms.each do |sym|
if not lsyms.include?(sym) then unbinds << sym end
end

puts "Bound Functions: #{bound.length}"
puts "Unbound Functions: #{unbound.length}"
puts "Bad Bindings: #{unbinds.length}"
puts "Completeness: #{((bound.length / lsyms.length.to_f) * 100).to_i}%"

if args[:verbose]
puts() if unbound.length > 0 and unbinds.length > 0

if unbound.length > 0
puts 'Unbound Functions:'
unbound.sort.each {|sym| puts sym}
puts
end

if unbinds.length > 0
puts 'Bad Bindings:'
unbinds.sort.each {|sym| puts sym}
end
end
end

task :default => [:test]
157 changes: 157 additions & 0 deletions ext/LLVM-EB/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@

SHELL = /bin/sh

#### Start of system configuration section. ####

srcdir = .
topdir = /usr/lib64/ruby/1.8/x86_64-linux
hdrdir = $(topdir)
VPATH = $(srcdir):$(topdir):$(hdrdir)
exec_prefix = $(DESTDIR)/usr
prefix = $(DESTDIR)/usr
sharedstatedir = $(DESTDIR)/var/lib
mandir = $(DESTDIR)/usr/share/man
psdir = $(docdir)
oldincludedir = $(DESTDIR)/usr/include
localedir = $(datarootdir)/locale
bindir = $(DESTDIR)/usr/bin
libexecdir = $(DESTDIR)/usr/libexec
sitedir = $(DESTDIR)/usr/lib/ruby/site_ruby
htmldir = $(docdir)
vendorarchdir = $(libdir)/ruby/$(ruby_version)/$(sitearch)
includedir = $(DESTDIR)/usr/include
infodir = $(DESTDIR)/usr/share/info
vendorlibdir = $(vendordir)/$(ruby_version)
sysconfdir = $(DESTDIR)/etc
libdir = $(DESTDIR)/usr/lib64
sbindir = $(DESTDIR)/usr/sbin
rubylibdir = $(vendordir)/$(ruby_version)
docdir = $(datarootdir)/doc/$(PACKAGE)
dvidir = $(docdir)
vendordir = $(DESTDIR)/usr/lib/ruby
datarootdir = $(prefix)/share
pdfdir = $(docdir)
archdir = $(libdir)/ruby/$(ruby_version)/$(sitearch)
sitearchdir = $(libdir)/ruby/site_ruby/$(ruby_version)/$(sitearch)
datadir = $(DESTDIR)/usr/share
localstatedir = $(DESTDIR)/var
sitelibdir = $(sitedir)/$(ruby_version)

CC = gcc
LIBRUBY = $(LIBRUBY_SO)
LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a
LIBRUBYARG_SHARED = -l$(RUBY_SO_NAME)
LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)-static

RUBY_EXTCONF_H =
CFLAGS = -fPIC -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -fno-strict-aliasing -fPIC $(cflags)-Wall -O3 -fPIC
INCFLAGS = -I. -I. -I/usr/lib64/ruby/1.8/x86_64-linux -I.
DEFS =
CPPFLAGS =
CXXFLAGS = $(CFLAGS)
ldflags = -I LLVM-2.9 -o libLLVM-EB-2.9.so
dldflags =
archflag =
DLDFLAGS = $(ldflags) $(dldflags) $(archflag)
LDSHARED = $(CC) -shared
AR = ar
EXEEXT =

RUBY_INSTALL_NAME = ruby
RUBY_SO_NAME = ruby
arch = x86_64-linux
sitearch = x86_64-linux
ruby_version = 1.8
ruby = /usr/bin/ruby
RUBY = $(ruby)
RM = rm -f
MAKEDIRS = mkdir -p
INSTALL = /usr/bin/install -c
INSTALL_PROG = $(INSTALL) -m 0755
INSTALL_DATA = $(INSTALL) -m 644
COPY = cp

#### End of system configuration section. ####

preload =

libpath = . $(libdir)
LIBPATH = -L. -L$(libdir)
DEFFILE =

CLEANFILES = mkmf.log
DISTCLEANFILES =

extout =
extout_prefix =
target_prefix =
LOCAL_LIBS =
LIBS = $(LIBRUBYARG_SHARED) -lLLVM-2.9 -lpthread -lrt -ldl -lcrypt -lm -lc
SRCS = support.cpp
OBJS = support.o
TARGET = LLVM-EB
DLLIB = $(TARGET).so
EXTSTATIC =
STATIC_LIB =

BINDIR = $(bindir)
RUBYCOMMONDIR = $(sitedir)$(target_prefix)
RUBYLIBDIR = $(sitelibdir)$(target_prefix)
RUBYARCHDIR = $(sitearchdir)$(target_prefix)

TARGET_SO = $(DLLIB)
CLEANLIBS = $(TARGET).so $(TARGET).il? $(TARGET).tds $(TARGET).map
CLEANOBJS = *.o *.a *.s[ol] *.pdb *.exp *.bak

all: $(DLLIB)
static: $(STATIC_LIB)

clean:
@-$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES)

distclean: clean
@-$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
@-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES)

realclean: distclean
install: install-so install-rb

install-so: $(RUBYARCHDIR)
install-so: $(RUBYARCHDIR)/$(DLLIB)
$(RUBYARCHDIR)/$(DLLIB): $(DLLIB)
$(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR)
install-rb: pre-install-rb install-rb-default
install-rb-default: pre-install-rb-default
pre-install-rb: Makefile
pre-install-rb-default: Makefile
$(RUBYARCHDIR):
$(MAKEDIRS) $@

site-install: site-install-so site-install-rb
site-install-so: install-so
site-install-rb: install-rb

.SUFFIXES: .c .m .cc .cxx .cpp .C .o

.cc.o:
$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<

.cxx.o:
$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<

.cpp.o:
$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<

.C.o:
$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<

.c.o:
$(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) -c $<

$(DLLIB): $(OBJS) Makefile
@-$(RM) $@
$(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)



$(OBJS): ruby.h defines.h
11 changes: 11 additions & 0 deletions ext/LLVM-EB/extconf.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
require 'mkmf'

extname = 'LLVM-EB'

have_library('LLVM-2.9')

$CFLAGS << '-Wall -O3 -fPIC'
$LDFLAGS = '-I LLVM-2.9 -o libLLVM-EB-2.9.so'

dir_config(extname)
create_makefile(extname)
11 changes: 11 additions & 0 deletions ext/LLVM-EB/support.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
* Extended bindings for LLVM.
*/

#include <llvm/Support/DynamicLibrary.h>

extern "C" {
int LLVMLoadLibraryPermanently(const char* filename) {
return llvm::sys::DynamicLibrary::LoadLibraryPermanently(filename);
}
}
20 changes: 20 additions & 0 deletions ext/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
LLVM_VERSION = 2.9

CXX = g++
CFLAGS = -O3 -fPIC
LIBFLAGS = -shared -Wl,-soname,libLLVM-EB-$(LLVM_VERSION).so

LIBS = /usr/local/lib/libLLVMSupport.a

all: libLLVM-EB.so

libLLVM-EB.so: support.o
$(CXX) $(CFLAGS) $(LIBFLAGS) -o libLLVM-EB-$(LLVM_VERSION).so support.o $(LIBS)

support.o: support.cpp
$(CXX) $(CFLAGS) -c $<

.PHONY: clean
clean:
rm -f *.o
rm -f *.so
11 changes: 11 additions & 0 deletions ext/support.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
* Extended bindings for LLVM.
*/

#include <llvm/Support/DynamicLibrary.h>

extern "C" {
int LLVMLoadLibraryPermanently(const char* filename) {
return llvm::sys::DynamicLibrary::LoadLibraryPermanently(filename);
}
}
13 changes: 3 additions & 10 deletions lib/llvm.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
require 'rubygems'
require 'ffi'

module LLVM
# @private
module C
extend ::FFI::Library

# load required libraries
ffi_lib ['LLVM-2.9', 'libLLVM-2.9']
end
autoload :Analysis, 'llvm/analysis'
autoload :Core, 'llvm/core'
autoload :ExecutionEngine, 'llvm/execution_engine'
end
13 changes: 0 additions & 13 deletions lib/llvm/analysis.rb
Original file line number Diff line number Diff line change
@@ -1,20 +1,7 @@
require 'llvm'
require 'llvm/core'
require 'llvm/target'

module LLVM
# @private
module C
enum :verifier_failure_action, [
:abort_process,
:print_message,
:return_status
]

attach_function :LLVMVerifyModule, [:pointer, :verifier_failure_action, :pointer], :int
attach_function :LLVMVerifyFunction, [:pointer, :verifier_failure_action], :int
end

class Module
# Verify that the module is valid.
# @return [nil, String] human-readable description of any invalid
Expand Down
Loading