1. undefined reference to 'NewDouble'

So I have been testing some methods for rebuilding wxEuphoria. Trying to link the Euphoria library (eu.a) into my DLL, the linker cannot find a reference to NewDouble.

I've distilled my problem down to this simple code. What am I doing wrong?

test.c said...

#include <stdint.h> 
#include "euphoria.h" 
 
object box_int( intptr_t x ) 
{ 
    if(x > NOVALUE && x < MAXINT) 
        return (object)x; 
    else 
        return (object)NewDouble((double)x); 
}	 

$ gcc -c test.c -o test.o -IC:\Euphoria\include 
$ gcc -shared -o test.dll C:\Euphoria\bin\eu.a test.o 
test.o:test.c:(.text+0x24): undefined reference to `NewDouble' 
collect2.exe: error: ld returned 1 exit status 
make: *** [test.dll] Error 1 

-Greg

new topic     » topic index » view message » categorize

2. Re: undefined reference to 'NewDouble'

ghaberek said...

So I have been testing some methods for rebuilding wxEuphoria. Trying to link the Euphoria library (eu.a) into my DLL, the linker cannot find a reference to NewDouble.

I've distilled my problem down to this simple code. What am I doing wrong?

test.c said...

#include <stdint.h> 
#include "euphoria.h" 
 
object box_int( intptr_t x ) 
{ 
    if(x > NOVALUE && x < MAXINT) 
        return (object)x; 
    else 
        return (object)NewDouble((double)x); 
}	 

$ gcc -c test.c -o test.o -IC:\Euphoria\include 
$ gcc -shared -o test.dll C:\Euphoria\bin\eu.a test.o 
test.o:test.c:(.text+0x24): undefined reference to `NewDouble' 
collect2.exe: error: ld returned 1 exit status 
make: *** [test.dll] Error 1 

-Greg

I'm not sure what's going on. NewDouble is defined be_alloc.c, but eu.a should have been built with that object file (be_alloc.o), which should have been enough to resolve the reference.

new topic     » goto parent     » topic index » view message » categorize

3. Re: undefined reference to 'NewDouble'

jimcbrown said...

I'm not sure what's going on. NewDouble is defined be_alloc.c, but eu.a should have been built with that object file (be_alloc.o), which should have been enough to resolve the reference.

Here is a dump of eu.a.

$ cd C:\Euphoria\source\build 
$ ar t eu.a 
be_decompress.o 
be_machine.o 
be_w.o 
be_alloc.o 
be_inline.o 
be_pcre.o 
be_socket.o 
be_runtime.o 
be_task.o 
be_callc.o 
pcre_chartables.o 
pcre_compile.o 
pcre_config.o 
pcre_dfa_exec.o 
pcre_exec.o 
pcre_fullinfo.o 
pcre_get.o 
pcre_globals.o 
pcre_info.o 
pcre_maketables.o 
pcre_newline.o 
pcre_ord2utf8.o 
pcreposix.o 
pcre_refcount.o 
pcre_study.o 
pcre_tables.o 
pcre_try_flipped.o 
pcre_ucd.o 
pcre_valid_utf8.o 
pcre_version.o 
pcre_xclass.o 

Here is a dump of be_alloc.o.

$ cd C:\Euphoria\source\build\libobj\back 
$ nm -C be_alloc.o 
00000000 b .bss 
00000000 d .data 
00000000 i .drectve 
00000000 r .eh_frame 
00000000 r .rdata 
00000000 t .text 
         U _assert 
00000671 T append_string 
00000004 B cache_size 
00000004 C call_back_arg1 
00000004 C call_back_arg2 
00000004 C call_back_arg3 
00000004 C call_back_arg4 
00000004 C call_back_arg5 
00000004 C call_back_arg6 
00000004 C call_back_arg7 
00000004 C call_back_arg8 
00000004 C call_back_arg9 
00000004 C call_back_result 
00000629 T copy_string 
00000000 B d_list 
         U de_reference 
         U default_heap 
00000014 b done.32117 
00000352 T EFree 
00000057 T EMalloc 
000003d1 T ERealloc 
0000000c B eu_dll_exists 
00000018 b freeblk_list 
00000010 b g_pagesize.32110 
00000017 T getpagesize 
         U GetSystemInfo@4 
         U HeapAlloc@12 
         U HeapFree@12 
         U HeapReAlloc@16 
         U HeapSize@12 
