Building component packages🔗

Component packages can be built either on the command line or graphically in the Builder. This document describes how to use the va-pkg command-line tool to build packages.

On Windows, the packaging tool is in the bin directory of the VisionAppster installation. In a user-scope Linux installation, it is placed in $HOME/bin or $HOME/.local/bin. If this directory is in your PATH, this command will give you basic usage instructions:

va-pkg

If you installed the Flatpak version to the system scope on Linux, type this first:

alias va-pkg="flatpak run --command=va-pkg com.visionappster.Builder"

Adding --help after a sub-command name will show you help on that sub-command.

Generally, the process of creating a component package has three phases:

  1. Create a directory structure with all the files that will go into the package.

  2. Create a manifest file, component.json, at the root.

  3. Zip the directory.

Native tool plugins🔗

Native tool plugins are created using the C tool API. An OpenCV-based C++ project template can be found here. If you need the plugin only internally, this is all you need on any platform.

If your intent is to publicly sell the plugin through VisionAppster Store, things become a bit more challenging. To prevent fragmentation of the platform, we require that all publicly distributed native extensions have been compiled for all the supported target platforms. Privately sold extensions don’t have this requirement. Furthermore, code that runs on VisionAppster Cloud as an API only needs to support Linux x86_64.

To build compliant native plugins, use our cross-compilation tools. They can also be used for example if you work on Windows and want your code to run in the cloud.

As a result of the build process, you’ll get one or more .toolplugin files, one for each supported architecture. These files are just shared libraries with a special extension.

The convention is to place native tool plugins into directories that specify the target architecture. So, at the minimum, the directory structure that goes into a tool plugin package is like this:

mycomponent/
mycomponent/linux-x86_64/
mycomponent/linux-x86_64/mycooltools.toolplugin

Here, mycomponent/ is the root directory that will hold the manifest file, component.json. The file doesn’t exist yet, but any update command will automatically create it. Since we followed the naming conventions, creating a manifest file is straightforward. Give this command in the parent directory of mycomponent/:

va-pkg update \
  --component-id com.example.tools.cool \
  --version 1.0.0 \
  --scan mycomponent

Here, com.example.tools.cool is the ID of your component. The --scan flag instructs va-pkg to scan the whole directory hierarchy and add all found files to the manifest file. Now you have what makes up a working package at a minimum:

mycomponent/
mycomponent/component.json
mycomponent/linux-x86_64/
mycomponent/linux-x86_64/mycooltools.toolplugin

To build the package:

va-pkg build mycomponent

This will create com.example.tools.cool-1.0.0.vapkg in the current directory. You can inspect the contents of the package with unzip:

unzip -l com.example.tools.cool-1.0.0.vapkg

The output should list these files:

com.example.tools.cool/1/linux-x86_64/mycooltools.toolplugin
com.example.tools.cool/1/component.json

Tool files🔗

Tool files contain processing graphs created in the Builder. They contain no native code and are thus executable on all supported platforms, provided that the native extensions used by the graph have been installed.

The processing graph and its parameters may be valuable information you want to protect. While the .tool file format isn’t designed to be human-readable, it isn’t too hard to figure out its contents. Obviously, the Builder can easily open them for introspection.

To protect your IPR, va-pkg makes it possible to encrypt .tool files. An encrypted processing graph can be loaded and executed by the VisionAppster Engine only if it comes from an installed component that has a valid digital signature, and the full component ID of that component matches the ID assigned to the .tool file. If an encrypted tool file is loaded in the Builder, it will appear just like a native tool that cannot be opened.

Since decrypting encrypted files require a valid signature, they can only be used if the package has been signed by the VisionAppster Store. You must register the component ID in the Store and use the full component ID to encrypt files.

Let’s assume you have created a processing graph, made it a compound and saved it as a .tool file. To include this file in a component package you just need to copy the file to the package directory. The contents of the directory will look like this:

mycomponent/
mycomponent/component.json
mycomponent/MyComplexTool.tool
mycomponent/linux-x86_64/
mycomponent/linux-x86_64/mycooltools.toolplugin

To encrypt the file, give this command in the root directory of the package (mycomponent/):

va-pkg tool encrypt \
  --full-component-id com.example.tools.cool/1 \
  MyComplexTool.tool

This will encrypt MyComplexTool.tool in a way that makes it unloadable from any component other than one with a full component ID of com.example.tools.cool/1 and a valid signature. The encrypted tool will be saved to MyComplexTool.toolc.

Alternatively, you can create a new package and make the package containing the native tool plugin a dependency (with va-pkg update --depends). Here, we’ll incorporate everything into a single component. Add the encrypted file to the manifest:

va-pkg update files +MyComplexTool.toolc .

Alternatively, va-pkg update --scan . can be used.

Now, if you build the component package again with va-pkg build, it will contain MyComplexTool.toolc. When installed, this tool will appear among other tools in the Builder as “My Complex Tool”.

Python tool plugins🔗

Just like native tool plugins and .tool files, a package can contain Python tool plugins. They are normal Python source files with a .py extension. The convention is to end the file name with toolplugin. If you follow this convention, va-pkg --scan will be able to set the correct file type automatically. The structure of a minimal component providing Python tools is as follows:

mycomponent/
mycomponent/component.json
mycomponent/toolplugin.py

Note that the component ID you pass to va.Tool.publish() in your Python code must match the component ID of the package you are building.

Apps🔗

When you save a project in the Builder, the Builder creates an app that runs a processing graph. The app is stored in the analysisapp/ directory under the project directory. Since the app is built in the Builder, the natural way to create a component package out of it is to use the Builder.

It is usually a good idea to build required tools into a separate component and add the full component IDs of required tool plugins as dependencies to the app component. You can define dependencies in the Builder’s graphical interface.

Alternatively, you can create a self-contained app component by copying the app’s files from analysisapp/ to the root directory of your tool plugin component:

mycomponent/
mycomponent/component.json
mycomponent/main.qml
mycomponent/appconfig.json
mycomponent/engine.tool
mycomponent/toolplugin.py
mycomponent/MyComplexTool.tool
mycomponent/linux-x86_64/
mycomponent/linux-x86_64/mycooltools.toolplugin

The component ID of such a package would need to be set so that it matches the component ID used in tool plugins implemented in Python or C. If you want to encrypt the .tool files, the new ID must be given there as well:

va-pkg tool encrypt \
  --full-component-id com.example.apps.cool/1 engine.tool
va-pkg tool encrypt \
  --full-component-id com.example.apps.cool/1 MyComplexTool.tool

The manifest must also be updated:

va-pkg update --component-id com.example.apps.cool --scan .

Finally, the package can be built:

cd ..
va-pkg build mycomponent

This will create com.example.apps.cool-1.0.0.vapkg that contains not only the app but also a native tool plugin and a tool file.

Store packages🔗

If you want to distribute your component through VisionAppster Store or run an app in VisionAppster Cloud, you must register the component’s ID on the Store, give it a name and sign the app. Giving a name is easy. Just give this command in the directory where component.json is stored:

va-pkg update --name "My cool component"

Signing🔗

If the package contains encrypted tool files or copy-protected native tool plugins, you’ll be unable to use them unless the package has a valid signature. A signature is also required for every component distributed through the VisionAppster Store.

To sign a component you need to create a token in the Store’s web interface (My Account → Tokens → New token) and assign the token the “Sign component” permission. Then, copy the token ID to va-pkg command line (in the directory where component.json is stored):

va-pkg sign --token 0123456789abcdef0123456789abcdef