ffi-compiler 0.0.2 → 0.0.3

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.
data/ffi-compiler.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'ffi-compiler'
3
- s.version = '0.0.2'
3
+ s.version = '0.0.3'
4
4
  s.author = 'Wayne Meissner'
5
5
  s.email = 'wmeissner@gmail.com'
6
6
  s.homepage = 'http://wiki.github.com/ffi/ffi'
@@ -2,18 +2,28 @@ require 'rake/tasklib'
2
2
  require 'rake/clean'
3
3
  require 'ffi'
4
4
  require 'tmpdir'
5
+ require 'rbconfig'
5
6
 
6
7
  module FFI
7
8
  class Compiler
9
+ DEFAULT_CFLAGS = %w(-fexceptions -O -fno-omit-frame-pointer -fno-strict-aliasing)
10
+ DEFAULT_LDFLAGS = %w(-fexceptions)
11
+
8
12
  class Task < Rake::TaskLib
13
+ attr_reader :cflags, :cxxflags, :ldflags, :libs
14
+
9
15
  def initialize(name)
10
- @name = name
16
+ @name = File.basename(name)
11
17
  @defines = []
12
18
  @include_paths = []
13
19
  @library_paths = []
14
20
  @libraries = []
15
21
  @headers = []
16
22
  @functions = []
23
+ @cflags = DEFAULT_CFLAGS.dup
24
+ @cxxflags = DEFAULT_CFLAGS.dup
25
+ @ldflags = DEFAULT_LDFLAGS.dup
26
+ @libs = []
17
27
 
18
28
  yield self if block_given?
19
29
  define_task!
@@ -40,55 +50,51 @@ module FFI
40
50
  try_library(libname, @library_paths) || try_library(libname, paths)
41
51
  end
42
52
 
43
- def create_rakefile!
44
- create_rakefile(@name)
45
- end
46
-
47
53
  private
48
54
  def define_task!
49
- lib_name = FFI.map_library_name(@name)
50
- pic_flags = '-fPIC'
51
- so_flags = ''
52
- ld_flags = ''
53
- cc = 'cc'
54
- cxx = 'c++'
55
- iflags = @include_paths.uniq.map { |p| "-I#{p}" }.join(' ')
56
- defines = @functions.uniq.map { |f| "-DHAVE_#{f.upcase}=1" }.join(' ')
57
- defines << " " + @headers.uniq.map { |h| "-DHAVE_#{h.upcase.sub(/\./, '_')}=1" }.join(' ')
58
-
55
+ pic_flags = %w(-fPIC)
56
+ so_flags = []
57
+
59
58
  if FFI::Platform.mac?
60
- pic_flags = ''
61
- ld_flags += ' -dynamiclib '
59
+ pic_flags = []
60
+ so_flags << '-dynamiclib'
62
61
 
63
62
  elsif FFI::Platform.name =~ /linux/
64
- so_flags += " -shared -Wl,-soname,#{lib_name} "
63
+ so_flags << "-shared -Wl,-soname,#{lib_name}"
64
+
65
+ else
66
+ so_flags << '-shared'
65
67
  end
68
+ so_flags = so_flags.join(' ')
69
+
70
+ lib_name = FFI.map_library_name(@name)
66
71
 
67
- cflags = "#{pic_flags} #{iflags} #{defines}".strip
68
- ld_flags += so_flags
69
- ld_flags += @library_paths.map { |path| "-L#{path}" }.join(' ')
70
- ld_flags.strip!
71
- ld = FileList['*.cpp'].empty? ? cc : cxx
72
- cxxflags = cflags
73
- libs = @libraries.map { |l| "-l#{l}" }.join(" ")
72
+ iflags = @include_paths.uniq.map { |p| "-I#{p}" }
73
+ defines = @functions.uniq.map { |f| "-DHAVE_#{f.upcase}=1" }
74
+ defines << @headers.uniq.map { |h| "-DHAVE_#{h.upcase.sub(/\./, '_')}=1" }
74
75
 
