Tag Archives: C++

Creating a PHP module with C++.

PHP and C++ are two programming languages.

PHP is normally used as a server side language in web development. It’s interpreted which means that the program is written in plain text and a runtime program interprets it and executes the instructions.

C++ has application in many domains. The program is written also in plain text but a compiler translates it into machine instructions in an executable file in compilation time and it’s that executable file that runs on its own in runtime.

The two languages support Object Oriented Programming paradigm.

One remarkable difference between the two is that C++ can be many fold faster than PHP in the same domain. This doesn’t come free, on the other hand it’s much quicker to program and get something functional in PHP.

PHP is easier to program and to debug and there is no compilation time whereas C++ is all the opposite.

There are scenarios where it’s more convenient to invest time in development to get the most of the machine for various reasons like we have high workloads or because we are getting charged for computing power so we want to reduce the overhead of interpreting the code.

But we don’t need to pick one or the other, we can have both working hand by hand.

If in a PHP development we identify bottle necks we can replace pieces of code for C++.

The way of doing this is by creating a PHP module with an interface that define PHP functions and classes which are actually implemented in C++.
This code will run at full speed in your CPU as it doesn’t need to be interpreted.

In this article I’m going to describe how to prepare the environment to do this in Windows.
I’m going to use XAMP 8.1.12 which brings PHP 8.1.16 64 bits Thread Safe, and Visual Studio 2022.

PHP 8.1.16 in windows is compiled with Visual C and the Platform Tool MSVC 14.29.
This platform tool MSVC 14.29 belongs to Visual Studio 2015 but it’s too old. Instead we are going to install MSVC 14.29 in our Visual Studio 2022. BTW this instructions may work in VS 2017 and VS 2019.

CONFIGURING THE ENVIRONMENT:

So we need to go to the Visual Studio Installer and click on Modify

In the next window we can select one of those MSVCs. As I’m explaining on VS 2022 I’m selecting the highest which is the exact version PHP 8 is compiled with, MSVC 14.29.

We also need to download the headers of PHP.

In https://windows.php.net/download/ search for PHP 8.1 VS16 x64 Thread Safe whose link is this:
https://windows.php.net/downloads/releases/php-devel-pack-8.1.16-Win32-vs16-x64.zip

This zip contains the headers of many PHP libraries and the .lib files for linking in Visual Studio.
So you unzip it somewhere.

Now we create a Visual Studio project. We want a Dynamic library but we can start with an empty project.

In my examples I called the project MyPHPModule.

Now, we need to set the path to the libraries and the Platform Toolset.
We do right click on the project and go to properties.
We make sure that Configuration is set to All Configurations and Platform to x64.

In the Properties window we go to Configuration PropertiesGeneral and in it we set:

Configuration Type as Dynamic Library (.dll)
Platform Toolset as Visual Studio 2019 (v142)

And for the sake of convenience we’ll change the Output Directory for the path to the module folder in our php distribution. In my case it’s C:\xampp\php\ext. So that the library is built right where it’s available for use by PHP.

Now we move to Configuration PropertiesVC++ Directories and in the property Include Directories we set the paths:

php-8.1.16-devel-vs16-x64\include
php-8.1.16-devel-vs16-x64\include\main
php-8.1.16-devel-vs16-x64\include\TSRM
php-8.1.16-devel-vs16-x64\include\win32
php-8.1.16-devel-vs16-x64\include\Zend

Where php-8.1.16-devel-vs16-x64 is the folder were you unzipped the libraries, obviously you need to provide the path to that folder in those 5.

In the property Library Directories we do the same for the path to php-8.1.16-devel-vs16-x64\lib

Now we move to Configuration PropertiesC/C++Preprocessor and in the property Preprocessor Definitions we set the following:

ZEND_DEBUG=0
ZTS=1
ZEND_WIN32
PHP_WIN32

