Module: Autobuild

Defined in:
lib/autobuild/config.rb,
lib/autobuild.rb,
lib/autobuild/test.rb,
lib/autobuild/tools.rb,
lib/autobuild/package.rb,
lib/autobuild/utility.rb,
lib/autobuild/version.rb,
lib/autobuild/importer.rb,
lib/autobuild/parallel.rb,
lib/autobuild/import/hg.rb,
lib/autobuild/reporting.rb,
lib/autobuild/reporting.rb,
lib/autobuild/exceptions.rb,
lib/autobuild/import/cvs.rb,
lib/autobuild/import/git.rb,
lib/autobuild/import/svn.rb,
lib/autobuild/subcommand.rb,
lib/autobuild/timestamps.rb,
lib/autobuild/environment.rb,
lib/autobuild/configurable.rb,
lib/autobuild/import/darcs.rb,
lib/autobuild/test_utility.rb,
lib/autobuild/build_logfile.rb,
lib/autobuild/mail_reporter.rb,
lib/autobuild/packages/ruby.rb,
lib/autobuild/import/archive.rb,
lib/autobuild/import/git-lfs.rb,
lib/autobuild/packages/cmake.rb,
lib/autobuild/packages/dummy.rb,
lib/autobuild/packages/genom.rb,
lib/autobuild/packages/import.rb,
lib/autobuild/packages/orogen.rb,
lib/autobuild/packages/python.rb,
lib/autobuild/packages/gnumake.rb,
lib/autobuild/progress_display.rb,
lib/autobuild/packages/autotools.rb,
lib/autobuild/packages/pkgconfig.rb,
lib/autobuild/rake_task_extension.rb

Overview

Main Autobuild module

Defined Under Namespace

Modules: RakeTaskExtension, Reporting, SelfTest, Subprocess Classes: AlreadyFailedError, ArchiveImporter, Autotools, BuildLogfile, CMake, CVSImporter, CommandNotFound, CompositeException, ConfigException, Configurable, DarcsImporter, DummyPackage, Environment, GenomModule, Git, Hg, Importer, ImporterCannotReset, ImporterPackage, InstalledPkgConfig, InteractionRequired, MailReporter, NotGNUMake, Orogen, Package, PackageException, PhaseException, ProgressDisplay, Python, RakeTaskParallelism, Reporter, Ruby, SVN, SourceTreeTask, StdoutReporter, SubcommandFailed, TestUtility, Utility

Constant Summary collapse

LIB_DIR =
__dir__
DEFAULT_OPTIONS =
{
    :nice => nil, :srcdir => Dir.pwd, :prefix => Dir.pwd,
    :logdir => nil, :verbose => false, :debug => false, :do_build => true,
    :do_forced_build => false, :do_rebuild => false, :do_update => true,
    :daemonize => false, :packages => [], :default_packages => [],
    :keep_oldlogs => false
}.freeze
TARGETS =
%w[import prepare build].freeze
VERSION =
"1.24.0".freeze
HUMAN_READABLE_SIZES =
[
    [1_000_000_000.0, "G"],
    [1_000_000.0, "M"],
    [1_000.0, "k"],
    [1.0, ""]
].freeze
Exception =

Backward compatibility

PhaseException
STAMPFILE =
"autobuild-stamp".freeze
SHELL_VAR_EXPANSION =
if windows? then "%%%s%%".freeze
else
    "$%s".freeze
end
SHELL_SET_COMMAND =
if windows? then "set %s=%s".freeze
else
    "%s=\"%s\"".freeze
end
SHELL_CONDITIONAL_SET_COMMAND =
if windows? then "set %s=%s".freeze
else
    "if test -z \"$%1$s\"; then\n  %1$s=\"%3$s\"\n"\
    "else\n  %1$s=\"%2$s\"\nfi".freeze
end
SHELL_UNSET_COMMAND =
"unset %s".freeze
SHELL_EXPORT_COMMAND =
if windows? then "set %s".freeze
else
    "export %s".freeze
end
SHELL_SOURCE_SCRIPT =
if windows? then "%s".freeze
else
    '. "%s"'.freeze
end
LIBRARY_PATH =
if macos? then 'DYLD_LIBRARY_PATH'.freeze
elsif windows? then 'PATH'.freeze
else
    'LD_LIBRARY_PATH'.freeze
end
LIBRARY_SUFFIX =
if macos? then 'dylib'
elsif windows? then 'dll'
else
    'so'
end
ORIGINAL_ENV =
Hash.new
TarImporter =

For backwards compatibility

ArchiveImporter
GNUMAKE_JOBSERVER_AUTH_VERSION =
Gem::Version.new("4.2.0")

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.displayed_error_line_countObject

Returns the value of attribute displayed_error_line_count.



60
61
62
# File 'lib/autobuild/subcommand.rb', line 60

def displayed_error_line_count
  @displayed_error_line_count
end

.ignore_errorsObject

Returns the value of attribute ignore_errors.



5
6
7
# File 'lib/autobuild/package.rb', line 5

def ignore_errors
  @ignore_errors
end

.ignored_filesObject (readonly)

The set of global ignores for SourceTreeTask

Regular expressions added to this set will be used to determine if a source tree has or has not changed



9
10
11
# File 'lib/autobuild/timestamps.rb', line 9

def ignored_files
  @ignored_files
end

.logdirObject

The directory in which logs are saved



171
172
173
# File 'lib/autobuild/config.rb', line 171

def logdir
    @logdir || "#{prefix}/log"
end

.mailObject (readonly)

Mailing configuration. It is a hash with the following keys (as symbols)

:to

the mail destination. Defaults to USER@HOSTNAME, where USER is

the username of autobuild's caller, and HOSTNAME the hostname of the
current machine.
:from

the mail origin. Defaults to the same value than :to

:smtp

the hostname of the SMTP server, defaults to localhost

:port

the port of the SMTP server, defauts to 22

:only_errors

mail only on errors. Defaults to false.



