From: Oliver L. <bl...@bl...> - 2008-12-19 18:29:42
|
Howdy, I'm having trouble compiling a GTK application for Win32 using MinGW under MSys. While the compiler commands work fine, the following link command causes trouble: gcc -Wall `pkg-config --libs gtk+-2.0 gthread-2.0` -o MyPrg.exe src/main.o src/app.o src/cpu.o src/io.o src/str.o src/sys.o output: undefined reference to g_printf undefined reference to g_object_unref ... and so on When i just modify the order of args in the command like this: gcc -o MyPrg.exe src/main.o src/app.o src/cpu.o src/io.o src/str.o src/sys.o -Wall `pkg-config --libs gtk+-2.0 gthread-2.0` ...then linking works fine. The matter is, i have to put '-o MyPrg.exe' and especially all object filenames at the beginning of the command line, followed by all other options... This problem ain't easy to circumvent because the linker commands in question are generated by either autotools or SCons, both causing the same trouble. I've tried this with gcc-core-3.4.5 as well as gcc-part-core-4.3.0, both with the same problem. By the way, `pkg-config --libs gtk+-2.0 gthread-2.0` is resolved to: -LE:/MSYS_GTK/1.0/lib -lgtk-win32-2.0 -lgdk-win32-2.0 -latk-1.0 -lgio-2.0 -lgdk_pixbuf-2.0 -lpangowin32-1.0 -lgdi32 -lpangocairo-1.0 -lpango-1.0 -lcairo -lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lglib-2.0 -lintl Again, compiler commands work fine, even if they contain a similar component like `pkg-config --cflags gtk+-2.0 gthread-2.0`. It's only about linking. GTK for Windows can be downloaded here: http://www.gtk.org/download-windows.html Direct link to the all-in-one bundle: http://ftp.gnome.org/pub/gnome/binaries/win32/gtk+/2.14/gtk+-bundle_2.14.6-20081216_win32.zip -- Cheers, Oliver 'Bloody' Lange. |
From: Chris W. <ch...@qw...> - 2008-12-19 18:54:35
|
Hi Oliver, On Fri, 19 Dec 2008, Oliver Lange wrote: > I'm having trouble compiling a GTK application for Win32 using MinGW > under MSys. While the compiler commands work fine, the following link > command causes trouble: > > gcc -Wall `pkg-config --libs gtk+-2.0 gthread-2.0` -o MyPrg.exe > src/main.o src/app.o src/cpu.o src/io.o src/str.o src/sys.o > > output: > undefined reference to g_printf > undefined reference to g_object_unref > ... and so on > > When i just modify the order of args in the command like this: > > gcc -o MyPrg.exe src/main.o src/app.o src/cpu.o src/io.o src/str.o > src/sys.o -Wall `pkg-config --libs gtk+-2.0 gthread-2.0` > > ...then linking works fine. It is well known that the MinGW/gcc linker is very sensitive to order of options on the command line: http://www.mingw.org/wiki/The_linker_consistently_giving_undefined_references http://www.mingw.org/wiki/Specify_the_libraries_for_the_linker_to_use > The matter is, i have to put '-o MyPrg.exe' and especially all object > filenames at the beginning of the command line, followed by all other > options... > > This problem ain't easy to circumvent because the linker commands in > question are generated by either autotools or SCons, both causing the > same trouble. I'm afraid you'll have to fix them anyway, or the build files that they read, or manually hack their output. Cheers, Chris. -- _____ __ _ \ __/ / ,__(_)_ | Chris Wilson <0000 at qwirx.com> - Cambs UK | / (_/ ,\/ _/ /_ \ | Security/C/C++/Java/Ruby/Perl/SQL Developer | \ _/_/_/_//_/___/ | Stop nuclear war http://www.nuclearrisk.org | |
From: Oliver L. <bl...@bl...> - 2008-12-19 19:59:41
|
Chris Wilson schrieb: > Hi Oliver, > > It is well known that the MinGW/gcc linker is very sensitive to order of > options on the command line: > > http://www.mingw.org/wiki/The_linker_consistently_giving_undefined_references > http://www.mingw.org/wiki/Specify_the_libraries_for_the_linker_to_use > Thank you very much for the links and the quick reply. I couldn't believe that this problem is part of the standard Wiki... > > I'm afraid you'll have to fix them anyway, or the build files that they > read, or manually hack their output. > Me fixing autotools? Muahahaa.. good one! :D Seriously, is it planned to keep this bug forever? Renders MinGW pretty much unusable... if it can't build software based on autotools, SCons or other common build envs, then what's the purpose of MinGW? No offense... Thanks again for the quick help. -- Cheers, Oliver 'Bloody' Lange. |
From: Chris W. <ch...@qw...> - 2008-12-19 20:07:31
|
Hi Oliver, On Fri, 19 Dec 2008, Oliver Lange wrote: > Thank you very much for the links and the quick reply. I couldn't > believe that this problem is part of the standard Wiki... Perhaps if you had read it first, or searched for the error message, then it would not be so hard to believe :) > > I'm afraid you'll have to fix them anyway, or the build files that > > they read, or manually hack their output. > > Me fixing autotools? Muahahaa.. good one! :D > > Seriously, is it planned to keep this bug forever? Renders MinGW pretty > much unusable... if it can't build software based on autotools, SCons or > other common build envs, then what's the purpose of MinGW? This is NOT a bug in MinGW. As Tor Lillqvist stated, it is a bug in Autotools and SCons (or in the build files of your project) if they produce non-portable output that relies on ELF-specific behaviour for undefined symbols to produce correct output. It would fail with Sun CC and many other compilers. ELF is the exception here, not the rule. Cheers, Chris. -- _____ __ _ \ __/ / ,__(_)_ | Chris Wilson <0000 at qwirx.com> - Cambs UK | / (_/ ,\/ _/ /_ \ | Security/C/C++/Java/Ruby/Perl/SQL Developer | \ _/_/_/_//_/___/ | Stop nuclear war http://www.nuclearrisk.org | |
From: Tor L. <tm...@ik...> - 2008-12-19 19:00:55
|
> The matter is, i have to put '-o MyPrg.exe' and especially all object > filenames at the beginning of the command line, followed by all other > options... You have arrived at the wrong conclusion. The correct conclusion is that you have to put the libraries, i.e. `pkg-config --libs whatever` *after* the object files that contain references to symbols from these libraries. This is indeed the normal, canonical, correct way, and has always been. It also makes sense if you think about it for a moment and imagine the linker handling the command-line arguments in sequence, searching each library to resolve undefined symbols at the point it encounters it on the command line. (I don't think it matters where the -o option is, although traditionally it is placed close to the beginning of the linking command line, before source files and/or object files and libraries.) The cause of the problem is that on Linux it works out fine, more or less always, even if you are sloppy and put the linking options in whatever random order (because ELF executables can contain undefined symbols), so more and more people are learning to do this the wrong way (from a portability point of view). For instance, the common idiom to use a single pkg-config invokation with both --cflags and --libs, as in gcc -o foo `pkg-config --cflags --libs bar` foo.o tem.o is quite non-portable. --tml |
From: Oliver L. <bl...@bl...> - 2008-12-19 20:14:04
|
Tor Lillqvist schrieb: > > You have arrived at the wrong conclusion. The correct conclusion is > that you have to put the libraries, i.e. > `pkg-config --libs whatever` > *after* the object files that contain references to symbols from these > libraries. This is indeed the normal, canonical, correct way, and has > always been. It also makes sense if you think about it for a moment > and imagine the linker handling the command-line arguments in > sequence, searching each library to resolve undefined symbols at the > point it encounters it on the command line. Wow, another fast reply, with helpful info. Well, my understanding (without knowing how the linker actually works), was that the linker should simply collect all arguments, putting object filenames into one list of objects to link, all libs into another list and then applying the remaining options to the build. At least that would be my approach.. but what do i know.. :P So you're saying that the autotools developers, the SCons developers and all the others must update their build systems because they all fail to humbly bow to the merciless implementation quirks of some linkers out there... Ok, joke aside. Of course your explanation is correct and offers some logic. > > The cause of the problem is that on Linux it works out fine, more or > less always, even if you are sloppy and put the linking options in > whatever random order (because ELF executables can contain undefined > symbols), so more and more people are learning to do this the wrong > way (from a portability point of view). > Hmmm, without seeking to annoy anyone, lets say i put the 'main.o' object at the very end of the object file parameter list, wouldnt a linker then have to fail because the previous objects can't be linked since the main() function is still undefined? Doesnt that mean that we all have to specify the object file which contains the main() function first of all? And if i pass further linker options after the object files & libs in the command line, wouldnt the linker ignore these options for all object files stated somewhere earlier on? I mean, it all sounds like as if the linker would actually start linking before it has finished parsing the entire command line... > For instance, the common idiom to use a single pkg-config invokation > with both --cflags and --libs, as in > gcc -o foo `pkg-config --cflags --libs bar` foo.o tem.o > is quite non-portable. > Thats a different story, since the linker might well be a separate program that only knows about how to link something, and vice versa, a compiler might only know about compiling but nothing about linking.. -- Cheers, Oliver 'Bloody' Lange. |
From: Chris W. <ch...@qw...> - 2008-12-19 20:30:33
|
Hi Oliver, On Fri, 19 Dec 2008, Oliver Lange wrote: > Well, my understanding (without knowing how the linker actually works), > was that the linker should simply collect all arguments, putting object > filenames into one list of objects to link, all libs into another list > and then applying the remaining options to the build. At least that > would be my approach.. but what do i know.. :P If that was all that a linker did then it might as well be replaced with "cat". Its most important job is to find unresolved symbol references and resolve them by editing the object files. The GNU linker does this by looking through the list of objects that it has already seen, earlier on the command line. It does NOT build a dependency tree or look at later options when doing so. In the case of ELF, if it fails to resolve a dependency at link time then I believe that it will leave it unresolved, and the ELF loader will search the binary and its shared-object dependencies at run time to see if it can satisfy unresolved symbols. The PE loader used by Windows DOES NOT do this. (This is all conjecture based on the evidence that I see, please correct me if I'm wrong). That should mean that loading a binary that was linked in the wrong order is slower than loading a correctly-linked one, but it still works, so the autotools/scons/makefile developers may have not paid enough attention to the problem to fix it. To be honest I suspect a problem with your build files rather than autotools or scons, as I've used autotools on projects on Windows and it has worked. > So you're saying that the autotools developers, the SCons developers and > all the others must update their build systems because they all fail to > humbly bow to the merciless implementation quirks of some linkers out > there... You need to find out where the problem actually is and file a bug report with them, not with us. I can't see this being fixed in MinGW as it's not our "fault", it's the PE loader in Windows. > Hmmm, without seeking to annoy anyone, lets say i put the 'main.o' > object at the very end of the object file parameter list, wouldnt a > linker then have to fail because the previous objects can't be linked > since the main() function is still undefined? Doesnt that mean that we > all have to specify the object file which contains the main() function > first of all? No, because main() is actually referenced by a CRT file which is invisibly added to the end of the list of files to link, after your main.o. > And if i pass further linker options after the object files & libs > in the command line, wouldnt the linker ignore these options for all > object files stated somewhere earlier on? I mean, it all sounds like > as if the linker would actually start linking before it has finished > parsing the entire command line... Not necessarily, it's only the order of _object files_ on the command line that matters as far as I know. GNU getopt, and probably others, permute the command line as they parse it, moving all the options to the front. > > For instance, the common idiom to use a single pkg-config invokation > > with both --cflags and --libs, as in > > gcc -o foo `pkg-config --cflags --libs bar` foo.o tem.o > > is quite non-portable. > > Thats a different story, since the linker might well be a separate > program that only knows about how to link something, and vice versa, a > compiler might only know about compiling but nothing about linking.. gcc -o foo runs the linker as well. In any case, I think that the point Tor was making is correct, that the gcc tools ARE sensitive to command-line order of objects, and you had best learn to deal with it. Cheers, Chris. -- _____ __ _ \ __/ / ,__(_)_ | Chris Wilson <0000 at qwirx.com> - Cambs UK | / (_/ ,\/ _/ /_ \ | Security/C/C++/Java/Ruby/Perl/SQL Developer | \ _/_/_/_//_/___/ | Stop nuclear war http://www.nuclearrisk.org | |
From: Keith M. <kei...@us...> - 2008-12-19 23:26:21
|
On Friday 19 December 2008 20:30:19 Chris Wilson wrote: > On Fri, 19 Dec 2008, Oliver Lange wrote: > > Well, my understanding (without knowing how the linker actually > > works), was that the linker should simply collect all arguments, > > putting object filenames into one list of objects to link, all > > libs into another list and then applying the remaining options to > > the build. At least that would be my approach.. but what do i > > know.. :P Not very much, about the *normal* behaviour of linkers, on probably the majority of UNIX, and UNIX-alike systems, it would seem ;-) > If that was all that a linker did then it might as well be replaced > with "cat". Its most important job is to find unresolved symbol > references and resolve them by editing the object files. The GNU > linker does this by looking through the list of objects that it has > already seen, earlier on the command line. It does NOT build a > dependency tree or look at later options when doing so. > > In the case of ELF, if it fails to resolve a dependency at link > time then I believe that it will leave it unresolved, and the ELF > loader will search the binary and its shared-object dependencies at > run time to see if it can satisfy unresolved symbols. Not exactly, (and I'm not at all sure of the precise details either). I can say categorically that the rules are the same, no matter what the system -- libraries must be specified *after* the object files which refer to their members. ELF linkers may be more forgiving of incorrect ordering, when the reference can be resolved from a shared object library, but it is still technically an error to rely on this feature; the ELF linker will be just as unforgiving of incorrectly ordered static libraries, as is a PE linker, resulting in similar undefined reference errors. > The PE loader used by Windows DOES NOT do this. > [...] > To be honest I suspect a problem with your build files rather than > autotools or scons, as I've used autotools on projects on Windows > and it has worked. > > > So you're saying that the autotools developers, the SCons > > developers and all the others must update their build systems > > because they all fail to humbly bow to the merciless > > implementation quirks of some linkers out there... No, not at all; he is saying that you, or the maintainers of the package you are having trouble with, should learn to use those tools correctly... > You need to find out where the problem actually is and file a bug > report with them, not with us. I can't see this being fixed in > MinGW as it's not our "fault", it's the PE loader in Windows. It's not even the fault of the PE loader; it is misuse of the tools used to maintain the project files. The autotools, in particular, do work very well on MS-Windows as on GNU/Linux, and on countless other platforms. (I'm sure the other tools mentioned do too; I simply have no experience of them, on which to base any comment). > > Hmmm, without seeking to annoy anyone, lets say i put the > > 'main.o' object at the very end of the object file parameter > > list, wouldnt a linker then have to fail because the previous > > objects can't be linked since the main() function is still > > undefined? Doesnt that mean that we all have to specify the > > object file which contains the main() function first of all? > > No, because main() is actually referenced by a CRT file which is > invisibly added to the end of the list of files to link, after your > main.o. Actually, it's called from the startup module, which is added to the linking list *ahead* of the user specified object files. However, that's mostly irrelevant anyway, because it isn't usual to define main() in a library; it's more common to define it in an explicitly specified object file, which will *always* be copied to the linked image anyway. > > And if i pass further linker options after the object files & > > libs in the command line, wouldnt the linker ignore these options > > for all object files stated somewhere earlier on? I mean, it all > > sounds like as if the linker would actually start linking before > > it has finished parsing the entire command line... > > Not necessarily, it's only the order of _object files_ on the > command line that matters as far as I know. Not at all. The order of object files, (or source files for that matter), doesn't matter at all; every *object* file, whether it is precompiled separately, or "on-the-fly", is copied in its entirety, into the linked image. What does matter is the placement of *libraries*, relative to the objects which reference them; (libraries are not object files, but rather archive collections of multiple object files). Object *members* from any library are only copied to the link image if they define a symbol which was referenced, but not yet defined, in any object file, (or by any selected member from another library), which *precedes* that library on the command line, (or is referenced by another member which has already been selected from the *same* library). > GNU getopt, and probably others, permute the command line as they > parse it, moving all the options to the front. BSD getopt does this too, but both provide a mechanism to disable that feature; the linkers for both these systems do so, and in common with the linkers of most UNIX systems, process arguments and options strictly in the order given on the command line. As Tor has already said, it is traditional to place a `-o exefile' option early on the command line, although this one is perhaps less fussy than any other. In general, you should place options *before* any file to which they should apply, and libraries, (whether they are specified by their full names or using the `-lname' pseudo-option shorthand), *after* the object files referring to them, (and in the case of interdependent libraries, the dependents must *precede* any prerequisites). -- Regards, Keith. |
From: Oliver L. <bl...@bl...> - 2008-12-26 14:43:28
|
Keith Marshall schrieb: > > BSD getopt does this too, but both provide a mechanism to disable that > feature; the linkers for both these systems do so, and in common with > the linkers of most UNIX systems, process arguments and options > strictly in the order given on the command line. > Now i've started something... all because linking indeed only worked under Linux but not on Win32, which made me believe it had to be MinGW. Alright, it's definitely not a MinGW problem. It's the result of an example SCons script which i had to convert to autotools since SCons doesnt work under MSys because it's using Windows path separators from Python for Windows. The original script was also using LDFLAGS for the pkg-config --libs part, and so was my autotools conversion.. Thanks everyone for the detailed answers. -- Cheers, Oliver 'Bloody' Lange. |
From: Ralf W. <Ral...@gm...> - 2008-12-21 10:24:16
|
Hello Oliver, * Oliver Lange wrote on Fri, Dec 19, 2008 at 09:13:52PM CET: > > So you're saying that the autotools developers, the SCons developers > and all the others must update their build systems because they all > fail to humbly bow to the merciless implementation quirks of some > linkers out there... Not really. In the case of Automake, you just shouldn't be using the *LDFLAGS variables instead of the *LDADD/*LIBADD/*LIBS variables, for specifying additional library dependencies. Can't speak for SCons, but I'd bet they have similar ways. Cheers, Ralf |
From: Oliver L. <bl...@bl...> - 2008-12-19 20:32:22
|
Chris Wilson schrieb: > Hi Oliver, > > This is NOT a bug in MinGW. As Tor Lillqvist stated, it is a bug in > Autotools and SCons (or in the build files of your project) if they > produce non-portable output that relies on ELF-specific behaviour for > undefined symbols to produce correct output. It would fail with Sun CC and > many other compilers. ELF is the exception here, not the rule. > > Cheers, Chris. Well that's interesting news i never learned before. A linker starts linking before it has read the entire command line... so i guess i'm best off when i first pass all link options (!), then all objects and then, at the very end, all libs? Sorry guys for raising all the dust.. -- Cheers, Oliver 'Bloody' Lange. |
From: Chris W. <ch...@qw...> - 2008-12-19 20:43:13
|
Hi Oliver, On Fri, 19 Dec 2008, Oliver Lange wrote: > > This is NOT a bug in MinGW. As Tor Lillqvist stated, it is a bug in > > Autotools and SCons (or in the build files of your project) if they > > produce non-portable output that relies on ELF-specific behaviour for > > undefined symbols to produce correct output. It would fail with Sun CC > > and many other compilers. ELF is the exception here, not the rule. > > Well that's interesting news i never learned before. A linker starts > linking before it has read the entire command line... so i guess i'm > best off when i first pass all link options (!), then all objects and > then, at the very end, all libs? > > Sorry guys for raising all the dust.. Please read the rest of my reply, where I talk about gnu getopt permuting the command line to move all the options to the front. So it should not matter in what order you specify the options. Also, libraries can have dependencies on each other, and can even depend on object files, and object files can depend on other object files. There is no guarantee that the ordering you specified will work. The only one that is guaranteed to work is where each item (object file or library) is followed by the ones that it depends on. That may mean specifying the same object files and libraries more than once, in the case of circular dependencies. Cheers, Chris. -- _____ __ _ \ __/ / ,__(_)_ | Chris Wilson <0000 at qwirx.com> - Cambs UK | / (_/ ,\/ _/ /_ \ | Security/C/C++/Java/Ruby/Perl/SQL Developer | \ _/_/_/_//_/___/ | Stop nuclear war http://www.nuclearrisk.org | |
From: Keith M. <kei...@us...> - 2008-12-19 23:35:10
|
On Friday 19 December 2008 20:43:08 Chris Wilson wrote: > Please read the rest of my reply, where I talk about gnu getopt > permuting the command line to move all the options to the front. So > it should not matter in what order you specify the options. No, this is not correct. Please see my other reply -- the command line is *not* permuted by the linker. The order of specification of options, file names and library references, (which are not really options, even though the `-lname' format looks very much like they are), does very much matter. -- Regards, Keith. |
From: Chris W. <ch...@qw...> - 2008-12-19 23:41:01
|
Hi Keith, On Fri, 19 Dec 2008, Keith Marshall wrote: > On Friday 19 December 2008 20:43:08 Chris Wilson wrote: > > Please read the rest of my reply, where I talk about gnu getopt > > permuting the command line to move all the options to the front. So > > it should not matter in what order you specify the options. > > No, this is not correct. Please see my other reply -- the command > line is *not* permuted by the linker. The order of specification of > options, file names and library references, (which are not really > options, even though the `-lname' format looks very much like they > are), does very much matter. Thanks for the enlightenment :) Of course I should have noticed that -lname library references would look like options, and therefore would be permuted if permutation was enabled. Cheers, Chris. -- _____ __ _ \ __/ / ,__(_)_ | Chris Wilson <0000 at qwirx.com> - Cambs UK | / (_/ ,\/ _/ /_ \ | Security/C/C++/Java/Ruby/Perl/SQL Developer | \ _/_/_/_//_/___/ | Stop nuclear war http://www.nuclearrisk.org | |