On 2012-11-09 20:38, Dimitry Andric wrote: > On 2012-11-09 19:28, Steve Kargl wrote: ... >> I'll see what I can do. sasmp is a fairly large OpenMPI program. > > Sorry, never mind that. I found a simple testcase: > > #include <math.h> > > int main(int argc, char *argv[]) > { > return isnan((double)argc) + isnan((float)argc); > } > > Building with -lm -static will trigger the link error. I'm > investigating where the problem is. I think I have an idea now what causes this. When you compile the above program with gcc, it emits a call to __isnanf(), but uses its builtin for isnan(). When you statically link it using -lm, the linker finds __isnanf() in libm.a's s_isnan.o member. It ignores libc.a's isnan.o member, because it does not need any additional symbols from it. In contrast, clang emits calls to both isnan() and __isnanf(), as the former is not a clang builtin. When you statically link with -lm, the linker first finds __isnanf() in libm.a's s_isnan.o member, just like before. Then, it finds isnan(), as a weak reference, in libc.a's isnan.o member, so it wants to load that too. This causes a conflict, because __isnanf() is defined both in libm.a's s_isnan.o member, and in libc.a's isna.o member. Note that you will see the same link error, if you use gcc -fno-builtin to compile the above program, and for the same reason: the copies of __isnanf() in libm.a and libc.a conflict. There seem to be two ways out of this conundrum: the easier one is to make clang also use a builtin for isnan(), for example by modifying the isnan() macro in math.h, letting it invoke __builtin_isnan() instead. However, this just papers over the issue. The more difficult way out is to not define any duplicate functions in libc.a and libm.a. For the shared libraries, this should not be a problem, since the dynamic linker will figure out which of the two copies will get precedence. The functions must stay available for backwards compatibility reasons anyway. For static libraries, this compatibility seems to be unnecessary, as they will only be used to link new programs. Therefore, it would probably be best to remove the whole isnan.o member from libc.a, and move all the isnan functions to libm.a instead. Currently, isnan() is commented out in lib/msun/src/s_isnan.c, maybe we can enable it whenever PIC is not defined? Then we could simply skip building lib/libc/gen/isnan.c for libc.a. Anther possible solution is to split off isnanf() and __isnanf() to separate files, then build s_isnanf.o for libm.a, but skip building isnanf.o for libc.a. This might be a little cleaner.Received on Fri Nov 09 2012 - 22:25:30 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:40:32 UTC