rake-builder 0.0.12 → 0.0.13

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/Rakefile CHANGED
@@ -23,6 +23,7 @@ spec = Gem::Specification.new do |s|
23
23
  s.homepage = 'http://github.com/joeyates/rake-builder'
24
24
  s.author = 'Joe Yates'
25
25
  s.email = 'joe.g.yates@gmail.com'
26
+ s.rubyforge_project = 'nowarning'
26
27
 
27
28
  s.files = ADMIN_FILES +
28
29
  SOURCE_FILES +
data/lib/compiler.rb ADDED
@@ -0,0 +1,84 @@
1
+
2
+ module Compiler
3
+
4
+ class Base
5
+ EXTRA_PATHS = [ '/opt/local/include' ]
6
+
7
+ def self.for( compiler )
8
+ COMPILERS[ compiler ].new
9
+ end
10
+
11
+ def initialize
12
+ @paths = {}
13
+ end
14
+
15
+ def include_paths( headers )
16
+ paths = []
17
+ headers.each do | header |
18
+ path = find_header( header )
19
+ raise "Can't find header '#{ header }' in any known include path" if path.nil?
20
+ paths << path
21
+ end
22
+ paths.uniq
23
+ end
24
+
25
+ private
26
+
27
+ def find_header( header )
28
+ EXTRA_PATHS.each do | path |
29
+ if File.exist?( "#{ path }/#{ header }" )
30
+ return path
31
+ end
32
+ end
33
+ nil
34
+ end
35
+
36
+ end
37
+
38
+ class GCC < Base
39
+
40
+ def self.framework_path( framework, qt_major )
41
+ "/Library/Frameworks/#{ framework }.framework/Versions/#{ qt_major }/Headers"
42
+ end
43
+
44
+ def default_include_paths( language )
45
+ return @paths[ language ] if @paths[ language ]
46
+
47
+ paths = []
48
+ # Below is the recommended(!) way of getting standard serach paths from GCC
49
+ output = `echo | gcc -v -x #{ language } -E - 2>&1 1>/dev/null`
50
+ collecting = false
51
+ output.each_line do | line |
52
+ case
53
+ when line =~ /#include <\.\.\.> search starts here:/
54
+ collecting = true
55
+ when line =~ /End of search list\./
56
+ collecting = false
57
+ when line =~ / \(framework directory\)/
58
+ # Skip frameworks
59
+ else
60
+ paths << line.strip if collecting
61
+ end
62
+ end
63
+
64
+ @paths[ language ] = paths
65
+ end
66
+
67
+ def missing_headers( include_paths, source_files )
68
+ include_path = include_paths.map { | path | "-I#{ path }" }.join( ' ' )
69
+ command = "makedepend -f- -- #{ include_path } -- #{ source_files.join( ' ' ) } 2>&1 1>/dev/null"
70
+ output = `#{ command }`
71
+ missing = []
72
+ output.each_line do | line |
73
+ match = line.match( /cannot find include file "([^"]*)"/m )
74
+ missing << match[ 1 ] if match
75
+ end
76
+
77
+ missing
78
+ end
79
+
80
+ end
81
+
82
+ COMPILERS = { :gcc => GCC }
83
+
84
+ end
@@ -8,10 +8,10 @@ module Rake
8
8
  # generate Info.plist
9
9
  # package task
10
10
 
11
+ attr_accessor :qt_version
11
12
  attr_accessor :frameworks
12
13
  attr_accessor :resource_files
13
- attr_accessor :qt_version
14
- attr_accessor :architecture
14
+ attr_accessor :ui_files
15
15
 
16
16
  def initialize( &block )
17
17
  super( &block )
@@ -25,11 +25,20 @@ module Rake
25
25
  super
26
26
  @programming_language = 'c++'
27
27
  @header_file_extension = 'h'
28
- @frameworks = [ 'QtGui', 'QtCore' ]
29
- @framework_paths = [ '/Library/Frameworks' ]
30
- @compilation_defines = '-DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED'
31
- @moc_defines = '-D__APPLE__ -D__GNUC__'
28
+ @frameworks = []
29
+ case
30
+ when RUBY_PLATFORM =~ /linux$/
31
+ @include_paths << '/usr/include/qt4'
32
+ @moc_defines = [ '-D__GNUC__' ]
33
+ when RUBY_PLATFORM =~ /darwin/i
34
+ @framework_paths = [ '/Library/Frameworks' ]
35
+ @moc_defines = [ '-D__APPLE__', '-D__GNUC__' ]
36
+ else
37
+ raise "Unrecognised platform"
38
+ end
39
+ @compilation_defines = [ '-DQT_GUI_LIB', '-DQT_CORE_LIB', '-DQT_SHARED' ]
32
40
  @resource_files = []
