Trolltech Home | Qt4-preview-feedback Home | Recent Threads | All Threads | Author | Date
All threads index page 1

Qt4-preview-feedback Archive, December 2007
[qt4.4.0-tp1]: metatype bug and linker flag issues


Message 1 in thread

Trying the 4.4.0-tp1 preview currently has following issues for me:

1. defining TEMPLATE = lib forces QMAKE_LFLAGS to contain '--no-undefined' 
which has changed in mkspecs/common/g++.conf.
This causes a linker error with all my intermediate libs (that depend on other 
libs). Adding QMAKE_LFLAGS -= --no-undefined doesn't work!!! as it doesn't 
remove the flag at all. Maybe a template param 'deplib' could be introduced 
here?

2. I use the following code snippets:

typedef QList <qint32> IntList
Q_DECLARE_METATYPE (IntList)

I have a class 'IntElementList' with:
Q_PROPERTY (IntList IntList WRITE setIntList READ getIntList);

And have registered the type for QScript:
qScriptRegisterSequenceMetaType <IntList> (m_scriptEngine);

Accessing that class from QScript throws:
QMetaProperty::read: Unable to handle unregistered datatype 'IntList' for 
property 'IntElementList::IntList'

The same works for many other data types (double float bool and their 
QList<type> correlate).

I also notice that:
QMetaType::type ("IntList")
and
qMetaTypeId ("IntList")
which mustn't happen - according to the docs

All the above mentioned stuff works fine in qt4.3.2

Frank

To unsubscribe - send "unsubscribe" in the subject to qt4-preview-feedback-request@xxxxxxxxxxxxx


Message 2 in thread

On Thursday 27 December 2007 21:30:19 Frank Hemer wrote:
> I also notice that:
> QMetaType::type ("IntList")
> and
> qMetaTypeId ("IntList")

oops ... missed a part:

return different identifiers!

> which mustn't happen - according to the docs

Frank

To unsubscribe - send "unsubscribe" in the subject to qt4-preview-feedback-request@xxxxxxxxxxxxx


Message 3 in thread

Frank Hemer wrote:
>On Thursday 27 December 2007 21:30:19 Frank Hemer wrote:
>> I also notice that:
>> QMetaType::type ("IntList")
>> and
>> qMetaTypeId ("IntList")
>
>oops ... missed a part:
>
>return different identifiers!

No such function qMetaTypeId("IntList"). If you meant 
qMetaTypeId<IntList>(), then I think I understand why.

The reason is because you're calling it "IntList" instead of the canonical 
name "QList<int>". Unfortunately, qMetaType<IntList>(), 
qMetaType<QList<qint32> >() and qMetaType<QList<int> >() are all the same 
function, whereas the strings aren't. And the meta type system cannot 
know that.

So you must use the canonical name for the metatypes, or you may run into 
unexpected problems like you're just seeing now. The fact that it worked 
in a previous version of Qt is not the issue. Any library code could have 
registered QList<int> under a different name, which can cause havoc.

I plan to address this metatype issue, but it's not very high in my 
priority list. The big issue is types with more than one template 
parameter -- since a comma breaks C macros, you have to use typedef for 
those.

-- 
 [ signature omitted ] 

Attachment: signature.asc
Description: This is a digitally signed message part.


Message 4 in thread

Frank Hemer wrote:
>1. defining TEMPLATE = lib forces QMAKE_LFLAGS to contain
> '--no-undefined' which has changed in mkspecs/common/g++.conf.
>This causes a linker error with all my intermediate libs (that depend on
> other libs). Adding QMAKE_LFLAGS -= --no-undefined doesn't work!!! as
> it doesn't remove the flag at all. Maybe a template param 'deplib'
> could be introduced here?

I introduced that flag. The rationale is that libraries that don't link to 
all their dependencies aren't really cross-platform.

Aren't you simply forgetting to add the necessary dependencies to LIBS?