This might be confusing at first. We are compiling for x64 platform but still we need to set the flags ZEND_WIN32 and PHP_WIN32 These _WIN32 only means Windows.

The last configuration now is to move to Configuration PropertiesLinker Input and in the property Additional Dependencies the value php8ts.lib.

Now we are good to go.

PROGRAMMING OUR FIRST MODULE

Now we are going to create a .cpp file. In my case the file MyPHPModule.cpp
My Module is going to have a function that prints “Hello World!!”, a function that takes two params and returns their multiplication, a function that counts up to a given number and a function that takes two arrays and returns an array with the sum of the two value by value.

We first include the PHP library:

#include <php.h>

Now we define the four functions:

PHP_FUNCTION(hello_world) {
	
	ZEND_PARSE_PARAMETERS_NONE();

	php_printf("Hello World!\n");

	RETURN_NULL();
}

PHP_FUNCTION(counting)
{
	zend_long n;

	ZEND_PARSE_PARAMETERS_START(1, 1)
		Z_PARAM_LONG(n)
	ZEND_PARSE_PARAMETERS_END();

	volatile zend_long count = 0;
	for (; count < n; count++);

	RETURN_LONG(count);
}

ZEND_FUNCTION(multiply)
{
	zend_long x, y;

	ZEND_PARSE_PARAMETERS_START(2, 2)
		Z_PARAM_LONG(x)
		Z_PARAM_LONG(y)
	ZEND_PARSE_PARAMETERS_END();

	RETURN_LONG(x * y);
}

PHP_FUNCTION(sum_arrays) {
	
	zval *arr1 = nullptr, *arr2 = nullptr;
	

	//we accept two params and the two are required
	ZEND_PARSE_PARAMETERS_START(2, 2)
		Z_PARAM_ARRAY(arr1) //the param 1 is an array
		Z_PARAM_ARRAY(arr2) //the param 2 is an array
	ZEND_PARSE_PARAMETERS_END();

	std::size_t arr1c = 0, arr2c = 0;
	arr1c = zend_array_count(Z_ARR_P(arr1));
	arr2c = zend_array_count(Z_ARR_P(arr2));

	zend_array *za1 = nullptr, *za2 = nullptr;
	std::size_t siz;

	//if the arra1 is longer than the arra2
	if (arr1c > arr2c) {
		za1 = Z_ARR(*arr1);
		za2 = Z_ARR(*arr2);
		siz = arr2c;
	}
	//if the arra2 is longer than the arra1
	else {
		za1 = Z_ARR(*arr2);
		za2 = Z_ARR(*arr1);
		siz = arr1c;
	}

	//we go through the array
	for (std::size_t index = 0; index < siz; index++) {
		//add the element of arr2 to arra1
		Z_LVAL_P(zend_hash_index_find(za1, index)) += Z_LVAL_P(zend_hash_index_find(za2, index));
	}

	//we return the arra1 with the values added.
	RETVAL_ARR(za1);
}

As you may have noticed we use macros to declare the functions and it’s inside the functions that we extract the parameters with the macros ZEND_PARSE_PARAMETERS_* and Z_PARAM_*.
ZEND_PARSE_PARAMETERS_START accepts two parameters, the first one is minimum number of parameters the function receives, the compulsory ones, and the second number is the max number of params.

It’s not like function prototypes in C or C++. This is because these functions are actually entry points to the module. Parameters and return value enter and leave the module through these functions declared this way. We can either implement the functionality right there or inside another functions called from them.

The prototype of those functions are expressed this way.

//prototype of function hello_world;
ZEND_BEGIN_ARG_INFO(arginfo_hello_world, 0)
ZEND_END_ARG_INFO()

//prototype of function counting;
ZEND_BEGIN_ARG_INFO(arginfo_counting, 0)
	ZEND_ARG_INFO(0, n)
ZEND_END_ARG_INFO()