41
+ @ui_files = []
33
42
  end
34
43
 
35
44
  def configure
@@ -39,37 +48,83 @@ module Rake
39
48
  super
40
49
 
41
50
  @resource_files = Rake::Path.expand_all_with_root( @resource_files, @rakefile_path )
51
+ @ui_files = Rake::Path.expand_all_with_root( @ui_files, @rakefile_path )
42
52
  @compilation_options += [ '-pipe', '-g', '-gdwarf-2', '-Wall', '-W' ]
43
- @compilation_options.uniq!
44
- @architecture ||= 'i386'
45
- @compilation_options += [ architecture_option ]
46
-
47
- @frameworks.each do | framework |
48
- @include_paths << "/Library/Frameworks/#{ framework }.framework/Versions/#{ qt_major }/Headers"
49
- @include_paths << "/usr/include/#{ framework }"
50
- end
53
+ @include_paths << @objects_path # for UI headers
51
54
  end
52
55
 
53
56
  def define
54
57
  super
58
+ define_ui_tasks
55
59
  define_moc_tasks
56
60
  define_resource_tasks
57
61
  end
58
62
 
59
63
  def generated_files
60
- super + moc_files + qrc_files
64
+ super + moc_files + ui_headers + qrc_files
65
+ end
66
+
67
+ def generated_headers
68
+ super + ui_headers
61
69
  end
62
70
 
63
71
  def source_files
64
72
  ( super + moc_files + qrc_files ).uniq
65
73
  end
66
74
 
75
+ def header_files
76
+ ( super + ui_headers ).uniq
77
+ end
78
+
67
79
  def compiler_flags
68
- [ compilation_options.join( ' ' ), @compilation_defines, include_path, framework_path_list ].join( ' ' )
80
+ flags = compilation_options + @compilation_defines + [ include_path ]
81
+ if RUBY_PLATFORM =~ /darwin/i
82
+ flags += framework_paths
83
+ flags << architecture_option
84
+ end
85
+ flags.join( ' ' )
69
86
  end
70
87
 
71
88
  def link_flags
72
- [ '-headerpad_max_install_names', architecture_option, @linker_options, library_paths_list, library_dependencies_list, framework_path_list, framework_list ].join( " " )
89
+ flags = [ @linker_options, library_paths_list, library_dependencies_list ]
90
+ if RUBY_PLATFORM =~ /darwin/i
91
+ flags += [ '-headerpad_max_install_names', architecture_option ]
92
+ flags += framework_paths + framework_options
93
+ end
94
+ flags.join( ' ' )
95
+ end
96
+
97
+ # Exclude paths like QtFoo/Bar, but grab frameworks
98
+ def missing_headers
99
+ super
100
+ @missing_headers.reject! do | path |
101
+ m = path.match( /^(Qt\w+)\/(\w+?(?:\.h)?)$/ )
102
+ if m
103
+ framework = m[ 1 ]
104
+ @frameworks << framework
105
+ framework_path = Compiler::GCC.framework_path( framework, qt_major )
106
+ header_path = "#{ framework_path }/#{ m[ 2 ] }"
107
+ File.exist?( header_path )
108
+ else
109
+ false
110
+ end
111
+ end
112
+
113
+ @frameworks.each do | framework |
114
+ @include_paths << Compiler::GCC.framework_path( framework, qt_major )
115
+ @include_paths << "/usr/include/#{ framework }"
116
+ end
117
+
118
+ # Last chance: exclude headers of the form 'Aaaaaa' if found under frameworks
119
+ @missing_headers.reject! do | header |
120
+ @frameworks.any? do | framework |
121
+ framework_path = Compiler::GCC.framework_path( framework, qt_major )
122
+ header_path = "#{ framework_path }/#{ header }"
123
+ File.exist?( header_path )
124
+ end
125
+ end
126
+
127
+ @missing_headers
73
128
  end
