This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: libiberty and getopt


bertrand marquis wrote:

Hi again,

   i just find the solution to my problem
   in fact it seems that adding:

extern int optind;
extern char *optarg;

solve the problem. The compiler then auto-import these variables and it is working after. This problem doesn't seem to exist under linux but it could be a difference in versions between my linux and my cygwin.

bertrand marquis a écrit:

Hi,

I need to compile a program using libiberty.a and the function getopt_long. When compiling with the flag -liberty my program crash because it don't take the right arguments from the command line. But without libiberty this part work before.

i made a small program showing that problem, if anyone has an idea ?
i'm using the latest cygwin from the installer ,gcc-3.3.1 and ld 2.15.90 20040312


thanks

You can find next my source code for the test program and the result i have with it.


My test program:


/*begin of argu.c*/
#include <unistd.h>
#include <getopt.h>
#include <ctype.h>
#include <stdio.h>

int main(int argc, char **argv) {

   struct option long_opts[] = {
   {"v", 1, 0, 'v'},
   {"no-v", 0, 0, 'V'},
   {"k", 1, 0, 'k'},
   {"no-k", 0, 0, 'K'},
   {"l", 1, 0, 'l'},
   {"no-l", 0, 0, 'L'},
   {0, 0, 0, 0}
   };
   int c;
   while ((c = getopt_long(argc, argv, "v:Vk:Kl:L:",
       long_opts, NULL)) != EOF) {

switch(c) {
case 'v':
printf("v %s\n",optarg);
break;
case 'V':
printf("V\n");
break;
case 'k':
printf("k %s\n",optarg);
break;
case 'K':
printf("K\n");
break;
case 'l':
printf("l %s\n",optarg);
break;
case 'L':
printf("L\n");
break;
case '?':
printf("other:%c\n",c);
}
}
printf("argc=%d , optind=%d , file=%s\n",argc,optind,argc>optind?*(argv+optind):"none");
return 0;
}
/*end of argu.c*/


when you compile it with : gcc argu.c -o argu.exe it works:
$ ./argu.exe -v abc -K test
v abc
K
argc=5 , optind=4 , file=test

but when you compile it with gcc argu.c -o argu.exe -liberty it gives:
$ ./argu.exe -v abc -K test
v (null)
K
argc=5 , optind=1 , file=-v

When you link with libiberty you are linking to an implementation of getopt* that does not correspond to the headers you have included.


There is no symbol called _optarg (or _optind, etc.) in libcygwin.a. The Cygwin headers declare the opt* variables __declspec(dllimport). So when you include the Cygwin headers, when you refer to optarg the symbol that gets generated is __imp__optarg, which /is/ exported from libcygwin.a. The version of getopt* in libiberty refers to symbols named _opt* and not __imp__opt*. So when you link against libiberty, your program and getopt() are referring to different opt* variables.

When you re-declare the opt* variables, you effectively undo the __declspec(dllimport) so your program again refers to _opt* instead of __imp__opt*. MSVC issues a warning in this case; gcc, it seems, does not.

A better way to solve this, I think, would be to link against libcygwin.a before libiberty.a.

~$ gcc argu.c -o argu.exe -lcygwin -liberty
~$ ./argu.exe -v abc -K test
v abc
K
argc=5 , optind=4 , file=test


FWIW, this has come up before:


http://sources.redhat.com/ml/cygwin/2004-02/msg00063.html


HTH, Cheers



-- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]