ffi-compiler 1.0.1 → 1.4.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
- SHA1:
3
- metadata.gz: e259c06c4c1c6dc1b0f0ff3ac34308bef10a077f
4
- data.tar.gz: 140239dc22fe032b91d7819f485082b3fda02388
2
+ SHA256:
3
+ metadata.gz: 59c39f1d0d925b12810c952af5c52fd0631ab72fab24601fb7b3b2eb9359f9a0
4
+ data.tar.gz: 45b7b6b883d0e484c87789287bb722105521033c0a70a2dfa6c7aa51162e902e
5
5
  SHA512:
6
- metadata.gz: 00c5494a75855984f97c69717d7466c5df44207007a19382029c72323831625c5ea338fb62a6d313cc8817dcc5ecc2948fdaad8c46c0e8f6f540c0da59111c10
7
- data.tar.gz: 2ec65c14eeaba45f8b75d44a7c184b00fa5daa52ab0904a749ba52d2cbbc639cea6f9326b90d840a1d6d97c913331cfecd11cb6bfb33355279a9d0da3a7d9093
6
+ metadata.gz: 3e1fafd139b595d06c04e9edcd46818b1d58a4986aa4617a84b0e2f794395f2575012b48368c0e5d019bb4914b0b882b82ac42bf33d63548bc93d42d94cccff8
7
+ data.tar.gz: a58808da33f2e358d8445178dbc19aa8fea350e0a0fcbbb54f58be19fc092cbd49fc3eb238af22ae6254501c47d358eeee517bf8ee7d4cb6f3f377ece1fec884
data/LICENSE CHANGED
@@ -187,7 +187,7 @@
187
187
  same "printed page" as the copyright notice for easier
188
188
  identification within third-party archives.
189
189
 
190
- Copyright [yyyy] [name of copyright owner]
190
+ Copyright 2020 FFI
191
191
 
192
192
  Licensed under the Apache License, Version 2.0 (the "License");
193
193
  you may not use this file except in compliance with the License.
data/ffi-compiler.gemspec CHANGED
@@ -1,19 +1,19 @@
1
+ require_relative 'lib/ffi-compiler/version'
2
+
1
3
  Gem::Specification.new do |s|
2
4
  s.name = 'ffi-compiler'
3
- s.version = '1.0.1'
5
+ s.version = FFI::Compiler::VERSION
4
6
  s.author = 'Wayne Meissner'
5
7
  s.email = ['wmeissner@gmail.com', 'steve@advancedcontrol.com.au']
6
- s.cert_chain = ['certs/stakach.pem']
7
- s.signing_key = File.expand_path("~/.ssh/gem-private_key.pem") if $0 =~ /gem\z/
8
- s.homepage = 'http://wiki.github.com/ffi/ffi'
8
+ s.homepage = 'https://github.com/ffi/ffi-compiler'
9
9
  s.summary = 'Ruby FFI Rakefile generator'
10
10
  s.description = 'Ruby FFI library'
11
11
  s.files = %w(ffi-compiler.gemspec Gemfile Rakefile README.md LICENSE) + Dir.glob("{lib,spec}/**/*")
12
- s.has_rdoc = false
13
- s.license = 'Apache 2.0'
12
+ s.license = 'Apache-2.0'
14
13
  s.required_ruby_version = '>= 1.9'
15
14
  s.add_dependency 'rake'
16
- s.add_dependency 'ffi', '>= 1.0.0'
15
+ s.add_dependency 'ffi', '>= 1.15.5'
17
16
  s.add_development_dependency 'rspec'
18
17
  s.add_development_dependency 'rubygems-tasks'
19
18
  end
19
+
@@ -5,12 +5,39 @@ require 'ffi'
5
5
  require 'tmpdir'
6
6
  require 'rbconfig'
7
7
  require_relative 'platform'
8
+ require_relative 'shell'
9
+ require_relative 'multi_file_task'
8
10
 
9
11
  module FFI
10
12
  module Compiler
11
13
  DEFAULT_CFLAGS = %w(-fexceptions -O -fno-omit-frame-pointer -fno-strict-aliasing)
12
14
  DEFAULT_LDFLAGS = %w(-fexceptions)
13
15
 