>2. I use the following code snippets:
>
>typedef QList <qint32> IntList
>Q_DECLARE_METATYPE (IntList)

Why not:
Q_DECLARE_METATYPE(QList<int>)  ?

>I have a class 'IntElementList' with:
>Q_PROPERTY (IntList IntList WRITE setIntList READ getIntList);
>
>And have registered the type for QScript:
>qScriptRegisterSequenceMetaType <IntList> (m_scriptEngine);
>
>Accessing that class from QScript throws:
>QMetaProperty::read: Unable to handle unregistered datatype 'IntList'
> for property 'IntElementList::IntList'
>
>The same works for many other data types (double float bool and their
>QList<type> correlate).
>
>I also notice that:
>QMetaType::type ("IntList")
>and
>qMetaTypeId ("IntList")
>which mustn't happen - according to the docs

Did you mean:
qMetaTypeId<IntList>()?

What value does that return? Can you verify that, after that function 
returns a value greater than 256, QtScript works?

>All the above mentioned stuff works fine in qt4.3.2

The --no-undefined flag is intentional. We can still reconsider it, but 
I'd like to hear your reasons for having a library that doesn't load! As 
far as I can tell, that's broken behaviour.

-- 
 [ signature omitted ] 

Attachment: signature.asc
Description: This is a digitally signed message part.


Message 5 in thread

On Friday 28 December 2007 02:38:31 Thiago Macieira wrote:
> Frank Hemer wrote:
> >1. defining TEMPLATE = lib forces QMAKE_LFLAGS to contain
> > '--no-undefined' which has changed in mkspecs/common/g++.conf.
> >This causes a linker error with all my intermediate libs (that depend on
> > other libs). Adding QMAKE_LFLAGS -= --no-undefined doesn't work!!! as
> > it doesn't remove the flag at all. Maybe a template param 'deplib'
> > could be introduced here?
>
> I introduced that flag. The rationale is that libraries that don't link to
> all their dependencies aren't really cross-platform.
>
> Aren't you simply forgetting to add the necessary dependencies to LIBS?
>
> The --no-undefined flag is intentional. We can still reconsider it, but
> I'd like to hear your reasons for having a library that doesn't load! As
> far as I can tell, that's broken behaviour.

Hmm - no, I don't think so.

I have a basic libA that builds fine with:
CONFIG += qt dll
TEMPLATE = lib

Theres another libB that depends on libA:
CONFIG += qt dll
TEMPLATE = lib
LIBS += -lB -L../lib

And the application itself:
CONFIG += qt
TEMPLATE = app
LIBS += -lA -lB -L ../lib

