Saturday, October 27, 2012

Building On Windows With Qt

In order to build the program (that now requires Qt), CMake needs to be able to find the Qt files.  It accomplishes this by looking for the Qmake executable (qmake.exe on Windows) even if it is not actually used, but its location is used to determine where Qt is installed.  To find the Qmake executable, CMake searches the directories in the execution path.

On Linux, the qmake executable is already in the standard directories.  On Windows, the directory for qmake.exe needs to be added to the execution path.  The instructions for adding a directory to the execution path was given in the post on October 20.  The directory C:\QtSDK\Desktop\Qt\4.8.1\mingw\bin needs to be added.  If using the MSYS command line, the directory /c/QtSDK/Desktop/Qt/4.8.1/mingw/bin needs to be added to the path (see post on October 7).

QtCreator can be used to access the git repository (see post on October 20).  To switch to the latest development branch (branch0.2 at the time of this post), the branch needs to retrieved from the repository on GitHub.  On the Tools menu, select Git and then Pull.  Only local branches can be checked out, so a local branch needs to be created.  On the Tools menu, select Git and then Branches....  Select branch0.2 under origin and click the Add... button.  Click OK on the next Dialog.  This will create local branch0.2, which can now be selected and checked out with the Checkout button.  Select Close to dismiss the Branches dialog.

To build, first select Run CMake on the Build menu and make sure the Generator is set to MinGW Generator (MinGW (x86 32bit)).  Now click the Run CMake button.  As mentioned previously, sometimes a bunch of errors occur the first time.  Trying a second time causes no errors.  If at any time there are problems running CMake, deleted every file in the qtcreator-build and try again.

There is a problem in running the regtest script in Windows XP when the build directory is under the current user directory under the C:\Documents and Settings\ directory.  The problem occurs because there are spaces in the directory name, which causes bash to incorrectly process the line.  There is no problem on Windows 7 because the user directories are under the C:\Users\ directory (which has no spaces).  There is also no problem if the build directory is under the user home directory within MSYS (again no spaces).  As for regtest.bat, this batch file requires the build to be performed in the source directory.  Also note that the new memory test script is not available on Windows.

Qt Transition – Translator RPN List

Before embarking on the memory issues, the Qt Transition was started by changing all List to QList and changing all the access functions accordingly.  However, that was going to take while, so those changes were abandoned to start a new approach in only changing one list at a time, and running the new memory test script after each.  This started with the Translator's RPN output list.

Wow, what a learning experience.  One nice feature of the current List class was being to obtain a  pointer to a particular element in the list.  Since the underlining code was implemented as a linked list, the element pointer could be used to access elements previous and following the element.  Though admittedly, the syntax for these element pointers was rather involved and therefore confusing.

The QList class has several ways to access the elements including by index (something List was not capable of) and with iterators (similar to but not the same as the pointers to list elements).  In the Translator, the list element pointer was used in several places, which to modified to use QList.

1. The done stack used to hold pointers to tokens added the output list, which are used when processing operators and functions when checking data types of the operands and arguments.  The done stack actually contained pointers to the output list elements (of RPN items containing the token).  There was no reason to have a pointer to the list element here, so it was changed to just point to the RPN item.

2. The RPN item structure contained an array of list element pointers for each of the operands of the token.  Operands are only kept for identifiers with a parentheses token (until it is determine whether it is an array of function), defined functions with parentheses token (needed to check with the functions arguments), and string operator tokens (until it is determine whether the operands are temporary or not).  There was no reason for these pointers to point to list elements, so the array was changed to an array of RPN item pointers.

3. The command stack used to hold the current command contained a pointer to a list element.  Currently, the INPUT command handler uses this pointer to insert tokens into the output list.  Several unsuccessful attempts were made to use Qt iterators for this pointer, but this only caused weird memory issues to be reported by valgrind (though the code appeared to work).  In the end, an index into the output list was used since QList items can be accessed by index.  In one location of the code, an iterator was used to access the last element in the list, and if a hidden token, stepped back to the previous element.  An iterator worked here because it did not require saving the iterator value and trying to use it later, which appears to cause problems.

One List to QList change is complete; now on to the rest.  The CMakeLists.txt file was also modified to support building with Qt, which involved finding the Qt package and added the Qt libraries to the executable (this works on Linux, but Windows requires some additional steps before it can be compiled).

[commit 34cbd66cd9]