//prototype of function multiply;
ZEND_BEGIN_ARG_INFO(arginfo_multiply, 0)
	ZEND_ARG_INFO(0, x)
	ZEND_ARG_INFO(0, y)
ZEND_END_ARG_INFO()

//prototype of function sum_arrays;
ZEND_BEGIN_ARG_INFO(arginfo_sum_arrays, 0)
	ZEND_ARG_ARRAY_INFO(0, arr1, 0)
	ZEND_ARG_ARRAY_INFO(0, arr2, 0)
ZEND_END_ARG_INFO()

The macro ZEND_BEGIN_ARG_INFO start variables called arginfo_ and the macro ZEND_ARG_INFO declares each parameter, whether by ref or by value, the name and whether accepts null.

In the following peace of code we gather all the functions and their definitions:

static zend_function_entry hello_world_functions[] = {

	PHP_FE(hello_world, arginfo_hello_world)
	PHP_FE(counting, arginfo_counting)
	PHP_FE(multiply, arginfo_multiply)
	PHP_FE(sum_arrays, arginfo_sum_arrays)
	PHP_FE_END
};

As you can see it’s an array and with the macro PHP_FE we link the function with its arginfo_<function>

We can declared some standard callbacks like PHP_MINFO_FUNCTION:

PHP_MINFO_FUNCTION(hello_world)
{
	php_info_print_table_start();
	php_info_print_table_header(2, "Hello World Module", "enabled");
	php_info_print_table_row(2, "Some parameter", "Some value");
	php_info_print_table_end();
}

which is used to print details about the module when running a phpinfo().

Finally we can put all together with this other structure:


/* Define the module entry */
extern zend_module_entry  hello_world_module_entry = {
	STANDARD_MODULE_HEADER,
	"hello_world",			/* Extension name */
	hello_world_functions,		/* zend_function_entry */
	NULL,				/* PHP_MINIT - Module initialization */
	NULL,				/* PHP_MSHUTDOWN - Module shutdown */
	NULL,				/* PHP_RINIT - Request initialization */
	NULL,				/* PHP_RSHUTDOWN - Request shutdown */
	PHP_MINFO(hello_world),		/* PHP_MINFO - Module info (PHP Info) */
	"1.0",				/* Version */
	STANDARD_MODULE_PROPERTIES
};

And register the module:

ZEND_GET_MODULE(hello_world)

CONFIGURING PHP

Assuming that the module gets compiled in the folder for modules, in my case C:\xampp\php\ext so it’s there, we just need to open the php.ini, in my case in the path C:\xampp\php and add the line:

extension=MyPHPModule.dll

Now, we can test whether the module is there with the next command in command line:

php -m | findstr  hello_world

If present we’ll get hello_world

Another test we can do is to make a .php file with a phpinfo() call:

<?php
phpinfo();

and with the browser explore that file. In my local server is the url http://localhost/MyPHPModule/

PHP will show the details we set in the callback function PHP_MINFO_FUNCTION

If we see either of them the module is correctly set up and we are ready to use in PHP.

PHP TESTS

We can now create a .php file and call the four functions we implemented in C++.

We can start with this little script:

<?php
echo '<pre>';
hello_world();

If we run it with the browser we get a Hello World!

Let’s now try the following test:

 $times = 100000;

$milliseconds = floor(microtime(true) * 1000);

//loop that only counts
for($n = 0; $n < $times ; $n++){
	;
}

$milliseconds = floor(microtime(true) * 1000) - $milliseconds;

echo "PHP loop took milliseconds: $milliseconds\n";

We are going to compare the performance of just counting.
We set the number of times we want to count in the var $times.

Then we capture the timestamp and right after we have a for loop.

After the for loop we get the time again and subtract the time we previously took so that we have the time it took to run the for loop.

Now we can do the same with our function counting():

$milliseconds = floor(microtime(true) * 1000);

//calling our counting function
$count = counting($times);