146
147
148
# File 'lib/autobuild/config.rb', line 146

def mail
  @mail
end

.parallel_build_levelObject

Returns the number of processes that can run in parallel during the build. This is a system-wide value that can be overriden in a per-package fashion by using Package#parallel_build_level.

If not set, defaults to the number of CPUs on the system

See also #parallel_build_level=



69
70
71
72
73
74
75
76
77
78
79
# File 'lib/autobuild/subcommand.rb', line 69

def parallel_build_level
    if @parallel_build_level.nil?
        # No user-set value, return the count of processors on this
        # machine
        autodetect_processor_count
    elsif !@parallel_build_level || @parallel_build_level <= 0
        1
    else
        @parallel_build_level
    end
end

.parallel_task_managerObject

Returns the value of attribute parallel_task_manager.



319
320
321
# File 'lib/autobuild/parallel.rb', line 319

def parallel_task_manager
  @parallel_task_manager
end

.post_install_handlersObject (readonly)

Returns the value of attribute post_install_handlers.



116
117
118
# File 'lib/autobuild/config.rb', line 116

def post_install_handlers
  @post_install_handlers
end

.programsObject (readonly)

Configure the programs used by different packages



4
5
6
# File 'lib/autobuild/tools.rb', line 4

def programs
  @programs
end

.programs_in_path{String=>[String,String,String]} (readonly)

A cache of entries in programs to their resolved full path

Returns:

  • ({String=>[String,String,String]})

    the triplet (full path, tool name, value of ENV). The last two values are used to invalidate the cache when needed

See Also:



12
13
14
# File 'lib/autobuild/tools.rb', line 12

def programs_in_path
  @programs_in_path
end

.utilities{String=>Class<Utility>} (readonly)

Returns the known utilities.

Returns:

  • ({String=>Class<Utility>})

    the known utilities

See Also:

  • {register_utility_class}


40
41
42
# File 'lib/autobuild/config.rb', line 40

def utilities
  @utilities
end

Class Method Details

.add_stat(package, phase, duration) ⇒ Object



33
34
35
36
37
38
39
40
41
# File 'lib/autobuild/subcommand.rb', line 33

def self.add_stat(package, phase, duration)
    if !@statistics[package]
        @statistics[package] = { phase => duration }
    elsif !@statistics[package][phase]
        @statistics[package][phase] = duration
    else
        @statistics[package][phase] += duration
    end
end

.all_phasesArray<String>

The name of all build phases that Autobuild knows about

Returns:

  • (Array<String>)


297
298
299
300
# File 'lib/autobuild/config.rb', line 297

def self.all_phases
    %w[import prepare build] +
        utilities.keys
end

.apply(packages, buildname = "autobuild", phases = [], options = Hash.new) ⇒ Object



302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
# File 'lib/autobuild/config.rb', line 302

def self.apply(packages, buildname = "autobuild", phases = [], options = Hash.new)
    options = Kernel.validate_options options,
                                      parallel: Autobuild.parallel_build_level

    if Autobuild.mail[:to]
        if !Autobuild::HAS_RMAIL
            Autobuild.warn "RMail is not available. Mail notification is disabled"
        else
            Reporting << MailReporter.new(Autobuild.mail)
        end
    end

    if Autobuild.do_rebuild
        packages.each do |pkg_name|
            Autobuild::Package[pkg_name].prepare_for_rebuild
        end
        # And delete the prefix !
        FileUtils.rm_rf Autobuild.prefix

    elsif Autobuild.do_forced_build
        packages.each do |pkg_name|
            Autobuild::Package[pkg_name].prepare_for_forced_build
        end
    end

    if phases.empty?
        if Autobuild.only_doc
            phases  = ['doc']
        else
            phases  = ['import']
            phases += %w[prepare build] if Autobuild.do_build
            phases << 'doc' if Autobuild.do_doc
        end
    end

    phases.each do |phase|
        # We create a dummy task listing what needs to be done, and then we
        # call it
        targets = if packages.empty?
                      phase
                  else
                      packages.
                        find_all { |pkg| Rake.application.lookup("#{pkg}-#{phase}") }.
                        map { |pkg| "#{pkg}-#{phase}" }
                  end

        task "#{buildname}-#{phase}" => targets
    end

    begin
        invoker = Autobuild::RakeTaskParallelism.new(options[:parallel])
        Autobuild.parallel_task_manager = invoker
        phases.each do |phase|
            package_tasks = packages.each_with_object({}) do |pkg_name, h|
                h["#{pkg_name}-#{phase}"] = true
            end
            callback =
                if block_given?
                    proc do |task|
                        yield(task.package, phase) if package_tasks[task.name]
                    end
                else
                    proc {}
                end

            invoker.invoke_parallel([Rake::Task["#{buildname}-#{phase}"]],
                                    completion_callback: callback)
        end
    ensure
        Autobuild.parallel_task_manager = nil
    end
end

.apply_post_install(pkg, info) ⇒ Object



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/autobuild/config.rb', line 119

def self.apply_post_install(pkg, info)
    return unless info

    case info
    when Array
        args = info.dup
        tool = Autobuild.tool(args.shift)
        pkg.run 'post-install', tool, *args
    when Proc
        if info.arity == 1
            info.call(pkg)
        else
            info.call
        end
    end
end

.arch_namesObject



957
958
959
960
961
# File 'lib/autobuild/environment.rb', line 957

def self.arch_names
    Autobuild.warn 'Autobuild.arch_names is deprecated, "\
        "use Autobuild.env.arch_names instead'
    env.arch_names
end

.arch_sizeObject



951
952
953
954
955
# File 'lib/autobuild/environment.rb', line 951

def self.arch_size
    Autobuild.warn 'Autobuild.arch_size is deprecated, "\
        "use Autobuild.env.arch_size instead'
    env.arch_size
end

.archive(source, options = {}) ⇒ Object

