[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: buildd failure for amd64 - floating point encoding?



Helen Faulkner wrote:
> Please CC to me - I'm not subscribed to the list.
> 
> I am maintaining a new package, labplot, that is failing, at its first 
> upload, to build on amd64 (among other things).

According to the package page it looks like this failed on all but
four of the current architectures.

> I believe the problem is that there is no floating point encoding
> being defined for that architecture, which is leading to an
> undefined type of struct later on.

I agree.  I looked at the code only briefly.  Enough to have it scare
me about the design of the code.  This looks to be a very old style of
programming where every possible configuration of machine is
specifically enumerated.  Blech!  The more modern style is to deduce
these things at configure time.  In particular this code seems to want
to know very particular bit encodings of how the cpu does floating
point.  That can be a trouble spot.

> The program defines the floating point encoding in the included cdf library 
> like this (from cdf/cdfdist.h, line 437 onwards):
> 
> /*****************************************************************************
> * Floating-point encodings.
> *   1..........Sun, SGi, IBM-RS, HP, NeXT, Macintosh
> *   2..........DECstation, IBM-PC, Alpha (OSF/1), Alpha (OpenVMS - 
> IEEE_FLOAT)
> *   3..........VAX, Alpha (OpenVMS - D_FLOAT)
> *   4..........Alpha (OpenVMS - G_FLOAT)
> *****************************************************************************/

The amd64 is basically an improved i386.  I would use that encoding as
a first guess.  I can't say this is really the right answer but it is
where I would start.  So I would make it look like the IBMPC.

If you follow the defines earlier in the code you will see the
following:

  #if defined(linux) || defined(__CYGWIN__)
  #  if defined(PPC)
  #    define POWERPC
  #  else
  #    if defined(i386)
  #      define IBMPC
  #    else
  #      if defined(__alpha)
  #        define alphaosf
  #      endif
  #    endif
  #  endif
  #endif

I believe that is how this is getting compiled on an i386 linux
platform.  You will want the same to occur on both amd64 and ia64.  I
know neither of those are IBMPC machines but those are probably
closest.  For the minimum change I would suggest the following.

 - #    if defined(i386)
 + #    if defined(i386) || defined(__amd64) || defined(__ia64)

I think from looking at the code that one of IBMPC, DEC, or MIEEE must
always be defined or things won't work.  So you are pretty much
committed to trying that.

> #if 
> defined(sun)||defined(MIPSEB)||defined(IBMRS)||defined(HP)||defined(NeXT)||defined(mac)||defined(POWERPC)
> #  define FP1cpu
> #endif
> 
> #if 
> defined(MIPSEL)||defined(IBMPC)||defined(alphaosf)||defined(alphavmsI)||defined(posixSHELLalphaI)
> #  define FP2cpu
> #endif
> 
> #if defined(vax)||defined(alphavmsD)||defined(posixSHELLalphaD)
> #  define FP3cpu
> #endif
> 
> #if defined(alphavmsG)||defined(posixSHELLalphaG)
> #  define FP4cpu
> #endif

Notice that the buildds that were successful were all covered by the
above with alpha, mips, i386.

A quick glance through the code finds a zillion #ifdef's there for
every possible combination.  Ugh.  QA on this type of program is
really difficult.  It may, and probably will, behave differently on
every platform.  Just because it works on one platform means nothing
about how it will work on another platform.  This code would be a good
example of the classic programming style of 20 years ago.a

Here is one quick example I saw:

  /* Return 1 if the sign bit of x is 1, else 0.  */

  int signbit(double x)
  {
  union
          {
          double d;
          short s[4];
          int i[2];
          } u;

  u.d = x;

  if( sizeof(int) == 4 )
          {
  #ifdef IBMPC
          return( u.i[1] < 0 );
  #endif
  #ifdef DEC
          return( u.s[3] < 0 );
  #endif
  #ifdef MIEEE
          return( u.i[0] < 0 );
  #endif
          }
  else
          {
  #ifdef IBMPC
          return( u.s[3] < 0 );
  #endif
  #ifdef DEC
          return( u.s[3] < 0 );
  #endif
  #ifdef MIEEE
          return( u.s[0] < 0 );
  #endif
          }
  }

Notice that if none of IBMPC, DEC, or MIEEE is not defined that the
return disappears and the function just falls off of the end with
nothing to catch that error?  Ugh.  (I wonder what this does in the
POWERPC case?)

I am on a slow connection right now and can't really stand to install
of the build dependencies needed for this program.  So I was unable to
test my suggestion.

Bob



Reply to: