Listing all header files your cpp depends on

I needed to extract certain Boost headers from its huge code base for memory mapped file & shared memory containers. The first idea came to my mind was a simple grep command for ‘#include’ statements and then parse the paths. This is simple but not so useful for the cases when headers are conditionally included. For example:


#ifndef NO_STL
#include "my_class_no_stl.h"
#else
#include "my_class_stl.h"
#endif

To be honest, grep won’t be able to handle it. We need a full fledged C++ pre-processor to correctly include headers and pass necessary values/definitions (it’s done with -D for g++). I was struggling a bit and got a tip from Ralph. It turned out to be very simple:


g++ -D NO_STL -I A_PATH -M source.cpp # to get all headers, including system headers
g++ -D NO_STL -I A_PATH -MM source.cpp # to get all headers, except system headers
g++ -D NO_STL -I A_PATH -H source.cpp # to print all headers nested in as a tree

Source: http://stackoverflow.com/questions/5834778/g-how-to-tell-where-a-header-file-is-included-from

How I picked up TDD & Google Test in a few hours

TDD Diagram
TDD Diagram

To confess, this is the first time I write unit testing for Java & C++ and it turned out this was rather simple. This weekend Daniel is hosting hackathon at his place and invited Kong & me to come over. The first thing we did was TDD. Daniel was fluent in TDD & pair-programming as his company used Ruby and actively worshiped agile development.

I was given a task: To implement a set data structure in Java as simple as possible to pass the test cases that he would write to challenge the implementation. The first test case was to assert emptiness of a new set via the method `bool isEmpty`. Returning `true` was easy. Then Daniel wrote another task to add a new element and requested the set must return `false`. I added a count & array as private data members. Daniel said I should implement as simple as possible. So I used private one member _isEmpty and set it to `true` by default and `false` when invoking `add(int value)`.

And we went on to add test cases to cover methods `int count()`, `void remove(int value)`, `int getIndexOf(int value)`… I got 2 bugs and JUnit was able to point out which test cases failed and I was able to locate the bugs with ease.

I got excited and then moved to C++ and installed Google Test framework. It was too simple and I regret not using it earlier. Read my TDD C++ code https://github.com/vietlq/cpp/tree/master/tdd_set, you will find it super simple. Here’s the screenshot of the test program:

Passed All Test Cases (Using Google Test)

The real value is seen when refactoring was involved in the process. TDD approach & the written test cases greatly aided me in verifying that code refactoring worked like the old code. When it comes to real life projects with hundeds of modules and millions of lines of code, refactoring without test coverage is like walking into a minefield. If you were diligent enough to write test cases to cover all functions and methods, then you can refactor at will and then run against the accumulated test cases with confidence.

However, one must be clear that test cases guarantee only the cases they cover. Passing the refactored code against the test cases doesn’t guarantee correct outcomes of untested cases. So, be diligent and creative enough to write quality test cases to cover all possible cases to exactly define the behavior of the functions & methods.

Lastly, TDD enforces no optimization. TDD requires you to write simplest possible code to pass all the test cases. Refactor along the way and pass the test cases. Profile when you need performance. That’s not to downplay the importance of throughout & mindful design of algorithms and data structures. One must find a good balance between TDD & efficient implementation that is crafted since the very beginning, not leaving refactoring to the very late stage.

Edit: If the above C++ Set example is oversimplified for you, follow its sibling WordPath https://github.com/vietlq/cpp/tree/master/WordPath

Enabling OpenSSL for Qt C++ on Windows

By default, Nokia Qt does not ship its Qt C++ framework with OpenSSL enabled. This degrades value of the framework and you won’t be able to access HTTPS pages or SSL enabled web services. The examples that require SSL won’t work as well. Take examples\webkit\googlechat for example. This post gives an approach to enable OpenSSL for Qt C++ framework on Windows.

Make sure you have readandbefore proceeding.

  1. Open CMD console & go to the directory C:\Qt\2010.02.1\qt\src\network (given that you have Qt 4.6.2. installed using standard options offered by the installer)
  2. Make sure the directories C:\Qt\2010.02.1\qt\bin and C:\Qt\2010.02.1\mingw\bin are in the environment variable PATH. If you are unsure, enter this command:

set PATH=%PATH%;C:\Qt\2010.02.1\mingw\bin;C:\Qt\2010.02.1\qt\bin;

  1. Configure QtNetwork build using this one-liner:

qmake "PWD=C:\Qt\2010.02.1\qt\src\network" "QMAKE_LIBS_NETWORK = -lws2_32 -lcrypto -leay32 -lssl32 -lssl -lgdi32" "DEFINES += QT_LINKED_OPENSSL" "DEFINES -= QT_NO_SSL"

It’s your responsibility to ensure that OpenSSL is installed and visible to MinGW.

  1. Go ahead with building with this single command:

mingw32-make

Wait for 5-10 mins and you have QtNetwork with OpenSSL enabled. Enjoy!

Installing Qt, QtCreator and MinGW for Windows

Ever thought of developing simple & nice cross-platform applications without sweating? Nokia Qt C++ frameworks empowers you to do so. To get started, first install the Qt SDK with IDE and of course famous GNU compiler chain GCC, branded under MinGW for Windows.

Get the framework, IDE & tool chain from: http://qt.nokia.com/downloads/sdk-windows-cpp

If you are interested in particular parts of MinGW, look here: http://sourceforge.net/projects/mingw/files/

Just follow default steps and you are safe. If you are interested in free M$ C/C++ compiler, just download the Qt source and build it yourself.

Now you are ready to play with magic. To appreciate Qt, run QtDemo and also watch some clips & read some stuff:

http://labs.trolltech.com/blogs/author/qtdeclarative/