Class: OroGen::Loaders::PkgConfig

Inherits:
Base
  • Object
show all
Includes:
Logger::Hierarchy
Defined in:
lib/orogen/loaders/pkg_config.rb

Overview

A loader that accesses the information from the pkg-config files installed by oroGen.

It allows to query oroGen-related information from the installed oroGen projects, as well as load the corresponding models. It assumes that the set of installed orogen projects is self-consistent.

It accesses the local file system

Direct Known Subclasses

RTT

Defined Under Namespace

Classes: AvailableDeployedTask, DeploymentInfo, Project, TaskLibrary, Type

Instance Attribute Summary collapse

Attributes inherited from Base

#interface_typelist, #loaded_deployment_models, #loaded_projects, #loaded_task_models, #loaded_typekits, #project_load_callbacks, #registry, #root_loader, #typekit_load_callbacks, #typekits_by_type_name

Instance Method Summary collapse

Methods inherited from Base

#added_child, #define_dummy_types=, #define_dummy_types?, #deployed_task_model_from_name, #deployment_model_from_name, #has_loaded_project?, #has_loaded_typekit?, #imported_typekits_for, #inspect, #interface_type?, #intermediate_type?, #intermediate_type_for, #m_type?, #on_project_load, #on_typekit_load, #opaque_type_for, #project_model_from_name, #project_model_from_text, #register_deployment_model, #register_project_model, #register_task_context_model, #register_type_model, #register_typekit_model, #remove_project_load_callback, #resolve_interface_type, #resolve_type, #task_library_model_from_name, #task_model_from_name, #typekit_model_from_name, #typelib_type_for

Constructor Details

#initialize(orocos_target, root_loader = self) ⇒ PkgConfig

Returns a new instance of PkgConfig

Parameters:

  • orocos_target (String)

    the orocos target we are loading for

  • root_loader (defaults to: self)

    the root loader. Other loaders might pass it instead of themselves to the Spec::Project objects so that they use the root loader to get their dependencies. The pkg-config loader assumes that we have a self-consistent set of packages on disk (since it is installed packages), and therefore does not use it.



64
65
66
67
# File 'lib/orogen/loaders/pkg_config.rb', line 64

def initialize(orocos_target, root_loader = self)
    @orocos_target = orocos_target
    super(root_loader)
end

Instance Attribute Details

#available_deployed_tasksHash<String,Set<String>> (readonly)

Returns the set of known deployments on a per-task-model basis

Returns:

  • (Hash<String,Set<String>>)

    the set of known deployments on a per-task-model basis



52
53
54
# File 'lib/orogen/loaders/pkg_config.rb', line 52

def available_deployed_tasks
  @available_deployed_tasks
end

#available_deploymentsHash<String,DeploymentInfo> (readonly)

Returns the set of known deployments

Returns:



49
50
51
# File 'lib/orogen/loaders/pkg_config.rb', line 49

def available_deployments
  @available_deployments
end

#available_projectsHash<String,Boolean> (readonly)

Returns a cache of project presence flags

Returns:

  • (Hash<String,Boolean>)

    a cache of project presence flags



40
41
42
# File 'lib/orogen/loaders/pkg_config.rb', line 40

def available_projects
  @available_projects
end

#available_task_modelsHash<String,String> (readonly)

Returns the set of known task models, as a mapping from the task model to the name of the task library that defines it

Returns:

  • (Hash<String,String>)

    the set of known task models, as a mapping from the task model to the name of the task library that defines it



46
47
48
# File 'lib/orogen/loaders/pkg_config.rb', line 46

def available_task_models
  @available_task_models
end

#available_typekitsSet (readonly)

Returns the set of known typekits

Returns:

  • (Set)

    the set of known typekits



42
43
44
# File 'lib/orogen/loaders/pkg_config.rb', line 42

def available_typekits
  @available_typekits
end

#available_typesHash<String,Type> (readonly)

Returns the set of known deployments on a per-task-model basis

Returns:

  • (Hash<String,Type>)

    the set of known deployments on a per-task-model basis



55
56
57
# File 'lib/orogen/loaders/pkg_config.rb', line 55

def available_types
  @available_types
end

#orocos_targetString (readonly)

Returns the name of the orocos target we are looking for

Returns:

  • (String)

    the name of the orocos target we are looking for



38
39
40
# File 'lib/orogen/loaders/pkg_config.rb', line 38

def orocos_target
  @orocos_target
end

Instance Method Details

