Following some instructions in this forum, as well as the NI Forums, I was able to get a successful 64-bit compilation of labview-zmq working with a NI Linux Real-Time x64 system.
However, I did have to modify zmq_libpath.vi to use a different path for the library. It would be ideal if the code would have some conditional disable symbols to include the correct path.
If possible I'd like to submit a pull request, and maybe some updated documentation, on how to get labview-zmq working for NI Linux Real-Time. I was also thinking it would be good to include the pre-compiled .so file along with the release, same way as you have the DLLs included.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
It'd be great if you could provide some more detailed instructions on compiling for real-time x64, which is a platform I've never worked with myself! I'm not especially keen on putting conditional disables in the zmq_libpath.vi because of a large number of inconsistencies with how that's treated by the mass-compile process under different versions of LabVIEW. I had used conditional disables originally and had to switch away from doing that because of several user-reported issues and I've prefer not to break backwards-compatibility.
I'd appreciate a precompiled build as I don't have access to that platform; it would be good to make it easier for users to get things up and running quickly!
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I will work on writing up a small tutorial on how to compile for NI Linux Real-Time x64 - it is almost identical to the steps in another post here about compiling for an ARM-based cRIO (9068 I believe).
I believe you already are using conditional disables though in zmq_libpath.vi? What I don't want is to have my own special copy of the library that works for NI Linux Real-Time x64 that I distribute separately - I think it would be best if there were some way to include this in the base library, otherwise anytime there was a new version of the library I would have to manually update the zmq_libpath.vi which seems like it should be an unnecessary extra step...
I don't have physical hardware that I am building this with - I am building this all from a VirtualBox VM for NI Linux Real-Time x64 - I was able to do this using this forum post here - you will need to look in the latest replies as the first few aren't as helpful. I'm not sure how you are handling your VIP build process but it is possible you could use this target to build automatically using SSH and a tool like Jenkins.
I have attached my compiled library for NI Linux Real-Time x64 to this post as well
Alright, here are the steps I took to compile labview-zmq for NI Linux Real-Time x64
Install build tools (make, gcc, etc) with opkg install packagegroup-core-buildessential
Install ZeroMQ using opkg install zeromq ; opkg install zeromq-staticdev – this step is also required on targets that you are trying to run this library on.
Copy the cintools folder (this can be found in your LabVIEW install folder, I used the one in my Windows installation) to /usr/local/natinst/labview
Copy the labview-zmq directory to /usr/local/natinst/labview/vi.lib/addons
Create a symlink to liblvrt with ln -s /usr/local/natinst/labview/liblvrt.so.19.0.0 /usr/local/natinst/labview/liblvrt.so making sure to replace 19 with the major version of LabVIEW you are using.
Modify /etc/ld.so.conf.d/natinst_libs.conf by appending the line /usr/local/natinst/labview to it – this ensures that liblvrt.so can be found at run-time. If this step is missed, Error 13 when running labview-zmq is the result.
Rebuild the ld cache with rm /etc/ld.so.cache ; ldconfig
Verify that libzmq.so is found by running ldconfig -p | grep libzmq.zo (this command should return something – if it returns nothing, verify the above steps were successful – see below for example output)
Verify that liblvrt.so is found by running ldconfig -p | grep liblvrt.so (this command should return something – if it returns nothing, verify the above steps were successful – see below for example output)
Run make in the /usr/local/natinst/labview/vi.lib/addons/zeromq/lib directory. You will see two warnings which is expected, the compilation will still succeed if only warnings are found.
Modify zmq_libpath.vi so that it points to the generated lvzmq64.so path correctly on your target (I did this with conditional disables)
???
Profit!
Last edit: Brandon Jones 2019-11-14
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
After some time using this I am finding that something is most definitely not quite right... I think it is related to the LVALIGNMENT. Things pseudo-work and then I get very strange LabVIEW crashes that don't provide helpful crash info...
Could you maybe talk a bit more about how you found what the correct LVALIGNMENT values should be?
As a note, I did tweak a few things in the code to try and fix this issue. Specifically I took care of the compiler warnings I was receiving, but that did not resolve the issue.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thanks for your input, sorry I've been swamped with work lately. I suspected there would need to be a modification to the alignment for 64-bit RTOS; I thought I had put one in already but evidently not. I expect LVALIGNMENT should be 8 so it should just be a case of modifying the preprocessor check around zmq_labview.c:56 to check SIZE_MAX to determine the native pointer size - or similar. Basically the alignment should be native - except on WIN32, where it's unaligned. Debugging all that caused me a lot of headaches originally, because it's not exactly documented by NI (or wasn't in the past) and it tends not to fail immediately - but rather crash in some unlikely place due to overflow or heap corruption.
The origin of the approach is the Clusters entry on this page, although NI didn't/don't specify where the alignment rules do and do not apply - my guess is it's just what the compiler automatically picks for their internal datastructures. In the end it took trial and error.
Thanks also for the hint about using a VM - hadn't thought of that! Next time I have some opportunity to work on side projects I might look into that.
Last edit: Martijn Jasperse 2019-11-25
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I looked at the link you sent, as that is what I was also using for testing, and I noticed that it calls out 4 byte alignment for MacOS and Linux...
(Windows 32-bit) Data is aligned only to 1-byte boundaries.
(macOS and Linux) Data is aligned naturally up to 4-byte boundaries.
(Phar Lap ETS, VxWorks, Windows 64-bit) Data is aligned naturally up to 8-byte boundaries.
Is the value of LVALIGNMENT just supposed to correspond to what is called out on that page for the specific OS?
However, I am also wondering if it is more than just an issue on the RT side... I know that ZeroMQ is not thread safe, but all the call library nodes in the API are set to run in any thread. Is the wrapper you provided "thread safe" or no? Because I know ZMQ itself is not thread safe...
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
My rough understanding is that compiling for the RTOS corresponds to VxWorks so that means 64-bit aligned and therefore the presently-used value is incorrect. Again, my expectation is that the 32-bit RTOS would be 4-byte aligned and the 64-bit RTOS would be 8-byte aligned. I believe the code has been used successfully on 32-bit RTOS, which appears to contradict this, but I have encountered many situations where the documentation is incomplete or missing a corner case.
Regarding thread safety, you should notice that all CLN calls are wrapped in DVR blocks. This is a simple thread safety paradigm to prevent concurrent access to the same "object". This has been extensively load-tested on Windows/Linux and I expect RTOS should be the same. The termination protocol of ZMQ basically requires some level of multithreading where the socket and context are separate. This is quite distinct from "direct" TCP usage where the concept of a context does not exist. I originally used mutexes at the C level but recursive function calls were a real pain and the DVR locks on the invocation side which is preferable.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hello,
I trying to use @Brandon Jones guide to build and run the library on Ubuntu20.4. I would be grateful to know how should I adapt the procedure. The first issue is that I cannot find zeromq-staticdev package for Ubuntu, so the only one which I have installed is :
libzmq3-dev
Then I hanave added /etc/ld.so.conf.d/natinst_libs.conf file with path to librarys. So my current librarys in system are:
After makefile modifications listed by Brandon Jones, make produced lvzmq64.so file with a warning only.
However, when I try to run VI with Create Context.VI, I can see Error 13 (which was described as a problem with dynamically loaded libraries). I can not find the source of this error -> is that connected with the missing -static package?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The problem was that c wrapper lvzmq64 is using draft functions of zmq library. To resolve this issue you need to install zmq library with draft mode enable. For Ubuntu its possible with manual package instalation:
Following some instructions in this forum, as well as the NI Forums, I was able to get a successful 64-bit compilation of labview-zmq working with a NI Linux Real-Time x64 system.
However, I did have to modify zmq_libpath.vi to use a different path for the library. It would be ideal if the code would have some conditional disable symbols to include the correct path.
If possible I'd like to submit a pull request, and maybe some updated documentation, on how to get labview-zmq working for NI Linux Real-Time. I was also thinking it would be good to include the pre-compiled .so file along with the release, same way as you have the DLLs included.
It'd be great if you could provide some more detailed instructions on compiling for real-time x64, which is a platform I've never worked with myself! I'm not especially keen on putting conditional disables in the zmq_libpath.vi because of a large number of inconsistencies with how that's treated by the mass-compile process under different versions of LabVIEW. I had used conditional disables originally and had to switch away from doing that because of several user-reported issues and I've prefer not to break backwards-compatibility.
I'd appreciate a precompiled build as I don't have access to that platform; it would be good to make it easier for users to get things up and running quickly!
I will work on writing up a small tutorial on how to compile for NI Linux Real-Time x64 - it is almost identical to the steps in another post here about compiling for an ARM-based cRIO (9068 I believe).
I believe you already are using conditional disables though in zmq_libpath.vi? What I don't want is to have my own special copy of the library that works for NI Linux Real-Time x64 that I distribute separately - I think it would be best if there were some way to include this in the base library, otherwise anytime there was a new version of the library I would have to manually update the zmq_libpath.vi which seems like it should be an unnecessary extra step...
I don't have physical hardware that I am building this with - I am building this all from a VirtualBox VM for NI Linux Real-Time x64 - I was able to do this using this forum post here - you will need to look in the latest replies as the first few aren't as helpful. I'm not sure how you are handling your VIP build process but it is possible you could use this target to build automatically using SSH and a tool like Jenkins.
I have attached my compiled library for NI Linux Real-Time x64 to this post as well
Alright, here are the steps I took to compile labview-zmq for NI Linux Real-Time x64
Install build tools (make, gcc, etc) with
opkg install packagegroup-core-buildessential
Install ZeroMQ using
opkg install zeromq ; opkg install zeromq-staticdev
– this step is also required on targets that you are trying to run this library on.Copy the cintools folder (this can be found in your LabVIEW install folder, I used the one in my Windows installation) to /usr/local/natinst/labview
Copy the labview-zmq directory to /usr/local/natinst/labview/vi.lib/addons
Create a symlink to liblvrt with
ln -s /usr/local/natinst/labview/liblvrt.so.19.0.0 /usr/local/natinst/labview/liblvrt.so
making sure to replace 19 with the major version of LabVIEW you are using.Modify /etc/ld.so.conf.d/natinst_libs.conf by appending the line /usr/local/natinst/labview to it – this ensures that liblvrt.so can be found at run-time. If this step is missed, Error 13 when running labview-zmq is the result.
Rebuild the ld cache with
rm /etc/ld.so.cache ; ldconfig
Verify that libzmq.so is found by running
ldconfig -p | grep libzmq.zo
(this command should return something – if it returns nothing, verify the above steps were successful – see below for example output)ldconfig -p | grep liblvrt.so
(this command should return something – if it returns nothing, verify the above steps were successful – see below for example output)Modify/verify line 62 in /usr/local/natinst/labview/vi.lib/addons/zeromq/lib/zmq_labview.c to be
#define LVALIGNMENT 8
Modify/verify line 604 in /usr/local/natinst/labview/vi.lib/addons/zeromq/lib/zmq_labview.c to be
pthread_t thread;
Modify/verify that the Linux build rules in the makefile located at /usr/local/natinst/labview/vi.lib/addons/zeromq/lib/makefile are as follows:
Run make in the /usr/local/natinst/labview/vi.lib/addons/zeromq/lib directory. You will see two warnings which is expected, the compilation will still succeed if only warnings are found.
Modify zmq_libpath.vi so that it points to the generated lvzmq64.so path correctly on your target (I did this with conditional disables)
???
Profit!
Last edit: Brandon Jones 2019-11-14
After some time using this I am finding that something is most definitely not quite right... I think it is related to the LVALIGNMENT. Things pseudo-work and then I get very strange LabVIEW crashes that don't provide helpful crash info...
Could you maybe talk a bit more about how you found what the correct LVALIGNMENT values should be?
As a note, I did tweak a few things in the code to try and fix this issue. Specifically I took care of the compiler warnings I was receiving, but that did not resolve the issue.
Thanks for your input, sorry I've been swamped with work lately. I suspected there would need to be a modification to the alignment for 64-bit RTOS; I thought I had put one in already but evidently not. I expect LVALIGNMENT should be 8 so it should just be a case of modifying the preprocessor check around zmq_labview.c:56 to check SIZE_MAX to determine the native pointer size - or similar. Basically the alignment should be native - except on WIN32, where it's unaligned. Debugging all that caused me a lot of headaches originally, because it's not exactly documented by NI (or wasn't in the past) and it tends not to fail immediately - but rather crash in some unlikely place due to overflow or heap corruption.
The origin of the approach is the Clusters entry on this page, although NI didn't/don't specify where the alignment rules do and do not apply - my guess is it's just what the compiler automatically picks for their internal datastructures. In the end it took trial and error.
Thanks also for the hint about using a VM - hadn't thought of that! Next time I have some opportunity to work on side projects I might look into that.
Last edit: Martijn Jasperse 2019-11-25
I looked at the link you sent, as that is what I was also using for testing, and I noticed that it calls out 4 byte alignment for MacOS and Linux...
Is the value of LVALIGNMENT just supposed to correspond to what is called out on that page for the specific OS?
However, I am also wondering if it is more than just an issue on the RT side... I know that ZeroMQ is not thread safe, but all the call library nodes in the API are set to run in any thread. Is the wrapper you provided "thread safe" or no? Because I know ZMQ itself is not thread safe...
My rough understanding is that compiling for the RTOS corresponds to VxWorks so that means 64-bit aligned and therefore the presently-used value is incorrect. Again, my expectation is that the 32-bit RTOS would be 4-byte aligned and the 64-bit RTOS would be 8-byte aligned. I believe the code has been used successfully on 32-bit RTOS, which appears to contradict this, but I have encountered many situations where the documentation is incomplete or missing a corner case.
Regarding thread safety, you should notice that all CLN calls are wrapped in DVR blocks. This is a simple thread safety paradigm to prevent concurrent access to the same "object". This has been extensively load-tested on Windows/Linux and I expect RTOS should be the same. The termination protocol of ZMQ basically requires some level of multithreading where the socket and context are separate. This is quite distinct from "direct" TCP usage where the concept of a context does not exist. I originally used mutexes at the C level but recursive function calls were a real pain and the DVR locks on the invocation side which is preferable.
Hello,
I trying to use @Brandon Jones guide to build and run the library on Ubuntu20.4. I would be grateful to know how should I adapt the procedure. The first issue is that I cannot find zeromq-staticdev package for Ubuntu, so the only one which I have installed is :
Then I hanave added /etc/ld.so.conf.d/natinst_libs.conf file with path to librarys. So my current librarys in system are:
After makefile modifications listed by Brandon Jones, make produced lvzmq64.so file with a warning only.
However, when I try to run VI with Create Context.VI, I can see Error 13 (which was described as a problem with dynamically loaded libraries). I can not find the source of this error -> is that connected with the missing -static package?
The problem was that c wrapper lvzmq64 is using draft functions of zmq library. To resolve this issue you need to install zmq library with draft mode enable. For Ubuntu its possible with manual package instalation:
I have also described the problem and the solution in more detail on lava :
https://lavag.org/topic/22673-running-zmq-package-on-linux-ubuntu20-c-library-build/#comment-143520
Last edit: Łukasz Kwiatkowski 2023-02-14