Class: Autobuild::Orogen

Inherits:
CMake show all
Defined in:
lib/autobuild/packages/orogen.rb

Overview

This class represents packages generated by orogen. oroGen is a specification and code generation tool for the Orocos/RTT integration framework. See rock-robotics.org for more information.

This class extends the CMake package class to handle the code generation step. Moreover, it will load the orogen specification and automatically add the relevant pkg-config dependencies as dependencies.

This requires that the relevant packages define the pkg-config definitions they install in the pkgconfig/ namespace. It means that a “driver/camera” package (for instance) that installs a “camera.pc” file will have to provide the “pkgconfig/camera” virtual package. This is done automatically by the CMake package handler if the source contains a camera.pc.in file, but can also be done manually with a call to Package#provides:

pkg.provides "pkgconfig/camera"

Constant Summary

Constants inherited from CMake

CMake::CMAKE_EQVS, CMake::DOXYGEN_ACCEPTED_VARIABLES

Class Attribute Summary collapse

Instance Attribute Summary collapse

Attributes inherited from CMake

#always_reconfigure, #always_use_doc_target, #defines, #delete_obsolete_files_in_prefix, #full_reconfigures, #generator, #show_make_messages

Attributes inherited from Configurable

#source_tree_excludes

Attributes inherited from Package

#dependencies, #env, #failures, #importdir, #importer, #logdir, #name, #prefix, #srcdir, #statistics, #update, #updated, #utilities

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from CMake

#all_defines, #always_use_doc_target?, always_use_doc_target?, #build, builddir, builddir=, #cmake_cache, #common_utility_handling, #configure, #configurestamp, #coverage_block, define, #define, defines, #defines_changed?, #delete_obsolete_files, delete_obsolete_files_in_prefix=, #delete_obsolete_files_in_prefix?, delete_obsolete_files_in_prefix?, #equivalent_option_value?, #full_reconfigures?, full_reconfigures?, #import, #install, #internal_doxygen_mode?, #module_path, #prefix_path, #run_doxygen, #self_fingerprint, show_make_messages=, show_make_messages?, #show_make_messages?, #with_coverage, #with_doc, #with_tests

Methods inherited from Configurable

#build, builddir, #builddir, builddir=, #builddir=, #buildstamp, #configure, #ensure_dependencies_installed, #prepare_for_rebuild

Methods inherited from Package

[], #add_env_op, #add_stat, #all_dependencies, #applied_post_install?, #apply_env, #apply_post_install, #checked_out?, clear, #depends_on, #depends_on?, #disable, #disable_doc, #disable_phases, #disabled?, #doc_dir, #doc_dir=, #doc_disabled, #doc_target_dir, #doc_target_dir=, #doc_task, each, #enable_doc, #env_add, #env_add_path, #env_add_prefix, #env_set, #env_source_after, #error, #failed?, #file, #find_in_path, #fingerprint, #full_env, #generates_doc?, #has_doc?, #import, #import=, #import_invoked?, #imported?, #in_dir, #inspect, #install, #install_doc, #install_invoked?, #installed?, #installstamp, #isolate_errors, #message, #method_missing, #parallel_build_level, #parallel_build_level=, #post_install, #prepare_for_rebuild, #process_formatting_string, #progress, #progress_done, #progress_start, #provides, #resolve_dependency_env, #resolved_env, #respond_to_missing?, #run, #self_fingerprint, #source_tree, #task, #to_s, #update?, #updated?, #utility, #warn, #working_directory

Constructor Details

#initialize(*args, &config) ⇒ Orogen

Returns a new instance of Orogen.



135
136
137
138
139
140
141
142
# File 'lib/autobuild/packages/orogen.rb', line 135

def initialize(*args, &config)
    super

    @orogen_tool_path = nil
    @orogen_version = nil
    @orocos_target = nil
    @orogen_options = []
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Autobuild::Package

Class Attribute Details

.always_regenerate=(value) ⇒ Object (writeonly)

See #always_regenerate?



34
35
36
# File 'lib/autobuild/packages/orogen.rb', line 34

def always_regenerate=(value)
  @always_regenerate = value
end

.corbaObject

Returns the value of attribute corba.



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

def corba
  @corba
end

.default_type_export_policyObject

Returns the value of attribute default_type_export_policy.



65
66
67
# File 'lib/autobuild/packages/orogen.rb', line 65

def default_type_export_policy
  @default_type_export_policy
end

