-
-
Notifications
You must be signed in to change notification settings - Fork 2
Developers
This section contains information related to developing Qt on OS/2.
The original Qt source code is hosted in a number of git repositories with URLs like git://code.qt.io/qt/PROJECT.git
where PROJECT is one of numerous Qt modules (qt5
, qtbase
etc). The web interface for these repositories is available at http://code.qt.io/cgit/qt/.
While it was technically possible to mirror these git repositories (via upstream remotes) in our own repositories at GitHub and perform OS/2 development on dedicated branches, we decided not to do so. Mostly because the original Qt history is huge and the Qt team generates too many new commits every day. Having it all in our repositories would drag too much attention from the OS/2 development and occupy additional hard disk space for nothing. Instead, we will create a clean repository for each Qt module that we decide to work on and use a method of "squashing" all intermediate commits between import points into a new one which is then pushed to our repository on a special branch named vendor
. Import points are usually official Qt releases (originally tagged as vX.Y.Z
where X.Y.Z is the released Qt version number).
The vendor
branch then becomes a starting point and a future merge source for the master
branch where all OS/2 development takes place. Once a new Qt release is imported into vendor
(as a single "squashed" commit tagged as vX.Y.Z
for convenience), it is then merged to master
once we decide to move all our OS/2 work to a new version and start working on it. This scheme is flexible enough and also allows to support the development (maintenance) of several OS/2 versions of Qt independently by creating branches from master
which are to be named X.Y[.Z]
according to their start point.
Once a new OS/2 release of Qt is out, it is tagged as vX.Y.Z-os2[-NNN]
where X.Y.Z is the Qt version number this release is based on. The optional NNN
part names an OS/2-specific release of a given Qt version. There may be multiple OS/2 releases of the same Qt version because we try to provide new OS/2 releases as soon as we can and don't wait until all features of a particular Qt version are implemented on OS/2. For this reason, our release cycle will most likely not match the Qt release cycle. For beta releases, NNN
is usually bN
where N is a sequential number of a beta release.
Let's assume the Qt module name is PROJECT and the starting point for the OS/2 work is vX.Y.Z. The main trick here is to use git reset
to squash all commits into one (we cannot use git merge --squash
here as it won't work for empty repositories without any commits). Note that we could also unpack the original tarball here and add everything to our repository with git add .
, but this is not as good as git reset
(or as git merge --sauash
if we could do it) because some information is lost when creating tarballs out of git repositories. For example, we would lose original commits recoded for git submodules (if there are any) as well as all files marked with a git-ignore
attribute in .gitattributes
(there might be a plenty). Using git reset
ensures all this information is preserved in our squashed commit.
- Create an empty repository at GitHub named
PROJECT-os2
and clone it locally - Link it to the Qt repository:
git remote add upstream git://code.qt.io/qt/PROJECT.git
- List original tags matching vX.Y.Z:
git ls-remote --tags upstream | grep vX.Y.Z
- Inspect the output and record the original commit NNNN matching vX.Y.Z
- Fetch upstream commits up to and including NNNN w/o tags (to avoid name clashes):
git fetch upstream --depth=1 --no-tags NNNN
(note that NNNN must be a full hex commit name) - Check out commit NNNN to the index and working tree (will also change HEAD):
git reset --hard NNNN
- Drop HEAD to make the repository empty again (w/o commits):
git update-ref -d HEAD
- Create the initial commit:
git commit
- Use the following commit message (replace X.Y.Z, PROJECT and NNNN with real values):
vendor: Import vX.Y.Z.
Source URL: git://code.qt.io/qt/PROJECT.git
Source Commit: NNNN
- Tag the result:
git tag vX.Y.Z
- Push it to GitHub:
git push && git push --tags
- Create a vendor branch:
git branch vendor
- Push it to GitHub:
git push -u origin vendor
This is similar to adding a new repository but there are a few differences. Note that we cannot use git merge --squash
here as well, because it can only squash from the beginning of the history while we need the previous import as a starting point. Therefore we have to use the git reset
trick again. Let's assume that you have our GitHub repository PROJECT-os2
already checked out and upstream
that points to the original PROJECT repository is already set up.
- Switch to the vendor branch:
git checkout vendor && git pull
- List original tags matching vX.Y.Z:
git ls-remote --tags upstream | grep vX.Y.Z
- Inspect the output and record the original commit NNNN matching vX.Y.Z
- Fetch upstream commits up to and including NNNN w/o tags (to avoid name clashes):
git fetch upstream --depth=1 --no-tags NNNN
(note that NNNN must be a full hex commit name) - Check out commit NNNN to the index and working tree (will also change HEAD):
git reset --hard NNNN
- Reset HEAD back to what it was before (to restore our history):
git reset --soft ORIG_HEAD
- Commit the result:
git commit
- Use the following commit message (replace X.Y.Z, PROJECT and NNNN with real values):
vendor: Import vX.Y.Z.
Source URL: git://code.qt.io/qt/PROJECT.git
Source Commit: NNNN
- Tag the result:
git tag vX.Y.Z
- Push it to GitHub:
git push && git push --tags
- Switch back to master (if needed):
git checkout master
If you also want to merge the new upstream version to the master branch, then also do the following (assumes the master branch):
- Pull the latest master changes:
git pull
- Create a branch for the previous version (for hot fixes & back-ports):
git branch X'.Y'.Z'
- Merge everything since last time it was done:
git merge vendor --no-commit
- Fix conflicts (if any) and commit the result:
git commit
- Use the following commit message (replace X.Y.Z with real values):
Merge vendor vX.Y.Z.
Conflicts resolved:
....
(conflicting file listing from the standard merge message, if any)
- Push it to GitHub:
git push
- Push the previous version's branch to GitHub:
git push -u origin X'.Y'.Z'
The original instructions for building Qt 5 from the Git repository are located here. They are, for the most part, applicable to OS/2 as well so read them first. Below is a typical list of steps that takes OS/2 specifics into account.
- Install mandatory packages:
yum install dash-sh gcc gcc-wlink gcc-wrc make perl git gawk libc-devel libcx-devel
- Install packages necessary to auto-enable common Qt features:
yum install zlib-devel libicu-devel libjpeg-devel libpng-devel freetype-devel fontconfig-devel openssl-devel cups-devel sqlite-devel
- Clone the repository:
git clone https://github.com/bitwiseworks/qt5-os2.git qt5
- Go to the cloned directory:
cd qt5
- Initialize the submodules:
sh init-repository-os2.sh [--branch]
The--branch
option is only necessary if you are a developer who intends to push submodule commits to their respective branches from.gitmodules
. - Create a shadow build directory:
cd ..; mkdir qt5-dev-build; cd qt5-dev-build
- Configure the build (from the shadow build directory):
sh ../qt5/configure -developer-build -opensource -confirm-license -force-debug-info -nomake examples -nomake tests -no-opengl -system-sqlite -openssl-linked
The-developer-build
option will enable the debug build by default and will generate more debug data. The two-nomake
options will save some time by not building examples and tests. The-sqlite
option is needed to enable using system-provided SQLite3 DLLs. The-no-opengl
option disables the OpenGL support and is a must for now (see https://github.com/bitwiseworks/qtbase-os2/issues/12 for details). - Make it:
make -jN all
(whereN
is the number of CPUs on your machine).
Note that by default Qt will be configured in debug_and_release
mode with optimized_tools
and debug
being the default build mode when make
is run w/o explicit targets. debug_and_release
means that both debug and release builds will co-exist in the same build tree. optimized_tools
builds qmake
, rcc
and some other tools in release
mode by default. This creates some non-obvious problems when building. E.g. running just make
will fail when building uic
and friends if the release DLLs are missing. Running make debug
will succeed here but will fail with some tests since there are single mode tests that don't have debug
or release
targets. Therefore, the only safe way to go in such a configuration is make all
which will build everything, including both release and debug (meaning it will take approximately two times longer).
As an alternative, Qt may be configured for either release or debug with -release
or -debug
configure options, respectively. Also, optimized tools may be disabled with -optimized-tools=no
. In such a case, make
without targets will work fine. It is, however, recommended to have both debug and release builds for debugging purposes.
Qt 5 comes with the built-in logging facility available to applications (see QLoggingCategory
, qCDebug
and friends). The logging facility groups log messages into user-defined categories and assigns them one of predefined severity levels (debug, info, warning, critical and fatal) using respective qCXxx
calls. The default message handler prints log messages to the console. The user may control which severity levels for which categories are enabled using the environment QT_LOGGING_RULES
variable which has a very simple syntax: a semicolon separated list of <category_name>[.<level>]=true|false
entries. Category names may contain an asterisk to perform wildcard matching: E.g.
QT_LOGGING_RULES="*.debug=false;my.category.debug=true"
This logging facility is used by various parts of Qt itself to provide means to debug it. This kind of logging is usually available both in release and debug builds of Qt but the debug
severity level is usually disabled by default and needs to be explicitly enabled using QT_LOGGING_RULES
. A good start is just to set a detailed message format and enable everything to be logged, like this:
QT_MESSAGE_PATTERN="[%{pid}-%{threadid}:%{time HH:mm:ss.zzz}] %{function}:%{line}:${category}: %{message}"
QT_LOGGING_RULES="*=true"
Then you may disable categories and levels you don't need with a more specific QT_LOGGING_RULES
setting.
The OS/2 code in Qt also employs this technique. However, due to the lack of the trace severity level in Qt, we use the debug level to log very frequent messages (e.g. PM message flow) and the info level for less verbose messages (which are still useful only for debugging). For this reason, we disable both debug
and info
levels for our categories by default and they need to be explicitly enabled to become visible. The OS/2 code defines the following categories:
Category | Purpose |
---|---|
qt.core.events | General Qt event flow (only in debug level) |
qt.qpa.windows | PM window creation and management (debug is not currently used) |
qt.qpa.backingstore | Raster window composition details, debug enables PNG creation for each paint event |
qt.qpa.events | Qt event flow for PM windows, debug enables frequent events like paint, resize, mouse and keyboard |
qt.qpa.messages | PM message flow (only in debug level) |