Now building libB fails with the forementioned message.
According to the linker man page, the flag '--no-undefined' is specially used 
for systems that don't support dependent libraries:
`-no-undefined'
   Declare that OUTPUT-FILE does not depend on any other libraries.
   Some platforms cannot create shared libraries that depend on other
   libraries (*note Inter-library dependencies::).
(libtool --version: ltmain.sh (GNU libtool) 1.5.24 (1.1220.2.455 2007/06/24 
02:13:29)

The flag is fine for basic libs without dependencies, but for intermediate 
libs (libB in my example) it mustn't be set for a successfull build.

> >2. I use the following code snippets:
> >
> >typedef QList <qint32> IntList
> >Q_DECLARE_METATYPE (IntList)
>
> Why not:
> Q_DECLARE_METATYPE(QList<int>)  ?
>
> >I have a class 'IntElementList' with:
> >Q_PROPERTY (IntList IntList WRITE setIntList READ getIntList);
> >
> >And have registered the type for QScript:
> >qScriptRegisterSequenceMetaType <IntList> (m_scriptEngine);
> >
> >Accessing that class from QScript throws:
> >QMetaProperty::read: Unable to handle unregistered datatype 'IntList'
> > for property 'IntElementList::IntList'
> >
> >The same works for many other data types (double float bool and their
> >QList<type> correlate).
> >
> >I also notice that:
> >QMetaType::type ("IntList")
> >and
> >qMetaTypeId ("IntList")
> >which mustn't happen - according to the docs
>
> Did you mean:
> qMetaTypeId<IntList>()?

Yes.

> What value does that return? Can you verify that, after that function
> returns a value greater than 256, QtScript works?

I use a whole bunch of classes that rely on the typedef QList <qint32> 
IntList. Now I have to access these properties in QtScript - and I didn't 
find a way to succeed.

To verify the return values:
QMetaTypeId <QList <qint32> >: 260
QMetaTypeId <QList <int> >: 260
QMetaTypeId <IntList>: 260
qScriptRegisterSequenceMetaType <QList <qint32> > (m_scriptEngine): 260
qScriptRegisterSequenceMetaType <QList <int> > (m_scriptEngine): 260
qScriptRegisterSequenceMetaType <IntList> (m_scriptEngine): 260

So for all cases a value > 256 is returned.

However if I try to access an IntList property from QtScript, I get the 
message:
QMetaProperty::read: Unable to handle unregistered datatype 'IntList' for 
property 'IntElementList::IntList'
More testing reveals, that the only way I can successfully access an int list 
is to specify the property like this:

Q_PROPERTY (QList <int> IntList WRITE setIntList READ getIntList);

Any other type (QList <qint32> or IntList) in the Q_PROPERTY macro fails.
I wonder what happens if used on a platform where int and qint32 are not 
equal?

This behavior should at least throw a BIG warning as one might spent a lot of 
time searching for the cause ...

As a side note, if more than one Q_PROPERTY declaration referencing the same 
property name (that was possibly set in an inherited class) are found, one of 
these declarations is silently ignored. This absolutely is a user error, but 
still might waste a lot of time ... a warning could help a lot here.

Thx for your feedback,
Frank

To unsubscribe - send "unsubscribe" in the subject to qt4-preview-feedback-request@xxxxxxxxxxxxx


Message 6 in thread

Frank Hemer wrote:
>> Aren't you simply forgetting to add the necessary dependencies to
>> LIBS?
>>
>> The --no-undefined flag is intentional. We can still reconsider it,
>> but I'd like to hear your reasons for having a library that doesn't
>> load! As far as I can tell, that's broken behaviour.
>
>Hmm - no, I don't think so.
>
>I have a basic libA that builds fine with:
>CONFIG += qt dll
>TEMPLATE = lib
>
>Theres another libB that depends on libA:
>CONFIG += qt dll
>TEMPLATE = lib
>LIBS += -lB -L../lib

I hope this is a copy/paste error, because you're linking libB to libB, 
not to libA. That won't work and will cause the problem you're seeing.

>And the application itself:
>CONFIG += qt
>TEMPLATE = app
>LIBS += -lA -lB -L ../lib
>
>Now building libB fails with the forementioned message.
>According to the linker man page, the flag '--no-undefined' is specially
> used for systems that don't support dependent libraries:
>`-no-undefined'
>   Declare that OUTPUT-FILE does not depend on any other libraries.
>   Some platforms cannot create shared libraries that depend on other
>   libraries (*note Inter-library dependencies::).
>(libtool --version: ltmain.sh (GNU libtool) 1.5.24 (1.1220.2.455
> 2007/06/24 02:13:29)

We don't use libtool. You're reading the wrong manual.
       --no-undefined
       -z defs
           Report  unresolved  symbol  references  from  regular  object
           files.   This  is  done even if the linker is creating a non-
           symbolic shared library.  The switch --[no-]allow-shlib-undeâ
           fined  controls the behaviour for reporting unresolved referâ
           ences found in shared libraries being linked in.

>The flag is fine for basic libs without dependencies, but for
> intermediate libs (libB in my example) it mustn't be set for a
> successfull build.

Qt builds successfully all of its libraries using that flag.

The flag is used to report if a library is using symbols that cannot be 
found in any of the libraries it's linking to. If you are getting this 
error, your program isn't portable because some systems do not allow that 
to happen at all (MacOS X, Windows, maybe AIX).

The reason why I added the flag was because I was developing QtNetwork and 
the same library is used by my compiler (TeamBuilder). Whenever I forgot 
to implement a function that was being called, the library would link, 
but the program would fail to start because of a missing symbol.

So I added the flag to make the linking process fail. That way, we won't 
risk shipping a library with a function undefined. This has already had 
another positive effect: in QtopiaCore, QtGui now links to QtNetwork. It 
had been using QtNetwork for a while without linking to it, forcing *all* 
QtopiaCore developers to remember to link to QtNetwork even if they 
didn't use it. Now the linker does the right thing instead of the 
developer.

>To verify the return values:
>QMetaTypeId <QList <qint32> >: 260
>QMetaTypeId <QList <int> >: 260
>QMetaTypeId <IntList>: 260
>qScriptRegisterSequenceMetaType <QList <qint32> > (m_scriptEngine): 260
>qScriptRegisterSequenceMetaType <QList <int> > (m_scriptEngine): 260
>qScriptRegisterSequenceMetaType <IntList> (m_scriptEngine): 260
>
>So for all cases a value > 256 is returned.

That's great.

>However if I try to access an IntList property from QtScript, I get the
>message:
>QMetaProperty::read: Unable to handle unregistered datatype 'IntList'
> for property 'IntElementList::IntList'
>More testing reveals, that the only way I can successfully access an int
> list is to specify the property like this:
>
>Q_PROPERTY (QList <int> IntList WRITE setIntList READ getIntList);
>
>Any other type (QList <qint32> or IntList) in the Q_PROPERTY macro
> fails. I wonder what happens if used on a platform where int and qint32
> are not equal?

Qt does not support any platform like that.

>This behavior should at least throw a BIG warning as one might spent a
> lot of time searching for the cause ...

I know. Like I said in another email, this is a limitation of the metatype 
system and has been there for a while. The specific behaviour you're 
seeing was added in Qt 4.2.0: meta types are registered given their C++ 
*real* type, but looked up using a string. If you don't pass the same 
string that was used to *first* register the property, it'll fail.

The problem is when someone else registers the same type you want before 
you do. Or after -- because then their code will start failing.

>As a side note, if more than one Q_PROPERTY declaration referencing the
> same property name (that was possibly set in an inherited class) are
> found, one of these declarations is silently ignored. This absolutely
> is a user error, but still might waste a lot of time ... a warning
> could help a lot here.

I thought that they would override each other the same way slots and 
virtual functions do.

-- 
 [ signature omitted ] 

Attachment: signature.asc
Description: This is a digitally signed message part.


Message 7 in thread

On Friday 28 December 2007 14:39:59 Thiago Macieira wrote:
> Frank Hemer wrote:
> >> Aren't you simply forgetting to add the necessary dependencies to
> >> LIBS?
> >>
> >> The --no-undefined flag is intentional. We can still reconsider it,
> >> but I'd like to hear your reasons for having a library that doesn't
> >> load! As far as I can tell, that's broken behaviour.
> >
> >Hmm - no, I don't think so.
> >
> >I have a basic libA that builds fine with:
> >CONFIG += qt dll
> >TEMPLATE = lib
> >
> >Theres another libB that depends on libA:
> >CONFIG += qt dll
> >TEMPLATE = lib
> >LIBS += -lB -L../lib
>
> I hope this is a copy/paste error, because you're linking libB to libB,
> not to libA. That won't work and will cause the problem you're seeing.

Absolutely;-)

