This document contains rules useful when you are porting a KDE library to win32. Most of these rules are also valid for porting external libraries code, like application's libraries and even application's private code.
Contents |
Look for '/' and "/" and change every single code like:
if (path[0]=='/')
or:
if (path.startsWith('/'))
with:
if (!QDir::isRelativePath(path))
(or "QDir::isRelativePath(path)" if there was used path[[0]!='/').
Macros for C++ code are defined in qglobal.h file. If you've got included at least one Qt header, you probably have qglobal.h included already, otherwise, include it explicity.
Use
#ifdef Q_WS_X11 ....
for any C++ code that looks like X11-only.
Use
#ifdef Q_OS_UNIX ....
for any C++ code that looks like UNIX-only, for example uses UNIX-specific OS features.
Use
#ifdef Q_WS_WIN ....
for any C++ code that is MSWindows-only.
Note that qglobal.h is C++-only, so instead use
#ifdef _WIN32 ....
for any C code that is MSWindows-only (regardless to compiler type).
#ifdef _MSC_VER ....//msvc code #endif </code> ====MS Visual C++ - Qt code==== <syntaxhighlight lang="cpp"> #ifdef Q_CC_MSVC ....//msvc code #endif </code> ====Borland C++ - Qt-independent code (especially, C code)==== <syntaxhighlight lang="cpp"> #ifdef __BORLANDC__ ....//borland code #endif </code> ====Borland C++ - Qt code==== <syntaxhighlight lang="cpp"> #ifdef Q_CC_BOR ....//borland code #endif </code> ===General notes=== In many places using #ifdef Q_OS_UNIX / #else / #endif is more readable than separate #ifdefs. '''NOTE!!!''' if you must ifdef parts of the code, which contain complete features, please file a bug report against kde-windows target, component porting, in kde's bugzilla, so that those can be fixed later. ===Related links=== * [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/_predir_predefined_macros.asp| msvc++ Predefined Macros] ==Header files== ===Common header file=== Unless there is are any header file from kdelibs included in your header file, you need to add: <code c> #include <kdemacros.h> </code> or <code c> #include <kdecore_export.h> </code> at the beginning of your header file to have some necessary system-independent macros defined. ===Export macros=== For win32 world, symbols are "hidden by default" (not visible by default as e.g. on unix). This has already been [http://lists.kde.org/?l=kde-core-devel&m=105154800130902&w=2|discussed] on the kde mailing list. For every library's code (not for standalone code), you need to make symbols exported for win32. Do this by adding ***_EXPORT macro (win32 export macro) after "class" keyword within any public class (and structure) declaration. You may also decide to put this macro even for non-public class, if you think that the class could be used somewhere outside your library. Example: <syntaxhighlight lang="cpp"> class KDEFOO_EXPORT FooClass { ... }; </code> '''Note''': For kdelibs, ***_EXPORT macros for are defined in kdelibs_export_win.h file (in kdelibs/win/ directory). You can study this file to see how the macros are defined. This file is simply included by kdelibs_export.h, for win32 target. '''Note2''': Recently we're prepared to gcc's export capatibilities, probably in versions newer than 3.4, just like these in win32's msvc compiler. In kdemacros.h file (included by kdelibs_export.h) there are defines prepared for this functionality: <syntaxhighlight lang="cpp"> #define KDE_NO_EXPORT __attribute__ ((visibility("hidden"))) #define KDE_EXPORT __attribute__ ((visibility("default"))) </code> For gcc <= 3.4, KDE_EXPORT and KDE_NO_EXPORT macros are just empty. Note that we're not using KDE_NO_EXPORT for non-public symbols: in the future probably it will be better to use command line switch to turn hidding by default (as win32 compiler has). '''Note3''': *_EXPORT macros depend on MAKE_{LIBRARYNAME}_LIB macro. In KDE4 buildsystem (cmake) the latter is defined automatically by reusing {LIBRARYNAME}, for example MAKE_KATEINTERFACES_LIB is constructed when KATEINTERFACES library is compiled. The logic behind it is implemented in kdelibs/cmake/modules/KDE4Macros.cmake: <syntaxhighlight lang="cpp"> if (WIN32) # for shared libraries/plugins a -DMAKE_target_LIB is required string(TOUPPER ${_target_NAME} _symbol) set(_symbol "MAKE_${_symbol}_LIB") set_target_properties(${_target_NAME} PROPERTIES DEFINE_SYMBOL ${_symbol}) endif (WIN32) </code> ===Exporting global functions=== Also add the same ***_EXPORT at the beginning of public functions' declaration and definition (just before function's type). This also includes functions defined within a namespace. Example: <syntaxhighlight lang="cpp"> namespace Foo { KDEFOO_EXPORT int publicFunction(); } </code> ===What not to export?=== * methods inside classes (no matter static or not) * inline functions * template classes, e.g.: <syntaxhighlight lang="cpp"> template <class T> class KGenericFactoryBase </code> ===Visibility=== There are classes or functions that are made "internal", by design. If you really decided anybody could neven need to link against these classes/functions, you don't need to add **_EXPORT macro for them. ===Deprecated classes=== Before porting KDElibs to win32, I realized that deprecated classes already use KDE_DEPRECATED macro. We're unable to add another macro like this: <syntaxhighlight lang="cpp"> class KDEFOO_EXPORT KDE_DEPRECATED FooClass { //< - bad for moc! ... }; </code> ..because moc'ing will fail for sure. We've defined special macros like that in kdelibs_export.h file (fell free to add your own if needed): <syntaxhighlight lang="cpp"> # ifndef KABC_EXPORT_DEPRECATED # define KABC_EXPORT_DEPRECATED KDE_DEPRECATED KABC_EXPORT # endif </code> So, we have following example of deprecated class: <syntaxhighlight lang="cpp"> class KABC_EXPORT_DEPRECATED FooClass { //<- ok for moc ... }; </code> .. which is ok for __moc__. Note that sometimes KDE_DEPRECATED is also used at the end of functions. You don't need to change it for win32 in any way. ==Loadable KDE modules/plugins== {{TODO|This is deprecated section; we should use K_PLUGIN_FACTORY and K_EXPORT_PLUGIN macros}} ===K_EXPORT_COMPONENT_FACTORY macro=== Use K_EXPORT_COMPONENT_FACTORY( libname, factory ), defined in klibloader.h, instead of hardcoding: <syntaxhighlight lang="cpp"> extern "C" {void *init_libname() { return new factory; } }; </code> ...because the former way is more portable (contains proper export macro, which ensures visiblility of "init_libname" symbol). Examples: <syntaxhighlight lang="cpp"> K_EXPORT_COMPONENT_FACTORY( ktexteditor_insertfile, GenericFactory<InsertFilePlugin>( "ktexteditor_insertfile" ) ) K_EXPORT_COMPONENT_FACTORY( libkatepart, KateFactoryPublic ) </code> ===More complex case=== Sometimes you need to declare a factory which defined as a template with multiple arguments, eg.: <syntaxhighlight lang="cpp"> extern "C" { void* init_resourcecalendarexchange() { return new KRES::PluginFactory<ResourceExchange,ResourceExchangeConfig>(); } } </code> ... but compiler complains about too many arguments passed to K_EXPORT_COMPONENT_FACTORY. To avoid this, you can use __typedef__: <code bash> typedef KRES::PluginFactory<ResourceExchange,ResourceExchangeConfig> MyFactory; K_EXPORT_COMPONENT_FACTORY(resourcecalendarexchange, MyFactory) </code> The same trick can be used if the constructor of the factory takes multiple arguments. ==Application icons== Windows keeps icon data within .exe binaries. For KDE applications use CMake's KDE4_ADD_APP_ICON(appsources pattern) macro in automatically assign to add .png images for .exe files. [[Development/CMake/Addons for KDE#Macros|More information on KDE4_ADD_APP_ICON() macro...]]