Difference between revisions of "Projects/KDE on Windows/Porting Guidelines"

Jump to: navigation, search
(K_PLUGIN_FACTORY)
(Templates)
 
(13 intermediate revisions by 6 users not shown)
Line 11: Line 11:
 
Look for '/' and "/" and change every single code like:
 
Look for '/' and "/" and change every single code like:
  
<code c>
+
<syntaxhighlight lang="c">
 
   if (path[0]=='/')
 
   if (path[0]=='/')
</code>
+
</syntaxhighlight>
 
or:
 
or:
  
<code cppqt3>
+
<syntaxhighlight lang="cpp-qt">
 
   if (path.startsWith('/'))
 
   if (path.startsWith('/'))
</code>
+
</syntaxhighlight>
 
with:
 
with:
  
<code cppqt3>
+
<syntaxhighlight lang="cpp-qt">
 
   if (!QDir::isRelativePath(path))
 
   if (!QDir::isRelativePath(path))
</code>
+
</syntaxhighlight>
 
(or "QDir::isRelativePath(path)" if there was used path[[0]!='/').
 
(or "QDir::isRelativePath(path)" if there was used path[[0]!='/').
  
Line 33: Line 33:
  
 
Use
 
Use
<code c>
+
<syntaxhighlight lang="c">
 
   #ifdef Q_WS_X11
 
   #ifdef Q_WS_X11
 
   ....
 
   ....
 
#endif
 
#endif
</code>
+
</syntaxhighlight>
 
for any C++ code that looks like X11-only.
 
for any C++ code that looks like X11-only.
  
 
Use
 
Use
<code c>
+
<syntaxhighlight lang="c">
 
   #ifdef Q_OS_UNIX
 
   #ifdef Q_OS_UNIX
 
   ....
 
   ....
 
#endif
 
#endif
</code>
+
</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
<code c>
+
<syntaxhighlight lang="c">
 
   #ifdef Q_WS_WIN
 
   #ifdef Q_WS_WIN
 
   ....
 
   ....
 
#endif
 
#endif
</code>
+
</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
<code c>
+
<syntaxhighlight lang="c">
   #ifdef _WINDOWS
+
   #ifdef _WIN32
 
   ....
 
   ....
 
#endif
 
#endif
</code>
+
</syntaxhighlight>
  
for any C code that is MSWindows-only (regardless to compiler type). In fact, you could use built-in _WIN32 but it's not defined on incoming 64bit MS Windows platform (_WIN64 is used there). So, there's a global rule for kdelibs/win32 defined globally in your build system (you don't need to include any file for this).
+
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)====
<code cpp>
+
<syntaxhighlight lang="cpp">
 
   #ifdef _MSC_VER
 
   #ifdef _MSC_VER
 
   ....//msvc code
 
   ....//msvc code
 
#endif
 
#endif
</code>
+
</syntaxhighlight>
  
 
====MS Visual C++ - Qt code====
 
====MS Visual C++ - Qt code====
<code cpp>
+
<syntaxhighlight lang="cpp">
 
   #ifdef Q_CC_MSVC
 
   #ifdef Q_CC_MSVC
 
   ....//msvc code
 
   ....//msvc code
 
#endif
 
#endif
</code>
+
</syntaxhighlight>
  
 
====Borland C++ - Qt-independent code (especially, C code)====
 
====Borland C++ - Qt-independent code (especially, C code)====
<code cpp>
+
<syntaxhighlight lang="cpp">
 
   #ifdef __BORLANDC__
 
   #ifdef __BORLANDC__
 
   ....//borland code
 
   ....//borland code
 
#endif
 
#endif
</code>
+
</syntaxhighlight>
  
 
====Borland C++ - Qt code====
 
====Borland C++ - Qt code====
<code cpp>
+
<syntaxhighlight lang="cpp">
 
   #ifdef Q_CC_BOR
 
   #ifdef Q_CC_BOR
 
   ....//borland code
 
   ....//borland code
 
#endif
 
#endif
</code>
+
</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 105: Line 107:
 
===Common header file===
 
===Common header file===
 
Unless there is are any header file from kdelibs included in your header file, you need to add:
 
Unless there is are any header file from kdelibs included in your header file, you need to add:
<code c>
+
<syntaxhighlight lang="c">
 
  #include <kdemacros.h>  
 
  #include <kdemacros.h>  
</code>
+
</syntaxhighlight>
 
or
 
or
<code c>
+
<syntaxhighlight lang="c">
 
  #include <kdecore_export.h>  
 
  #include <kdecore_export.h>  
</code>
+
</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 122: Line 124:
 
Example:
 
Example:
  
<code cpp>
+
<syntaxhighlight lang="cpp">
 
class KDEFOO_EXPORT FooClass {
 
class KDEFOO_EXPORT FooClass {
 
...
 
...
 
};
 
};
</code>
+
</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 132: 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:
  
<code cpp>
+
<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")))
</code>
+
</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:
<code cpp>
+
<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 147: Line 149:
 
       set_target_properties(${_target_NAME} PROPERTIES DEFINE_SYMBOL ${_symbol})
 
       set_target_properties(${_target_NAME} PROPERTIES DEFINE_SYMBOL ${_symbol})
 
endif (WIN32)  
 
endif (WIN32)  
</code>
+
</syntaxhighlight>
  
 
===Exporting global functions===
 
===Exporting global functions===
Line 153: Line 155:
  
 
Example:
 
Example:
<code cpp>
+
<syntaxhighlight lang="cpp">
 
namespace Foo {
 
namespace Foo {
 
  KDEFOO_EXPORT int publicFunction();
 
  KDEFOO_EXPORT int publicFunction();
 
}
 
}
</code>
+
</syntaxhighlight>
  
 
===What not to export?===
 
===What not to export?===
Line 164: Line 166:
 
* template classes, e.g.:
 
* template classes, e.g.:
  
<code cpp>
+
<syntaxhighlight lang="cpp">
 
template <class T>
 
template <class T>
 
class KGenericFactoryBase
 
class KGenericFactoryBase
</code>
+
</syntaxhighlight>
  
  
Line 177: 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:
  
<code cpp>
+
<syntaxhighlight lang="cpp">
 
class KDEFOO_EXPORT KDE_DEPRECATED FooClass { //< - bad for moc!
 
class KDEFOO_EXPORT KDE_DEPRECATED FooClass { //< - bad for moc!
 
...
 
...
 
};
 
};
</code>
+
</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):
  
<code cpp>
+
<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
</code>
+
</syntaxhighlight>
  
 
So, we have following example of deprecated class:
 
So, we have following example of deprecated class:
  
<code cpp>
+
<syntaxhighlight lang="cpp">
 
class KABC_EXPORT_DEPRECATED FooClass { //<- ok for moc
 
class KABC_EXPORT_DEPRECATED FooClass { //<- ok for moc
 
...
 
...
 
};
 
};
</code>
+
</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.
Line 208: Line 210:
  
 
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:
<code cpp>
+
<syntaxhighlight lang="cpp">
 
  extern "C" {void *init_libname() { return new factory; } };
 
  extern "C" {void *init_libname() { return new factory; } };
</code>
+
</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:  
<code cpp>
+
<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 )
</code>
+
</syntaxhighlight>
  
 
===More complex case===
 
