In this tutorial we propose a guideline to port existing binary code into PID. First of all, as far as possible you should always try to work with open source code, because it allows PID to generate binary archives for target platforms which is far more convenient. Anyway sometimes you have no other choice than using precompiled binaries.

First of all when you want to port an existing binary project you will have to write a wrapper. So please have first a look at this tutorial that explains how a wrapper can build an external project in order to integrate it into PID.

Now the difference is that there is no more build process since we have only precompiled binaries. We choose to wrap the Vimba external project. Vimba is a SDK developped by Allied Vision Technology used to manage their cameras. The code is available only under binary format.

Step 1: Identify and download the version of the external project

Before beginning to work you have to identify which version of the project you want to wrap. Indeed binary archives reflect predefined versions of the project build for predefined platforms.

For the example we look at AVT website and chose the last available version that was 2.1.3 at that time. We follow the download link to download the binary archive of this version for linux platforms.

Put this archive somewhere, the path to the folder containing the archive is supposed to be /path/to/archive/. Then extract the archive:

cd /path/to/archive/
tar xvf Vimba_v2.1.3_Linux.tgz
cd Vimba_2_1
ls

You see now the content of the archive, it will ne useful in later part of the tutorial.

Step 2: Create the wrapper

  • In your git hosting solution, create a git repository for the PID wrapper of vimba you will develop for the example binary package. Copy its address, then:
cd <pid-workspace>
pid create wrapper=vimba url=<url previously copied>
cd <pid-workspace>/wrappers/vimba
  • Now simply choose the version you want to port and create adequate foldes in the wrapper. At the time this tutorial has been written we choose to wrap the version 2.1.3 of Vimba:
cd <vimba>/src
mkdir 2.1.3
touch 2.1.3/CMakeLists.txt
touch 2.1.3/install.cmake
  • Copy the downloaded archive into the version folder
cp /path/to/archive/Vimba_v2.1.3_Linux.tgz <vimba>/src/2.1.3

This is a good solution to directly embbed the archive since private companies provide most of time only the latest version and not a complete history of versions. So it is preferable to keep your own copy of the archive because it is not sure you will be able to access it again in the future. If no more available then your wrapper becomes (at least partly) obsolete. By putting the archive directly into the wrapper you keep in memory all versions you wrapped.

  • Then edit the root CMakeLists.txt of vimba:
cmake_minimum_required(VERSION 3.8.2)
set(WORKSPACE_DIR ${CMAKE_SOURCE_DIR}/../.. CACHE PATH "root of the PID workspace")
list(APPEND CMAKE_MODULE_PATH ${WORKSPACE_DIR}/cmake) # using generic scripts/modules of the workspace
include(Wrapper_Definition NO_POLICY_SCOPE)

project(vimba)

PID_Wrapper(AUTHOR          Robin Passama
		        INSTITUTION		  CNRS/LIRMM
		        MAIL 			      passama@lirmm.fr
            ADDRESS         git@gite.lirmm.fr:rob-vision-devices/vimba.git
            PUBLIC_ADDRESS  https://gite.lirmm.fr/rob-vision-devices/vimba.git
			      YEAR 		        2019
			      LICENSE 	      GNULGPL
			      DESCRIPTION 	  "PID wrapper for the vimba project, developped by Allied Vision Technology company. Provides API to interface with various cameras from AVT."
		)