#add_project_from(pkg) ⇒ Project

Registers a project from its pkg-config object

Parameters:

  • the (Utilrb::PkgConfig)

    pkg-config from the project (orogen-project-NAME)

Returns:

  • (Project)

    the registered project



84
85
# File 'lib/orogen/loaders/pkg_config.rb', line 84

def add_project_from(pkg)
end

#clearObject



69
70
71
72
73
74
75
76
77
# File 'lib/orogen/loaders/pkg_config.rb', line 69

def clear
    super
    @available_projects = Hash.new
    @available_typekits = Hash.new
    @available_task_models = Hash.new
    @available_deployments = Hash.new
    @available_deployed_tasks = Hash.new
    @available_types = nil
end

#each_available_deployed_task {|| ... } ⇒ Object

Enumerate information about the available deployments on this system

Yield Parameters:



435
436
437
438
439
440
441
442
443
444
445
446
447
# File 'lib/orogen/loaders/pkg_config.rb', line 435

def each_available_deployed_task(&block)
    return enum_for(__method__) if !block_given?

    if available_deployed_tasks.empty?
        load_available_deployed_tasks
    end

    available_deployed_tasks.each do |deployed_task_name, deployments|
        deployments.each do |task|
            yield(task)
        end
    end
end

#each_available_deployed_task_name(&block) ⇒ Object

Deprecated.


419
420
421
422
423
424
425
# File 'lib/orogen/loaders/pkg_config.rb', line 419

def each_available_deployed_task_name(&block)
    return enum_for(__method__) if !block_given?

    each_available_deployed_task do |task|
        yield(task.task_name, task.deployment_name)
    end
end

#each_available_deployment_name(&block) ⇒ Object



410
411
412
413
414
415
416
# File 'lib/orogen/loaders/pkg_config.rb', line 410

def each_available_deployment_name(&block)
    return enum_for(__method__) if !block_given?
    rx = /^orogen-\w+$/
    Utilrb::PkgConfig.each_package(rx) do |pkg_name|
        yield(pkg_name.gsub(/^orogen-/, ''))
    end
end

#each_available_project_nameObject



380
381
382
383
384
385
386
# File 'lib/orogen/loaders/pkg_config.rb', line 380

def each_available_project_name
    return enum_for(__method__) if !block_given?
    rx = /^orogen-project-/
    Utilrb::PkgConfig.each_package(rx) do |pkg_name|
        yield(pkg_name.gsub(rx, ''))
    end
end

#each_available_task_model_name(&block) ⇒ Object



396
397
398
399
400
401
402
403
404
405
406
407
408
# File 'lib/orogen/loaders/pkg_config.rb', line 396

def each_available_task_model_name(&block)
    return enum_for(__method__) if !block_given?
    each_available_project_name do |project_name|
        begin
            pkg = Utilrb::PkgConfig.new("#{project_name}-tasks-#{orocos_target}")
        rescue Utilrb::PkgConfig::NotFound
            next
        end
        pkg.task_models.split(',').each do |model_name|
            yield(model_name, project_name)
        end
    end
end

#each_available_type_name {|type_name, typekit_name, exported| ... } ⇒ Object

Enumerate the types available on this system

Yield Parameters:

  • type_name (String)

    the name of the type

  • typekit_name (String)

    the name of one typekit that defines it

  • exported (Boolean)

    whether this type is exported or not



467
468
469
470
471
472
473
474
475
476
# File 'lib/orogen/loaders/pkg_config.rb', line 467

def each_available_type_name(&block)
    return enum_for(__method__) if !block_given?

    if !available_types
        load_available_types
    end
    available_types.each do |type_name, type_info|
        yield(type_name, type_info.name, type_info.exported)
    end
end

#each_available_typekit_name(&block) ⇒ Object



388
389
390
391
392
393
394
# File 'lib/orogen/loaders/pkg_config.rb', line 388

def each_available_typekit_name(&block)
    return enum_for(__method__) if !block_given?
    rx = /-typekit-#{orocos_target}$/
    Utilrb::PkgConfig.each_package(rx) do |pkg_name|
        yield(pkg_name.gsub(rx, ''))
    end
end

#find_basic_deployed_task_info(task_name) ⇒ AvailableDeployedTask?

Returns basic information about a deployed task

Parameters:

  • task_name (String)

Returns:



453
454
455
456
457
458
# File 'lib/orogen/loaders/pkg_config.rb', line 453