$milliseconds = floor(microtime(true) * 1000) - $milliseconds;

echo "Our module's loop took milliseconds: $milliseconds\n";

When racing one against the other you will get such result as this:

PHP loop took milliseconds: 7
Our module's loop took milliseconds: 0

you can try with bigger numbers.

The next bit is to test the multiply() function:

//testing our multiply function.
echo '3 * 3 = ' . multiply(3,3) . PHP_EOL;

This function doesn’t actually pose any improvement in performance. It’s just a demonstration of a function that accepts params and returns results.

The last test is our sum_arrays function:

//the first array contains numbers from 0 through 10
$arr = range(0, 10);

//the second array only then 1s
$arr2 = array_fill(0, 10, 1);

//we sum the values of the first and second arrays into a third array;
$arr3 = sum_arrays($arr, $arr2);

print_r($arr3);

In this tests we create two arrays, one has numbers from 0 to 10 and the other only 1s.
The function sums one array to the other element by element.

The this function is nearly 20 times faster than its counterpart in PHP.
We can make it even faster if our module was capable to send those arrays to the GPU and parallelize the calculation.

You can see the potential that moving PHP parts into C++ has.

I hope you enjoy this tutorial.

The rule of five

C++ supports Object Oriented Programming which means that you can express entities with classes and structures (struct) and make instances of them.

These classes group the operations available to work with the data the classes and structs encapsulate.

In a class, data is represented by members which are fields that contain data expressed in their data types and member functions which are the operations on that data.

Classes get constructed and destroy. If the Class is not complex, it only has fields of primitive types and it doesn’t allocate memory in the heap, C++ provides us with implicit constructors and destructors.

These constructors and destructors are methods that are run on construction and destruction respectively.

These methods constructor and destructor are special member functions that call just like the class and in the case of the destructor it’s preceded by the tilde character.

If we ever need to implement one of these methods we must know that we can implement many different constructors but only one destructor.

Constructors can have parameters or not have them at all.

There are 3 types of constructors though.

The first type is a constructor to create an instance out of parameters or without them.

class MyClass
{
public:
	MyClass(){/* your implementation */}

	MyClass(int param1, int param2){/* your implementation */}
}

MyClass my_object(1, 2);

A Second type of constructor is called copy constructor.

class MyClass
{
public:
	MyClass(const MyClass& inst){/* your implementation */}
}

MyClass my_object;


MyClass another_object(my_object);

This is a special type which accepts as only parameter an instance of the same type and it’s mean to copy that object into the object we are instantiating.

The third type is the move constructor.

class MyClass
{
public:
	MyClass(MyClass&& inst){/* your implementation */}
}

MyClass my_object;


MyClass another_object(std::move(my_object));

It’s similar to the copy constructor, it accepts an instance of the same class as only parameter but it uses move semantics and it’s meant to fetch the resources of the instance given and leave it in an empty status.

There are another two special operations or rather operators. One is the copy assignment and the other the move assignment.

Copy assignment is meant to copy the data of an object in an existing object.

class MyClass
{
public:
	MyClass& operator = (const MyClass &) {/* your implementation */}
}

MyClass my_object,  another_object;

my_object = another_object;

Move assignment is like copy, it copies the data of an object in an existing object but it leaves the original object in an empty status.

class MyClass
{

public:
	MyClass& operator = (Class &&) {/* your implementation */}
}

MyClass my_object,  another_object;

my_object = std::move(another_object);

If C++ provides these 5 operations why would we need to have our own?

If you have an object with pointers and you don’t define a copy constructor C++ is going to provide the default copy constructor which only does shallow copies.

A shallow copy is that it will copy the pointers but not the buffers or objects those pointers point to, therefore the new and the old object point to the same resources, and when one of the two instances gets destroyed, most probably it’s going to release those resources and now the other object is going to be pointed unallocated memory.

In that case you need to define your copy constructor and manually copy those resources.

