Windows/Porting Guidelines: Difference between revisions
*>Ananth123 m KDE on Windows/Porting Guidelines |
m Ochurlaud moved page Windows/Imported From TechBase/Porting Guidelines to Windows/Porting Guidelines |
||
(21 intermediate revisions by 9 users not shown) | |||
Line 1: | Line 1: | ||
This document contains rules useful when you | 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. | ||
==Before you start== | ==Before you start== | ||
* Make sure (ask KDElibs/win32 maintainer) that the library you selected for porting is not ported, but just not | * Make sure (ask KDElibs/win32 maintainer) that the library you selected for porting is not ported, but just not committed yet. | ||
* You can ask maintainer for proposals, what can be useful for porting. | * You can ask the maintainer for proposals, what can be useful for porting. | ||
* You will need KDE | * You will need KDE svn account for your work. | ||
* Download most current (HEAD) of the KDE libraries. | * Download most current (HEAD) of the KDE libraries. | ||
==Absolute | ==Absolute directory checking== | ||
Look for '/' and "/" and change every single code like: | Look for '/' and "/" and change every single code like: | ||
< | <syntaxhighlight lang="c"> | ||
if (path[0]=='/') | if (path[0]=='/') | ||
</ | </syntaxhighlight> | ||
or: | or: | ||
< | <syntaxhighlight lang="cpp-qt"> | ||
if (path.startsWith('/')) | if (path.startsWith('/')) | ||
</ | </syntaxhighlight> | ||
with: | with: | ||
< | <syntaxhighlight lang="cpp-qt"> | ||
if (!QDir::isRelativePath(path)) | if (!QDir::isRelativePath(path)) | ||
</ | </syntaxhighlight> | ||
(or "QDir::isRelativePath(path)" if there was used path[[0]!='/') | (or "QDir::isRelativePath(path)" if there was used path[[0]!='/'). | ||
==Ifdefs== | ==Ifdefs== | ||
Line 33: | Line 33: | ||
Use | Use | ||
< | <syntaxhighlight lang="c"> | ||
#ifdef Q_WS_X11 | #ifdef Q_WS_X11 | ||
.... | .... | ||
#endif | |||
</ | </syntaxhighlight> | ||
for any C++ code that looks like X11-only. | for any C++ code that looks like X11-only. | ||
Use | Use | ||
< | <syntaxhighlight lang="c"> | ||
#ifdef Q_OS_UNIX | #ifdef Q_OS_UNIX | ||
.... | .... | ||
#endif | |||
</ | </syntaxhighlight> | ||
for any C++ code that looks like UNIX-only, for example uses UNIX-specific OS features. | for any C++ code that looks like UNIX-only, for example uses UNIX-specific OS features. | ||
Use | Use | ||
< | <syntaxhighlight lang="c"> | ||
#ifdef Q_WS_WIN | #ifdef Q_WS_WIN | ||
.... | .... | ||
#endif | |||
</ | </syntaxhighlight> | ||
for any C++ code that is MSWindows-only. | for any C++ code that is MSWindows-only. | ||
===C code=== | ===C code=== | ||
Note that qglobal.h is C++-only, so instead use | Note that qglobal.h is C++-only, so instead use | ||
< | <syntaxhighlight lang="c"> | ||
#ifdef | #ifdef _WIN32 | ||
.... | .... | ||
#endif | |||
</ | </syntaxhighlight> | ||
for any C code that is MSWindows-only (regardless to compiler type | for any C code that is MSWindows-only (regardless to compiler type). | ||
=== Rare cases: How to check in Windows-only code which compiler is used?=== | === Rare cases: How to check in Windows-only code which compiler is used?=== | ||
====MS Visual C++ - Qt-independent code (especially, C code)==== | ====MS Visual C++ - Qt-independent code (especially, C code)==== | ||
< | <syntaxhighlight lang="cpp"> | ||
#ifdef _MSC_VER | #ifdef _MSC_VER | ||
....//msvc code | ....//msvc code | ||
#endif | |||
</ | </syntaxhighlight> | ||
====MS Visual C++ - Qt code==== | ====MS Visual C++ - Qt code==== | ||
< | <syntaxhighlight lang="cpp"> | ||
#ifdef Q_CC_MSVC | #ifdef Q_CC_MSVC | ||
....//msvc code | ....//msvc code | ||
#endif | |||
</ | </syntaxhighlight> | ||
====Borland C++ - Qt-independent code (especially, C code)==== | ====Borland C++ - Qt-independent code (especially, C code)==== | ||
< | <syntaxhighlight lang="cpp"> | ||
#ifdef __BORLANDC__ | #ifdef __BORLANDC__ | ||
....//borland code | ....//borland code | ||
#endif | |||
</ | </syntaxhighlight> | ||
====Borland C++ - Qt code==== | ====Borland C++ - Qt code==== | ||
< | <syntaxhighlight lang="cpp"> | ||
#ifdef Q_CC_BOR | #ifdef Q_CC_BOR | ||
....//borland code | ....//borland code | ||
#endif | |||
</ | </syntaxhighlight> | ||
===General notes=== | ===General notes=== | ||
In many places using #ifdef Q_OS_UNIX / #else / #endif is more readable than separate #ifdefs. | 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=== | ===Related links=== | ||
Line 104: | Line 106: | ||
==Header files== | ==Header files== | ||
===Common header file=== | ===Common header file=== | ||
Unless there is are any header file from kdelibs included in your header file, you need to add: | |||
your header file, you need to add: | <syntaxhighlight lang="c"> | ||
< | #include <kdemacros.h> | ||
#include < | </syntaxhighlight> | ||
</ | or | ||
<syntaxhighlight lang="c"> | |||
#include <kdecore_export.h> | |||
</syntaxhighlight> | |||
at the beginning of your header file to have some necessary system-independent macros defined. | at the beginning of your header file to have some necessary system-independent macros defined. | ||
Line 119: | Line 124: | ||
Example: | Example: | ||
< | <syntaxhighlight lang="cpp"> | ||
class KDEFOO_EXPORT FooClass { | class KDEFOO_EXPORT FooClass { | ||
... | ... | ||
}; | }; | ||
</ | </syntaxhighlight> | ||
'''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. | '''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. | ||
Line 129: | Line 134: | ||
'''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: | '''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_NO_EXPORT __attribute__ ((visibility("hidden"))) | ||
#define KDE_EXPORT __attribute__ ((visibility("default"))) | #define KDE_EXPORT __attribute__ ((visibility("default"))) | ||
</ | </syntaxhighlight> | ||
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). | 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: | '''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) | if (WIN32) | ||
# for shared libraries/plugins a -DMAKE_target_LIB is required | # for shared libraries/plugins a -DMAKE_target_LIB is required | ||
Line 143: | Line 148: | ||
set(_symbol "MAKE_${_symbol}_LIB") | set(_symbol "MAKE_${_symbol}_LIB") | ||
set_target_properties(${_target_NAME} PROPERTIES DEFINE_SYMBOL ${_symbol}) | set_target_properties(${_target_NAME} PROPERTIES DEFINE_SYMBOL ${_symbol}) | ||
endif (WIN32) | |||
</ | </syntaxhighlight> | ||
===Exporting global functions=== | ===Exporting global functions=== | ||
Line 150: | Line 155: | ||
Example: | Example: | ||
< | <syntaxhighlight lang="cpp"> | ||
namespace Foo { | namespace Foo { | ||
KDEFOO_EXPORT int publicFunction(); | KDEFOO_EXPORT int publicFunction(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===What not to export?=== | ===What not to export?=== | ||
Line 161: | Line 166: | ||
* template classes, e.g.: | * template classes, e.g.: | ||
< | <syntaxhighlight lang="cpp"> | ||
template <class T> | template <class T> | ||
class KGenericFactoryBase | class KGenericFactoryBase | ||
</ | </syntaxhighlight> | ||
Line 174: | Line 179: | ||
Before porting KDElibs to win32, I realized that deprecated classes already use KDE_DEPRECATED macro. We're unable to add another macro like this: | 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! | class KDEFOO_EXPORT KDE_DEPRECATED FooClass { //< - bad for moc! | ||
... | ... | ||
}; | }; | ||
</ | </syntaxhighlight> | ||
..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): | ..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 | # ifndef KABC_EXPORT_DEPRECATED | ||
# define KABC_EXPORT_DEPRECATED KDE_DEPRECATED KABC_EXPORT | # define KABC_EXPORT_DEPRECATED KDE_DEPRECATED KABC_EXPORT | ||
# endif | # endif | ||
</ | </syntaxhighlight> | ||
So, we have following example of deprecated class: | So, we have following example of deprecated class: | ||
< | <syntaxhighlight lang="cpp"> | ||
class KABC_EXPORT_DEPRECATED FooClass { //<- ok for moc | class KABC_EXPORT_DEPRECATED FooClass { //<- ok for moc | ||
... | ... | ||
}; | }; | ||
</ | </syntaxhighlight> | ||
.. 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. | .. 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== | ==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=== | ===K_EXPORT_COMPONENT_FACTORY macro=== | ||
Use K_EXPORT_COMPONENT_FACTORY( libname, factory ), defined in klibloader.h, instead of hardcoding: | 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; } }; | extern "C" {void *init_libname() { return new factory; } }; | ||
</ | </syntaxhighlight> | ||
...because the former way is more portable (contains proper export macro, which ensures visiblility of "init_libname" symbol). | ...because the former way is more portable (contains proper export macro, which ensures visiblility of "init_libname" symbol). | ||
Examples: | Examples: | ||
< | <syntaxhighlight lang="cpp"> | ||
K_EXPORT_COMPONENT_FACTORY( ktexteditor_insertfile, | K_EXPORT_COMPONENT_FACTORY( ktexteditor_insertfile, | ||
GenericFactory<InsertFilePlugin>( "ktexteditor_insertfile" ) ) | GenericFactory<InsertFilePlugin>( "ktexteditor_insertfile" ) ) | ||
K_EXPORT_COMPONENT_FACTORY( libkatepart, KateFactoryPublic ) | K_EXPORT_COMPONENT_FACTORY( libkatepart, KateFactoryPublic ) | ||
</ | </syntaxhighlight> | ||
===More complex case=== | ===More complex case=== | ||
Line 219: | Line 226: | ||
Sometimes you need to declare a factory which defined as a template with multiple arguments, eg.: | Sometimes you need to declare a factory which defined as a template with multiple arguments, eg.: | ||
< | <syntaxhighlight lang="cpp"> | ||
extern "C" | extern "C" | ||
{ | { | ||
Line 227: | Line 234: | ||
} | } | ||
} | } | ||
</ | </syntaxhighlight> | ||
... but compiler complains about too many arguments passed to K_EXPORT_COMPONENT_FACTORY. To avoid this, you can use __typedef__: | ... but compiler complains about too many arguments passed to K_EXPORT_COMPONENT_FACTORY. To avoid this, you can use __typedef__: | ||
< | <syntaxhighlight lang="bash"> | ||
typedef KRES::PluginFactory<ResourceExchange,ResourceExchangeConfig> MyFactory; | typedef KRES::PluginFactory<ResourceExchange,ResourceExchangeConfig> MyFactory; | ||
K_EXPORT_COMPONENT_FACTORY(resourcecalendarexchange, MyFactory) | K_EXPORT_COMPONENT_FACTORY(resourcecalendarexchange, MyFactory) | ||
</ | </syntaxhighlight> | ||
The same trick can be used if the constructor of the factory takes multiple arguments. | The same trick can be used if the constructor of the factory takes multiple arguments. | ||
==Templates== | |||
MSVC 6 templates support was heavily broker. Since then the situation has improved a lot. However some specific cases do exist and these are explained in this section. | |||
===Template arguments need to be defined in header files=== | |||
This won't work with forward declaration: | |||
<syntaxhighlight lang="cpp-qt"> | |||
class QColor; | |||
#include <QList> | |||
QList<QColor> foo; // error | |||
</syntaxhighlight> | |||
You need to include full QColor declaration too: | |||
<syntaxhighlight lang="cpp-qt"> | |||
#include <QColor> | |||
#include <QList> | |||
QList<QColor> foo; // ok | |||
</syntaxhighlight> | |||
So this is different when compared to GCC. | |||
===“non-class type as already been declared as a class type” errors=== | |||
Code like this breaks in MSVC 2008/2010 (works under GCC and standard says it should work): | |||
<syntaxhighlight lang="cpp-qt"> | |||
template <typename T> | |||
void foo(struct bar & b); | |||
struct bar {}; | |||
int main() {} | |||
</syntaxhighlight> | |||
This causes ''“non-class type as already been declared as a class type”'' error. The example is quoted after this [http://stackoverflow.com/questions/5995774/forward-declared-type-and-non-class-type-as-already-been-declared-as-a-class-ty stackoverflow entry]. See also a [https://connect.microsoft.com/VisualStudio/feedback/details/668430/forward-declared-type-and-non-class-type-as-already-been-declared-as-a-class-type bug report] sent to MS, when the vendor rejects request for fixing this bug. | |||
A fix exists under MSVC 2008/2010: "struct bar;" should be added before the template function declaration | |||
<syntaxhighlight lang="cpp-qt"> | |||
struct bar {}; | |||
template <typename T> | |||
void foo(struct bar & b); | |||
int main() {} | |||
</syntaxhighlight> | |||
In practice, if our templated declaration is a class like QList<>, we have to add the ''struct bar {};'' declaration before #include <QList>. | |||
<syntaxhighlight lang="cpp-qt"> | |||
struct bar {}; | |||
#include <QList> | |||
QList<bar> myFunction(); | |||
int main() {} | |||
</syntaxhighlight> | |||
MSVC 2008/2010 changed its behaviour what can be perceived as broken, with regression compared to 2005. | |||
==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...]] |
Latest revision as of 14:58, 18 March 2016
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.
Before you start
- Make sure (ask KDElibs/win32 maintainer) that the library you selected for porting is not ported, but just not committed yet.
- You can ask the maintainer for proposals, what can be useful for porting.
- You will need KDE svn account for your work.
- Download most current (HEAD) of the KDE libraries.
Absolute directory checking
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]!='/').
Ifdefs
C++ code
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
....
#endif
for any C++ code that looks like X11-only.
Use
#ifdef Q_OS_UNIX
....
#endif
for any C++ code that looks like UNIX-only, for example uses UNIX-specific OS features.
Use
#ifdef Q_WS_WIN
....
#endif
for any C++ code that is MSWindows-only.
C code
Note that qglobal.h is C++-only, so instead use
#ifdef _WIN32
....
#endif
for any C code that is MSWindows-only (regardless to compiler type).
Rare cases: How to check in Windows-only code which compiler is used?
MS Visual C++ - Qt-independent code (especially, C code)
#ifdef _MSC_VER
....//msvc code
#endif
MS Visual C++ - Qt code
#ifdef Q_CC_MSVC
....//msvc code
#endif
Borland C++ - Qt-independent code (especially, C code)
#ifdef __BORLANDC__
....//borland code
#endif
Borland C++ - Qt code
#ifdef Q_CC_BOR
....//borland code
#endif
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
Header files
Common header file
Unless there is are any header file from kdelibs included in your header file, you need to add:
#include <kdemacros.h>
or
#include <kdecore_export.h>
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 [1] 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:
class KDEFOO_EXPORT FooClass {
...
};
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:
#define KDE_NO_EXPORT __attribute__ ((visibility("hidden")))
#define KDE_EXPORT __attribute__ ((visibility("default")))
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:
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)
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:
namespace Foo {
KDEFOO_EXPORT int publicFunction();
}
What not to export?
- methods inside classes (no matter static or not)
- inline functions
- template classes, e.g.:
template <class T>
class KGenericFactoryBase
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:
class KDEFOO_EXPORT KDE_DEPRECATED FooClass { //< - bad for moc!
...
};
..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):
# ifndef KABC_EXPORT_DEPRECATED
# define KABC_EXPORT_DEPRECATED KDE_DEPRECATED KABC_EXPORT
# endif
So, we have following example of deprecated class:
class KABC_EXPORT_DEPRECATED FooClass { //<- ok for moc
...
};
.. 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:
extern "C" {void *init_libname() { return new factory; } };
...because the former way is more portable (contains proper export macro, which ensures visiblility of "init_libname" symbol).
Examples:
K_EXPORT_COMPONENT_FACTORY( ktexteditor_insertfile,
GenericFactory<InsertFilePlugin>( "ktexteditor_insertfile" ) )
K_EXPORT_COMPONENT_FACTORY( libkatepart, KateFactoryPublic )
More complex case
Sometimes you need to declare a factory which defined as a template with multiple arguments, eg.:
extern "C"
{
void* init_resourcecalendarexchange()
{
return new KRES::PluginFactory<ResourceExchange,ResourceExchangeConfig>();
}
}
... but compiler complains about too many arguments passed to K_EXPORT_COMPONENT_FACTORY. To avoid this, you can use __typedef__:
typedef KRES::PluginFactory<ResourceExchange,ResourceExchangeConfig> MyFactory;
K_EXPORT_COMPONENT_FACTORY(resourcecalendarexchange, MyFactory)
The same trick can be used if the constructor of the factory takes multiple arguments.
Templates
MSVC 6 templates support was heavily broker. Since then the situation has improved a lot. However some specific cases do exist and these are explained in this section.
Template arguments need to be defined in header files
This won't work with forward declaration:
class QColor;
#include <QList>
QList<QColor> foo; // error
You need to include full QColor declaration too:
#include <QColor>
#include <QList>
QList<QColor> foo; // ok
So this is different when compared to GCC.
“non-class type as already been declared as a class type” errors
Code like this breaks in MSVC 2008/2010 (works under GCC and standard says it should work):
template <typename T>
void foo(struct bar & b);
struct bar {};
int main() {}
This causes “non-class type as already been declared as a class type” error. The example is quoted after this stackoverflow entry. See also a bug report sent to MS, when the vendor rejects request for fixing this bug.
A fix exists under MSVC 2008/2010: "struct bar;" should be added before the template function declaration
struct bar {};
template <typename T>
void foo(struct bar & b);
int main() {}
In practice, if our templated declaration is a class like QList<>, we have to add the struct bar {}; declaration before #include <QList>.
struct bar {};
#include <QList>
QList<bar> myFunction();
int main() {}
MSVC 2008/2010 changed its behaviour what can be perceived as broken, with regression compared to 2005.
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. More information on KDE4_ADD_APP_ICON() macro...