Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
December 23, 2010 Undefined references when linking to C library | ||||
---|---|---|---|---|
| ||||
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 |
December 23, 2010 Re: Undefined references when linking to C library | ||||
---|---|---|---|---|
| ||||
Posted in reply to Peter Federighi | 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 |
December 23, 2010 Re: Undefined references when linking to C library | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | 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 |
December 23, 2010 Re: Undefined references when linking to C library | ||||
---|---|---|---|---|
| ||||
Posted in reply to Peter Federighi | 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
|
December 23, 2010 Re: Undefined references when linking to C library | ||||
---|---|---|---|---|
| ||||
Posted in reply to Peter Federighi Attachments:
| 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 think gpm_zerobased, _bpm_buf and _gpm_arg should be declared __gshared. Jerome -- mailto:jeberger@free.fr http://jeberger.free.fr Jabber: jeberger@jabber.fr |
December 23, 2010 Re: Undefined references when linking to C library | ||||
---|---|---|---|---|
| ||||
Posted in reply to Peter Federighi | 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.
|
December 24, 2010 Re: Undefined references when linking to C library | ||||
---|---|---|---|---|
| ||||
Posted in reply to wrzosk | wrzosk wrote: > 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. 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 |
Copyright © 1999-2021 by the D Language Foundation