Compiling OpenSSL in Solaris 10 with GCC 5.1.0
I got this error when trying to compile OpenSSL 1.0.2d on my Solaris machines:
[...] gcc -I.. -I../.. -I../modes -I../asn1 -I../evp -I../../include -fPIC -DOPENSSL_PIC -DZLIB_SHARED -DZLIB -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -Wa,--noexecstack -m64 -O3 -Wall -DL_ENDIAN -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM -DECP_NISTZ256_ASM -c -o randfile.o randfile.c In file included from /usr/include/stdio.h:21:0, from randfile.c:65: /usr/local/lib/gcc/i386-pc-solaris2.10/5.1.0/include-fixed/sys/feature_tests.h:346:2: error: #error "Compiler or options invalid for pre-UNIX 03 X/Open applications and pre-2001 POSIX applications" #error "Compiler or options invalid for pre-UNIX 03 X/Open applications \ ^ <builtin>: recipe for target 'randfile.o' failed make[2]: *** [randfile.o] Error 1 make[2]: Leaving directory '/tmp/z/openssl-1.0.2d/crypto/rand' Makefile:88: recipe for target 'subdirs' failed make[1]: *** [subdirs] Error 1 make[1]: Leaving directory '/tmp/z/openssl-1.0.2d/crypto' Makefile:283: recipe for target 'build_crypto' failed make: *** [build_crypto] Error 1
When I get an error like this my next step is to try to compile again the already (own) compiled version present in my system. In this particular case I downloaded and recompiled OpenSSL 1.0.2c again. It fails with the same error, but it was correctly compiled a month ago. Given this, I know that the problem is not with the changes in the new release but changes in my environment.
Notably I upgraded my installed GCC version from 4.9.2 to 5.1.0 a few days ago.
The source code raising the error didn't changed between GCC 4.9.2 and 5.1.0:
$ diff -u \ /usr/local/lib/gcc/i386-pc-solaris2.10/4.9.2/include-fixed/sys/feature_tests.h \ /usr/local/lib/gcc/i386-pc-solaris2.10/5.1.0/include-fixed/sys/feature_tests.h \ $ echo $? 0
Let's see it:
/* * It is invalid to compile an XPG3, XPG4, XPG4v2, or XPG5 application * using c99. The same is true for POSIX.1-1990, POSIX.2-1992, POSIX.1b, * and POSIX.1c applications. Likewise, it is invalid to compile an XPG6 * or a POSIX.1-2001 application with anything other than a c99 or later * compiler. Therefore, we force an error in both cases. */ #if defined(_STDC_C99) && (defined(__XOPEN_OR_POSIX) && !defined(_XPG6)) #error "Compiler or options invalid for pre-UNIX 03 X/Open applications \ and pre-2001 POSIX applications" #elif !defined(_STDC_C99) && \ (defined(__XOPEN_OR_POSIX) && defined(_XPG6)) #error "Compiler or options invalid; UNIX 03 and POSIX.1-2001 applications \ require the use of c99" #endif
Quite interesting, indeed. My first suspicion was that GCC 5.1.0 is defining _STDC_C99, but I was mistaken:
$ gcc -dM -E - </dev/null|grep -i C99
Humm...
Let's take a look to the sourcecode raising the issue, openssl-1.0.2d/crypto/rand/randfile.c. I see this suspicious code:
/* We need to define this to get macros like S_IFBLK and S_IFCHR */ #if !defined(OPENSSL_SYS_VXWORKS) # define _XOPEN_SOURCE 500 #endif |
Apparently setting _XOPEN_SOURCE to 500 enables some additional flags in GCC 5.1.0. Interestingly this setting is enabled in every system beside VxWorks, but maybe we don't need it in Solaris.
Let's delete those lines and try to recompile.
Everything goes well this time. Solaris doesn't need that #define.
make check is green.
Success!.
Bonus Track
I was curious and I checked the usage of S_IFBLK and S_IFCHR in the code. I found this:
This is interesting. I would expect S_IFBLK and S_IFCHR detection at configuration time, but the programmer wrote a compilation-time check. That is, if those #define are missing, the code will compile anyway, skipping some checks.
So maybe Solaris needs #define _XOPEN_SOURCE 500 after all. I checked /usr/include/sys/stat.h header file to be sure and, fortunately, I confirm that those flags are always available, independently of _XOPEN_SOURCE value.
Just to be sure we could do this change:
--- crypto/rand/randfile.c.old 2015-07-10 02:44:30.171640289 +0200 +++ crypto/rand/randfile.c 2015-07-10 02:54:20.081824839 +0200 @@ -57,7 +57,7 @@ */ /* We need to define this to get macros like S_IFBLK and S_IFCHR */ -#if !defined(OPENSSL_SYS_VXWORKS) +#if !defined(OPENSSL_SYS_VXWORKS) && !defined(__sun) # define _XOPEN_SOURCE 500 #endif @@ -82,6 +82,12 @@ # include <fcntl.h> #endif +#if defined(__sun) +# if !defined(S_IFBLK) || !defined(S_IFCHR) +# error "We need S_IFBLK and S_IFCHR" +# endif +#endif + #ifdef _WIN32 # define stat _stat # define chmod _chmod
Better safe than sorry.