Bug 822710

Summary: Can't build 32bit Qt release application on 64bit
Product: [Fedora] Fedora Reporter: Dominik.Riebeling
Component: qtAssignee: Than Ngo <than>
Status: CLOSED RAWHIDE QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 16CC: itamar, jreznik, kevin, ltinkl, rdieter, rnovacek, smparrish, than
Target Milestone: ---   
Target Release: ---   
Hardware: x86_64   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2012-05-18 00:42:12 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Dominik.Riebeling 2012-05-17 21:04:48 UTC
Description of problem:
When trying to build a 32bit binary for a Qt based program on 64bit CFLAGS will always include -m64 for release configuration.

Version-Release number of selected component (if applicable):
$ rpm -q qt-devel
qt-devel-4.8.1-5.fc16.x86_64
qt-devel-4.8.1-5.fc16.i686
$ uname -a
Linux luna.lan 3.3.5-2.fc16.x86_64 #1 SMP Tue May 8 11:24:50 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
$ cat /etc/fedora-release 
Fedora release 16 (Verne)


How reproducible:
Always reproducible with -spec linug-g++-32 for release binary, not reproducible for debug binary (-spec linux-g++-32 -config debug).


Steps to Reproduce:
Build an arbitrary Qt based program (example below taken from http://doc.qt.nokia.com/4.7/gettingstartedqt.html) using -spec linux-g++-32:
$ cat << EOF > test.cpp
> #include <QApplication>
> #include <QTextEdit>
> 
> int main(int argv, char **args)
> {
>     QApplication app(argv, args);
> 
>     QTextEdit textEdit;
>     textEdit.show();
> 
>     return app.exec();
> }
> EOF
$ qmake-qt4 -project
$ qmake-qt4 -spec linux-g++-32
$ make
g++ -c -m32 -pipe -O2 -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/lib64/qt4/mkspecs/linux-g++-32 -I. -I/usr/include/QtCore -I/usr/include/QtGui -I/usr/include -I. -I. -o test.o test.cpp
g++ -m32 -Wl,-O1 -o a test.o    -L/usr/lib64 -lQtGui -lQtCore -lpthread 
/usr/bin/ld: skipping incompatible /usr/lib64/libQtGui.so when searching for -lQtGui
/usr/bin/ld: skipping incompatible /usr/lib64/libQtCore.so when searching for -lQtCore
/usr/bin/ld: skipping incompatible /usr/lib64/libpthread.so when searching for -lpthread
/usr/bin/ld: skipping incompatible /usr/lib64/libm.so when searching for -lm
/usr/bin/ld: skipping incompatible /usr/lib64/libc.so when searching for -lc
/usr/bin/ld: i386:x86-64 architecture of input file `test.o' is incompatible with i386 output
collect2: ld returned 1 exit status
make: *** [a] Error 1

This problem does not appear if you build as debug binary:
$ qmake-qt4 -spec linux-g++-32 -config debug
$ make
g++ -c -m32 -pipe -g -Wall -W -D_REENTRANT -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/lib64/qt4/mkspecs/linux-g++-32 -I. -I/usr/include/QtCore -I/usr/include/QtGui -I/usr/include -I. -I. -o test.o test.cpp
g++ -m32 -o a test.o    -L/usr/lib64 -lQtGui -lQtCore -lpthread 
/usr/bin/ld: skipping incompatible /usr/lib64/libQtGui.so when searching for -lQtGui
/usr/bin/ld: skipping incompatible /usr/lib64/libQtCore.so when searching for -lQtCore
/usr/bin/ld: skipping incompatible /usr/lib64/libpthread.so when searching for -lpthread
/usr/bin/ld: skipping incompatible /usr/lib64/libm.so when searching for -lm
/usr/bin/ld: skipping incompatible /usr/lib64/libc.so when searching for -lc
{ test -n "" && DESTDIR="" || DESTDIR=.; } && test $(gdb --version | sed -e 's,[^0-9]\+\([0-9]\)\.\([0-9]\).*,\1\2,;q') -gt 72 && gdb --nx --batch --quiet -ex 'set confirm off' -ex "save gdb-index $DESTDIR" -ex quit 'a' && test -f a.gdb-index && objcopy --add-section '.gdb_index=a.gdb-index' --set-section-flags '.gdb_index=readonly' 'a' 'a' && rm -f a.gdb-index || true
$ ldd a
(bunch of 32bit libs)

  
Actual results:
Compiler flags contain -m64 additionally and after -m32, resulting in 64bit objects.


Expected results:
Compiler flags contain -m32 only, resulting in 32bit objects.


Additional info:
The problem is caused by the mkspec gcc-base.conf, which adds the -m64 parameter to QMAKE_CFLAGS_RELEASE. When removing the -m64 things work as expected. This also explains why the problem doesn't appear if -config debug is used.

Comment 1 Rex Dieter 2012-05-17 21:29:30 UTC
Indeed, I don't recall all the history/rationale behind modifying the mkspecs/common/g*base.conf files right now, but, since it causes bad side-effects... I'll see if we can avoid doing that.

Comment 2 Rex Dieter 2012-05-18 00:20:12 UTC
Looks like that approach works, I'll whip up a fix to commit.

In the meantime...
This still won't use the fedora default compiler flags for non-native builds this way however (that's a separate problem which may not be reasonably solvable, past attemps have failed)

To achieve that on a 64bit fedora system now, you'd need to run
/usr/lib/qt4/bin/qmake
instead of the native 64bit one (via either /usr/bin/qmake-qt4 or /usr/lib64/qt4/bin/qmake)

Comment 3 Rex Dieter 2012-05-18 00:42:12 UTC
http://pkgs.fedoraproject.org/gitweb/?p=qt.git;a=commit;h=e0673557d0252b5de1146d15ce9fa41e1714c6f7

fixed in rawhide, will be rolled into the next qt update we do for f16

(You can use the workarounds I suggested in the meantime, I hope)

Comment 4 Kevin Kofler 2012-05-18 04:33:41 UTC
The rationale behind modifying g*base.conf was probably to ensure that even non-RPM builds default to our default flags. I'm nervous about changing this, it might also affect some package builds. Not all specfiles set CFLAGS explicitly.

Comment 5 Rex Dieter 2012-05-18 11:49:39 UTC
I tested and made sure the flags still get set via mkspecs/default/qmake.conf

As a matter of fact, I'd noticed the RPM_OPT_FLAGS were appearing twice for some time now, and had been thinking of looking into why that was happening.  turned out to be this.