David Oswald
2012-03-08 15:43:48 UTC
I just had a thought on all the hurdles we're going through on trying
to guess the proper default libraries for a given platform.
This may be totally wrong, but here goes:
Within Makefile.PL we're already test-compiling a C++ program to
detect whether headers should have a .h extension or not. Why not
test-compile another C++ program that we know to be portable, using
the -v flag. We could capture the verbose output using backticks, and
parse it looking for the pattern m/\s(-l\w+)\b/g, which should tell us
all the -lxxxxx libraries that are automatically linked by the
compiler/linker under normal conditions.
For example, on my Ubuntu linux system using g++ version 4.6.1, the
verbose output of a full build produces a line that looks like this:
COLLECT_GCC_OPTIONS='-Wall' '-v' '-o' 'mytest' '-shared-libgcc'
'-mtune=generic' '-march=i686'
and a final line that looks like this:
/usr/lib/gcc/i686-linux-gnu/4.6.1/collect2 --build-id --no-add-needed
--as-needed --eh-frame-hdr -m elf_i386 --hash-style=gnu
-dynamic-linker /lib/ld-linux.so.2 -z relro -o mytest
/usr/lib/gcc/i686-linux-gnu/4.6.1/../../../i386-linux-gnu/crt1.o
/usr/lib/gcc/i686-linux-gnu/4.6.1/../../../i386-linux-gnu/crti.o
/usr/lib/gcc/i686-linux-gnu/4.6.1/crtbegin.o
-L/usr/lib/gcc/i686-linux-gnu/4.6.1
-L/usr/lib/gcc/i686-linux-gnu/4.6.1/../../../i386-linux-gnu
-L/usr/lib/gcc/i686-linux-gnu/4.6.1/../../../../lib
-L/lib/i386-linux-gnu -L/lib/../lib -L/usr/lib/i386-linux-gnu
-L/usr/lib/../lib -L/usr/lib/gcc/i686-linux-gnu/4.6.1/../../..
/tmp/ccBPbWmX.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc
/usr/lib/gcc/i686-linux-gnu/4.6.1/crtend.o
/usr/lib/gcc/i686-linux-gnu/4.6.1/../../../i386-linux-gnu/crtn.o
...which I think is an expansion of the linking stage.
I see in that final line that the '-shared-libgcc' flag must expand to include:
-lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s (again?) -lgcc (again?)
If Makefile.PL parsed that last line using a hash to remove
duplicates, I would end up with:
-lstdc++
-lm
-lgcc_s
-lgcc
-lc
I could then specify those specific default libraries in Makefile.PL,
and should get a clean build on my system.
I'm not sure if this technique would be portable across other flavors
of compilers though. But if it is, it seems like a good way to get
rid of a lot of a big if(){} elsif(){} elsif(){} chain.
Dave
to guess the proper default libraries for a given platform.
This may be totally wrong, but here goes:
Within Makefile.PL we're already test-compiling a C++ program to
detect whether headers should have a .h extension or not. Why not
test-compile another C++ program that we know to be portable, using
the -v flag. We could capture the verbose output using backticks, and
parse it looking for the pattern m/\s(-l\w+)\b/g, which should tell us
all the -lxxxxx libraries that are automatically linked by the
compiler/linker under normal conditions.
For example, on my Ubuntu linux system using g++ version 4.6.1, the
verbose output of a full build produces a line that looks like this:
COLLECT_GCC_OPTIONS='-Wall' '-v' '-o' 'mytest' '-shared-libgcc'
'-mtune=generic' '-march=i686'
and a final line that looks like this:
/usr/lib/gcc/i686-linux-gnu/4.6.1/collect2 --build-id --no-add-needed
--as-needed --eh-frame-hdr -m elf_i386 --hash-style=gnu
-dynamic-linker /lib/ld-linux.so.2 -z relro -o mytest
/usr/lib/gcc/i686-linux-gnu/4.6.1/../../../i386-linux-gnu/crt1.o
/usr/lib/gcc/i686-linux-gnu/4.6.1/../../../i386-linux-gnu/crti.o
/usr/lib/gcc/i686-linux-gnu/4.6.1/crtbegin.o
-L/usr/lib/gcc/i686-linux-gnu/4.6.1
-L/usr/lib/gcc/i686-linux-gnu/4.6.1/../../../i386-linux-gnu
-L/usr/lib/gcc/i686-linux-gnu/4.6.1/../../../../lib
-L/lib/i386-linux-gnu -L/lib/../lib -L/usr/lib/i386-linux-gnu
-L/usr/lib/../lib -L/usr/lib/gcc/i686-linux-gnu/4.6.1/../../..
/tmp/ccBPbWmX.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc
/usr/lib/gcc/i686-linux-gnu/4.6.1/crtend.o
/usr/lib/gcc/i686-linux-gnu/4.6.1/../../../i386-linux-gnu/crtn.o
...which I think is an expansion of the linking stage.
I see in that final line that the '-shared-libgcc' flag must expand to include:
-lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s (again?) -lgcc (again?)
If Makefile.PL parsed that last line using a hash to remove
duplicates, I would end up with:
-lstdc++
-lm
-lgcc_s
-lgcc
-lc
I could then specify those specific default libraries in Makefile.PL,
and should get a clean build on my system.
I'm not sure if this technique would be portable across other flavors
of compilers though. But if it is, it seems like a good way to get
rid of a lot of a big if(){} elsif(){} elsif(){} chain.
Dave
--
David Oswald
daoswald-***@public.gmane.org
David Oswald
daoswald-***@public.gmane.org