16
+ class Flags
17
+ attr_accessor :raw
18
+
19
+ def initialize(flags)
20
+ @flags = flags
21
+ @raw = true # For backward compatibility
22
+ end
23
+
24
+ def <<(flag)
25
+ if @raw
26
+ @flags += shellsplit(flag.to_s)
27
+ else
28
+ @flags << flag
29
+ end
30
+ end
31
+
32
+ def to_a
33
+ @flags
34
+ end
35
+
36
+ def to_s
37
+ shelljoin(@flags)
38
+ end
39
+ end
40
+
14
41
  class CompileTask < Rake::TaskLib
15
42
  attr_reader :cflags, :cxxflags, :ldflags, :libs, :platform
16
43
  attr_accessor :name, :ext_dir, :source_dirs, :exclude
@@ -26,9 +53,9 @@ module FFI
26
53
  @libraries = []
27
54
  @headers = []
28
55
  @functions = []
29
- @cflags = DEFAULT_CFLAGS.dup
30
- @cxxflags = DEFAULT_CFLAGS.dup
31
- @ldflags = DEFAULT_LDFLAGS.dup
56
+ @cflags = Flags.new(shellsplit(ENV['CFLAGS']) || DEFAULT_CFLAGS.dup)
57
+ @cxxflags = Flags.new(shellsplit(ENV['CXXFLAGS']) || DEFAULT_CFLAGS.dup)
58
+ @ldflags = Flags.new(shellsplit(ENV['LDFLAGS']) || DEFAULT_LDFLAGS.dup)
32
59
  @libs = []
33
60
  @platform = Platform.system
34
61
  @exports = []
@@ -93,7 +120,7 @@ module FFI
93
120
  else
94
121
  so_flags << '-shared'
95
122
  end
96
- so_flags = so_flags.join(' ')
123
+ so_flags = shelljoin(so_flags)
97
124
 
98
125
  out_dir = "#{@platform.arch}-#{@platform.os}"
99
126
  if @ext_dir != '.'
@@ -106,36 +133,36 @@ module FFI
106
133
  lib_name = File.join(out_dir, Platform.system.map_library_name(@name))
107
134
 
108
135
  iflags = @include_paths.uniq.map { |p| "-I#{p}" }
109
- @defines << @functions.uniq.map { |f| "-DHAVE_#{f.upcase}=1" }
110
- @defines << @headers.uniq.map { |h| "-DHAVE_#{h.upcase.sub(/\./, '_')}=1" }
136
+ @defines += @functions.uniq.map { |f| "-DHAVE_#{f.upcase}=1" }
137
+ @defines += @headers.uniq.map { |h| "-DHAVE_#{h.upcase.sub(/\./, '_')}=1" }
111
138
 
112
- cflags = (@cflags + pic_flags + iflags + @defines).join(' ')
113
- cxxflags = (@cxxflags + @cflags + pic_flags + iflags + @defines).join(' ')
114
- ld_flags = (@library_paths.map { |path| "-L#{path}" } + @ldflags).join(' ')
115
- libs = (@libraries.map { |l| "-l#{l}" } + @libs).join(' ')
139
+ cflags = shelljoin(@cflags.to_a + pic_flags + iflags + @defines)
140
+ cxxflags = shelljoin(@cxxflags.to_a + @cflags.to_a + pic_flags + iflags + @defines)
141
+ ld_flags = shelljoin(@library_paths.map { |path| "-L#{path}" } + @ldflags.to_a)
142
+ libs = shelljoin(@libraries.map { |l| "-l#{l}" } + @libs)
116
143
 
117
144
  src_files = []
118
145
  obj_files = []
119
146
  @source_dirs.each do |dir|
120
- files = FileList["#{dir}/**/*.{c,cpp}"]
121
- unless @exclude.empty?
122
- files.delete_if { |f| f =~ Regexp.union(*@exclude) }
123
- end
147
+ files = FileList["#{dir}/**/*.{c,cpp,m}"]
148
+ unless @exclude.empty?
149
+ files.delete_if { |f| f =~ Regexp.union(*@exclude) }
150
+ end
124
151
  src_files += files