Creates an importer which downloads a tarball from source and unpacks it. The allowed values in options are described in ArchiveImporter.new.



578
579
580
# File 'lib/autobuild/import/archive.rb', line 578

def self.archive(source, options = {})
    ArchiveImporter.new(source, options)
end

.autodetect_processor_countObject

Returns the number of CPUs present on this system



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/autobuild/subcommand.rb', line 83

def self.autodetect_processor_count
    return @processor_count if @processor_count

    if File.file?('/proc/cpuinfo')
        cpuinfo = File.readlines('/proc/cpuinfo')
        physical_ids  = []
        core_count    = []
        processor_ids = []
        cpuinfo.each do |line|
            case line
            when /^processor\s+:\s+(\d+)$/
                processor_ids << Integer($1)
            when /^physical id\s+:\s+(\d+)$/
                physical_ids << Integer($1)
            when /^cpu cores\s+:\s+(\d+)$/
                core_count << Integer($1)
            end
        end

        # Try to count the number of physical cores, not the number of
        # logical ones. If the info is not available, fallback to the
        # logical count
        has_consistent_info =
            (physical_ids.size == core_count.size) &&
            (physical_ids.size == processor_ids.size)
        if has_consistent_info
            info = Array.new
            while (id = physical_ids.shift)
                info[id] = core_count.shift
            end
            @processor_count = info.compact.inject(&:+)
        else
            @processor_count = processor_ids.size
        end
    else
        result = Open3.popen3("sysctl", "-n", "hw.ncpu") do |_, io, _|
            io.read
        end
        @processor_count = Integer(result.chomp.strip) unless result.empty?
    end

    # The format of the cpuinfo file is ... let's say not very standardized.
    # If the cpuinfo detection fails, inform the user and set it to 1
    unless @processor_count
        # Hug... What kind of system is it ?
        Autobuild.message "INFO: cannot autodetect the number of CPUs on this sytem"
        Autobuild.message "INFO: turning parallel builds off"
        Autobuild.message "INFO: you can manually set the number of parallel build "\
            "processes to N"
        Autobuild.message "INFO: (and therefore turn this message off)"
        Autobuild.message "INFO: with"
        Autobuild.message "    Autobuild.parallel_build_level = N"
        @processor_count = 1
    end

    @processor_count
end

.autotools(opts, &proc) ⇒ Object



10
11
12
# File 'lib/autobuild/packages/autotools.rb', line 10

def self.autotools(opts, &proc)
    Autotools.new(opts, &proc)
end

.bsd?Boolean

Returns:

  • (Boolean)


21
22
23
# File 'lib/autobuild/environment.rb', line 21

def self.bsd?
    @freebsd || @macos # can be extended to some other OSes liek NetBSD
end

.clean_log!Object

Removes all log files



176
177
178
179
180
# File 'lib/autobuild/config.rb', line 176

def clean_log!
    Reporting.each_log do |file|
        FileUtils.rm_f file
    end
end

.clear_logfilesObject



9
10
11
# File 'lib/autobuild/subcommand.rb', line 9

def self.clear_logfiles
    @logfiles.clear
end

.cmake(options, &block) ⇒ Object



5
6
7
# File 'lib/autobuild/packages/cmake.rb', line 5

def self.cmake(options, &block)
    CMake.new(options, &block)
end

.color(message, *style) ⇒ Object



20
21
22
# File 'lib/autobuild/reporting.rb', line 20

def color(message, *style)
    @colorizer.decorate(message, *style)
end

.color=(flag) ⇒ Object



7
8
9
10
11
12
13
14
# File 'lib/autobuild/reporting.rb', line 7

def color=(flag)
    @colorizer =
        if flag.nil?
            Pastel.new
        else
            Pastel.new(enabled: flag)
        end
end

.color?Boolean

Returns:

  • (Boolean)


16
17
18
# File 'lib/autobuild/reporting.rb', line 16

def color?
    @colorizer.enabled?
end

.commandline(args) ⇒ Object

Gets autobuild options from the command line and returns the remaining elements



184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
# File 'lib/autobuild/config.rb', line 184

def commandline(args)
    parser = OptionParser.new do |opts|
        opts.separator "Path specification"
        opts.on("--srcdir PATH", "sources are installed in PATH") do |v|
            Autobuild.srcdir = v
        end
        opts.on("--prefix PATH", "built packages are installed in PATH") do |v|
            Autobuild.prefix = v
        end
        opts.on("--logdir PATH", "logs are saved in PATH "\
            "(default: <prefix>/autobuild)") do |v|
            Autobuild.logdir = v
        end

        opts.separator ""
        opts.separator "General behaviour"
        opts.on('--nice NICE', Integer,
                'nice the subprocesses to the given value') do |v|
            Autobuild.nice = v
        end
        opts.on("-h", "--help", "Show this message") do
            puts opts
            exit
        end
        if defined? Daemons
            opts.on("--[no-]daemon", "go into daemon mode") do |v|
                Autobuild.daemonize = v
            end
        end
        opts.on("--no-update", "update already checked-out sources") do |v|
            Autobuild.do_update = v
        end
        opts.on("--no-build",  "only prepare packages, do not build them") do |v|
            Autobuild.do_build = v
        end
        opts.on("--forced-build", "force the trigger of "\
            "all the build commands") do |v|
            Autobuild.do_forced_build = v
        end
        opts.on("--rebuild", "clean and rebuild") do |v|
            Autobuild.do_forced_build = v
        end
        opts.on("--only-doc", "only generate documentation") do |v|
            Autobuild.only_doc = v
        end
        opts.on("--no-doc", "don't generate documentation") do |v|
            Autobuild.do_doc = v
        end
        opts.on("--doc-errors", "treat documentation failure as error") do |v|
            Autobuild.pass_doc_errors = v
        end

        opts.separator ""
        opts.separator "Program output"
        opts.on("--[no-]verbose", "display output of commands on stdout") do |v|
            Autobuild.verbose = v
        end
        opts.on("--[no-]debug", "debug information") do |v|
            Autobuild.debug = v
        end
        opts.on("--keep-oldlogs", "old logs will be kept, "\
            "new program output being appended") do |v|
            Autobuild.keep_oldlogs = v
        end
        opts.on('--version', "displays autobuild version and then exits") do
            puts "autobuild v#{Autobuild::VERSION}"
            exit 0
        end

        opts.separator ""
        opts.separator "Mail reports"
        opts.on("--mail-from EMAIL", String,
                "From: field of the sent mails") do |from_email|
            mail[:from] = from_email
        end
        opts.on("--mail-to EMAILS", String, "comma-separated list of emails "\
            "to which the reports should be sent") do |emails|
            mail[:to] ||= []
            mail[:to] += emails.split(',')
        end
        opts.on("--mail-subject SUBJECT", String,
                "Subject: field of the sent mails") do |subject_email|
            mail[:subject] = subject_email
        end
        opts.on("--mail-smtp HOSTNAME", String, "address of the mail server "\
            "written as hostname[:port]") do |smtp|
            unless smtp =~ /^([^:]+)(?::(\d+))?$/
                raise "invalid SMTP specification #{smtp}"
            end

            mail[:smtp] = $1
            mail[:port] = Integer($2) if $2 && !$2.empty?
        end
        opts.on("--mail-only-errors", "send mail only on errors") do
            mail[:only_errors] = true
        end
    end

    parser.parse!(args)
    unless args[0]
        puts parser
        exit
    end

    Rake.application.options.trace = debug

    args[0..-1]
