Recommendations for Deploying LabVIEW Plugins in the Run-Time Engine


One technical aspect of creating the Measurement Utility that continues to prove to be challenging is building plugins in order to ensure they can be called correctly in the run-time engine (RTE).  To be clear, I’m referring specifically to plugins that are loaded dynamically by a LabVIEW-built executable using a factory pattern.  I thought I’d take a few minutes to document some of the lessons I’ve learned through this process.

Calling a plugin in the RTE requires that compiled copies of all linked dependencies are found when he plugin is loaded into memory.  This is something that we all take for granted in the development environment, as any deeply nested libraries you use can typically be found beneath vi.lib, user.lib, etc…, which are included in the default search paths that the development environment uses. However, except for a core group of supporting libraries, the run-time engine does not contain copies of many of these libraries, requiring a set of processes for deployment that ensure their presence.

I expect and recommend that plugins be developed independently of the calling framework using agreed upon interfaces, which I would expect to be defined by a base class from which the plugins inherit.  The framework should be built, managed and deployed using a separate Project than the measurements – both should have unique build specifications and potentially, unique installers.

After experimenting with different options and mechanisms, my general recommendation is to use source distributions as a mechanism to deploy plugins that will be loaded dynamically by a factory pattern.  PPLs (packed project libraries) have their own set of uses cases, but are generally better suited for statically linked libraries that will need to be replaced or updated independently of the calling code.  For dynamic dependencies I prefer source distributions as I have more explicit control over what they can include and how they are formatted and organized.

The following are recommendations (in no particular order) that are specific to the definition of plugin build specifications and the management of their dependencies:

1) Place the source files for your plugin inside a virtual folder – this makes it possible to apply settings to ‘all contained items,’ which cannot be done if a library or class is the highest-level item inside the Project (you then have to do it for each individualitem). When deployed, for example, you may want to disable debugging (which improves performance) and strip block diagrams (which protects against unauthorized modifications) – both settings can most easily be applied to the virtual folder that contains everything.

VirtualFolders

2) Identify which dependencies of a plugin should already be loaded by the calling executable versus the plugin. Parent classes of a plugin are a great example of something that is a dependency of the plugin, but should be loaded by the executable.  As a result, we can exclude items are built into the calling framework. To simplify this, I recommend creating a virtual folder in the Project Explorer of a plugin specifically to contain the items to be excluded – if, as an example, you create a new plugin for the Measurement Utility from a template, you’ll notice that the Project it creates includes an ‘Exclude from Build’ folder containing all the libraries that are included in the framework EXE.  This are all ideally located in an ‘installed’ directory in the development environment, such as user.lib.  In the source distribution build spec, this folder is marked as ‘Exclude from Build.

Source File Selection

3) Place everything you’ve developed for your specific plugin within a Project Library (or at least a class).  This helps avoid namespace collisions that could occur as a result of user-developed dependencies for a plugin sharing a name with dependencies of another plugin.  This can be especially problematic in the run-time, as the first copy of a dependency that gets called will be loaded into memory, so you can see plugins fail to load only in a scenario in which a conflicting items has already been loaded by another plugin.  Again, you’ll see that that Measurement Utility plugin demonstrates the use of Project Libraries to illustrate this.

4) Remove un-used members of libraries AND modify the library file.  As an example, almost every measurement is going to use some form of math, likely from the ‘Advanced Analysis Library’ in vi.lib, which is quite large.  Plugins should be small and atomic, so they should not be transporting large libraries that can a lot of superfluous functionality.   However, removing unused components introduces a new challenge: If library FOO contains functions A and B, and Plugin X uses A but not B, and Plugin Y uses B but not A, the build steps will create two new copies of the FOO library file, one which thinks it only contains A, and one which thinks it only contains B. As a result, whichever plugin is loaded first will define which functions can belong to it and if Plugin X is loaded first, Plugin Y will not be able to load correctly.  To address this, see number

Exclusions