75
- obj_files = FileList['*.c', '*.cpp'].map { |f| f.gsub(/\.(c|cpp)$/, '.o') }
76
+ cflags = (@cflags + pic_flags + iflags + defines).join(' ')
77
+ cxxflags = (@cxxflags + @cflags + pic_flags + iflags + defines).join(' ')
78
+ ld_flags = (@library_paths.map { |path| "-L#{path}" } + @ldflags).join(' ')
79
+ libs = (@libraries.map { |l| "-l#{l}" } + @libs).join(' ')
80
+
81
+ src_files = FileList['*.{c,cpp}']
82
+ obj_files = src_files.ext '.o'
83
+ ld = src_files.detect { |f| f =~ /\.cpp$/ } ? cxx : cc
76
84
 
77
85
  CLEAN.include(obj_files)
78
86
 
79
- desc "Compile C file to object file"
80
- rule '.o' => ['.c'] do |t|
87
+ rule '.o' => '.c' do |t|
81
88
  sh "#{cc} #{cflags} -o #{t.name} -c #{t.source}"
82
89
  end
83
90
 
84
- desc "Compile C++ file to object file"
85
- rule '.o' => ['.cpp'] do |t|
91
+ rule '.o' => '.cpp' do |t|
86
92
  sh "#{cxx} #{cxxflags} -o #{t.name} -c #{t.source}"
87
93
  end
88
94
 
89
- desc "Compile to dynamic library"
95
+ desc "Build dynamic library"
90
96
  file lib_name => obj_files do |t|
91
- sh "#{ld} #{ld_flags} -o #{t.name} #{t.prerequisites.join(' ')} #{libs}"
97
+ sh "#{ld} #{so_flags} -o #{t.name} #{t.prerequisites.join(' ')} #{ld_flags} #{libs}"
92
98
  end
93
99
  CLEAN.include(lib_name)
94
100
 
@@ -138,16 +144,24 @@ module FFI
138
144
  def try_compile(src, *opts)
139
145
  Dir.mktmpdir do |dir|
140
146
  path = File.join(dir, 'ffi-test.c')
141
- File.open(path, "w") do |f|
147
+ File.open(path, 'w') do |f|
142
148
  f << src
143
149
  end
144
150
  begin
145
- return system "cc #{opts.join(' ')} -o #{File.join(dir, 'ffi-test')} #{path} >& /dev/null"
151
+ return system "#{cc} #{opts.join(' ')} -o #{File.join(dir, 'ffi-test')} #{path} >& /dev/null"
146
152
  rescue
147
153
  return false
148
154
  end
149
155
  end
150
156
  end
157
+
158
+ def cc
159
+ @cc ||= (ENV['CC'] || RbConfig::CONFIG['CC'] || 'cc')
160
+ end
161
+
162
+ def cxx
163
+ @cxx ||= (ENV['CXX'] || RbConfig::CONFIG['CXX'] || 'c++')
164
+ end
151
165
  end
152
166
  end
153
- end
167
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ffi-compiler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-16 00:00:00.000000000 Z
12
+ date: 2013-01-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -70,7 +70,6 @@ files:
70
70
  - Rakefile
71
71
  - LICENSE
72
72
  - lib/ffi-compiler/loader.rb
73
- - lib/ffi-compiler/mkrf.rb
74
73
  - lib/ffi-compiler/task.rb
75
74
  homepage: http://wiki.github.com/ffi/ffi
76
75
  licenses:
@@ -1,168 +0,0 @@
1
- require 'ffi'
2
- require 'tmpdir'
3
-
4
- module FFI
5
- class Compiler
6
- def initialize(name, &block)
7
- @name = name
8
- @defines = []
9
- @include_paths = []
10
- @library_paths = []
11
- @libraries = []
12
- @headers = []
13
- @functions = []
14
-
15
- if block_given?
16
- yield self
17
- create_rakefile!
18
- end
19
- end
20
-
21
- def have_func?(func)
22
- main = <<-C_FILE
23
- extern void #{func}();
24
- int main(int argc, char **argv) { #{func}(); return 0; }
25
- C_FILE
26
-
27
- if try_compile(main)
28
- @functions << func
29
- return true
30
- end
31
- false
32
- end
33
-
34
- def have_header?(header, *paths)
35
- try_header(header, @include_paths) || try_header(header, paths)
36
- end
37
-
38
- def have_library?(libname, *paths)
39
- try_library(libname, @library_paths) || try_library(libname, paths)
40
- end
41
-
42
- def create_rakefile!
43
- create_rakefile(@name)
44
- end
45
-
46
- private
47
-
48
- def try_header(header, paths)
49
- main = <<-C_FILE
50
- #include <#{header}>
51
- int main(int argc, char **argv) { return 0; }
52
- C_FILE
53
-
54
- if paths.empty? && try_compile(main)
55
- @headers << header
56
- return true
57
- end
58
-
59
- paths.each do |path|
60
- if try_compile(main, "-I#{path}")
61
- @include_paths << path
62
- @headers << header
63
- return true
64
- end
65
- end
66
- false
67
- end
68
-
69
-
70
- def try_library(libname, paths)
71
- main = <<-C_FILE
72
- int main(int argc, char **argv) { return 0; }
73
- C_FILE
74
-
75
- if paths.empty? && try_compile(main)
76
- @libraries << libname
77
- return true
78
- end
79
-
80
- paths.each do |path|
81
- if try_compile(main, "-L#{path}", "-l#{libname}")
82
- @library_paths << path
83
- @libraries << libname
84
- end
85
- end
86
- end
87
-
88
- def try_compile(src, *opts)
89
- Dir.mktmpdir do |dir|
90
- path = File.join(dir, 'ffi-test.c')
91
- File.open(path, "w") do |f|
92
- f << src
93
- end
94
- begin
95
- return system "cc #{opts.join(' ')} -o #{File.join(dir, 'ffi-test')} #{path} >& /dev/null"
96
- rescue
97
- return false
98
- end
99
- end
100
- end
101
-
102
- def create_rakefile(name)
103
- lib_name = FFI.map_library_name(name)
104
- pic_flags = '-fPIC'
105
- so_flags = ''
106
- ld_flags = ''
107
- cc = 'cc'
108
- cxx = 'c++'
109
- iflags = @include_paths.uniq.map{ |p| "-I#{p}" }.join(' ')
110
- defines = @functions.uniq.map { |f| "-DHAVE_#{f.upcase}=1" }.join(' ')
111
- defines << " " + @headers.uniq.map { |h| "-DHAVE_#{h.upcase.sub(/\./, '_')}=1" }.join(' ')
112
-
113
- if FFI::Platform.mac?
114
- pic_flags = ''
115
- ld_flags += ' -dynamiclib '
116
-
117
- elsif FFI::Platform.name =~ /linux/
118
- so_flags += " -shared -Wl,-soname,#{lib_name} "
119
- end
120
-
121
- cflags = "#{pic_flags} #{iflags} #{defines}".strip
122
- ld_flags += so_flags
123
- ld_flags += @library_paths.map { |path| "-L#{path}" }.join(' ')
124
- ld_flags.strip!
125
-
126
- File.open('Rakefile', 'w') do |f|
127
- f.puts <<-RAKEFILE
128
-
129
- require 'rake/clean'
130
-
131
- CC = '#{cc}'
132
- CXX = '#{cxx}'
133
- LD = FileList['*.cpp'].empty? ? CC : CXX
134
- CFLAGS = '#{cflags}'
135
- CXXFLAGS = '#{cflags}'
136
- LDFLAGS = '#{ld_flags}'
137
- LIBS = '#{@libraries.map {|l| "-l#{l}" }.join(" ")}'
138
-
139
- OBJ_FILES = FileList['*.c', '*.cpp'].map { |f| f.gsub(/\.(c|cpp)$/, '.o') }
140
-
141
- CLEAN.include(OBJ_FILES)
142
-
143
- desc "Compile C file to object file"
144
- rule '.o' => [ '.c' ] do |t|
145
- sh "\#{CC} \#{CFLAGS} -o \#{t.name} -c \#{t.source}"
146
- end
147
-
148
- desc "Compile C++ file to object file"
149
- rule '.o' => [ '.cpp' ] do |t|
150
- sh "\#{CXX} \#{CXXFLAGS} -o \#{t.name} -c \#{t.source} "
151
- end
152
-
153
- desc "Compile to dynamic library"
154
- task :compile => "#{lib_name}"
155
-
156
- file "#{lib_name}" => OBJ_FILES do |t|
157
- sh "\#{LD} \#{LDFLAGS} -o \#{t.name} \#{t.prerequisites.join(' ')} \#{LIBS}"
158
- end
159
-
160
- task :default => :compile
161
-
162
- RAKEFILE
163
- end
164
- end
165
-
166
- end
167
- end
168
-