Opened 10 years ago

Closed 10 years ago

Last modified 10 years ago

#110 closed defect (fixed)

Upgrade to GCC 4

Reported by: dmik Owned by:
Priority: blocker Milestone: Qt GA
Component: General Version: 4.5.1 Beta 3
Severity: low Keywords:
Cc:

Description

We should move to GCC 4 ASAP (thanks to Paul for providing the builds) because GCC 3.3.5 is waaaay to old out of life (GCC 4 includes tons of very nice fixes).

Attachments (3)

qt4-gcc442.diff (1.9 KB) - added by psmedley 10 years ago.
Diff for building qwith gcc 4.4.2
gccenv.cmd (11.5 KB) - added by dmik 10 years ago.
Double fixed gccenv.cmd from the bin subdirectory of the gcc4 package by Paul
gccenv.cmd.452 (11.6 KB) - added by dmik 8 years ago.
A fresh gccenv.cmd suitable for GCC 4.5.2

Download all attachments as: .zip

Change History (27)

comment:1 Changed 10 years ago by dmik

One of the most amazing bugs that is related o freetype.h parsing. See r170, r395 and the end of #107. I really hope that it was fixed in GCC 4.

Note that when we upgrade, we should rollback r395 at all to restore freetype.h to its pristine form. Note that r170 is already reverted in r396.

comment:2 Changed 10 years ago by psmedley

Please let me know if you hit problems :) GCC 4.4.2 just added to my site includes a hack for parsing of \ vs / in @files

Changed 10 years ago by psmedley

Diff for building qwith gcc 4.4.2

comment:3 Changed 10 years ago by dmik

I'm experiencing some difficulties with gcc442 regarding the size of the resulting executable. Taken the hello world program and using -s -Zomf options, i get:

3.3.5 4.4.2
gcc1056 B 1260 B
g++1380 B 41984 B

Not nice. Looks like g++ from 4.4.2 links the application to something that is not really necessary.

comment:4 Changed 10 years ago by dmik

Hmm, maybe it's some exception stuff enabled by default in gcc4...

comment:5 Changed 10 years ago by dmik

Okay, I was right (-Zmap revealed it). For some reason, -fexceptions is set by default. Specifying -fno-exceptions gives us even a smaller executable than with g++3: just 1056 bytes.

comment:6 Changed 10 years ago by dmik

Another strange thing. Once I add #include <iostream> and std::cout << "Hello world++", -fno-exceptions does not make any difference any more and exception support gets still compiled in (increasing the .exe size upto 300K!). This doesn't happen with gcc3 where it still stays 1K.

comment:7 Changed 10 years ago by dmik

I think that the reason is that exception related symbols get dragged in for some strange reason when std::cout from libstdc++ is referenced. This should not happen (and e.g. gcc 4.4.1 on linux does not do that). Paul, can you comment on it?

comment:8 Changed 10 years ago by psmedley

Probably something to do with libstdc++.a being linked statically. With GCC 3.3.5, the symbols from libstdc++ are included in libc063.dll

comment:9 Changed 10 years ago by dmik

Well, yes, big (all?) parts of libstdc++ 3.x are in libc063.dll, but the hello world C++ example compiled by gcc 3 only contains these C++ objects (at all):

__ZSt4cout                          libc063
__ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc libc063
__ZNSt8ios_base4InitC1Ev            libc063
__ZNSt8ios_base4InitD1Ev      

which is exactly what needed.

While the same example compiled by gcc4 contains more than 1800 C++ objects, statically linked indeed but it's not an excuse anyway: this damn simple program didn't ask for these functions and doesn't need them.

Many of these objects look like forced template instantiations, I'll check this direction too.

comment:10 Changed 10 years ago by dmik

Found that this issue affects other platforms as well, for example a commend from http://stackoverflow.com/questions/1042773/gcc-c-hello-world-program-exe-is-500kb-big-when-compiled-on-windows-how:

Basically, there's not really anything you can do to reduce that .exe size with a base distribution of mingw. 550kb is about as small as you can get it, because mingw and gcc/g++ in general are bad at stripping unused functions. About 530kb of that is from the msvcrt.a library.

If you really wanted to get into it, you might be able to rebuild the msvcrt.a library with -ffunction-sections -fdata-sections compiler options, and then use the -Wl,--gc-sections linker options when linking your app, and this should be able to strip a lot of that stuff out of there. But if you're just learning C++, rebuilding that library may be a bit advanced.

Or you could just use MSVC, which is great at stripping unused functions. That same bit of code compiled with MSVC produces a 10kb exe.

Seems that we bump into the same non-stripped unused symbols problem. Paul, can you try to build libstdc++ with the options above?

PS. Netlabs is really slow today, been checking a fresh SVN copy for more than 2 hours now...

comment:11 Changed 10 years ago by dmik

Paul, I found a really nice bug in the gcc442.cmd and gccenv.cmd files from the archive (it was the reason why src\tools\uic\cpp\cppwriteiconinitialization.cpp didn't compile; your patch doesn't actually fix anything there so I wonder how you built it at all).

The cause is CPLUS_INCLUDE_PATH. According to http://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Environment-Variables.html#Environment-Variables, gcc recognizes the empty path element in this and similar variables, and more over, it recognizes empty path elements at the beginning and at the end of the path string. In case of our OS, it means that an opening or a trailing semicolon in the variable's value means an empty path for gcc which it treats as the current working directory.

Both .cmd files have a trailing semicolon in the CPLUS_INCLUDE_PATH value. This makes the current working directory (whatever it is) the system include directory. And as any other system directory, it is searched after all directories specified with -I (note that gcc checks if a path in -I is a system path and ignores such an option if so).

Now we ccme down to the exact problem: cppwriteiconinitialization.cpp includes D:\Coding\qt\qt4_gcc4\src\tools\uic\utils.h as #include "utils.h" assuming that it passes the -I. option to gcc and D:\Coding\qt\qt4_gcc4\src\tools\uic is the current working directory when it's built. However, the CWD is a system include directory placed at the end of the search list, after /gcc335csd3/usr/include, which, just by accident also has a file named "utils.h"! And the latter is the one that gets included by cppwriteiconinitialization.cpp and it of course doesn't contain the missing fixString() function which this .cpp needs.

The fix of the problem is to remove leading or trailing ";" and make sure the paths don't contain ";;" in between. And taking the above into account, the empty path element must never be in either of the path-related environment variables as it contains a hidden trap for all programs compiled with gcc4.

So please fix those .cmd files in your distribution.

comment:12 Changed 10 years ago by dmik

I'm attaching a fixed gccenv.cmd that is free of the above issue.

I'm also posting here my chat session with Paul to make sure my suggestions to his gcc4 distro aren't lost:

(02:05:15) dmik: hey Paul again
(02:09:30) dmik: any reason that in gcc-4.4.2-os2-20091204.zip you call it local44 instead of local442?
(02:10:10) dmik: the gccenv.cmd script (that I used to use) assumes that and after renamed to local442 this script even starts to work
(02:12:33) dmik: another small detail is that neither the gcc335 /usr tree nor the gcc422 /usr/local442 tree has to be in the root dir
(02:12:58) dmik: I've been always keeping it deep inside my D:\Dev
(02:13:59) dmik: from this point, it's not actually clear from readme.os2 that in order to work the contents of the gcc442 archive should be put to the same dir where usr from the gcc335 compiler resides
(02:14:57) dmik: it took me several minutes to get it :)
(02:19:22) dmik: another problem is that gcc4 generates an extremely big executable for the classic hello world program given the -s option: 300K versus 4K of gcc3
(02:19:44) dmik: is it known?
(02:20:21) dmik: this is of course much slower
(02:46:33) dmik: see also #110
(02:47:23) dmik: also, gcc442.cmd from the archive doesn't work here. The compiler says:
gcc -s -Zomf hello.c -o hello_c.exe
emxomfld: _abspath failed on 'crt0.obj'!!!
make: * [hello_c.exe] Error 1
(02:47:37) dmik: using gccenv.cmd from /bin works
(09.12.2009 11:12:31) psmedley: bigger .exe's is known - i dunno why it is the case tho - I presume due to the emxomf warnings....
(17:16:11) psmedley has signed on.
(17:17:01) dmik: no, emxomf warnings are due to .a -> .lib conversion
(17:17:15) dmik: btw, would be nice if you put MakeOMFLibs.cmd to lib as gcc335 does
(17:17:44) dmik: you only have to fix one path in the original .cmd (the path to gcc442.a)

