Compiling the C++ library with CMake

Compiling the C++ library with CMake

Recently, we have had several customers who decided to compile our C++ library under Linux. This process is documented in the README file and there is a post explaining how to compile the library with the Code::Blocks IDE. However, we hadn't yet documented how to use CMake to compile the library and use it in a program. This week, we are tackling this issue.



Note: we assume that you already have a minimal knowledge of the C++ language and of our programming libraries. If it is not the case, we recommend that you start by reading our post "How to start in C++ with Yoctopuce modules" which explains how our library works.

First of all, a few words on CMake. CMake is neither a compiler nor an IDE, but it is a "tool for managing the build process of software". In other words, the role of CMake is not to actually build the executable, but to prepare a list of commands to be performed to generate the executable. Usually under Linux, one uses CMake to generate a GNU make file which then uses gcc or g++ to compile the source file and to create the executable.

CMake generates makefiles which enable you to compile the application with gcc
CMake generates makefiles which enable you to compile the application with gcc



A CMake project is composed of source files and of one or several CMakeLists.txt files containing the required information to compile the application, such as the location of the source files, the name of the executable, the libraries to be used, and so on.

We could wonder why not using GNU make directly. Indeed, GNU make already enables us to describe the commands to be run to transform a .cpp file into an executable, but its syntax is very complex and becomes almost incomprehensible for large projects. As we are going to see below, the CMake syntax is much simpler, making the life of the developer easier as well.

Moreover, CMake is open source and is available on almost all platforms.

For these reasons, since version 1.10.42060 of our C++ library, we added a CMakeLists.txt file in the Sources subdirectory. This file contains all the compilation rules for our library. To use our C++ library in a CMake project, you only need to include this file and to reference our library with the yoctolib name.

A short example


In order to illustrate what we are saying, we are going to see all the steps to compile the following code:

#include <iostream>
#include "yocto_api.h"

using namespace std;

int main(int argc, const char * argv[])
{
  string      errmsg;

  if(YAPI::RegisterHub("usb", errmsg) != YAPI::SUCCESS) {
    cerr << "RegisterHub error: " << errmsg << endl;
    return 1;
  }

  cout << "Device list: " << endl;
  YModule *module = YModule::FirstModule();
  while (module != NULL) {
    cout << module->get_serialNumber() << " ";
    cout << module->get_productName()  << endl;
    module = module->nextModule();
  }
  YAPI::FreeAPI();
  return 0;
}



This code displays the serial number and the product name of all the Yoctopuce modules connected on the USB ports of the machine. For more information on the functions that are used in this example, you can read the documentation of the C++ library. We save this code in a main.cpp file that we are going to compile.

To compile this code, you must have g++, CMake, and libusb-1.0-dev installed on the machine. On a Debian or Ubuntu based distribution, you can install all these packages with the following commands:

sudo apt-get update sudo apt-get install cmake sudo apt-get install build-essential gdb sudo apt-get install libusb-1.0-0-dev



Then, you must download the Yoctopuce C++ library. You can do so with Git or directly from our web site. The Sources subdirectory contains all the source files to be compiled to use our library, as well as the CMakeLists.txt file which is used by CMake.

Note the path of this directory, because you will need it later on. In our case, the library is unzipped in the /home/yocto/Yoctolib.CPP/ directory and we therefore need the /home/yocto/Yoctolib.CPP/Source path.

The CMakeLists.txt file


Now that we have our main.cpp file and all the dependencies installed on the machine, we can start to write the CMakeLists.txt file for our demo application. As explained above, this file contains all the instructions to compile the application.

We start by checking that the installed version of CMake is recent enough and by giving a name to the project, in our case the project is called "Demo" and we need version 3.16 of CMake.

cmake_minimum_required (VERSION 3.16) project (Demo)



Then, we define the name of the executable and the source files to be compiled. In our case, the name of the executable is demo and there is only one source file: main.cpp. There is no need to add the source files of our C++ library, as we are going to include the CMakeLists.txt file of the library.

add_executable (demo main.cpp)



We are only missing the instructions to include the Yoctopuce C++ library. This task is easy because we already have a CMakeLists.txt file in the Sources subdirectory. This files contains the list of all the files of the library which must be compiled as well as the flags to pass to the compiler or to the linker to generate the executable.

Note: this file is present only since version 1.10.42060 of the library. If it is not present in your version, you must simply use a more recent version of our library.

The add_subdirectory command with the path of the Sources subdirectory of the library enables us to add the library. In our case, the path is /home/yocto/Yoctolib.CPP/Sources/. The second parameter compiled_yoctolib defines a subdirectory that CMake uses to compile the library.

add_subdirectory (/home/yocto/Yoctolib.CPP/Sources/ compiled_yoctolib)



Finally, we must specify that the demo executable uses the Yoctopuce library (Yoctolib).

target_link_libraries (demo LINK_PUBLIC YoctoLib)



Here is the complete CMakeLists.txt file:

# This is a minimal CMakeLists file which includes the Yoctopuce C++ lib.
cmake_minimum_required (VERSION 3.16)
project (Demo)

# Adds the executable called "demo" that is built from the source files "main.cpp".
add_executable (demo main.cpp)

# Adds the Sources subfolder of the Yoctopuce C++ library.
add_subdirectory (/home/yocto/Yoctolib.CPP/Sources/ compiled_yoctolib)

# Links the executable to the Yoctopuce C++ library (YoctoLib).
target_link_libraries (demo LINK_PUBLIC YoctoLib)



Compiling

To generate the compilation files, you must run cmake:

yocto@laptop-linux:~/tmp$ cmake . -- The C compiler identification is GNU 9.3.0 -- The CXX compiler identification is GNU 9.3.0 -- Check for working C compiler: /usr/bin/cc -- Check for working C compiler: /usr/bin/cc -- works -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Detecting C compile features -- Detecting C compile features - done -- Check for working CXX compiler: /usr/bin/c++ -- Check for working CXX compiler: /usr/bin/c++ -- works -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Detecting CXX compile features -- Detecting CXX compile features - done -- Configuring done -- Generating done -- Build files have been written to: /home/yocto/tmp



To actually compile the application, you must use GNU make with the make command:

yocto@laptop-linux:~/tmp$ make Scanning dependencies of target YoctoLib [ 1%] Building CXX object compiled_yoctolib/CMakeFiles/YoctoLib.dir/yocto_accelerometer.cpp.o ... [ 97%] Linking CXX static library libYoctoLib.a [ 97%] Built target YoctoLib Scanning dependencies of target demo [ 98%] Building CXX object CMakeFiles/demo.dir/main.cpp.o [100%] Linking CXX executable demo [100%] Built target demo


There you are! the application is compiled and you can launch it with the ./demo command:

yocto@laptop-linux:~/tmp$ sudo ./demo Device list: YLTCHRL1-CD28D Yocto-LatchedRelay



You can find the source code of this example on GitHub: https://github.com/yoctopuce-examples/cmake_example

Conclusion

CMake is a very handy tool when you code in C++. It is more convivial than GNU make. For comparison purposes, the CMakeLists.txt file of our C++ library is only 14 lines long while the GNU makefile is made of 938 lines...

Add a comment No comment yet Back to blog












Yoctopuce, get your stuff connected.