Class: Rbind::Rbind
- Inherits:
-
Object
show all
- Defined in:
- lib/rbind/rbind.rb
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
Constructor Details
#initialize(name) ⇒ Rbind
Returns a new instance of Rbind.
49
50
51
52
53
54
55
56
57
58
59
|
# File 'lib/rbind/rbind.rb', line 49
def initialize(name)
@name = name
@includes = []
@pkg_config = []
@gems = []
@parser = DefaultParser.new
lib_name = "rbind_#{name.downcase}"
@generator_c = GeneratorC.new(@parser,lib_name)
@generator_ruby = GeneratorRuby.new(@parser,name,lib_name)
@generator_extern = GeneratorExtern.new(@parser)
end
|
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(m, *args) ⇒ Object
199
200
201
202
203
204
205
206
207
|
# File 'lib/rbind/rbind.rb', line 199
def method_missing(m,*args)
t = @parser.type(m.to_s,false,false)
return t if t
op = @parser.operation(m.to_s,false)
return op if op
super
end
|
Instance Attribute Details
#gems ⇒ Object
Returns the value of attribute gems.
11
12
13
|
# File 'lib/rbind/rbind.rb', line 11
def gems
@gems
end
|
#generator_c ⇒ Object
Returns the value of attribute generator_c.
6
7
8
|
# File 'lib/rbind/rbind.rb', line 6
def generator_c
@generator_c
end
|
#generator_ruby ⇒ Object
Returns the value of attribute generator_ruby.
7
8
9
|
# File 'lib/rbind/rbind.rb', line 7
def generator_ruby
@generator_ruby
end
|
#includes ⇒ Object
Returns the value of attribute includes.
8
9
10
|
# File 'lib/rbind/rbind.rb', line 8
def includes
@includes
end
|
#name ⇒ Object
Returns the value of attribute name.
9
10
11
|
# File 'lib/rbind/rbind.rb', line 9
def name
@name
end
|
#parser ⇒ Object
Returns the value of attribute parser.
5
6
7
|
# File 'lib/rbind/rbind.rb', line 5
def parser
@parser
end
|
#pkg_config ⇒ Object
Returns the value of attribute pkg_config.
10
11
12
|
# File 'lib/rbind/rbind.rb', line 10
def pkg_config
@pkg_config
end
|
Class Method Details
.gem_path(gem_name) ⇒ Object
28
29
30
31
32
33
34
35
|
# File 'lib/rbind/rbind.rb', line 28
def self.gem_path(gem_name)
out = IO.popen("gem contents #{gem_name}")
out.readlines.each do |line|
return $1 if line =~ /(.*)extern.rbind/
end
raise "Cannot find paths for gem #{gem_name}"
end
|
.pkg_paths(pkg_name) ⇒ Object
13
14
15
16
17
18
19
20
|
# File 'lib/rbind/rbind.rb', line 13
def self.pkg_paths(pkg_name)
out = IO.popen("pkg-config --cflags-only-I #{pkg_name}")
paths = out.read.split("-I").delete_if(&:empty?).map do |i|
i.gsub("\n","").gsub(" ","")
end
raise "Cannot find pkg paths for #{pkg_name}" if paths.empty?
paths
end
|
.rbind_pkg_paths(pkg_names) ⇒ Object
37
38
39
40
41
42
43
44
45
46
47
|
# File 'lib/rbind/rbind.rb', line 37
def self.rbind_pkg_paths(pkg_names)
rbind_packages = rbind_pkgs(pkg_names)
rbind_paths = rbind_packages.map do |pkg|
paths = pkg_paths(pkg)
path = paths.find do |p|
File.exist?(File.join(p,pkg,"extern.rbind"))
end
raise "cannot find extern.rbind for rbind package #{pkg}" unless path
File.join(path,pkg)
end
end
|
.rbind_pkgs(pkg_names) ⇒ Object
22
23
24
25
26
|
# File 'lib/rbind/rbind.rb', line 22
def self.rbind_pkgs(pkg_names)
pkg_names.find_all do |p|
!!(p =~ /^rbind_.*/)
end
end
|
Instance Method Details
#build ⇒ Object
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
# File 'lib/rbind/rbind.rb', line 125
def build
::Rbind.log.info "build c wrappers"
path = File.join(generator_c.output_path,"build")
FileUtils.mkdir_p(path) if path && !File.directory?(path)
Dir.chdir(path) do
if !system("cmake -C ..")
raise "CMake Configure Error"
end
if !system("make")
raise "Make Build Error"
end
end
if !system("cp #{File.join(path,"lib*.*")} #{generator_ruby.output_path}")
raise "cannot copy library to #{generator_ruby.output_path}"
end
::Rbind.log.info "all done !"
end
|
#check_python ⇒ Object
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
# File 'lib/rbind/rbind.rb', line 67
def check_python
out = IO.popen("which python")
if(out.read.empty?)
raise 'Cannot find python interpreter needed for parsing header files'
end
in_,out,err = Open3.popen3("python --version")
str = err.read
str = if str.empty?
out.read
else
str
end
if(str =~ /[a-zA-Z]* (.*)/)
if $1.to_f < 2.7
raise "Wrong python version #{$1}. At least python 2.7 is needed for parsing header files"
end
else
raise 'Cannot determine python version needed for parsing header files'
end
end
|
#generate(c_path = "src", ruby_path = "ruby/lib/#{name.downcase}") ⇒ Object
143
144
145
146
147
|
# File 'lib/rbind/rbind.rb', line 143
def generate(c_path = "src",ruby_path = "ruby/lib/#{name.downcase}")
generate_c c_path
generate_extern c_path
generate_ruby ruby_path
end
|
#generate_c(path) ⇒ Object
160
161
162
163
164
165
166
167
|
# File 'lib/rbind/rbind.rb', line 160
def generate_c(path)
::Rbind.log.info "generate c wrappers"
@generator_c.includes += includes
@generator_c.includes.uniq!
@generator_c.pkg_config = pkg_config
@generator_c.gems = gems
@generator_c.generate(path)
end
|
#generate_extern(path) ⇒ Object
169
170
171
|
# File 'lib/rbind/rbind.rb', line 169
def generate_extern(path)
@generator_extern.generate(path,@generator_ruby.module_name,@generator_ruby.file_prefix)
end
|
#generate_ruby(path) ⇒ Object
149
150
151
152
153
154
155
156
157
158
|
# File 'lib/rbind/rbind.rb', line 149
def generate_ruby(path)
::Rbind.log.info "generate ruby ffi wrappers"
paths = Rbind.rbind_pkg_paths(@pkg_config)
modules = paths.map do |pkg|
config = YAML.load(File.open(File.join(pkg,"config.rbind")).read)
config.file_prefix
end
@generator_ruby.required_module_names = modules + gems
@generator_ruby.generate(path)
end
|
#import_std_string ⇒ Object
194
195
196
197
|
# File 'lib/rbind/rbind.rb', line 194
def import_std_string
@generator_c.includes << "<string>"
@parser.add_type(RString.new("std::string",@parser))
end
|
#libs ⇒ Object
190
191
192
|
# File 'lib/rbind/rbind.rb', line 190
def libs
@generator_c.libs
end
|
#on_type_not_found(&block) ⇒ Object
186
187
188
|
# File 'lib/rbind/rbind.rb', line 186
def on_type_not_found(&block)
@parser.on_type_not_found(&block)
end
|
#parse(*files) ⇒ Object
61
62
63
64
65
|
# File 'lib/rbind/rbind.rb', line 61
def parse(*files)
files.each do |path|
parser.parse File.new(path).read
end
end
|
#parse_extern ⇒ Object
parses other rbind packages
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
# File 'lib/rbind/rbind.rb', line 89
def parse_extern
paths = Rbind.rbind_pkg_paths(@pkg_config)
paths.each do |pkg|
config = YAML.load(File.open(File.join(pkg,"config.rbind")).read)
path = File.join(pkg,"extern.rbind")
::Rbind.log.info "parsing extern rbind pkg file #{path}"
parser.parse(File.open(path).read,config.ruby_module_name)
end
@gems.each do |gem|
path = Rbind.gem_path(gem)
config = YAML.load(File.open(File.join(path,"config.rbind")).read)
path = File.join(path,"extern.rbind")
::Rbind.log.info "parsing extern gem file #{path}"
parser.parse(File.open(path).read,config.ruby_module_name)
end
end
|
121
122
123
|
# File 'lib/rbind/rbind.rb', line 121
def (*)
parser.parse (*)
end
|
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
# File 'lib/rbind/rbind.rb', line 106
def (*)
check_python
= if .empty?
includes
else
end
= .map do |h|
"\"#{h}\""
end
path = File.join(File.dirname(__FILE__),'tools','hdr_parser.py')
out = IO.popen("python #{path} #{headers.join(" ")}")
out.read
end
|
#type(*args) ⇒ Object
182
183
184
|
# File 'lib/rbind/rbind.rb', line 182
def type(*args)
parser.type(*args)
end
|
#use_namespace(name) ⇒ Object
173
174
175
176
177
178
179
180
|
# File 'lib/rbind/rbind.rb', line 173
def use_namespace(name)
t = if name.is_a? String
parser.type(name)
else
name
end
parser.use_namespace t
end
|