diff --git a/src/qpm.io/common/messages/qpm.pb.go b/src/qpm.io/common/messages/qpm.pb.go index a442291..14d57f2 100644 --- a/src/qpm.io/common/messages/qpm.pb.go +++ b/src/qpm.io/common/messages/qpm.pb.go @@ -174,6 +174,8 @@ type Package struct { License LicenseType `protobuf:"varint,7,opt,name=license,enum=messages.LicenseType" json:"license,omitempty"` PriFilename string `protobuf:"bytes,8,opt,name=pri_filename" json:"pri_filename,omitempty"` Webpage string `protobuf:"bytes,10,opt,name=webpage" json:"webpage,omitempty"` + Plugins []*Package_Plugin `protobuf:"bytes,11,rep,name=plugins" json:"plugins,omitempty"` + Headers []string `protobuf:"bytes,12,rep,name=headers" json:"headers,omitempty"` } func (m *Package) Reset() { *m = Package{} } @@ -201,6 +203,13 @@ func (m *Package) GetVersion() *Package_Version { return nil } +func (m *Package) GetPlugins() []*Package_Plugin { + if m != nil { + return m.Plugins + } + return nil +} + type Package_Repository struct { Type RepoType `protobuf:"varint,1,opt,name=type,enum=messages.RepoType" json:"type,omitempty"` Url string `protobuf:"bytes,2,opt,name=url" json:"url,omitempty"` @@ -229,6 +238,15 @@ func (m *Package_Author) Reset() { *m = Package_Author{} } func (m *Package_Author) String() string { return proto.CompactTextString(m) } func (*Package_Author) ProtoMessage() {} +type Package_Plugin struct { + Class string `protobuf:"bytes,1,opt,name=class" json:"class,omitempty"` + Uri string `protobuf:"bytes,2,opt,name=uri" json:"uri,omitempty"` +} + +func (m *Package_Plugin) Reset() { *m = Package_Plugin{} } +func (m *Package_Plugin) String() string { return proto.CompactTextString(m) } +func (*Package_Plugin) ProtoMessage() {} + type Dependency struct { Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` Repository *Package_Repository `protobuf:"bytes,2,opt,name=repository" json:"repository,omitempty"` @@ -488,6 +506,7 @@ func init() { proto.RegisterType((*Package_Repository)(nil), "messages.Package.Repository") proto.RegisterType((*Package_Version)(nil), "messages.Package.Version") proto.RegisterType((*Package_Author)(nil), "messages.Package.Author") + proto.RegisterType((*Package_Plugin)(nil), "messages.Package.Plugin") proto.RegisterType((*Dependency)(nil), "messages.Dependency") proto.RegisterType((*VersionInfo)(nil), "messages.VersionInfo") proto.RegisterType((*SearchResult)(nil), "messages.SearchResult") diff --git a/src/qpm.io/common/messages/qpm.proto b/src/qpm.io/common/messages/qpm.proto index 4df5adf..715ded9 100644 --- a/src/qpm.io/common/messages/qpm.proto +++ b/src/qpm.io/common/messages/qpm.proto @@ -57,6 +57,11 @@ message Package { string name = 1; string email = 2; } + + message Plugin { + string class = 1; + string uri = 2; + } string name = 1; string description = 2; @@ -67,6 +72,8 @@ message Package { LicenseType license = 7; string pri_filename = 8; string webpage = 10; + repeated Plugin plugins = 11; + repeated string headers = 12; } message Dependency { diff --git a/src/qpm.io/qpm/commands/install.go b/src/qpm.io/qpm/commands/install.go index bddbe45..aa9ffb6 100644 --- a/src/qpm.io/qpm/commands/install.go +++ b/src/qpm.io/qpm/commands/install.go @@ -28,6 +28,15 @@ var packageFuncs = template.FuncMap{ return abs } }, + "relHeaderFile": func(vendorDir string, dep *common.PackageWrapper, headerFile string) string { + abs := filepath.Join(dep.RootDir(), headerFile) + rel, err := filepath.Rel(vendorDir, abs) + if err == nil { + return rel + } else { + return abs + } + }, } var ( @@ -39,12 +48,49 @@ DEFINES += QPM_INIT\\(E\\)=\"E.addImportPath(QStringLiteral(\\\"qrc:/\\\"));\" DEFINES += QPM_USE_NS INCLUDEPATH += $$PWD QML_IMPORT_PATH += $$PWD +HEADERS += $$PWD/vendor.h {{$vendirDir := .VendorDir}} {{range $dep := .Dependencies}} include($$PWD/{{relPriFile $vendirDir $dep}}){{end}} `)) ) +var ( + // This template is very dense to avoid excessive whitespace in the generated code. + // We can address this in a future version of Go (1.6?): + // https://github.com/golang/go/commit/e6ee26a03b79d0e8b658463bdb29349ca68e1460 + vendorHeader = template.Must(template.New("vendorHeader").Funcs(packageFuncs).Parse(` +#include +#include + +{{$vendirDir := .VendorDir}} +{{range $dep := .Dependencies}} +{{range $header := $dep.Package.Headers}} +#include "{{relHeaderFile $vendirDir $dep $header}}" +{{end}} +{{end}} + +namespace qpm { + +void init(const QCoreApplication &app, QQmlEngine &engine) { + // Add qml components + engine.addImportPath(QStringLiteral("qrc:/")); + + // Add C++ components + {{range $dep := .Dependencies}} + {{range $plugin := $dep.Package.Plugins}} + // {{$plugin}} + {{$plugin.Class}} pluginInstance_{{$plugin.Class}}; + pluginInstance_{{$plugin.Class}}.registerTypes("{{$plugin.Uri}}"); + pluginInstance_{{$plugin.Class}}.initializeEngine(&engine, "{{$plugin.Uri}}"); + {{end}} + {{end}} +} + +} +`)) +) + type ProgressProxyReader struct { io.Reader total int64 @@ -247,9 +293,38 @@ func (i *InstallCommand) postInstall() error { i.Error(err) return err } + if err := GenerateVendorHeader(i.vendorDir, i.pkg); err != nil { + i.Error(err) + return err + } return nil } +func GenerateVendorHeader(vendorDir string, pkg *common.PackageWrapper) error { + depMap, err := common.LoadPackages(vendorDir) + if err != nil { + return err + } + + var deps []*common.PackageWrapper + for _, dep := range depMap { + deps = append(deps, dep) + } + + vendorHeaderFile := filepath.Join(vendorDir, core.Vendor+".h") + + data := struct { + VendorDir string + Package *common.PackageWrapper + Dependencies []*common.PackageWrapper + }{ + vendorDir, + pkg, + deps, + } + return core.WriteTemplate(vendorHeaderFile, vendorHeader, data) +} + // Generates a vendor.pri inside vendorDir using the information contained in the package file // and the dependencies func GenerateVendorPri(vendorDir string, pkg *common.PackageWrapper) error {