end

.create_utility(utility_name, package) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/autobuild/config.rb', line 69

def create_utility(utility_name, package)
    klass, creation_options, options = utilities[utility_name]
    if klass
        utility = klass.new(utility_name, package, **options)
        package.utilities[utility_name] = utility
        utility.enabled = !creation_options[:disabled_by_default]
        utility
    else
        raise ArgumentError, "there is no utility called #{utility_name}, "\
            "available utilities are #{utilities.keys.sort.join(', ')}"
    end
end

.cvs(root, options = {}, backward_compatibility = nil) ⇒ Object

Returns the CVS importer which will get the name module in repository repo. The allowed values in options are described in CVSImporter.new.



82
83
84
85
86
87
88
89
# File 'lib/autobuild/import/cvs.rb', line 82

def self.cvs(root, options = {}, backward_compatibility = nil)
    if backward_compatibility
        backward_compatibility[:module] = options
        CVSImporter.new(root, backward_compatibility)
    else
        CVSImporter.new(root, options)
    end
end

.darcs(source, options = {}) ⇒ Object

Returns the Darcs importer which will get the source from the Darcs repository source. The allowed values in options are described in DarcsImporter.new.



51
52
53
# File 'lib/autobuild/import/darcs.rb', line 51

def self.darcs(source, options = {})
    DarcsImporter.new(source, options)
end

.dummy(spec) ⇒ Object



2
3
4
# File 'lib/autobuild/packages/dummy.rb', line 2

def self.dummy(spec)
    DummyPackage.new(spec)
end

.each_env_search_path(prefix, patterns) ⇒ Object

@deprecated, use the API on env instead



933
934
935
# File 'lib/autobuild/environment.rb', line 933

def self.each_env_search_path(prefix, patterns)
    env.each_env_search_path(prefix, patterns)
end

.each_utility {|utility, utility, utility| ... } ⇒ void

This method returns an undefined value.

Yields all known utility classes

Yield Parameters:

  • utility (String)

    name

  • utility (Class)

    class

  • utility (Hash)

    options



48
49
50
51
52
# File 'lib/autobuild/config.rb', line 48

def each_utility
    return enum_for(__method__) unless block_given?

    utilities.each { |name, (utl, options)| yield(name, utl, options) }
end

.ensure_gnumake_detected(pkg, path = Autobuild.tool(:make)) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/autobuild/packages/gnumake.rb', line 9

def self.ensure_gnumake_detected(pkg, path = Autobuild.tool(:make))
    @make_is_gnumake ||= Hash.new
    @gnumake_version ||= Hash.new
    return @make_is_gnumake[path] if @make_is_gnumake.key?(path)

    begin
        gnumake_version_string = pkg.run('prepare', path, '--version')
    rescue Autobuild::SubcommandFailed
        @make_is_gnumake[path] = false
        return
    end

    gnumake_match = /^GNU Make[^\d]+(\d[\d.]+)/.match(gnumake_version_string.first)
    unless gnumake_match
        @make_is_gnumake[path] = false
        return
    end

    @gnumake_version[path] = Gem::Version.new(gnumake_match[1])
    @make_is_gnumake[path] = true
end

.envObject



836
837
838
839
840
841
842
# File 'lib/autobuild/environment.rb', line 836

def self.env
    unless @env
        @env = Environment.new
        @env.prepare
    end
    @env
end

.env=(env) ⇒ Object



830
831
832
# File 'lib/autobuild/environment.rb', line 830

def self.env=(env)
    @env = env
end

.env_add(name, *values) ⇒ Object

@deprecated, use the API on env instead



885
886
887
# File 'lib/autobuild/environment.rb', line 885

def self.env_add(name, *values)
    env.add(name, *values)
end

.env_add_path(name, *paths) ⇒ Object

@deprecated, use the API on env instead



898
899
900
# File 'lib/autobuild/environment.rb', line 898

def self.env_add_path(name, *paths)
    env.add_path(name, *paths)
end

.env_clear(name = nil) ⇒ Object

@deprecated, use the API on env instead



850
851
852
# File 'lib/autobuild/environment.rb', line 850

def self.env_clear(name = nil)
    env.clear(name)
end

.env_inherit(*names) ⇒ Object

@deprecated, use the API on env instead



870
871
872
# File 'lib/autobuild/environment.rb', line 870

def self.env_inherit(*names)
    env.inherit(*names)
end