It should read:
CONFIG += qt dll
TEMPLATE = lib
LIBS += -lA -L../lib

> >And the application itself:
> >CONFIG += qt
> >TEMPLATE = app
> >LIBS += -lA -lB -L ../lib
> >
> >Now building libB fails with the forementioned message.
> >According to the linker man page, the flag '--no-undefined' is specially
> > used for systems that don't support dependent libraries:
> >`-no-undefined'
> >   Declare that OUTPUT-FILE does not depend on any other libraries.
> >   Some platforms cannot create shared libraries that depend on other
> >   libraries (*note Inter-library dependencies::).
> >(libtool --version: ltmain.sh (GNU libtool) 1.5.24 (1.1220.2.455
> > 2007/06/24 02:13:29)
>
> We don't use libtool. You're reading the wrong manual.
>        --no-undefined
>        -z defs
>            Report  unresolved  symbol  references  from  regular  object
>            files.   This  is  done even if the linker is creating a non-
>            symbolic shared library.  The switch --[no-]allow-shlib-undeâ
>            fined  controls the behaviour for reporting unresolved referâ
>            ences found in shared libraries being linked in.

Yes, ld would have been a better place to look for ...

> >The flag is fine for basic libs without dependencies, but for
> > intermediate libs (libB in my example) it mustn't be set for a
> > successfull build.
>
> Qt builds successfully all of its libraries using that flag.
>
> The flag is used to report if a library is using symbols that cannot be
> found in any of the libraries it's linking to. If you are getting this
> error, your program isn't portable because some systems do not allow that
> to happen at all (MacOS X, Windows, maybe AIX).

Well, not in my case (works fine on win and unix), see below.

> The reason why I added the flag was because I was developing QtNetwork and
> the same library is used by my compiler (TeamBuilder). Whenever I forgot
> to implement a function that was being called, the library would link,
> but the program would fail to start because of a missing symbol.
>
> So I added the flag to make the linking process fail. That way, we won't
> risk shipping a library with a function undefined. This has already had
> another positive effect: in QtopiaCore, QtGui now links to QtNetwork. It
> had been using QtNetwork for a while without linking to it, forcing *all*
> QtopiaCore developers to remember to link to QtNetwork even if they
> didn't use it. Now the linker does the right thing instead of the
> developer.

In my special case it appears to be the other way around:

My basic lib implements extensions based on Q3Canvas taken from Qt3Support 
module. To prevent usage of qt3support stuff by mistake, I have successfully 
removed qt3 dependencies from all other libs and the application itself. 
Still on load time, the basic lib is linked against Qt3Support.
Now when linking the other libs, they require a few symbols from Qt3Support 
because there are a few references in the Q3Canvas header files that get 
included and cannot be forward declared.

Now I either have the choice to add 'QT += qt3support' (I don't want that 
because of the forementioned reasons) or to add 'LIBS += Qt3Support' which 
forces this line to appear in all other libs and plugins (which are quite 
many by now) and forces plugin developers to remember this. Somewhat similar 
to the QtopiaCore->QtNetwork dependencies you mentioned. So at the time where 
I can successfully replace Q3Canvas with QGraphicsScene, this will require 
adaptions in the other project parts.

To sum this up: The required lib (Qt3Support) is available at load time but 
there's no need to link against it at link time (from my intermediate libs) 
as there are no references to qt3support stuff in them (except those that get 
included by the QtCanvas header file ...).

I tried to work around this by adding 'QMAKE_LFLAGS -= --no-undefined, but 
this doesn't have any effect. Appears like a bug to me.

For now I helped myself with 'unix::QMAKE_LFLAGS = -m64' but this is not a 
clean solution either.

> >As a side note, if more than one Q_PROPERTY declaration referencing the
> > same property name (that was possibly set in an inherited class) are
> > found, one of these declarations is silently ignored. This absolutely
> > is a user error, but still might waste a lot of time ... a warning
> > could help a lot here.
>
> I thought that they would override each other the same way slots and
> virtual functions do.

Hmm, I couldn't reproduce this in a short try (its some time in the past when 
I stumbled over this behavior) - however I managed to cause some strange moc 
errors with missleading type errors ... a warning telling about duplicate 
definitions could save time here.

Frank

To unsubscribe - send "unsubscribe" in the subject to qt4-preview-feedback-request@xxxxxxxxxxxxx