type t
declare constructor( )
as integer ptr p = new integer
end type
constructor t( )
end constructor
'' ld: /usr/lib/gcc/i686-linux-gnu/4.7/libsupc++.a(eh_globals.o): undefined reference to symbol '___tls_get_addr@@GLIBC_2.3'
'' ld: note: '___tls_get_addr@@GLIBC_2.3' is defined in DSO /lib/i386-linux-gnu/ld-linux.so.2 so try adding it to the linker command line
'' /lib/i386-linux-gnu/ld-linux.so.2: could not read symbols: Invalid operation
I'm using a Git build of fbc on Ubuntu 12.10. But I've tried a Ubuntu 12.04 system that works, so I'm wondering whether Ubuntu or I have broken something. If it's my fault, I have no idea how to fix it..
I (definitely) should also have mentioned: both installs are 32-bit.
The mentions of both i386 and i686 is perhaps a clue to the problem. Though I really don't know. For the most part, Ubuntu is just a well-organised black box to me.
Apparently it is gcc's libsupc++.a that needs this symbol, I think FB code only uses libsupc++ for NEW/DELETE.
I suspect it's another piece of the multiarch puzzle. fbc uses -dynamic-linker /lib/ld-linux.so.2 when linking, maybe we'd need to use /lib/i386-linux-gnu/ld-linux.so.2 here as suggested by that ld message?
It is weird though, I thought there were symlinks in place to prevent having to adjust paths like this... does Ubuntu i386 not have /lib/ld-linux.so.2 anymore, or is it really different from /lib/i386-linux-gnu/ld-linux.so.2? (could try comparing nm output, the list of symbols)
Another thing to try would be to compile a similar C/C++ program with gcc/g++ and see what ld options it will use, for comparison, then possibly adjust fbc to do the same if possible.
By the way, in the Debian/Ubuntu world they use i386 for all 32bit x86, often the system compiler is really something different though, for example I see i686 on recent Ubuntus and remember i486 toolchains from others.
And when statically linking that C++ program also check what libs are really linked.
While I never have looked into it in recent times, I can vaguely remember something about libc.a only containing the core libc code, and not the other libs that are combined to glibc.so (like iconv). It could be that TLS stuff is some other .a.
Another possibility is that libraries are not implicitely linked when not dynamic linking. (think libpthreads and libgcc here)
which is the main linker commandline. Note the libgcc_eh. the rest (after the closing ] ) is the environment, and can be useful for LD_FLAGS, C_FLAGS etc:
I hoped I gave a quick idea how to tackle such problems. Not the most elegant way probably, but easy to remember (I only do this every so and so many years)
Heh. I whittled my code down from a unit test, guess I didn't do enough whittling..
If FB is unable to use New/Delete on the latest version of a popular OS, that's pretty serious, right?
Can g++ be persuaded to reveal its ld command line more simply? (I find the contents of the last post a little overwhelming..)
I agree it's important to solve this. gcc/g++ support the -v (verbose) option which will show the linking command line, much like fbc. It can also help to look at the ld map files (fbc -map map.txt and g++ -Wl,-Map,map.txt).
Maybe it's just a problem of -l option order (that happens even when using ld's -( -) group options if libs have duplicate symbols)
-l fb -l gcc -l pthread -l c -l m -l dl -l ncurses -l supc++ -l gcc_eh
If I change the order of -l options the error goes away (this order is derived from gcc):
It seems like the problem only shows up if -lsupc++/-lstdc++ appear behind -lc, fixing this solves the problem. Another thing that seemed to work was to link against libstdc++ like g++, instead of just the libsupc++ part of it. I think the only reason fbc does that was to prevent having to distribute the huge libstdc++ binary, but since our FB-Linux release don't include prebuilt gcc libs anymore nowadays this is not an issue anymore.