.env_inherit=(value) ⇒ Object

@deprecated, use the API on env instead



865
866
867
# File 'lib/autobuild/environment.rb', line 865

def self.env_inherit=(value)
    env.inherit = value
end

.env_inherit?(name = nil) ⇒ Boolean

@deprecated, use the API on env instead

Returns:

  • (Boolean)


860
861
862
# File 'lib/autobuild/environment.rb', line 860

def self.env_inherit?(name = nil)
    env.inherit?(name)
end

.env_init_from_env(name) ⇒ Object

@deprecated, use the API on env instead



875
876
877
# File 'lib/autobuild/environment.rb', line 875

def self.env_init_from_env(name)
    env.init_from_env(name)
end

.env_push(name, *values) ⇒ Object

@deprecated, use the API on env instead



880
881
882
# File 'lib/autobuild/environment.rb', line 880

def self.env_push(name, *values)
    env.push(name, *values)
end

.env_push_path(name, *values) ⇒ Object

@deprecated, use the API on env instead



908
909
910
# File 'lib/autobuild/environment.rb', line 908

def self.env_push_path(name, *values)
    env.push_path(name, *values)
end

.env_remove_path(name, *paths) ⇒ Object

@deprecated, use the API on env instead



903
904
905
# File 'lib/autobuild/environment.rb', line 903

def self.env_remove_path(name, *paths)
    env.remove_path(name, *paths)
end

.env_reset(name = nil) ⇒ Object

@deprecated, use the API on env instead



845
846
847
# File 'lib/autobuild/environment.rb', line 845

def self.env_reset(name = nil)
    env.reset(name)
end

.env_set(name, *values) ⇒ Object

@deprecated, use the API on env instead



855
856
857
# File 'lib/autobuild/environment.rb', line 855

def self.env_set(name, *values)
    env.set(name, *values)
end

.env_source_after(file = nil, shell: 'sh') ⇒ Object

@deprecated, use the API on env instead



923
924
925
# File 'lib/autobuild/environment.rb', line 923

def self.env_source_after(file = nil, shell: 'sh')
    env.source_after(file, shell: shell)
end

.env_source_before(file = nil, shell: 'sh') ⇒ Object

@deprecated, use the API on env instead



918
919
920
# File 'lib/autobuild/environment.rb', line 918

def self.env_source_before(file = nil, shell: 'sh')
    env.source_before(file, shell: shell)
end

.env_source_file(file, shell: 'sh') ⇒ Object

@deprecated, use the API on env instead



913
914
915
# File 'lib/autobuild/environment.rb', line 913

def self.env_source_file(file, shell: 'sh')
    env.source_after(file, shell: shell)
end

.env_update_var(name) ⇒ Object

@deprecated, there is no corresponding API on the Environment



895
# File 'lib/autobuild/environment.rb', line 895

def self.env_update_var(name); end

.env_value(name, options = Hash.new) ⇒ Object

@deprecated, use the API on env instead



890
891
892
# File 'lib/autobuild/environment.rb', line 890

def self.env_value(name, options = Hash.new)
    env.value(name, options)
end

.error(message = "") ⇒ Object

Displays an error message



72
73
74
# File 'lib/autobuild/reporting.rb', line 72

def self.error(message = "")
    message("  ERROR: #{message}", :red, :bold, io: STDERR)
end

.export_env_sh(io) ⇒ Object

@deprecated, use the API on env instead



928
929
930
# File 'lib/autobuild/environment.rb', line 928

def self.export_env_sh(io)
    env.export_env_sh(io)
end

.find_in_path(file, envvar = 'PATH') ⇒ Object

Find a file in a given path-like variable



25
26
27
# File 'lib/autobuild/tools.rb', line 25

def find_in_path(file, envvar = 'PATH')
    env.find_in_path(file, envvar)
end

.freebsd?Boolean

Returns:

  • (Boolean)


17
18
19
# File 'lib/autobuild/environment.rb', line 17

def self.freebsd?
    @freebsd
end

.full_build?Boolean

True if we build and if the build is applied on all packages

Returns:

  • (Boolean)


85
86
87
# File 'lib/autobuild/config.rb', line 85

def full_build?
    do_build && !only_doc && packages.empty?
end

.genom(opts, &proc) ⇒ Object



6
7
8
# File 'lib/autobuild/packages/genom.rb', line 6

def self.genom(opts, &proc)
    GenomModule.new(opts, &proc)
end

.get_stamp(stampfile) ⇒ Object



84
85
86
87
88
89
90
# File 'lib/autobuild/timestamps.rb', line 84

def self.get_stamp(stampfile)
    if File.exist?(stampfile)
        File.mtime(stampfile)
    else
        Time.at(0)
    end
end

.git(repository, branch = nil, options = {}) ⇒ Object

Creates a git importer which gets the source for the given repository and branch URL source.



1454
1455
1456
# File 'lib/autobuild/import/git.rb', line 1454

def self.git(repository, branch = nil, options = {})
    Git.new(repository, branch, options)
end

.gnumake_jobserver_option(job_server, pkg, path = Autobuild.tool(:make)) ⇒ Object



57
58
59
60
61
62
63
64
65
66
# File 'lib/autobuild/packages/gnumake.rb', line 57

def self.gnumake_jobserver_option(job_server, pkg, path = Autobuild.tool(:make))
    jobserver_fds_arg = "#{job_server.rio.fileno},#{job_server.wio.fileno}"

    version = gnumake_version(pkg, path)
    if version >= GNUMAKE_JOBSERVER_AUTH_VERSION
        ["--jobserver-auth=#{jobserver_fds_arg}"]
    else
        ["--jobserver-fds=#{jobserver_fds_arg}", "-j"]
    end
end

.gnumake_version(pkg, path = Autobuild.tool(:make)) ⇒ Object



38
39
40
41
42
43
44
45
# File 'lib/autobuild/packages/gnumake.rb', line 38