74
129
 
75
130
  # QT-specific
@@ -78,18 +133,38 @@ module Rake
78
133
  @qt_version.match( /^(\d+)/ )[ 1 ]
79
134
  end
80
135
 
81
- def architecture_option
82
- "-arch #{ @architecture }"
136
+ def framework_paths
137
+ @framework_paths.map { |p| "-F#{ p }" }
138
+ end
139
+
140
+ def framework_options
141
+ @frameworks.map { |p| "-framework #{ p }" }
83
142
  end
84
143
 
85
- def framework_path_list
86
- @framework_paths.map { |p| "-F#{ p }" }.join( " " )
144
+ # UI
145
+ # /Developer/Tools/Qt/uic ../scanner_cpp/mainwindow.ui -o ui_mainwindow.h
146
+
147
+ def define_ui_tasks
148
+ @ui_files.each do | ui_file |
149
+ ui_header = ui_header_path( ui_file )
150
+ file ui_header => [ @objects_path, ui_file ] do |t|
151
+ command = "uic #{ ui_file } -o #{ ui_header }"
152
+ shell command
153
+ end
154
+ end
87
155
  end
88
156
 
89
- def framework_list
90
- @frameworks.map { |p| "-framework #{ p }" }.join( " " )
157
+ def ui_headers
158
+ @ui_files.collect do | ui_file |
159
+ ui_header_path( ui_file )
160
+ end
161
+ end
162
+
163
+ def ui_header_path( ui_file )
164
+ header_name = 'ui_' + File.basename( ui_file ).gsub( '.ui', '.h' )
165
+ Rake::Path.expand_with_root( header_name, @objects_path )
91
166
  end
92
-
167
+
93
168
  # MOC
94
169
 
95
170
  def define_moc_tasks
@@ -98,7 +173,10 @@ module Rake
98
173
  moc = moc_pathname( header_file )
99
174
 
100
175
  file moc => [ header_file ] do |t|
101
- command = "moc #{ @compilation_defines } #{ framework_path_list } #{ @moc_defines } #{ header_file } -o #{ moc }"
176
+ options = @compilation_defines
177
+ options += framework_paths if RUBY_PLATFORM =~ /darwin/i
178
+ options += @moc_defines
179
+ command = "moc #{ options.join( ' ' ) } #{ header_file } -o #{ moc }"
102
180
  shell command
103
181
  end
104
182
 
data/lib/rake/builder.rb CHANGED
@@ -5,6 +5,7 @@ require 'rake'
5
5
  require 'rake/tasklib'
6
6
  require 'rake/path'
7
7
  require 'rake/file_task_alias'
8
+ require 'compiler'
8
9
 
9
10
  module Rake
10
11
 
@@ -23,8 +24,8 @@ module Rake
23
24
  module VERSION #:nodoc:
24
25
  MAJOR = 0
25
26
  MINOR = 0
26
- TINY = 12
27
-
27
+ TINY = 13
28
+
28
29
  STRING = [ MAJOR, MINOR, TINY ].join('.')
29
30
  end
30
31
 
@@ -39,7 +40,10 @@ module Rake
39
40
  # The types of file that can be built
40
41
  TARGET_TYPES = [ :executable, :static_library, :shared_library ]
41
42
 
42
- # The programming language: 'c++' or 'c' (default 'c++')
43
+ # processor type: 'i386', 'x86_64', 'ppc' or 'ppc64'.
44
+ attr_accessor :architecture
45
+
46
+ # The programming language: 'c++', 'c' or 'objective-c' (default 'c++')
43
47
  # This also sets defaults for source_file_extension
44
48
  attr_accessor :programming_language
45
49
 
@@ -165,6 +169,8 @@ module Rake
165
169
  end
166
170
 
167
171
  def initialize_attributes
172
+ @architecture = 'i386'
173
+ @compiler_data = Compiler::Base.for( :gcc )
168
174
  @logger = Logger.new( STDOUT )
169
175
  @logger.level = Logger::UNKNOWN
170
176
  @logger.formatter = Formatter.new
@@ -179,9 +185,13 @@ module Rake
179
185
  @target = 'a.out'
180
186
  @generated_files = []
181
187
  @compilation_options = []
188
+ @include_paths = []
182
189
  end
183
190
 
