This is the mail archive of the cygwin-apps mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [64bit] autoconf test for GetConsoleScreenBufferInfo


On May 14 20:30, marco atzeri wrote:
> the attached test extracted by configure of hdf5 is
> failing on 32 bit as expected with
> 
> /tmp/cc5L84Vo.o: In function `main':
> /cygdrive/e/cygwin64/tmp/conftest.c:140: undefined reference to
> `_GetConsoleScreenBufferInfo'
> collect2: ld returned 1 exit status
> 
> but it is passing on 64 bit
> 
> ls -sh conftest.exe
> 64K conftest.exe
> 
> so I guess there is some weird include pulling w32api
> as the definition is only on the w32api
> 
> $ grep -rH GetConsoleScreenBufferInfo /usr/include/*
> /usr/include/w32api/wincon.h:  WINBASEAPI WINBOOL WINAPI
> GetConsoleScreenBufferInfo(HANDLE
> hConsoleOutput,PCONSOLE_SCREEN_BUFFER_INFO
> lpConsoleScreenBufferInfo);
> /usr/include/w32api/wincon.h:WINBASEAPI WINBOOL WINAPI
> GetConsoleScreenBufferInfoEx(
> 
> 
> To test just ". config_test.txt"

I think this is another problem.  It's not exactly a problem in fact,
but just the way the 64 bit ABI works.

On 32 bit, all functions exported by Windows DLLs are using the
"stdcall" calling convention.  This calling convention uses a symbol
decoration which denotes the number of bytes on stack used by the
arguments of the function.  That's what WINAPI does in the Windows 
header files.  OTOH, the "cdecl" default calling convention does not add
this decoration to the symbol name.

So what happens is this:  Given that you didn't include the windows.h
header file, gcc assumes that GetConsoleScreenBufferInfo is using the
default "cdecl" calling convention.  It emits a reference to the
external function "_GetConsoleScreenBufferInfo" (the leading underscore
is an integral part of all C calling conventions on 32 bit ix86).
However, GetConsoleScreenBufferInfo is a stdcall function exported by
kernel32.dll.  So the exported symbol is
"_GetConsoleScreenBufferInfo@8".  Therefore, on 32 bit, even though all
executables are linked against kernel32.dll, the reference can't be
resolved due to the name difference.

This does not happen on 64 bit for the following reason:  On 64 bit
there are only two calling convention, one of them the Microsoft
convention called MS-ABI, the other one used by all other x86_64 systems
called SYSV-ABI.  But either way, none of the two conventions add a
symbol decoration, so gcc emits a reference to
"GetConsoleScreenBufferInfo" (no underscore either on x86_64) and
kernel32.dll exports the function as "GetConsoleScreenBufferInfo".
Therefore the symbol can be resolved at link time.

I fear you might not like my answer:  The problem here is NOT that the
linking works, the problem is that, if the configure test is used to
find out if we're running on Windows or not, it's simply not feasible
anymore when taking x86_64 Cygwin into account.  This has to be solved
differently, for instance by not performing this test if configure
already knows the target is Cygwin.


Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Maintainer                 cygwin AT cygwin DOT com
Red Hat


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]