digitalmars.D.learn - Undefined references when linking to C library
- Peter Federighi <pfederighi yahoo.com> Dec 22 2010
- Jonathan M Davis <jmdavisProg gmx.com> Dec 22 2010
- Peter Federighi <pfederighi yahoo.com> Dec 23 2010
- =?UTF-8?B?IkrDqXLDtG1lIE0uIEJlcmdlciI=?= <jeberger free.fr> Dec 23 2010
- wrzosk <dprogr gmail.com> Dec 23 2010
- Peter Federighi <pfederighi yahoo.com> Dec 23 2010
- Jonathan M Davis <jmdavisProg gmx.com> Dec 23 2010
Hello all. I'm writing a simple terminal game (that will eventually be turned into a simple SDL game) and thought I would add mouse support via libgpm. So, I converted gpm.h into gpm.d. Perhaps I didn't do this correctly because I get several undefined references when trying to link. Here's an example: The original gpm.h says: extern int gpm_zerobased; extern unsigned char _gpm_buf[]; extern unsigned short * _gpm_arg; My gpm.d says: extern int gpm_zerobased; extern char* _gpm_buf; extern ushort* _gpm_arg; When running 'dmd gev.d gpm.d -L-lgpm', I get: gpm.d:(.text._D3gpm15Gpm_DrawPointerFiiiZv+0x12): undefined reference to `_D3gpm8_gpm_bufPa' gpm.d:(.text._D3gpm15Gpm_DrawPointerFiiiZv+0x26): undefined reference to `_D3gpm13gpm_zerobasedi' gpm.d:(.text._D3gpm15Gpm_DrawPointerFiiiZv+0x34): undefined reference to `_D3gpm8_gpm_argPt' Does anyone have any ideas? Thank you, - Peter
Dec 22 2010
On Wednesday 22 December 2010 19:25:35 Peter Federighi wrote:Hello all. I'm writing a simple terminal game (that will eventually be turned into a simple SDL game) and thought I would add mouse support via libgpm. So, I converted gpm.h into gpm.d. Perhaps I didn't do this correctly because I get several undefined references when trying to link. Here's an example: The original gpm.h says: extern int gpm_zerobased; extern unsigned char _gpm_buf[]; extern unsigned short * _gpm_arg; My gpm.d says: extern int gpm_zerobased; extern char* _gpm_buf; extern ushort* _gpm_arg; When running 'dmd gev.d gpm.d -L-lgpm', I get: gpm.d:(.text._D3gpm15Gpm_DrawPointerFiiiZv+0x12): undefined reference to `_D3gpm8_gpm_bufPa' gpm.d:(.text._D3gpm15Gpm_DrawPointerFiiiZv+0x26): undefined reference to `_D3gpm13gpm_zerobasedi' gpm.d:(.text._D3gpm15Gpm_DrawPointerFiiiZv+0x34): undefined reference to `_D3gpm8_gpm_argPt' Does anyone have any ideas?
Did you wrap the C declarations in an extern(C) block? Without that, it's going to think that your variables are D variables not C variables. The same goes for any functions - _especially_ for the functions. In fact, a large portion of - in not all of - your gpm.d file should likely be in extern(C). You can try htod ( http://www.digitalmars.com/d/2.0/htod.html ) and see what it creates. It won't necessarily be correct, but it might be, and it might give you a better idea of where you screwed up. It's a Windows program, but it will run in wine. - Jonathan M Davis
Dec 22 2010
Jonathan M Davis wrote:Did you wrap the C declarations in an extern(C) block? Without that, it's going to think that your variables are D variables not C variables. The same goes for any functions - _especially_ for the functions. In fact, a large portion of - in not all of - your gpm.d file should likely be in extern(C).
I tried "extern (C)" for the whole module and individually. I get the following error: /usr/lib64/gcc/x86_64-suse-linux/4.5/../../../../x86_64-suse-linux/bin/ld: _gpm_arg: TLS reference in gev.o mismatches non-TLS definition in /usr/lib64/gcc/x86_64-suse-linux/4.5/../../../../lib/libgpm.so section .data /usr/lib64/gcc/x86_64-suse-linux/4.5/../../../../lib/libgpm.so: could not read symbols: Bad value collect2: ld returned 1 exit status --- errorlevel 1 Is this a 32/64 bit issue? I have both versions of libgpm installed. Those file paths are obtuse, but they do point to the 32 bit libraries. I've successfully compiled other programs that use C libraries such as SDL and OpenGL (both via the Derelict2 modules). I also tried htod and compared the output with what I wrote. The differences are inconsequential. Thank you, - Peter Federighi
Dec 23 2010
Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Peter Federighi wrote:Jonathan M Davis wrote:Did you wrap the C declarations in an extern(C) block? Without that, i=
to think that your variables are D variables not C variables. The same=
any functions - _especially_ for the functions. In fact, a large porti=
not all of - your gpm.d file should likely be in extern(C).
I tried "extern (C)" for the whole module and individually. I get the =
error: /usr/lib64/gcc/x86_64-suse-linux/4.5/../../../../x86_64-suse-linux/bin/=
_gpm_arg: TLS reference in gev.o mismatches non-TLS definition in /usr/lib64/gcc/x86_64-suse-linux/4.5/../../../../lib/libgpm.so section =
/usr/lib64/gcc/x86_64-suse-linux/4.5/../../../../lib/libgpm.so: could n=
symbols: Bad value collect2: ld returned 1 exit status --- errorlevel 1 =20 Is this a 32/64 bit issue? I have both versions of libgpm installed. =
paths are obtuse, but they do point to the 32 bit libraries. I've succ=
compiled other programs that use C libraries such as SDL and OpenGL (bo=
Derelict2 modules). =20
__gshared. Jerome --=20 mailto:jeberger free.fr http://jeberger.free.fr Jabber: jeberger jabber.fr
Dec 23 2010
On 23.12.2010 20:38, Peter Federighi wrote:Jonathan M Davis wrote:Did you wrap the C declarations in an extern(C) block? Without that, it's going to think that your variables are D variables not C variables. The same goes for any functions - _especially_ for the functions. In fact, a large portion of - in not all of - your gpm.d file should likely be in extern(C).
I tried "extern (C)" for the whole module and individually. I get the following error: /usr/lib64/gcc/x86_64-suse-linux/4.5/../../../../x86_64-suse-linux/bin/ld: _gpm_arg: TLS reference in gev.o mismatches non-TLS definition in /usr/lib64/gcc/x86_64-suse-linux/4.5/../../../../lib/libgpm.so section .data /usr/lib64/gcc/x86_64-suse-linux/4.5/../../../../lib/libgpm.so: could not read symbols: Bad value collect2: ld returned 1 exit status --- errorlevel 1 Is this a 32/64 bit issue? I have both versions of libgpm installed. Those file paths are obtuse, but they do point to the 32 bit libraries. I've successfully compiled other programs that use C libraries such as SDL and OpenGL (both via the Derelict2 modules). I also tried htod and compared the output with what I wrote. The differences are inconsequential. Thank you, - Peter Federighi
I've had simmilar issue a few days ago. The problem is that global values from C should be marked shared in D extern int val; -> extern (C) shared int val; or maybe __gshared. Both makes linking stage finishes with success.
Dec 23 2010
wrzosk wrote:I've had simmilar issue a few days ago. The problem is that global values from C
extern int val; -> extern (C) shared int val; or maybe __gshared. Both makes linking stage finishes with success.
Jerome M. Berger wrote:I think gpm_zerobased, _bpm_buf and _gpm_arg should be declared __gshared.
Indeed. So I added a bunch of "__gshared"s to all the variables and it compiles and links. Yah! I just have to remember to declare handler functions with extern (C), otherwise the program will segfault once the handler returns. Where should I post/upload the files that I converted? There are a whole two of them: One is gpm.h which is specific to libgpm. The other is paths.h which I was surprised to find not already available. I would assume that it should be available as std.c.linux.paths or core.sys.posix.paths. Also, should the files end with .d or .di I may be the only person who wants to use libgpm with D, but I figure it should be available just in case. Thank you all for your help. - Peter Federighi
Dec 23 2010
On Thursday 23 December 2010 11:38:28 Peter Federighi wrote:Jonathan M Davis wrote:Did you wrap the C declarations in an extern(C) block? Without that, it's going to think that your variables are D variables not C variables. The same goes for any functions - _especially_ for the functions. In fact, a large portion of - in not all of - your gpm.d file should likely be in extern(C).
I tried "extern (C)" for the whole module and individually. I get the following error: /usr/lib64/gcc/x86_64-suse-linux/4.5/../../../../x86_64-suse-linux/bin/ld: _gpm_arg: TLS reference in gev.o mismatches non-TLS definition in /usr/lib64/gcc/x86_64-suse-linux/4.5/../../../../lib/libgpm.so section .data /usr/lib64/gcc/x86_64-suse-linux/4.5/../../../../lib/libgpm.so: could not read symbols: Bad value collect2: ld returned 1 exit status --- errorlevel 1 Is this a 32/64 bit issue? I have both versions of libgpm installed. Those file paths are obtuse, but they do point to the 32 bit libraries. I've successfully compiled other programs that use C libraries such as SDL and OpenGL (both via the Derelict2 modules). I also tried htod and compared the output with what I wrote. The differences are inconsequential.
Yeah. It looks like the compiler is finding the 64-bit versions rather than the 32-bit versions. How to fix that will likely depend on the libraries in question and on how your system is set up. Obviously, a 32-bit chroot environment would fix the problem, but that's also obviously not a pleasant, or even necessarily simple, solution. I'm not really all that well-versed in dealing with linking issues like this, but I'd say that either the compiler is just not finding the 32-bit versions, because of a messed up or missing path, or you need to be linking separately because you're on a 64-bit system (which I don't _think_ is the case, but it might be). Regardless, you can try compiling all of the code with -c and then linking it with gcc directly (probably with -m32). Unfortunately, while I do run a 64-bit environment, due to problems with Arch and multilib systems, I've generally had to run dmd in a chrooted environment, and you don't have to deal with the 32-bit vs 64-bit issues with that, so I don't have much experience with this sort of problem. Regardless, I'll be very glad when the 64-bit port of dmd is completed. - Jonathan M Davis
Dec 23 2010









=?UTF-8?B?IkrDqXLDtG1lIE0uIEJlcmdlciI=?= <jeberger free.fr> 