ffi-compiler 1.0.0 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 0d72c341f9ccb50429bfd8a3542d3c9481f7e4d2
4
- data.tar.gz: 780d11e250a8e1637d287d8482c7eb319d170db8
2
+ SHA256:
3
+ metadata.gz: 6b5d2323276536d7b5525a84f71e6b740d93dbb7599bc593b07c6cbe4555d71a
4
+ data.tar.gz: 59c2d2f0e72494eb68b396f2c99b6c78229839b363abda938869134c205b1aab
5
5
  SHA512:
6
- metadata.gz: a4d9af481db298d53bba6d89b85f4f288043748ca736f84f751f1cb16ad829be4719fbf5faab58a14ebdbaa91a01d0cafbaa31104c1dbfaae6cd9093f371c1e5
7
- data.tar.gz: f7d499575077854ec5913209f0ec8fb83e01028a90b93ba86c8b221bc9b31f8c135a3df6370b47cc0a5f7a611167c1ae4f0971c6cec7032e40d435ff2123395e
6
+ metadata.gz: '074259969bc26ce9cf1c5ef33b6e64c16bdc6f6283248ed1b2d124268d8686eb103421a3208fbfd30d43518933c65f012d3394ebb5fc9c5566564aa50f04ff35'
7
+ data.tar.gz: 861960b3190b87b5b6ca902b2076e12abb6788a137bc7cf04d7fb6eb27fea7b9fb673e20b887c2a6e5285c6c4a4b3bf27f7d45362360d3149851e50c32cff25e
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
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,17 +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.0'
5
+ s.version = FFI::Compiler::VERSION
4
6
  s.author = 'Wayne Meissner'
5
- s.email = 'wmeissner@gmail.com'
6
- s.homepage = 'http://wiki.github.com/ffi/ffi'
7
+ s.email = ['wmeissner@gmail.com', 'steve@advancedcontrol.com.au']
8
+ s.homepage = 'https://github.com/ffi/ffi-compiler'
7
9
  s.summary = 'Ruby FFI Rakefile generator'
8
10
  s.description = 'Ruby FFI library'
9
- s.files = %w(ffi-compiler.gemspec README.md Rakefile LICENSE) + Dir.glob("{lib,spec}/**/*")
10
- s.has_rdoc = false
11
- s.license = 'Apache 2.0'
11
+ s.files = %w(ffi-compiler.gemspec Gemfile Rakefile README.md LICENSE) + Dir.glob("{lib,spec}/**/*")
12
+ s.license = 'Apache-2.0'
12
13
  s.required_ruby_version = '>= 1.9'
13
14
  s.add_dependency 'rake'
14
- s.add_dependency 'ffi', '>= 1.0.0'
15
+ s.add_dependency 'ffi', '>= 1.15.5'
15
16
  s.add_development_dependency 'rspec'
16
17
  s.add_development_dependency 'rubygems-tasks'
17
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
147
  files = FileList["#{dir}/**/*.{c,cpp}"]
121
- unless @exclude.empty?
122
- files.delete_if { |f| f =~ Regexp.union(*@exclude) }
123
- end
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
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
- 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
@@ -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}/**/{#{FFI::Platform::ARCH}-#{FFI::Platform::OS}/#{library},#{library}}") do |f|
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
@@ -0,0 +1,7 @@
1
+
2
+ module FFI
3
+ module Compiler
4
+ VERSION = "1.3.1"
5
+ end
6
+ end
7
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ffi-compiler
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
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
10
  cert_chain: []
11
- date: 2016-07-06 00:00:00.000000000 Z
11
+ date: 2024-03-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 1.0.0
33
+ version: 1.15.5
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: 1.0.0
40
+ version: 1.15.5
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -67,11 +67,14 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  description: Ruby FFI library
70
- email: wmeissner@gmail.com
70
+ email:
71
+ - wmeissner@gmail.com
72
+ - steve@advancedcontrol.com.au
71
73
  executables: []
72
74
  extensions: []
73
75
  extra_rdoc_files: []
74
76
  files:
77
+ - Gemfile
75
78
  - LICENSE
76
79
  - README.md
77
80
  - Rakefile
@@ -82,13 +85,16 @@ files:
82
85
  - lib/ffi-compiler/fake_ffi/ffi-compiler/loader.rb
83
86
  - lib/ffi-compiler/fake_ffi/ffi.rb
84
87
  - lib/ffi-compiler/loader.rb
88
+ - lib/ffi-compiler/multi_file_task.rb
85
89
  - lib/ffi-compiler/platform.rb
90
+ - lib/ffi-compiler/shell.rb
86
91
  - lib/ffi-compiler/task.rb
87
- homepage: http://wiki.github.com/ffi/ffi
92
+ - lib/ffi-compiler/version.rb
93
+ homepage: https://github.com/ffi/ffi-compiler
88
94
  licenses:
89
- - Apache 2.0
95
+ - Apache-2.0
90
96
  metadata: {}
91
- post_install_message:
97
+ post_install_message:
92
98
  rdoc_options: []
93
99
  require_paths:
94
100
  - lib
@@ -103,10 +109,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
103
109
  - !ruby/object:Gem::Version
104
110
  version: '0'
105
111
  requirements: []
106
- rubyforge_project:
107
- rubygems_version: 2.5.1
108
- signing_key:
112
+ rubygems_version: 3.5.6
113
+ signing_key:
109
114
  specification_version: 4
110
115
  summary: Ruby FFI Rakefile generator
111
116
  test_files: []
112
- has_rdoc: false