Also if your object holds resources, you need to tell C++ how to release them at the end of life of the object, otherwise they will remain locked and unaccessible and we don’t want that.

Based on the above discussion on what a copy constructor, move constructor, copy assignation, move assignation and destructor are, I’m going to explain the rule of 5.

The rule of 5 dictates that if you need to implement one of the 5 operations, you need to implement the 5 of them.

This is because if you need a destructor because you need to manually release resources, if you copy or move the object you also need to do something about.

Another option is to delete those operations so that you prevent an object from being copied or moved.

class MyClass
{
public:
	MyClass(int param1, int param2){/* your implementation */}

	MyClass(const MyClass& inst) = delete; // deletion of the copy constructor
	MyClass& operator =(const MyClass &) = delete; // deletion of the copy assignment
	MyClass(MyClass&& inst) = delete; // deletion of the move constructor
	MyClass& operator =(MyClass&&) = delete; // deletion of the move assignment
	
	~ MyClass() {/* your implementation */}
}

The point is that you don’t leave the default operation in effect but a customized one or deleted.

I hope it helps.

Recompiling Qt’s driver for MySQL and for MinGW64

I’m currently working on some project developed with the Qt framework.

In this project I need to connect to a MySQL database, but Qt doesn’t include the libraries for licensing problems, so you need to compile them yourself.

In the Qt documentation is told how to do it but I found it inaccurate, and I had to do lots of research to manage and here is how I did it.

I have Qt in the path C:\Qt and the version 6.4.0. you may have other versions though. There are the versions 6.3.2, 6.2.4 or even 5.15.2.
Of whatever version you might have you need also the sources.

In my case the sources are in C:\Qt\6.4.0\Src\

you will also need to download the mysql-connector-c.6.1.11 from https://downloads.mysql.com/archives/c-c/?version=6.1.11&amp;os=src

In the Qt’s documentation they use mysql-8.0.22-winx64. In my example I choose mysql-connector-c-6.1.11-winx64. You can pick the 32 or 64 versions.

It’s important that you download the zip file, and you unzip it in a path without spaces. In my case the path is C:\mysql-connector-c-6.1.11-winx64

If you installed it from the .msi it won’t probably work because it’s in C:\Program Files\MySQL\MySQL Connector C 6.1 which contains spaces.

Now you can go to C:\Qt\6.4.0\Src\qtbase\src\plugins\sqldrivers and create a building folder and configure, build and install the drivers with the following commands:

cd C:\Qt\6.4.0\Src\qtbase\src\plugins\sqldrivers
mkdir build-sqldrivers
cd build-sqldrivers
qt-cmake ^
	-D CMAKE_MAKE_PROGRAM="C:\Qt\Tools\Ninja\ninja.exe" ^
	-G Ninja C:\Qt\6.4.0\Src\qtbase\src\plugins\sqldrivers ^
	-D CMAKE_INSTALL_PREFIX="C:\Qt\6.4.0\mingw_64" ^
	-D MySQL_INCLUDE_DIR="C:\mysql-connector-c-6.1.11-winx64\include" ^
	-D MySQL_LIBRARY="C:\mysql-connector-c-6.1.11-winx64\lib\libmysql.lib"

If all goes well, you will see this screen:

Then you just need to run these two commands:

cmake --build .
cmake --install .

Obviously, you need to set your own paths.

The Qt documentation doesn’t seem to include the param
-D MAKE_MAKE_PROGRAM=”C:\Qt\Tools\Ninja\ninja.exe“.
This is key because otherwise it won’t find the Ninja program.

Once this is done, you need to do something else and that is to copy the file C:\mysql-connector-c-6.1.11-winx64\lib\libmysql.dll either in the folder where you generate your exe or in the path C:\Qt\6.4.0\mingw_64\bin

Also, you need to distribute your app along this file.

I hope it helps.

How to install GLUT in Windows 10.

