autobuild 0.4 → 0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +57 -0
- data/README +29 -46
- data/Rakefile +161 -0
- data/lib/autobuild/config-interpolator.rb +80 -91
- data/lib/autobuild/config.rb +21 -6
- data/lib/autobuild/environment.rb +13 -11
- data/lib/autobuild/exceptions.rb +46 -45
- data/lib/autobuild/import/cvs.rb +34 -39
- data/lib/autobuild/import/svn.rb +23 -29
- data/lib/autobuild/import/tar.rb +120 -0
- data/lib/autobuild/importer.rb +4 -6
- data/lib/autobuild/options.rb +18 -11
- data/lib/autobuild/package.rb +1 -1
- data/lib/autobuild/packages/autotools.rb +107 -121
- data/lib/autobuild/packages/genom.rb +56 -62
- data/lib/autobuild/packages/import.rb +14 -12
- data/lib/autobuild/reporting.rb +91 -55
- data/lib/autobuild/subcommand.rb +89 -46
- data/lib/autobuild/timestamps.rb +47 -37
- metadata +43 -78
- data/bin/autobuild +0 -83
- data/test/base.rb +0 -8
- data/test/tc_config.rb +0 -40
- data/test/tc_config_interpolation.rb +0 -57
- data/test/tc_import.rb +0 -77
- data/test/tc_subcommand.rb +0 -61
- data/test/tools.rb +0 -39
data/lib/autobuild/importer.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'autobuild/exceptions'
|
2
2
|
|
3
|
-
class Importer
|
3
|
+
class Autobuild::Importer
|
4
4
|
def initialize(options)
|
5
5
|
@options = options
|
6
6
|
end
|
@@ -22,7 +22,7 @@ class Importer
|
|
22
22
|
begin
|
23
23
|
checkout(package)
|
24
24
|
patch(package)
|
25
|
-
rescue
|
25
|
+
rescue Autobuild::Exception
|
26
26
|
FileUtils.rm_rf package.srcdir
|
27
27
|
raise
|
28
28
|
end
|
@@ -34,13 +34,13 @@ class Importer
|
|
34
34
|
# We assume that package.srcdir already exists (checkout
|
35
35
|
# is supposed to have been called)
|
36
36
|
def patchlist(package)
|
37
|
-
"#{package.srcdir}/autobuild-
|
37
|
+
"#{package.srcdir}/patches-autobuild-stamp"
|
38
38
|
end
|
39
39
|
|
40
40
|
def call_patch(package, reverse, file)
|
41
41
|
patch = ($PROGRAMS['patch'] || 'patch')
|
42
42
|
Dir.chdir(package.srcdir) {
|
43
|
-
|
43
|
+
Subprocess.run(package.target, :patch, patch, '-p0', (reverse ? '-R' : nil), "<#{file}")
|
44
44
|
}
|
45
45
|
end
|
46
46
|
|
@@ -68,8 +68,6 @@ class Importer
|
|
68
68
|
apply(package, p)
|
69
69
|
cur_patches << p
|
70
70
|
}
|
71
|
-
rescue SubcommandFailed => e
|
72
|
-
raise ImportException.new(e), "can't patch #{package.target} (#{e.message})"
|
73
71
|
ensure
|
74
72
|
File.open(patchlist(package), 'w+') do |f|
|
75
73
|
f.write(cur_patches.join("\n"))
|
data/lib/autobuild/options.rb
CHANGED
@@ -1,15 +1,22 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
module Autobuild
|
2
|
+
Options = Struct.new( :update, :nice,
|
3
|
+
:srcdir, :prefix, :builddir, :logdir,
|
4
|
+
:verbose, :debug, :do_build,
|
5
|
+
:daemonize, :use_http )
|
5
6
|
|
6
|
-
class Options
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
7
|
+
class Options
|
8
|
+
def self.default
|
9
|
+
default_values = { :update => true, :nice => 0,
|
10
|
+
:srcdir => nil, :prefix => nil, :builddir => nil, :logdir => nil,
|
11
|
+
:verbose => false, :debug => false, :do_build => true,
|
12
|
+
:daemonize => false, :use_http => false }
|
13
|
+
|
14
|
+
default_values.inject(Options.new) { |opt, defval|
|
15
|
+
k, v = *defval
|
16
|
+
opt[k] = v
|
17
|
+
opt
|
18
|
+
}
|
19
|
+
end
|
13
20
|
end
|
14
21
|
end
|
15
22
|
|
data/lib/autobuild/package.rb
CHANGED
@@ -3,92 +3,92 @@ require 'autobuild/environment'
|
|
3
3
|
require 'autobuild/package'
|
4
4
|
require 'autobuild/subcommand'
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
# -
|
15
|
-
#
|
16
|
-
#
|
17
|
-
# -
|
18
|
-
#
|
19
|
-
#
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
def buildstamp
|
34
|
-
"#{builddir}/#{target}-#{STAMPFILE}"
|
35
|
-
end
|
36
|
-
|
37
|
-
def initialize(target, options)
|
38
|
-
options = DefaultOptions.merge(options) { |key, old, new|
|
39
|
-
(new.nil? || (new.respond_to?(:empty) && new.empty?)) ? old : new
|
6
|
+
module Autobuild
|
7
|
+
##
|
8
|
+
# ==== Handles autotools-based packages
|
9
|
+
#
|
10
|
+
# == Used programs
|
11
|
+
# - aclocal, autoheader, autoconf, automake
|
12
|
+
#
|
13
|
+
# == Available options
|
14
|
+
# - aclocal (default: true if autoconf is enabled, false otherwise) run aclocal
|
15
|
+
# - autoconf (default: autodetect) run autoconf. Will be enabled if there is
|
16
|
+
# +configure.in+ or +configure.ac+ in the source directory
|
17
|
+
# - autoheader (default: false) run autoheader
|
18
|
+
# - automake (default: autodetect) run automake. Will run automake if there is a
|
19
|
+
# +Makefile.am+ in the source directory
|
20
|
+
#
|
21
|
+
class Autotools < Package
|
22
|
+
factory :autotools, self
|
23
|
+
|
24
|
+
attr_reader :builddir
|
25
|
+
|
26
|
+
DefaultOptions = {
|
27
|
+
:autoheader => false,
|
28
|
+
:aclocal => nil,
|
29
|
+
:autoconf => nil,
|
30
|
+
:automake => nil,
|
31
|
+
:builddir => 'build'
|
40
32
|
}
|
41
|
-
super(target, options)
|
42
33
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
@builddir = File.expand_path(builddir, srcdir)
|
47
|
-
end
|
34
|
+
def buildstamp
|
35
|
+
"#{builddir}/#{target}-#{STAMPFILE}"
|
36
|
+
end
|
48
37
|
|
49
|
-
|
50
|
-
|
38
|
+
def initialize(target, options)
|
39
|
+
options = DefaultOptions.merge(options) { |key, old, new|
|
40
|
+
(new.nil? || (new.respond_to?(:empty) && new.empty?)) ? old : new
|
41
|
+
}
|
42
|
+
super(target, options)
|
51
43
|
|
52
|
-
|
53
|
-
|
44
|
+
@builddir = options[:builddir]
|
45
|
+
raise ConfigException, "autotools packages need a non-empty builddir" if (@builddir.nil? || @builddir.empty?)
|
46
|
+
raise ConfigException, "absolute builddirs are unsupported" if (Pathname.new(@builddir).absolute?)
|
47
|
+
@builddir = File.expand_path(builddir, srcdir)
|
54
48
|
end
|
55
49
|
|
56
|
-
|
57
|
-
|
58
|
-
build
|
59
|
-
end
|
50
|
+
def prepare
|
51
|
+
regen_targets
|
60
52
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
end
|
53
|
+
file "#{builddir}/config.status" => "#{srcdir}/configure" do
|
54
|
+
configure
|
55
|
+
end
|
65
56
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
update_environment(prefix)
|
71
|
-
end
|
57
|
+
source_tree srcdir, builddir
|
58
|
+
file buildstamp => [ srcdir, "#{builddir}/config.status" ] do
|
59
|
+
build
|
60
|
+
end
|
72
61
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
file
|
79
|
-
|
80
|
-
|
62
|
+
if !dependencies.empty?
|
63
|
+
file buildstamp => dependencies
|
64
|
+
file srcdir => dependencies
|
65
|
+
end
|
66
|
+
|
67
|
+
file installstamp => buildstamp do
|
68
|
+
install
|
69
|
+
Autobuild.update_environment(prefix)
|
70
|
+
end
|
71
|
+
Autobuild.update_environment(prefix)
|
81
72
|
end
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
73
|
+
|
74
|
+
def regen_targets
|
75
|
+
conffile = "#{srcdir}/configure"
|
76
|
+
if File.exists?("#{conffile}.ac")
|
77
|
+
file conffile => [ "#{conffile}.ac" ]
|
78
|
+
elsif File.exists?("#{conffile}.in")
|
79
|
+
file conffile => [ "#{conffile}.in" ]
|
80
|
+
else
|
81
|
+
raise PackageException.new(target), "neither configure.ac nor configure.in present in #{srcdir}"
|
82
|
+
end
|
83
|
+
file conffile do
|
84
|
+
Dir.chdir(srcdir) {
|
85
|
+
$PROGRAMS[:aclocal] ||= 'aclocal'
|
86
|
+
$PROGRAMS[:autoconf] ||= 'autoconf'
|
87
|
+
$PROGRAMS[:autoheader] ||= 'autoheader'
|
88
|
+
$PROGRAMS[:automake] ||= 'automake'
|
89
|
+
|
90
90
|
if @options[:autogen]
|
91
|
-
|
91
|
+
Subprocess.run(target, 'configure', File.expand_path(@options[:autogen]))
|
92
92
|
else
|
93
93
|
# Autodetect autoconf/aclocal/automake
|
94
94
|
if @options[:autoconf].nil?
|
@@ -101,59 +101,45 @@ class Autotools < Package
|
|
101
101
|
@options[:automake] = File.exists?(File.join(srcdir, 'Makefile.am'))
|
102
102
|
end
|
103
103
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
104
|
+
Subprocess.run(target, 'configure', $PROGRAMS[:aclocal]) if @options[:aclocal]
|
105
|
+
Subprocess.run(target, 'configure', $PROGRAMS[:autoconf]) if @options[:autoconf]
|
106
|
+
Subprocess.run(target, 'configure', $PROGRAMS[:autoheader]) if @options[:autoheader]
|
107
|
+
Subprocess.run(target, 'configure', $PROGRAMS[:automake]) if @options[:automake]
|
108
108
|
end
|
109
|
-
|
110
|
-
|
111
|
-
end
|
112
|
-
}
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
def configure
|
117
|
-
if File.exists?(builddir) && !File.directory?(builddir)
|
118
|
-
raise ConfigException, "#{builddir} already exists but is not a directory"
|
109
|
+
}
|
110
|
+
end
|
119
111
|
end
|
120
112
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
command |= @options[:configureflags].to_a
|
125
|
-
|
126
|
-
begin
|
127
|
-
subcommand(target, 'configure', *command)
|
128
|
-
rescue SubcommandFailed => e
|
129
|
-
raise BuildException.new(e), "failed to configure #{target}"
|
113
|
+
def configure
|
114
|
+
if File.exists?(builddir) && !File.directory?(builddir)
|
115
|
+
raise ConfigException, "#{builddir} already exists but is not a directory"
|
130
116
|
end
|
131
|
-
}
|
132
|
-
end
|
133
117
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
118
|
+
FileUtils.mkdir_p builddir if !File.directory?(builddir)
|
119
|
+
Dir.chdir(builddir) {
|
120
|
+
command = [ "#{srcdir}/configure", "--no-create", "--prefix=#{prefix}" ]
|
121
|
+
command |= @options[:configureflags].to_a
|
122
|
+
|
123
|
+
Subprocess.run(target, 'configure', *command)
|
124
|
+
}
|
125
|
+
end
|
126
|
+
|
127
|
+
def build
|
128
|
+
Dir.chdir(builddir) {
|
129
|
+
Subprocess.run(target, 'build', './config.status')
|
138
130
|
$PROGRAMS['make'] ||= 'make'
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
}
|
144
|
-
touch_stamp(buildstamp)
|
145
|
-
end
|
131
|
+
Subprocess.run(target, 'build', $PROGRAMS['make'])
|
132
|
+
}
|
133
|
+
touch_stamp(buildstamp)
|
134
|
+
end
|
146
135
|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
end
|
155
|
-
}
|
156
|
-
touch_stamp(installstamp)
|
136
|
+
def install
|
137
|
+
Dir.chdir(builddir) {
|
138
|
+
make = ($PROGRAMS['make'] or 'make')
|
139
|
+
Subprocess.run(target, 'install', make, 'install')
|
140
|
+
}
|
141
|
+
touch_stamp(installstamp)
|
142
|
+
end
|
157
143
|
end
|
158
144
|
end
|
159
145
|
|
@@ -1,80 +1,74 @@
|
|
1
1
|
require 'autobuild/packages/autotools'
|
2
2
|
require 'open3'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
4
|
+
module Autobuild
|
5
|
+
class GenomModule < Autotools
|
6
|
+
def prepare
|
7
|
+
super
|
8
|
+
get_requires
|
9
|
+
get_provides
|
10
|
+
end
|
11
|
+
def genomstamp; "#{srcdir}/.genom/genom-stamp" end
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
13
|
+
def cpp_options
|
14
|
+
@options[:genomflags].to_a.find_all { |opt| opt =~ /^-D/ }
|
15
|
+
end
|
15
16
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
17
|
+
def get_requires
|
18
|
+
cpp = ($PROGRAMS['cpp'] || 'cpp')
|
19
|
+
Open3.popen3("#{cpp} #{cpp_options.join(" ")} #{srcdir}/#{target}.gen") do |cin, out, err|
|
20
|
+
out.each_line { |line|
|
21
|
+
if line =~ /^\s*requires\s*:\s*([\w\-]+(?:\s*,\s*[\w\-]+)*);/
|
22
|
+
$1.split(/, /).each { |name|
|
23
|
+
depends_on name
|
24
|
+
}
|
25
|
+
elsif line =~ /^\s*requires/
|
26
|
+
puts "failed to match #{line}"
|
27
|
+
end
|
28
|
+
}
|
29
|
+
end
|
28
30
|
end
|
29
|
-
end
|
30
31
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
32
|
+
def depends_on(name)
|
33
|
+
super
|
34
|
+
file genomstamp => Package.name2target(name)
|
35
|
+
end
|
35
36
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
37
|
+
def get_provides
|
38
|
+
File.open("#{srcdir}/configure.ac.user") do |f|
|
39
|
+
f.each_line { |line|
|
40
|
+
if line =~ /^\s*EXTRA_PKGCONFIG\s*=\s*"?([\w\-]+(?:\s+[\w\-]+)*)"?/
|
41
|
+
$1.split(/\s+/).each { |pkg|
|
42
|
+
provides pkg
|
43
|
+
}
|
44
|
+
end
|
45
|
+
}
|
46
|
+
end
|
45
47
|
end
|
46
|
-
|
47
|
-
|
48
|
+
|
48
49
|
|
49
|
-
|
50
|
-
|
50
|
+
def regen_targets
|
51
|
+
cmdline = [ 'genom', target ] | @options[:genomflags].to_a
|
51
52
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
raise BuildException.new(e), "failed to generate module #{target}"
|
59
|
-
end
|
60
|
-
}
|
61
|
-
end
|
53
|
+
file buildstamp => genomstamp
|
54
|
+
file genomstamp => [ :genom, "#{srcdir}/#{target}.gen" ] do
|
55
|
+
Dir.chdir(srcdir) {
|
56
|
+
Subprocess.run(target, 'genom', *cmdline)
|
57
|
+
}
|
58
|
+
end
|
62
59
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
subcommand(target, 'genom', File.expand_path('autogen'))
|
71
|
-
rescue SubcommandFailed => e
|
72
|
-
raise BuildException.new(e), "failed to generate module #{target}"
|
60
|
+
acuser = "#{srcdir}/configure.ac.user"
|
61
|
+
if File.exists?(acuser)
|
62
|
+
file "#{srcdir}/configure" => acuser do
|
63
|
+
# configure does not depend on the .gen file
|
64
|
+
# since the generation takes care of rebuilding configure
|
65
|
+
# if .gen has changed
|
66
|
+
Subprocess.run(target, 'genom', File.expand_path('autogen'))
|
73
67
|
end
|
74
68
|
end
|
75
69
|
end
|
76
|
-
end
|
77
70
|
|
78
|
-
|
71
|
+
factory :genom, self
|
72
|
+
end
|
79
73
|
end
|
80
74
|
|