def self.gnumake_version(pkg, path = Autobuild.tool(:make))
    if ensure_gnumake_detected(pkg, path)
        @gnumake_version.fetch(path)
    else
        raise NotGNUMake, "either #{path} is not a GNU Make or it does not have "\
                          "the expected version string"
    end
end

.hg(repository, options = {}) ⇒ Object

Creates a hg importer which gets the source for the given repository and branch URL source.

Parameters:

  • repository (String)

    the repository URL

  • options (Hash) (defaults to: {})

    a customizable set of options



83
84
85
# File 'lib/autobuild/import/hg.rb', line 83

def self.hg(repository, options = {})
    Hg.new(repository, options)
end

.hires_modification_time?Boolean

Returns:

  • (Boolean)


92
93
94
95
96
97
98
99
100
101
# File 'lib/autobuild/timestamps.rb', line 92

def self.hires_modification_time?
    if @hires_modification_time.nil?
        Tempfile.open('test') do |io|
            io.flush
            p_time = File.mtime(io.path)
            @hires_modification_time = (p_time.tv_usec != 0)
        end
    end
    @hires_modification_time
end

.human_readable_size(size) ⇒ Object



244
245
246
247
248
249
250
251
252
253
# File 'lib/autobuild/reporting.rb', line 244

def self.human_readable_size(size)
    HUMAN_READABLE_SIZES.each do |scale, name|
        scaled_size = (size / scale)
        if scaled_size > 1
            return format("%3.1<scaled>f%<scale_name>s",
                          scaled: scaled_size,
                          scale_name: name)
        end
    end
end

.ignore(path) ⇒ Object

Add a file and/or a regular expression to the ignore list

The matching paths will not be considered when looking if a source tree has been updated or not.



17
18
19
20
21
22
23
24
# File 'lib/autobuild/timestamps.rb', line 17

def self.ignore(path)
    ignored_files <<
        if path.kind_of?(Regexp)
            path
        else
            Regexp.new("^#{Regexp.quote(path)}")
        end
end

.import(spec, &proc) ⇒ Object



5
6
7
# File 'lib/autobuild/packages/import.rb', line 5

def self.import(spec, &proc)
    ImporterPackage.new(spec, &proc)
end

.installed_pkgconfig(name, &block) ⇒ Object



26
27
28
# File 'lib/autobuild/packages/pkgconfig.rb', line 26

def self.installed_pkgconfig(name, &block)
    InstalledPkgConfig.new(name, &block)
end

.invoke_make_parallel(pkg, cmd_path = Autobuild.tool(:make)) {|options| ... } ⇒ Object

Yields:

  • (options)


68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/autobuild/packages/gnumake.rb', line 68

def self.invoke_make_parallel(pkg, cmd_path = Autobuild.tool(:make))
    reserved = nil
    return yield unless make_has_j_option?(pkg, cmd_path)

    manager = Autobuild.parallel_task_manager
    return yield("-j#{pkg.parallel_build_level}") unless manager

    job_server = manager.job_server

    specific_parallel_level = (
        pkg.parallel_build_level != Autobuild.parallel_build_level
    )
    if !make_has_gnumake_jobserver?(pkg, cmd_path) || specific_parallel_level
        reserved = pkg.parallel_build_level
        # Account for the one token autobuild uses
        begin
            job_server.get(reserved - 1)
            return yield("-j#{pkg.parallel_build_level}")
        ensure
            job_server.put(reserved - 1)
        end
    end

    options = gnumake_jobserver_option(job_server, pkg, cmd_path)
    yield(*options)
end

.lfs_setup(importer, package) ⇒ Object



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
34
35
36
37
38
# File 'lib/autobuild/import/git-lfs.rb', line 6

def self.lfs_setup(importer, package)
    importer.run_git(package, 'lfs', 'install', '--force', '--local', '--skip-smudge')

    includes = importer.options.fetch(:lfs_include, '')
    if includes.empty?
        begin
            importer.run_git_bare(package, 'config', '--local',
                                  '--unset', 'lfs.fetchinclude')
        rescue SubcommandFailed => e
            raise if e.status != 5
        end
    else
        importer.run_git_bare(package, 'config', '--local',
                              'lfs.fetchinclude', includes)
    end

    excludes = importer.options.fetch(:lfs_exclude, '')
    if excludes.empty?
        begin
            importer.run_git_bare(package, 'config', '--local',
                                  '--unset', 'lfs.fetchexclude')
        rescue SubcommandFailed => e
            raise if e.status != 5
        end
    else
        importer.run_git_bare(package, 'config', '--local',
                              'lfs.fetchexclude', excludes)
    end

    if importer.options[:lfs] != false
        importer.run_git(package, 'lfs', 'pull', importer.remote_name)
    end
end

.logfilesObject



13
14
15
# File 'lib/autobuild/subcommand.rb', line 13

def self.logfiles
    @logfiles
end

.macos?Boolean

Returns:

  • (Boolean)


12
13
14
# File 'lib/autobuild/environment.rb', line 12

def self.macos?
    @macos
end

.make_has_gnumake_jobserver?(pkg, path = Autobuild.tool(:make)) ⇒ Boolean

Returns:

  • (Boolean)


51
52
53
# File 'lib/autobuild/packages/gnumake.rb', line 51

def self.make_has_gnumake_jobserver?(pkg, path = Autobuild.tool(:make))
    make_is_gnumake?(pkg, path)
end

.make_has_j_option?(pkg, path = Autobuild.tool(:make)) ⇒ Boolean

Returns:

  • (Boolean)


47
48
49
# File 'lib/autobuild/packages/gnumake.rb', line 47

def self.make_has_j_option?(pkg, path = Autobuild.tool(:make))
    make_is_gnumake?(pkg, path)
end

.make_is_gnumake?(pkg, path = Autobuild.tool(:make)) ⇒ Boolean

Returns:

  • (Boolean)


31
32
33
# File 'lib/autobuild/packages/gnumake.rb', line 31

