autobuild 1.0 → 1.0.1
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 +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
|
-
|