def find_basic_deployed_task_info(task_name)
    if available_deployed_tasks.empty?
        load_available_deployed_tasks
    end
    available_deployed_tasks[task_name]
end

#find_deployment_binfile(deployment_name) ⇒ Object



265
266
267
268
269
# File 'lib/orogen/loaders/pkg_config.rb', line 265

def find_deployment_binfile(deployment_name)
    if find_project_from_deployment_name(deployment_name)
        available_deployments[deployment_name].binfile
    end
end

#find_deployments_from_deployed_task_name(name) ⇒ Object



302
303
304
305
306
307
308
309
310
311
# File 'lib/orogen/loaders/pkg_config.rb', line 302

def find_deployments_from_deployed_task_name(name)
    if available_deployed_tasks.empty?
        load_available_deployed_tasks
    end

    if available_deployed_tasks.has_key?(name)
        return available_deployed_tasks[name].map(&:deployment_name)
    else return Set.new
    end
end

#find_pkgconfig(name, minimal: true) ⇒ Object



87
88
89
90
# File 'lib/orogen/loaders/pkg_config.rb', line 87

def find_pkgconfig(name, minimal: true)
    Utilrb::PkgConfig.get(name, minimal: minimal)
rescue Utilrb::PkgConfig::NotFound
end

#find_project_from_deployment_name(deployment_name) ⇒ Object



247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
# File 'lib/orogen/loaders/pkg_config.rb', line 247

def find_project_from_deployment_name(deployment_name)
    if available_deployments.has_key?(deployment_name)
        return available_deployments[deployment_name].project_name
    end
    
    if deployment_pkg = find_pkgconfig("orogen-#{deployment_name}")
        if has_project?(deployment_pkg.project_name)
            info = DeploymentInfo.new(deployment_pkg.project_name, deployment_pkg.binfile)
            available_deployments[deployment_name] = info
            info.project_name
        else
            available_deployments[deployment_name] = nil
        end
    else
        available_deployments[deployment_name] = nil
    end
end

#find_task_library_from_task_model_name(model_name) ⇒ Object



153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/orogen/loaders/pkg_config.rb', line 153

def find_task_library_from_task_model_name(model_name)
    if available_task_models.has_key?(model_name)
        return available_task_models[model_name]
    end

    project_name = model_name.split('::').first
    project_pkg = find_pkgconfig("#{project_name}-tasks-#{orocos_target}")

    if project_pkg
        project_pkg.task_models.split(',').each do |project_task_name|
            available_task_models[project_task_name] = project_name
        end
    end

    if available_task_models.has_key?(model_name)
        available_task_models[model_name]
    else
        available_task_models[model_name] = nil
    end
end

#has_pkgconfig?(name) ⇒ Boolean

Returns:

  • (Boolean)


92
93
94
# File 'lib/orogen/loaders/pkg_config.rb', line 92

def has_pkgconfig?(name)
    !!find_pkgconfig(name, minimal: true)
end

#has_project?(name) ⇒ Boolean

Returns:

  • (Boolean)


96
97
98
99
100
101
102
103
104
# File 'lib/orogen/loaders/pkg_config.rb', line 96

def has_project?(name)
    if super
        true
    elsif available_projects.has_key?(name)
        available_projects[name]
    else
        available_projects[name] = has_pkgconfig?("orogen-project-#{name}")
    end
end

#has_typekit?(name) ⇒ Boolean

Returns:

  • (Boolean)


106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/orogen/loaders/pkg_config.rb', line 106

def has_typekit?(name)
    if super
        true
    elsif available_typekits.has_key?(name)
        available_typekits[name]
    elsif !has_pkgconfig?("#{name}-typekit-#{orocos_target}")
        available_typekits[name] = false
    elsif !(project_pkg = find_pkgconfig("orogen-project-#{name}"))
        available_typekits[name] = false
    else
        available_typekits[name] = !!project_pkg.type_registry
    end
end

#load_available_deployed_tasksObject



271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
# File 'lib/orogen/loaders/pkg_config.rb', line 271