def self.make_is_gnumake?(pkg, path = Autobuild.tool(:make))
    ensure_gnumake_detected(pkg, path)
end

.make_subcommand(pkg, phase, *options, &block) ⇒ Object



95
96
97
98
99
100
# File 'lib/autobuild/packages/gnumake.rb', line 95

def self.make_subcommand(pkg, phase, *options, &block)
    invoke_make_parallel(pkg, Autobuild.tool(:make)) do |*make_parallel_options|
        pkg.run(phase, Autobuild.tool(:make),
                *make_parallel_options, *options, &block)
    end
end

.message(*args, **options) ⇒ Object



67
68
69
# File 'lib/autobuild/reporting.rb', line 67

def self.message(*args, **options)
    @display.message(*args, **options)
end

.msys?Boolean

Returns:

  • (Boolean)


26
27
28
# File 'lib/autobuild/environment.rb', line 26

def self.msys?
    @msys
end

.orogen(opts, &proc) ⇒ Object



2
3
4
# File 'lib/autobuild/packages/orogen.rb', line 2

def self.orogen(opts, &proc)
    Orogen.new(opts, &proc)
end

.package_set(spec) ⇒ Object



884
885
886
887
888
889
890
# File 'lib/autobuild/package.rb', line 884

def self.package_set(spec)
    spec.each do |name, packages|
        Autobuild::TARGETS.each do |target|
            task "#{name}-#{target}" => packages.map { |dep| "#{dep}-#{target}" }
        end
    end
end

.pathvar(path, varname) ⇒ Object

Deprecated.

use Env#add_path on env instead



943
944
945
946
947
948
949
# File 'lib/autobuild/environment.rb', line 943

def self.pathvar(path, varname)
    if File.directory?(path)
        return if block_given? && !yield(path)

        env.add_path(varname, path)
    end
end

.post_install(*args, &block) ⇒ Object



106
107
108
109
110
111
112
113
114
# File 'lib/autobuild/config.rb', line 106

def self.post_install(*args, &block)
    if args.empty?
        @post_install_handlers << block
    elsif !block
        @post_install_handlers << args
    else
        raise ArgumentError, "cannot set both arguments and block"
    end
end

.post_success_message(*args, &block) ⇒ Object

call-seq:

post_success_message => string
post_success_message "msg" => "msg"
post_success_message { } => block

Gets or updates a message to be displayed on success. Can either be a string or a block, in which case the block must return the message string.



156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/autobuild/config.rb', line 156

def post_success_message(*args, &block)
    if args.empty? && !block
        if @post_success_message.respond_to?(:to_str)
            @post_success_message.to_str
        elsif @post_success_message
            @post_success_message.call
        end
    elsif block
        @post_success_message = block
    else
        @post_success_message = args.first.to_str
    end
end

.progress(key, *args) ⇒ Object



85
86
87
# File 'lib/autobuild/reporting.rb', line 85

def self.progress(key, *args)
    @display.progress(key, *args)
end

.progress_display_enabled=(value) ⇒ Object

Deprecated.


55
56
57
# File 'lib/autobuild/reporting.rb', line 55

def self.progress_display_enabled=(value)
    @display.progress_enabled = value
end

.progress_display_enabled?Boolean

Returns:

  • (Boolean)


46
47
48
# File 'lib/autobuild/reporting.rb', line 46

def self.progress_display_enabled?
    @display.progress_enabled?
end

.progress_display_mode=(value) ⇒ Object



59
60
61
# File 'lib/autobuild/reporting.rb', line 59

def self.progress_display_mode=(value)
    @display.progress_mode = value
end

.progress_display_period=(value) ⇒ Object



63
64
65
# File 'lib/autobuild/reporting.rb', line 63

def self.progress_display_period=(value)
    @display.progress_period = value
end

.progress_display_synchronize(&block) ⇒ Object



50
51
52
# File 'lib/autobuild/reporting.rb', line 50

def self.progress_display_synchronize(&block)
    @display.synchronize(&block)
end

.progress_done(key, display_last = true, message: nil) ⇒ Object



89
90
91
# File 'lib/autobuild/reporting.rb', line 89

def self.progress_done(key, display_last = true, message: nil)
    @display.progress_done(key, display_last, message: message)
end

.progress_start(key, *args, **options, &block) ⇒ Object



81
82
83
# File 'lib/autobuild/reporting.rb', line 81

def self.progress_start(key, *args, **options, &block)
    @display.progress_start(key, *args, **options, &block)
end

.python(opts, &proc) ⇒ Object



6
7
8
# File 'lib/autobuild/packages/python.rb', line 6

def self.python(opts, &proc)
    Python.new(opts, &proc)
end

.register_logfile(path) ⇒ Object



17
18
19
# File 'lib/autobuild/subcommand.rb', line 17

def self.register_logfile(path)
    @logfiles << path
end

.register_utility_class(name, klass, disabled_by_default: false, **options) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/autobuild/config.rb', line 54

def register_utility_class(name, klass, disabled_by_default: false, **options)
    creation_options = { disabled_by_default: disabled_by_default }
    utilities[name] = [klass, creation_options, options]
    singleton_class.class_eval do
        attr_accessor "only_#{name}"
        attr_accessor "do_#{name}"
        attr_accessor "#{name}_prefix"
        attr_accessor "pass_#{name}_errors"
    end
    instance_variable_set "@only_#{name}", false
    instance_variable_set "@do_#{name}", false
    instance_variable_set "@pass_#{name}_errors", false
    instance_variable_set "@#{name}_prefix", name
end

.registered_logfile?(logfile) ⇒ Boolean

Returns:

  • (Boolean)


21
22
23
# File 'lib/autobuild/subcommand.rb', line 21

def self.registered_logfile?(logfile)
    @logfiles.include?(logfile)
end

.reset_gnumake_detectionObject



4
5
6
7
# File 'lib/autobuild/packages/gnumake.rb', line 4

