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

Spatial Data Management For GIS and Data Scientists

  Videos of the lectures taught in Fall 2023 at the University of Tennessee are now available as a YouTube playlist. They provide a complete overview of the concepts of GeoSpatial science using Google Earth Engine, PostgresSQL GIS , DuckDB, Python and SQL. https://www.i-programmer.info/news/145-mapping-a-gis/16772-spatial-data-management-for-gis-and-data-scientists.html