000001df T InitEMalloc 
00000008 B low_on_space 
         U memcopy 
000006ac T NewDouble 
0000055b T NewPreallocSeq 
0000048c T NewS1 
000004fa T NewSequence 
00000536 T NewString 
00000004 C pagesize 
00000088 b pool_map 
         U printf 
         U RTFatal 
         U RTFatal_va 
00000000 T RTInternal 
000005c5 T SequenceCopy 
00000048 T SpaceMessage 
000001cc T tmp_alloc 
00000624 T TransAlloc 

-Greg

new topic     » goto parent     » topic index » view message » categorize

4. Re: undefined reference to 'NewDouble'

ghaberek said...

Here is a dump of be_alloc.o.

$ cd C:\Euphoria\source\build\libobj\back 
$ nm -C be_alloc.o 
... 
000006ac T NewDouble 
... 

It's definitely in be_alloc.o then. It'd be nice to extract the be_alloc.o from eu.a just to verify that the two really are the same object file.

ghaberek said...

Here is a dump of eu.a.

$ cd C:\Euphoria\source\build 
$ ar t eu.a 
... 
be_alloc.o 
... 

Isn't that the wrong eu.a though? I thought you were using the one in bin, not source/build.

new topic     » goto parent     » topic index » view message » categorize

5. Re: undefined reference to 'NewDouble'

jimcbrown said...

Isn't that the wrong eu.a though? I thought you were using the one in bin, not source/build.

In all my fiddling around, I accidentally deleted that one. Building Euphoria from source and using that copy of eu.a made no difference (same error).

-Greg

new topic     » goto parent     » topic index » view message » categorize

6. Re: undefined reference to 'NewDouble'

ghaberek said...
jimcbrown said...

Isn't that the wrong eu.a though? I thought you were using the one in bin, not source/build.

In all my fiddling around, I accidentally deleted that one. Building Euphoria from source and using that copy of eu.a made no difference (same error).

-Greg

That is odd. You should be able to work around the issue by adding source/build/libobj/back/be_alloc.o to gcc's command line - but using eu.a should have workedby itself.

new topic     » goto parent     » topic index » view message » categorize

7. Re: undefined reference to 'NewDouble'

I did find this, but since we aren't using -l here I'm not sure if it's relevant.

http://www.mingw.org/wiki/Specify_the_libraries_for_the_linker_to_use said...

Finally, please do not fall into the all-too-common trap of placing any "-l <name>" specification before the name of any source or object module which requires it. Where the source file bar.c has dependencies on the library archive libfoo.a, the command:

$ gcc -lfoo bar.c

is incorrect, and will surely lead to "undefined reference" errors. The correct form for this command is:

$ gcc bar.c -lfoo

new topic     » goto parent     » topic index » view message » categorize

8. Re: undefined reference to 'NewDouble'

jimcbrown said...

That is odd. You should be able to work around the issue by adding source/build/libobj/back/be_alloc.o to gcc's command line - but using eu.a should have workedby itself.

Nope. It didn't like that either.

