ffi-compiler 1.0.1 → 1.3.1
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 +5 -5
- data/LICENSE +1 -1
- data/ffi-compiler.gemspec +7 -7
- data/lib/ffi-compiler/compile_task.rb +49 -21
- data/lib/ffi-compiler/loader.rb +5 -1
- data/lib/ffi-compiler/multi_file_task.rb +41 -0
- data/lib/ffi-compiler/shell.rb +24 -0
- data/lib/ffi-compiler/version.rb +7 -0
- metadata +14 -36
- checksums.yaml.gz.sig +0 -1
- data.tar.gz.sig +0 -0
- metadata.gz.sig +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 6b5d2323276536d7b5525a84f71e6b740d93dbb7599bc593b07c6cbe4555d71a
|
4
|
+
data.tar.gz: 59c2d2f0e72494eb68b396f2c99b6c78229839b363abda938869134c205b1aab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '074259969bc26ce9cf1c5ef33b6e64c16bdc6f6283248ed1b2d124268d8686eb103421a3208fbfd30d43518933c65f012d3394ebb5fc9c5566564aa50f04ff35'
|
7
|
+
data.tar.gz: 861960b3190b87b5b6ca902b2076e12abb6788a137bc7cf04d7fb6eb27fea7b9fb673e20b887c2a6e5285c6c4a4b3bf27f7d45362360d3149851e50c32cff25e
|
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
|
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 =
|
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.
|
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.
|
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.
|
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
|
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
|
110
|
-
@defines
|
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)
|
113
|
-
cxxflags = (@cxxflags + @cflags + pic_flags + iflags + @defines)
|
114
|
-
ld_flags = (@library_paths.map { |path| "-L#{path}" } + @ldflags
|
115
|
-
libs = (@libraries.map { |l| "-l#{l}" } + @libs)
|
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
147
|
files = FileList["#{dir}/**/*.{c,cpp}"]
|
121
|
-
|
122
|
-
|
123
|
-
|
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
|
-
|
153
|
+
end
|
127
154
|
|
128
155
|
index = 0
|
129
156
|
src_files.each do |src|
|
130
157
|
obj_file = obj_files[index]
|
131
158
|
if src =~ /\.c$/
|
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
|
-
|
153
|
-
|
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
|
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
|
data/lib/ffi-compiler/loader.rb
CHANGED
@@ -9,7 +9,11 @@ module FFI
|
|
9
9
|
library = Platform.system.map_library_name(name)
|
10
10
|
root = false
|
11
11
|
Pathname.new(start_path || caller_path(caller[0])).ascend do |path|
|
12
|
-
Dir.glob("#{path}
|
12
|
+
Dir.glob("#{path}/**/#{FFI::Platform::ARCH}-#{FFI::Platform::OS}/#{library}") do |f|
|
13
|
+
return f
|
14
|
+
end
|
15
|
+
|
16
|
+
Dir.glob("#{path}/**/#{library}") do |f|
|
13
17
|
return f
|
14
18
|
end
|
15
19
|
|
@@ -0,0 +1,41 @@
|
|
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
|
+
private
|
28
|
+
|
29
|
+
def out_of_date?(timestamp)
|
30
|
+
all_prerequisite_tasks.any? do |prereq|
|
31
|
+
prereq_task = application[prereq, @scope]
|
32
|
+
if prereq_task.instance_of?(Rake::FileTask)
|
33
|
+
File.exist?(prereq_task.name) && prereq_task.timestamp > timestamp
|
34
|
+
else
|
35
|
+
prereq_task.needed?
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
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
|
metadata
CHANGED
@@ -1,37 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ffi-compiler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Wayne Meissner
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
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
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-03-13 00:00:00.000000000 Z
|
35
12
|
dependencies:
|
36
13
|
- !ruby/object:Gem::Dependency
|
37
14
|
name: rake
|
@@ -53,14 +30,14 @@ dependencies:
|
|
53
30
|
requirements:
|
54
31
|
- - ">="
|
55
32
|
- !ruby/object:Gem::Version
|
56
|
-
version: 1.
|
33
|
+
version: 1.15.5
|
57
34
|
type: :runtime
|
58
35
|
prerelease: false
|
59
36
|
version_requirements: !ruby/object:Gem::Requirement
|
60
37
|
requirements:
|
61
38
|
- - ">="
|
62
39
|
- !ruby/object:Gem::Version
|
63
|
-
version: 1.
|
40
|
+
version: 1.15.5
|
64
41
|
- !ruby/object:Gem::Dependency
|
65
42
|
name: rspec
|
66
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -108,13 +85,16 @@ files:
|
|
108
85
|
- lib/ffi-compiler/fake_ffi/ffi-compiler/loader.rb
|
109
86
|
- lib/ffi-compiler/fake_ffi/ffi.rb
|
110
87
|
- lib/ffi-compiler/loader.rb
|
88
|
+
- lib/ffi-compiler/multi_file_task.rb
|
111
89
|
- lib/ffi-compiler/platform.rb
|
90
|
+
- lib/ffi-compiler/shell.rb
|
112
91
|
- lib/ffi-compiler/task.rb
|
113
|
-
|
92
|
+
- lib/ffi-compiler/version.rb
|
93
|
+
homepage: https://github.com/ffi/ffi-compiler
|
114
94
|
licenses:
|
115
|
-
- Apache
|
95
|
+
- Apache-2.0
|
116
96
|
metadata: {}
|
117
|
-
post_install_message:
|
97
|
+
post_install_message:
|
118
98
|
rdoc_options: []
|
119
99
|
require_paths:
|
120
100
|
- lib
|
@@ -129,10 +109,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
129
109
|
- !ruby/object:Gem::Version
|
130
110
|
version: '0'
|
131
111
|
requirements: []
|
132
|
-
|
133
|
-
|
134
|
-
signing_key:
|
112
|
+
rubygems_version: 3.5.6
|
113
|
+
signing_key:
|
135
114
|
specification_version: 4
|
136
115
|
summary: Ruby FFI Rakefile generator
|
137
116
|
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�=��
|