.extended_statesObject

If set to true, all components are generated with the –extended-states option

The default is false



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

def extended_states
  @extended_states
end

.orogen_optionsObject (readonly)

Returns the value of attribute orogen_options.



70
71
72
# File 'lib/autobuild/packages/orogen.rb', line 70

def orogen_options
  @orogen_options
end

.transportsObject (readonly)

The list of enabled transports as an array of strings (default: typelib, corba)



68
69
70
# File 'lib/autobuild/packages/orogen.rb', line 68

def transports
  @transports
end

Instance Attribute Details

#corbaObject



102
103
104
# File 'lib/autobuild/packages/orogen.rb', line 102

def corba
    @corba || (@corba.nil? && Orogen.corba)
end

#extended_statesObject



109
110
111
# File 'lib/autobuild/packages/orogen.rb', line 109

def extended_states
    @extended_states || (@extended_states.nil? && Orogen.extended_states)
end

#orocos_targetObject

The orocos target that should be used for this particular orogen package

By default, it is the same than Orogen.orocos_target. It can be set by doing

package.orocos_target = 'target_name'


92
93
94
95
96
97
98
# File 'lib/autobuild/packages/orogen.rb', line 92

def orocos_target
    if @orocos_target.nil?
        Orogen.orocos_target
    else
        @orocos_target
    end
end

#orogen_fileObject

Path to the orogen file used for this package

If not set, the class will look for a .orogen file in the package source directory. It will return nil if the package is not checked out yet, and raise ArgumentError if the package is indeed present but no orogen file can be found

It can be explicitely set with #orogen_file=



121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/autobuild/packages/orogen.rb', line 121

def orogen_file
    if @orogen_file
        @orogen_file
    else
        return unless File.directory?(srcdir)

        Dir.glob(File.join(srcdir, '*.orogen')) do |path|
            return File.basename(path)
        end
        raise ArgumentError,
              "cannot find an oroGen specification file in #{srcdir}"
    end
end

#orogen_optionsObject (readonly)

Returns the value of attribute orogen_options.



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

def orogen_options
  @orogen_options
end

#orogen_tool_pathObject (readonly)

The path to the orogen tool as resolved from Package#full_env



80
81
82
# File 'lib/autobuild/packages/orogen.rb', line 80

def orogen_tool_path
  @orogen_tool_path
end

Class Method Details

.always_regenerate?Boolean

If true (the default), the oroGen component will be regenerated every time a dependency is newer than the package itself.

Otherwise, autobuild tries to regenerate it only when needed

This is still considered experimental. Use Orogen.always_regenerate= to set it

Returns:

  • (Boolean)


43
44
45
# File 'lib/autobuild/packages/orogen.rb', line 43

def always_regenerate?
    @always_regenerate
end

.orocos_targetObject

The target that should be used to generate and build orogen components



53
54
55
56
57
58
59
60
61
62
# File 'lib/autobuild/packages/orogen.rb', line 53

def self.orocos_target
    user_target = ENV['OROCOS_TARGET']
    if @orocos_target
        @orocos_target.dup
    elsif user_target && !user_target.empty?
        user_target
    else
        'gnulinux'
    end
end

Instance Method Details

#add_cmd_to_cmdline(cmd, cmdline) ⇒ Object



192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/autobuild/packages/orogen.rb', line 192