I was following a tutorial on OpenGL based in GLUT which is an auxiliary library created by Mark Kilgard to create a window in an easy way so that one can focus in learning OpenGL.

GLUT can be found at the URL http://opengl.org/resources/libraries/glut/glut_downloads.php

The problem is that GLUT has been abandoned and the last version runs on Windows XP and it isn’t an open source project either so no one can develop it on.

Fortunately Pawel W. Olszta, Andreas Umbach and Steve Baker developed an Open Source alternative called Free GLUT which is compatible with GLUT and replaces it in modern operating systems.

In this article I’m going to explain how to install it in Code::Blocks and on Windows 10.

The project is hosted at this URL: http://freeglut.sourceforge.net/ where you can download the sources and compile them yourself but it also links to Martin Payne’s web where the library is already compiled and available for MinGW which is Code::Block’s compiler or for Microsoft Visual Studio.

The URL of Martin Payne for the compiled library is https://www.transmissionzero.co.uk/software/freeglut-devel/

We click on the link Download freeglut 3.0.0 for MinGW, it’s a zip file which contains a folder called freeglut. I unzipped it in the path C:\freeglut

At this point you can create a project in Code::Blocks and manually add the pats to the folders include and lib plus the linker flags.

In order to do that we click the right button of the mouse on the project and in the menu we select Build Options… This will open a window.

In this window, in the profile Debug move onto the the tab Search directories and search for the sub tab compiler. In it enter the path C:\freeglut\include

Now move onto the sub tab Linker and add the path to C:\freeglut\lib\x64

Afterwards go to the tab Linker settings which is next to Search directories and inside it there is a vertical textbox titled Other linker Options: and enter the flags: -lfreeglut -lopengl32 -lglu32

To compile in Release you need to do the same setting as for Debug.

Lastly you need to copy the file C:\freeglut\bin\x64\freeglut.dll in the folder with the executable file that it’s created in the paths bin\Debug or bin\Release in your project.

At this stage you can now compile your OpenGL program making use of the auxiliary library FreeGLUT.

You’ll need to do the same configuration every time you start a new project but it doesn’t have to be so.

Code::Blocks has a template out of the box to create GLUT project but this template is broken because it’s designed to do it with the original library which as I said it won’t work in Windows 10.

What we need to do however is to make some changes to generate project that use FreeGLUT.

In order to do that we need fist to edit the file C:\Program Files\CodeBlocks\share\CodeBlocks\templates\glut.cbp with Notepad or any other text editor and replace any occurrence of the word glut32 for freeglut.

Then we go to the file C:\Program Files\CodeBlocks\share\CodeBlocks\templates\wizard\glut\wizard.script and also there we replace all the occurrences of glut32 for freeglut.

Now, if when creating a new project we select GLUT, a wizard will pop up asking things like the project name and the path.

Then it will ask the path to the GLUT library. Here you need to provide the path to the folder C:\freeglut and then finish creating the project.

This Wizard will create a demonstration project which you can compile and run.

I hope you find this tutorial useful.

Google Test with Eclipse and MinGW-W64 from scratch

I was researching how to make unit tests in C++ due to an online course about Google Test.
In the process of installing the environment I found a number of challenges that I had to overcome beyond of what the course taught and I decided that I would be matter for an article.

In this article I’m going to describe how to install Google Test in Eclipse CDT, Git, CMake and MinGW-W64 in Windows from scratch.

Installing Eclipse:

Eclipse is an open source integrated development environment. It’s got a lots of modules to make it suitable to develop in languages like Java, PHP, and many more and of course for C++.

The Eclipse for C++ is called Eclipse CDT which means C/C++ Development Tooling.

One way to obtain CDT is by installing the plug in upon a plain Eclipse.

Eclipse with CDT is also available for download at https://www.eclipse.org/downloads/packages/release/2022-06/r/eclipse-ide-cc-developers

