Skip to main content

old gcc + new a2ps = library mismatch

I wanted to set up a2ps 4.14 on an old SCO Unix machine (which suprsingly had a gcc compiler installed) for Transforming Ingres' legacy reports with PostScript 

Before you set up a2ps, you have to set gperf up first. Its installation  was a breeze, so I assumed that a2ps would install easily too.....However that was not the case; when reaching the 'make' phase I was getting the following error :

Making all in lib
        make  all-am
Making all in src
        make  all-am
        /bin/ksh ../libtool --tag=CC --mode=link gcc  -g -O2     -o a2ps  main.o
 read.o  sshread.o ssheet.o select.o  generate.o delegate.o regex.o  buffer.o ve
rsions.o ffaces.o  version-etc.o long-options.o  parsessh.o lexssh.o lexps.o  sh
eets-map.o ../lib/liba2ps.la  -lm
gcc -g -O2 -o a2ps main.o read.o sshread.o ssheet.o select.o generate.o delegate
.o regex.o buffer.o versions.o ffaces.o version-etc.o long-options.o parsessh.o
lexssh.o lexps.o sheets-map.o  ../lib/.libs/liba2ps.a -lm 
 
Undefined                       first referenced
symbol                              in file
va_copy                             liba2ps.a(printlen.o) 
 
UX:ld: ERROR: Symbol referencing errors. No output written to a2ps
collect2: ld returned 1 exit status
*** Error code 1 (bu21)
UX:make: ERROR: fatal error.
*** Error code 1 (bu21)
UX:make: ERROR: fatal error.
*** Error code 1 (bu21)
UX:make: ERROR: fatal error.
*** Error code 1 (bu21)
UX:make: ERROR: fatal error. 
 
After a minute of constant....swearing (!!), I found my cool again and set to examine liba2ps.a

liba2ps.a is a collection of libraries, whose dissasembly reveals :

Symbols from ./lib/.libs/liba2ps.a[printlen.o]:

[Index]     Value      Size      Type  Bind  Other Shndx   Name

[1]       |0         |0         |FILE |LOCL |0    |ABS    |printlen.c
[2]       |0         |0         |SECT |LOCL |0    |1      |
[3]       |0         |0         |SECT |LOCL |0    |3      |
[4]       |0         |0         |SECT |LOCL |0    |4      |
[5]       |0         |0         |NOTY |LOCL |0    |1      |gcc2_compiled.
[6]       |0         |0         |SECT |LOCL |0    |6      |
[7]       |0         |0         |SECT |LOCL |0    |7      |
[8]       |0         |0         |SECT |LOCL |0    |9      |
[9]       |0         |0         |SECT |LOCL |0    |12     |
[10]      |0         |253       |FUNC |LOCL |0    |1      |int_printflen
[11]      |0         |0         |SECT |LOCL |0    |14     |
[12]      |0         |0         |NOTY |LOCL |0    |14     |__FRAME_BEGIN__
[13]      |0         |0         |SECT |LOCL |0    |16     |
[14]      |0         |0         |SECT |LOCL |0    |18     |
[15]      |0         |0         |SECT |LOCL |0    |5      |
[16]      |0         |0         |SECT |LOCL |0    |11     |
[17]      |0         |0         |NOTY |GLOB |0    |UNDEF  |strchr
[18]      |256       |43        |FUNC |GLOB |0    |1      |vprintflen
[19]      |0         |0         |NOTY |GLOB |0    |UNDEF  |va_copy
[20]      |300       |26        |FUNC |GLOB |0    |1      |printflen

that 'va_copy' is referenced in the printlen.o library and printlen.c file.Examining printlen.c we find a call to it at line 102 :
va_copy (ap, args);

Also since it is a GLOB binding we gather that it is defined elsewhere and not inside printlen.o; as a matter of fact it is not defined in none of the a2ps libraries but belongs to the underlying c library (or gcc library in this case) with its definition appearing in the 'stdarg.h' header :

vi ./usr/gnu/lib/gcc-lib/i586-unknown-sysv5/2.95.3pl1/include/stdarg.h

/* Copy __gnuc_va_list into another variable of this type. */
#define __va_copy(dest, src) (dest) = (src)
#endif /* _STDARG_H */

the issue here is that the gcc version is outdated,hence the gcc library itself, and subsequnetly 'va_copy''s signature does not match the one of the prototype inside printlen.c

Getting a new version of gcc was not an option; I was happy enough to see that there was a gcc instalation after all,let alone installing a new one!
So I was set for a workaround; modify the macro's definition from :

/* Copy __gnuc_va_list into another variable of this type. */
#define __va_copy(dest, src) (dest) = (src)
#endif /* _STDARG_H */

to :

/* Copy __gnuc_va_list into another variable of this type. */
#define va_copy(d,s)
#endif /* _STDARG_H */

This little change satisfied 'make',compiled successfully and a2ps was set up, at last. Now a test was in order to see if it actually works; fortunatelly it did and a2ps transformed a text file into a perfect postscript one

Comments

Popular posts from this blog