autobuild 1.7.10 → 1.7.11.rc1

Sign up to get free protection for your applications and to get access to all the features.
@@ -44,7 +44,11 @@ module Autobuild
44
44
  end
45
45
  end
46
46
 
47
- def update(package)
47
+ def update(package,only_local=false)
48
+ if only_local
49
+ Autobuild.warn "The importer #{self.class} does not support local updates, skipping #{self}"
50
+ return
51
+ end
48
52
  validate_importdir(package)
49
53
  Dir.chdir(package.importdir) do
50
54
  Subprocess.run(package, :import, Autobuild.tool('hg'), 'pull', repository)
@@ -35,7 +35,11 @@ module Autobuild
35
35
 
36
36
  private
37
37
 
38
- def update(package) # :nodoc:
38
+ def update(package,only_local=false) # :nodoc:
39
+ if only_local
40
+ Autobuild.warn "The importer #{self.class} does not support local updates, skipping #{self}"
41
+ return
42
+ end
39
43
  Dir.chdir(package.importdir) do
40
44
  old_lang, ENV['LC_ALL'] = ENV['LC_ALL'], 'C'
41
45
  svninfo = []
@@ -119,7 +119,7 @@ class Importer
119
119
  end
120
120
  end
121
121
 
122
- def perform_update(package)
122
+ def perform_update(package,only_local=false)
123
123
  cur_patches = currently_applied_patches(package)
124
124
  needed_patches = self.patches
125
125
  if cur_patches.map(&:last) != needed_patches.map(&:last)
@@ -129,7 +129,7 @@ class Importer
129
129
  retry_count = 0
130
130
  package.progress_start "updating %s"
131
131
  begin
132
- update(package)
132
+ update(package,only_local)
133
133
  rescue Interrupt
134
134
  raise
135
135
  rescue ::Exception => original_error
@@ -146,7 +146,7 @@ class Importer
146
146
  package.message "update failed and some patches are applied, retrying after removing all patches first"
147
147
  begin
148
148
  patch(package, [])
149
- return perform_update(package)
149
+ return perform_update(package,only_local)
150
150
  rescue Interrupt
151
151
  raise
152
152
  rescue ::Exception
@@ -204,12 +204,12 @@ class Importer
204
204
  end
205
205
 
206
206
  # Performs the import of +package+
207
- def import(package)
207
+ def import(package,only_local = false)
208
208
  importdir = package.importdir
209
209
  if File.directory?(importdir)
210
210
  package.isolate_errors(false) do
211
211
  if package.update?
212
- perform_update(package)
212
+ perform_update(package,only_local)
213
213
  else
214
214
  if Autobuild.verbose
215
215
  package.message "%s: not updating"
@@ -1,7 +1,3 @@
1
- require 'autobuild/timestamps'
2
- require 'autobuild/environment'
3
- require 'autobuild/subcommand'
4
-
5
1
  module Autobuild
6
2
  TARGETS = %w{import prepare build}
7
3
 
@@ -63,6 +59,9 @@ module Autobuild
63
59
  # Sets the log directory. If no value is set, the package will use
64
60
  # Autobuild.logdir
65
61
  attr_writer :logdir
62
+ # The set of utilities attached to this package
63
+ # @return [{String=>Utility}]
64
+ attr_reader :utilities
66
65
 
67
66
  # Sets importer object for this package. Defined for backwards compatibility.
68
67
  # Use the #importer attribute instead
@@ -135,6 +134,7 @@ module Autobuild
135
134
  @failures = Array.new
136
135
  @post_install_blocks = Array.new
137
136
  @in_dir_stack = Array.new
137
+ @utilities = Hash.new
138
138
 
139
139
  if Hash === spec
140
140
  name, depends = spec.to_a.first
@@ -150,8 +150,8 @@ module Autobuild
150
150
  # Call the config block (if any)
151
151
  yield(self) if block_given?
152
152
 
153
- @doc_dir ||= 'doc'
154
- @doc_target_dir ||= name
153
+ self.doc_utility.source_dir ||= 'doc'
154
+ self.doc_utility.target_dir ||= name
155
155
 
156
156
  # Define the default tasks
157
157
  task "#{name}-import" do
@@ -260,9 +260,9 @@ module Autobuild
260
260
  # Call the importer if there is one. Autodetection of "provides" should
261
261
  # be done there as well. See the documentation of Autobuild::Package for
262
262
  # more information.
263
- def import
263
+ def import(only_local=false)
264
264
  if @importer
265
- @importer.import(self)
265
+ @importer.import(self,only_local)
266
266
  elsif Autobuild.do_update
267
267
  message "%s: no importer defined, doing nothing"
268
268
  end
@@ -377,34 +377,6 @@ module Autobuild
377
377
  Autobuild::Subprocess.run(self, *args, &block)
378
378
  end
379
379
 
380
- # Directory in which the documentation target will have generated the
381
- # documentation (if any). The interpretation of relative directories
382
- # is package-specific. The default implementation interpret them
383
- # as relative to the source directory, but packages like CMake will
384
- # interpret them as relative to their build directories.
385
- attr_writer :doc_dir
386
-
387
- # Absolute path to where documentation is generated. Returns nil if the
388
- # doc_dir attribute is not set.
389
- def doc_dir
390
- if @doc_dir
391
- File.expand_path(@doc_dir, srcdir)
392
- end
393
- end
394
-
395
- # Directory in which the documentation target should install the
396
- # documentation. If it is relative, it is interpreted as relative to
397
- # the documentation prefix directory (Autobuild.doc_prefix)
398
- attr_writer :doc_target_dir
399
-
400
- # Absolute path to where documentation has to be installed. Returns nil
401
- # if the doc_target_dir attribute is not set.
402
- def doc_target_dir
403
- if @doc_target_dir
404
- File.expand_path(@doc_target_dir, File.expand_path(Autobuild.doc_prefix || '.', prefix))
405
- end
406
- end
407
-
408
380
  module TaskExtension
409
381
  attr_accessor :package
410
382
  end
@@ -432,101 +404,44 @@ module Autobuild
432
404
  task
433
405
  end
434
406
 
435
- # Defines a documentation generation task. The documentation is first
436
- # generated by the given block, and then installed. The local attribute
437
- # #doc_dir defines where the documentation is generated by the
438
- # package's build system, and the #doc_target_dir and
439
- # Autobuild.doc_prefix attributes define where it should be installed.
440
- #
441
- # The block is invoked in the package's source directory
442
- #
443
- # In general, specific package types define a meaningful #with_doc
444
- # method which calls this method internally.
445
- def doc_task
446
- @doc_task = task "#{name}-doc" => "#{name}-build" do
447
- # This flag allows to disable documentation generation
448
- # once doc_task has been called
449
- if generates_doc?
450
- @installed_doc = false
451
- catch(:doc_disabled) do
452
- begin
453
- yield if block_given?
454
-
455
- unless @installed_doc
456
- install_doc
457
- end
458
-
459
- rescue Interrupt
460
- raise
461
- rescue ::Exception => e
462
- if Autobuild.doc_errors
463
- raise
464
- else
465
- warn "%s: failed to generate documentation"
466
- if e.kind_of?(SubcommandFailed)
467
- warn "%s: see #{e.logfile} for more details"
468
- else
469
- warn "%s: #{e.message}"
470
- end
471
- end
472
- end
473
- end
474
- end
475
- end
476
-
477
- task :doc => "#{name}-doc"
478
- end
479
-
480
- # True if some documentation will be generated and false otherwise.
481
- #
482
- # This will return true only if a documentation task has been defined by
483
- # calling #doc_task _and_ #disable_doc has not been called (or if
484
- # #enable_doc has been called after the last call to #disable_doc).
485
- def generates_doc?
486
- if @doc_disabled
487
- return false
488
- else
489
- return !!@doc_task
490
- end
491
- end
492
-
493
- # Re-enables documentation generation after #disable_doc has been called
494
- def enable_doc
495
- @doc_disabled = false
407
+ module TaskExtension
408
+ attr_accessor :package
496
409
  end
497
410
 
498
- # Disables any documentation generation, regardless of whether doc_task
499
- # has been called or not.
500
- def disable_doc
501
- @doc_disabled = true
411
+ def source_tree(*args, &block)
412
+ task = Autobuild.source_tree(*args, &block)
413
+ task.extend TaskExtension
414
+ task.package = self
415
+ task
502
416
  end
503
417
 
504
- def install_doc
505
- if !File.directory?(self.doc_dir)
506
- raise "#{self.doc_dir} was expected to be a directory, but it is not. Check the package's documentation generation, the generated documentation should be in #{self.doc_dir}"
507
- end
508
-
509
- doc_target_dir = self.doc_target_dir
510
- doc_dir = self.doc_dir
511
- FileUtils.rm_rf doc_target_dir
512
- FileUtils.mkdir_p File.dirname(doc_target_dir)
513
- FileUtils.cp_r doc_dir, doc_target_dir
514
-
515
- @installed_doc = true
418
+ # Calls Rake to define a file task and then extends it with TaskExtension
419
+ def file(*args, &block)
420
+ task = super
421
+ task.extend TaskExtension
422
+ task.package = self
423
+ task
516
424
  end
517
425
 
