From Saturday, Nov 23rd 7:00 PM CST - Sunday, Nov 24th 7:45 AM CST, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

Community Documents

cancel
Showing results for 
Search instead for 
Did you mean: 

Debugging Symptoms - Packed Project Library PPL Dependencies - Searching for Dependencies Dialog When Running Executable

Debugging Symptoms Introduction

Welcome to my first posting as a Technical Support Engineer at NI! I'll be starting off a series of documents showcasing symptoms you might run into in the world of developing LabVIEW applications, the situation(s) that cause them, and how to fix them. These writeups will include a bit of a narrative describing some techniques the developer may have heard about that could lead them down the path they're stuck on and provide context to how they arrived at their destination. Eventually I'll be recording demo videos walking through the demos but we'll see how long it takes me to get around to those; I have a habit of taking on too many projects at once!

 

Prerequisites

The code for the demos are made in LabVIEW 2020.

 

To ensure PPLs are built in the correct order MGI's Solution Explorer (download page opens in a new tab) is used. This tool is now included in LabVIEW starting with 2020 so no separate download is needed! The Solution Explorer (LVSLN) is a tool that allows coordinating build specs contained in several projects, as well as running specific VIs as build actions, and differentiating between debug builds and release builds. It should be considered a mandatory tool when working with PPLs! The MGI Solution Explorer download page lists it as an evaluation but it's the full, free tool.

 

You can find the LVSLN tool in the... tools menu of the project explorer:

lvsln-menu.png

 

Symptom Overview

If you're following along with the code sample, you can extract the zip pretty much anywhere on your machine. This example will use an intermediate output folder at C:\common-libs so if you somehow already have this folder for your own development, don't be surprised when we empty out all PPLs in that folder later on in the demo!

 

This sample application represents one of the problems that can be run into when improperly managing PPL dependencies. The project consists of two main parts, reuse libraries and the application, which are further divided into sets of libraries and an executable.

 

There are the common libraries: Logging, Network, & UI which together represent a reusable set of components that are used across many projects; they're basically empty for this demo. These libraries are built to PPLs, specifically to c:\common-libs, to make managing development environments straight forward. Though they are part of this build solution for simplicity, imagine that these libraries are pre-built for company wide use and copied to development machines from a network share or source control.

 

The application leverages these common libraries as well as breaks up its functionality into a couple of PPLs separately from the executable. This is to encapsulate functionality a bit more explicitly and reduce build times when only a single component has changes. The PPLs generated in the App folder are specific to the application and can't be reused elsewhere so they aren't built to a common output folder; their output paths are left at default values. Then the main executable VI references these PPLs in the separate build output folders. To prevent the extra copying around of the common PPLs, the application specific PPLs have the option enabled to exclude dependent PPLs.

 

The executable itself does NOT have the exclude option selected as the developer desires a single root output folder to easily package and deploy to other machines.

excludeppls.png

 

Building & Testing in a Development Environment

The LabVIEW Solution file included with this demo.The LabVIEW Solution file included with this demo.

The first read-through of this assumes that the Clear Common Dev Env build step in the lvsln file is disabled to represent initial development processes and testing the executable on the development machine. This build step will be enabled later on to cause the problem to show up when "deploying" to a production machine.

 

Building the LVSLN should succeed and result in being able to run the autotest.exe as well as open the Main project and run Main from within the development environment. This results in a series of message dialogs showing some simple call hierarchies just to show which VIs are calling into which libraries. Something to note (and why the developer is initially confused) is that when exploring the EXE output folder (which can easily be reached by right-clicking on the AutoTester EXE entry in the solution explorer and choosing Explore to Destination) is that a data folder exists that contains ALL of the dependent PPLs which is exactly what they desired. The developer can copy the contents of this one root output folder and everything required will be present, easy peasey!

 

greet.png

The bit of functionality in the common libs to demonstrate they are working and who is calling them.

 

Deploying to a Production Environment

Now they deploy the application to a production environment and all of a sudden the application is trying to search for several of the PPLs that are in fact contained in the data folder. What gives? This can be simulated by right-clicking the Clear Common Dev Env entry in the solution explorer and manually selecting Rebuild. (It clears out the common PPLs at the development path of c:\common-libs) At this point attempting to run the EXE results in the search dialog showing up. When deploying to the production machine the developer knows the PPLs are already contained in the data folder so they expect to not need to setup the same common-libs folder.

