openbabel-ruby 3.1.1.0 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4b041ce12f6f124d860ad7280ec2ce5aeaf36df897405b2b9a2819f703dc734c
4
- data.tar.gz: 5236c280c3186d3406dda3009e277a30748f042371c9f91e583609006e3f0c51
3
+ metadata.gz: 2c4c81751e6986f725fa4fad1a69afc9e556b530013ad7e0e219eb8b11013b83
4
+ data.tar.gz: ee14805b357d1ac78aaf827fb3a5a0350c03dd0557db0786599e492cb78f7d78
5
5
  SHA512:
6
- metadata.gz: 9f69a57091083cad77100223068b413221e803a883d7521f203866c049d5f8b7af6f12e7c13172b7ceca515a95eeb9036ae01d2853ef875908f7297094ea8d64
7
- data.tar.gz: a6b24eaa24f2ea9fef22e993a4298d24e08337891cf12d2469ded36bee31344d82c99ae3d74501183daeef4cecf424f87df695772d6b08a1ee28bdc659848c63
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
@@ -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
- # install OpenBabel
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, "build"
12
- install_dir = File.join main_dir, "openbabel"
13
- install_lib_dir = File.join install_dir, "lib"
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 # should be POSIX compatible
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 "Downloading OpenBabel sources"
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 "Configuring OpenBabel"
38
- cmake = "cmake #{src_dir} -DCMAKE_INSTALL_PREFIX=#{install_dir} -DBUILD_GUI=OFF -DENABLE_TESTS=OFF -DRUN_SWIG=ON -DRUBY_BINDINGS=ON"
39
- # set rpath for local installations
40
- # http://www.cmake.org/Wiki/CMake_RPATH_handling
41
- # http://vtk.1045678.n5.nabble.com/How-to-force-cmake-not-to-remove-install-rpath-td5721193.html
42
- cmake += " -DCMAKE_INSTALL_RPATH:STRING=\"#{install_lib_dir}\""
43
- system cmake
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 "Compiling OpenBabel sources."
49
- system "make -j#{nr_processors}"
50
- system "make install"
51
- ENV["PKG_CONFIG_PATH"] = File.dirname(File.expand_path(Dir["#{install_dir}/**/openbabel*pc"].first))
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
- # create a fake Makefile
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