5) Apply a pre-fix to items within the ‘Dependencies.’  Everything you developed for a plugin should be within the library mentioned in number 3.  Dependencies that the executable will load should’ve been excluded as noted in number 2.  This leaves a number of dependencies that are neither excluded nor developed by the user for the specific behavior of the plugin – as mentioned in number 4, a great example would be the Advanced Analysis Library.  Leave these items and their dependencies under the ‘Dependencies’ section of the project.  In the Build Specifications for a Source Distribution, you can apply a prefix to anything contained under dependencies.  Doing so avoids the scenario described in 4 by creating two unique namespaces for each instance of the library.

prefix

6) Do not place source files directly into the destination directory of the source distribution. Instead, the destination of the source distribution should be the name of the common folder that all plugins will inhabit, and a specific destination folder should be defined under the ‘Destinations’ category.  The output of building the source distribution will be identical using either approach; however, it will make defining an installer easier to follow this recommendation.  An installer replicates the hierarchy of a source distribution’s default destination directory in whichever folder it is told to use.  If you have followed this recommendation, the installer prompt will just show \Measurements as the destination directory, but it will place any plugins it includes into appropriate sub-folders.  Otherwise, you will need to manually create installer destinations for every plugin the installer contains.

dest

Advertisements

5 thoughts on “Recommendations for Deploying LabVIEW Plugins in the Run-Time Engine

    1. Barns

      Hi,

      I have one issue when doing as described.
      If the parent class uses a sub vi the child also needs it is excluded and not placed in the distribution. E.g. I use config file.vi’s to save the state of the plugin. With name prefix the vi’s in the llb are renamed but the library not. So it is not found in runtime. Is this a problem of Labview 2013? or am I missing something?

      cheers
      Barns

  1. Hi Elijah,

    My name is Jarobit Pina, I have developed a Test Applications Framework based in the “Plug-in” architecture that you describe above. The framework accesses to a server and takes the application that it desires to run it in the test bench and after verifying that it is possible to execute the application it runs it. I presented this architecture in last year’s UK NIDays and the CSLUG Group in Newbury

    The framework then does not know the code that it will run at all and I am practically able to insert any kind of test application in this framework without knowing its source code. Till here everything sounds great hehe. The framework is great for a company like mine, with facilities all over the world, because I can update my test systems just uploading a new version of a test application to a server. It is like having a cloud of automated systems.

    The problem I have is that sometimes when the architecture of my test applications is complex, to build the PPLs is a real pain in the ***, I get errors related to the dependencies that I cannot replicate when I use the source code, I sometimes cannot understand why the PPL does not carry all the dependencies with it when I am adding everything I need to my built, etc. I tried to find more information about the PPLs and how do they internally work, but the information that I can find is not enough.

    I wonder if you could address me to find more detailed information that can help me to understand the PPLs better or if you could tell me if I can write to someone who could help me. I would really appreciate any help as I sometimes spend more time trying to find out what the PPL does not like than programming my applications.

    Thank you,
    Jarobit

  2. Hey Jacobit,

    Hopefully this response is better late than never. Why are you wanting to use a PPL? If you have a plugin architecture with classes, I’d strongly recommend using the methodology outlined in this article instead.

    If you insist on using PPLs, you’ll need to build the base class in the framework into a PPL and make sure it’s installed with the calling framework. You’ll then need to relink the children against the parent that exists inside the PPL, which will have a new namespace. Then, when you author the leaf-level PPLs, you’ll need to be sure to discard the copies of the parent PPLs that are automatically created.

    The simple explanation for this approach is that PPLs guarantee that all statically linked dependencies are pulled in. However, they also change the name space – this means that a parent class, which is a static dependency, is going to be referenced by a different name by the framework and the plugin. The only way to avoid this is to build the parent class into a PPL.

    It’s enough work that again, I strongly recommend not pursuing this option.

    1. Sergey

      Elijah,

      This is exactly as you described about the changed namespace and the need to relink the children against the parent that exists in PPL. Now, what if not build the base class into PPL, but build only children that distributed as plugins? The base class is static and its methods are called in application directly, what the benefits of having it as a PPL as we may just include it in the application build directly?

      Thanks,
      Sergey

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s