Загрузка модуля libpeas, написанного на Vala и построенного с помощью meson, завершается неудачно

Я попытался построить этот пример с помощью meson: Начало работы с расширениями libpeas в vala

Мой meson.build выглядит следующим образом:

vala_deps = [
  dependency('gio-2.0', version: '>= 2.50'),
  dependency('gtk+-3.0', version: '>= 3.22'),
]
libpeas_dep = dependency('libpeas-1.0')

libfoo_deps = [vala_deps, libpeas_dep]
libfoo = shared_library(
  'foo',
  'window.vala',
  vala_header: 'foo.h',
  dependencies: libfoo_deps,
  install: true,
)
libfoo_dep = declare_dependency(
      link_with: libfoo,
      dependencies: libfoo_deps,
      include_directories: include_directories('.'),
)

extension_deps = [vala_deps, libpeas_dep]
extension = shared_library(
  'extension',
  'extension.vala',
  vala_header: 'extension.h',
  dependencies: [vala_deps, libpeas_dep, libfoo_dep],
  install: true,
  #install_dir : '/app/bin'
)
extension_dep = declare_dependency(
      link_with: extension,
      dependencies: extension_deps,
      include_directories: include_directories('.'),
)

gnome = import('gnome')
extension_resources = gnome.compile_resources(    
  'extension-resources',                      
  'extension.gresource.xml',                      
  c_name: 'extension',                        
)
foo_sources = [
  'main.vala',
  extension_resources[0],
]
foo = executable(
  'foo',
  foo_sources,
  link_with: extension,
  #objects: 'libextension.so',
  dependencies: [vala_deps, libfoo_dep, extension_dep],
  install: true,
)

если я использую предварительно скомпилированный файл общего объекта objects: 'libextension.so', внутри foo = executable( пример работает, если нет, то нет.

Какие-либо предложения?

РЕДАКТИРОВАТЬ:

вовлеченные файлы имеют следующее содержимое:

extension.gresource.xml:

<?xml version="1.0" encoding="UTF-8"?>
<gresources>
  <gresource prefix="/org/gnome/Foo/plugins">
    <file>extension.plugin</file>
  </gresource>
</gresources>

extension.plugin:

[Plugin]
Name=extension
Module=extension
Embedded=peas_register_types

extension.vala:

class ValaExtension : Object, Foo.Extension {

    public Foo.Window window { get; construct set; }

    Gtk.Button button;

    void activate() {
        button = new Gtk.Button.with_label("Say Hello");
        button.clicked.connect(() => {
            button.set_label("Hello World!");
        });
        window.buttons.add(button);
        button.show();
    }

    void deactivate() {
        window.buttons.remove(button);
    }
}

[ModuleInit]
public void peas_register_types(TypeModule module) {
    var objmodule = module as Peas.ObjectModule;

    objmodule.register_extension_type(typeof (Foo.Extension), typeof (ValaExtension));
}

main.vala:

int main (string[] args) {
    var app = new Gtk.Application ("org.gnome.Foo", ApplicationFlags.FLAGS_NONE);
    app.activate.connect (() => {
        var win = app.active_window;
        if (win == null) {
            win = new Foo.Window (app);
        }
        win.present ();
    });

    return app.run (args);
}

window.vala:

namespace Foo {

    public class Window : Gtk.Window {

        public Gtk.ButtonBox buttons { get; set; }

        private Peas.ExtensionSet extensions { get; set; }

        public Window(Gtk.Application app) {
            Object(application: app);

            this.buttons = new Gtk.ButtonBox(Gtk.Orientation.VERTICAL);
            this.destroy.connect(Gtk.main_quit);

            var engine = Peas.Engine.get_default();

            engine.add_search_path("/app/lib", null);
            engine.prepend_search_path("resource:///org/gnome/Foo/plugins/", null);

            extensions = new Peas.ExtensionSet(engine, typeof (Foo.Extension), "window", this);
            extensions.extension_added.connect((info, extension) => {
                (extension as Foo.Extension).activate();
            });
            extensions.extension_removed.connect((info, extension) => {
                (extension as Foo.Extension).deactivate();
            });

            foreach (var plugin in engine.get_plugin_list())
                engine.try_load_plugin(plugin);

            this.add(buttons);
            this.show_all();
        }
    }

    public interface Extension : Object {
        public abstract Window window { get; construct set; }
        public abstract void activate();
        public abstract void deactivate();
    }
}

если я прокомментирую objects:'libextension.so' В строке я получаю следующую ошибку:

(foo:2): libpeas-WARNING **: 20:27:31.400: Failed to get 'peas_register_types' for module 'extension': 'peas_register_types': foo: undefined symbol: peas_register_types

(foo:2): libpeas-WARNING **: 20:27:31.400: Error loading plugin 'extension'

Решено:

если я добавлю фиктивную функцию:

public void extension_init ()
{
}

для extension.vala и вызова его из main.vala, ссылка работает корректно для встроенного плагина, см. также здесь: gnome_builder_plugins_init.c

1 ответ

Решение

objects: 'libextension.so' будет связывать объект непосредственно с исполняемым файлом. Из примера видно, что вы загружаете модуль во время выполнения, используя libpeas. Поэтому, встроив модуль в исполняемый файл, я бы предположил, что у вас возникли проблемы с загрузкой модуля во время выполнения.

Учебник также советует установить LD_LIBRARY_PATH включить каталог с расширением, а также иметь libpeas .plugin файл. Это может быть проблемой. Было бы полезно, если бы вы перечислили сообщение об ошибке или детали того, что не работает.

Кстати, для использования объекта из цели сборки мезона лучше сделать objects: extension.extract_objects() поэтому имя объекта не является жестко заданным в сборке. Смотрите построить целевой объект. Использование objects: в основном полезно для тестов.

Обновить

Я думаю, что название вашего модуля в extension.plugin должно быть extension.so, Я также хотел бы быть откровенным о загрузчике модуля, поэтому я использовал Loader=C в прошлом. Я не сталкивался Embedded до. Так что я бы попробовал это как мой extension.plugin:

[Plugin]
Name=My first libpeas extension
Module=extension.so
Loader=C
Другие вопросы по тегам