Opened 18 years ago

Closed 18 years ago

Last modified 18 years ago

#18 closed task (fixed)

Implement new naming scheme for official builds of the Qt DLL

Reported by: dmik Owned by: dmik
Priority: normal Milestone: qt-os2-3.3.1-rc07
Component: [general] Version:
Severity: normal Keywords: DLL naming scheme
Cc:

Description

Currently, the Qt library, when built as a DLL, is named as follows:

qt-mtXYZ.dll

where XYZ is the version number (for example, qt-mt331.dll), and mt stands for multi-threaded (actually this is the only case for OS/2 -- single-threaded applications are nonsence). The same scheme is used in Qt for Windows. In particular, this scheme implies that all intermediate builds of the same release are binary compatible. However, in case of Qt for OS/2 it's usually not the case, because we're constantly adding new (missing) features to the same release of the library.

Therefore, we need another naming scheme that will allow us to differentiate between (most likely) binary incompatible sub-releases (or even bug fixes) of the same Qt release. And even if two sub-releases (or release candidates as we call them) are binary compatible, having different DLL names can still make sence: for some reason, the end user might want to have several Qt versions simultaneously installed on his machine (for example, an application he's using can theoretically require this due to functional differences between releases and such).

Change History (9)

comment:1 Changed 18 years ago by dmik

Status: newassigned

Thinking of a new scheme, we meet one of the oldest limitations of OS/2: DLL names must fit into the 8.3 naming format. Taking this limitation into account I'm going to introduce the following naming scheme:

qtXYZrNN.dll

where XYZ is the version number (three decimal digits) and NN is the sub-release (release candidate) number (two decimal digits, leading zeros are not ommitted). For example, qt331r07.dll.

When two sub-releases are binary compatible (or can be made binary compatible by redirecting changed/removed functions to other functions or stubs), but we still want to boost the sub-release number for some reason, we can simply provide a forwader DLL for an older sub-release (that will have exactly the same name). This will let applications depending on it work with the new release without recompilation and/or loss of functionality.

comment:2 Changed 18 years ago by dmik

Actually, having unique DLL names is necessary not only to differentiate between incompatible releases of Qt for OS/2. Another serious problem is that currently we distrubute the Qt library as the full source package only. This means that everybody who downloads it and builds the Qt DLL can easily get two incompatible versions of the same release (just by disabling some unnecessary components, for example) that will carry identical names (as defined by the release version).

Nothing stops a Qt application developer from supplying his custom Qt DLL with his application that uses it. Another developer can do exactly the same thing (build a custom Qt dll with a different set of components and distribute it with his application). As a result, if we have both applications installed on the same machine, only one of them will work correctly at a given moment of time, because an attempt to load another one will cause the Qt DLL loaded by the first application (which is likely to be incompatibel) to be reused -- so called DLL hell or call it as you like.

comment:3 Changed 18 years ago by dmik

I see the following solutions to the above problem:

  1. Developers and/or end users use a CMD script with SET BEGINLIBPATH=.\. and SET LIPBATHSTRICH=T so that every application will load its own copy of the Qt DLL no matter if another copy (located in the different application directory) is already loaded or not. I don't like this idea because using scripts to launch PM applications seems stupid to me (requires an (at least temporary) extra CMD process and doesn't properly integrate with WPS).
  2. We manually load the Qt DLL at application startup using DosLoadModule() with the full path or after issuing DosSetExtLIBPATH('T', LIBPATHSTRICT) for the current process. This idea seems attractive, since it solves both the 8.3 DLL name limitation problem and the DLL hell problem, but it's not that easy. I know how to manually resolve all exported functions in a manner transparent for the application (by a cost of a single long jump CPU instruction per every Qt library call), but I don't yet know what to do with data segments.
  3. We do the following things:
    1. Start to distribute a binary package of the Qt library that will be called an official binary build and will always include all the features/components currently available. The Qt DLL in this package will carry the release version in its name to distinguish between (possibly binary incompatible) releases. This official build will be recommended as a peferred way to develop applications that want to use the DLL version of the Qt library.
    2. Adjust the library build procedure so that when the Qt DLL is built by a developer directly using the source distribution package, he is asked (from the configure.cmd script) to provide a custom name for the DLL that will definitely not match the naming scheme of the official binary distribution.