184
191
  def configure
192
+ @compilation_options += [ architecture_option ] if RUBY_PLATFORM =~ /apple/i
193
+ @compilation_options.uniq!
194
+
185
195
  @programming_language.downcase!
186
196
  raise "Don't know how to build '#{ @programming_language }' programs" if KNOWN_LANGUAGES[ @programming_language ].nil?
187
197
  @compiler ||= KNOWN_LANGUAGES[ @programming_language ][ :compiler ]
@@ -201,7 +211,8 @@ module Rake
201
211
  @install_path ||= default_install_path( @target_type )
202
212
 
203
213
  @linker_options ||= ''
204
- @include_paths ||= @header_search_paths.dup
214
+ @include_paths += []
215
+ @include_paths = Rake::Path.expand_all_with_root( @include_paths.uniq, @rakefile_path )
205
216
  @generated_files = Rake::Path.expand_all_with_root( @generated_files, @rakefile_path )
206
217
 
207
218
  @default_task ||= :build
@@ -209,32 +220,9 @@ module Rake
209
220
 
210
221
  @makedepend_file = @objects_path + '/.' + target_basename + '.depend.mf'
211
222
 
212
- load_local_config
213
-
214
- @include_paths = Rake::Path.expand_all_with_root( @include_paths, @rakefile_path )
215
-
216
223
  raise "No source files found" if source_files.length == 0
217
224
  end
218
225
 
219
- def local_config
220
- filename = '.rake-builder'
221
- filename += '.' + @task_namespace.to_s if @task_namespace
222
- Rake::Path.expand_with_root( filename, @rakefile_path )
223
- end
224
-
225
- def load_local_config
226
- return if ! File.exist?( local_config )
227
-
228
- config = YAML.load_file( local_config )
229
-
230
- version = config[ :rake_builder ][ :config_file ][ :version ]
231
- raise "Config file version missing" if version.nil?
232
-
233
- @include_paths += config[ :include_paths ] if config[ :include_paths ]
234
- rescue => e
235
- raise "#{__FILE__}:#{__LINE__}: Failed to load local config file '#{ local_config }': #{ e.message }"
236
- end
237
-
238
226
  def define_tasks
239
227
  if @task_namespace
240
228
  namespace @task_namespace do
@@ -287,12 +275,38 @@ module Rake
287
275
 
288
276
  directory @objects_path
289
277
 
290
- file @makedepend_file => [ @objects_path, *project_files ] do
278
+ file local_config => scoped_task( :missing_headers ) do
279
+ added_includes = @compiler_data.include_paths( missing_headers )
280
+ config = { :rake_builder => { :config_file => { :version=> '1.0' } },
281
+ :include_paths => added_includes }
282
+ File.open( local_config, 'w' ) do | file |
283
+ file.write config.to_yaml
284
+ end
285
+ end
286
+
287
+ file @makedepend_file => [ scoped_task( :load_local_config ),
288
+ scoped_task( :missing_headers ),
289
+ @objects_path,
290
+ *project_files ] do
291
291
  @logger.add( Logger::DEBUG, "Analysing dependencies" )
292
292
  command = "makedepend -f- -- #{ include_path } -- #{ file_list( source_files ) } 2>/dev/null > #{ @makedepend_file }"
293
293
  shell command
294
294
  end
295
295
 
296
+ task :load_local_config => local_config do
297
+ config = YAML.load_file( local_config )
298
+
299
+ version = config[ :rake_builder ][ :config_file ][ :version ]
300
+ raise "Config file version missing" if version.nil?
301
+
302
+ config[ :include_paths ] ||= []
303
+ @include_paths += Rake::Path.expand_all_with_root( config[ :include_paths ], @rakefile_path )
304
+ end
305
+
306
+ task :missing_headers => [ *generated_headers ] do
307
+ missing_headers
308
+ end
309
+
296
310
  # Reimplemented mkdepend file loading to make objects depend on
297
311
  # sources with the correct paths:
298
312
  # the standard rake mkdepend loader doesn't do what we want,
@@ -355,6 +369,10 @@ module Rake
355
369
  end
356
370
  end
357
371
 
372
+ def generated_headers
373
+ []
374
+ end
375
+
358
376
  def scoped_task( task )
359
377
  if @task_namespace
360
378
  "#{ task_namespace }:#{ task }"