def load_available_deployed_tasks
    @available_deployed_tasks = Hash.new

    Utilrb::PkgConfig.each_package(/^orogen-\w+$/) do |pkg_name|
        pkg = Utilrb::PkgConfig.get(pkg_name, minimal: true)
        project_name = pkg.project_name
        deployment_name = pkg_name.gsub(/^orogen-/, '')

        if !pkg.deployed_tasks_with_models
            # oroGen has a bug, in which it installed the pkg-config
            # file for deployments that were not meant to be
            # installed.
            #
            # Workaround
            next
        elsif !has_project?(project_name)
            next
        end

        pkg.deployed_tasks_with_models.split(',').each_slice(2) do |task_name, task_model_name|
            available_deployed_tasks[task_name] ||= Set.new
            available_deployed_tasks[task_name] <<
                AvailableDeployedTask.new(
                    task_name, deployment_name,
                    task_model_name, project_name)
            available_deployments[deployment_name] =
                DeploymentInfo.new(project_name, pkg.binfile)
        end
    end
end

#load_available_typesObject



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
# File 'lib/orogen/loaders/pkg_config.rb', line 313

def load_available_types
    @available_types = Hash.new

    Utilrb::PkgConfig.each_package(/-typekit-#{orocos_target}$/) do |pkg_name|
        pkg = Utilrb::PkgConfig.get(pkg_name, minimal: true)
        next if !pkg.type_registry

        typelist = pkg.type_registry.gsub(/tlb$/, 'typelist')
        typelist, typelist_exported =
            OroGen::Spec::Typekit.parse_typelist(File.read(typelist))
        typelist = typelist - typelist_exported
        typelist.compact.each do |typename|
            if existing = available_types[typename]
                OroGen.info "#{typename} is defined by both #{existing[0]} and #{pkg.project_name}, registering #{existing[0]} as the responsible typekit"
            else
                available_types[typename] = Type.new(pkg.project_name, false)
            end
        end
        typelist_exported.compact.each do |typename|
            if existing = available_types[typename]
                OroGen.info "#{typename} is defined by both #{existing[0]} and #{pkg.project_name}, registering #{pkg.project_name} as it exports the type but #{existing[0]} does not"
            end
            available_types[typename] = Type.new(pkg.project_name, true)
        end
    end
end

#project_model_text_from_name(name) ⇒ Object



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/orogen/loaders/pkg_config.rb', line 120

def project_model_text_from_name(name)
    begin
        pkg = Utilrb::PkgConfig.get("orogen-project-#{name}", minimal: true)
        available_projects[name] = true
    rescue Utilrb::PkgConfig::NotFound
        available_projects[name] = false
        raise ProjectNotFound, "cannot find a project called #{name}"
    end

    project = pkg.project_name
    if project.empty?
        warn "#{pkg.name}.pc does not have a project_name field"
    elsif pkg.deffile.empty?
        warn "#{pkg.name}.pc does not have a deffile field"
    end
    return File.read(pkg.deffile), pkg.deffile
end

#resolve_package_library(package, library_name) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Resolve the full path to a library from a pkg-config package

Parameters:

  • package (Utilrb::PkgConfig)

    the package whose library dirs will be used for resolution

  • library_name (String)

    the library name, without a possible “lib” prefix and the platform-specific suffix

Returns:

  • (String)

    the resolved path

Raises:

  • LibraryNotFound if the library cannot be found



217
218
219
220
221
222
223
224
225
# File 'lib/orogen/loaders/pkg_config.rb', line 217

def resolve_package_library(package, library_name)
    libname = "lib#{library_name}.#{Loaders.shared_library_suffix}"
    package.library_dirs.each do |dir|
        if File.exist?(path = File.join(dir, libname))
            return path
        end
    end
    raise LibraryNotFound, "cannot find #{library_name} from #{package.name}"
end

#resolve_task_library_package(name, minimal: false) ⇒ Utilrb::PkgConfig

Return the pkgconfig description for a given task library package

Parameters:

  • name (String)

Returns:

  • (Utilrb::PkgConfig)

    the package

Raises:

  • TaskLibraryNotFound if the package cannot be found



179
180
181
182
183
# File 'lib/orogen/loaders/pkg_config.rb', line 179

def resolve_task_library_package(name, minimal: false)
    Utilrb::PkgConfig.get("#{name}-tasks-#{orocos_target}", minimal: minimal)
rescue Utilrb::PkgConfig::NotFound
    raise TaskLibraryNotFound, "the '#{name}' typekit is not available to pkgconfig"
end

#resolve_transport_package(typekit_name, transport_name, minimal: false) ⇒ Utilrb::PkgConfig

Return the pkgconfig description for a given transport package

Parameters:

  • name (String)

Returns:

  • (Utilrb::PkgConfig)

    the package

Raises:

  • TransportNotFound if the package cannot be found



201
202
203
204
205
# File 'lib/orogen/loaders/pkg_config.rb', line 201

def resolve_transport_package(typekit_name, transport_name, minimal: false)
    Utilrb::PkgConfig.get("#{typekit_name}-transport-#{transport_name}-#{orocos_target}", minimal: minimal)
rescue Utilrb::PkgConfig::NotFound
    raise TransportNotFound, "the '#{transport_name}' transport for the '#{typekit_name}' typekit is not available to pkgconfig"
end

#resolve_typekit_package(name, minimal: false) ⇒ Utilrb::PkgConfig

Return the pkgconfig description for a given typekit package

Parameters:

  • name (String)

Returns:

  • (Utilrb::PkgConfig)

    the package

Raises:

  • TypekitNotFound if the package cannot be found



190
191
192
193
194
# File 'lib/orogen/loaders/pkg_config.rb', line 190

def resolve_typekit_package(name, minimal: false)
    Utilrb::PkgConfig.get("#{name}-typekit-#{orocos_target}", minimal: minimal)
rescue Utilrb::PkgConfig::NotFound
    raise TypekitNotFound, "the '#{name}' typekit is not available to pkgconfig"
end

#task_library_path_from_name(tasklib_name) ⇒ Object

Return the full path to a task library's installed shared library



228
229
230
231
# File 'lib/orogen/loaders/pkg_config.rb', line 228

def task_library_path_from_name(tasklib_name)
    libpkg = resolve_task_library_package(tasklib_name)
    resolve_package_library(libpkg, libpkg.name)
end

#to_sObject



35
# File 'lib/orogen/loaders/pkg_config.rb', line 35

def to_s; "#<OroGen::Loaders::PkgConfig(#{object_id.to_s(16)}) #{orocos_target}>" end

#transport_library_path_from_name(typekit_name, transport_name) ⇒ Object

Return the full path to a transport's installed shared library



240
241
242
243
# File 'lib/orogen/loaders/pkg_config.rb', line 240

def transport_library_path_from_name(typekit_name, transport_name)
    libpkg = resolve_transport_package(typekit_name, transport_name)
    resolve_package_library(libpkg, libpkg.name)
end

#typekit_for(type, exported = true) ⇒ Spec::Typekit

Returns the typekit that defines the given type

Parameters:

  • type (#name, String)

    the type name

  • exported (Boolean) (defaults to: true)

    if true, the method will raise if the type is defined but not exported.

Returns:

Raises:

  • NotTypekitType, NotExportedType



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
374
375
376
377
378
# File 'lib/orogen/loaders/pkg_config.rb', line 347

def typekit_for(type, exported = true)
    typename = if type.respond_to?(:name)
                   type.name
               else type
               end

    if typekits = typekits_by_type_name[typename]
        if export_tk = typekits.find { |tk| tk.interface_type?(typename) }
            return export_tk
        elsif !exported
            return typekits.first
        end
    end

    if !available_types
        load_available_types
    end

    typekit = available_types[typename]
    if !typekit
        raise NotTypekitType.new(typename), "no type #{typename} has been registered in an oroGen project"
    elsif exported && !typekit.exported
        begin
            typekits = imported_typekits_for(typename)
            raise NotExportedType.new(typename, typekits), "the type #{typename} is registered in the #{typekits.map(&:name).sort.join(", ")} typekit, but it is not exported to the RTT type system"
        rescue DefinitionTypekitNotFound
            raise NotExportedType.new(typename, []), "the type #{typename} is not exported to the RTT type system"
        end
    else
        typekit_model_from_name(typekit.name)
    end
end

#typekit_library_path_from_name(typekit_name) ⇒ Object

Return the full path to a typekit's installed shared library



234
235
236
237
# File 'lib/orogen/loaders/pkg_config.rb', line 234

def typekit_library_path_from_name(typekit_name)
    libpkg = resolve_typekit_package(typekit_name)
    resolve_package_library(libpkg, libpkg.name)
end

#typekit_model_text_from_name(name) ⇒ Object



138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/orogen/loaders/pkg_config.rb', line 138

def typekit_model_text_from_name(name)
    begin
        pkg = resolve_typekit_package(name, minimal: true)
        available_typekits[name] = true
    rescue TypekitNotFound
        available_typekits[name] = false
        raise
    end

    registry = File.read(pkg.type_registry)
    typelist = File.join(File.dirname(pkg.type_registry), "#{name}.typelist")
    typelist = File.read(typelist)
    return registry, typelist
end