autobuild 1.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Changes.txt +7 -0
- data/Manifest.txt +1 -1
- data/bin/autobuild +4 -0
- data/lib/autobuild.rb +1 -1
- data/lib/autobuild/import/tar.rb +14 -6
- data/lib/autobuild/package.rb +125 -127
- data/lib/autobuild/packages/autotools.rb +28 -11
- data/samples/openrobots.autobuild +78 -0
- metadata +2 -2
- data/samples/demo.rb +0 -25
data/Changes.txt
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
== Version 1.0.1
|
2
|
+
* The "test suites are there for something" release
|
3
|
+
* Fixes bugs introduced in the last version
|
4
|
+
* Added a real example in samples/openrobots.rb
|
5
|
+
* Fixed documentation in various places
|
6
|
+
* Fail more gracefully on circular dependencies
|
7
|
+
|
1
8
|
== Version 1.0
|
2
9
|
|
3
10
|
* Releasing 1.0. Autobuild is stable, and is in daily use at my work
|
data/Manifest.txt
CHANGED
data/bin/autobuild
CHANGED
data/lib/autobuild.rb
CHANGED
data/lib/autobuild/import/tar.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'autobuild/importer'
|
1
2
|
require 'open-uri'
|
2
3
|
|
3
4
|
module Autobuild
|
@@ -77,13 +78,13 @@ module Autobuild
|
|
77
78
|
# Sets the source URL and update +cachefile+ and +mode+ attributes accordingly.
|
78
79
|
def url=(url)
|
79
80
|
@url = URI.parse(url)
|
80
|
-
raise ConfigException, "invalid URL #{url}" unless VALID_URI_SCHEMES.include?(url.scheme)
|
81
|
+
raise ConfigException, "invalid URL #{@url}" unless VALID_URI_SCHEMES.include?(@url.scheme)
|
81
82
|
|
82
83
|
@mode = TarImporter.url_to_mode(url)
|
83
|
-
if url.scheme == 'file'
|
84
|
-
@cachefile = url
|
84
|
+
if @url.scheme == 'file'
|
85
|
+
@cachefile = @url.path
|
85
86
|
else
|
86
|
-
@cachefile = File.join(cachedir, File.basename(url.path))
|
87
|
+
@cachefile = File.join(cachedir, File.basename(@url.path))
|
87
88
|
end
|
88
89
|
end
|
89
90
|
|
@@ -95,10 +96,14 @@ module Autobuild
|
|
95
96
|
attr_reader :mode
|
96
97
|
# The directory in which remote files are cached
|
97
98
|
def cachedir; @options[:cachedir] end
|
99
|
+
# The directory contained in the tar file
|
100
|
+
def tardir; @options[:tardir] end
|
98
101
|
|
99
102
|
# Creates a new importer which downloads +url+ in +cachedir+ and unpacks it. The following options
|
100
103
|
# are allowed:
|
101
104
|
# [:cachedir] the cache directory. Defaults to "#{Autobuild.prefix}/cache"
|
105
|
+
# [:tardir] the directory contained in the tar file. If set, the importer will rename that directory
|
106
|
+
# to make it match Package#srcdir
|
102
107
|
def initialize(url, options)
|
103
108
|
@options = options.dup
|
104
109
|
@options[:cachedir] ||= "#{Autobuild.prefix}/cache"
|
@@ -117,8 +122,11 @@ module Autobuild
|
|
117
122
|
base_dir = File.dirname(package.srcdir)
|
118
123
|
FileUtils.mkdir_p base_dir
|
119
124
|
cmd = [ 'tar', "x#{TAR_OPTION[mode]}f", cachefile, '-C', base_dir ]
|
120
|
-
|
125
|
+
|
121
126
|
Subprocess.run(package.name, :import, *cmd)
|
127
|
+
if tardir
|
128
|
+
File.mv File.join(base_dir, tardir), package.srcdir
|
129
|
+
end
|
122
130
|
|
123
131
|
rescue OpenURI::HTTPError
|
124
132
|
raise Autobuild::Exception.new(package.name, :import)
|
@@ -130,7 +138,7 @@ module Autobuild
|
|
130
138
|
|
131
139
|
# Creates an importer which downloads a tarball from +source+ and unpacks
|
132
140
|
# it. The allowed values in +options+ are described in TarImporter.new.
|
133
|
-
def self.tar(source, options)
|
141
|
+
def self.tar(source, options = {})
|
134
142
|
TarImporter.new(source, options)
|
135
143
|
end
|
136
144
|
end
|
data/lib/autobuild/package.rb
CHANGED
@@ -4,148 +4,146 @@ require 'autobuild/subcommand'
|
|
4
4
|
|
5
5
|
module Autobuild
|
6
6
|
TARGETS = %w{import prepare build}
|
7
|
-
end
|
8
|
-
|
9
|
-
# Basic block for the autobuilder
|
10
|
-
#
|
11
|
-
# The build is done in three phases:
|
12
|
-
# - import
|
13
|
-
# - prepare
|
14
|
-
# - build & install
|
15
|
-
class Autobuild::Package
|
16
|
-
@@packages = {}
|
17
|
-
@@provides = {}
|
18
|
-
|
19
|
-
# the package name
|
20
|
-
attr_reader :name
|
21
|
-
# set the source directory. If a relative path is given,
|
22
|
-
# it is relative to Autobuild.srcdir. Defaults to #name
|
23
|
-
attr_writer :srcdir
|
24
|
-
# set the installation directory. If a relative path is given,
|
25
|
-
# it is relative to Autobuild.prefix. Defaults to ''
|
26
|
-
attr_writer :prefix
|
27
7
|
|
28
|
-
#
|
29
|
-
#
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
#
|
34
|
-
|
8
|
+
# Basic block for the autobuilder
|
9
|
+
#
|
10
|
+
# The build is done in three phases:
|
11
|
+
# - import
|
12
|
+
# - prepare
|
13
|
+
# - build & install
|
14
|
+
class Package
|
15
|
+
@@packages = {}
|
16
|
+
@@provides = {}
|
17
|
+
|
18
|
+
# the package name
|
19
|
+
attr_reader :name
|
20
|
+
# set the source directory. If a relative path is given,
|
21
|
+
# it is relative to Autobuild.srcdir. Defaults to #name
|
22
|
+
attr_writer :srcdir
|
23
|
+
# set the installation directory. If a relative path is given,
|
24
|
+
# it is relative to Autobuild.prefix. Defaults to ''
|
25
|
+
attr_writer :prefix
|
26
|
+
|
27
|
+
# Sets importer object for this package. Defined for backwards compatibility.
|
28
|
+
# Use the #importer attribute instead
|
29
|
+
def import=(value)
|
30
|
+
@importer = value
|
31
|
+
end
|
32
|
+
# Sets an importer object for this package
|
33
|
+
attr_accessor :importer
|
34
|
+
|
35
|
+
# The list of packages this one depends upon
|
36
|
+
attr_reader :dependencies
|
37
|
+
|
38
|
+
# Absolute path to the source directory. See #srcdir=
|
39
|
+
def srcdir; File.expand_path(@srcdir || name, Autobuild.srcdir) end
|
40
|
+
# Absolute path to the installation directory. See #prefix=
|
41
|
+
def prefix; File.expand_path(@prefix || '', Autobuild.prefix) end
|
42
|
+
|
43
|
+
# The file which marks when the last sucessful install
|
44
|
+
# has finished. The path is absolute
|
45
|
+
#
|
46
|
+
# A package is sucessfully built when it is installed
|
47
|
+
def installstamp; "#{Autobuild.logdir}/#{name}-#{STAMPFILE}" end
|
48
|
+
|
49
|
+
def initialize(spec)
|
50
|
+
@dependencies = Array.new
|
51
|
+
@provides = Array.new
|
52
|
+
|
53
|
+
if Hash === spec
|
54
|
+
name, depends = spec.to_a.first
|
55
|
+
else
|
56
|
+
name, depends = spec, nil
|
57
|
+
end
|
35
58
|
|
36
|
-
|
37
|
-
|
59
|
+
name = name.to_s
|
60
|
+
@name = name
|
61
|
+
raise ConfigException, "package #{name} is already defined" if Autobuild::Package[name]
|
62
|
+
@@packages[name] = self
|
63
|
+
|
64
|
+
# Call the config block (if any)
|
65
|
+
yield(self) if block_given?
|
66
|
+
|
67
|
+
# Declare the installation stampfile
|
68
|
+
file installstamp do
|
69
|
+
Dir.chdir(srcdir) do
|
70
|
+
Autobuild.apply_post_install(@post_install)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
task "#{name}-build" => installstamp
|
74
|
+
task :build => "#{name}-build"
|
38
75
|
|
39
|
-
|
40
|
-
|
41
|
-
# Absolute path to the installation directory. See #prefix=
|
42
|
-
def prefix; File.expand_path(@prefix || '', Autobuild.prefix) end
|
76
|
+
# Add dependencies declared in spec
|
77
|
+
depends_on *depends if depends
|
43
78
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
else
|
57
|
-
name, depends = spec, nil
|
58
|
-
end
|
59
|
-
|
60
|
-
name = name.to_s
|
61
|
-
@name = name
|
62
|
-
raise ConfigException, "package #{name} is already defined" if Package[name]
|
63
|
-
@@packages[name] = self
|
64
|
-
|
65
|
-
# Call the config block (if any)
|
66
|
-
yield(self) if block_given?
|
67
|
-
|
68
|
-
# Declare the installation stampfile
|
69
|
-
file installstamp do
|
70
|
-
Dir.chdir(srcdir) do
|
71
|
-
Autobuild.apply_post_install(@post_install)
|
79
|
+
# Define the import task
|
80
|
+
task "#{name}-import" do import end
|
81
|
+
task :import => "#{name}-import"
|
82
|
+
|
83
|
+
# Define the prepare task
|
84
|
+
task "#{name}-prepare" do prepare end
|
85
|
+
task :prepare => "#{name}-prepare"
|
86
|
+
|
87
|
+
task(name) do
|
88
|
+
Rake::Task["#{name}-import"].invoke
|
89
|
+
Rake::Task["#{name}-prepare"].invoke
|
90
|
+
Rake::Task["#{name}-build"].invoke
|
72
91
|
end
|
92
|
+
task :default => name
|
73
93
|
end
|
74
|
-
task "#{name}-build" => installstamp
|
75
|
-
task :build => "#{name}-build"
|
76
|
-
|
77
|
-
# Add dependencies declared in spec
|
78
|
-
depends_on *depends if depends
|
79
|
-
|
80
|
-
# Define the import task
|
81
|
-
task "#{name}-import" do import end
|
82
|
-
task :import => "#{name}-import"
|
83
|
-
|
84
|
-
# Define the prepare task
|
85
|
-
task "#{name}-prepare" do prepare end
|
86
|
-
task :prepare => "#{name}-prepare"
|
87
|
-
|
88
|
-
task(name) do
|
89
|
-
Rake::Task["#{name}-import"].invoke
|
90
|
-
Rake::Task["#{name}-prepare"].invoke
|
91
|
-
Rake::Task["#{name}-build"].invoke
|
92
|
-
end
|
93
|
-
task :default => name
|
94
|
-
end
|
95
94
|
|
96
|
-
|
97
|
-
|
95
|
+
def import; @importer.import(self) if @importer end
|
96
|
+
def prepare; end
|
98
97
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
98
|
+
def post_install(*args, &block)
|
99
|
+
if args.empty?
|
100
|
+
@post_install = block
|
101
|
+
elsif !block
|
102
|
+
@post_install = args
|
103
|
+
else
|
104
|
+
raise ArgumentError, "cannot set both arguments and block"
|
105
|
+
end
|
106
106
|
end
|
107
|
-
end
|
108
107
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
108
|
+
# This package depends on +packages+
|
109
|
+
def depends_on(*packages)
|
110
|
+
packages.each do |p|
|
111
|
+
p = p.to_s
|
112
|
+
next if p == name
|
113
|
+
unless Package[p]
|
114
|
+
raise ConfigException.new(name), "package #{p} not defined"
|
115
|
+
end
|
116
|
+
file installstamp => Package[p].installstamp
|
117
|
+
task "#{name}-import" => "#{p}-import"
|
118
|
+
task "#{name}-prepare" => "#{p}-prepare"
|
119
|
+
@dependencies << p
|
120
|
+
end
|
121
|
+
end
|
123
122
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
123
|
+
# Declare that this package provides +packages+
|
124
|
+
def provides(*packages)
|
125
|
+
packages.each do |p|
|
126
|
+
p = p.to_s
|
127
|
+
@@provides[p] = self
|
128
|
+
task p => name
|
129
|
+
@provides << p
|
130
|
+
end
|
131
|
+
end
|
133
132
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
133
|
+
# Iterates on all available packages
|
134
|
+
# if with_provides is true, includes the list
|
135
|
+
# of package aliases
|
136
|
+
def self.each(with_provides = false, &p)
|
137
|
+
@@packages.each(&p)
|
138
|
+
@@provides.each(&p) if with_provides
|
139
|
+
end
|
141
140
|
|
142
|
-
|
143
|
-
|
144
|
-
|
141
|
+
# Gets a package from its name
|
142
|
+
def self.[](name)
|
143
|
+
@@packages[name.to_s] || @@provides[name.to_s]
|
144
|
+
end
|
145
145
|
end
|
146
|
-
end
|
147
146
|
|
148
|
-
module Autobuild
|
149
147
|
def self.package_set(spec)
|
150
148
|
spec.each do |name, packages|
|
151
149
|
Autobuild::TARGETS.each do |target|
|
@@ -14,18 +14,12 @@ module Autobuild
|
|
14
14
|
# ==== Handles autotools-based packages
|
15
15
|
#
|
16
16
|
# == Used programs (see <tt>Autobuild.programs</tt>)
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
17
|
+
# Autotools will use the 'aclocal', 'autoheader', 'autoconf' and 'automake'
|
18
|
+
# programs defined on Autobuild.programs. autoheader is disabled by default,
|
19
|
+
# aclocal, autoconf and automake use are autodetected.
|
20
|
+
#
|
21
|
+
# To override this default behaviour on a per-package basis, use Autotools#use
|
21
22
|
#
|
22
|
-
# == Available options
|
23
|
-
# * aclocal (default: true if autoconf is enabled, false otherwise) run aclocal
|
24
|
-
# * autoconf (default: true)
|
25
|
-
# * autoheader (default: false) run autoheader
|
26
|
-
# * automake (default: autodetect) run automake. Will run automake if there is a
|
27
|
-
# +Makefile.am+ in the source directory
|
28
|
-
#
|
29
23
|
class Autotools < Package
|
30
24
|
attr_accessor :using
|
31
25
|
attr_accessor :configureflags
|
@@ -61,6 +55,29 @@ module Autobuild
|
|
61
55
|
Autobuild.update_environment(prefix)
|
62
56
|
end
|
63
57
|
|
58
|
+
# Overrides the default behaviour w.r.t. autotools script generation
|
59
|
+
#
|
60
|
+
# Use it like that:
|
61
|
+
# * to force a generation step (skipping autodetection), do
|
62
|
+
# pkg.use <program> => true
|
63
|
+
# For instance, for aclocal
|
64
|
+
# pkg.use :aclocal => true
|
65
|
+
#
|
66
|
+
# * to force a generation step, overriding the program defined on Autobuild
|
67
|
+
# pkg.use <program> => true
|
68
|
+
# For instance, for autoconf
|
69
|
+
# pkg.use :autoconf => 'my_autoconf_program'
|
70
|
+
#
|
71
|
+
# * to disable a generation step, do
|
72
|
+
# pkg.use <program> => false
|
73
|
+
# For instance, for automake
|
74
|
+
# pkg.use :automake => false
|
75
|
+
#
|
76
|
+
# * to restore autodetection, do
|
77
|
+
# pkg.use <program> => nil
|
78
|
+
# For instance, for automake
|
79
|
+
# pkg.use :automake => nil
|
80
|
+
#
|
64
81
|
def use(*programs)
|
65
82
|
programs = *programs
|
66
83
|
if !programs.kind_of?(Hash)
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# This sample file installs a set of autotools packages from
|
2
|
+
# the OpenRobots suite of tools (http://softs.laas.fr/openrobots)
|
3
|
+
#
|
4
|
+
# The user (you) is asked about the installation directory (prefix). Then, the various packages
|
5
|
+
# are installed the following way:
|
6
|
+
# * sources are in prefix/src
|
7
|
+
# * installed packages are in prefix/bin, prefix/lib, prefix/include, ...
|
8
|
+
#
|
9
|
+
# This version uses the Tar importer to get the latest release
|
10
|
+
require 'autobuild'
|
11
|
+
require 'autobuild/packages/autotools'
|
12
|
+
require 'autobuild/import/tar'
|
13
|
+
|
14
|
+
Thread.abort_on_exception = true
|
15
|
+
STDOUT.sync = true
|
16
|
+
|
17
|
+
# Ask the user (you) where you want everything installed
|
18
|
+
default_prefix = "#{ENV['HOME']}/openrobots"
|
19
|
+
print "Where to intall openrobots ? [#{default_prefix}]"
|
20
|
+
answer = STDIN.readline
|
21
|
+
answer = default_prefix if answer == "\n"
|
22
|
+
|
23
|
+
# Set the root directory for sources import and package installation
|
24
|
+
Autobuild.srcdir = File.join(answer, "src")
|
25
|
+
Autobuild.prefix = answer
|
26
|
+
|
27
|
+
# Define a fake 'openrobots' package type which describes the common package
|
28
|
+
# configuration for packages from openrobots
|
29
|
+
#
|
30
|
+
# spec is either a name (the package name) or a name => dependencies hash
|
31
|
+
OPENROBOTS_DOWNLOAD_BASEURL = "http://softs.laas.fr/openrobots/php/download.php/"
|
32
|
+
def openrobots(version, spec)
|
33
|
+
Autobuild.autotools(spec) do |pkg|
|
34
|
+
# Install the sources in #{Autobuild.srcdir}/package_name
|
35
|
+
pkg.srcdir = pkg.name
|
36
|
+
|
37
|
+
# Build packages into #{package source dir}/build
|
38
|
+
pkg.builddir = "build"
|
39
|
+
|
40
|
+
# The importer object will download the file and decompress it into the
|
41
|
+
# specified source directory
|
42
|
+
#
|
43
|
+
# The tarballs contain a name-version directory. The :tardir option
|
44
|
+
# makes the tar importer rename that directory into 'name'
|
45
|
+
pkg.importer = Autobuild.tar(OPENROBOTS_DOWNLOAD_BASEURL + "#{pkg.name}-#{version}.tar.gz",
|
46
|
+
:tardir => "#{pkg.name}-#{version}")
|
47
|
+
|
48
|
+
# Do not autogenerate configure scripts, use the ones in the tarball instead
|
49
|
+
pkg.use :aclocal => false
|
50
|
+
pkg.use :autoconf => false
|
51
|
+
pkg.use :automake => false
|
52
|
+
|
53
|
+
# All openrobots package depend on mkdep
|
54
|
+
if pkg.name != "mkdep"
|
55
|
+
pkg.depends_on 'mkdep'
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# You can override the version of aclocal/autoconf/automake used if needed
|
61
|
+
# Autotools.aclocal = "aclocal-1.9"
|
62
|
+
# Autotools.automake = "automake-1.9"
|
63
|
+
|
64
|
+
# Declare the packages themselves
|
65
|
+
openrobots "2.6", :mkdep
|
66
|
+
openrobots "2.2", :pocolibs
|
67
|
+
|
68
|
+
# Genom depends on pocolibs, declare that
|
69
|
+
openrobots "1.99.902", :genom => :pocolibs
|
70
|
+
|
71
|
+
# GDHE needs a X display to install. Check that the DISPLAY environment
|
72
|
+
# variable is set
|
73
|
+
if ENV['DISPLAY']
|
74
|
+
openrobots "3.7", :gdhe
|
75
|
+
else
|
76
|
+
STDERR.puts "GDHE installation requires a X display. Disabled"
|
77
|
+
end
|
78
|
+
|
metadata
CHANGED
@@ -3,7 +3,7 @@ rubygems_version: 0.9.4
|
|
3
3
|
specification_version: 1
|
4
4
|
name: autobuild
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version:
|
6
|
+
version: 1.0.1
|
7
7
|
date: 2007-06-22 00:00:00 +02:00
|
8
8
|
summary: Rake-based utility to build and install multiple packages with dependencies
|
9
9
|
require_paths:
|
@@ -53,7 +53,7 @@ files:
|
|
53
53
|
- lib/autobuild/reporting.rb
|
54
54
|
- lib/autobuild/subcommand.rb
|
55
55
|
- lib/autobuild/timestamps.rb
|
56
|
-
- samples/
|
56
|
+
- samples/openrobots.autobuild
|
57
57
|
- test/data/cvsroot.tar
|
58
58
|
- test/data/svnroot.tar
|
59
59
|
- test/data/tarimport.tar.gz
|
data/samples/demo.rb
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
require 'autobuild'
|
2
|
-
|
3
|
-
# Remove the need for the Autobuild. prefix in
|
4
|
-
# front of everything
|
5
|
-
include Autobuild
|
6
|
-
|
7
|
-
# Define a common configuration routine
|
8
|
-
openrobots_config = lambda { |pkg|
|
9
|
-
pkg.import = cvs(openrobots, pkg.name)
|
10
|
-
pkg.depends_on :mkdep
|
11
|
-
}
|
12
|
-
|
13
|
-
Autotools.aclocal = "aclocal-1.9"
|
14
|
-
Autotools.automake = "automake-1.9"
|
15
|
-
|
16
|
-
autotools(:mkdep, &openrobots_config)
|
17
|
-
autotools(:gdhe, &openrobots_config)
|
18
|
-
autotools(:pocolibs, &openrobots_config)
|
19
|
-
autotools :genom do |pkg|
|
20
|
-
openrobots_config[pkg]
|
21
|
-
pkg.autoheader = true # Force usage of autoheader
|
22
|
-
pkg.automake = 'automake' # use the default automake instead
|
23
|
-
# of Autotools.automake
|
24
|
-
end
|
25
|
-
|