comment:4 Changed 18 years ago by dmik

I'm going to select the third approach. The DLL in the official binary build will have the following scheme:

qtXYZNN.dll

where XYZ is the release version and NN is the sub-release version. We will use a special flag to indicate the DLL being built is for the official binary distribution.

In all other cases a user supplied name will be used for the Qt DLL (something like myqt.dll). The static library in any case will use the current naming scheme (i.e. qt.lib) because it cannot produce any naming conflicts.

comment:5 Changed 18 years ago by dmik

As it said above we will not differentiate between single-threaded and multithreaded builds. The official distribution, will never contain a single-threaded version of the library. What about custom builds, differentiating between them makes sense only if the user wants to use both single-threaded and multi-threaded versions of the library simultaneously from the same Qt installation directory (for example, for different projects). I believe this is a rare case, even theoretically. And when necessary, the user can simply run configure to switch to the single-threaded version and back (since object files are always created in separate directories for all release/debug/singe/multi/static/shared combinations, this will only recreate the library itself, no full recompilation is necessary).

Instead, the official binary distribution will provide simultaneous usage of the following library versions from the same installation directory (w/o running configure, but using the appropriate flags release/debug and shared/static) in the CONFIG statement of the project file):

  • Static Release
  • Static Debug
  • DLL Release
  • DLL Debug.

Probably, the custom build will provide just the same thing. Anyway, differentiating between release/debug or between static/DLL is more useful than between single-/multi-threaded.

comment:6 Changed 18 years ago by anonymous

The new naming scheme (qtXYZNN.dll) including the custom Qt DLL name for non-official builds has been implemented.

Also, having four build types (static/dllrelease/debug) in the same installation directory has also been done. When generating a Makefile from the qmake project file containing qt in the CONFIG statement, the GNUMAKE backend tries to select a build of the Qt library corresponding to appropriate CONFIG flags, as follows:

  • When debug is present in CONFIG, the path to the debug version of the Qt library goes before the path to the release version. This way, the debug version will be choosen (if built), otherwise the release version will be used. When debug is not present, the release build takes precedence over the debug one in the similar way.
  • When shared is present in CONFIG, the application will be linked against the DLL version of Qt (release or debug as described above, so either of them must be built -- the static Qt library will not be taken into account). Otherwise, it is linked against the static Qt library (again, release or debug as described above).

The next thing to do is to modify configure.cmd further so that it is possible to build the Qt library separately from anything else (uic and other tools) after changing the build type. Note, that during the build of the new type of the Qt library the moc tool will be always recompiled (and thus replaced in the /bin subdirectory) using the current setup (i.e. debug or release). This is because moc is necessary for building the library and thus there is a strict dependency in the Makefile.

comment:7 Changed 18 years ago by anonymous

Well, the said about moc is not fully correct -- it is always built in the release mode, because the CONFIG variable is overriden in its .pro file so it doesn't contain the debug keyword even if the Qt library has been configured for the debug mode. However, moc is always rebult from scratch after switching the build type of Qt with configure.cmd because its Makefile is regenerated in this case.

comment:8 Changed 18 years ago by dmik

Resolution: fixed
Status: assignedclosed

The separate 'Qt Library only' compile option is done. Everything should now work as described above.

comment:9 Changed 18 years ago by dmik

A little addition to the naming scheme. It's now:

qtXYZNNc.dll

where c is either nothing (for for officially released versions) or some char (currently 'a') to indicate this is a development build (for example, from the SVN repo). The version number format (stored in the DLL description) becomes:

X.Y.Z.N.Nc

This will let us strictly differentiate between released builds (those without c) and all other ones.

The policy of adding the c symbol is as follows: right after releasing version X.Y.X.N.N, the NN number is increased by one and 'a' is appended. When this new version is ready for releasing, 'a' is removed and everything repeats from the beginning.

Note: See TracTickets for help on using tickets.