1. undefined reference to 'NewDouble'
- Posted by ghaberek (admin) Apr 21, 2013
- 1853 views
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?
#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
2. Re: undefined reference to 'NewDouble'
- Posted by jimcbrown (admin) Apr 21, 2013
- 1851 views
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?
#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.
3. Re: undefined reference to 'NewDouble'
- Posted by ghaberek (admin) Apr 21, 2013
- 1873 views
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
4. Re: undefined reference to 'NewDouble'
- Posted by jimcbrown (admin) Apr 21, 2013
- 1835 views
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.
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.
5. Re: undefined reference to 'NewDouble'
- Posted by ghaberek (admin) Apr 21, 2013
- 1824 views
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
6. Re: undefined reference to 'NewDouble'
- Posted by jimcbrown (admin) Apr 21, 2013
- 1824 views
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.
7. Re: undefined reference to 'NewDouble'
- Posted by jimcbrown (admin) Apr 21, 2013
- 1861 views
I did find this, but since we aren't using -l here I'm not sure if it's relevant.
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
8. Re: undefined reference to 'NewDouble'
- Posted by ghaberek (admin) Apr 21, 2013
- 1833 views
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
9. Re: undefined reference to 'NewDouble'
- Posted by ghaberek (admin) Apr 21, 2013
- 1833 views
I did find this, but since we aren't using -l here I'm not sure if it's relevant.
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
10. Re: undefined reference to 'NewDouble'
- Posted by jimcbrown (admin) Apr 21, 2013
- 1846 views
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.
11. Re: undefined reference to 'NewDouble'
- Posted by jimcbrown (admin) Apr 21, 2013
- 1830 views
I did find this, but since we aren't using -l here I'm not sure if it's relevant.
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.
12. Re: undefined reference to 'NewDouble'
- Posted by jimcbrown (admin) Apr 21, 2013
- 1850 views
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.
13. Re: undefined reference to 'NewDouble'
- Posted by ghaberek (admin) Apr 21, 2013
- 1890 views
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.
Regardless, here are my technically now-working sources, just for this test...
#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
#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); }
#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; }
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
14. Re: undefined reference to 'NewDouble'
- Posted by mattlewis (admin) Apr 22, 2013
- 1830 views
Although, we probably do need a better static library for working with Euphoria from an external library.
Alternatively, we could turn the runtime library into a dynamic / shared library and link it that way.
Matt
15. Re: undefined reference to 'NewDouble'
- Posted by jimcbrown (admin) Apr 22, 2013
- 1831 views
Although, we probably do need a better static library for working with Euphoria from an external library.
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...
16. Re: undefined reference to 'NewDouble'
- Posted by ghaberek (admin) Apr 22, 2013
- 1820 views
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
17. Re: undefined reference to 'NewDouble'
- Posted by mattlewis (admin) Apr 22, 2013
- 1831 views
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