autobuild 1.3.3 → 1.4.0
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/Changes.txt +8 -0
- data/Manifest.txt +1 -0
- data/Rakefile +10 -0
- data/lib/autobuild.rb +2 -1
- data/lib/autobuild/config.rb +19 -2
- data/lib/autobuild/configurable.rb +11 -0
- data/lib/autobuild/package.rb +40 -0
- data/lib/autobuild/packages/autotools.rb +3 -3
- data/lib/autobuild/packages/cmake.rb +8 -4
- data/lib/autobuild/packages/dummy.rb +31 -0
- data/lib/autobuild/reporting.rb +17 -1
- data/lib/autobuild/subcommand.rb +98 -12
- metadata +3 -2
data/Changes.txt
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
== Version 1.4.0
|
2
|
+
* cmake package handler now displays progress value
|
3
|
+
* added support for parallel builds
|
4
|
+
* added the long-awaited --force-build and --rebuild options.
|
5
|
+
The first one forces the call to all the build steps, but without deleting the
|
6
|
+
build products. The second one deletes all build products and retriggers a
|
7
|
+
full build.
|
8
|
+
|
1
9
|
== Version 1.3.3
|
2
10
|
* fix: changing Orogen.corba now affects packages that have already been
|
3
11
|
declared but for which the #corba attribute has not been set explicitely to
|
data/Manifest.txt
CHANGED
@@ -18,6 +18,7 @@ lib/autobuild/importer.rb
|
|
18
18
|
lib/autobuild/package.rb
|
19
19
|
lib/autobuild/packages/autotools.rb
|
20
20
|
lib/autobuild/packages/cmake.rb
|
21
|
+
lib/autobuild/packages/dummy.rb
|
21
22
|
lib/autobuild/packages/genom.rb
|
22
23
|
lib/autobuild/packages/import.rb
|
23
24
|
lib/autobuild/packages/orogen.rb
|
data/Rakefile
CHANGED
@@ -16,3 +16,13 @@ Hoe.spec 'autobuild' do
|
|
16
16
|
['utilrb', '>= 1.3.3']
|
17
17
|
end
|
18
18
|
|
19
|
+
Rake.clear_tasks(/publish_docs/)
|
20
|
+
task 'publish_docs' => 'doc' do
|
21
|
+
if !system('./update_github')
|
22
|
+
raise "cannot update the gh-pages branch for GitHub"
|
23
|
+
end
|
24
|
+
if !system('git', 'push', 'origin', 'gh-pages')
|
25
|
+
raise "cannot push the documentation"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
data/lib/autobuild.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
module Autobuild
|
2
|
-
VERSION = "1.
|
2
|
+
VERSION = "1.4.0" unless defined? Autobuild::VERSION
|
3
3
|
end
|
4
4
|
|
5
5
|
require 'autobuild/config'
|
@@ -18,6 +18,7 @@ require 'autobuild/packages/genom'
|
|
18
18
|
require 'autobuild/packages/import'
|
19
19
|
require 'autobuild/packages/orogen'
|
20
20
|
require 'autobuild/packages/pkgconfig'
|
21
|
+
require 'autobuild/packages/dummy'
|
21
22
|
require 'autobuild/pkgconfig'
|
22
23
|
require 'autobuild/reporting'
|
23
24
|
require 'autobuild/subcommand'
|
data/lib/autobuild/config.rb
CHANGED
@@ -18,6 +18,8 @@ end
|
|
18
18
|
# debug:: more verbose than 'verbose': displays Rake's debugging output
|
19
19
|
# do_update:: if we should update the packages
|
20
20
|
# do_build:: if we should build the packages
|
21
|
+
# do_forced_build:: if we should forcefully trigger all the packages build phases
|
22
|
+
# do_rebuild:: if we should cleanly rebuild every packages
|
21
23
|
# do_doc:: if we should produce the documentation
|
22
24
|
# doc_errors:: if errors during the documentation generation are treated as errors
|
23
25
|
# daemonize:: if the build should go into daemon mode (only if the daemons gem is available)
|
@@ -30,7 +32,7 @@ end
|
|
30
32
|
module Autobuild
|
31
33
|
class << self
|
32
34
|
%w{ nice srcdir prefix
|
33
|
-
verbose debug do_update do_build only_doc do_doc doc_errors
|
35
|
+
verbose debug do_update do_build do_rebuild do_forced_build only_doc do_doc doc_errors
|
34
36
|
daemonize clean_log packages default_packages
|
35
37
|
doc_prefix keep_oldlogs}.each do |name|
|
36
38
|
attr_accessor name
|
@@ -48,7 +50,7 @@ module Autobuild
|
|
48
50
|
end
|
49
51
|
DEFAULT_OPTIONS = { :nice => 0,
|
50
52
|
:srcdir => Dir.pwd, :prefix => Dir.pwd, :logdir => nil,
|
51
|
-
:verbose => false, :debug => false, :do_build => true, :do_update => true,
|
53
|
+
:verbose => false, :debug => false, :do_build => true, :do_forced_build => false, :do_rebuild => false, :do_update => true,
|
52
54
|
:daemonize => false, :packages => [], :default_packages => [],
|
53
55
|
:only_doc => false, :do_doc => true, :doc_errors => false,
|
54
56
|
:doc_prefix => 'doc', :keep_oldlogs => false }
|
@@ -157,6 +159,8 @@ module Autobuild
|
|
157
159
|
end
|
158
160
|
opts.on("--no-update", "update already checked-out sources") do |@do_update| end
|
159
161
|
opts.on("--no-build", "only prepare packages, do not build them") do |@do_build| end
|
162
|
+
opts.on("--forced-build", "force the trigger of all the build commands") do |@do_forced_build| end
|
163
|
+
opts.on("--rebuild", "clean and rebuild") do |@do_forced_build| end
|
160
164
|
opts.on("--only-doc", "only generate documentation") do |@only_doc| end
|
161
165
|
opts.on("--no-doc", "don't generate documentation") do |@do_doc| end
|
162
166
|
opts.on("--doc-errors", "treat documentation failure as error") do |@doc_errors| end
|
@@ -211,6 +215,19 @@ module Autobuild
|
|
211
215
|
end
|
212
216
|
end
|
213
217
|
|
218
|
+
if Autobuild.do_rebuild
|
219
|
+
packages.each do |pkg_name|
|
220
|
+
Autobuild::Package[pkg_name].prepare_for_rebuild
|
221
|
+
end
|
222
|
+
# And delete the prefix !
|
223
|
+
FileUtils.rm_rf Autobuild.prefix
|
224
|
+
|
225
|
+
elsif Autobuild.do_forced_build
|
226
|
+
packages.each do |pkg_name|
|
227
|
+
Autobuild::Package[pkg_name].prepare_for_forced_build
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
214
231
|
if Autobuild.only_doc
|
215
232
|
phases = ['doc']
|
216
233
|
else
|
@@ -50,6 +50,17 @@ module Autobuild
|
|
50
50
|
Autobuild.update_environment(prefix)
|
51
51
|
end
|
52
52
|
|
53
|
+
def prepare_for_forced_build
|
54
|
+
FileUtils.rm_f buildstamp
|
55
|
+
FileUtils.rm_f configurestamp
|
56
|
+
end
|
57
|
+
|
58
|
+
def prepare_for_rebuild
|
59
|
+
if File.exists?(builddir) && builddir != srcdir
|
60
|
+
FileUtils.rm_rf builddir
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
53
64
|
def depends_on(*packages)
|
54
65
|
super
|
55
66
|
stamps = packages.collect { |p| Package[p.to_s].installstamp }
|
data/lib/autobuild/package.rb
CHANGED
@@ -83,6 +83,7 @@ module Autobuild
|
|
83
83
|
def initialize(spec)
|
84
84
|
@dependencies = Array.new
|
85
85
|
@provides = Array.new
|
86
|
+
@parallel_build_level = nil
|
86
87
|
|
87
88
|
if Hash === spec
|
88
89
|
name, depends = spec.to_a.first
|
@@ -127,6 +128,20 @@ module Autobuild
|
|
127
128
|
@spec_dependencies = depends
|
128
129
|
end
|
129
130
|
|
131
|
+
# Called before a forced build. It should remove all the timestamp and
|
132
|
+
# target files so that all the build phases of this package gets
|
133
|
+
# retriggered. However, it should not clean the build products.
|
134
|
+
def prepare_for_forced_build
|
135
|
+
if File.exists?(installstamp)
|
136
|
+
FileUtils.rm_f installstamp
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
# Called when the user asked for a full rebuild. It should delete the
|
141
|
+
# build products so that a full build is retriggered.
|
142
|
+
def prepare_for_rebuild
|
143
|
+
end
|
144
|
+
|
130
145
|
# Call the importer if there is one. Autodetection of "provides" should
|
131
146
|
# be done there as well. See the documentation of Autobuild::Package for
|
132
147
|
# more information.
|
@@ -279,6 +294,31 @@ module Autobuild
|
|
279
294
|
def self.[](name)
|
280
295
|
@@packages[name.to_s] || @@provides[name.to_s]
|
281
296
|
end
|
297
|
+
|
298
|
+
# Sets the level of parallelism authorized while building this package
|
299
|
+
#
|
300
|
+
# See #parallel_build_level and Autobuild.parallel_build_level for more
|
301
|
+
# information.
|
302
|
+
#
|
303
|
+
# Note that not all package types use this value
|
304
|
+
def parallel_build_level=(value)
|
305
|
+
@parallel_build_level = Integer(value)
|
306
|
+
end
|
307
|
+
|
308
|
+
# Returns the level of parallelism authorized during the build for this
|
309
|
+
# particular package. If not set, defaults to the system-wide option
|
310
|
+
# (Autobuild.parallel_build_level and Autobuild.parallel_build_level=).
|
311
|
+
#
|
312
|
+
# The default value is the number of CPUs on this system.
|
313
|
+
def parallel_build_level
|
314
|
+
if @parallel_build_level.nil?
|
315
|
+
Autobuild.parallel_build_level
|
316
|
+
elsif !@parallel_build_level || @parallel_build_level <= 0
|
317
|
+
1
|
318
|
+
else
|
319
|
+
@parallel_build_level
|
320
|
+
end
|
321
|
+
end
|
282
322
|
end
|
283
323
|
|
284
324
|
def self.package_set(spec)
|
@@ -62,7 +62,7 @@ module Autobuild
|
|
62
62
|
doc_task do
|
63
63
|
Dir.chdir(builddir) do
|
64
64
|
Autobuild.progress "generating documentation for #{name}"
|
65
|
-
Subprocess.run(name, 'doc', Autobuild.tool(:make), target)
|
65
|
+
Subprocess.run(name, 'doc', Autobuild.tool(:make), "-j#{parallel_build_level}", target)
|
66
66
|
yield if block_given?
|
67
67
|
end
|
68
68
|
end
|
@@ -233,7 +233,7 @@ module Autobuild
|
|
233
233
|
Dir.chdir(builddir) {
|
234
234
|
Autobuild.progress "building #{name}"
|
235
235
|
Subprocess.run(name, 'build', './config.status')
|
236
|
-
Subprocess.run(name, 'build', Autobuild.tool(:make))
|
236
|
+
Subprocess.run(name, 'build', Autobuild.tool(:make), "-j#{parallel_build_level}")
|
237
237
|
}
|
238
238
|
Autobuild.touch_stamp(buildstamp)
|
239
239
|
end
|
@@ -242,7 +242,7 @@ module Autobuild
|
|
242
242
|
def install
|
243
243
|
Dir.chdir(builddir) {
|
244
244
|
Autobuild.progress "installing #{name}"
|
245
|
-
Subprocess.run(name, 'install', Autobuild.tool(:make), 'install')
|
245
|
+
Subprocess.run(name, 'install', Autobuild.tool(:make), "-j#{parallel_build_level}", 'install')
|
246
246
|
}
|
247
247
|
Autobuild.touch_stamp(installstamp)
|
248
248
|
Autobuild.update_environment(prefix)
|
@@ -40,7 +40,7 @@ module Autobuild
|
|
40
40
|
doc_task do
|
41
41
|
Dir.chdir(builddir) do
|
42
42
|
Autobuild.progress "generating documentation for #{name}"
|
43
|
-
Subprocess.run(name, 'doc', Autobuild.tool(:make), target)
|
43
|
+
Subprocess.run(name, 'doc', Autobuild.tool(:make), "-j#{parallel_build_level}", target)
|
44
44
|
yield if block_given?
|
45
45
|
end
|
46
46
|
end
|
@@ -134,11 +134,15 @@ module Autobuild
|
|
134
134
|
# Do the build in builddir
|
135
135
|
def build
|
136
136
|
Dir.chdir(builddir) do
|
137
|
-
Autobuild.
|
137
|
+
Autobuild.progress_with_value "building #{name}"
|
138
138
|
if always_reconfigure || !File.file?('Makefile')
|
139
139
|
Subprocess.run(name, 'build', Autobuild.tool(:cmake), '.')
|
140
140
|
end
|
141
|
-
Subprocess.run(name, 'build', Autobuild.tool(:make))
|
141
|
+
Subprocess.run(name, 'build', Autobuild.tool(:make), "-j#{parallel_build_level}") do |line|
|
142
|
+
if line =~ /\[\s+(\d+)%\]/
|
143
|
+
Autobuild.progress_value Integer($1)
|
144
|
+
end
|
145
|
+
end
|
142
146
|
end
|
143
147
|
Autobuild.touch_stamp(buildstamp)
|
144
148
|
end
|
@@ -147,7 +151,7 @@ module Autobuild
|
|
147
151
|
def install
|
148
152
|
Dir.chdir(builddir) do
|
149
153
|
Autobuild.progress "installing #{name}"
|
150
|
-
Subprocess.run(name, '
|
154
|
+
Subprocess.run(name, 'build', Autobuild.tool(:make), "-j#{parallel_build_level}", 'install')
|
151
155
|
Autobuild.update_environment prefix
|
152
156
|
end
|
153
157
|
super
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Autobuild
|
2
|
+
def self.dummy(spec)
|
3
|
+
ImporterPackage.new(spec)
|
4
|
+
end
|
5
|
+
|
6
|
+
class DummyPackage < Package
|
7
|
+
def installstamp
|
8
|
+
"#{srcdir}/#{STAMPFILE}"
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(*args)
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
def import
|
16
|
+
end
|
17
|
+
|
18
|
+
def prepare
|
19
|
+
%w{import prepare build doc}.each do |phase|
|
20
|
+
Rake.task("#{name}-#{phase}")
|
21
|
+
t = Rake::Task["#{name}-#{phase}"]
|
22
|
+
def t.needed?; false end
|
23
|
+
end
|
24
|
+
Rake.task(installstamp)
|
25
|
+
t = Rake::Task[installstamp]
|
26
|
+
def t.needed?; false end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
|
data/lib/autobuild/reporting.rb
CHANGED
@@ -16,7 +16,23 @@ require 'autobuild/exceptions'
|
|
16
16
|
|
17
17
|
module Autobuild
|
18
18
|
def self.progress(msg)
|
19
|
-
|
19
|
+
if @last_msg
|
20
|
+
progress_value(100)
|
21
|
+
puts
|
22
|
+
end
|
23
|
+
@last_msg = nil
|
24
|
+
puts " #{msg}"
|
25
|
+
end
|
26
|
+
def self.progress_with_value(msg)
|
27
|
+
if @last_msg
|
28
|
+
progress_value(100)
|
29
|
+
puts
|
30
|
+
end
|
31
|
+
@last_msg = msg
|
32
|
+
print " #{msg}"
|
33
|
+
end
|
34
|
+
def self.progress_value(value)
|
35
|
+
print "\r #{@last_msg} (#{value}%)"
|
20
36
|
end
|
21
37
|
|
22
38
|
## The reporting module provides the framework
|
data/lib/autobuild/subcommand.rb
CHANGED
@@ -1,5 +1,59 @@
|
|
1
1
|
require 'autobuild/exceptions'
|
2
2
|
require 'autobuild/reporting'
|
3
|
+
require 'fcntl'
|
4
|
+
|
5
|
+
module Autobuild
|
6
|
+
@parallel_build_level = nil
|
7
|
+
class << self
|
8
|
+
# Sets the level of parallelism during the build
|
9
|
+
#
|
10
|
+
# See #parallel_build_level for detailed information
|
11
|
+
attr_writer :parallel_build_level
|
12
|
+
|
13
|
+
# Returns the number of processes that can run in parallel during the
|
14
|
+
# build. This is a system-wide value that can be overriden in a
|
15
|
+
# per-package fashion by using Package#parallel_build_level.
|
16
|
+
#
|
17
|
+
# If not set, defaults to the number of CPUs on the system
|
18
|
+
#
|
19
|
+
# See also #parallel_build_level=
|
20
|
+
def parallel_build_level
|
21
|
+
if @parallel_build_level.nil?
|
22
|
+
# No user-set value, return the count of processors on this
|
23
|
+
# machine
|
24
|
+
autodetect_processor_count
|
25
|
+
elsif !@parallel_build_level || @parallel_build_level <= 0
|
26
|
+
1
|
27
|
+
else
|
28
|
+
@parallel_build_level
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Returns the number of CPUs present on this system
|
34
|
+
def self.autodetect_processor_count
|
35
|
+
if @processor_count
|
36
|
+
return @processor_count
|
37
|
+
end
|
38
|
+
|
39
|
+
if File.file?('/sys/devices/system/cpu/present')
|
40
|
+
range = File.read('/sys/devices/system/cpu/present').
|
41
|
+
chomp
|
42
|
+
|
43
|
+
@processor_count = Integer(range.split('-').last) + 1
|
44
|
+
elsif File.file?('/proc/cpuinfo')
|
45
|
+
# Just count the numer of processor: \d lines
|
46
|
+
@processor_count = File.readlines('/proc/cpuinfo').
|
47
|
+
find_all { |l| l =~ /^processor\s+:\s+\d+$/ }.
|
48
|
+
count
|
49
|
+
else
|
50
|
+
# Hug... What kind of system is it ?
|
51
|
+
STDERR.puts "INFO: cannot autodetect the number of CPUs on this sytem"
|
52
|
+
@processor_count = 1
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
3
57
|
|
4
58
|
module Autobuild::Subprocess
|
5
59
|
class Failed < Exception
|
@@ -12,6 +66,8 @@ module Autobuild::Subprocess
|
|
12
66
|
CONTROL_COMMAND_NOT_FOUND = 1
|
13
67
|
CONTROL_UNEXPECTED = 2
|
14
68
|
def self.run(target, phase, *command)
|
69
|
+
STDOUT.sync = true
|
70
|
+
|
15
71
|
# Filter nil and empty? in command
|
16
72
|
command.reject! { |o| o.nil? || (o.respond_to?(:empty?) && o.empty?) }
|
17
73
|
command.collect! { |o| o.to_s }
|
@@ -41,17 +97,29 @@ module Autobuild::Subprocess
|
|
41
97
|
logfile.puts " #{command.join(" ")}"
|
42
98
|
logfile.puts
|
43
99
|
logfile.flush
|
100
|
+
logfile.sync = true
|
44
101
|
|
45
|
-
|
102
|
+
if !input_streams.empty?
|
103
|
+
pread, pwrite = IO.pipe # to feed subprocess stdin
|
104
|
+
end
|
105
|
+
if block_given? # the caller wants the stdout/stderr stream of the process, git it to him
|
106
|
+
outread, outwrite = IO.pipe
|
107
|
+
outread.sync = true
|
108
|
+
outwrite.sync = true
|
109
|
+
end
|
46
110
|
cread, cwrite = IO.pipe # to control that exec goes well
|
47
111
|
|
112
|
+
cwrite.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
|
113
|
+
|
48
114
|
pid = fork do
|
49
115
|
cwrite.sync = true
|
50
116
|
begin
|
51
117
|
Process.setpriority(Process::PRIO_PROCESS, 0, Autobuild.nice)
|
52
|
-
|
53
|
-
|
54
|
-
|
118
|
+
|
119
|
+
if outwrite
|
120
|
+
outread.close
|
121
|
+
$stderr.reopen(outwrite.dup)
|
122
|
+
$stdout.reopen(outwrite.dup)
|
55
123
|
else
|
56
124
|
$stderr.reopen(logfile.dup)
|
57
125
|
$stdout.reopen(logfile.dup)
|
@@ -73,17 +141,19 @@ module Autobuild::Subprocess
|
|
73
141
|
end
|
74
142
|
|
75
143
|
# Feed the input
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
144
|
+
if !input_streams.empty?
|
145
|
+
pread.close
|
146
|
+
begin
|
147
|
+
input_streams.each do |infile|
|
148
|
+
File.open(infile) do |instream|
|
149
|
+
instream.each_line { |line| pwrite.write(line) }
|
150
|
+
end
|
81
151
|
end
|
152
|
+
rescue Errno::ENOENT => e
|
153
|
+
raise Failed.new, "cannot open input files: #{e.message}"
|
82
154
|
end
|
83
|
-
|
84
|
-
raise Failed.new, "cannot open input files: #{e.message}"
|
155
|
+
pwrite.close
|
85
156
|
end
|
86
|
-
pwrite.close
|
87
157
|
|
88
158
|
# Get control status
|
89
159
|
cwrite.close
|
@@ -98,6 +168,22 @@ module Autobuild::Subprocess
|
|
98
168
|
end
|
99
169
|
end
|
100
170
|
|
171
|
+
# If the caller asked for process output, provide it to him
|
172
|
+
# line-by-line.
|
173
|
+
if outread
|
174
|
+
outwrite.close
|
175
|
+
outread.each_line do |line|
|
176
|
+
if Autobuild.verbose
|
177
|
+
STDOUT.print line
|
178
|
+
end
|
179
|
+
logfile.puts line
|
180
|
+
if block_given?
|
181
|
+
yield(line)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
outread.close
|
185
|
+
end
|
186
|
+
|
101
187
|
childpid, childstatus = Process.wait2(pid)
|
102
188
|
childstatus
|
103
189
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: autobuild
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sylvain Joyeux
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-10-
|
12
|
+
date: 2009-10-25 01:00:00 +02:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -111,6 +111,7 @@ files:
|
|
111
111
|
- lib/autobuild/package.rb
|
112
112
|
- lib/autobuild/packages/autotools.rb
|
113
113
|
- lib/autobuild/packages/cmake.rb
|
114
|
+
- lib/autobuild/packages/dummy.rb
|
114
115
|
- lib/autobuild/packages/genom.rb
|
115
116
|
- lib/autobuild/packages/import.rb
|
116
117
|
- lib/autobuild/packages/orogen.rb
|