PID_Original_Project(
		AUTHORS "Allied Vision Technology Gmbh"
		LICENSES "Allied Vision Technology license for Vimba"
		URL https://www.alliedvision.com)

build_PID_Wrapper()

Simply set the information relative to the authors (name, institution, mail) and about original project. Also you can provide a public address for the wrapper so that anyone can clone it whithout having an account in your git hosting solution. Your online repository for vimba should have a public visibility (clonable by anyone) to make then possible to anyone to use your wrapper.

Step 3: Analyse the content of binary archive

3.1: identify the components

Now its time to look a bit more the binary archive Vimba_v2.1.3_Linux.tgz. Open it with an archive manager to see its content.

What you have to deduce is:

  • what are the components (libraries and applications) ?
  • what are the dependencies between these components ?
  • what are the dependencies between these components and other projects ?

In archive Vimba_v2.1.3_Linux.tgz we found interesting documentation in Vimba_2_1/Documentation/Vimba_Manual.pdf:

  • vimba provides 2 base libraries used to interface AVT cameras: one “low-level” C library and one “higher-level” C++ library.
  • it also provides a utility library for image processing (named “image transform library”).
  • 3 applications are provided: the vimba viewer a GUI tool to access and configure cameras, the firmware updater and a class generator. Most useful tools are the viewer and the firmware updater.

3.2: identify the dependencies of libraries

Now we have to find the dependencies. To do this we need to analyze the binaries. From documentation we know that VimbaCPP library uses the VimbaC library so the first library to analyse is VimbaC. We are working on a 64 bit station so we will analyse 64 bits version of VimbaC:

cd /path/to/archive/Vimba_2_1/VimbaC/DynamicLib/x86_64bit
ldd libVimbaC.so

The output should be something like:

linux-vdso.so.1 =>  (0x00007ffc4b1b1000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fb0bf033000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fb0bee2f000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fb0bec27000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fb0be8a5000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fb0be59c000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fb0be386000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fb0bdfbc000)
/lib64/ld-linux-x86-64.so.2 (0x00007fb0bf522000)

We can deduce that VimbaC has no complex dependencies, it only uses standard libraries. To know its direct dependencies:

cd /path/to/archive/Vimba_2_1/VimbaC/DynamicLib/x86_64bit
readelf -d libVimbaC.so

The output should be something like:

0x0000000000000001 (NEEDED)             Bibliothèque partagée: [libpthread.so.0]
0x0000000000000001 (NEEDED)             Bibliothèque partagée: [libdl.so.2]
0x0000000000000001 (NEEDED)             Bibliothèque partagée: [librt.so.1]
0x0000000000000001 (NEEDED)             Bibliothèque partagée: [libstdc++.so.6]
0x0000000000000001 (NEEDED)             Bibliothèque partagée: [libm.so.6]
0x0000000000000001 (NEEDED)             Bibliothèque partagée: [libgcc_s.so.1]
0x0000000000000001 (NEEDED)             Bibliothèque partagée: [libc.so.6]

We deduce that the library directly needs posix libraries like pthread or dl. So we know that VimbaC requires the posix configuration.

Now we can do the same with VimbaCPP:

cd /path/to/archive/Vimba_2_1/VimbaCPP/DynamicLib/x86_64bit
readelf -d libVimbaCPP.so

The output should be something like:

0x0000000000000001 (NEEDED)             Bibliothèque partagée: [libVimbaC.so]
0x0000000000000001 (NEEDED)             Bibliothèque partagée: [libpthread.so.0]
0x0000000000000001 (NEEDED)             Bibliothèque partagée: [libstdc++.so.6]
0x0000000000000001 (NEEDED)             Bibliothèque partagée: [libm.so.6]
0x0000000000000001 (NEEDED)             Bibliothèque partagée: [libgcc_s.so.1]
0x0000000000000001 (NEEDED)             Bibliothèque partagée: [libc.so.6]
0x000000000000000f (RPATH)              Bibliothèque rpath: [$ORIGIN]
...

We deduce that VimbaCPP depends on VimbaC, which was explained in documentation. Furthermore we now that VimbaCPP also directly requires the posix configuration. We need a bit more details about this dependency. Indeed we need to know if VimbaCPP exports VimbaC or not because it has side effects on the way a project using Vimba libraries has to be built. To know if something is exported we need to see if any header of VimbaCPP include an header of VimbaC.

1) First have a look at VimbaC headers

cd /path/to/archive/Vimba_2_1/VimbaC/Include
ls

There are only 2 files: VimbaC.h and VmbCommonTypes.h. This will simplify a lot the search.

2) Now see if any header include VimbaC.h or VmbCommonTypes.h

