URGENT Help with port of command line app...

Posted:
in Genius Bar edited January 2014
HI all,



My department is making an investment in a server farm next week. I have almost managed to pitch an Apple solution, but acceptance is predicated on the successful porting of several mission critical apps to OSX. I have managed most of them, even though I am a relative UNIX newbie, but one has me stumped, and I'm asking here for help to finish the project.



It's an obscure little app called Abidot.

It can be obtained <a href="http://www.tbi.univie.ac.at/~ivo/RNA/ALIDOT/"; target="_blank">HERE</a>.



IT should be a breeze, except for one issue.



On first attempt, after "./configure" and "make", it complains about no "malloc.h". No problem; I'm aware of the issue here, so I touch malloc.h in appropriate directory and start again. Passed hurdle #1.



On second attempt it complains about no "getopt.h". I search for getopt.h and find it in the source directory of another UNIX app I use, but nowhere in the system. I copy that file into /usr/include and try again. This time it compiles but craps out with an error in the linker stage... Here is the whole make attempt (only 10 lines or so, its a small app)...



[code]:



[Home:/Applications/Biology/alidot-2.0] admin% make

make all-recursive

Making all in Tutorial

make[2]: Nothing to be done for `all'.

gcc -DHAVE_CONFIG_H -I. -I. -I. -fno-common -fno-strict-aliasing -flat_namespace -g -O2 -c main.c

gcc -DHAVE_CONFIG_H -I. -I. -I. -fno-common -fno-strict-aliasing -flat_namespace -g -O2 -c ali.c

gcc -DHAVE_CONFIG_H -I. -I. -I. -fno-common -fno-strict-aliasing -flat_namespace -g -O2 -c PS_dot.c

gcc -DHAVE_CONFIG_H -I. -I. -I. -fno-common -fno-strict-aliasing -flat_namespace -g -O2 -c compare.c

gcc -g -O2 -flat_namespace --disable-shared -o alidot main.o ali.o PS_dot.o compare.o -lm

ld: Undefined symbols:

_getopt_long

make[2]: *** [alidot] Error 1

make[1]: *** [all-recursive] Error 1

make: *** [all-recursive-am] Error 2





</pre><hr></blockquote>



I can add "-undefined suppress " to the linker flags and pass the compile stage. But then the app will die with the follwing message upon execution...





code:



[WYRMELAIR:Biology/alidot-2.0/Tutorial] admin% [code]alidot &lt; HIV_5prime.aln &gt; alidot.out

dyld: alidot Undefined symbols:

_getopt_long

Trace/BPT trap



</pre><hr></blockquote>





I am at wits end. Any help would be appreciated. And because a purchase decision hangs in the balance with 10s of thousands of dollars potentially going Apple's way, I would appreciate a quick response.



Regards.



Stephen



PS cross-posted at MacOSXHints.com

Comments

  • Reply 1 of 6
    rodukroduk Posts: 706member
    Is [i]_getop
  • Reply 2 of 6
    getopt.h is a GNU header file that is used for parsing options from the command line. getopt_long is used to handle long name options like "--version".



    The header file includes this section which seems to define getopt_long. I don't speak C, but it looks to me like there is a conditional statement that might apply this definition only in the context of the Gnu C library.



    [code]

    #ifndef _GETOPT_H

    #define _GETOPT_H 1



    #include "config.h"



    #ifdef __cplusplus

    extern "C" {

    #endif



    /* For communication from `getopt' to the caller.

    When `getopt' finds an option that takes an argument,

    the argument value is returned here.

    Also, when `ordering' is RETURN_IN_ORDER,

    each non-option ARGV-element is returned here. */



    extern char *optarg;



    /* Index in ARGV of the next element to be scanned.

    This is used for communication to and from the caller

    and for communication between successive calls to `getopt'.



    On entry to `getopt', zero means this is the first call; initialize.



    When `getopt' returns -1, this is the index of the first of the

    non-option elements that the caller should itself scan.



    Otherwise, `optind' communicates from one call to the next

    how much of ARGV has been scanned so far. */



    extern int optind;



    /* Callers store zero here to inhibit the error message `getopt' prints

    for unrecognized options. */



    extern int opterr;



    /* Set to an option character which was unrecognized. */



    extern int optopt;



    /* Describe the long-named options requested by the application.

    The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector

    of `struct option' terminated by an element containing a name which is

    zero.



    The field `has_arg' is:

    no_argument (or 0) if the option does not take an argument,

    required_argument (or 1) if the option requires an argument,

    optional_argument (or 2) if the option takes an optional argument.



    If the field `flag' is not NULL, it points to a variable that is set

    to the value given in the field `val' when the option is found, but

    left unchanged if the option is not found.



    To have a long-named option do something other than set an `int' to

    a compiled-in constant, such as set a value from `optarg', set the

    option's `flag' field to zero and its `val' field to a nonzero

    value (the equivalent single-letter option character, if there is

    one). For long options that have a zero `flag' field, `getopt'

    returns the contents of the `val' field. */



    struct option

    {

    #if defined (__STDC__) && __STDC__

    const char *name;

    #else

    char *name;

    #endif

    /* has_arg can't be an enum because some compilers complain about

    type mismatches in all the code that assumes it is an int. */

    int has_arg;

    int *flag;

    int val;

    };



    /* Names for the values of the `has_arg' field of `struct option'. */



    #define no_argument 0

    #define required_argument 1

    #define optional_argument 2



    #if defined (__STDC__) && __STDC__

    #ifdef __GNU_LIBRARY__

    /* Many other libraries have conflicting prototypes for getopt, with

    differences in the consts, in stdlib.h. To avoid compilation

    errors, only prototype getopt for the GNU C library. */

    extern int getopt (int argc, char *const *argv, const char *shortopts);

    #else /* not __GNU_LIBRARY__ */

    extern int getopt ();

    #endif /* __GNU_LIBRARY__ */

    extern int getopt_long (int argc, char *const *argv, const char *shortopts,

    const struct option *longopts, int *longind);

    extern int getopt_long_only (int argc, char *const *argv,

    const char *shortopts,

    const struct option *longopts, int *longind);



    /* Internal only. Users should not call this directly. */

    extern int _getopt_internal (int argc, char *const *argv,

    const char *shortopts,

    const struct option *longopts, int *longind,

    int long_only);

    #else /* not __STDC__ */

    extern int getopt ();

    extern int getopt_long ();

    extern int getopt_long_only ();



    extern int _getopt_internal ();

    #endif /* __STDC__ */



    #ifdef __cplusplus

    }

    #endif



    #endif /* _GETOPT_H */

    </pre><hr></blockquote>
  • Reply 3 of 6
    rodukroduk Posts: 706member
    The header file seems to be declaring getopt_long, rather than _getopt_long, which is what the linker seems to be looking for.

    Also, it seems to be declaring it as an external, i.e. the routine itself is defined in another unit, which perhaps isn't being linked in. Is there a file called getopt.c in the same place where you copied getopt.h from?
  • Reply 4 of 6
    wormboywormboy Posts: 220member
    Yes, there is a getopt.c file. I've got a couple of them now. But I would not know how to require getopt.c and link in any compiled getopt.o during the build.



    I have been pointed to a <a href="http://www.geocrawler.com/archives/3/11114/2001/7/0/6258047/"; target="_blank">discussion</a> over at the fink developer forum, but it was more than a year old, and I was hoping that this issue had been dealt with. I guess not.



    Any ideas? Reading the fink discussion, it appears that there is a fairly trivial solution, esp. for such a modest program, but I'm just too naive on how to execute the solution.
  • Reply 5 of 6
    rodukroduk Posts: 706member
    Hmmm. From the link it looks as if getopt_long, which your application requires, is not supported by all Unices, including OS X. They mention some apps include GNU code to emulate it, and I wonder whether that's what you already have. You say you found getopt.h in the source directory of another UNIX application you use. Have you successfully compiled this application in the past?



    If you have, the following may work:



    Copy getopt.c to the directory where the other .c files are that you are trying to compile.



    Edit getopt.h (which you have already copied) and getopt.c to replace all occurences of getopt_long with _getopt_long, if there are no existing occurences with the leading underscore.



    Edit the make file as follows:



    gcc -DHAVE_CONFIG_H -I. -I. -I. -fno-common -fno-strict-aliasing -flat_namespace -g -O2 -c main.c

    gcc -DHAVE_CONFIG_H -I. -I. -I. -fno-common -fno-strict-aliasing -flat_namespace -g -O2 -c ali.c

    gcc -DHAVE_CONFIG_H -I. -I. -I. -fno-common -fno-strict-aliasing -flat_namespace -g -O2 -c PS_dot.c

    gcc -DHAVE_CONFIG_H -I. -I. -I. -fno-common -fno-strict-aliasing -flat_namespace -g -O2 -c compare.c

    gcc -DHAVE_CONFIG_H -I. -I. -I. -fno-common -fno-strict-aliasing -flat_namespace -g -O2 -c getopt.c

    gcc -g -O2 -flat_namespace --disable-shared -o alidot main.o ali.o PS_dot.o compare.o getopt.o -lm



    The make file should be editable with a standard editor, and can be found by greping for something you know is in the file, like DHAVE_CONFIG_H.



    Cross your fingers and try compiling the application.



    [ 10-12-2002: Message edited by: RodUK ]</p>
  • Reply 6 of 6
    wormboywormboy Posts: 220member
    me -&gt; slaps head



    fink install gnugetopt



    problem solved.



    I looked at fink first, but missed this file in the list. Should'a used grep.



    Thanks for the suggestions. Case closed.
Sign In or Register to comment.