www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - gcc linkage problem with C & D

reply Charles D Hixson <charleshixsn earthlink.net> writes:
Here's what I have.  I hope it makes sense to other people:
test0c.c is -->
#include	<stdio.h>

int	test()
{  printf ("Hello, world\n");
    return  0;
}

//int main(int argc, char *argv[])
//{	return	test(argc, argv);	}

test0d.d is -->
extern(C):
	int	test();

void	main()
{	test;	}

Makefile.test0 is -->
all:  test0

test0:  test0d.o test0c.o
	$(CC)	test0d.o test0c.o -o test0

test0d.o:
	dmd  -c test0d.d $(LL)  -I~/src/phobos test0c.o

test0c.o: test0c.c
	$(CC)  -c test0c.c -o test0c.o

clean:
	rm -f *.o  test0

THEN:
$ make -fMakefile.test0
dmd  -c test0d.d   -I~/src/phobos test0c.o
cc  -c test0c.c -o test0c.o
cc      test0d.o test0c.o -o test1
test0d.o: In function `gcc2_compiled.':
test0d.d:(.text+0x8): undefined reference to `_Dmodule_ref'
collect2: ld returned 1 exit status
make: *** [test0] Error 1

I don't know how to even get started addressing this problem. 
  bud dies with even less informative messages.
Jul 25 2007
parent reply Carlos Santander <csantander619 gmail.com> writes:
Charles D Hixson escribió:
 Here's what I have.  I hope it makes sense to other people:
 test0c.c is -->
 #include    <stdio.h>
 
 int    test()
 {  printf ("Hello, world\n");
    return  0;
 }
 
 //int main(int argc, char *argv[])
 //{    return    test(argc, argv);    }
 
 test0d.d is -->
 extern(C):
     int    test();
 
 void    main()
 {    test;    }
 
 Makefile.test0 is -->
 all:  test0
 
 test0:  test0d.o test0c.o
     $(CC)    test0d.o test0c.o -o test0
 
 test0d.o:
     dmd  -c test0d.d $(LL)  -I~/src/phobos test0c.o
 
 test0c.o: test0c.c
     $(CC)  -c test0c.c -o test0c.o
 
 clean:
     rm -f *.o  test0
 
 THEN:
 $ make -fMakefile.test0
 dmd  -c test0d.d   -I~/src/phobos test0c.o
 cc  -c test0c.c -o test0c.o
 cc      test0d.o test0c.o -o test1
 test0d.o: In function `gcc2_compiled.':
 test0d.d:(.text+0x8): undefined reference to `_Dmodule_ref'
 collect2: ld returned 1 exit status
 make: *** [test0] Error 1
 
 I don't know how to even get started addressing this problem.  bud dies 
 with even less informative messages.
You're missing -lphobos (-lgphobos if you were using GDC). The easiest way to do it is like this: dmd -c test0d.d cc -c test0c.c -o test0c.o dmd test0d.o test0c.o That first step is only if you absolutely require separate commands for compiling and linking. Otherwise, you could remove it and pass test0d.d to DMD instead of test0d.o. Also, if DMD is properly set up, you shouldn't need to pass -I~/src/phobos to it. -- Carlos Santander Bernal
Jul 25 2007
parent reply Charles D Hixson <charleshixsn earthlink.net> writes:
Carlos Santander wrote:
 Charles D Hixson escribió:
 Here's what I have.  I hope it makes sense to other people:
 test0c.c is -->
 #include    <stdio.h>

 int    test()
 {  printf ("Hello, world\n");
    return  0;
 }

 //int main(int argc, char *argv[])
 //{    return    test(argc, argv);    }

 test0d.d is -->
 extern(C):
     int    test();

 void    main()
 {    test;    }

 Makefile.test0 is -->
 all:  test0

 test0:  test0d.o test0c.o
     $(CC)    test0d.o test0c.o -o test0

 test0d.o:
     dmd  -c test0d.d $(LL)  -I~/src/phobos test0c.o

 test0c.o: test0c.c
     $(CC)  -c test0c.c -o test0c.o

 clean:
     rm -f *.o  test0

 THEN:
 $ make -fMakefile.test0
 dmd  -c test0d.d   -I~/src/phobos test0c.o
 cc  -c test0c.c -o test0c.o
 cc      test0d.o test0c.o -o test1
 test0d.o: In function `gcc2_compiled.':
 test0d.d:(.text+0x8): undefined reference to `_Dmodule_ref'
 collect2: ld returned 1 exit status
 make: *** [test0] Error 1

 I don't know how to even get started addressing this problem.  bud 
 dies with even less informative messages.
You're missing -lphobos (-lgphobos if you were using GDC). The easiest way to do it is like this: dmd -c test0d.d cc -c test0c.c -o test0c.o dmd test0d.o test0c.o That first step is only if you absolutely require separate commands for compiling and linking. Otherwise, you could remove it and pass test0d.d to DMD instead of test0d.o.
Well, if I can figure out how to do this I'm going to be passing calls to things written by GLADE, and only lightly edited. This is just a test run to try to figure out how to make the linkage work. So far it's a bust. But this means that I'm going to need to pass into the linker the output of `pkg-config --libs gtk+-2.0`, which doesn't appear to pass correctly to dmd. (I can't even see any compiler options for accepting it...you'd think that -L might work, but if it will I haven't out how to cause it to.)
 Also, if DMD is properly set up, you shouldn't need to pass 
 -I~/src/phobos to it.
Fixed this one. The P variable in dmd.conf doesn't work correctly if you're using links to the binary routines.
Jul 25 2007
parent reply Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Charles D Hixson wrote:
 a bust.  But this means that I'm going to need to pass into the linker 
 the output of `pkg-config --libs gtk+-2.0`, which doesn't appear to pass 
 correctly to dmd. (I can't even see any compiler options for accepting 
 it...you'd think that -L might work, but if it will I haven't out how to 
 cause it to.)
Two options: 1) Pass "-L$(DMD_DIR)/lib -lphobos -lpthread -lm" to gcc or ld when using either for linking (these are the libs D requires when compiled with dmd, IIRC). 2) Pass something like $(addprefix -L, $(shell pkg-config --libs gtk+-2.0)) to dmd when using it for linking. This will add '-L' in front of every library specification; the reason just adding -L didn't work was that your command adds multiple libraries.
Jul 26 2007
next sibling parent Charles D Hixson <charleshixsn earthlink.net> writes:
Frits van Bommel wrote:
 Charles D Hixson wrote:
 a bust.  But this means that I'm going to need to pass into the linker 
 the output of `pkg-config --libs gtk+-2.0`, which doesn't appear to 
 pass correctly to dmd. (I can't even see any compiler options for 
 accepting it...you'd think that -L might work, but if it will I 
 haven't out how to cause it to.)
Two options: 1) Pass "-L$(DMD_DIR)/lib -lphobos -lpthread -lm" to gcc or ld when using either for linking (these are the libs D requires when compiled with dmd, IIRC). 2) Pass something like $(addprefix -L, $(shell pkg-config --libs gtk+-2.0)) to dmd when using it for linking. This will add '-L' in front of every library specification; the reason just adding -L didn't work was that your command adds multiple libraries.
Thanks much. That should enable me to build. (I still can't figure out why gcc won't link...unless that's your first answer. Haven't yet tried this, and won't tonight, as it's early in the morning.)
Jul 26 2007
prev sibling next sibling parent reply Charles D Hixson <charleshixsn earthlink.net> writes:
Frits van Bommel wrote:
 Charles D Hixson wrote:
 a bust.  But this means that I'm going to need to pass into the linker 
 the output of `pkg-config --libs gtk+-2.0`, which doesn't appear to 
 pass correctly to dmd. (I can't even see any compiler options for 
 accepting it...you'd think that -L might work, but if it will I 
 haven't out how to cause it to.)
Two options: 1) Pass "-L$(DMD_DIR)/lib -lphobos -lpthread -lm" to gcc or ld when using either for linking (these are the libs D requires when compiled with dmd, IIRC). 2) Pass something like $(addprefix -L, $(shell pkg-config --libs gtk+-2.0)) to dmd when using it for linking. This will add '-L' in front of every library specification; the reason just adding -L didn't work was that your command adds multiple libraries.
The short of it is: md -c test0d.d gcc -g -I/usr/include/gdk -c test0c.c -o test0c.o gcc -g -I/usr/include/gdk -WAll -L/usr/local/dmd/lib -lphobos -lpthread -lm test0d.o test0c.o -o test0 /usr/local/dmd/lib/libphobos.a(dmain2.o): In function `main': internal/dmain2.d:(.gnu.linkonce.tmain+0x74): undefined reference to `_Dmain' internal/dmain2.d:(.gnu.linkonce.tmain+0xc5): undefined reference to `_Dmain' /usr/local/dmd/lib/libphobos.a(deh2.o): In function `_D4deh213__eh_finddataFPvZPS4deh213DHandlerTable': internal/deh2.d:(.gnu.linkonce.t_D4deh213__eh_finddataFPvZPS4deh21 DHandlerTable+0x9): undefined reference to `_deh_beg' internal/deh2.d:(.gnu.linkonce.t_D4deh213__eh_finddataFPvZPS4deh21 DHandlerTable+0xe): undefined reference to `_deh_beg' internal/deh2.d:(.gnu.linkonce.t_D4deh213__eh_finddataFPvZPS4deh213 HandlerTable+0x14): undefined reference to `_deh_end' internal/deh2.d:(.gnu.linkonce.t_D4deh213__eh_finddataFPvZPS4deh213 HandlerTable+0x37): undefined reference to `_deh_end' collect2: ld returned 1 exit status make: *** [test0] Error 1 Which totally boggles me. This is what I rewrote the Makefile to: CC = gcc -g -I/usr/include/gdk CD = dmd DMD_DIR = /usr/local/dmd DLNK = -L$(DMD_DIR)/lib -lphobos -lpthread -lm all: test0 test0: test0d.o test0c.o $(CC) -WAll $(DLNK) test0d.o test0c.o -o test0 test0d.o: $(CD) -c test0d.d test0c.o: test0c.c $(CC) -c test0c.c -o test0c.o clean: rm -f *.o test0 (minus some wrapping that happened in posting). The other files are unchanged: test0c.c is a "hello, world" function, and test0d.d is a main routine that just calls the function. $ ls /usr/local/dmd bin html lib license.txt man readme samples src and $ ls /usr/local/dmd/lib gcstub.obj libphobos.a phobos.lib readme.txt WS2_32.LIB (basically I just copied the dmd folder to /usr/local after unzipping it) $ cat /etc/dmd.conf [Environment] DFLAGS=-I/usr/local/dmd/src/phobos -L-L/usr/local/dmd/lib (I know I'm sort of flailing around here, but I haven't a clue as to what the problem is.)
Jul 26 2007
parent reply Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Charles D Hixson wrote:
 /usr/local/dmd/lib/libphobos.a(dmain2.o): In function `main':
 internal/dmain2.d:(.gnu.linkonce.tmain+0x74): undefined reference to 
 `_Dmain'
 internal/dmain2.d:(.gnu.linkonce.tmain+0xc5): undefined reference to 
 `_Dmain'
 /usr/local/dmd/lib/libphobos.a(deh2.o): In function 
 `_D4deh213__eh_finddataFPvZPS4deh213DHandlerTable':
 internal/deh2.d:(.gnu.linkonce.t_D4deh213__eh_finddataFPvZPS4deh21
DHandlerTable+0x9): 
 undefined reference to `_deh_beg'
 internal/deh2.d:(.gnu.linkonce.t_D4deh213__eh_finddataFPvZPS4deh21
DHandlerTable+0xe): 
 undefined reference to `_deh_beg'
 internal/deh2.d:(.gnu.linkonce.t_D4deh213__eh_finddataFPvZPS4deh213
HandlerTable+0x14): 
 undefined reference to `_deh_end'
 internal/deh2.d:(.gnu.linkonce.t_D4deh213__eh_finddataFPvZPS4deh213
HandlerTable+0x37): 
 undefined reference to `_deh_end'
 collect2: ld returned 1 exit status
 make: *** [test0] Error 1
 
