digitalmars.D.learn - Undefined references when linking to C library
- Peter Federighi (24/24) Dec 22 2010 Hello all.
- Jonathan M Davis (10/37) Dec 22 2010 Did you wrap the C declarations in an extern(C) block? Without that, it'...
- Peter Federighi (18/22) Dec 23 2010 I tried "extern (C)" for the whole module and individually. I get the f...
- Jonathan M Davis (18/42) Dec 23 2010 Yeah. It looks like the compiler is finding the 64-bit versions rather t...
- =?UTF-8?B?IkrDqXLDtG1lIE0uIEJlcmdlciI=?= (18/39) Dec 23 2010 goes for
- wrzosk (5/27) Dec 23 2010 I've had simmilar issue a few days ago. The problem is that global
- Peter Federighi (14/18) Dec 23 2010 Jerome M. Berger 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? 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
On Thursday 23 December 2010 11:38:28 Peter Federighi wrote:Jonathan M Davis wrote: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 DavisDid 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.
Dec 23 2010
Peter Federighi wrote:Jonathan M Davis wrote:t's goingDid you wrap the C declarations in an extern(C) block? Without that, i=goes forto think that your variables are D variables not C variables. The same=on of - inany functions - _especially_ for the functions. In fact, a large porti=followingnot all of - your gpm.d file should likely be in extern(C).=20 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/=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 ==2Edata/usr/lib64/gcc/x86_64-suse-linux/4.5/../../../../lib/libgpm.so: could n=ot readsymbols: 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. =Those filepaths are obtuse, but they do point to the 32 bit libraries. I've succ=essfullycompiled other programs that use C libraries such as SDL and OpenGL (bo=th via theDerelict2 modules). =20I think gpm_zerobased, _bpm_buf and _gpm_arg should be declared __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: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.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
wrzosk wrote:I've had simmilar issue a few days ago. The problem is that global values from Cshould be marked shared in Dextern 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