src/libm/math_private.h
author Sam Lantinga <slouken@libsdl.org>
Fri, 24 Nov 2017 03:01:07 -0800
changeset 11713 0083f778ede4
parent 11683 48bcba563d9c
child 11852 c3fc99758ad2
permissions -rw-r--r--
Fixed bug 3979 - Failed to link with "multiple definition of `scalbln'" error on both MinGW and MinGW-w64 by CMake

Vitaly Novichkov

Once I ran build of my codecs collection on AppVeyor where my CMake script downloads latest SDL2 from HG repo, failed to link because of math functions conflict:

https://ci.appveyor.com/project/Wohlstand/audiocodecs/build/1.0.44
The revision is b94292eebb5c

There are both vanilla MinGW and MinGW-w64 are failed to build.


```
[100%] Linking C shared library libSDL2.dll
c:/mingw/bin/../lib/gcc/mingw32/5.3.0/../../../libmingwex.a(scalbn.o):(.text+0x0): multiple definition of `scalbln'
CMakeFiles\SDL2.dir/objects.a(s_scalbn.c.obj):C:/projects/audiocodecs/build-MinGW-Release-Win32/external/SDL2/src/SDL2HG/src/libm/s_scalbn.c:30: first defined here
     1 /*
     2  * ====================================================
     3  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
     4  *
     5  * Developed at SunPro, a Sun Microsystems, Inc. business.
     6  * Permission to use, copy, modify, and distribute this
     7  * software is freely granted, provided that this notice
     8  * is preserved.
     9  * ====================================================
    10  */
    11 
    12 /*
    13  * from: @(#)fdlibm.h 5.1 93/09/24
    14  * $Id: math_private.h,v 1.3 2004/02/09 07:10:38 andersen Exp $
    15  */
    16 
    17 #ifndef _MATH_PRIVATE_H_
    18 #define _MATH_PRIVATE_H_
    19 
    20 /* #include <endian.h> */
    21 #include "SDL_endian.h"
    22 /* #include <sys/types.h> */
    23 
    24 #define _IEEE_LIBM
    25 #define attribute_hidden
    26 #define libm_hidden_proto(x)
    27 #define libm_hidden_def(x)
    28 #define strong_alias(x, y)
    29 
    30 #ifndef __HAIKU__ /* already defined in a system header. */
    31 typedef unsigned int u_int32_t;
    32 #endif
    33 
    34 #define atan            SDL_uclibc_atan
    35 #define __ieee754_atan2 SDL_uclibc_atan2
    36 #define copysign        SDL_uclibc_copysign
    37 #define cos             SDL_uclibc_cos
    38 #define fabs            SDL_uclibc_fabs
    39 #define floor           SDL_uclibc_floor
    40 #define __ieee754_fmod  SDL_uclibc_fmod
    41 #define __ieee754_log   SDL_uclibc_log
    42 #define __ieee754_pow   SDL_uclibc_pow
    43 #define scalbln         SDL_uclibc_scalbln
    44 #define scalbn          SDL_uclibc_scalbn
    45 #define sin             SDL_uclibc_sin
    46 #define __ieee754_sqrt  SDL_uclibc_sqrt
    47 #define tan             SDL_uclibc_tan
    48 
    49 /* The original fdlibm code used statements like:
    50 	n0 = ((*(int*)&one)>>29)^1;		* index of high word *
    51 	ix0 = *(n0+(int*)&x);			* high word of x *
    52 	ix1 = *((1-n0)+(int*)&x);		* low word of x *
    53    to dig two 32 bit words out of the 64 bit IEEE floating point
    54    value.  That is non-ANSI, and, moreover, the gcc instruction
    55    scheduler gets it wrong.  We instead use the following macros.
    56    Unlike the original code, we determine the endianness at compile
    57    time, not at run time; I don't see much benefit to selecting
    58    endianness at run time.  */
    59 
    60 /* A union which permits us to convert between a double and two 32 bit
    61    ints.  */
    62 
    63 /*
    64  * Math on arm is special:
    65  * For FPA, float words are always big-endian.
    66  * For VFP, floats words follow the memory system mode.
    67  */
    68 
    69 #if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
    70 
    71 typedef union
    72 {
    73     double value;
    74     struct
    75     {
    76         u_int32_t msw;
    77         u_int32_t lsw;
    78     } parts;
    79 } ieee_double_shape_type;
    80 
    81 #else
    82 
    83 typedef union
    84 {
    85     double value;
    86     struct
    87     {
    88         u_int32_t lsw;
    89         u_int32_t msw;
    90     } parts;
    91 } ieee_double_shape_type;
    92 
    93 #endif
    94 
    95 /* Get two 32 bit ints from a double.  */
    96 
    97 #define EXTRACT_WORDS(ix0,ix1,d)				\
    98 do {								\
    99   ieee_double_shape_type ew_u;					\
   100   ew_u.value = (d);						\
   101   (ix0) = ew_u.parts.msw;					\
   102   (ix1) = ew_u.parts.lsw;					\
   103 } while (0)
   104 
   105 /* Get the more significant 32 bit int from a double.  */
   106 
   107 #define GET_HIGH_WORD(i,d)					\
   108 do {								\
   109   ieee_double_shape_type gh_u;					\
   110   gh_u.value = (d);						\
   111   (i) = gh_u.parts.msw;						\
   112 } while (0)
   113 
   114 /* Get the less significant 32 bit int from a double.  */
   115 
   116 #define GET_LOW_WORD(i,d)					\
   117 do {								\
   118   ieee_double_shape_type gl_u;					\
   119   gl_u.value = (d);						\
   120   (i) = gl_u.parts.lsw;						\
   121 } while (0)
   122 
   123 /* Set a double from two 32 bit ints.  */
   124 
   125 #define INSERT_WORDS(d,ix0,ix1)					\
   126 do {								\
   127   ieee_double_shape_type iw_u;					\
   128   iw_u.parts.msw = (ix0);					\
   129   iw_u.parts.lsw = (ix1);					\
   130   (d) = iw_u.value;						\
   131 } while (0)
   132 
   133 /* Set the more significant 32 bits of a double from an int.  */
   134 
   135 #define SET_HIGH_WORD(d,v)					\
   136 do {								\
   137   ieee_double_shape_type sh_u;					\
   138   sh_u.value = (d);						\
   139   sh_u.parts.msw = (v);						\
   140   (d) = sh_u.value;						\
   141 } while (0)
   142 
   143 /* Set the less significant 32 bits of a double from an int.  */
   144 
   145 #define SET_LOW_WORD(d,v)					\
   146 do {								\
   147   ieee_double_shape_type sl_u;					\
   148   sl_u.value = (d);						\
   149   sl_u.parts.lsw = (v);						\
   150   (d) = sl_u.value;						\
   151 } while (0)
   152 
   153 /* A union which permits us to convert between a float and a 32 bit
   154    int.  */
   155 
   156 typedef union
   157 {
   158     float value;
   159     u_int32_t word;
   160 } ieee_float_shape_type;
   161 
   162 /* Get a 32 bit int from a float.  */
   163 
   164 #define GET_FLOAT_WORD(i,d)					\
   165 do {								\
   166   ieee_float_shape_type gf_u;					\
   167   gf_u.value = (d);						\
   168   (i) = gf_u.word;						\
   169 } while (0)
   170 
   171 /* Set a float from a 32 bit int.  */
   172 
   173 #define SET_FLOAT_WORD(d,i)					\
   174 do {								\
   175   ieee_float_shape_type sf_u;					\
   176   sf_u.word = (i);						\
   177   (d) = sf_u.value;						\
   178 } while (0)
   179 
   180 /* ieee style elementary functions */
   181 extern double
   182 __ieee754_sqrt(double)
   183     attribute_hidden;
   184      extern double __ieee754_acos(double) attribute_hidden;
   185      extern double __ieee754_acosh(double) attribute_hidden;
   186      extern double __ieee754_log(double) attribute_hidden;
   187      extern double __ieee754_atanh(double) attribute_hidden;
   188      extern double __ieee754_asin(double) attribute_hidden;
   189      extern double __ieee754_atan2(double, double) attribute_hidden;
   190      extern double __ieee754_exp(double) attribute_hidden;
   191      extern double __ieee754_cosh(double) attribute_hidden;
   192      extern double __ieee754_fmod(double, double) attribute_hidden;
   193      extern double __ieee754_pow(double, double) attribute_hidden;
   194      extern double __ieee754_lgamma_r(double, int *) attribute_hidden;
   195      extern double __ieee754_gamma_r(double, int *) attribute_hidden;
   196      extern double __ieee754_lgamma(double) attribute_hidden;
   197      extern double __ieee754_gamma(double) attribute_hidden;
   198      extern double __ieee754_log10(double) attribute_hidden;
   199      extern double __ieee754_sinh(double) attribute_hidden;
   200      extern double __ieee754_hypot(double, double) attribute_hidden;
   201      extern double __ieee754_j0(double) attribute_hidden;
   202      extern double __ieee754_j1(double) attribute_hidden;
   203      extern double __ieee754_y0(double) attribute_hidden;
   204      extern double __ieee754_y1(double) attribute_hidden;
   205      extern double __ieee754_jn(int, double) attribute_hidden;
   206      extern double __ieee754_yn(int, double) attribute_hidden;
   207      extern double __ieee754_remainder(double, double) attribute_hidden;
   208      extern int __ieee754_rem_pio2(double, double *) attribute_hidden;
   209 #if defined(_SCALB_INT)
   210      extern double __ieee754_scalb(double, int) attribute_hidden;
   211 #else
   212      extern double __ieee754_scalb(double, double) attribute_hidden;
   213 #endif
   214 
   215 /* fdlibm kernel function */
   216 #ifndef _IEEE_LIBM
   217      extern double __kernel_standard(double, double, int) attribute_hidden;
   218 #endif
   219      extern double __kernel_sin(double, double, int) attribute_hidden;
   220      extern double __kernel_cos(double, double) attribute_hidden;
   221      extern double __kernel_tan(double, double, int) attribute_hidden;
   222      extern int __kernel_rem_pio2(double *, double *, int, int, int,
   223                                   const int *) attribute_hidden;
   224 
   225 #endif /* _MATH_PRIVATE_H_ */