@@ -368,7 +386,8 @@ module Rake
368
386
  @generated_files << object
369
387
  file object => [ source ] do |t|
370
388
  @logger.add( Logger::INFO, "Compiling '#{ source }'" )
371
- shell "#{ @compiler } -c #{ compiler_flags } -o #{ object } #{ source }"
389
+ command = "#{ @compiler } -c #{ compiler_flags } -o #{ object } #{ source }"
390
+ shell command
372
391
  end
373
392
  end
374
393
 
@@ -395,6 +414,15 @@ module Rake
395
414
  end
396
415
  end
397
416
 
417
+ # Discovery
418
+
419
+ def missing_headers
420
+ return @missing_headers if @missing_headers
421
+ default_includes = @compiler_data.default_include_paths( @programming_language )
422
+ all_includes = default_includes + @include_paths
423
+ @missing_headers = @compiler_data.missing_headers( all_includes, source_files )
424
+ end
425
+
398
426
  # Compiling and linking parameters
399
427
 
400
428
  def include_path
@@ -402,21 +430,34 @@ module Rake
402
430
  end
403
431
 
404
432
  def compiler_flags
405
- include_path + ' ' + compilation_options.join( " " )
433
+ flags = include_path + ' ' + compilation_options.join( ' ' )
434
+ flags << ' ' << architecture_option if RUBY_PLATFORM =~ /darwin/i
435
+ flags
436
+ end
437
+
438
+ def architecture_option
439
+ "-arch #{ @architecture }"
406
440
  end
407
441
 
408
442
  def link_flags
409
- [ @linker_options, library_paths_list, library_dependencies_list ].join( " " )
443
+ flags = [ @linker_options, architecture_option, library_paths_list, library_dependencies_list ]
444
+ flags << architecture_option if RUBY_PLATFORM =~ /darwin/i
445
+ flags.join( " " )
410
446
  end
411
447
 
412
448
  # Paths
413
449
 
450
+ def local_config
451
+ filename = '.rake-builder'
452
+ Rake::Path.expand_with_root( filename, @rakefile_path )
453
+ end
454
+
414
455
  def save_rakefile_info( block )
415
456
  if RUBY_VERSION < '1.9'
416
457
  # Hack the path from the block String representation
417
458
  @rakefile = block.to_s.match( /@([^\:]+):/ )[ 1 ]
418
459
  else
419
- @rakefile = block.source_location
460
+ @rakefile = block.source_location[ 0 ]
420
461
  end
421
462
  @rakefile_path = File.expand_path( File.dirname( @rakefile ) )
422
463
  end
@@ -455,8 +496,8 @@ module Rake
455
496
  source_files + header_files
456
497
  end
457
498
 
458
- def file_list( files )
459
- files.join( " " )
499
+ def file_list( files, delimiter = ' ' )
500
+ files.join( delimiter )
460
501
  end
461
502
 
462
503
  def library_paths_list
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rake-builder
3
3
  version: !ruby/object:Gem::Version
4
- hash: 7
4
+ hash: 5
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 12
10
- version: 0.0.12
9
+ - 13
10
+ version: 0.0.13
11
11
  platform: ruby
12
12
  authors:
13
13
  - Joe Yates
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-12-30 00:00:00 +01:00
18
+ date: 2011-02-20 00:00:00 +00:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -43,6 +43,7 @@ extensions: []
43
43
  extra_rdoc_files:
44
44
  - COPYING
45
45
  - README.rdoc
46
+ - lib/compiler.rb
46
47
  - lib/rake/builder/qt_builder.rb
47
48
  - lib/rake/builder.rb
48
49
  - lib/rake/file_task_alias.rb
@@ -59,6 +60,7 @@ files:
59
60
  - COPYING
60
61
  - Rakefile
61
62
  - README.rdoc
63
+ - lib/compiler.rb
62
64
  - lib/rake/builder/qt_builder.rb
63
65
  - lib/rake/builder.rb
64
66
  - lib/rake/file_task_alias.rb
@@ -131,7 +133,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
131
133
  version: "0"
132
134
  requirements: []
133
135
 
134
- rubyforge_project:
136
+ rubyforge_project: nowarning
135
137
  rubygems_version: 1.3.7
136
138
  signing_key:
137
139
  specification_version: 3