Welcome to the docs on developing and building from source. If you spot any problems, please open an issue.
The library consists of two main components - a binary shared library file (.dll or .so) which does the heavy lifting and then a lightweight LabVIEW wrapper.
The majority of changes to the library features, functionality or bug fixes will require being able to build the library from source we will start there.
-
LabVIEW Real-Time Module
-
An NI-Linux-RT Virtual Machine (Recommended)
-
Oracle Virtual Box Users can follow Edward Jones’s video: https://www.youtube.com/watch?v=s15gM5b635M
-
VMware Users can follow Sam Taggart’s guide: https://www.sasworkshops.com/how-to-create-a-crio-virtual-machine/
-
-
Microsoft Visual C++ Tools 2019 (
mingwcould work but not setup or tested)-
Install with Microsoft Visual Studio 2019 or standalone Build Tools For Visual Studio
-
-
Docker - setup to use Linux Containers if Linux builds are also required
-
GNU build tools for your distribution(
gcc,g++etc) NOTE: there is no tooling provided to build the Windows binaries on Linux
-
Visual Studio Code with the following Extensions (Recommended)
Currently, the tooling provided is only aimed at Windows-based development (why not submit an issue to discuss this changing).
The tooling comes in two parts
-
Build Scripts which will install dependencies, build the code and install it into the correct location for the LabVIEW code.
-
Example VSCode configuration files to allow for building and debugging from within VSCode.
|
Warning
|
All the tooling and scripts assume the that vcpkg is installed in C:\src\vcpkg
|
If your system setup differs then please duplicate the build scripts, modify the variables defined at the top of each file and situate them alongside the existing build scripts.
You are now ready to build the library binaries so can jump ahead to the next section if you do not want to setup the VSCode Environment.
If you want to install the VScode configuration files, copy the .vscode-example to a top level folder called .vscode. If you already have custom files in the .vscode then you will have to manually merge them.
This should leave you with a root directory structure as follows;
-
📁.vscode
copied from .vscode-example, potentially modified -
📁.vscode-example
-
📁C++
-
📁docker-nilrt-build
-
📁src
-
📄 CMakeLists.txt
-
📄 vcpkg.json
-
📄 x64-nilrt-build.bat
-
📄 x64-win-build.bat
-
📄 x86-win-build.bat
-
📄 x86-my-custom-build.bat
copied from x86-win-build.bat and modified if required
-
-
📁docs
-
📁LabVIEW
-
📄 .gitignore
-
<other files>
You are so close to some binary goodness assuming you have installed and setup the required prerequisites.
Complete your journey as follows:
-
Ensure that your vcpkg install is up-to-date by performing a
git pulland.\bootstrap-vcpkg.batfrom thevcpkgdirectory (typicallyC:\src\vcpkg). -
Close LabVIEW 2020 if it is open otherwise it might prevent the installation of the binary into the
LabVIEWdirectory. -
Call the build script you need e.g.
C++/x86-win-build.bat. If you need aDebugbuild useC++/x86-win-build.bat debug. -
Wait while the dependency build process and source build completes (this may take many minutes! ☕⌚)
-
Check the
/LabVIEW/serenial.io-ase/for the shared library files,/LabVIEW/test-binariesfor the test application executable and/LabVIEW/packagesif creating the Linux binaries.
The majority of development work with this library is based around creating the shared library binaries written in C++ with cross-platform build support provided by CMake. Docker is used to provide a more portable build-system when building the binaries for Linux on a Windows machine.
The LabVIEW code consists of a wrapper around the binary and some unit tests of the library’s API.
Development of the LabVIEW code does not require any special experience but a good understanding of User Events and Data Value References will be beneficial.
Development of the C++ code will require understanding of pointers, classes, mutexes, lamdas, threads and futures & promises.
The library centres on the cross-platform boost::process::child class from the boost c++ libraries. This class allows for a child process to be spawned that can call an executable and provide standard-out and standard-err redirection to custom handlers.
These custom handlers can send data back to LabVIEW using User Events and the LVPostUserEvent() function provided by C-based LabVIEW’s Memory Manager library.
As LabVIEW provides a limited number of threads, any long-running shared-library calls can easily block other operations. To avoid this, a number of non-LabVIEW managed threads are used - primarily to run the boost::asio::io_context which runs an event loop that hosts the standard-out/err handlers but also to handle polling-with-timeout calls without blocking LabVIEW.
The C++ code has been designed to minimize complexity at the expense of testability. Unfortunately this means more debugging is required when adding features but avoids the addition of a handler abstraction layers.
Thread safety is implemented where resources may be contested in the C++ code but it is assumed that the order of some shared library calls is managed by a DVR on the LabVIEW side. This allows for the shared library calls to use any LabVIEW thread so multiple instances of a Asynchronous System Exec can run without blocking each other.
The following overview provides useful information before diving into development of the library:
The project file structure is split between C++ development and LabVIEW development. The outputs from the C++ build are installed into the LabVIEW library directory to (hopefully) make LabVIEW more likely to find the binaries on different systems.
The CMakeLists.txt file handles builds for different targets. All binaries are built with a static-runtime/standard-libs to provide greater compatibility on different platforms and different Linux distributions.
The configuration flags for vcpkg in the CMakeLists.txt must occur before the project declaration. This means that the normal system type detection routines are unavailable but detection of 32 or 64 bit Windows system should be OK given the restriction to the MSVC compiler.
The .vscode-example configuration includes settings to facilitate building with VSCode’s CMake Tools extension.
==== Debugging
The .vscode-example configuration includes tools that allow for VSCode to connect to the debugging interface that the LabVIEW executable process exposes. Ensure that the binaries have been built with debugging symbols, that you have placed break-points in the C++ code and that the required LabVIEW code you are wish to run is open, then click on the Run >> Start Debugging in VSCode and run the VIs in LabVIEW.
Building the Linux binaries and NI-Linux-RT package is achieved using Docker. This creates an CentOS 8 image that meets the system requirements and uses the NI provided cross-compilation tools to perform a build. The creation of this image will take considerable time due to the need to build boost for cross-compilation.
A copy of LabVIEW’s c-integration headers are required for the Linux build which can be provided by mounting the <Path to LabVIEW 2020 Directory>/cintools from the local (Windows) LabVIEW install into the running container. The C++/x64_nilrt-build.bat file sets up the directory mounts when running the container and is the preferred method to perform the build.
If there are errors with the build then adding the line bash into the /C++/docker-nilrt-build/build-and-package.sh before the statement that errors can help. This will provide an interactive command line interface into the running container (but without any script environment settings) which can be handy for debugging the build script.
The CLFNs of the LabVIEW library are contained within a conditional disable structure. The default case uses explicit paths which means that LabVIEW will manage the shared-library binary as a dependency when it comes to building executables and packed-project-libraries. This make life easier for library users but can confuse LabVIEW. In addition, shared-library path wildcards are used to so LabVIEW will automatically pick up the correct 32/64 bit shared-library and choose .dll on Windows and .so on Linux.
This can cause problems with LabVIEW’s path resolution and you may have to change a CLFN to point to an explicit file path. A tool is provided in the LabVIEW project’s utilities folder which uses scripting to reset all the relevant CLFNs to the wildcard path name.
The other case of the conditional disable structure provides support for NI-Linux-RT targets but uses an supplied library path to point to the shared-library that will have been installed using opkg on the Real-Time Target. The use of a supplied path here prevents LabVIEW trying to search for the Linux Real-Time binary when opening the project on Windows.
-
A rewrite of dependency walker on GitHub to check what resources a DLL requires
-
ldcommand on Linux - useful to check for missing resources on Linux Systems For NI-Linux-RT installbinutilswithopkgto installld.