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/  -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


Popular posts from this blog

Book Review : How To Create Pragmatic, Lightweight Languages

At last, a guide that makes creating a language with its associated baggage of lexers, parsers and compilers, accessible to mere mortals, rather to a group of a few hardcore eclectics as it stood until now.

The first thing that catches the eye, is the subtitle:

The unix philosophy applied to language design, for GPLs and DSLs"
What is meant by "unix philosophy" ?. It's taking simple, high quality components and combining them together in smart ways to obtain a complex result; the exact approach the book adopts.
I'm getting ahead here, but a first sample of this philosophy becomes apparent at the beginnings of Chapter 5 where the Parser treats and calls the Lexer like  unix's pipes as in lexer|parser. Until the end of the book, this pipeline is going to become larger, like a chain, due to the amount of components that end up interacting together.

The book opens by putting things into perspective in Chapter 1: Motivation: why do you want to build lan…

How Much Gameplay Can You Pack In Just 13K?

Given our expectations of Xbox games, you might consider writing a game within a 13K limit, which is the challenge for the annual js13K competition far too restrictive. Its results are now out and prove that it is possible to produce a game that is fun to play. 

Back in the tape loading days and on platforms the likes of Commodore64 games came in sizes of 4K or less. As proof of concept, here's a list of a few such 4K titles, copied over from Lemon64 's archive:
Alien SidestepBug CrusherDot GobblerClose EncountersDot Gobbler v2GridrunnerLaser CyclesMarios BrewerySpace ActionSpace RicoshayTank WarsHesmon64Retro Ball  Fast forward to now, at a time when Javascript's eating the world by making all sorts of applications or  games available to everyone through the medium of the browser, rendering the need of dedicated platforms and Operating systems obsolete, 13K is sufficient enough to pack both gameplay AND cool graphics due to the advanced browser engines and HTML5.

Hour of Code 2017 Introduces App Lab

t's the time of year when the world-class Hour of Code once more commences; just an hour for introducing coding to the uninitiated, having them complete self guided tutorials. But is a hour sufficient? What can a beginner actually code within this limit? The answer is a bit more complicated than that, so let's find out all about it! Integrated into the larger, worldwide, annual Computer Science Education week, this year taking place December 4-10, Hour of Code's novel mission has always been to get everybody coding, aged from 4 to 104, by providing: "a one-hour introduction to computer science, designed to demystify code, showing that anybody can learn the basics, and broadening participation in the field of computer science". But first of all, why this obsession with Computer Science, in particular in getting  kids as young as 4 to learn to code? The answer is simple. Nowadays code is everywhere around us, from desktop computers to mobile phones and, thanks to w…