cd /path/to/archive/Vimba_2_1/VimbaCPP/Include
grep -nr "VimbaC.h" .

We simply search for the string VimbaC.h in the folder containing headers of VimbaCPP library. The output should be:

./Feature.h:37:#include <VimbaC/Include/VimbaC.h>
./Interface.h:31:#include <VimbaC/Include/VimbaC.h>
./ICameraFactory.h:31:#include <VimbaC/Include/VimbaC.h>
./VimbaSystem.h:33:#include <VimbaC/Include/VimbaC.h>
./Frame.h:31:#include <VimbaC/Include/VimbaC.h>
./EnumEntry.h:38:#include <VimbaC/Include/VimbaC.h>
./Camera.h:34:#include <VimbaC/Include/VimbaC.h>

So we immediately deduce that VimbaCPP exports VimbaC.

We can also see that in the code of Feature.h the headers of VimbaC should be installed in path <included folder>/VimbaC/Include/ with <included folder> the path to the folder where to find headers of VimbaC. In same header Feature.h we see that the headers of VimbaCPP follows same pattern for inclusion of its headers (<included folder>/VimbaCPP/Include/).

Finally do the same for VimbaImageTransform library:

cd /path/to/archive/Vimba_2_1/VimbaImageTransform/DynamicLib/x86_64bit
readelf -d libVimbaImageTransform.so

The output should be something like:

0x0000000000000001 (NEEDED)             Bibliothèque partagée: [librt.so.1]
0x0000000000000001 (NEEDED)             Bibliothèque partagée: [libpthread.so.0]
0x0000000000000001 (NEEDED)             Bibliothèque partagée: [libstdc++.so.6]
0x0000000000000001 (NEEDED)             Bibliothèque partagée: [libm.so.6]
0x0000000000000001 (NEEDED)             Bibliothèque partagée: [libgcc_s.so.1]
0x0000000000000001 (NEEDED)             Bibliothèque partagée: [libc.so.6]
...

So we deduce that this library has no dependncy either to VimbaCPP and VimbaC and also requires the posix configuration.

3.3: identify the dependencies of applications

We start with the viewer application:

cd /path/to/archive/Vimba_2_1/Tools/Viewer/Bin/x86_64bit
ldd VimbaViewer

The output should be something like:

linux-vdso.so.1 =>  (0x00007fffb5fc8000)
libVimbaCPP.so => /home/robin/soft/tier/Vimba_2_1/Tools/Viewer/Bin/x86_64bit/./libVimbaCPP.so (0x00007f6a14c3f000)
libVimbaImageTransform.so => /home/robin/soft/tier/Vimba_2_1/Tools/Viewer/Bin/x86_64bit/./libVimbaImageTransform.so (0x00007f6a14945000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f6a1473d000)
libQtCore.so.4 => /home/robin/soft/tier/Vimba_2_1/Tools/Viewer/Bin/x86_64bit/./libQtCore.so.4 (0x00007f6a14229000)
libQtGui.so.4 => /home/robin/soft/tier/Vimba_2_1/Tools/Viewer/Bin/x86_64bit/./libQtGui.so.4 (0x00007f6a134d0000)
libQtSvg.so.4 => /home/robin/soft/tier/Vimba_2_1/Tools/Viewer/Bin/x86_64bit/./libQtSvg.so.4 (0x00007f6a13273000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f6a12ef1000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f6a12be8000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f6a129d2000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f6a12608000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f6a123eb000)
libVimbaC.so => /home/robin/soft/tier/Vimba_2_1/Tools/Viewer/Bin/x86_64bit/./libVimbaC.so (0x00007f6a12119000)
libfontconfig.so.1 => /usr/lib/x86_64-linux-gnu/libfontconfig.so.1 (0x00007f6a11ed6000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f6a11cd2000)
/lib64/ld-linux-x86-64.so.2 (0x00007f6a14e92000)
libfreetype.so.6 => /usr/lib/x86_64-linux-gnu/libfreetype.so.6 (0x00007f6a11a28000)
libSM.so.6 => /usr/lib/x86_64-linux-gnu/libSM.so.6 (0x00007f6a11820000)
libICE.so.6 => /usr/lib/x86_64-linux-gnu/libICE.so.6 (0x00007f6a11606000)
libXrender.so.1 => /usr/lib/x86_64-linux-gnu/libXrender.so.1 (0x00007f6a113fc000)
libXext.so.6 => /usr/lib/x86_64-linux-gnu/libXext.so.6 (0x00007f6a111ea000)
libX11.so.6 => /usr/lib/x86_64-linux-gnu/libX11.so.6 (0x00007f6a10eb0000)
libexpat.so.1 => /lib/x86_64-linux-gnu/libexpat.so.1 (0x00007f6a10c87000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f6a10a6d000)
libpng12.so.0 => /lib/x86_64-linux-gnu/libpng12.so.0 (0x00007f6a10848000)
libuuid.so.1 => /lib/x86_64-linux-gnu/libuuid.so.1 (0x00007f6a10643000)
libxcb.so.1 => /usr/lib/x86_64-linux-gnu/libxcb.so.1 (0x00007f6a10421000)
libXau.so.6 => /usr/lib/x86_64-linux-gnu/libXau.so.6 (0x00007f6a1021d000)
libXdmcp.so.6 => /usr/lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007f6a10017000)