518
- # Can be called in the doc_task implementation to announce that the
519
- # documentation is to be disabled for that package. This is mainly used
520
- # when a runtime check is necessary to know if a package has
521
- # documentation or not.
522
- def doc_disabled
523
- throw :doc_disabled
426
+ # Calls Rake to define a plain task and then extends it with TaskExtension
427
+ def task(*args, &block)
428
+ task = super
429
+ task.extend TaskExtension
430
+ task.package = self
431
+ task
524
432
  end
525
433
 
526
- # True if a documentation task is defined for this package
527
- def has_doc?
528
- !!Rake.application.lookup("#{name}-doc")
529
- end
434
+ def doc_dir=(value); doc_utility.source_dir = value end
435
+ def doc_dir; doc_utility.source_dir end
436
+ def doc_target_dir=(value); doc_utility.target_dir = value end
437
+ def doc_target_dir; doc_utility.target_dir end
438
+ def doc_task(&block); doc_utility.task(&block) end
439
+ def generates_doc?; doc_utility.enabled? end
440
+ def enable_doc; doc_utility.enabled = true end
441
+ def disable_doc; doc_utility.enabled = false end
442
+ def install_doc; doc_utility.install end
443
+ def doc_disabled; doc_utility.disabled end
444
+ def has_doc?; doc_utility.has_task? end
530
445
 
531
446
  def post_install(*args, &block)
532
447
  if args.empty?
@@ -668,19 +583,43 @@ module Autobuild
668
583
  @disabled
669
584
  end
670
585
 
671
- # Make sure that this package will be ignored in the build
672
- def disable
673
- @disabled = true
674
- %w{import prepare build doc}.each do |phase|
586
+ # Makes sure that the specified phases of this package will be no-ops
587
+ def disable_phases(*phases)
588
+ phases.each do |phase|
675
589
  task "#{name}-#{phase}"
676
590
  t = Rake::Task["#{name}-#{phase}"]
677
- def t.needed?; false end
678
- t.instance_variable_set :@already_invoked, true
591
+ t.disable!
679
592
  end
593
+ end
594
+
595
+ # Make sure that this package will be ignored in the build
596
+ def disable(phases = Autobuild.all_phases)
597
+ @disabled = true
598
+ disable_phases(*phases)
680
599
  task(installstamp)
681
600
  t = Rake::Task[installstamp]
682
- def t.needed?; false end
683
- t.instance_variable_set :@already_invoked, true
601
+ t.disable!
602
+ end
603
+
604
+ def utility(utility_name)
605
+ utilities[utility_name] ||= Autobuild.create_utility(utility_name, self)
606
+ end
607
+
608
+
609
+ def method_missing(m, *args, &block)
610
+ case m.to_s
611
+ when /(\w+)_utility$/
612
+ utility_name = $1
613
+ if !args.empty?
614
+ raise ArgumentError, "expected 0 arguments and got #{args.size}"
615
+ end
616
+ begin
617
+ return utility(utility_name)
618
+ rescue ArgumentError => e
619
+ raise NoMethodError.new(m), e.message, e.backtrace
620
+ end
621
+ end
622
+ super
684
623
  end
685
624
  end
686
625
 
@@ -28,29 +28,48 @@ module Autobuild
28
28
  class Autotools < Configurable
29
29
  attr_accessor :using
30
30
  attr_accessor :configureflags
31
+ attr_accessor :aclocal_flags
32
+ attr_accessor :autoheader_flags
33
+ attr_accessor :autoconf_flags
34
+ attr_accessor :automake_flags
31
35
 
32
36
  @builddir = 'build'
33
-
37
+
34
38
  def configurestamp; "#{builddir}/config.status" end
35
39
 
36
40
  def initialize(options)
37
41
  @using = Hash.new
38
42
  @configureflags = []
39
-
43
+ @aclocal_flags = Array.new
44
+ @autoheader_flags = Array.new
45
+ @autoconf_flags = Array.new
46
+ @automake_flags = Array.new
47
+
40
48
  super
41
49
  end
42
-
43
- # Declare that the given target can be used to generate documentation
44
- def with_doc(target = 'doc')
45
- task "#{name}-doc" => configurestamp
46
- doc_task do
47
- progress_start "generating documentation for %s", :done_message => 'generated_documentation for %s' do
48
- Subprocess.run(self, 'doc', Autobuild.tool(:make), "-j#{parallel_build_level}", target, :working_directory => builddir)
50
+
51
+ def common_utility_handling(utility, target)
52
+ utility.task do
53
+ progress_start "generating documentation for %s", :done_message => 'generated documentation for %s' do
54
+ if internal_doxygen_mode?
55
+ run_doxygen
56
+ else
57
+ Subprocess.run(self, utility.name, Autobuild.tool(:make), "-j#{parallel_build_level}", target, :working_directory => builddir)
58
+ end
59
+ yield if block_given?
49
60
  end