def add_cmd_to_cmdline(cmd, cmdline)
    if cmd =~ /^([\w-]+)$/
        cmd_filter = $1
    else
        cmdline << cmd
        return
    end

    cmdline.delete_if { |str| str =~ /^#{cmd_filter}/ }
    if cmd_filter =~ /^--no-(.*)/
        cmd_filter = $1
        cmdline.delete_if { |str| str =~ /^--#{cmd_filter}/ }
    end
    cmdline << cmd
end

#generation_uptodate?Boolean

Returns:

  • (Boolean)


294
295
296
297
298
299
300
301
302
303
# File 'lib/autobuild/packages/orogen.rb', line 294

def generation_uptodate?
    if !File.file?(genstamp)
        true
    elsif File.file?(File.join(builddir, 'Makefile'))
        make = Autobuild.tool('make')
        system("#{make} -C #{builddir} check-uptodate > /dev/null 2>&1")
    else
        true
    end
end

#genstampObject



188
189
190
# File 'lib/autobuild/packages/orogen.rb', line 188

def genstamp
    File.join(srcdir, '.orogen', 'orogen-stamp')
end

#orogen_rootObject



168
169
170
171
172
173
# File 'lib/autobuild/packages/orogen.rb', line 168

def orogen_root
    if orogen_tool_path
        root = File.expand_path(File.join('..', '..'), orogen_tool_path)
        root if File.directory?(File.join(root, 'lib', 'orogen'))
    end
end

#orogen_versionObject

The version of orogen, given as a string

It is used to enable/disable some configuration features based on the orogen version string



159
160
161
162
163
164
165
166
# File 'lib/autobuild/packages/orogen.rb', line 159

def orogen_version
    if !@orogen_version && (root = orogen_root)
        version_file = File.join(root, 'lib', 'orogen', 'version.rb')
        version_line = File.readlines(version_file).grep(/VERSION\s*=\s*"/).first
        @orogen_version = $1 if version_line =~ /.*=\s+"(.+)"$/
    end
    @orogen_version
end

#prepareObject



175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/autobuild/packages/orogen.rb', line 175

def prepare
    file configurestamp => genstamp
    stamps = dependencies.map { |pkg| Autobuild::Package[pkg].installstamp }

    file genstamp => [*stamps, source_tree(srcdir)] do
        isolate_errors { regen }
    end

    with_doc

    super
end

#prepare_for_forced_buildObject



144
145
146
147
# File 'lib/autobuild/packages/orogen.rb', line 144

def prepare_for_forced_build
    super
    FileUtils.rm_f genstamp
end

#regenObject



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
292
# File 'lib/autobuild/packages/orogen.rb', line 208

def regen
    cmdline = []
    cmdline << '--corba' if corba

    ext_states = extended_states
    unless ext_states.nil?
        cmdline.delete_if { |str| str =~ /extended-states/ }
        cmdline <<
            if ext_states
                '--extended-states'
            else
                '--no-extended-states'
            end
    end

    unless (@orogen_tool_path = find_in_path('orogen'))
        raise ArgumentError, "cannot find 'orogen' in #{resolved_env['PATH']}"
    end

    unless (version = orogen_version)
        raise ArgumentError, "cannot determine the orogen version"
    end

    if version >= "1.0" # rubocop:disable Style/IfUnlessModifier
        cmdline << "--parallel-build=#{parallel_build_level}"
    end
    if version >= "1.1"
        cmdline << "--type-export-policy=#{Orogen.default_type_export_policy}"
        cmdline << "--transports=#{Orogen.transports.sort.uniq.join(',')}"
    end
    if version >= "1.2"
        cmdline << "--parallel-codegen=#{parallel_build_level}"
        if (job_server = Autobuild.parallel_task_manager&.job_server)
            fds = "#{job_server.rio.fileno},#{job_server.wio.fileno}"
            cmdline << "--jobserver-auth=#{fds}"
        end
    end

    # Now, add raw options
    #
    # The raw options take precedence
    Orogen.orogen_options.each do |cmd|
        add_cmd_to_cmdline(cmd, cmdline)
    end
    orogen_options.each do |cmd|
        add_cmd_to_cmdline(cmd, cmdline)
    end

    cmdline = cmdline.sort
    cmdline << orogen_file

    needs_regen = Autobuild::Orogen.always_regenerate?

    # Try to avoid unnecessary regeneration as generation can be pretty
    # long
    #
    # First, check if the command line changed
    needs_regen ||=
        if File.exist?(genstamp)
            last_cmdline = File.read(genstamp).split("\n")
            last_cmdline != cmdline
        else
            true
        end

    # Then, if it has already been built, check what the check-uptodate
    # target says
    needs_regen ||= !generation_uptodate?

    if needs_regen
        progress_start "generating oroGen %s",
                       done_message: 'generated oroGen %s' do
            in_dir(srcdir) do
                run 'orogen', Autobuild.tool('ruby'), '-S',
                    orogen_tool_path, *cmdline
                File.open(genstamp, 'w') do |io|
                    io.print cmdline.join("\n")
                end
            end
        end
    else
        message "no need to regenerate the oroGen project %s"
        Autobuild.touch_stamp genstamp
    end
end

#update_environmentObject



149
150
151
152
153
# File 'lib/autobuild/packages/orogen.rb', line 149

def update_environment
    super
    typelib_plugin = File.join(prefix, 'share', 'typelib', 'ruby')
    env_add_path 'TYPELIB_RUBY_PLUGIN_PATH', typelib_plugin
end