125
152
  obj_files += files.ext('.o').map { |f| File.join(out_dir, f.sub(/^#{dir}\//, '')) }
126
- end
153
+ end
127
154
 
128
155
  index = 0
129
156
  src_files.each do |src|
130
157
  obj_file = obj_files[index]
131
- if src =~ /\.c$/
158
+ if src =~ /\.[cm]$/
132
159
  file obj_file => [ src, File.dirname(obj_file) ] do |t|
133
- sh "#{cc} #{cflags} -o #{t.name} -c #{t.prerequisites[0]}"
160
+ sh "#{cc} #{cflags} -o #{shellescape(t.name)} -c #{shellescape(t.prerequisites[0])}"
134
161
  end
135
162
 
136
163
  else
137
164
  file obj_file => [ src, File.dirname(obj_file) ] do |t|
138
- sh "#{cxx} #{cxxflags} -o #{t.name} -c #{t.prerequisites[0]}"
165
+ sh "#{cxx} #{cxxflags} -o #{shellescape(t.name)} -c #{shellescape(t.prerequisites[0])}"
139
166
  end
140
167
  end
141
168
 
@@ -149,15 +176,16 @@ module FFI
149
176
  obj_files.map { |f| File.dirname(f) }.sort.uniq.map { |d| directory d }
150
177
 
151
178
  desc "Build dynamic library"
152
- file lib_name => obj_files do |t|
153
- sh "#{ld} #{so_flags} -o #{t.name} #{t.prerequisites.join(' ')} #{ld_flags} #{libs}"
179
+ MultiFileTask.define_task(lib_name => src_files + obj_files) do |t|
180
+ objs = t.prerequisites.select { |file| file.end_with?('.o') }
181
+ sh "#{ld} #{so_flags} -o #{shellescape(t.name)} #{shelljoin(objs)} #{ld_flags} #{libs}"
154
182
  end
155
183
  CLEAN.include(lib_name)
156
184
 
157
185
  @exports.each do |e|
158
186
  desc "Export #{e[:rb_file]}"
159
187
  file e[:header] => [ e[:rb_file] ] do |t|
160
- ruby "-I#{File.join(File.dirname(__FILE__), 'fake_ffi')} -I#{File.dirname(t.prerequisites[0])} #{File.join(File.dirname(__FILE__), 'exporter.rb')} #{t.prerequisites[0]} #{t.name}"
188
+ ruby "-I#{File.join(File.dirname(__FILE__), 'fake_ffi')} -I#{File.dirname(t.prerequisites[0])} #{File.join(File.dirname(__FILE__), 'exporter.rb')} #{shellescape(t.prerequisites[0])} #{shellescape(t.name)}"
161
189
  end
162
190
 
163
191
  obj_files.each { |o| file o => [ e[:header] ] }
@@ -221,10 +249,10 @@ module FFI
221
249
  File.open(path, 'w') do |f|
222
250
  f << src
223
251
  end
224
- cflags = opts.join(' ')
252
+ cflags = shelljoin(opts)
225
253
  output = File.join(dir, 'ffi-test')
226
254
  begin
227
- return system "#{cc} #{cflags} -o #{output} -c #{path} > #{path}.log 2>&1"
255
+ return system "#{cc} #{cflags} -o #{shellescape(output)} -c #{shellescape(path)} > #{shellescape(path)}.log 2>&1"
228
256
  rescue
229
257
  return false
230
258
  end
@@ -7,9 +7,26 @@ module FFI
7
7
  module Loader
8
8
  def self.find(name, start_path = nil)
9
9
  library = Platform.system.map_library_name(name)
10
+ start_path ||= caller_path(caller[0])
11
+
12
+ # Load from modern extension fast-path when called from an active gem spec
13
+ if defined?(Gem::Specification) &&
14
+ (spec = Gem::Specification.find_active_stub_by_path(library)) &&
15
+ spec.respond_to?(:extension_dir) &&
16
+ start_path.start_with?(spec.gem_dir)
17
+
18
+ ext_path = File.join(spec.extension_dir, library)
19
+ return ext_path if File.exist?(ext_path)
20
+ end
21
+
22
+ # Try to find the library in the legacy lib path, passed start_path or local folder
10
23
  root = false
11
- Pathname.new(start_path || caller_path(caller[0])).ascend do |path|
12
- Dir.glob("#{path}/**/{#{FFI::Platform::ARCH}-#{FFI::Platform::OS}/#{library},#{library}}") do |f|
24
+ Pathname.new(start_path).ascend do |path|
25
+ Dir.glob("#{path}/**/#{FFI::Platform::ARCH}-#{FFI::Platform::OS}/#{library}") do |f|
26
+ return f
27
+ end
28
+
29
+ Dir.glob("#{path}/**/#{library}") do |f|
13
30
  return f
14
31
  end
15
32
 
@@ -33,4 +50,4 @@ module FFI
33
50
  end
34
51
  end
35
52
  end
36
- end
53
+ end
@@ -0,0 +1,47 @@
1
+ require 'rake'
2
+
3
+ module FFI
4
+ module Compiler
5
+ class MultiFileTask < Rake::MultiTask
6
+ def needed?
7
+ begin
8
+ @application.options.build_all || out_of_date?(File.mtime(name))
9
+ rescue Errno::ENOENT
10
+ true
11
+ end
12
+ end
13
+
14
+ def timestamp
15
+ begin
16
+ File.mtime(name)
17
+ rescue Errno::ENOENT
18
+ Rake::LATE
19
+ end
20
+ end
21
+
22
+ def invoke_with_call_chain(task_args, invocation_chain)
23
+ return unless needed?
24
+ super
25
+ end
26
+
27
+ # This is here for backwards-compatibility so we have namespace-free name
28
+ # FileTask (which we used in past) never uses scope
29
+ def self.scope_name(scope, task_name)
30
+ task_name
31
+ end
32
+
33
+ private
34
+
35
+ def out_of_date?(timestamp)
36
+ all_prerequisite_tasks.any? do |prereq|
37
+ prereq_task = application[prereq, @scope]
38
+ if prereq_task.instance_of?(Rake::FileTask)
39
+ File.exist?(prereq_task.name) && prereq_task.timestamp > timestamp
40
+ else
41
+ prereq_task.needed?
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,24 @@
1
+ require 'shellwords'
2
+ require 'rbconfig'
3
+
4
+ def shellescape(str)
5
+ return str unless str
6
+ if FFI::Platform::OS == 'windows'
7
+ '"' + str.gsub('"', '""') + '"'
8
+ else
9
+ str.shellescape
10
+ end
11
+ end
12
+
13
+ def shelljoin(args)
14
+ if FFI::Platform::OS == 'windows'
15
+ args.reduce { |cmd, arg| cmd + ' ' + shellescape(arg) }
16
+ else
17
+ args.shelljoin
18
+ end
19
+ end
20
+
21
+ def shellsplit(str)
22
+ return str unless str
23
+ str.shellsplit
24
+ end
@@ -0,0 +1,7 @@
1
+
2
+ module FFI
3
+ module Compiler
4
+ VERSION = "1.4.2"
5
+ end
6
+ end
7
+
metadata CHANGED
@@ -1,37 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ffi-compiler
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Wayne Meissner
8
- autorequire:
9
8
  bindir: bin
10
- cert_chain:
11
- - |
12
- -----BEGIN CERTIFICATE-----
13
- MIIDvDCCAqSgAwIBAgIBATANBgkqhkiG9w0BAQUFADBaMQ4wDAYDVQQDDAVzdGV2
14
- ZTEfMB0GCgmSJomT8ixkARkWD2FkdmFuY2VkY29udHJvbDETMBEGCgmSJomT8ixk
15
- ARkWA2NvbTESMBAGCgmSJomT8ixkARkWAmF1MB4XDTE2MDYyNjIyMjMyMloXDTE3
16
- MDYyNjIyMjMyMlowWjEOMAwGA1UEAwwFc3RldmUxHzAdBgoJkiaJk/IsZAEZFg9h
17
- ZHZhbmNlZGNvbnRyb2wxEzARBgoJkiaJk/IsZAEZFgNjb20xEjAQBgoJkiaJk/Is
18
- ZAEZFgJhdTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKvI6Zfmxakj
19
- ADC7rWDhCtHDSCdn2jrzeMDO2xqq9P315j0x7YVglKF49Xz7OCnWGxn0Zzec22Ha
20
- xq2St09wLPtE6+/qTiq48ffxLKPR/Aahdk31HGx5AXDjRQ5p48m5CK3BDratshbi
21
- ssg2bVMOxMSnNowb5Mqc448X2shYHwfuo9C4fsvkn0eC+XtpwOKBsLJnmYxI8opB
22
- A6cL5onHD1JH5Ywt7mWn3XCGEZY98Hq3V7wpCACWSHP9FfCmf0Vyn30UTlBivoUh
23
- qmtLB+TDW4Qvma/1cc7p1e3HF9xQHSza9FTyfhzw/vxnSF+jT4upUtXdhCTMqqDv
24
- m597hs3/6z8CAwEAAaOBjDCBiTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNV
25
- HQ4EFgQUqqCOTfINjbAqX/8nFvbzHcYG8xIwJwYDVR0RBCAwHoEcc3RldmVAYWR2
26
- YW5jZWRjb250cm9sLmNvbS5hdTAnBgNVHRIEIDAegRxzdGV2ZUBhZHZhbmNlZGNv
27
- bnRyb2wuY29tLmF1MA0GCSqGSIb3DQEBBQUAA4IBAQB/DUhYFbdLHAuZMgjwNUxF
28
- tnf3a2o40p9mEtVm48yxfP9/9w6xh+gRN/rbBCkKbe2zSue9Nnr3zfKNONfqePlz
29
- 9BZOMx7LO/wFOkuWONIU+U7v5Obxi7a0bjZ6OQnY5M6FpuWG5RT6hVIlkbrh40Xd
30
- SgbJ2CyHXTL3tC7ykvvI5nXQLE6OG8lyHk5Cop2Lbm4qeBVCVEDgDsXi/PFP+hjk
31
- wpN2wi2CVPoj+c4bOYxgvF17WNGDWYdVEXXCRzoqGbA2kLbTH1o9BxI6NBzmfwyH
32
- LY7uYxN8Hy8S4Oto/gB1eREHqYwwXt3TmlJ6kAVGbO5y9xblPncdnfwNLCUnPfxN
33
- -----END CERTIFICATE-----
34
- date: 2016-07-07 00:00:00.000000000 Z
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
35
11
  dependencies:
36
12
  - !ruby/object:Gem::Dependency
37
13
  name: rake
@@ -53,14 +29,14 @@ dependencies:
53
29
  requirements:
54
30
  - - ">="
55
31
  - !ruby/object:Gem::Version
56
- version: 1.0.0
32
+ version: 1.15.5
57
33
  type: :runtime
58
34
  prerelease: false
59
35
  version_requirements: !ruby/object:Gem::Requirement
60
36
  requirements:
61
37
  - - ">="
62
38
  - !ruby/object:Gem::Version
63
- version: 1.0.0
39
+ version: 1.15.5
64
40
  - !ruby/object:Gem::Dependency
65
41
  name: rspec
66
42
  requirement: !ruby/object:Gem::Requirement
@@ -108,13 +84,15 @@ files:
108
84
  - lib/ffi-compiler/fake_ffi/ffi-compiler/loader.rb
109
85
  - lib/ffi-compiler/fake_ffi/ffi.rb
110
86
  - lib/ffi-compiler/loader.rb
87
+ - lib/ffi-compiler/multi_file_task.rb
111
88
  - lib/ffi-compiler/platform.rb
89
+ - lib/ffi-compiler/shell.rb
112
90
  - lib/ffi-compiler/task.rb
113
- homepage: http://wiki.github.com/ffi/ffi
91
+ - lib/ffi-compiler/version.rb
92
+ homepage: https://github.com/ffi/ffi-compiler
114
93
  licenses:
115
- - Apache 2.0
94
+ - Apache-2.0
116
95
  metadata: {}
117
- post_install_message:
118
96
  rdoc_options: []
119
97
  require_paths:
120
98
  - lib
@@ -129,10 +107,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
129
107
  - !ruby/object:Gem::Version
130
108
  version: '0'
131
109
  requirements: []
132
- rubyforge_project:
133
- rubygems_version: 2.5.1
134
- signing_key:
110
+ rubygems_version: 4.0.5
135
111
  specification_version: 4
136
112
  summary: Ruby FFI Rakefile generator
137
113
  test_files: []
138
- has_rdoc: false
checksums.yaml.gz.sig DELETED
@@ -1 +0,0 @@
1
- zpt ���,�P��I��􃦄߿�5��=�r�[��� RT�gɬ�(x�U�Ȱ�g}� �w��g��0>޽��H�|e>#�]D��i�%���S���2/�U���p-?}��|"Hv�ME����� �~1,ø��i� CB��٘T�jA��� h���d.���E@d�.D�$�8�:5it )�XKI��0�Hn��歄@5RX�˩%5ɕ�dj�r�4ֻԲa��HQGT(L�W��ӈ"cF!���
data.tar.gz.sig DELETED
Binary file
metadata.gz.sig DELETED
@@ -1 +0,0 @@
1
- g`�.��8��&��������j�?\&��”��O0�b������qŖ]����W��J>M�9�.������sX���:�s(t�,F�@��Z]=���\�t�G���Ղ�å�q�O�*)r\�W�=��