50
- yield if block_given?
51
61
  end
52
62
  end
53
63
 
64
+ # Declare that the given target can be used to generate documentation
65
+ def with_doc(target = 'doc', &block)
66
+ common_utility_handling(doc_utility, target, &block)
67
+ end
68
+
69
+ def with_tests(target = 'test')
70
+ common_utility_handling(test_utility, target, &block)
71
+ end
72
+
54
73
  # Overrides the default behaviour w.r.t. autotools script generation
55
74
  #
56
75
  # Use it like that:
@@ -114,7 +133,7 @@ module Autobuild
114
133
  FileUtils.rm_f configurestamp
115
134
  end
116
135
 
117
- def import
136
+ def import(only_local=false)
118
137
  # We force a regen after the first checkout. The issue is that
119
138
  # autotools is less robust than it should, and very often it is
120
139
  # better to generate the build system for the system on which we
@@ -247,7 +266,7 @@ module Autobuild
247
266
  else; Autobuild.tool(tool)
248
267
  end
249
268
 
250
- Subprocess.run(self, 'configure', tool_program)
269
+ Subprocess.run(self, 'configure', tool_program, *send("#{tool}_flags"))
251
270
  end
252
271
  end
253
272
  end
@@ -269,7 +288,7 @@ module Autobuild
269
288
  end
270
289
  command << "--prefix=#{prefix}"
271
290
  command += Array[*configureflags]
272
-
291
+
273
292
  progress_start "configuring autotools for %s", :done_message => 'configured autotools for %s' do
274
293
  Subprocess.run(self, 'configure', *command)
275
294
  end
@@ -199,22 +199,38 @@ module Autobuild
199
199
  Subprocess.run(self, 'doc', Autobuild.tool(:doxygen), doxyfile)
200
200
  end
201
201
 
202
- # Declare that the given target can be used to generate documentation
203
- def with_doc(target = 'doc')
204
- doc_task do
205
- in_dir(builddir) do
206
- progress_start "generating documentation for %s", :done_message => 'generated documentation for %s' do
207
- if internal_doxygen_mode?
208
- run_doxygen
209
- else
210
- Subprocess.run(self, 'doc', Autobuild.tool(:make), "-j#{parallel_build_level}", target)
211
- end
212
- yield if block_given?
202
+ def common_utility_handling(utility, target, start_msg, done_msg)
203
+ utility.task do
204
+ progress_start start_msg, :done_message => done_msg do
205
+ if internal_doxygen_mode?
206
+ run_doxygen
207
+ else
208
+ Subprocess.run(self, utility.name,
209
+ Autobuild.tool(:make),
210
+ "-j#{parallel_build_level}",
211
+ target,
212
+ :working_directory => builddir)
213
213
  end
214
+ yield if block_given?
214
215
  end
215
216
  end
216
217
  end
217
218
 
219
+ # Declare that the given target can be used to generate documentation
220
+ def with_doc(target = 'doc', &block)
221
+ common_utility_handling(
222
+ doc_utility, target,
223
+ "generating documentation for %s",
224
+ "generated documentation for %s", &block)
225
+ end
226
+
227
+ def with_tests(target = 'test', &block)
228
+ common_utility_handling(
229
+ test_utility, target,
230
+ "running tests for %s",
231
+ "successfully ran tests for %s", &block)
232
+ end
233
+
218
234
  CMAKE_EQVS = {
219
235
  'ON' => 'ON',
220
236
  'YES' => 'ON',
@@ -235,7 +251,7 @@ module Autobuild
235
251
  end
236
252
  end
237
253
 
238
- def import
254
+ def import(only_local=false)
239
255
  super
240
256
 
241
257
  Dir.glob(File.join(srcdir, "*.pc.in")) do |file|
@@ -245,10 +261,6 @@ module Autobuild
245
261
  end
246
262
 
247
263
  def prepare
248
- if !internal_doxygen_mode? && has_doc?
249
- task "#{name}-doc" => configurestamp
250
- end
251
-
252
264
  # A failed initial CMake configuration leaves a CMakeCache.txt file,
253
265
  # but no Makefile.
254
266
  #
@@ -257,6 +269,8 @@ module Autobuild
257
269
  FileUtils.rm_f cmake_cache
258
270
  end
259
271
 
272
+ doc_utility.source_ref_dir = builddir
273
+
260
274
  if File.exists?(cmake_cache)
261
275
  all_defines = defines.dup
262
276
  all_defines['CMAKE_INSTALL_PREFIX'] = prefix