===More complex case===
Line 224: 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.:
  
<code cpp>
+
<syntaxhighlight lang="cpp">
 
extern "C"
 
extern "C"
 
{
 
{
Line 232: Line 234:
 
   }
 
   }
 
}
 
}
</code>
+
</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__:
  
<code bash>
+
<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)
</code>
+
</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 21:24, 25 November 2011

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

[edit] 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.

[edit] 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]!='/').

[edit] Ifdefs

[edit] 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.

[edit] 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).

[edit] Rare cases: How to check in Windows-only code which compiler is used?

[edit] MS Visual C++ - Qt-independent code (especially, C code)

  #ifdef _MSC_VER
  ....//msvc code
#endif

[edit] MS Visual C++ - Qt code

  #ifdef Q_CC_MSVC
  ....//msvc code
#endif

[edit] Borland C++ - Qt-independent code (especially, C code)

  #ifdef __BORLANDC__
  ....//borland code
#endif

[edit] Borland C++ - Qt code

  #ifdef Q_CC_BOR
  ....//borland code
#endif

[edit] 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.

[edit] Related links

[edit] Header files

[edit] 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.

[edit] 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)

[edit] 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();
}

[edit] What not to export?

  • methods inside classes (no matter static or not)
  • inline functions
  • template classes, e.g.:
template <class T>
class KGenericFactoryBase


[edit] 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.

[edit] 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.

[edit] Loadable KDE modules/plugins

noframe
 
TODO
This is deprecated section; we should use K_PLUGIN_FACTORY and K_EXPORT_PLUGIN macros


[edit] 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 )

[edit] 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.

[edit] 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.

[edit] 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.

[edit] “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.

[edit] 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...


This page was last modified on 25 November 2011, at 21:24. This page has been accessed 10,345 times. Content is available under Creative Commons License SA 3.0 as well as the GNU Free Documentation License 1.2.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V.Legal