comment:13 Changed 10 years ago by dmik

I committed the patches necessary to build Qt with GCC4 in r412.

Note that I also put the GCC runtime WPI to ftp://ftp.netlabs.org/pub/qt4/gcc-lib-4_4_2-20091204.wpi, for convenience.

comment:14 Changed 10 years ago by dmik

Simple tests (played with QLinguist for some time) show that the build is pretty functioning.

Now about the size of the generated executables compared to GCC3. I found that for simple and small command line tools whose GCC3 size is less than 1 MB (rcc.exe, moc.exe, uic.exe, etc.) GCC4 generated executables that are larger than the GCC3 ones just by 20 KB average -- this is more than accepted.

What about bigger modules such as our Qt DLLs, the wonderful thing is that their size with GCC4 is significantly smaller than with GCC3 -- for example, QtGui4.dll lost 800 KB! (being just 6245791 bytes in size vs 7056295 bytes in the GCC3 build). This is a good news, looks like GCC4 drops unused C++ constructs more efficiently than GCC3. And maybe some extra size optimizations are also in charge.

PS. I compiled everything in release mode with exceptions enabled and compressed with lxlite afterwards as usual. W/o lxlite, the difference between GCC4'd and GCC3'd DLLs would have been even bigger :)

comment:15 Changed 10 years ago by dmik

I tried precompiled headers with GCC 4.4.2 (this should greatly speed up building time of Qt) but failed. GCC traps with this:

make[1]: Entering directory `D:/Coding/qt/qt4_gcc4/qmake'
g++ -x c++-header -c -Zomf -s -O2 -Wall -DQT_NO_TABLET DQT_NO_SYSTEMSEMAPHORE -DQT_NO_SHAREDMEMORY -DQT_NO_SESSIONMANAGER -DQT_NO_IM -DQT_NO_ACCESSIBILITY -DQT_NO_IPV6 -DQT_NO_PRINTER DQT_NO_PRINTDIALOG -DQT_NO_DRAGANDDROP -DQMAKE_OPENSOURCE_EDITION -DQT_NO_DEBUG -DQT_SCRIPT_LIB -DQT_CORE_LIB -I..\include\QtCore I..\include\QtScript -I..\include -Igenerators -Igenerators\unix -Igenerators\win32 Igenerators\os2 -Igenerators\mac -I..\include -I..\include\QtCore -I. I..\include\QtScript -Irelease-shared -I"..\mkspecs\os2-g++" -o tmp\pch\debug-shared\qmake_pch.h.gch\c++ qmake_pch.h
g++ -c -include tmp\pch\debug-shared\qmake_pch.h -Zomf -s -O2 -Wall DQT_NO_TABLET -DQT_NO_SYSTEMSEMAPHORE -DQT_NO_SHAREDMEMORY -DQT_NO_SESSIONMANAGER -DQT_NO_IM -DQT_NO_ACCESSIBILITY -DQT_NO_IPV6 DQT_NO_PRINTER -DQT_NO_PRINTDIALOG -DQT_NO_DRAGANDDROP -DQMAKE_OPENSOURCE_EDITION -DQT_NO_DEBUG -DQT_SCRIPT_LIB -DQT_CORE_LIB I..\include\QtCore -I..\include\QtScript -I..\include -Igenerators -Igenerators\unix -Igenerators\win32 -Igenerators\os2 -Igenerators\mac I..\include -I..\include\QtCore -I. -I..\include\QtScript -Irelease-shared -I"..\mkspecs\os2-g++" -o release-shared\project.obj project.cpp

Killed by SIGSEGV
pid=0x663f ppid=0x663e tid=0x0001 slot=0x009d pri=0x0200 mc=0x0001
D:\DEV\GCC335CSD3\USR\LOCAL442\LIBEXEC\GCC\I386-PC-OS2-EMX\4.4.2\CC1PLUS.EXE
CC1PLUS 0:00303db5
cs:eip=005b:00313db5      ss:esp=0053:00a8f83c      ebp=00a8f848
 ds=0053      es=0053      fs=150b      gs=0000     efl=00010a12
eax=118f2ee8 ebx=6d697320 ecx=66696c70 edx=69e96fc8 edi=00000048 esi=20727563
Process dumping was disabled, use DUMPPROC / PROCDUMP to enable it.
g++: Internal error: Segmentation fault (program cc1plus)
Please submit a full bug report.
See <http://gcc.gnu.org/bugs.html> for instructions.
make[1]: *** [release-shared\project.obj] Error 1
make[1]: Leaving directory `D:/Coding/qt/qt4_gcc4/qmake'
make: *** [release] Error 2