clearlibs.png

 

Explanation & Fix

The LabVIEW App Builder knows to copy the lvlibp files into the data folder since they are listed as dependencies in the project, however that's where its capabilities end when dealing with built PPLs. The main problem is that the common libraries existed in a folder on the root of the C drive while the application libraries are built in a separate hierarchy or on a different drive letter (which is still a different path hierarchy?). This causes the App-Devices and App-Steps PPLs to be built with absolute path references to c:\common-libs. Then when building the EXE, LabVIEW copies everything into the data folder but it can't fix the common library references in App-Devices and App-Steps since they're already built. Even though copies were brought into the data folder, the App-* libraries still expect the PPLs to live in the c:\common-libs folder which doesn't exist on the production machine.

 

To fix this, all PPLs and source code should live on the same drive letter as a start. Another key point even for developing on a single drive is that there must be a common root folder containing both the build folders and the source folders. Following both of these rules will make sure the App Builder can use relative paths instead of absolute paths. Then even the Application specific PPLs should be built to the same folder containing the common libraries' PPLs. With this scheme all of the PPLs will have simple relative references to each other such as .\network.lvlibp and they can be moved around together and not break.

 

There are still options available for building the EXE. If EVERY SINGLE PPL in the dependency chain of the EXE was built to the same output folder, it will be safe to leave the exclude PPLs option unchecked and they'll all be copied to the data folder. Since all the PPLs know to look in the same folder for dependencies they'll be fine.

However if the PPLs are organized in subfolders within that common output folder then the EXE should also be built with the exclude PPLs option checked so the PPLs stay where they're at and know where to find their dependencies. To make this simpler for deployment and making installers the EXE should also be built to a folder within this common output folder. An example of this for applications I have built in the past might look like:

 

    • C:
      • dev
        • build
          • bin - Application EXE outputs
          • cfg - Application configuration files
          • ppl - Base PPL outputs
            • devices - HAL device classes
            • plugins - PPLs for other dynamically loaded features
        • source
          • common
            • network
            • logging
            • ui
          • app
            • devices
            • steps
            • main

This example build output scheme means PPLs will always know where to find each other and executables know to go up one folder, into the ppl folder, and then find the PPLs there. There can be further organization such as the plugins and devices folders in this example but EVERYTHING that might be needed by an application should exist within this common build root folder. Deployment can then be as easy as copying all the contents of the build folder and copying to a production machine or having an installer generated from the contents of the build folder.

 

Wrapping Up

Let me know if this is helpful for you or if you have anything to add to help make this more valuable for the community! I'm curious to see how many people have run into this issue before and what feedback anyone might have about the format.

Comments
Karthik_Abiram
Member Member
Member
on

Just ran into this issue in a project with multiple dependent PPLs. Thanks for documenting and sharing the explanation and fix to the community! 🙂

------
Using LabVIEW since 2012. Certified LabVIEW & TestStand Architect
BertMcMahan
Active Participant
Active Participant
on

Thanks for the article, very helpful! Unfortunately the example code doesn't work for me. If I unzip the directory to C:\dev\AutoTester PPL example, then run it with no mods other than to switch to 64-bit mode, the executable doesn't work even without running the cleanup VI. I believe I've understood what's supposed to happen so the article is still helpful.

 

Regarding the last part of your code, it's a little hard to follow what the fix is. Could you provide an example of a build spec that DOES fix all of the links correctly so that the app can run with the PPL's in the data folder? You described one but having an actual buildable example would be great as well.

DerrickB
NI Employee (retired)
on

@BertMcMahan I'll take a look and see what's up. What versions of LabVIEW have you tried this in?

BertMcMahan
Active Participant
Active Participant
on

LabVIEW 2020 64 bit. I fully admit I could've screwed something up in my install since I've been playing with PPL's, so it could be on me.

DerrickB
NI Employee (retired)
on

Also regarding the data folder, I'd rather remove that comment then provide an example for it. I definitely recommend having a common location and using the exclude dependencies option over using the data folder, unless there's really really good reason to. If everything uses the common folder and that build spec option, once working there are fewer opportunities for linking oddities when stuff moves around.

Contributors