In the download links place you can find the ones for Windows, Linux and Mac OS.

The one I downloaded at the time of this article was: https://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/2022-06/R/eclipse-cpp-2022-06-R-win32-x86_64.zip

You can unzip it wherever you want.

Installing MinGW-W64.

Eclipse on its own it not more than a very sophisticated notepad. It doesn’t include any compiler but it uses any compiler you may have. It could be the one of Visual C, or Clang or like in our case MinGW-W64.

MinGW-W64 is one of several GCC distributions for Windows like Cygwin or MSY2.

The MinGW project is hosted at https://sourceforge.net/projects/mingw-w64/

There is an install wizard with which you can select some aspects like the architectures x86_64 or i686 (64 or 32 bits respectively), or whether whether you want it to simulate the posix interface of the Unix-like operating systems or win32 straight away, and to choose between sjlj, seh and dwarf.
These last three are standards that have to do with the way you want to deal with exceptions but I don’t understand it yet.

Well, the Installer doesn’t work so don’t download it. Instead you want to go to the files section and there you’ll see all the versions available.

As I don’t understand much about the versions available I only download the one I have seen more common and that is x86_64, posix, and she, version 8.1.0 at the moment of this article.

Here is the link to that file: https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/8.1.0/threads-posix/seh/x86_64-8.1.0-release-posix-seh-rt_v6-rev0.7z

We unzip the file. Normally this goes in C:\mingw64 but you can place it wherever you want. Only remember the path.

Inside the folder there is the folder bin. You have to add that folder C:\mingw64\bin in the Windows environment var called PATH so that the executables are all available.

Once added you can go to the command line with Win+R and type cmd and in the console type gcc -v and check that GCC is now available.

Installing CMake

Another tool we need in order to install Google Test is CMake.

When a C or C++ program has more files than the main.c file it is necessary a tool to automatically compile without having to type all the commands and their libraries.

For this purposes the tool Make was invented and is included in almost all compilers.

This tool reads from a file called Makefile where it’s all the instructions to compile your project.

The problem came when projects had to be multiplatform and they had to have different Makefiles for each.

o solve that problem another tool was invented call Configure which automatically assessed your system and what dependences it satisfied and created a tailored Makefile for it which could be used with the Make command.

The problem with this tool is that it’s so versatile and complex that sometimes it’s set up is larger and more complex than the project that we’re trying to compile. Because of this we now have CMake.

CMake is therefore to create the Makefile but in an easy way and it’s the last trend.

CMake is available to download at https://cmake.org/download/ and it’s got an installer in Windows.

When you install it you have to add the path of its executables in the PATH. Presumably in C:\Program Files\CMake\bin

In the command line like we did before we can check that it’s been installed correctly by running the command:

cmake -version

Installing Git

The Google Test project is hosted at github.org and in order to download it we need the program Git which is a control version source software. it’s the most popular.

You can find it at https://git-scm.com/downloads

Once installed, in the command line you can check whether it installed correctly with this command:

git --version

Compiling Google Test

Now we can download the Google Test sources and compile it although it won’t be the last stage in this journey.

You need to find a place to download Google Test. If you opened the Eclipse it probably created a folder in the path: C:\Users\your user\eclipse-workspace. This is a good place to go.
In the folder you choose you have to run the following command:

git clone https://github.com/google/googletest.git

This downloads the source code of Google Test inside the folder googletest therefore let’s go in:

cd googletest

Then we create a fonder inside where we are going to compile the library.
We may use the shell commands like mkdir but CMake provides a shell agnostic command to do it in any operating system.

cmake -E make_directory mingw_build

Now we are going to make use of CMake to compile the project but we aren’t going to run the plain command because by default it will build a project to be compiled by Visual C. Instead we have to pass a number of parameters to tell it to compile with MinGW-W64 therefore we run the following commands:

cmake -E chdir mingw_build cmake -G "MinGW Makefiles" -D CMAKE_C_COMPILER=gcc.exe -D CMAKE_CXX_COMPILER=g++.exe -D CMAKE_MAKE_PROGRAM=mingw32-make.exe ..

The first part tells CMake to work inside the folder mingw_build and to create a project suitable to be compile with MinGW-W64.

Now we build it and installing with this two commands also shell agnostic.

cmake --build mingw_build
cmake --install mingw_build

For the command install you may need Admin privileges because it’s going to install it inside the folder C:/Program Files (x86)

After a while it will have compiled and will be ready to use in our project.

Setting up Eclipse for unit tests.

Eclipse has a plug in with which automatize unit test so let’s install it.
Up in the tool bar, Help, in the option menu we click on Install New Software… A dialogue window opens.
There is a drop down named Working with: Select the repository: 2022-03 – https://download.eclipse.org/releases/2022-03 which is true at the moment of this article.

There is a try underneath, we go to Programming Languages and inside it, C/C++ Unit Testing Support.

This for now, later we will configure our project with it.

Creating a project.

Now we create a new project so we go File → New → C/C++ Project. This opens up a window.

I’d suggest to create it of the type C++ Managed Build. This means that Eclipse is responsible to compile and link automatically.

In the next page in the window we give the project a name and in Project Type we can chose Hello World C++ Project. In the list next to it we can see the toolchains available. We chose MinGW GCC.

Now we should have a project with a sample code with the obligated Hello World.

Now, In the project list of the Project Explorer we click with the right button of the mouse and from the option menu we select properties and a window opens up.

In this window there is a tree on the left side. We go to C/C++ General → Paths and Symbols.
On the right hand of the tree there are several tabs.

We move onto the tab Includes and in the languages list we select GNU C++ and on the right side of it we click on add…

Another dialogue opens up. We now click on File system… and look for a the folder include of Google Test. It would be like this: C:/Program Files (x86)/googletest-distribution/include

Now we move onto the tab Library Paths and in the same way we click on add… In the next dialogue we click on File System… as we did earlier but now we’re looking for the folder C:/Program Files (x86)/googletest-distribution/lib/

Finally we go back to the property tree to C/C++ Build → Settings and in the tab Tool Settings there is another tree. We move onto MinGW C++ Linker → Libraries and on the right side will see two lists, one empty and the other with the path to C:\Program Files (x86)\googletest-distribution\lib that we previously entered.

In the empty list we need to add library twice, and enter gtest and gtest_main as in the image:

Now our project can compile linking the Google Test library.

Adding the test runner.

Now we add the test runner which is for using the unit test plug in that we installed earlier to our Eclipse.

In order to do that we search the tool bar for the button run, but the one with the little arrow pointing down. A menu opens up and from it we click on Run Configurations…
This opens a new window with a tree on the left. In this tree we look for C/C++ unit and with it selected we click the button new on the top of the tree and this will create a new node beneath C/C++ unit.

On the right of the tree we have the name of the test runner.
We can change it if we want. I called mine GTTests Unit Tests.

Bellow it, we have several tabs. let’s go to C/C++ Testing. Here we find a very simple for. it’s got a drop down named Test Runner. We select Google Tests Runner.

Testing it all.

At this point we have everything set up and ready to test that it works.
We go back to our code. We can delete it all and replace it with this other:

#include <iostream>
#include <gtest/gtest.h>

TEST(FooTest, tests_foo){
	ASSERT_TRUE(true);
}

Now we click on the button compile, the one with the hammer.
To run it we can click run.
This renders an output in the console that tells us that it has passed the test, because the test is designed to be passed.
But this is the output that we get when we run the executable as it is.

As now we have a test runner we can select it in the drop down menu beside, in my case I called it GTTests Unit Tests. And now we click on run.
Now what we see is the runner instead of the console with the details in a more friendly format.

Up till now this article. In next articles we’ll immerse ourselves in doing units tests.