openbabel-ruby 3.1.1.1 → 3.1.1.2
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.
- checksums.yaml +4 -4
- data/Rakefile +269 -0
- data/ext/openbabel/extconf.rb +33 -25
- data/ext/openbabel/patches/CMakeLists.txt +739 -0
- data/ext/openbabel/patches/scripts/CMakeLists.txt +239 -0
- data/lib/openbabel/version.rb +1 -1
- data/lib/openbabel.rb +81 -2
- metadata +9 -6
- data/test/test_openbabel.rb +0 -22
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2c4c81751e6986f725fa4fad1a69afc9e556b530013ad7e0e219eb8b11013b83
|
|
4
|
+
data.tar.gz: ee14805b357d1ac78aaf827fb3a5a0350c03dd0557db0786599e492cb78f7d78
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7eb6c84c88967ae33159cd3d179d4bb19f74ef10488182d32acba0527e07e0d809453d584a540e8b9e2e835e598b8bb3aa8552497977fe57665b3c55c82d4490
|
|
7
|
+
data.tar.gz: 677f07a3a433d11474db288b5a0da00c5b9623e9183cb8e32f20e28110bc6ca20990f2360e09aadb09ac93544978111ff93cd016153f32cc961f81d47f7d994d
|
data/Rakefile
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require "bundler/gem_tasks"
|
|
2
2
|
require 'rake/testtask'
|
|
3
|
+
require 'fileutils'
|
|
3
4
|
|
|
4
5
|
Rake::TestTask.new do |t|
|
|
5
6
|
t.libs << 'test'
|
|
@@ -7,3 +8,271 @@ end
|
|
|
7
8
|
|
|
8
9
|
desc "Run tests"
|
|
9
10
|
task :default => :test
|
|
11
|
+
|
|
12
|
+
# =============================================================================
|
|
13
|
+
# Native Gem Building Tasks
|
|
14
|
+
# =============================================================================
|
|
15
|
+
|
|
16
|
+
RUBY_VERSION_DIR = "#{RUBY_VERSION.split('.')[0..1].join('.')}.0"
|
|
17
|
+
GEM_ROOT = File.expand_path('..', __FILE__)
|
|
18
|
+
NATIVE_DIR = File.join(GEM_ROOT, 'lib', 'openbabel', RUBY_VERSION_DIR)
|
|
19
|
+
|
|
20
|
+
def find_installed_gem_dir
|
|
21
|
+
Gem::Specification.find_all_by_name('openbabel-ruby').each do |spec|
|
|
22
|
+
return spec.gem_dir if File.directory?(File.join(spec.gem_dir, 'openbabel'))
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
Gem.path.each do |gem_path|
|
|
26
|
+
pattern = File.join(gem_path, 'gems', 'openbabel-ruby-*')
|
|
27
|
+
Dir[pattern].sort.reverse.each do |dir|
|
|
28
|
+
return dir if File.directory?(File.join(dir, 'openbabel'))
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
nil
|
|
33
|
+
rescue Gem::MissingSpecError
|
|
34
|
+
nil
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def find_extension_path
|
|
38
|
+
gem_dir = find_installed_gem_dir
|
|
39
|
+
return nil unless gem_dir
|
|
40
|
+
|
|
41
|
+
openbabel_lib = File.join(gem_dir, 'openbabel', 'lib')
|
|
42
|
+
|
|
43
|
+
[
|
|
44
|
+
File.join(openbabel_lib, 'openbabel.so'),
|
|
45
|
+
File.join(openbabel_lib, 'openbabel.bundle')
|
|
46
|
+
].each do |path|
|
|
47
|
+
return path if File.exist?(path)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
Dir[File.join(openbabel_lib, '**', 'openbabel.{so,bundle}')].first
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def find_openbabel_libs
|
|
54
|
+
gem_dir = find_installed_gem_dir
|
|
55
|
+
return [] unless gem_dir
|
|
56
|
+
|
|
57
|
+
lib_dir = File.join(gem_dir, 'openbabel', 'lib')
|
|
58
|
+
Dir[File.join(lib_dir, '*.so*')] + Dir[File.join(lib_dir, '*.dylib')]
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def find_openbabel_data
|
|
62
|
+
gem_dir = find_installed_gem_dir
|
|
63
|
+
return nil unless gem_dir
|
|
64
|
+
|
|
65
|
+
File.join(gem_dir, 'openbabel', 'share', 'openbabel')
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def find_openbabel_plugins
|
|
69
|
+
gem_dir = find_installed_gem_dir
|
|
70
|
+
return nil unless gem_dir
|
|
71
|
+
|
|
72
|
+
plugin_dir = Dir[File.join(gem_dir, 'openbabel', 'lib', 'openbabel', '*')].first
|
|
73
|
+
plugin_dir if plugin_dir && File.directory?(plugin_dir)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
desc "Stage native binaries for packaging"
|
|
77
|
+
task :stage_native do
|
|
78
|
+
puts "Staging native binaries for Ruby #{RUBY_VERSION_DIR}..."
|
|
79
|
+
|
|
80
|
+
ext_path = find_extension_path
|
|
81
|
+
raise "Could not find openbabel extension. Run 'gem install openbabel-ruby' first." if ext_path.nil?
|
|
82
|
+
|
|
83
|
+
FileUtils.mkdir_p(NATIVE_DIR)
|
|
84
|
+
|
|
85
|
+
ext_name = File.basename(ext_path)
|
|
86
|
+
FileUtils.cp(ext_path, File.join(NATIVE_DIR, ext_name))
|
|
87
|
+
puts " Copied #{ext_name}"
|
|
88
|
+
|
|
89
|
+
find_openbabel_libs.each do |lib|
|
|
90
|
+
next if lib == ext_path
|
|
91
|
+
lib_name = File.basename(lib)
|
|
92
|
+
FileUtils.cp(lib, File.join(NATIVE_DIR, lib_name))
|
|
93
|
+
puts " Copied #{lib_name}"
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
plugin_dir = find_openbabel_plugins
|
|
97
|
+
if plugin_dir && File.directory?(plugin_dir)
|
|
98
|
+
target_plugin_dir = File.join(NATIVE_DIR, 'plugins')
|
|
99
|
+
FileUtils.cp_r(plugin_dir, target_plugin_dir)
|
|
100
|
+
puts " Copied plugins directory"
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
data_dir = find_openbabel_data
|
|
104
|
+
if data_dir && File.directory?(data_dir)
|
|
105
|
+
target_data_dir = File.join(NATIVE_DIR, 'data')
|
|
106
|
+
FileUtils.cp_r(data_dir, target_data_dir)
|
|
107
|
+
puts " Copied data directory"
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
puts "Staging complete: #{NATIVE_DIR}"
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
desc "Fix RPATH for Linux binaries"
|
|
114
|
+
task :fix_rpath_linux do
|
|
115
|
+
puts "Fixing RPATH for Linux..."
|
|
116
|
+
|
|
117
|
+
ext_path = find_extension_path
|
|
118
|
+
raise "Extension not found. Install the gem first: gem install openbabel-ruby" unless ext_path
|
|
119
|
+
|
|
120
|
+
system("patchelf --set-rpath '$ORIGIN' #{ext_path}")
|
|
121
|
+
puts " Fixed RPATH for #{File.basename(ext_path)}"
|
|
122
|
+
|
|
123
|
+
find_openbabel_libs.each do |lib|
|
|
124
|
+
next unless lib.end_with?('.so') || lib.include?('.so.')
|
|
125
|
+
system("patchelf --set-rpath '$ORIGIN' #{lib}")
|
|
126
|
+
puts " Fixed RPATH for #{File.basename(lib)}"
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
desc "Bundle system libraries for Linux"
|
|
131
|
+
task :bundle_system_libs_linux do
|
|
132
|
+
puts "Bundling system libraries for Linux..."
|
|
133
|
+
|
|
134
|
+
ext_path = find_extension_path
|
|
135
|
+
raise "Extension not found" unless ext_path
|
|
136
|
+
|
|
137
|
+
lib_dir = File.dirname(ext_path)
|
|
138
|
+
libs_to_bundle = []
|
|
139
|
+
|
|
140
|
+
ldd_output = `ldd #{ext_path} 2>/dev/null`
|
|
141
|
+
ldd_output.each_line do |line|
|
|
142
|
+
if line =~ /libopenbabel|libinchi|libcoordgen/
|
|
143
|
+
if line =~ /=> (.+\.so[^\s]*)/
|
|
144
|
+
lib_path = $1.strip
|
|
145
|
+
libs_to_bundle << lib_path if File.exist?(lib_path)
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
libs_to_bundle.uniq.each do |lib|
|
|
151
|
+
target = File.join(lib_dir, File.basename(lib))
|
|
152
|
+
unless File.exist?(target)
|
|
153
|
+
FileUtils.cp(lib, target)
|
|
154
|
+
system("patchelf --set-rpath '$ORIGIN' #{target}")
|
|
155
|
+
puts " Bundled #{File.basename(lib)}"
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
desc "Fix library paths for macOS binaries"
|
|
161
|
+
task :fix_rpath_macos do
|
|
162
|
+
puts "Fixing library paths for macOS..."
|
|
163
|
+
|
|
164
|
+
ext_path = find_extension_path
|
|
165
|
+
raise "Extension not found. Install the gem first: gem install openbabel-ruby" unless ext_path
|
|
166
|
+
|
|
167
|
+
ext_name = File.basename(ext_path)
|
|
168
|
+
system("install_name_tool -id '@loader_path/#{ext_name}' #{ext_path}")
|
|
169
|
+
|
|
170
|
+
otool_output = `otool -L #{ext_path}`
|
|
171
|
+
otool_output.each_line do |line|
|
|
172
|
+
next if line.include?(ext_name)
|
|
173
|
+
|
|
174
|
+
if line =~ /^\s+(.+\.dylib)/
|
|
175
|
+
old_path = $1.split(' ').first
|
|
176
|
+
lib_name = File.basename(old_path)
|
|
177
|
+
|
|
178
|
+
if old_path.start_with?('/') && !old_path.start_with?('/usr/lib', '/System')
|
|
179
|
+
system("install_name_tool -change '#{old_path}' '@loader_path/#{lib_name}' #{ext_path}")
|
|
180
|
+
puts " Changed #{old_path} -> @loader_path/#{lib_name}"
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
find_openbabel_libs.each do |lib|
|
|
186
|
+
next unless lib.end_with?('.dylib')
|
|
187
|
+
lib_name = File.basename(lib)
|
|
188
|
+
|
|
189
|
+
system("install_name_tool -id '@loader_path/#{lib_name}' #{lib}")
|
|
190
|
+
|
|
191
|
+
otool_output = `otool -L #{lib}`
|
|
192
|
+
otool_output.each_line do |line|
|
|
193
|
+
if line =~ /^\s+(.+\.dylib)/
|
|
194
|
+
old_path = $1.split(' ').first
|
|
195
|
+
dep_name = File.basename(old_path)
|
|
196
|
+
|
|
197
|
+
if old_path.start_with?('/') && !old_path.start_with?('/usr/lib', '/System')
|
|
198
|
+
system("install_name_tool -change '#{old_path}' '@loader_path/#{dep_name}' #{lib}")
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
desc "Bundle system libraries for macOS"
|
|
206
|
+
task :bundle_system_libs_macos do
|
|
207
|
+
puts "Bundling system libraries for macOS..."
|
|
208
|
+
|
|
209
|
+
ext_path = find_extension_path
|
|
210
|
+
raise "Extension not found" unless ext_path
|
|
211
|
+
|
|
212
|
+
lib_dir = File.dirname(ext_path)
|
|
213
|
+
libs_to_bundle = []
|
|
214
|
+
|
|
215
|
+
otool_output = `otool -L #{ext_path}`
|
|
216
|
+
otool_output.each_line do |line|
|
|
217
|
+
if line =~ /^\s+(.+\.dylib)/
|
|
218
|
+
lib_path = $1.split(' ').first
|
|
219
|
+
if lib_path =~ /libopenbabel|libinchi|libcoordgen/ && File.exist?(lib_path)
|
|
220
|
+
libs_to_bundle << lib_path
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
libs_to_bundle.uniq.each do |lib|
|
|
226
|
+
target = File.join(lib_dir, File.basename(lib))
|
|
227
|
+
unless File.exist?(target)
|
|
228
|
+
FileUtils.cp(lib, target)
|
|
229
|
+
lib_name = File.basename(lib)
|
|
230
|
+
system("install_name_tool -id '@loader_path/#{lib_name}' #{target}")
|
|
231
|
+
puts " Bundled #{lib_name}"
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
desc "Build fat gem with precompiled binaries"
|
|
237
|
+
task :build_fat_gem do
|
|
238
|
+
puts "Building fat gem..."
|
|
239
|
+
|
|
240
|
+
staged_dirs = Dir[File.join(GEM_ROOT, 'lib', 'openbabel', '*.0')]
|
|
241
|
+
raise "No staged binaries found. Run stage_native first for each Ruby version." if staged_dirs.empty?
|
|
242
|
+
|
|
243
|
+
puts "Found staged binaries for: #{staged_dirs.map { |d| File.basename(d) }.join(', ')}"
|
|
244
|
+
|
|
245
|
+
ENV['OPENBABEL_PRECOMPILED'] = '1'
|
|
246
|
+
FileUtils.mkdir_p('pkg')
|
|
247
|
+
|
|
248
|
+
platform = ENV['OPENBABEL_PLATFORM'] || begin
|
|
249
|
+
case RUBY_PLATFORM
|
|
250
|
+
when /darwin/
|
|
251
|
+
"#{`uname -m`.strip}-darwin"
|
|
252
|
+
when /linux/
|
|
253
|
+
arch = `uname -m`.strip
|
|
254
|
+
arch = 'aarch64' if arch == 'arm64'
|
|
255
|
+
"#{arch}-linux"
|
|
256
|
+
else
|
|
257
|
+
Gem::Platform.local.to_s
|
|
258
|
+
end
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
puts "Building for platform: #{platform}"
|
|
262
|
+
ENV['OPENBABEL_PLATFORM'] = platform
|
|
263
|
+
|
|
264
|
+
system("gem build openbabel.gemspec")
|
|
265
|
+
|
|
266
|
+
Dir['openbabel-ruby-*.gem'].each do |gem_file|
|
|
267
|
+
FileUtils.mv(gem_file, 'pkg/')
|
|
268
|
+
puts "Built: pkg/#{gem_file}"
|
|
269
|
+
end
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
desc "Clean staged binaries"
|
|
273
|
+
task :clean_staged do
|
|
274
|
+
Dir[File.join(GEM_ROOT, 'lib', 'openbabel', '*.0')].each do |dir|
|
|
275
|
+
FileUtils.rm_rf(dir)
|
|
276
|
+
puts "Removed #{dir}"
|
|
277
|
+
end
|
|
278
|
+
end
|
data/ext/openbabel/extconf.rb
CHANGED
|
@@ -2,20 +2,18 @@ require 'fileutils'
|
|
|
2
2
|
require 'rbconfig'
|
|
3
3
|
require 'mkmf'
|
|
4
4
|
|
|
5
|
-
main_dir = File.expand_path(File.join(File.dirname(__FILE__),
|
|
5
|
+
main_dir = File.expand_path(File.join(File.dirname(__FILE__), '..', '..'))
|
|
6
|
+
patches_dir = File.join(File.dirname(__FILE__), 'patches')
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
openbabel_dir = File.join main_dir, "openbabel_src"
|
|
8
|
+
openbabel_dir = File.join main_dir, 'openbabel_src'
|
|
10
9
|
src_dir = openbabel_dir
|
|
11
|
-
build_dir = File.join src_dir,
|
|
12
|
-
install_dir = File.join main_dir,
|
|
13
|
-
install_lib_dir = File.join install_dir,
|
|
14
|
-
ruby_src_dir = File.join src_dir, "scripts", "ruby"
|
|
10
|
+
build_dir = File.join src_dir, 'build'
|
|
11
|
+
install_dir = File.join main_dir, 'openbabel'
|
|
12
|
+
install_lib_dir = File.join install_dir, 'lib'
|
|
15
13
|
|
|
16
14
|
begin
|
|
17
|
-
nr_processors = `getconf _NPROCESSORS_ONLN`.to_i
|
|
18
|
-
rescue
|
|
15
|
+
nr_processors = `getconf _NPROCESSORS_ONLN`.to_i
|
|
16
|
+
rescue StandardError
|
|
19
17
|
nr_processors = 1
|
|
20
18
|
end
|
|
21
19
|
|
|
@@ -24,37 +22,47 @@ OPENBABEL_COMMIT = '889c350'
|
|
|
24
22
|
FileUtils.mkdir_p openbabel_dir
|
|
25
23
|
Dir.chdir main_dir do
|
|
26
24
|
FileUtils.rm_rf src_dir
|
|
27
|
-
puts
|
|
25
|
+
puts 'Downloading OpenBabel sources'
|
|
28
26
|
system "git clone https://github.com/openbabel/openbabel.git #{src_dir}"
|
|
29
27
|
Dir.chdir(src_dir) do
|
|
30
28
|
system "git checkout #{OPENBABEL_COMMIT}"
|
|
31
29
|
end
|
|
32
30
|
end
|
|
33
31
|
|
|
32
|
+
puts 'Applying CMake 4.x compatibility patches...'
|
|
33
|
+
FileUtils.cp(File.join(patches_dir, 'CMakeLists.txt'), File.join(src_dir, 'CMakeLists.txt'))
|
|
34
|
+
FileUtils.cp(File.join(patches_dir, 'scripts', 'CMakeLists.txt'), File.join(src_dir, 'scripts', 'CMakeLists.txt'))
|
|
35
|
+
|
|
34
36
|
FileUtils.mkdir_p build_dir
|
|
35
37
|
FileUtils.mkdir_p install_dir
|
|
36
38
|
Dir.chdir build_dir do
|
|
37
|
-
puts
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
39
|
+
puts 'Configuring OpenBabel'
|
|
40
|
+
cmake_args = [
|
|
41
|
+
"cmake #{src_dir}",
|
|
42
|
+
"-DCMAKE_INSTALL_PREFIX=#{install_dir}",
|
|
43
|
+
'-DBUILD_GUI=OFF',
|
|
44
|
+
'-DENABLE_TESTS=OFF',
|
|
45
|
+
'-DRUN_SWIG=ON',
|
|
46
|
+
'-DRUBY_BINDINGS=ON',
|
|
47
|
+
'-DCMAKE_CXX_STANDARD=14',
|
|
48
|
+
"-DCMAKE_INSTALL_RPATH:STRING=\"#{install_lib_dir}\"",
|
|
49
|
+
'-Wno-dev'
|
|
50
|
+
].join(' ')
|
|
51
|
+
|
|
52
|
+
abort 'ERROR: CMake configuration failed' unless system(cmake_args)
|
|
44
53
|
end
|
|
45
54
|
|
|
46
|
-
# local installation in gem directory
|
|
47
55
|
Dir.chdir build_dir do
|
|
48
|
-
puts
|
|
49
|
-
system
|
|
50
|
-
system
|
|
51
|
-
|
|
56
|
+
puts 'Compiling OpenBabel sources.'
|
|
57
|
+
abort 'ERROR: OpenBabel compilation failed' unless system("make -j#{nr_processors}")
|
|
58
|
+
abort 'ERROR: OpenBabel installation failed' unless system('make install')
|
|
59
|
+
pc_file = Dir["#{install_dir}/**/openbabel*pc"].first
|
|
60
|
+
ENV['PKG_CONFIG_PATH'] = File.dirname(File.expand_path(pc_file)) if pc_file
|
|
52
61
|
end
|
|
53
62
|
|
|
54
63
|
FileUtils.remove_dir(openbabel_dir)
|
|
55
64
|
|
|
56
|
-
|
|
57
|
-
File.open(File.join(File.dirname(__FILE__),"Makefile"),"w+") do |makefile|
|
|
65
|
+
File.open(File.join(File.dirname(__FILE__), 'Makefile'), 'w+') do |makefile|
|
|
58
66
|
makefile.puts "all:\n\ttrue\n\ninstall:\n\ttrue\n"
|
|
59
67
|
end
|
|
60
68
|
|