Den 2009-08-14 23:41 skrev David Byron:
I'm pretty sure I'm running into a pr-msvc-support-specific problem but I'm
still learning about libtool so...
I'm trying to get rid of unresolved externs when linked an executable
against a libtool shared library compiled with msvc. The unresolved externs
are global variables. The code in question yet another getopt
implementation. The variables are declared and defined like this:
<getopt.h>
extern UTL_EXPORT int opterr;
extern UTL_EXPORT int optind;
extern UTL_EXPORT int optopt;
extern UTL_EXPORT int optreset;
extern UTL_EXPORT char *optarg;
<getopt_long.c>
int opterr = 1;
int optind = 1;
int optopt = '?';
int optreset;
char *optarg;
UTL_EXPORT becomes __declspec(dllexport) when compiling the shared lib,
__declspec(dllimport) when compiling the executable that uses it.
What's interesting is that I only get unresolved externs for the initialized
variables:
utils-test.obj : error LNK2001: unresolved external symbol _optopt
utils-test.obj : error LNK2001: unresolved external symbol _optind
utils-test.obj : error LNK2001: unresolved external symbol _opterr
Snippets from dumpbin -symbols on the getopt_long.obj look like this:
COFF SYMBOL TABLE
000 006DC627 ABS notype Static | @comp.id
001 00000001 ABS notype Static | @feat.00
002 00000000 SECT1 notype Static | .drectve
Section length C9, #relocs 0, #linenums 0, checksum 0
004 00000000 SECT2 notype Static | .debug$S
Section length 1EEC, #relocs 5B, #linenums 0, checksum 0
006 00000000 SECT3 notype Static | .bss
Section length 7, #relocs 0, #linenums 0, checksum 0
008 00000000 SECT3 notype Static | $SG6258
009 00000004 UNDEF notype External | _optarg
00A 00000004 UNDEF notype External | _optreset
00B 00000000 SECT4 notype Static | .data
Section length 44, #relocs 1, #linenums 0, checksum 2C7EE1AD
00D 00000000 SECT4 notype External | _opterr
00E 00000004 SECT4 notype External | _optind
00F 00000008 SECT4 notype External | _optopt
010 0000000C SECT4 notype Static | _place
Note that the unitialized variables are marked as "UNDEF" whereas optopt,
optind and optopt are marked as "SECT4".
After a bit of digging, I have a feeling that the place to fix this is the
source file that puts this in the generated libtool script:
# Take the output of nm and produce a listing of raw symbols and C names.
global_symbol_pipe="gawk ' {last_section=section; section=\$ 3};
/Section length .*#relocs.*(pick any)/{hide[last_section]=1}; \$
0!~/External *\\|/{next}; / 0+ UNDEF /{next}; / UNDEF
\\([^|]\\)*()/{next}; {if(hide[section]) next}; {f=0}; \$
0~/\\(\\).*\\|/{f=1}; {printf f ? \"T \" : \"D \"}; {split(\$ 0, a,
/\\||\\r/); split(a[2], s)}; s[1]~/^...@?]/{print s[1], s[1]; next};
s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))} '
prfx=^_"
My libtool/awk skills are not where they need to be to fix this. My
understanding of symbol resolution/linking in general is not where it needs
to be to even know if pulling in everything marked "External" but not
necessarily "UNDEF" is the right thing to do.
I could (obviously) use a hand here.
Thanks for your help.
I don't think the awk script is at fault, if I run your dumpbin -symbols
data through that global_symbols_pipe (manually, m4sh-isms stripped
of course) it produces:
D _optarg optarg
D _optreset optreset
D _opterr opterr
D _optind optind
D _optopt optopt
which seems about right. Sure, the initialized variables *could* have
been marked with C instead of D, but I think C and D are treated
equally further down in the processsing.
However, to be 100% certain and eliminate any doubt you can - if you
wish - configure with NM=nm (instead of dumpbin -symbols) and see if
that makes any difference.
I need to see more of what you are actually trying to do, the real
libtool invocations and the output they produce etc. Compress the
output if it is large...
Cheers,
Peter
_______________________________________________
http://lists.gnu.org/mailman/listinfo/libtool