We can see that all runtime dependencies are resolved even if the viewer tool is not installed in default path of the system. This is explained by the fact that all its runtime dependencies are put directly into the folder : either VimbaImageTransform, VimbaCPP and VimbaC but also QT libraries used to design the GUI.

By doing:

cd /path/to/archive/Vimba_2_1/Tools/Viewer/Bin/x86_64bit
readelf -d VimbaViewer

The output should be something like:

0x0000000000000001 (NEEDED)             Bibliothèque partagée: [libVimbaCPP.so]
0x0000000000000001 (NEEDED)             Bibliothèque partagée: [libVimbaImageTransform.so]
0x0000000000000001 (NEEDED)             Bibliothèque partagée: [librt.so.1]
0x0000000000000001 (NEEDED)             Bibliothèque partagée: [libQtCore.so.4]
0x0000000000000001 (NEEDED)             Bibliothèque partagée: [libQtGui.so.4]
0x0000000000000001 (NEEDED)             Bibliothèque partagée: [libQtSvg.so.4]
0x0000000000000001 (NEEDED)             Bibliothèque partagée: [libstdc++.so.6]
0x0000000000000001 (NEEDED)             Bibliothèque partagée: [libm.so.6]
0x0000000000000001 (NEEDED)             Bibliothèque partagée: [libgcc_s.so.1]
0x0000000000000001 (NEEDED)             Bibliothèque partagée: [libc.so.6]
0x0000000000000001 (NEEDED)             Bibliothèque partagée: [libpthread.so.0]
0x000000000000000f (RPATH)              Bibliothèque rpath: [$ORIGIN]
0x000000000000000c (INIT)               0x42c620
...

We deduce that VimbaViewer directly depends on VimbaImageTransform and VimbaCPP and requires the posix configuration. Also we now that if we simply copy the content of /path/to/archive/Vimba_2_1/Tools/Viewer/Bin/x86_64bit into the binary package generated by vimba wrapper, the application will be functionnal. Indeed the executable have a specific RPATH that is set to $ORIGIN meaning that every shared object in the same folder than the executable can be automatically found at runtime.

Exactly the same pattern has been used for all tools provided by the vimba poject so we do not develop them.

Step 4: Describe content of the wrapper

Now we have a more precise understanding of the external project content, we can start writing the wrapper. Edit the file src/2.1.3/CMakeLists.txt.

  • Define the version and its required configurations:
PID_Wrapper_Version(VERSION 2.1.3 DEPLOY install.cmake)
PID_Wrapper_Configuration(CONFIGURATION posix)

The deploy script that is referenced is named install.cmake, it must match the script file with same name in src/2.1.3.

From analysis of dependencies we know that all components require posix libraries to be available, so we scpecify the corresponding platform configuration constraint using PID_Wrapper_Configuration.

  • Define the components and their dependencies:
