autobuild 1.3.3 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|