In previous tutorial you learned how to develop native packages that depends on other native packages. In this tutorial we will see how a native package can use external packages.

First of all just a precision on terminology:

  • native packages are those implemented using the PID package API. In previous tutorial you defined and used only native packages.
  • external packages are implemented using the PID wrapper API. External packages have not been defined using the PID API but with their own specific build system. They are provided with a description of their content in such a way that they can be used within PID nearly “as if” they were native packages.

Step 1: Define a dependency to an external package

Let’s suppose we want to add an external dependency to the package my-first-package defined in previous tutorials. For instance, we want to use the well known boost filesystem library. boost is a very popular C++ project that provides many facilities to software developpers and it has been “wrapped” into PID.

The first thing to do is to declare boost external project as a dependency of my-first-package. To do this edit the CMakeLists.txt of my-first-package:

cmake_minimum_required(VERSION 3.8.2)
set(WORKSPACE_DIR ${CMAKE_SOURCE_DIR}/../.. CACHE PATH "root of the packages workspace directory")
list(APPEND CMAKE_MODULE_PATH ${WORKSPACE_DIR}/cmake) # using generic scripts/modules of the workspace
include(Package_Definition NO_POLICY_SCOPE)

project(my-first-package)

PID_Package(AUTHOR 		    My Name
			      INSTITUTION	  LIRMM
            YEAR 		      2015
            ADDRESS		    git@gite.lirmm.fr:own/my-first-package.git
            LICENSE 	    CeCILL
            DESCRIPTION   TODO: input a short description of package toto utility here
            VERSION       0.2.0
		)

PID_Dependency(boost)#use any known version of boost

build_PID_Package()

As you may see dependencies to external packages are expressed the same way as for native packages, using the PID_Dependency command. We defined no version to the boost dependency because all recent versions of boost implement filesystem library and it has a very stable API so the code is supposed to be buildable with any version of boost wrapped into PID.

Step 2: Define a dependency to an external component

Now we will modify a bit the behavior of the hello-app application defined in my-first-package in order to make it use boost filesystem library.

2.1 Write the code

First edit the file named hello_main.cpp in apps/hello folder and paste the following code:

#include <hello.h>
#include <iostream>
#include <boost/filesystem.hpp>

using namespace std;
using namespace boost::filesystem;

int main(int argc, char* argv[]){
    if(argc == 1){
	   cout<<"Only one argument ... error !! Please input a string as argument of the program"<<endl;
	   return 1;
    }
    path p(argv[1]);
    std::string str(argv[1]);
    if(! exists(p)){
      str+=" is NOT a valid path !!"
    }
    else{
      str+=" is a valid path !!"
    }
    print_Hello(str);
    return 0;
}

The code now checks if the string passed as argument is a valid path in filesystem and then prints it. To do this, it uses boost filesystem API that is found thanks to #include <boost/filesystem.hpp> procedure.

2.2 Modify the description

So the source code of the application now also depends on boost filesystem library and we need to configure the application adequately. Open the CMakeLists.txt file of the app folder and replace existing description with the following one:

PID_Component(hello-app APP DIRECTORY hello
              DEPEND hello-static boost/boost-filesystem)

Compared to previous version of the code we simply added the dependency boost/boost-filesystem. So the description of dependencies to external components is the same as for native components.

Step 3: Configure, build and run

Now that the source code is ready, let’s build it.

  • configure the package:
cd <my-first-package>/build
cmake ..

This command should deploy the boost package into your workspace (except if already installed). This deployment can lead to an automatic build of the boost project which can take a long time.

  • build the package:
cd <my-first-package>
pid build
  • run hello-app:
cd <my-first-package>/build/release
./hello-app /lib
./hello-app /path/to/nowhere

The output of the command should print something like:

Hello /lib is a valid path !!
Hello /path/to/nowhere is NOT a valid path !!

Step 4: Change dependency version

By default PID should have installed the last available version of boost because there is not version constraint in specification of package dependency. To know which version is used launch the list_dependencies command:

cd <my-first-package>
pid list_dependencies

The output gives you the exact version of boost used by my-first-package. Let’s suppose my-first-package use version 1.64.0 of boost and you want now to change this version to a previous one, let’s say 1.55.0:

cd <my-first-package>/build
ccmake ..

In available user cache entries you should see one called boost_ALTERNATIVE_VERSION_USED whose value should be ANY. Now to change to the version 1.55.0 simply enter this version number instead of ANY and reconfigure (type c then g). This is equivalent to do:

cd <my-first-package>
pid -Dboost_ALTERNATIVE_VERSION_USED=1.55.0

This should again deploy boost but this time the version 1.55.0. Then rebuild and run, you shoud see no difference ! Do:

cd <my-first-package>
pid list_dependencies

The version for dependency boost should have changed and is now 1.55.0.