PID_Wrapper_Version(VERSION 2.1.3 DEPLOY install.cmake)
PID_Wrapper_Configuration(CONFIGURATION posix)

PID_Wrapper_Component(vimba-c INCLUDES include SHARED_LINKS lib/libVimbaC)

PID_Wrapper_Component(vimba-cpp INCLUDES include SHARED_LINKS lib/libVimbaCPP
                      EXPORT vimba-c)

PID_Wrapper_Component(vimba-image-transform INCLUDES include SHARED_LINKS lib/libVimbaImageTransform)

So We simply describe with PID API the relatioships analyzed at previous step: 3 libraries called vimba-c, vimba-cpp and vimba-image-transform with only dependency being vimba-cpp exporting vimba-c.

We decided :

  • that the install folder of vimba will contain an include folder that will itself contain VimbaC, VimbaCPP and VimbaImageTransform subfolders (where to find headers of libraries).
  • that binaries of libraries will all be put into a lib folder.
  • to avoid defining applications explicitly because the provided tools do not need extra configuration to bind them with installed library (they have their own copy of their required libraries). Furthermore there are few chances that these tools will be used by third party programs (they are end users tools with GUI) so they do not really need to be described in PID.

Step 5: Write the install procedure

Now we have to describe the install procedure for the binary archive in install.cmake. To achieve this we mainly use basic CMake commands:

message("[PID] extracting the archive Vimba_v2.1.3_Linux.tgz")

if(CURRENT_PLATFORM_OS STREQUAL linux AND CURRENT_PLATFORM_TYPE STREQUAL x86)
  execute_process(COMMAND ${CMAKE_COMMAND} -E tar xv ${TARGET_SOURCE_DIR}/Vimba_v2.1.3_Linux.tgz WORKING_DIRECTORY ${TARGET_BUILD_DIR})
#do the same for other available archives
else()
  message("[PID] ERROR : during install of vimba version 2.1.3, no known archive")
  set(ERROR_IN_SCRIPT TRUE)
  return()
endif()

set(PATH_TO_VIMBA_INPUT ${TARGET_BUILD_DIR}/Vimba_2_1)

message("[PID] prepare install...")
if(EXISTS ${TARGET_INSTALL_DIR}/include)
  file(REMOVE ${TARGET_INSTALL_DIR}/include)
endif()
file(MAKE_DIRECTORY ${TARGET_INSTALL_DIR}/include)

if(EXISTS ${TARGET_INSTALL_DIR}/lib)
  file(REMOVE ${TARGET_INSTALL_DIR}/lib)
endif()
file(MAKE_DIRECTORY ${TARGET_INSTALL_DIR}/lib)

if(EXISTS ${TARGET_INSTALL_DIR}/bin)
  file(REMOVE ${TARGET_INSTALL_DIR}/bin)
endif()
file(MAKE_DIRECTORY ${TARGET_INSTALL_DIR}/bin)

# copy binary files to destination
message("[PID] copying binary files...")

if(CURRENT_PLATFORM_ARCH STREQUAL 64)
  #copying libraries
  file(COPY ${PATH_TO_VIMBA_INPUT}/VimbaC/DynamicLib/x86_64bit/libVimbaC.so ${PATH_TO_VIMBA_INPUT}/VimbaC/DynamicLib/x86_64bit/VimbaC.xml DESTINATION ${TARGET_INSTALL_DIR}/lib NO_SOURCE_PERMISSIONS)
  file(COPY ${PATH_TO_VIMBA_INPUT}/VimbaCPP/DynamicLib/x86_64bit/libVimbaCPP.so DESTINATION ${TARGET_INSTALL_DIR}/lib NO_SOURCE_PERMISSIONS)
  file(COPY ${PATH_TO_VIMBA_INPUT}/VimbaImageTransform/DynamicLib/x86_64bit/libVimbaImageTransform.so DESTINATION ${TARGET_INSTALL_DIR}/lib NO_SOURCE_PERMISSIONS)
  file(COPY ${PATH_TO_VIMBA_INPUT}/VimbaImageTransform/DynamicLib/x86_64bit/OpenMP DESTINATION ${TARGET_INSTALL_DIR}/lib NO_SOURCE_PERMISSIONS)

  #copying tools
  file(COPY ${PATH_TO_VIMBA_INPUT}/Tools/FirmwareUpdater/Bin/x86_64bit/ DESTINATION ${TARGET_INSTALL_DIR}/bin/FirmwareUpdater)
  file(COPY ${PATH_TO_VIMBA_INPUT}/Tools/Viewer/Bin/x86_64bit/ DESTINATION ${TARGET_INSTALL_DIR}/bin/Viewer)
  file(COPY ${PATH_TO_VIMBA_INPUT}/Tools/VimbaClassGenerator/Bin/x86_64bit/ DESTINATION ${TARGET_INSTALL_DIR}/bin/VimbaClassGenerator)

