Bang Jun-Young bjy@mogua.org writes:
I've nearly completed new DLL configuration code in configure.in. Before making it available, I need to know what uname(1) command prints out on UnixWare (and Solaris?).
Why do you need that? Using uname(1) in a configure script is almost certainly the wrong thing to do.
On Mon, Jun 04, 2001 at 08:06:44PM -0700, Alexandre Julliard wrote:
Why do you need that? Using uname(1) in a configure script is almost certainly the wrong thing to do.
There are some reasons for that:
1. Configure message is wrong: checking whether we can build a Linux dll... yes I see this even on FreeBSD and NetBSD. :( It's not a Linux dll, but an FreeBSD/NetBSD dll.
2. Linux/FreeBSD/NetBSD running on x86 are all based on ELF, so replacing 'Linux' with 'ELF' would be more appropriate. The problem is, however, they have slightly different linker flags for building shared libraries. For example, giving -Bsymbolic when compiling sources on NetBSD causes an error even though compiler/linker toolchain is almost same as one used in Linux. It's due to different startup code, but unfortunately, I have no idea how to detect it during configure process without help from uname.
3. IMHO, my modification is more readable than existing code.
Jun-Young
On Tue, 5 Jun 2001, Bang Jun-Young wrote:
On Mon, Jun 04, 2001 at 08:06:44PM -0700, Alexandre Julliard wrote:
Why do you need that? Using uname(1) in a configure script is almost certainly the wrong thing to do.
There are some reasons for that:
- Configure message is wrong: checking whether we can build a Linux dll... yes I see this even on FreeBSD and NetBSD. :( It's not a Linux dll, but an FreeBSD/NetBSD dll.
Maybe this message should be changed, yes. But I don't think you should put a `uname` there.
- Linux/FreeBSD/NetBSD running on x86 are all based on ELF, so replacing 'Linux' with 'ELF' would be more appropriate. The problem is, however, they have slightly different linker flags for building shared libraries. For example, giving -Bsymbolic when compiling sources on NetBSD causes an error even though compiler/linker toolchain is almost same as one used in Linux. It's due to different startup code, but unfortunately, I have no idea how to detect it during configure process without help from uname.
If it gives an error then it should be easy to detect with autoconf: Just use the flags that cause the command to fail. If it fails then we must use other flags. Otherwise these are the ones to use. What kind of error is it btw?
- IMHO, my modification is more readable than existing code.
Why don't you show us the new code, or an outline thereof?
-- Francois Gouget fgouget@free.fr http://fgouget.free.fr/ "Lotto: A tax on people who are bad at math." -- unknown "Windows: Microsoft's tax on computer illiterates." -- WE7U
On Tue, Jun 05, 2001 at 12:18:00AM -0700, Francois Gouget wrote:
On Tue, 5 Jun 2001, Bang Jun-Young wrote:
- Configure message is wrong: checking whether we can build a Linux dll... yes I see this even on FreeBSD and NetBSD. :( It's not a Linux dll, but an FreeBSD/NetBSD dll.
Maybe this message should be changed, yes. But I don't think you should put a `uname` there.
Could you explain me a bit further why we shouldn't do that?
- Linux/FreeBSD/NetBSD running on x86 are all based on ELF, so replacing 'Linux' with 'ELF' would be more appropriate. The problem is, however, they have slightly different linker flags for building shared libraries. For example, giving -Bsymbolic when compiling sources on NetBSD causes an error even though compiler/linker toolchain is almost same as one used in Linux. It's due to different startup code, but unfortunately, I have no idea how to detect it during configure process without help from uname.
If it gives an error then it should be easy to detect with autoconf: Just use the flags that cause the command to fail. If it fails then we must use other flags. Otherwise these are the ones to use. What kind of error is it btw?
programs/winetest.c couldn't find where the global variable environ is. It could be easily fixed by adding 'extern char **environ' to the beginning of the file without touching ld flags, but I thought it would be better if I was able to do the same without touching sources instead.
- IMHO, my modification is more readable than existing code.
Why don't you show us the new code, or an outline thereof?
Oh, I'm sorry to forget that. *) Here it is.
Jun-Young
On Wed, 6 Jun 2001, Bang Jun-Young wrote:
On Tue, Jun 05, 2001 at 12:18:00AM -0700, Francois Gouget wrote:
On Tue, 5 Jun 2001, Bang Jun-Young wrote:
- Configure message is wrong: checking whether we can build a Linux dll... yes I see this even on FreeBSD and NetBSD. :( It's not a Linux dll, but an FreeBSD/NetBSD dll.
Maybe this message should be changed, yes. But I don't think you should put a `uname` there.
Could you explain me a bit further why we shouldn't do that?
Maybe it was not your intention but I was afraid that we would end up with something like: "checking whether we can build a `uname` dll..." and then a few lines down: "checking whether we can build a `uname` dll..."
The problem is then you don't know exactly where the message comes from.
[...]
programs/winetest.c couldn't find where the global variable environ is. It could be easily fixed by adding 'extern char **environ' to the beginning of the file without touching ld flags, but I thought it would be better if I was able to do the same without touching sources instead.
It sounds like a compilation error. One that I've seen in a few Winelib programs by the way. The problem is that the Unix C library headers are not entirely compatible with the windows ones. The solution is to use the msvcrt headers, i.e. Wine's microsoft compatible C library headers, and import msvcrt.dll in the '.spec' file too. In winetest I see: envp = environ; /* envp is not valid (yet) in Winelib */ Maybe envp is valid now. If not then it should be fixed and environ removed.
Anyway, if it's a compilation error I don't understand why you would need to change the ld flags and how it could help. Are you getting a link error? What does it say?
- IMHO, my modification is more readable than existing code.
Why don't you show us the new code, or an outline thereof?
Oh, I'm sorry to forget that. *) Here it is.
Here's the problem. Your patch essentially does the following:
OSNAME=`uname` if test "$OSNAME" = "Linux" then # Set flags for Linux elif test "$OSNAME" = "FreeBSD" then # Set flags for FreeBSD elif test "$OSNAME" = "UnixWare" then # Set flags for UnixWare elif ...
But what if one runs this configure script on Darwin. The configure script does not know about it so it will fail although Darwin might behave exactly like FreeBSD. And what if tomorrow the Linux toolchain changes to behave like UnixWare, or something entirely different? This configure script will not work anymore, and when you detect that 'OSNAME==Linux' you'll still have to determine whether to use the old or the new flags somehow. This is the whole point of Autoconf-style scripts: it's pointless to expect to guess how things work based on the name of the platform, i.e what uname returns. Instead you should test features: if I compile&link a test file with the '-shared -Wl,-Bsymbolic' flag combination does it work? If yes then it does not matter whether the platform is Linux, UnixWare or FeeeBSD. We'll just use these flags since they do what we want.
-- Francois Gouget fgouget@free.fr http://fgouget.free.fr/ "Lotto: A tax on people who are bad at math." -- unknown "Windows: Microsoft's tax on computer illiterates." -- WE7U
On Tue, Jun 05, 2001 at 11:51:19PM -0700, Francois Gouget wrote:
Maybe it was not your intention but I was afraid that we would end up with something like: "checking whether we can build a `uname` dll..." and then a few lines down: "checking whether we can build a `uname` dll..."
The problem is then you don't know exactly where the message comes from.
Sorry but I don't catch what you mean quite well. It's obvious which message is printed on the screen, isn't it?
programs/winetest.c couldn't find where the global variable environ is. It could be easily fixed by adding 'extern char **environ' to the beginning of the file without touching ld flags, but I thought it would be better if I was able to do the same without touching sources instead.
It sounds like a compilation error. One that I've seen in a few Winelib programs by the way. The problem is that the Unix C library headers are not entirely compatible with the windows ones. The solution is to use the msvcrt headers, i.e. Wine's microsoft compatible C library headers, and import msvcrt.dll in the '.spec' file too. In winetest I see: envp = environ; /* envp is not valid (yet) in Winelib */ Maybe envp is valid now. If not then it should be fixed and environ removed.
Anyway, if it's a compilation error I don't understand why you would need to change the ld flags and how it could help. Are you getting a link error? What does it say?
Oh, I'm sorry to forget that. *) Here it is.
Here's the problem. Your patch essentially does the following:
OSNAME=`uname` if test "$OSNAME" = "Linux" then # Set flags for Linux elif test "$OSNAME" = "FreeBSD" then # Set flags for FreeBSD elif test "$OSNAME" = "UnixWare" then # Set flags for UnixWare elif ...
No, it should be read as:
if test "$OSNAME" = "Linux" then # Check if flags work for Linux AC_CACHE_CHECK(...) if test "$ac_cv_c_dll_linux" = "yes" # Then we can safely set flags LDSHARED="..." fi elif ...
What if the flags don't work? Then we don't have to try with UnixWare or FreeBSD again. Simply you won't be able to build shared libraries on that platform and configure will give a warning.
But what if one runs this configure script on Darwin. The configure script does not know about it so it will fail although Darwin might behave exactly like FreeBSD. And what if tomorrow the Linux toolchain changes to behave like UnixWare, or something entirely different? This configure script will not work anymore, and when you detect that 'OSNAME==Linux' you'll still have to determine whether to use the old or the new flags somehow.
Existing configure won't work, neither. We should add or modify code in any case.
This is the whole point of Autoconf-style scripts: it's pointless to expect to guess how things work based on the name of the platform, i.e what uname returns. Instead you should test features: if I compile&link a test file with the '-shared -Wl,-Bsymbolic' flag combination does it work? If yes then it does not matter whether the platform is Linux, UnixWare or FeeeBSD. We'll just use these flags since they do what we want.
The combination works itself nicely with NetBSD, but compilation doesn't. That's why I feel it's difficult to write valid test. It will be easier to add "extern char **environ".
What do you think about replacing "Linux dll" with "GNU style ELF dll"?
Jun-Young
On Wed, 6 Jun 2001, Bang Jun-Young wrote:
On Tue, Jun 05, 2001 at 11:51:19PM -0700, Francois Gouget wrote:
Maybe it was not your intention but I was afraid that we would end up with something like: "checking whether we can build a `uname` dll..." and then a few lines down: "checking whether we can build a `uname` dll..."
The problem is then you don't know exactly where the message comes from.
Sorry but I don't catch what you mean quite well. It's obvious which message is printed on the screen, isn't it?
Given this message and the code below can you tell me which line printed the message? checking whether we can build a Linux dll...
Code (based on current configure): --- cut here --- if test "$LIBEXT" = "so" then AC_CACHE_CHECK("whether we can build a `uname` dll", ... if test "$ac_cv_c_dll_linux" = "yes" then ... else AC_CACHE_CHECK(whether we can build a `uname` dll, ... if test "$ac_cv_c_dll_unixware" = "yes" then ... else AC_CACHE_CHECK("whether we can build a `uname` dll", ...
But it's obvious this is not what you intended to do so I apologize for causing confusion.
[...]
Oh, I'm sorry to forget that. *) Here it is.
Here's the problem. Your patch essentially does the following:
OSNAME=`uname` if test "$OSNAME" = "Linux" then # Set flags for Linux elif test "$OSNAME" = "FreeBSD" then # Set flags for FreeBSD elif test "$OSNAME" = "UnixWare" then # Set flags for UnixWare elif ...
No, it should be read as:
if test "$OSNAME" = "Linux" then # Check if flags work for Linux AC_CACHE_CHECK(...) if test "$ac_cv_c_dll_linux" = "yes" # Then we can safely set flags LDSHARED="..." fi elif ...
I know but the only flags you check in the Linux case are one set of flags. You cannot assume that these are the only flags that will *ever* work on Linux and that these flags will *never* work on any other platform. What if tomorrow the Linux guys say 'what we have done until now is really broken, we should do like the UnixWare guys'? Your script won't check the flags used on UnixWare if you know you are on a Linux platform thus it will break while the original one would have kept on working. Also your uname checks cause you to duplicates the checks done on Linux for the FreeBSD case too.
What if the flags don't work? Then we don't have to try with
UnixWare or FreeBSD again. Simply you won't be able to build shared libraries on that platform and configure will give a warning.
But what if one runs this configure script on Darwin. The configure script does not know about it so it will fail although Darwin might behave exactly like FreeBSD. And what if tomorrow the Linux toolchain changes to behave like UnixWare, or something entirely different? This configure script will not work anymore, and when you detect that 'OSNAME==Linux' you'll still have to determine whether to use the old or the new flags somehow.
Existing configure won't work, neither. We should add or modify code in any case.
Yes but not by testing uname. And deriving the compile flags from AC_CANONICAL_HOST is not any better. There is no link between `uname` and the flags to be used for compiling and linking. Take Solaris for instance. How do you know based on `uname` whether to use the native compiler flags or the gcc flags? Anyway, what you want is change the NetBSD flags. What about the following change:
--- cut here --- Index: configure.in =================================================================== RCS file: /home/cvs/wine/wine/configure.in,v retrieving revision 1.204 diff -u -r1.204 configure.in --- configure.in 2001/05/31 21:35:15 1.204 +++ configure.in 2001/06/06 16:16:45 @@ -620,13 +620,13 @@ AC_CACHE_CHECK("whether we can build a NetBSD a.out dll", ac_cv_c_dll_netbsd, [saved_cflags=$CFLAGS - CFLAGS="$CFLAGS -fPIC -Wl,-Bshareable,-Bforcearchive" + CFLAGS="$CFLAGS -fPIC -shared -Wl,-soname,conftest.so.1.0" AC_TRY_LINK(,[return 1],ac_cv_c_dll_netbsd="yes",ac_cv_c_dll_netbsd="no") CFLAGS=$saved_cflags ]) if test "$ac_cv_c_dll_netbsd" = "yes" then - LDSHARED="$(CC) -Wl,-Bshareable,-Bforcearchive" + LDSHARED="$(CC) -shared $(SONAME:%=-Wl,-soname,%) -Wl,-rpath,$(libdir)" LDDLLFLAGS="" #FIXME fi fi --- cut here ---
Now I have the following questions: * we had different flags before. How come they don't work? Did the toolchain change on NetBSD? Should we test the old flags too in case we are on an old NetBSD? * Don't you need flags in LDDLLFLAGS too? * it seems you don't have an equivalent to '-Bsymbolic' in your flags? This is pretty important for Wine dlls to work correctly (they will compile and link without it, but run?). Is there an equivalent flag on NetBSD or is it simply assumed by default? hmm, maybe it's assume since '-Bsymbolic' is an ELF thing and NetBSD appears to be a.out based. In any case, to help you check if there's something similar here's what 'info ld' has to say about '-Bsymbolic' here:
When creating a shared library, bind references to global symbols to the definition within the shared library, if any. Normally, it is possible for a pro gram linked against a shared library to override the definition within the shared library. This option is only meaningful on ELF platforms which support shared libraries.
[...]
The combination works itself nicely with NetBSD, but compilation doesn't. That's why I feel it's difficult to write valid test. It will be easier to add "extern char **environ".
So it's a compilation error, not a link error. Why change the link flags then?
What do you think about replacing "Linux dll" with "GNU style ELF dll"?
Could work. I guess none of the other platforms is covered by this description?
-- Francois Gouget fgouget@free.fr http://fgouget.free.fr/ In theory, theory and practice are the same, but in practice they're different.
On Wed, Jun 06, 2001 at 09:42:17AM -0700, Francois Gouget wrote:
I know but the only flags you check in the Linux case are one set of flags. You cannot assume that these are the only flags that will *ever* work on Linux and that these flags will *never* work on any other platform. What if tomorrow the Linux guys say 'what we have done until now is really broken, we should do like the UnixWare guys'? Your script won't check the flags used on UnixWare if you know you are on a Linux platform thus it will break while the original one would have kept on working.
That will never happen, I believe. We always communicate closely with each other, at least in the free/open source world. ;)
Also your uname checks cause you to duplicates the checks done on Linux for the FreeBSD case too.
Yes, they could be merged together.
Existing configure won't work, neither. We should add or modify code in any case.
Yes but not by testing uname. And deriving the compile flags from AC_CANONICAL_HOST is not any better. There is no link between `uname` and the flags to be used for compiling and linking. Take Solaris for instance. How do you know based on `uname` whether to use the native compiler flags or the gcc flags? Anyway, what you want is change the NetBSD flags. What about the following change:
It doesn't help much because:
* Code itself will never executed. Checking for Linux always succeeds on NetBSD 1.5 or later which are based on ELF. * NetBSD a.out support should be removed. Wine will never run on NetBSD 1.4 or earlier which lack kernel threads. They are no more actively maintained by core team.
Now I have the following questions:
- we had different flags before. How come they don't work? Did the
toolchain change on NetBSD? Should we test the old flags too in case we are on an old NetBSD?
- Don't you need flags in LDDLLFLAGS too?
- it seems you don't have an equivalent to '-Bsymbolic' in your flags?
This is pretty important for Wine dlls to work correctly (they will compile and link without it, but run?). Is there an equivalent flag on NetBSD or is it simply assumed by default? hmm, maybe it's assume since '-Bsymbolic' is an ELF thing and NetBSD appears to be a.out based. In any case, to help you check if there's something similar here's what 'info ld' has to say about '-Bsymbolic' here:
When creating a shared library, bind references to global symbols to the definition within the shared library, if any. Normally, it is possible for a pro)B� gram linked against a shared library to override the definition within the shared library. This option is only meaningful on ELF platforms which support shared libraries.
[...]
The combination works itself nicely with NetBSD, but compilation doesn't. That's why I feel it's difficult to write valid test. It will be easier to add "extern char **environ".
So it's a compilation error, not a link error. Why change the link flags then?
Oops, I'm sorry. It wasn't a compilation error. I got number of linking errors with winetest:
perl.o(.text+0xc7f): undefined reference to `environ' perl.o(.text+0x4077): undefined reference to `environ' ... util.o(.text+0x794): undefined reference to `environ' ...
All of above object s are in lib/libperl.a.
Without -Bsymbolic, I had no problem.
What do you think about replacing "Linux dll" with "GNU style ELF dll"?
Could work. I guess none of the other platforms is covered by this description?
A new patch will be sent to wine-patches@ shortly.
Jun-Young
On Thu, 7 Jun 2001, Bang Jun-Young wrote:
On Wed, Jun 06, 2001 at 09:42:17AM -0700, Francois Gouget wrote:
I know but the only flags you check in the Linux case are one set of flags. You cannot assume that these are the only flags that will *ever* work on Linux and that these flags will *never* work on any other platform. What if tomorrow the Linux guys say 'what we have done until now is really broken, we should do like the UnixWare guys'? Your script won't check the flags used on UnixWare if you know you are on a Linux platform thus it will break while the original one would have kept on working.
That will never happen, I believe.
Maybe not with UnixWare, but that's not the point. Change is a fact of life.
[...]
Anyway, what you want is change the NetBSD flags. What about the following change:
[snipped]
It doesn't help much because:
- Code itself will never executed. Checking for Linux always succeeds on NetBSD 1.5 or later which are based on ELF.
So using the 'Linux' flags does not work. What are the symptoms? Is it just the link problem with winetest or is there other issues with the rest of Wine?
- NetBSD a.out support should be removed. Wine will never run on NetBSD 1.4 or earlier which lack kernel threads. They are no more actively maintained by core team.
Ok, seems reasonable.
[...]
Oops, I'm sorry. It wasn't a compilation error. I got number of linking errors with winetest:
perl.o(.text+0xc7f): undefined reference to `environ' perl.o(.text+0x4077): undefined reference to `environ' ... util.o(.text+0x794): undefined reference to `environ' ...
All of above object s are in lib/libperl.a.
Hmm, linking with libperl.a to get 'environ' seems wrong. 'environ' is a C library thing, it should be in a C library too. What does 'nm /usr/lib/libperl.a | grep -w environ' print? Here I get a number of U environ Which means environ is not defined in libperl (U=Undefined, i.e. get it elsewhere). Maybe the command that is issued for the link is wrong. Part of it is provided by perl itself which is supposed to know best. But here I had to create a symbolic link from '/usr/lib/libperl.so' to '/usr/lib/libperl.so.5.6.0' so I don't trust it entirely. What is the command that you get? If you add 'char** foo=environ;' somewhere in winclock.c, does it fail to compile too? What about a simple 'foo.c' program compiled outside of Wine?
Without -Bsymbolic, I had no problem.
Maybe but '-Bsymbolic' is very important for Wine and I doubt you will get a working Wine without it. But Alexandre is the real specialist who can explain why '-Bsymbolic' is needed.
-- Francois Gouget fgouget@free.fr http://fgouget.free.fr/ 1 + e ^ ( i * pi ) = 0
On Wed, 6 Jun 2001, Francois Gouget wrote:
On Thu, 7 Jun 2001, Bang Jun-Young wrote: [...]
Oops, I'm sorry. It wasn't a compilation error. I got number of linking errors with winetest:
perl.o(.text+0xc7f): undefined reference to `environ' perl.o(.text+0x4077): undefined reference to `environ' ... util.o(.text+0x794): undefined reference to `environ' ...
All of above object s are in lib/libperl.a.
Exactly *which* link command fails like this?
Also, state the binutils version. For example, I know there was a -Bsymbolic bug introduced in 2.11.90.0.5 (a snapshot release?) that hit some debian-unstable users before it was fixed in 2.11.90.0.7, according to the changelog.Debian file.
Hmm, linking with libperl.a to get 'environ' seems wrong. 'environ' is a C library thing, it should be in a C library too. What does 'nm /usr/lib/libperl.a | grep -w environ' print? Here I get a number of U environ Which means environ is not defined in libperl (U=Undefined, i.e. get it elsewhere).
This is hardly interesting. It's obvious (and natural) that libperl doesn't define it, otherwise the reference would probably not be undefined... it's a libc symbol.
Maybe the command that is issued for the link is wrong. Part of it is provided by perl itself which is supposed to know best. But here I had to create a symbolic link from '/usr/lib/libperl.so' to '/usr/lib/libperl.so.5.6.0' so I don't trust it entirely.
Did you install libperl-dev?
Without -Bsymbolic, I had no problem.
Maybe but '-Bsymbolic' is very important for Wine and I doubt you will get a working Wine without it. But Alexandre is the real specialist who can explain why '-Bsymbolic' is needed.
I'd think he has better things to spend his time on than to explain this again. Summary: -Bsymbolic is necessary for the DLL import mechanism to work; it is imperative that when the .so is created, the imported symbols are immediately linked to the import stubs (which winebuild generates) when linking the .so. Without -Bsymbolic, this doesn't happen during link, and the imports will be handled by ld.so instead. And that... can get BAD.