def self.reset_gnumake_detection
    @make_is_gnumake = Hash.new
    @gnumake_version = Hash.new
end

.reset_statisticsObject



29
30
31
# File 'lib/autobuild/subcommand.rb', line 29

def self.reset_statistics
    @statistics = Hash.new
end

.ruby(spec, &proc) ⇒ Object



114
115
116
# File 'lib/autobuild/packages/ruby.rb', line 114

def self.ruby(spec, &proc)
    Ruby.new(spec, &proc)
end

.silent(&block) ⇒ Object



42
43
44
# File 'lib/autobuild/reporting.rb', line 42

def self.silent(&block)
    @display.silent(&block)
end

.silent=(flag) ⇒ Object



36
37
38
# File 'lib/autobuild/reporting.rb', line 36

def silent=(flag)
    @display.silent = flag
end

.silent?Boolean

Returns:

  • (Boolean)


32
33
34
# File 'lib/autobuild/reporting.rb', line 32

def silent?
    @display.silent?
end

.source_tree(path, &block) ⇒ Object



78
79
80
81
82
# File 'lib/autobuild/timestamps.rb', line 78

def self.source_tree(path, &block)
    task = SourceTreeTask.define_task(path)
    block&.call(task)
    task
end

.statisticsObject



25
26
27
# File 'lib/autobuild/subcommand.rb', line 25

def self.statistics
    @statistics
end

.svn(source, options = {}) ⇒ Object

Creates a subversion importer which import the source for the Subversion URL source. The allowed values in options are described in SVN.new.



258
259
260
# File 'lib/autobuild/import/svn.rb', line 258

def self.svn(source, options = {})
    SVN.new(source, options)
end

.tar(source, options = {}) ⇒ Object

DEPRECATED. Use Autobuild.archive instead.



583
584
585
# File 'lib/autobuild/import/archive.rb', line 583

def self.tar(source, options = {})
    ArchiveImporter.new(source, options)
end

.tool(name) ⇒ Object

Get a given program, using its name as default value. For instance

tool('automake')

will return ‘automake’ unless the autobuild script defined another automake program in Autobuild.programs by doing

Autobuild.programs['automake'] = 'automake1.9'


20
21
22
# File 'lib/autobuild/tools.rb', line 20

def tool(name)
    programs[name.to_sym] || programs[name.to_s] || name.to_s
end

.tool_in_path(name, env: self.env) ⇒ Object

Resolves the absolute path to a given tool



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/autobuild/tools.rb', line 30

def tool_in_path(name, env: self.env)
    path, path_name, path_env = programs_in_path[name]
    current = tool(name)
    env_path = env.resolved_env['PATH']
    if (path_env != env_path) || (path_name != current)
        # Delete the current entry given that it is invalid
        programs_in_path.delete(name)
        path =
            if current[0, 1] == "/"
                # This is already a full path
                current
            else
                env.find_executable_in_path(current)
            end

        unless path
            raise ArgumentError, "tool #{name}, set to #{current}, "\
                "can not be found in PATH=#{env_path}"
        end

        programs_in_path[name] = [path, current, env_path]
    end

    path
end

.touch_stamp(stampfile) ⇒ Object



103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/autobuild/timestamps.rb', line 103

def self.touch_stamp(stampfile)
    Autobuild.message "Touching #{stampfile}" if Autobuild.debug
    dir = File.dirname(stampfile)
    if File.exist?(dir) && !File.directory?(dir)
        raise "#{dir} exists and is not a directory"
    elsif !File.exist?(dir)
        FileUtils.mkdir_p dir
    end

    FileUtils.touch(stampfile)

    unless hires_modification_time?
        # File modification times on most Unix filesystems have a granularity of
        # one second, so we (unfortunately) have to sleep 1s to make sure that
        # time comparisons will work as expected.
        sleep(1)
    end
end

.tree_timestamp(path, *exclude) ⇒ Object



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/autobuild/timestamps.rb', line 26

def self.tree_timestamp(path, *exclude)
    # Exclude autobuild timestamps
    exclude << /#{Regexp.quote(STAMPFILE)}$/
    exclude << /\.autobuild-patches$/

    Autobuild.message "getting tree timestamp for #{path}" if Autobuild.debug
    latest = Time.at(0)
    latest_file = ""

    Find.find(path) do |p|
        Find.prune if File.basename(p) =~ /^\./
        exclude.each do |pattern|
            if pattern === p
                if Autobuild.debug
                    Autobuild.message "  excluding #{p} because of #{pattern}"
                end
                Find.prune
            end
        end
        next unless File.file?(p)

        p_time = File.mtime(p)
        if latest < p_time
            latest = p_time
            latest_file = p
        end
    end

    Autobuild.message "  newest file: #{latest_file} at #{latest}" if Autobuild.debug
    [latest_file, latest]
end

.update_environment(newprefix, includes = nil) ⇒ Object

@deprecated, use the API on env instead



938
939
940
# File 'lib/autobuild/environment.rb', line 938

def self.update_environment(newprefix, includes = nil)
    env.update_environment(newprefix, includes)
end

.validate_displayed_error_line_count(lines) ⇒ Object



141
142
143
144
145
146
147
148
149
150
# File 'lib/autobuild/subcommand.rb', line 141

def self.validate_displayed_error_line_count(lines)
    if lines == 'ALL'
        Float::INFINITY
    elsif lines.to_i > 0
        lines.to_i
    else
        raise ConfigException.new, 'Autobuild.displayed_error_line_count can only "\
            "be a positive integer or \'ALL\''
    end
end

.warn(message = "", *style) ⇒ Object

Displays a warning message



77
78
79
# File 'lib/autobuild/reporting.rb', line 77

def self.warn(message = "", *style)
    message("  WARN: #{message}", :magenta, *style, io: STDERR)
end

.windows?Boolean

Returns:

  • (Boolean)


7
8
9
# File 'lib/autobuild/environment.rb', line 7

def self.windows?
    @windows
end