gcc -shared -o test.dll C:\Euphoria\source\build\libobj\back\be_alloc.o C:\Euphoria\source\build\eu.a test.o 
C:\Euphoria\source\build\libobj\back\be_alloc.o:be_alloc.c:(.text+0xb2): undefined reference to `default_heap' 
C:\Euphoria\source\build\libobj\back\be_alloc.o:be_alloc.c:(.text+0xf6): undefined reference to `default_heap' 
C:\Euphoria\source\build\libobj\back\be_alloc.o:be_alloc.c:(.text+0x14c): undefined reference to `default_heap' 
C:\Euphoria\source\build\libobj\back\be_alloc.o:be_alloc.c:(.text+0x182): undefined reference to `default_heap' 
C:\Euphoria\source\build\libobj\back\be_alloc.o:be_alloc.c:(.text+0x367): undefined reference to `default_heap' 
C:\Euphoria\source\build\libobj\back\be_alloc.o:be_alloc.c:(.text+0x398): more undefined references to `default_heap' follow 
c:/mingw/bin/../lib/gcc/mingw32/4.7.2/../../../../mingw32/bin/ld.exe: C:\Euphoria\source\build\libobj\back\be_alloc.o: bad reloc address 0x20 in section `.eh_frame' 
collect2.exe: error: ld returned 1 exit status 

-Greg

new topic     » goto parent     » topic index » view message » categorize

9. Re: undefined reference to 'NewDouble'

jimcbrown said...

I did find this, but since we aren't using -l here I'm not sure if it's relevant.

http://www.mingw.org/wiki/Specify_the_libraries_for_the_linker_to_use said...

Finally, please do not fall into the all-too-common trap of placing any "-l <name>" specification before the name of any source or object module which requires it. Where the source file bar.c has dependencies on the library archive libfoo.a, the command:

$ gcc -lfoo bar.c

is incorrect, and will surely lead to "undefined reference" errors. The correct form for this command is:

$ gcc bar.c -lfoo

Yeah, I'm also two-stepping the process and that seems to imply compiling and linking in one step.

-Greg

new topic     » goto parent     » topic index » view message » categorize

10. Re: undefined reference to 'NewDouble'

ghaberek said...

Nope. It didn't like that either.

gcc -shared -o test.dll C:\Euphoria\source\build\libobj\back\be_alloc.o C:\Euphoria\source\build\eu.a test.o 
C:\Euphoria\source\build\libobj\back\be_alloc.o:be_alloc.c:(.text+0xb2): undefined reference to `default_heap' 
C:\Euphoria\source\build\libobj\back\be_alloc.o:be_alloc.c:(.text+0xf6): undefined reference to `default_heap' 
C:\Euphoria\source\build\libobj\back\be_alloc.o:be_alloc.c:(.text+0x14c): undefined reference to `default_heap' 
C:\Euphoria\source\build\libobj\back\be_alloc.o:be_alloc.c:(.text+0x182): undefined reference to `default_heap' 
C:\Euphoria\source\build\libobj\back\be_alloc.o:be_alloc.c:(.text+0x367): undefined reference to `default_heap' 
C:\Euphoria\source\build\libobj\back\be_alloc.o:be_alloc.c:(.text+0x398): more undefined references to `default_heap' follow 
c:/mingw/bin/../lib/gcc/mingw32/4.7.2/../../../../mingw32/bin/ld.exe: C:\Euphoria\source\build\libobj\back\be_alloc.o: bad reloc address 0x20 in section `.eh_frame' 
collect2.exe: error: ld returned 1 exit status 

-Greg

default_heap is created by the translator (see source/compile.e for the details). Since you're using a custom C file instead of translated source, you'll need define that HANDLE and call GetProcessHeap() yourself.

new topic     » goto parent     » topic index » view message » categorize

11. Re: undefined reference to 'NewDouble'

ghaberek said...
jimcbrown said...

I did find this, but since we aren't using -l here I'm not sure if it's relevant.

http://www.mingw.org/wiki/Specify_the_libraries_for_the_linker_to_use said...

Finally, please do not fall into the all-too-common trap of placing any "-l <name>" specification before the name of any source or object module which requires it. Where the source file bar.c has dependencies on the library archive libfoo.a, the command:

$ gcc -lfoo bar.c

is incorrect, and will surely lead to "undefined reference" errors. The correct form for this command is:

$ gcc bar.c -lfoo

Yeah, I'm also two-stepping the process and that seems to imply compiling and linking in one step.

-Greg

Well, it did say that object modules with dependencies need to come before the library too.

new topic     » goto parent     » topic index » view message » categorize

12. Re: undefined reference to 'NewDouble'

jimcbrown said...

default_heap is created by the translator (see source/compile.e for the details). Since you're using a custom C file instead of translated source, you'll need define that HANDLE and call GetProcessHeap() yourself.

I didn't think about this, but now that I think about it, there are actually like a gazillion things that the translator outputs in the translated C code that you'd need to mimic if you wanted to link it all by hand.

new topic     » goto parent     » topic index » view message » categorize

13. Re: undefined reference to 'NewDouble'

jimcbrown said...

I didn't think about this, but now that I think about it, there are actually like a gazillion things that the translator outputs in the translated C code that you'd need to mimic if you wanted to link it all by hand.

I'm starting to realize this! I had to pull out Argc, Argv, default_heap, and some strange object called _00. I thought that maybe this would be a better method compared to how Matt had imported a bunch of things manually from the Euphoria source (be.c, etc.). This may not be the proper method after all.