[snip makefile]
 
 (minus some wrapping that happened in posting).  The other files are 
 unchanged:  test0c.c is a "hello, world" function, and test0d.d is a 
 main routine that just calls the function.
I just had another look at your test0d.d file, and found your problem. Your file is this: ----- extern(C): int test(); void main() { test; } ----- That little ':' at the end of the first line means it'll apply extern(C) to _everything that follows_, not just test(). So your main() is also extern(C), which changes the name in the object file and doesn't invoke DMDs special handling of the D main function (which emits _deh_* to help exception handling support locate exception handler data). So to fix your program, just delete the ':'. It compiled and ran fine on my machine after that modification (besides some minor issues you probably won't have; using a 32-bit gcc on my 64-bit machine and correcting the dmd dir in the makefile for my machine).
Jul 27 2007
parent Charles D Hixson <charleshixsn earthlink.net> writes:
Frits van Bommel wrote:
 Charles D Hixson wrote:
 /usr/local/dmd/lib/libphobos.a(dmain2.o): In function `main':
 internal/dmain2.d:(.gnu.linkonce.tmain+0x74): undefined reference to 
 `_Dmain'
 internal/dmain2.d:(.gnu.linkonce.tmain+0xc5): undefined reference to 
 `_Dmain'
 /usr/local/dmd/lib/libphobos.a(deh2.o): In function 
 `_D4deh213__eh_finddataFPvZPS4deh213DHandlerTable':
 internal/deh2.d:(.gnu.linkonce.t_D4deh213__eh_finddataFPvZPS4deh21
DHandlerTable+0x9): 
 undefined reference to `_deh_beg'
 internal/deh2.d:(.gnu.linkonce.t_D4deh213__eh_finddataFPvZPS4deh21
DHandlerTable+0xe): 
 undefined reference to `_deh_beg'
 internal/deh2.d:(.gnu.linkonce.t_D4deh213__eh_finddataFPvZPS4deh213
HandlerTable+0x14): 
 undefined reference to `_deh_end'
 internal/deh2.d:(.gnu.linkonce.t_D4deh213__eh_finddataFPvZPS4deh213
HandlerTable+0x37): 
 undefined reference to `_deh_end'
 collect2: ld returned 1 exit status
 make: *** [test0] Error 1
[snip makefile]
 (minus some wrapping that happened in posting).  The other files are 
 unchanged:  test0c.c is a "hello, world" function, and test0d.d is a 
 main routine that just calls the function.
I just had another look at your test0d.d file, and found your problem. Your file is this: ----- extern(C): int test(); void main() { test; } ----- That little ':' at the end of the first line means it'll apply extern(C) to _everything that follows_, not just test(). So your main() is also extern(C), which changes the name in the object file and doesn't invoke DMDs special handling of the D main function (which emits _deh_* to help exception handling support locate exception handler data). So to fix your program, just delete the ':'. It compiled and ran fine on my machine after that modification (besides some minor issues you probably won't have; using a 32-bit gcc on my 64-bit machine and correcting the dmd dir in the makefile for my machine).
THANK YOU!! (Well, I feel stupid, but at least Makefile3 is now working. Presumably I can get the others to work also.)
Jul 27 2007
prev sibling parent Charles D Hixson <charleshixsn earthlink.net> writes:
Frits van Bommel wrote:
 Charles D Hixson wrote:
 a bust.  But this means that I'm going to need to pass into the linker 
 the output of `pkg-config --libs gtk+-2.0`, which doesn't appear to 
 pass correctly to dmd. (I can't even see any compiler options for 
 accepting it...you'd think that -L might work, but if it will I 
 haven't out how to cause it to.)
Two options: 1) Pass "-L$(DMD_DIR)/lib -lphobos -lpthread -lm" to gcc or ld when using either for linking (these are the libs D requires when compiled with dmd, IIRC). 2) Pass something like $(addprefix -L, $(shell pkg-config --libs gtk+-2.0)) to dmd when using it for linking. This will add '-L' in front of every library specification; the reason just adding -L didn't work was that your command adds multiple libraries.
OK, this time following the other path, here's the short: $ make -fMakefile2.test0 gcc -g -I/usr/include/gdk -c test0c.c -o test0c.o dmd test0d.d test0c.o -L-lgtk-x11-2.0 -L-lgdk-x11-2.0 -L-latk-1.0 -L-lgdk_pixbuf-2.0 -L-lm -L-lpangocairo-1.0 -L-lfontconfig -L-lXext -L-lXrender -L-lXinerama -L-lXi -L-lXrandr -L-lXcursor -L-lXfixes -L-lpango-1.0 -L-lcairo -L-lX11 -L-lgobject-2.0 -L-lgmodule-2.0 -L-ldl -L-lglib-2.0 gcc test0d.o test0c.o -o test0d -m32 -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgdk_pixbuf-2.0 -lm -lpangocairo-1.0 -lfontconfig -lXext -lXrender -lXinerama -lXi -lXrandr -lXcursor -lXfixes -lpango-1.0 -lcairo -lX11 -lgobject-2.0 -lgmodule-2.0 -ldl -lglib-2.0 -Xlinker -L/usr/local/dmd/lib -lphobos -lpthread -lm /usr/lib/gcc/i486-linux-gnu/4.1.3/../../../../lib/libphobos.a(deh2.o): In function `_D4deh213__eh_finddataFPvZPS4deh213DHandlerTable': internal/deh2.d:(.gnu.linkonce.t_D4deh213__eh_finddataFPvZPS4deh21 DHandlerTable+0x9): undefined reference to `_deh_beg' internal/deh2.d:(.gnu.linkonce.t_D4deh213__eh_finddataFPvZPS4deh21 DHandlerTable+0xe): undefined reference to `_deh_beg' internal/deh2.d:(.gnu.linkonce.t_D4deh213__eh_finddataFPvZPS4deh213 HandlerTable+0x14): undefined reference to `_deh_end' internal/deh2.d:(.gnu.linkonce.t_D4deh213__eh_finddataFPvZPS4deh213 HandlerTable+0x37): undefined reference to `_deh_end' collect2: ld returned 1 exit status --- errorlevel 1 make: *** [test0] Error 1 and here's the makefile: CC = gcc -g -I/usr/include/gdk CD = dmd DMD_DIR = /usr/local/dmd DLNK = -L$(DMD_DIR)/lib -lphobos -lpthread -lm all: test0 test0: test0c.o $(CD) test0d.d test0c.o $(addprefix -L, $(shell pkg-config --libs gtk+-2.0)) test0c.o: test0c.c $(CC) -c test0c.c -o test0c.o clean: rm -f *.o test0 as before, the post wrapped the makefile, but that's pretty clear. The system config is unchanged. And I'm confused. Well, this test case shouldn't need those extra libraries in gtk, so I tried eliminating them in Makefile3.test0: CC = gcc -g -I/usr/include/gdk CD = dmd DMD_DIR = /usr/local/dmd DLNK = -L$(DMD_DIR)/lib -lphobos -lpthread -lm all: test0 test0: test0c.o $(CD) test0d.d test0c.o test0c.o: test0c.c $(CC) -c test0c.c -o test0c.o clean: rm -f *.o test0 but running it yielded no improvement: $ make -fMakefile3.test0 gcc -g -I/usr/include/gdk -c test0c.c -o test0c.o dmd test0d.d test0c.o gcc test0d.o test0c.o -o test0d -m32 -Xlinker -L/usr/local/dmd/lib -lphobos -lpthread -lm /usr/lib/gcc/i486-linux-gnu/4.1.3/../../../../lib/libphobos.a(deh2.o): In function `_D4deh213__eh_finddataFPvZPS4deh213DHandlerTable': internal/deh2.d:(.gnu.linkonce.t_D4deh213__eh_finddataFPvZPS4deh21 DHandlerTable+0x9): undefined reference to `_deh_beg' internal/deh2.d:(.gnu.linkonce.t_D4deh213__eh_finddataFPvZPS4deh21 DHandlerTable+0xe): undefined reference to `_deh_beg' internal/deh2.d:(.gnu.linkonce.t_D4deh213__eh_finddataFPvZPS4deh213 HandlerTable+0x14): undefined reference to `_deh_end' internal/deh2.d:(.gnu.linkonce.t_D4deh213__eh_finddataFPvZPS4deh213 HandlerTable+0x37): undefined reference to `_deh_end' collect2: ld returned 1 exit status --- errorlevel 1 make: *** [test0] Error 1
Jul 26 2007