PDA

View Full Version : Strange link problem using VS2008 and qt-vs-addin



bnilsson
8th June 2009, 19:14
I have a strange linking problem using VS2008, Qt4.5.1 and qt-vs-addin 1.0.1.
I import the .pro file to a .vcproj, and it builds fine.
I edit some source files and build again, and now I get things like this:

Generating Code...
Compiling resources...
Microsoft (R) Windows (R) Resource Compiler Version 6.0.5724.0
Copyright (C) Microsoft Corporation. All rights reserved.
Linking...
LINK : warning LNK4068: /MACHINE not specified; defaulting to X86
PAMSapp.obj : error LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __thiscall PAMSApp::metaObject(void)const " (?metaObject@PAMSApp@@UBEPBUQMetaObject@@XZ)
PAMSapp.obj : error LNK2001: unresolved external symbol "public: virtual void * __thiscall PAMSApp::qt_metacast(char const *)" (?qt_metacast@PAMSApp@@UAEPAXPBD@Z)
PAMSapp.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall PAMSApp::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@PAMSApp@@UAEHW4Call@QMetaObject@@HPA PAX@Z)
PAMSapp.obj : error LNK2001: unresolved external symbol "public: static struct QMetaObject const PAMSApp::staticMetaObject" (?staticMetaObject@PAMSApp@@2UQMetaObject@@B)
serialport.obj : error LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __thiscall SerialPort::metaObject(void)const " (?metaObject@SerialPort@@UBEPBUQMetaObject@@XZ)
serialport.obj : error LNK2001: unresolved external symbol "public: virtual void * __thiscall SerialPort::qt_metacast(char const *)" (?qt_metacast@SerialPort@@UAEPAXPBD@Z)
serialport.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall SerialPort::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@SerialPort@@UAEHW4Call@QMetaObject@@ HPAPAX@Z)
settings.obj : error LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __thiscall CorrectionPane::metaObject(void)const " (?metaObject@CorrectionPane@@UBEPBUQMetaObject@@XZ )
settings.obj : error LNK2001: unresolved external symbol "public: virtual void * __thiscall CorrectionPane::qt_metacast(char const *)" (?qt_metacast@CorrectionPane@@UAEPAXPBD@Z)
settings.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall CorrectionPane::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@CorrectionPane@@UAEHW4Call@QMetaObje ct@@HPAPAX@Z)
settings.obj : error LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __thiscall PAMS_Settings::metaObject(void)const " (?metaObject@PAMS_Settings@@UBEPBUQMetaObject@@XZ)
settings.obj : error LNK2001: unresolved external symbol "public: virtual void * __thiscall PAMS_Settings::qt_metacast(char const *)" (?qt_metacast@PAMS_Settings@@UAEPAXPBD@Z)
settings.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall PAMS_Settings::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@PAMS_Settings@@UAEHW4Call@QMetaObjec t@@HPAPAX@Z)
debug\PAMS3.exe : fatal error LNK1120: 13 unresolved externals
Build log was saved at "file://c:\Documents and Settings\bnilsson\My Documents\Visual Studio 2008\Projects\QtPAMS\PAMS3016\debug\BuildLog.htm"
PAMS3 - 14 error(s), 5 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

It is the first time I see anything like this, and I don't know what to make of it.
The only thing that I have done new is installing Qt4.5.1 and the qt-vs-addin.
Any clues would be appreciated.

BN

freezeblue
9th June 2009, 06:39
I met this several times in vs2008. I found two situations cause it.

1. VS using wrong moc files, for example, you are compiling Release, but VS using the moc files generated for Debug. You can edit sections in .vcproj file to correct this mistake:


<File
RelativePath=".\GeneratedFiles\Release\moc_SSMainMenu.cpp"
>
<FileConfiguration
Name="Debug|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="ReleaseStatic|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File>

2. incompatible qmake.exe, moc.exe with Qt library. This means your qt library was compiled by a certain parameter but qmake.exe, moc.exe was built by another different parameter.

Once, for convenience, I directly copied the qmake.exe, moc.exe of a shared Qt building to my static Qt building's bin directory and built my project, similar errors appeared.

bnilsson
11th June 2009, 21:49
I did not understand your case (1) above.
Is the code listing showing the solution or the problem?

To correct problem (2) from above, I took a good look at the install instructions once again and opened the Visual Studio 2008 command window and did
# nmake distclean
# configure -static -no-webkit
# nmake

I imported a .pro file again, built it successfully.
I edited a source file and built again, and the same link errors appeared.
So it is not solved yet.

bnilsson
12th June 2009, 16:54
I have found the apparent reason for the strange link behaviour.
Whenever a source file is edited in my project , the corresponding moc file is for some reason changed to "Exclude from build = yes" by the project, and thus removed from build.
This is causing the link errors.
If I manually set the moc file back to "Exclude from build = no" it builds fine.
However, why this happens I have no idea.
I will have to test if this is specific to .vcproj projects created by qt-vs-addin or not.

freezeblue
13th June 2009, 03:45
That was exactly my case (1). Sorry for ambiguous description.
This problem re-appears in my vs solution frequently. Every time, I have to edit each .vcproj file manually. Terrible thing...
Probably, it's related with qt-vs-addin. But I have no idea how to solve it.

bnilsson
13th June 2009, 09:08
Thanks for the confirmation.
Please tell me in more detail how you edit the .vcproj file.
Once you edit it, is it then good for subsequent builds? Is the problem coming back?

BN

freezeblue
13th June 2009, 14:57
Actually, .vcproj is a XML file. Edit it with any text editor. You will find contents similar with what I listed in #2 in it.

I think these contents are generated by qt-vs-addin. But they are really not good works. Always, the flag ExcludedFromBuild(true/false) of some moc files are incorrectly set.

After correcting them manually, the build works well. But if you add/modify some source files or add some new build configuration, qt-vs-addin starts modifying .vcproj and keeps making mistakes AGAIN. Thus, this problem will comes back at anytime.

bnilsson
13th June 2009, 17:31
I think I may have a clue.
I created a New.. Qt project from VS, and generated a "basic .pro file" to have a look at it.
It seems this is necessary:

release {
DESTDIR = Release
INCLUDEPATH += ./GeneratedFiles ./GeneratedFiles/Release ./
MOC_DIR = ./GeneratedFiles/Release
OBJECTS_DIR += Release
}
debug {
DESTDIR = Debug
INCLUDEPATH += ./GeneratedFiles ./GeneratedFiles/Debug ./
MOC_DIR = ./GeneratedFiles/Debug
OBJECTS_DIR += Debug
}
I included this in my older .pro file, imported it to VS, and then the project started working.

It seems to me the qt-vs-addin assumes this structure but does not correctly handle the situation when it is not.
My hypothesis is that in (release) compilation VS generates and enables the "release"moc_ file and then disables the "debug" moc_ file, and if they are both the same, the final result is that the moc file is disabled and not included in the link.
If there are separate Debug/moc_ and Release/moc_ it works.
In the project that works there are two copies of the same moc_ filename, one is excluded from build and the other is not. In the not-working project there is only one copy, always excluded unless you manually include it.
I guess the script responsible for this should be somewhere in the .vcproj file, but I think it is easier to change the .pro file.

Finally, it seems the generated "basic .pro file" was not correct.
It included "MOC_DIR += ./GeneratedFiles/Release" which did not work.
It should be "MOC_DIR = ./GeneratedFiles/Release".
I had to tweak the .pro file for a while before it was working.

Here is a .pro file for a minimal test project which was actually working:

# -----------------------------------------------------------
# This file is generated by the Qt Visual Studio Integration.
# -----------------------------------------------------------

# This is a reminder that you are using a generated .pro file.
# Remove it when you are finished editing this file.
# message("You are running qmake on a generated .pro file. This may not work!")


TEMPLATE = app
TARGET = Qtest
CONFIG += debug_and_release

release {
DESTDIR = Release
INCLUDEPATH += ./GeneratedFiles ./GeneratedFiles/Release ./
DEPENDPATH += .
MOC_DIR = ./GeneratedFiles/Release
OBJECTS_DIR += Release
}
debug {
DESTDIR = Debug
INCLUDEPATH += ./GeneratedFiles ./GeneratedFiles/Debug ./
DEPENDPATH += .
MOC_DIR = ./GeneratedFiles/Debug
OBJECTS_DIR += Debug
}

UI_DIR += ./GeneratedFiles
RCC_DIR += ./GeneratedFiles

#Include file(s)
#include(Qtest.pri)
#Header files
HEADERS += ./qtest.h

#Source files
SOURCES += ./main.cpp \
./qtest.cpp

#Forms
FORMS += ./qtest.ui

#Resource file(s)
RESOURCES += ./qtest.qrc


I included the .pri file for clarity.

Of course, if you have implemented this already and it is still not working in the long term,
I am totally wrong and we must find another solution.

BN

bnilsson
14th June 2009, 14:17
Having used this scheme for a while, I also notice the VS project is unstable.
Frequently, it suddenly puts the built release .exe into the Debug. Looking in the Project Properties, I see it has changed the output directory all by itself.
Same thing with the moc_ files in GeneratedFiles/debug and release, sometimes it works, sometimes not.
I will uninstall qt-vs-addin and see if that helps.

BN

bnilsson
23rd June 2009, 19:41
This issue has now been filed as a Qt bug, tasks 256573 and 256573.
See http://www.qtsoftware.com/developer/task-tracker.

freezeblue
24th June 2009, 03:08
I find a temporary solution.

After projects becoming stable , which I mean you will not add more sources, forms or resources and projects' parameters are set correctly and .vcproj files get corrected as we talk about before and now you only modify sources, just set all .vcproj files to read only.

You can still select build configuration to build release, debug, etc. But this time, VS warns you .vcproj files read only, you have two choice: overwrite read only file/save changes to .vcproj files in memory.

Choose the later, the build goes fine and the problem never happen again.