Although, we probably do need a better static library for working with Euphoria from an external library. getlost

Regardless, here are my technically now-working sources, just for this test...

libtest.h said...

#ifndef _LIBTEST_H 
#define _LIBTEST_H 
 
#include <stdint.h> 
#include "euphoria.h" 
 
extern unsigned default_heap; 
extern object box_int( intptr_t x ); 
 
#endif // _LIBTEST_H 

libtest.c said...

#include "libtest.h" 
 
int Argc; char **Argv; 
unsigned default_heap; 
struct routine_list _00[] = {}; 
 
object box_int( intptr_t x ) 
{ 
    if(x > NOVALUE && x < MAXINT) 
        return (object)x; 
    else 
        return (object)NewDouble((double)x); 
}	 

test.c said...

#include "windows.h" 
#include "libtest.h" 
 
int main() 
{ 
    default_heap = (unsigned)GetProcessHeap(); 
 
    object test1 = box_int( 1 ); // a simple int 
    object test2 = box_int( MAXINT + 1 ); // should be a double 
 
    return 0; 
} 

Makefile said...

EUDIR = C:\Euphoria 
EUBUILD = $(EUDIR)\source\build 
BACKEND = $(EUBUILD)\libobj\back 
 
all: libtest.dll test.exe 
 
test.exe: test.o 
	gcc -o test.exe test.o -L. -ltest 
 
test.o: test.c 
	gcc -c test.c -o test.o -I. -I$(EUDIR)\include 
 
libtest.dll: libtest.o 
	gcc -shared -o libtest.dll $(BACKEND)\be_alloc.o $(EUBUILD)\eu.a libtest.o 
 
libtest.o: libtest.c 
	gcc -c libtest.c -o libtest.o -I$(EUDIR)\include 
 
.PHONY: clean 
 
clean: 
	-@rm -f libtest.dll libtest.o test.exe test.o 

-Greg

new topic     » goto parent     » topic index » view message » categorize

14. Re: undefined reference to 'NewDouble'

ghaberek said...

Although, we probably do need a better static library for working with Euphoria from an external library. getlost

Alternatively, we could turn the runtime library into a dynamic / shared library and link it that way.

Matt

new topic     » goto parent     » topic index » view message » categorize

15. Re: undefined reference to 'NewDouble'

mattlewis said...
ghaberek said...

Although, we probably do need a better static library for working with Euphoria from an external library. getlost

Alternatively, we could turn the runtime library into a dynamic / shared library and link it that way.

Matt

Well, if we did that and nothing else, we'd still have the issues with default_heap and _00 and other auto-generated symbols...

new topic     » goto parent     » topic index » view message » categorize

16. Re: undefined reference to 'NewDouble'

jimcbrown said...
mattlewis said...

Alternatively, we could turn the runtime library into a dynamic / shared library and link it that way.

Well, if we did that and nothing else, we'd still have the issues with default_heap and _00 and other auto-generated symbols...

I don't know if a shared library is the way to go. What I think would be really helpful is just a static library that provides all of the NewS1/NewDouble stuff and reference counting measures to create, pass, and accept Euphoria objects in native C/C++ code. I suppose it wouldn't be terribly difficult to extract the necessary parts from the backend code and adapt them for independent use, but I was thinking it could be part of the Euphoria build process.

-Greg

new topic     » goto parent     » topic index » view message » categorize

17. Re: undefined reference to 'NewDouble'

ghaberek said...
jimcbrown said...
mattlewis said...

Alternatively, we could turn the runtime library into a dynamic / shared library and link it that way.

Well, if we did that and nothing else, we'd still have the issues with default_heap and _00 and other auto-generated symbols...

I don't know if a shared library is the way to go. What I think would be really helpful is just a static library that provides all of the NewS1/NewDouble stuff and reference counting measures to create, pass, and accept Euphoria objects in native C/C++ code. I suppose it wouldn't be terribly difficult to extract the necessary parts from the backend code and adapt them for independent use, but I was thinking it could be part of the Euphoria build process.

Yes. I was posting before coffee, and I don't think I really understood what you were trying to do. This would be a useful thing, instead of having the copied code that's currently in wxEuphoria. It's been a while since I've messed with any of that.

Matt

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu