hubris 0.0.3 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +31 -0
- data/.rvmrc +2 -0
- data/Gemfile +11 -0
- data/Haskell/Hubrify.hs +69 -0
- data/Haskell/LICENSE +22 -0
- data/Haskell/Language/Ruby/Foo.hs +20 -0
- data/Haskell/Language/Ruby/Hubris/Binding.hsc +214 -0
- data/Haskell/Language/Ruby/Hubris/GHCBuild.hs +46 -0
- data/Haskell/Language/Ruby/Hubris/Hash.hs +27 -0
- data/Haskell/Language/Ruby/Hubris/Interpolator.hs +22 -0
- data/Haskell/Language/Ruby/Hubris/LibraryBuilder.hs +181 -0
- data/Haskell/Language/Ruby/Hubris/ZCode.hs +68 -0
- data/Haskell/Language/Ruby/Hubris.hs +254 -0
- data/Haskell/Language/Ruby/Wrappers.hs +32 -0
- data/Haskell/Language/Ruby/testLib.hs +9 -0
- data/Haskell/Setup.hs +31 -0
- data/Haskell/cbits/rshim.c +46 -0
- data/Haskell/cbits/rshim.h +50 -0
- data/Haskell/hubris.cabal +53 -0
- data/INSTALL +21 -0
- data/Manifest.txt +22 -0
- data/PostInstall.txt +1 -0
- data/README.markdown +107 -0
- data/Rakefile +46 -43
- data/VERSION +1 -0
- data/doc/CommonErrors.txt +18 -0
- data/doc/CommonErrors.txt~HEAD +18 -0
- data/doc/don_feedback.txt +25 -0
- data/doc/haskell-hubris.tex +242 -0
- data/doc/new_interface.rb +74 -0
- data/doc/ruby-hubris.tex +176 -0
- data/doc/wisdom_of_ancients.txt +55 -0
- data/ext/hubris.rb +4 -0
- data/ext/stub/extconf.rb +5 -0
- data/ext/{HubrisStubLoader.c → stub/stub.c} +1 -1
- data/hubris.gemspec +31 -0
- data/lib/Makefile +181 -0
- data/lib/hubris/version.rb +3 -0
- data/lib/hubris.rb +16 -13
- data/rspec.rake +21 -0
- data/sample/Fibonacci.hs +2 -2
- data/sample/config.ru +3 -1
- data/script/ci.sh +25 -0
- data/script/console +10 -0
- data/spec/hubris_spec.rb +173 -47
- data/tasks/extconf/stub.rake +43 -0
- data/tasks/extconf.rake +13 -0
- metadata +118 -27
- data/ext/extconf.rb +0 -5
data/doc/ruby-hubris.tex
ADDED
@@ -0,0 +1,176 @@
|
|
1
|
+
% Local Variables:
|
2
|
+
% compile-command: "/opt/local/bin/pdflatex fp-syd.tex && open fp-syd.pdf"
|
3
|
+
% End:
|
4
|
+
|
5
|
+
\documentclass{beamer}
|
6
|
+
\usepackage{listings}
|
7
|
+
\usepackage{beamerthemesplit}
|
8
|
+
|
9
|
+
\title{Hubris}
|
10
|
+
\subtitle{subjecting Haskell to Ruby's iron will}
|
11
|
+
\author{Mark Wotton \textless mwotton@shimweasel.com\textgreater}
|
12
|
+
\date{\today}
|
13
|
+
|
14
|
+
\begin{document}
|
15
|
+
\lstset{language=Haskell}
|
16
|
+
\section{Two cultures}
|
17
|
+
\frame{\titlepage}
|
18
|
+
|
19
|
+
% \subsection
|
20
|
+
\begin{frame}
|
21
|
+
\frametitle{I \ding{170} Ruby}
|
22
|
+
\begin{itemize}
|
23
|
+
\item concise and flexible
|
24
|
+
\item Big web community, many libraries
|
25
|
+
\item Fun
|
26
|
+
\end{itemize}
|
27
|
+
\end{frame}
|
28
|
+
|
29
|
+
|
30
|
+
|
31
|
+
\begin{frame}
|
32
|
+
\frametitle{I \ding{170} Haskell}
|
33
|
+
\begin{itemize}
|
34
|
+
\item<1-> Fast (optimised native code, multicore, etc)
|
35
|
+
\item<2-> Expressive - type systems don't have to suck.
|
36
|
+
\item<3-> Provably safe at compile time
|
37
|
+
\end{itemize}
|
38
|
+
\end{frame}
|
39
|
+
|
40
|
+
|
41
|
+
\subsection{lies, damn lies, benchmarks}
|
42
|
+
\begin{frame}
|
43
|
+
\frametitle{the slide that's going to get me lynched}
|
44
|
+
\center{JRuby vs GHC}
|
45
|
+
\begin{tabular}{l l l l}
|
46
|
+
Program & Time &Memory & Source Size\\ \hline
|
47
|
+
reverse-complement &5 &1 &1/4\\
|
48
|
+
regex-dna &7 &3 &1/5\\
|
49
|
+
binary-trees &8 &7 &1 \\
|
50
|
+
k-nucleotide &10 &1 &1/7 \\
|
51
|
+
pidigits &18 &18 &2 \\
|
52
|
+
n-body &26 &53 &1 \\
|
53
|
+
chameneos-redux &30 &24 &1 \\
|
54
|
+
fasta &31 &142 &1 \\
|
55
|
+
fannkuch &45 &22 &1/4 \\
|
56
|
+
spectral-norm &227 &56 &1/3 \\
|
57
|
+
mandelbrot &319 &3 &1/2\\
|
58
|
+
\end{tabular}
|
59
|
+
\end{frame}
|
60
|
+
|
61
|
+
\begin{frame}
|
62
|
+
\frametitle{319 times? Really?}
|
63
|
+
\begin{itemize}
|
64
|
+
\item<1-> Haskell code written by expert hackers
|
65
|
+
\item<2-> Longer in some cases - gone hard on optimisations
|
66
|
+
even when they blow out source code size. But...
|
67
|
+
\item <3-> 319 times faster, 1/3 the memory.
|
68
|
+
\end{itemize}
|
69
|
+
\end{frame}
|
70
|
+
|
71
|
+
\subsection{problems with Haskell}
|
72
|
+
\begin{frame}
|
73
|
+
\frametitle{more lies to outrage Myles}
|
74
|
+
\setlength\parskip{0.1in}
|
75
|
+
there are approximately twelve programmers in the world who know Haskell
|
76
|
+
|
77
|
+
Nine are working on four different compilers with extensions for
|
78
|
+
solving logic puzzles in the type system (not kidding, google
|
79
|
+
``haskell instant insanity'')
|
80
|
+
|
81
|
+
The other three are working on six different web frameworks
|
82
|
+
\end{frame}
|
83
|
+
|
84
|
+
\section{Hubris}
|
85
|
+
\begin{frame}
|
86
|
+
\frametitle{Peanut butter, meet chocolate}
|
87
|
+
Ruby has a heap of web frameworks, convenience libraries, well-tested
|
88
|
+
integration with javascript + CSS
|
89
|
+
\setlength\parskip{0.25in}
|
90
|
+
|
91
|
+
Haskell is smoking fast with rock solid type safety but a tiny
|
92
|
+
community
|
93
|
+
|
94
|
+
Hubris is my bridge between the two
|
95
|
+
\end{frame}
|
96
|
+
|
97
|
+
\subsection{Haskell example}
|
98
|
+
\begin{frame}[fragile]
|
99
|
+
\frametitle{lazy, statically typed, and pure}
|
100
|
+
\begin{lstlisting}
|
101
|
+
clMax lim = maximumBy (comparing snd) (assocs arr)
|
102
|
+
where arr = listArray (1,lim)
|
103
|
+
(0:(map depth [2..]))
|
104
|
+
step x = if even x
|
105
|
+
then div x 2
|
106
|
+
else 3 * x + 1
|
107
|
+
depth x = 1 + if n <= lim
|
108
|
+
then arr ! n
|
109
|
+
else depth n
|
110
|
+
where n = step x
|
111
|
+
\end{lstlisting}
|
112
|
+
\end{frame}
|
113
|
+
|
114
|
+
|
115
|
+
\subsection{wrap it in Ruby}
|
116
|
+
\begin{frame}[fragile]
|
117
|
+
\frametitle{actually using it}
|
118
|
+
\lstset{language=Ruby}
|
119
|
+
\begin{lstlisting}
|
120
|
+
require Hubris # my favourite line
|
121
|
+
c = Collatz.new # any ruby object
|
122
|
+
c.inline(haskell_string) # from above
|
123
|
+
puts c.clMax(1000000)
|
124
|
+
>> 837799
|
125
|
+
\end{lstlisting}
|
126
|
+
\end{frame}
|
127
|
+
|
128
|
+
% \frametitle{Predictive}
|
129
|
+
\section{TODO, gotchas, FIXME}
|
130
|
+
\begin{frame}
|
131
|
+
\setlength\parskip{0.1in}
|
132
|
+
\frametitle{Making it less sucky}
|
133
|
+
Needs to use jhc, because ghc can't produce dynamic libs right now
|
134
|
+
(works with GHC HEAD, will be compatible with 6.12)
|
135
|
+
|
136
|
+
one-way bridge, no callbacks to Ruby
|
137
|
+
|
138
|
+
a smarter mapping layer
|
139
|
+
|
140
|
+
caching of Haskell binaries
|
141
|
+
|
142
|
+
cleanup of ruby interface
|
143
|
+
|
144
|
+
shore up support for arrays, hashes, BigInts
|
145
|
+
|
146
|
+
autoconf support to find ruby libs and includes
|
147
|
+
|
148
|
+
... lots to do
|
149
|
+
\end{frame}
|
150
|
+
|
151
|
+
|
152
|
+
\begin{frame}
|
153
|
+
\frametitle{Try it out!}
|
154
|
+
install GHC and JHC
|
155
|
+
|
156
|
+
git clone git://github.com/mwotton/Hubris.git
|
157
|
+
|
158
|
+
follow the README
|
159
|
+
|
160
|
+
tell me what's missing
|
161
|
+
|
162
|
+
patches very much welcome (thanks to Josh Price, James Britt and Tatsuhiro Ujihisa)
|
163
|
+
\end{frame}
|
164
|
+
|
165
|
+
|
166
|
+
\begin{frame}
|
167
|
+
\frametitle{Learning Haskell}
|
168
|
+
Learn You A Haskell: why the lucky stiff's academic cousin
|
169
|
+
|
170
|
+
Real World Haskell: awesome, practical introduction
|
171
|
+
|
172
|
+
haskell channel on freenode
|
173
|
+
|
174
|
+
beginners@haskell.org
|
175
|
+
\end{frame}
|
176
|
+
\end{document}
|
@@ -0,0 +1,55 @@
|
|
1
|
+
15:31 < mmorrow> blackdog: i think it's a matter of each .so having the correct list of .so's that its dependent on included within it,
|
2
|
+
which (i'm not positive why) ghc doesn't currently do/have-done
|
3
|
+
15:31 -!- Saizan [n=saizan@host19-23-dynamic.9-79-r.retail.telecomitalia.it] has quit [Read error: 110 (Connection timed out)]
|
4
|
+
15:32 < mmorrow> blackdog: so i think if you can manage to add this info to your .so files, you'd be ok. i'm not sure about what the
|
5
|
+
options are to accomplish this though (maybe ld has some options to modify .so's)
|
6
|
+
15:32 < mmorrow> i don't recall the name of the field for ELF, but iirc it's DEPENDS or something like that
|
7
|
+
15:35 < blackdog> so if i want to depend on a standard installed package, i'd have to fiddle with the .so files that are being built so
|
8
|
+
it knows its dependencies too?
|
9
|
+
15:36 < blackdog> i think i need .hi files as well - i need to do some reflection on the interface
|
10
|
+
15:39 -!- Saizan [n=saizan@host86-241-static.12-87-b.business.telecomitalia.it] has joined #ghc
|
11
|
+
15:48 -!- blackh [n=blackh@125-236-232-55.adsl.xtra.co.nz] has quit [Read error: 110 (Connection timed out)]
|
12
|
+
15:50 -!- blackh [n=blackh@125-236-232-55.adsl.xtra.co.nz] has joined #ghc
|
13
|
+
15:54 -!- Saizan_ [n=saizan@host241-26-dynamic.9-79-r.retail.telecomitalia.it] has quit [Read error: 110 (Connection timed out)]
|
14
|
+
16:37 -!- dolio [n=dolio@nr22-66-161-253-70.fuse.net] has quit [Read error: 104 (Connection reset by peer)]
|
15
|
+
16:41 -!- dolio [n=dolio@nr22-66-161-253-70.fuse.net] has joined #ghc
|
16
|
+
16:46 < mmorrow> blackdog: yeah, fixing the .so files to have the dependency info they should have would fix the linking problem, but
|
17
|
+
if you don't know anything about the code you're dlopen()'ing (and you wanted/needed to), you'd need to decode .hi
|
18
|
+
files
|
19
|
+
16:46 < mmorrow> blackdog: which you'd need to use the ghc-api for
|
20
|
+
16:47 < mmorrow> blackdog: the old hs-plugins code that had its own .hi parser is bitrotted
|
21
|
+
16:47 < mmorrow> since the binary format for .hi files is unstable
|
22
|
+
16:50 < mmorrow> blackdog: although i suppose you could "extract" from ghc what you'd need to decode .hi files, and the associated data
|
23
|
+
decls for the contents thereof/etc to avert linking ghc into you app (that'd be nice if the ghc-api itself was in a
|
24
|
+
.so..)
|
25
|
+
16:54 -!- Saizan_ [n=saizan@host27-5-dynamic.9-79-r.retail.telecomitalia.it] has joined #ghc
|
26
|
+
17:07 < blackdog> mmorrow: thanks, that's useful to know. i won't rely wholly on hs-plugins, then
|
27
|
+
17:09 < blackdog> so if I want to be able to do it without an installed ghc, I'd better build a .so myself that can do whatever munging
|
28
|
+
I need, then just embed the dependencies into that and just ship .so files
|
29
|
+
17:10 -!- Saizan [n=saizan@host86-241-static.12-87-b.business.telecomitalia.it] has quit [Read error: 110 (Connection timed out)]
|
30
|
+
17:10 < blackdog> what would be the semantics of dlopen-ing two haskell .so files and calling them concurrently from C? will horrible
|
31
|
+
things happen?
|
32
|
+
17:11 < mmorrow> oh, calling them from C.. hmm, i'm not positive.
|
33
|
+
17:12 < mmorrow> i know each module has a module init area, where there a .long/.quad in .data that's either 0 or 1, and initializing a
|
34
|
+
module amounts to jumping to some label in that area, and a module will recursively initialize all mods it depends on
|
35
|
+
17:13 < mmorrow> i'm not sure exactly though what the deal is if you've got an rts instance, say, then you dlopen a few haskell .so's
|
36
|
+
from C
|
37
|
+
17:14 < blackdog> do you know who would know? it's a difficult thing to test for, it might work fine for a million tests then launch
|
38
|
+
the missiles on the next
|
39
|
+
17:14 < mmorrow> blackdog: re: building an .so yourself, aside from ensuring there's the needed .so dep info in the dynamic section (or
|
40
|
+
whatever), i guess you could go about embedding type/etc info in two ways/at two different levels
|
41
|
+
17:15 < mmorrow> the first level being to add that info to each module (say in "interface :: Map String Info"), or alternatively (and
|
42
|
+
probably epic) would be to embed that info in the .so file itself somewhere
|
43
|
+
17:15 < mmorrow> e.g. ELF has NOTE sections..
|
44
|
+
17:15 < blackdog> i think i can probably get away with a bit less information
|
45
|
+
17:15 < mmorrow> but that would mean you'd need to parse the object files themselves ..
|
46
|
+
17:16 < mmorrow> blackdog: i'd ask JaffaCake about this
|
47
|
+
17:16 < mmorrow> if anyone knew what you need to do/what could do wrong i'd say it'd be him
|
48
|
+
17:17 -!- bos [n=bos@67.188.108.77] has quit [Read error: 145 (Connection timed out)]
|
49
|
+
17:18 < blackdog> well, i can write a program that uses the ghc-api at compile time to get a list of the identifiers in a given module,
|
50
|
+
with their types. I can then filter out the identifiers that don't fit my scheme, and create an SO with the minimal
|
51
|
+
info i need to call it from outside
|
52
|
+
17:18 < blackdog> at that stage, the types will be exactly the same, all i need is the names of the wrapper functions
|
53
|
+
17:18 < mmorrow> blackdog: totally, that sounds do-able
|
54
|
+
17:18 < mmorrow> right
|
55
|
+
17:18 < blackdog> ok, cool. thanks for helping me vet my logic:)
|
data/ext/hubris.rb
ADDED
data/ext/stub/extconf.rb
ADDED
data/hubris.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "hubris/version"
|
4
|
+
require 'rake'
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "hubris"
|
8
|
+
s.version = Hubris::VERSION
|
9
|
+
s.platform = Gem::Platform::RUBY
|
10
|
+
s.authors = ["Mark Wotton", "James Britt", "Josh Price"]
|
11
|
+
s.email = ["mwotton@gmail.com"]
|
12
|
+
s.homepage = "http://rubygems.org/gems/hubris"
|
13
|
+
s.summary = %q{A bridge between Ruby and Haskell}
|
14
|
+
s.description = %q{A bridge between Ruby and Haskell}
|
15
|
+
|
16
|
+
s.rubyforge_project = "Hubris"
|
17
|
+
|
18
|
+
s.files = `git ls-files`.split("\n")
|
19
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
20
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
21
|
+
|
22
|
+
s.require_paths = ["lib"]
|
23
|
+
|
24
|
+
s.add_dependency 'rake-compiler', '>= 0.7.6'
|
25
|
+
s.add_development_dependency 'rspec', '2.4.0'
|
26
|
+
s.add_dependency 'rake'
|
27
|
+
s.add_dependency 'open4'
|
28
|
+
s.extensions = 'Rakefile' # ext/mkrf_conf.rb'
|
29
|
+
# system "bundle exec rake compile"
|
30
|
+
# Rake::Task['compile'].invoke
|
31
|
+
end
|
data/lib/Makefile
ADDED
@@ -0,0 +1,181 @@
|
|
1
|
+
|
2
|
+
SHELL = /bin/sh
|
3
|
+
|
4
|
+
#### Start of system configuration section. ####
|
5
|
+
|
6
|
+
srcdir = .
|
7
|
+
topdir = /opt/local/include/ruby-1.9.1
|
8
|
+
hdrdir = /opt/local/include/ruby-1.9.1
|
9
|
+
arch_hdrdir = /opt/local/include/ruby-1.9.1/$(arch)
|
10
|
+
VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby
|
11
|
+
prefix = $(DESTDIR)/opt/local
|
12
|
+
exec_prefix = $(prefix)
|
13
|
+
vendorhdrdir = $(rubyhdrdir)/vendor_ruby
|
14
|
+
sitehdrdir = $(rubyhdrdir)/site_ruby
|
15
|
+
rubyhdrdir = $(includedir)/$(RUBY_INSTALL_NAME)-$(ruby_version)
|
16
|
+
vendordir = $(libdir)/$(RUBY_INSTALL_NAME)/vendor_ruby
|
17
|
+
sitedir = $(libdir)/$(RUBY_INSTALL_NAME)/site_ruby
|
18
|
+
mandir = $(DESTDIR)/opt/local/share/man
|
19
|
+
localedir = $(datarootdir)/locale
|
20
|
+
libdir = $(exec_prefix)/lib
|
21
|
+
psdir = $(docdir)
|
22
|
+
pdfdir = $(docdir)
|
23
|
+
dvidir = $(docdir)
|
24
|
+
htmldir = $(docdir)
|
25
|
+
infodir = $(datarootdir)/info
|
26
|
+
docdir = $(datarootdir)/doc/$(PACKAGE)
|
27
|
+
oldincludedir = $(DESTDIR)/usr/include
|
28
|
+
includedir = $(prefix)/include
|
29
|
+
localstatedir = $(prefix)/var
|
30
|
+
sharedstatedir = $(prefix)/com
|
31
|
+
sysconfdir = $(prefix)/etc
|
32
|
+
datadir = $(datarootdir)
|
33
|
+
datarootdir = $(prefix)/share
|
34
|
+
libexecdir = $(exec_prefix)/libexec
|
35
|
+
sbindir = $(exec_prefix)/sbin
|
36
|
+
bindir = $(exec_prefix)/bin
|
37
|
+
rubylibdir = $(libdir)/$(ruby_install_name)/$(ruby_version)
|
38
|
+
archdir = $(rubylibdir)/$(arch)
|
39
|
+
sitelibdir = $(sitedir)/$(ruby_version)
|
40
|
+
sitearchdir = $(sitelibdir)/$(sitearch)
|
41
|
+
vendorlibdir = $(vendordir)/$(ruby_version)
|
42
|
+
vendorarchdir = $(vendorlibdir)/$(sitearch)
|
43
|
+
|
44
|
+
CC = /usr/bin/gcc-4.0
|
45
|
+
CXX = /usr/bin/g++-4.0
|
46
|
+
LIBRUBY = $(LIBRUBY_SO)
|
47
|
+
LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a
|
48
|
+
LIBRUBYARG_SHARED = -l$(RUBY_SO_NAME)
|
49
|
+
LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)-static
|
50
|
+
OUTFLAG = -o
|
51
|
+
COUTFLAG = -o
|
52
|
+
|
53
|
+
RUBY_EXTCONF_H =
|
54
|
+
cflags = $(optflags) $(debugflags) $(warnflags)
|
55
|
+
optflags = -O2
|
56
|
+
debugflags = -g
|
57
|
+
warnflags = -Wall -Wno-parentheses
|
58
|
+
CFLAGS = -fno-common -O2 $(cflags) -fno-common -pipe -fno-common
|
59
|
+
INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir)
|
60
|
+
DEFS =
|
61
|
+
CPPFLAGS = -I/opt/local/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE $(DEFS) $(cppflags)
|
62
|
+
CXXFLAGS = $(CFLAGS) -O2 $(cxxflags)
|
63
|
+
ldflags = -L. -L/opt/local/lib -L/usr/local/lib
|
64
|
+
dldflags =
|
65
|
+
archflag =
|
66
|
+
DLDFLAGS = $(ldflags) $(dldflags) $(archflag)
|
67
|
+
LDSHARED = cc -dynamic -bundle -undefined suppress -flat_namespace
|
68
|
+
LDSHAREDXX = $(LDSHARED)
|
69
|
+
AR = ar
|
70
|
+
EXEEXT =
|
71
|
+
|
72
|
+
RUBY_INSTALL_NAME = ruby
|
73
|
+
RUBY_SO_NAME = ruby
|
74
|
+
arch = i386-darwin9
|
75
|
+
sitearch = i386-darwin9
|
76
|
+
ruby_version = 1.9.1
|
77
|
+
ruby = /opt/local/bin/ruby
|
78
|
+
RUBY = $(ruby)
|
79
|
+
RM = rm -f
|
80
|
+
RM_RF = $(RUBY) -run -e rm -- -rf
|
81
|
+
RMDIRS = $(RUBY) -run -e rmdir -- -p
|
82
|
+
MAKEDIRS = mkdir -p
|
83
|
+
INSTALL = /usr/bin/install -c
|
84
|
+
INSTALL_PROG = $(INSTALL) -m 0755
|
85
|
+
INSTALL_DATA = $(INSTALL) -m 644
|
86
|
+
COPY = cp
|
87
|
+
|
88
|
+
#### End of system configuration section. ####
|
89
|
+
|
90
|
+
preload =
|
91
|
+
|
92
|
+
libpath = . $(libdir)
|
93
|
+
LIBPATH = -L. -L$(libdir)
|
94
|
+
DEFFILE =
|
95
|
+
|
96
|
+
CLEANFILES = mkmf.log
|
97
|
+
DISTCLEANFILES =
|
98
|
+
DISTCLEANDIRS =
|
99
|
+
|
100
|
+
extout =
|
101
|
+
extout_prefix =
|
102
|
+
target_prefix =
|
103
|
+
LOCAL_LIBS =
|
104
|
+
LIBS = $(LIBRUBYARG_SHARED) -lpthread -ldl -lobjc
|
105
|
+
SRCS = HubrisStubLoader.c
|
106
|
+
OBJS = HubrisStubLoader.o
|
107
|
+
TARGET = HubrisStubLoader
|
108
|
+
DLLIB = $(TARGET).bundle
|
109
|
+
EXTSTATIC =
|
110
|
+
STATIC_LIB =
|
111
|
+
|
112
|
+
BINDIR = $(bindir)
|
113
|
+
RUBYCOMMONDIR = $(sitedir)$(target_prefix)
|
114
|
+
RUBYLIBDIR = $(sitelibdir)$(target_prefix)
|
115
|
+
RUBYARCHDIR = $(sitearchdir)$(target_prefix)
|
116
|
+
HDRDIR = $(rubyhdrdir)/ruby$(target_prefix)
|
117
|
+
ARCHHDRDIR = $(rubyhdrdir)/$(arch)/ruby$(target_prefix)
|
118
|
+
|
119
|
+
TARGET_SO = $(DLLIB)
|
120
|
+
CLEANLIBS = $(TARGET).bundle
|
121
|
+
CLEANOBJS = *.o *.bak
|
122
|
+
|
123
|
+
all: $(DLLIB)
|
124
|
+
static: $(STATIC_LIB)
|
125
|
+
|
126
|
+
clean-rb-default::
|
127
|
+
clean-rb::
|
128
|
+
clean-so::
|
129
|
+
clean: clean-so clean-rb-default clean-rb
|
130
|
+
@-$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES)
|
131
|
+
|
132
|
+
distclean-rb-default::
|
133
|
+
distclean-rb::
|
134
|
+
distclean-so::
|
135
|
+
distclean: clean distclean-so distclean-rb-default distclean-rb
|
136
|
+
@-$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
|
137
|
+
@-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES)
|
138
|
+
@-$(RMDIRS) $(DISTCLEANDIRS)
|
139
|
+
|
140
|
+
realclean: distclean
|
141
|
+
install: install-so install-rb
|
142
|
+
|
143
|
+
install-so: $(RUBYARCHDIR)
|
144
|
+
install-so: $(RUBYARCHDIR)/$(DLLIB)
|
145
|
+
$(RUBYARCHDIR)/$(DLLIB): $(DLLIB)
|
146
|
+
$(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR)
|
147
|
+
install-rb: pre-install-rb install-rb-default
|
148
|
+
install-rb-default: pre-install-rb-default
|
149
|
+
pre-install-rb: Makefile
|
150
|
+
pre-install-rb-default: Makefile
|
151
|
+
$(RUBYARCHDIR):
|
152
|
+
$(MAKEDIRS) $@
|
153
|
+
|
154
|
+
site-install: site-install-so site-install-rb
|
155
|
+
site-install-so: install-so
|
156
|
+
site-install-rb: install-rb
|
157
|
+
|
158
|
+
.SUFFIXES: .c .m .cc .cxx .cpp .C .o
|
159
|
+
|
160
|
+
.cc.o:
|
161
|
+
$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
|
162
|
+
|
163
|
+
.cxx.o:
|
164
|
+
$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
|
165
|
+
|
166
|
+
.cpp.o:
|
167
|
+
$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
|
168
|
+
|
169
|
+
.C.o:
|
170
|
+
$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
|
171
|
+
|
172
|
+
.c.o:
|
173
|
+
$(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $<
|
174
|
+
|
175
|
+
$(DLLIB): $(OBJS) Makefile
|
176
|
+
@-$(RM) $(@)
|
177
|
+
$(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)
|
178
|
+
|
179
|
+
|
180
|
+
|
181
|
+
$(OBJS): $(hdrdir)/ruby.h $(hdrdir)/ruby/defines.h $(arch_hdrdir)/ruby/config.h
|
data/lib/hubris.rb
CHANGED
@@ -3,7 +3,8 @@ require 'rubygems'
|
|
3
3
|
require 'open4'
|
4
4
|
require 'digest/md5'
|
5
5
|
require 'rbconfig'
|
6
|
-
|
6
|
+
$:.unshift File.dirname(__FILE__) + "/../ext/stub"
|
7
|
+
require 'stub'
|
7
8
|
# require 'file/temp'
|
8
9
|
# require 'libHaskell'
|
9
10
|
# TODO delete old files
|
@@ -26,10 +27,10 @@ class File
|
|
26
27
|
end
|
27
28
|
|
28
29
|
module Hubris
|
29
|
-
|
30
|
-
SO_CACHE = File.expand_path("/
|
31
|
-
HS_CACHE = File.expand_path("/
|
32
|
-
require '
|
30
|
+
HUBRIS_DIR = ENV['HUBRIS_DIR'] || "/var/hubris"
|
31
|
+
SO_CACHE = File.expand_path(HUBRIS_DIR + "/cache")
|
32
|
+
HS_CACHE = File.expand_path(HUBRIS_DIR + "/source")
|
33
|
+
# require 'stub'
|
33
34
|
[SO_CACHE,HS_CACHE].each {|dir| FileUtils.mkdir_p(dir)}
|
34
35
|
$:.push(SO_CACHE)
|
35
36
|
@always_rebuild=false
|
@@ -79,10 +80,14 @@ module Hubris
|
|
79
80
|
|
80
81
|
def hubrify(mod, args, src,packages=[])
|
81
82
|
libFile = "#{SO_CACHE}/#{zencode(mod)}.#{dylib_suffix}"
|
83
|
+
headers = ""
|
84
|
+
libraries = ""
|
82
85
|
if @always_rebuild or !File.exists?(libFile)
|
83
|
-
status,msg = Hubris.noisy("Hubrify --module #{mod} --output #{libFile} #{args.join(' ')} " +
|
86
|
+
status,msg = Hubris.noisy("Hubrify #{headers} #{libraries} -v --module #{mod} --output #{libFile} #{args.join(' ')} " +
|
84
87
|
(packages+@@basepackages).collect{|x| "--package #{x}"}.join(' ') + ' ' + src)
|
85
|
-
# if Hubrify's not installed, we throw an exception. just as
|
88
|
+
# if Hubrify's not installed, we throw an exception. just as
|
89
|
+
# good as explicitly checking a flag.
|
90
|
+
# puts msg
|
86
91
|
raise HaskellError.new("Hubrify error:\n#{msg + status.exitstatus.to_s}") unless status.exitstatus == 0
|
87
92
|
end
|
88
93
|
return libFile
|
@@ -90,12 +95,9 @@ module Hubris
|
|
90
95
|
|
91
96
|
def dylib_suffix
|
92
97
|
case Config::CONFIG['target_os']
|
93
|
-
when /darwin
|
94
|
-
|
95
|
-
|
96
|
-
"so"
|
97
|
-
else
|
98
|
-
"so" #take a punt
|
98
|
+
when /darwin/; "bundle"
|
99
|
+
when /linux/; "so"
|
100
|
+
else; "so" #take a punt
|
99
101
|
end
|
100
102
|
end
|
101
103
|
|
@@ -113,6 +115,7 @@ ran |#{str}|
|
|
113
115
|
output|#{stdout.read}|
|
114
116
|
error |#{stderr.read}|
|
115
117
|
EOF
|
118
|
+
puts msg
|
116
119
|
ignored, status = Process.waitpid2 pid
|
117
120
|
msg += "status |#{status}|"
|
118
121
|
return status, msg
|
data/rspec.rake
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
begin
|
2
|
+
require 'spec'
|
3
|
+
rescue LoadError
|
4
|
+
require 'rubygems' unless ENV['NO_RUBYGEMS']
|
5
|
+
require 'spec'
|
6
|
+
end
|
7
|
+
begin
|
8
|
+
require 'spec/rake/spectask'
|
9
|
+
rescue LoadError
|
10
|
+
puts <<-EOS
|
11
|
+
To use rspec for testing you must install rspec gem:
|
12
|
+
gem install rspec
|
13
|
+
EOS
|
14
|
+
exit(0)
|
15
|
+
end
|
16
|
+
|
17
|
+
desc "Run the specs under spec/models"
|
18
|
+
Spec::Rake::SpecTask.new do |t|
|
19
|
+
t.spec_opts = ['--options', "spec/spec.opts"]
|
20
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
21
|
+
end
|
data/sample/Fibonacci.hs
CHANGED
@@ -7,8 +7,8 @@ import Maybe
|
|
7
7
|
|
8
8
|
-- main = putStrLn "11"
|
9
9
|
|
10
|
-
fibonacci ::
|
11
|
-
fibonacci n = fibs !! n
|
10
|
+
fibonacci :: Integer -> Integer
|
11
|
+
fibonacci n = fibs !! (fromIntegral n)
|
12
12
|
where fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
|
13
13
|
|
14
14
|
-- local_map = Data.Map.fromList [(1,2), (3,4)]
|
data/sample/config.ru
CHANGED
@@ -10,12 +10,14 @@ end
|
|
10
10
|
|
11
11
|
|
12
12
|
def arg_from env
|
13
|
-
env['REQUEST_URI'] ? env['REQUEST_URI'].to_s.sub(/^\//, '').to_i : 0
|
13
|
+
#env['REQUEST_URI'] ? env['REQUEST_URI'].to_s.sub(/^\//, '').to_i : 0
|
14
|
+
env['PATH_INFO'] ? env['PATH_INFO'].to_s.sub(/^\//, '').to_i : 0
|
14
15
|
end
|
15
16
|
|
16
17
|
app = proc do |env|
|
17
18
|
value = Fibonacci.new.fibonacci( arg_from env )
|
18
19
|
[ 200, {'Content-Type' => 'text/plain'}, "The fib number is #{value }" ]
|
20
|
+
# [ 200, {'Content-Type' => 'text/plain'}, "The fib number is #{arg_from env}" ]
|
19
21
|
end
|
20
22
|
|
21
23
|
run app
|
data/script/ci.sh
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
|
2
|
+
#!/bin/bash -x
|
3
|
+
ghc_version=$1
|
4
|
+
set -e
|
5
|
+
export PATH=$PATH:$HOME/.cabal/bin
|
6
|
+
# another huge hack. let's fix this properly soon TODO
|
7
|
+
# export LD_LIBRARY_PATH=$HOME/.rvm/rubies/ruby-1.9.1-p378/lib/
|
8
|
+
export HUBRIS_DIR=~/tmp
|
9
|
+
mkdir $HUBRIS_DIR || true
|
10
|
+
rm -rf $HUBRIS_DIR/* || true
|
11
|
+
rm -rf /tmp/hubris* ||true
|
12
|
+
cabal install zlib --user --enable-shared # needed for tests
|
13
|
+
|
14
|
+
# delete old haskell stuff
|
15
|
+
ghc-pkg-$ghc_version unregister hubris || true
|
16
|
+
rm `which Hubrify` || true
|
17
|
+
rvm 1.9.1
|
18
|
+
gem build hubris.gemspec
|
19
|
+
gem install hubris-0.0.4.gem # can we do these two in one step?
|
20
|
+
|
21
|
+
#gem install bundler # i am aware how awful this is.
|
22
|
+
#bundle install
|
23
|
+
#bundle exec rake compile
|
24
|
+
#rm -rf $HUBRIS_DIR/*
|
25
|
+
#bundle exec rake
|
data/script/console
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# File: script/console
|
3
|
+
irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
|
4
|
+
|
5
|
+
libs = " -r irb/completion"
|
6
|
+
# Perhaps use a console_lib to store any extra methods I may want available in the cosole
|
7
|
+
# libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
|
8
|
+
libs << " -r #{File.dirname(__FILE__) + '/../lib/hubris.rb'}"
|
9
|
+
puts "Loading Hubris gem"
|
10
|
+
exec "#{irb} #{libs} --simple-prompt"
|