elseif(CURRENT_PLATFORM_ARCH STREQUAL 32)
  #copying libraries
  file(COPY ${PATH_TO_VIMBA_INPUT}/VimbaC/DynamicLib/x86_32bit/libVimbaC.so ${PATH_TO_VIMBA_INPUT}/VimbaC/DynamicLib/x86_32bit/VimbaC.xml DESTINATION ${TARGET_INSTALL_DIR}/lib NO_SOURCE_PERMISSIONS)
  file(COPY ${PATH_TO_VIMBA_INPUT}/VimbaCPP/DynamicLib/x86_32bit/libVimbaCPP.so DESTINATION ${TARGET_INSTALL_DIR}/lib NO_SOURCE_PERMISSIONS)
  file(COPY ${PATH_TO_VIMBA_INPUT}/VimbaImageTransform/DynamicLib/x86_32bit/libVimbaImageTransform.so DESTINATION ${TARGET_INSTALL_DIR}/lib NO_SOURCE_PERMISSIONS)
  file(COPY ${PATH_TO_VIMBA_INPUT}/VimbaImageTransform/DynamicLib/x86_32bit/OpenMP DESTINATION ${TARGET_INSTALL_DIR}/lib NO_SOURCE_PERMISSIONS)

  #copying tools
  file(COPY ${PATH_TO_VIMBA_INPUT}/Tools/FirmwareUpdater/Bin/x86_32bit/ DESTINATION ${TARGET_INSTALL_DIR}/bin/FirmwareUpdater)
  file(COPY ${PATH_TO_VIMBA_INPUT}/Tools/Viewer/Bin/x86_32bit/ DESTINATION ${TARGET_INSTALL_DIR}/bin/Viewer)
  file(COPY ${PATH_TO_VIMBA_INPUT}/Tools/VimbaClassGenerator/Bin/x86_32bit/ DESTINATION ${TARGET_INSTALL_DIR}/bin/VimbaClassGenerator)

else()
  message("[PID] ERROR : during install of vimba version 2.1.3 nbinaries do not support platform with ${CURRENT_PLATFORM_ARCH} bits processors.")
  set(ERROR_IN_SCRIPT TRUE)
  return()
endif()

#copying headers
file(COPY ${PATH_TO_VIMBA_INPUT}/VimbaC/Include DESTINATION ${TARGET_INSTALL_DIR}/include/VimbaC)
file(COPY ${PATH_TO_VIMBA_INPUT}/VimbaCPP/Include DESTINATION ${TARGET_INSTALL_DIR}/include/VimbaCPP)
file(COPY ${PATH_TO_VIMBA_INPUT}/VimbaImageTransform/Include DESTINATION ${TARGET_INSTALL_DIR}/include/VimbaImageTransform)

