Jump to content

[VIPM] Building a package which uses a linux shared project (.so file)


Recommended Posts

I've built a VIPM package of re-usable code which I want to use with the Raspberry Pi, the RPi effectively being an embedded linux platform. For the code I first built a shared object file (.so extension, basically a linux DLL) for this GPIO library. I then wrap the functions I need using LabVIEW CLFN's. Of course Windows hates this file and LabVIEW will complain if it tries to access it, but I can solve that by building my library inside a project with RPi as the target. When I build my VIPM package, a search takes place for the .so file, but it gets ignored and the package builds without errors. So everything is fine up to this point.

Project.png

The problem occurs though when I install the VIPM package (to vi.lib, although it doesn't matter where). All the VI's in the package are broken (see pics below). I can solve this by simply opening up each CLFN on the block diagrams and then closing them- the VI is fixed and the Run arrow becomes unbroken. So this will solve the problem. But I need to do this for all the VIs in the package which is tedious. Does anyone have any recommendations on how to solve the broken VI problem? To be honest I don't mind the fix I have (opening and closing the CLFN for all VIs) but other users might not like this idea, and sharing decent code is one of my aims in using the RPi (in the Maker tradition).

Broken VI.png

Open and close CLFN to fix broken VI:

Open CLFN.png

Fixed VI:

Fixed VI.png

Edited by dmurray
Forgot pics
Link to comment
3 hours ago, drjdpowell said:

Try libLV_2835.*, as that means to use .dll or .so as applicable.

Doesn't seem to work unfortunately. For some reason a phantom file "libLV_2835.dll" has now appeared in the project dependencies, but the original problem still remains.

Link to comment

I would check the "specify path on diagram" and try passing the path into the CLFN node and use a conditional disable structure to pass in the extension (or hard code it to only support Linux targets).  Best practice would be to create a subVI with the constant so that you use the same path for all instances.

Edited by Omar Mussa
  • Like 2
Link to comment
4 hours ago, Omar Mussa said:

I would check the "specify path on diagram" and try passing the path into the CLFN node and use a conditional disable structure to pass in the extension (or hard code it to only support Linux targets).  Best practice would be to create a subVI with the constant so that you use the same path for all instances.

Works perfect, thanks for the suggestion! Here's the steps I used, for anyone else who has this issue:

1. Created a directory in vi.lib for this shared object and future shared objects.

2. Used the 'Specifiy path...' option for the CLFN, and created the sub-vi for the path.

pic1.png

 

3. Created two options for the path; one for OS == Win and the other for OS == Linux.

pic2.png

pic3.png

 

3. When I build the VIPM package, I use the OS == Win symbol.

pic4.png

 

4. Then, in projects that I will deploy to the RPi, I use the OS == Linux option.

pic5.png

 

Thanks again, much appreciated. :)

 

 

 

Link to comment

That's great!  One other thing you might try - I think the build process should also work if the Conditional structure default case was "empty path" and that the "Linux" path was as you coded it - in that case it avoids the unnecessary hardcoded path to the .SO file in the unsupported cases (non-Linux).  I think the code will still open as 'non-broken' if open on a Linux target context (as it should be) and it will open broken on a Windows context (as it should be).  Its probably best that the code is broken when opened in an unsupported context - because its better to break at development time than at run-time in this scenario.

  • Like 2
Link to comment
13 hours ago, Omar Mussa said:

That's great!  One other thing you might try - I think the build process should also work if the Conditional structure default case was "empty path" and that the "Linux" path was as you coded it - in that case it avoids the unnecessary hardcoded path to the .SO file in the unsupported cases (non-Linux).  I think the code will still open as 'non-broken' if open on a Linux target context (as it should be) and it will open broken on a Windows context (as it should be).  Its probably best that the code is broken when opened in an unsupported context - because its better to break at development time than at run-time in this scenario.

Done. Thanks again.

Link to comment
2 hours ago, ShaunR said:

The OS condition is project only. When you deploy your package, the end user needs to have that in his project too (it also won't work if the VI is opened outside of a project). It is better to use the TARGET_TYPE (Windows, Unix and Mac) which doesn't require the user to do anything and works without a project file.

TARGET_TYPE doesn't seem too work in this case. Or, to elaborate, it works fine when building the package, but not when I deploy a project to the RPi (I get an error that the .so library cannot be opened). Also, on the project that I'm deploying to the RPi, I can't now set the TARGET_TYPE parameter to Unix try to get around the error. It says something about the symbol being reserved by LabVIEW. Possibly I'm doing something wrong.

I don't think it matters that the user can only work in a project. I think they actually have to, as they need to set the target to Raspberry Pi (see below).

Project.png

Another possibly important detail about the shared object file in this case is that it will only be compatible with the LabVIEW LINX tools. There are already some conditional disable options set up for the RPi in that case:       

Default MakerHub Properties.png

 

Link to comment
3 hours ago, hooovahh said:

Will the steps mentioned also force LabVIEW to recognize the SO file as a dependency, and include it any builds?  That's one issue I thought I remember having with Windows built EXE, when specifying the DLL path by the CLN input.

I don't think so, the build process doesn't seem to care too much about the file once it can 'see' it in the Shared Object folder I created in vi.lib. However, users will still have to copy the shared object file into the correct location on the RPi, using Filezilla or some other means. And it needs to go into the user space that the MakerHub LINX tool creates. See Local IO description here for more details on the architecture if you're interested. So a user still has some work to do, which isn't ideal. I'm sure the process could be automated, but that's lower priority at the moment.

Another point is that the .so file in this case would not be compatible with the TSXperts compiler for RPi, which I believe is imminent. 

 

Edit to add: Just realized you mean will there be a dependency problem for users when they install the package. That's something I need to check on a second machine.

Edited by dmurray
Link to comment
1 hour ago, ShaunR said:

The OS condition is project only. When you deploy your package, the end user needs to have that in his project too (it also won't work if the VI is opened outside of a project). It is better to use the TARGET_TYPE (Windows, Unix and Mac) which doesn't require the user to do anything and works without a project file.

I think that in this case, the OS flag is OK even if its project only since you (typically?) need to be in a project to work on a target's code anyway (as far as I understand how working with targets works).

1 hour ago, hooovahh said:

Will the steps mentioned also force LabVIEW to recognize the SO file as a dependency, and include it any builds?  That's one issue I thought I remember having with Windows built EXE, when specifying the DLL path by the CLN input.

I'm not sure - actually think I may have messed that up and it may have just worked for the case where the dependency already existed where expected.  I think VIPM builld process may grab it if its in the source folder of the package, not sure - would be definitely worth testing by deploying package to a new machine.

Link to comment
7 minutes ago, Omar Mussa said:

I'm not sure - actually think I may have messed that up and it may have just worked for the case where the dependency already existed where expected.  I think VIPM builld process may grab it if its in the source folder of the package, not sure - would be definitely worth testing by deploying package to a new machine.

Now that you mention it, I am actually getting a second PC in place to test these packages before I share them anyway. That will tell me a lot.

Link to comment
48 minutes ago, hutha said:

What's path you put "libLV_2835.so" inside Pi directory ? for example "/home/pi" or other path ?

Amornthep

You need to place them in "/usr/lib", but you also need to be logged on as the root user working in the LV chroot. I wrote a simple document on how to create these shared objects and where they need to go on RPi. All the information should be there but if anything is unclear let me know.

Link to comment
  • 1 month later...
On 8/24/2016 at 9:13 PM, hooovahh said:

Will the steps mentioned also force LabVIEW to recognize the SO file as a dependency, and include it any builds?  That's one issue I thought I remember having with Windows built EXE, when specifying the DLL path by the CLN input.

 

On 8/24/2016 at 10:51 PM, dmurray said:

I don't think so, the build process doesn't seem to care too much about the file once it can 'see' it in the Shared Object folder I created in vi.lib. However, users will still have to copy the shared object file into the correct location on the RPi, using Filezilla or some other means. And it needs to go into the user space that the MakerHub LINX tool creates. See Local IO description here for more details on the architecture if you're interested. So a user still has some work to do, which isn't ideal. I'm sure the process could be automated, but that's lower priority at the moment.

Another point is that the .so file in this case would not be compatible with the TSXperts compiler for RPi, which I believe is imminent. 

 

Edit to add: Just realized you mean will there be a dependency problem for users when they install the package. That's something I need to check on a second machine.

Okay, just to tidy up this post, the steps I used work with no dependency issues when I tested on a second PC (just got around to testing this now). The package(s) are available on the NI forum here, if anyone is interested. Thanks to everyone who helped me with this. 

Link to comment
  • 2 weeks later...
On 24-8-2016 at 10:13 PM, hooovahh said:

Will the steps mentioned also force LabVIEW to recognize the SO file as a dependency, and include it any builds?  That's one issue I thought I remember having with Windows built EXE, when specifying the DLL path by the CLN input.

LabVIEW doesn't deploy shared libraries to the embedded targets itself (except the old Pharlap based systems). So in my experience you always need to find a way to bring the necessary shared libraries to those targets yourself. One option is to just copy them manually into the correct location for the system in question (/usr/local/lib for the NI Linux RT based systems). Another one is to create a distribution package that the user then can install to the target through the NI Max Software installation section for the specific target. The creation of such a package isn't to difficult, it is mostly a simple configuration file that needs to be made and copied into a subdirectory in the "Program Files/National Instruments/RT Images" folder together with the shared library file(s) and any other necessary files.

The OpenG ZIP library makes use of this last method to install support for the various NI RT targets.

  • Like 1
Link to comment
On 10/11/2016 at 0:51 PM, rolfk said:

Another one is to create a distribution package that the user then can install to the target through the NI Max Software installation section for the specific target. The creation of such a package isn't to difficult, it is mostly a simple configuration file that needs to be made and copied into a subdirectory in the "Program Files/National Instruments/RT Images" folder together with the shared library file(s) and any other necessary files.

It this process documented anywhere?

Link to comment
7 hours ago, ShaunR said:

It this process documented anywhere?

To my knowledge not beyond what you can get from the OpenG library. When I tried to do that I was looking for some further documentation but couldn't find anything beyond some tidbits in remotely related things in knowledge articles. So I simply gleemed through the different packages and deduced the necessary format for the .cdf ( component definition file ). Being an XML format file made it somewhat easy to guess the relevant parts.

There is in newer LabVIEW versions an option to create an installation package for RT from an RT project which uses the same cdf file, but the creation of that file is of course hidden inside the according package builder plugin. If the purpose is to only create an installer component for a shared library then the files from the OpenG ZIP library should give some headstart.

One problem you might have to solve is also to get the files into the RT Image subdirectory. Since it is inside the Program Files, your installer app needs to have elevated privileges in order to put it there. If you do this as part of a VIPM or OGP package file, then VIPM often is not started by default with such rights. I solved that by packing all the components into a setup file made with innosetup which will request the privilege evelation. Then I start that setup file at the end of the package installation and it then installs the components into the RT Image subdirectory.

  • Like 1
Link to comment
11 hours ago, rolfk said:

To my knowledge not beyond what you can get from the OpenG library. When I tried to do that I was looking for some further documentation but couldn't find anything beyond some tidbits in remotely related things in knowledge articles. So I simply gleemed through the different packages and deduced the necessary format for the .cdf ( component definition file ). Being an XML format file made it somewhat easy to guess the relevant parts.

There is in newer LabVIEW versions an option to create an installation package for RT from an RT project which uses the same cdf file, but the creation of that file is of course hidden inside the according package builder plugin. If the purpose is to only create an installer component for a shared library then the files from the OpenG ZIP library should give some headstart.

One problem you might have to solve is also to get the files into the RT Image subdirectory. Since it is inside the Program Files, your installer app needs to have elevated privileges in order to put it there. If you do this as part of a VIPM or OGP package file, then VIPM often is not started by default with such rights. I solved that by packing all the components into a setup file made with innosetup which will request the privilege evelation. Then I start that setup file at the end of the package installation and it then installs the components into the RT Image subdirectory.

Yes. I have looked at the RT Images directory now and it seems fairly straight forward. There seems to be a couple of ways to utilise the deployment framework but the only thing I'm not sure of is the origin of the GUID strings. I haven't looked at the zip package as yet.

I get around the elevation by using my own VI that is invoked as the pre-install VI of VI Package Manager. If it fails, it tells the user to run the LabVIEW IDE using the "Run As Administrator". Not perfect but users seem to have no issue with this process and it works on other platforms (like Linux and Mac) too - of course changing the appropriate language (su, kdesu etc).

Since I have all the tools, I'm also thinking of SFTP from a LabVIEW menu instead of the NI deployment. Max and I don't really get along and Silverlight brings me out in hives :D  It would be great for the Linux  platforms and avoid most if not all all the privilege problems since I would be able to control the interaction . I'm just mulling over whether I want that knowledge and can be bothered to see where it goes :lol:

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.