Paul, could you please have a look into the issue?

I still committed the PCH support in r417, but you have to enable it in configure.cmd (line 559) as it's commented out. Also, I'm ready to assist you with debugging if necessary.

comment:16 Changed 10 years ago by dmik

As far as I see, the precompied header was compiled OK, but the invocation that includes this header (-include blabla above) actually crashed.

comment:17 Changed 10 years ago by psmedley

Will look at all the above ASAP - probably in a couple of weeks when I'm on vacation. PCH issues are known - just had no time to debug yet.

comment:18 Changed 10 years ago by dmik

Okay, thanks. In the meantime, I will practice more with the GCC4 build of Qt, and if there are no new problems, I think we'll still release GA with it even if PCH don't work (as it's at least not worse than GCC3 so far, and even better regarding the size of the big EXEs and DLLs).

comment:19 Changed 10 years ago by dmik

There is another annoying problem about the GCC4 build. During the compile stage, it spits out tons of warnings like this:

........CODINGQTQT4include/QtCore/../../src/corelib/arch/qatomic_i386.h: ssembler messages:
........CODINGQTQT4include/QtCore/../../src/corelib/arch/qatomic_i386.h:123: Warning: line numbers must be positive; line number 0 rejected
........CODINGQTQT4include/QtCore/../../src/corelib/arch/qatomic_i386.h:135: Warning: line numbers must be positive; line number 0 rejected

Adding the -S option, gives the following assembler output that causes complains of the binutils assembler:

#APP
# 120 "..\..\..\..\CODING\QT\QT4\include/QtCore/../../src/corelib/arch/qatomic_i386.h" 1
	lock
incl (%eax)
setne -1(%ebp)
# 0 "" 2
	.stabd	68,0,121
#NO_APP

The following GCC bug contains a similar discussion http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21250, but we actually don't deal with built-ins here but rather with the normal code...

comment:20 Changed 10 years ago by dmik

Being built by GCC3, the corresponding piece looks like this:

#APP
	lock
incl (%edx)
setne -1(%ebp)
	.stabd	68,0,121
#NO_APP

I.e. there are no line references in there...

This problem may be OS/2-specific (maybe path-related). Paul, please look at this too. Currently, it's really annoying, as this message may is emitted thousands times across the build.

comment:21 Changed 10 years ago by dmik

Okay, I can confirm that using newer binutils taken from here http://download.smedley.info/binutils-2.19.1-os2-20090427.zip causes this annoying warning to disappear. Looks that these # 0 "" are somehow expected by as now and so not an OS/2-specific bug.

comment:22 Changed 10 years ago by psmedley

http://gcc.gnu.org/ml/gcc-patches/2004-06/msg00031.html has the patches that were used to add PCH support for mingw32 - I'll study these a little closer and see if they can help with added PCH support for OS/2

comment:23 Changed 10 years ago by dmik

  • Resolution set to fixed
  • Status changed from new to closed

I think that this task is mostly done as we can successfully build with GCC4 now. Paul, I created #116 to track the PCH issue.

comment:24 Changed 10 years ago by dmik

  • Severity set to low

The attached gccenv.cmd had a couple of bugs showing up under certain circumstances; I'm attaching a new one.

Changed 10 years ago by dmik

Double fixed gccenv.cmd from the bin subdirectory of the gcc4 package by Paul

Changed 8 years ago by dmik

A fresh gccenv.cmd suitable for GCC 4.5.2

Note: See TracTickets for help on using tickets.