message("[PID] install done ...")
  • The script first extracts the archive in the build folder in order to be able to directly manipulate its elements. The extraction procedure is conditionate by the target platform. For now there is only one archive containing binaries for linux x86 platforms that is registered into the wrapper. But we may add more archives to manage more platforms (for instance 32 and 64 bits arm processors) in the future. Furthermore we need to detect if the wrapper cannot install binaries for a given platform. That is why all operations should be guarded with if calls taking current platform information as condition.
  • Then it cleans the install folder before reinstalling.
  • Finally it copies binary files and headers at previously defined places. As you may notice we take care to copy adequate binary in adequate places depending on the target processor architecture (if(CURRENT_PLATFORM_ARCH STREQUAL 32) ...).

Step 6: Install the version

As usual do:

cd <vimba>
pid build version=2.1.3

Build should be successful if you run it on a x86 linux platform and fail otherwise. If it succeeded you should see the result in <pid-workspace>/install/<platform>/vimba/2.1.3.

Your wrapper is now functional. But there is still something missing.

Step 7: add a custom install procedure

Indeed, in order for Vimba to work correctly it needs to detect cameras when they are connected to the PC. To do this the vimba provides some extra install scripts used to configure the system to be able to detect those devices (these install scripts are provided in VimbaGigETL and VimbaUSBTL in the original project).

This could be done directly in install.cmake script but then this configuration would be done only once when the wrapper is build and not anytime the external package needs to be reconfigured for any reason. The best thing to do would be to automatically configure the system anytime required even if the external package is already installed in the workspace (possibly long time after it has been built from the vimba wrapper).

  • First thing to do to delay the execution of configuration scripts provided by the original Vimba project is to copy them in the install tree when the wrapper is built. So in install.cmake we add few lines at the end to put configuration scripts and data in the share folder in install tree:
...
file(COPY ${PATH_TO_VIMBA_INPUT}/VimbaImageTransform/Include DESTINATION ${TARGET_INSTALL_DIR}/include/VimbaImageTransform)

message("[PID] copying hardware configuration scripts ...")

file(COPY ${PATH_TO_VIMBA_INPUT}/VimbaGigETL DESTINATION ${TARGET_INSTALL_DIR}/share/VimbaGigETL)
file(COPY ${PATH_TO_VIMBA_INPUT}/VimbaUSBTL DESTINATION ${TARGET_INSTALL_DIR}/share/VimbaUSBTL)

message("[PID] install done ...")
  • Second we need to define how to call those scripts to be executed at post-install time. To do this we need to modify a bit the description of the version:
PID_Wrapper_Version(VERSION 2.1.3 DEPLOY install.cmake POSTINSTALL configure.cmake)
... #same as previously

We use the POSTINSTALL argument of PID_Wrapper_Version to give the path to a cmake script that implements the configuration of operating system using scripts provided by Vimba. The script will be copied in install tree and automatically executed anytime needed.

  • Third we then have to create and write the configure.cmake script, basically something like:
execute_process(COMMAND sudo sh ./Install.sh
WORKING_DIRECTORY ${WORKSPACE_DIR}/install/${CURRENT_PLATFORM}/vimba/${vimba_VERSION_STRING}/share/VimbaUSBTL)

execute_process(COMMAND sudo sh ./Install.sh
  WORKING_DIRECTORY ${WORKSPACE_DIR}/install/${CURRENT_PLATFORM}/vimba/${vimba_VERSION_STRING}/share/VimbaGigETL)

The post install script simply call configuration script provided by the Vimba project, using those present in the install tree. Launch again the build command: the end of the output should look like this:

...
[PID] INFO : performing post install operations from file /home/robin/soft/PID/pid-workspace/wrappers/vimba/../../install/x86_64_linux_stdc++11/vimba/2.1.3/share/configure.cmake ...
Registering GENICAM_GENTL32_PATH
Registering GENICAM_GENTL64_PATH
Registering VimbaUSBTL device types
Done
Please reboot before using the USB transport layer
Registering GENICAM_GENTL32_PATH
Registering GENICAM_GENTL64_PATH
Done
Please log off once before using the GigE transport layer
[PID] INFO : external package vimba version 2.1.3 built.
Built target build

These last lines come from the install scripts provided by AVT.

That’s it you have finished writing the wrapper for vimba version 2.1.3. For adding more version simply repeat the same protocol !