Any way to detect SparcWorks on SunOS?
Asked Answered
D

3

11

I've got a legacy C++ code base which includes the following:

// this kludge is required because SparcWorks 3.0.1 under SunOS
// includes malloc.h in stdlib.h, and misdeclares free() to take a char*, 
// and malloc() and memalign() to return char*

Clearly this is some leftover from ancient C. The comment is followed by prototypes (wrong here on Fedora Linux 39, they clash with the ones glibc-2.38-18 has). I'd like to #if that part out cleanly. Any macro that I can use?

Dyak answered 23/4 at 11:40 Comment(5)
Is there any reason for preserving the 1990's codebase?Gillian
@Gillian While 1990 might not be the most current one, maybe the code does exactly what they need, and fixing a few hiccups might be faster than rewriting the whole thing. Or maybe they do want to rewrite the whole thing, but also start with something that already works...Suture
@Gillian You sure it's that recent? ;-) SparcWorks 3.0.1 was "old" 21 years ago... Also, see How to print preprocessor macros under Sun Studio? - assuming those options work...Beka
@AndrewHenle, I don't have access to any Suns anymore (and didn't run SunOS on it when I had one ;-). This is legacy code, still (somewhat) maintained. I can't just go and trample all over it to make it build here if I want to benefit from upstream changes.Dyak
-xdumpmacros does not appear as an option in the C 3.0.1 User’s GuideBeka
G
9

You could try to use both these macros:

  • __SUNPRO_CC (for C++) or __SUNPRO_C (for C), which are macros typically defined by the SparcWorks compiler indicating the usage of Sun C/C++ compiler;
  • __sun, which is a macro defined by the SunOS platform, indicating the usage of the Sun compiler.
#if defined(__SUNPRO_CC) && defined(__sun)
// Specific code for SparcWorks compiler on SunOS
#else
// Code for other compilers or platforms
#endif

Maybe useful reference: Sun™ Studio 12: C++ FAQ

Glimmering answered 23/4 at 12:8 Comment(3)
It seems the version is critical here (again, I have no access to such a machine, so I'm flying mostly blind).Dyak
@Dyak It seems the version is critical here How so? Can you edit your question and add how the version matters, and what compiler(s) and OSes you have to support? It's not clear right now if you still have to support Solaris/SunOS or any of Sun/Oracle compiler(s) and if so what version(s).Beka
@AndrewHenle, what I copied in the question is all I've got. I have no access to Sun machines, even less with ancient versions of development tools, to check further. In any case, if I change this, presumably any user of those will fix it later. Or it never comes up.Dyak
B
6

A bit of Google magic discovered this link:

C 3.0.1 User’s Guide

Page 77 has this table:

The following predefinitions are valid in all modes:

  • __sparc (SPARC only)
  • __i386 (x86 only)
  • __sun
  • __unix
  • __BUILTIN_VA_ARG_INCR
  • __SVR4 (Solaris 2.x only)
  • __SUNPRO_C=0x301

__SUNPRO_C=0x301 seems to be definitive - for the C compiler. I've not been able to find the C++ documentation other than some 1992 product notes at https://vtda.org/docs/computing/Sun/hardware/801-3206-10_SPARCompilerSPARCworksProductNotes_RevA_Oct92.pdf

The document dates from 1994 - it appears to be a non-ANSI K&R compiler with support for an ANSI/C89 mode.


Given the comments and the questions stated need to support •glibc-based Fedora, the following outputs from cc -E -xdumpmacros /dev/null on Solaris 11 and RHEL 8 systems may prove useful.

RHEL 8:

cc -E -xdumpmacros /dev/null
#define __LINE__ 
#define __FILE__ 
#define __STDC__ 1
#define __STDC_VERSION__ 201112L
#define __DATE__ "Apr 23 2024"
#define __TIME__ "13:53:22"
#define __STDC_HOSTED__ 1
#define __STDC_ANALYZABLE__ 1
#define __STDC_NO_THREADS__ 1
#define __STDC_UTF_16__ 1
#define __STDC_UTF_32__ 1
#define __ATOMIC_RELAXED 0
#define __ATOMIC_CONSUME 1
#define __ATOMIC_ACQUIRE 2
#define __ATOMIC_RELEASE 3
#define __ATOMIC_ACQ_REL 4
#define __ATOMIC_SEQ_CST 5
#define __has_attribute (attr) ___has_attribute___ ( attr )
#define __SUNPRO_C 0x5150
#define __unix 1
#define __unix__ 1
#define __linux 1
#define __linux__ 1
#define __gnu__linux__ 1
#define __x86_64 1
#define __x86_64__ 1
#define __amd64 1
#define __amd64__ 1
#define _LP64 1
#define __LP64__ 1
#define __ORDER_LITTLE_ENDIAN__ 1234
#define __ORDER_BIG_ENDIAN__ 4321
#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
#define __BUILTIN_VA_STRUCT 1
#define __C11FEATURES__ 1
#define __C99FEATURES__ 1
#define __PRAGMA_REDEFINE_EXTNAME 1
#define unix 1
#define linux 1
#define __RESTRICT 1
#define __FLT_EVAL_METHOD__ 0
#define __SUN_PREFETCH 1
#define __SIZE_TYPE__ unsigned long
# 1 "/dev/null"
#ident "acomp: Studio 12.6 Sun C 5.15 Linux_i386 2017/05/30"

Solaris 11:

cc -E -xdumpmacros /dev/null
#define __LINE__ 
#define __FILE__ 
#define __STDC__ 0
#define __STDC_VERSION__ 201112L
#define __DATE__ "Apr 23 2024"
#define __TIME__ "14:04:45"
#define __STDC_IEC_559__ 1
#define __STDC_IEC_559_COMPLEX__ 1
#define __STDC_HOSTED__ 1
#define __STDC_ANALYZABLE__ 1
#define __STDC_NO_THREADS__ 1
#define __STDC_UTF_16__ 1
#define __STDC_UTF_32__ 1
#define __ATOMIC_RELAXED 0
#define __ATOMIC_CONSUME 1
#define __ATOMIC_ACQUIRE 2
#define __ATOMIC_RELEASE 3
#define __ATOMIC_ACQ_REL 4
#define __ATOMIC_SEQ_CST 5
#define __has_attribute (attr) ___has_attribute___ ( attr )
#define __SunOS_5_11 1
#define __SunOS_RELEASE 0x051100
#define __SUNPRO_C 0x5150
#define __unix 1
#define __SVR4__ 1
#define __svr4__ 1
#define __SVR4 1
#define __sun 1
#define __sun__ 1
#define __SunOS 1
#define __i386 1
#define __i386__ 1
#define __ORDER_LITTLE_ENDIAN__ 1234
#define __ORDER_BIG_ENDIAN__ 4321
#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
#define __BUILTIN_VA_ARG_INCR 1
#define __C11FEATURES__ 1
#define __C99FEATURES__ 1
#define __PRAGMA_REDEFINE_EXTNAME 1
#define unix 1
#define sun 1
#define i386 1
#define __RESTRICT 1
#define __FLT_EVAL_METHOD__ 0
#define __SUN_PREFETCH 1
# 1 "/dev/null"
#ident "acomp: Studio 12.6 Sun C 5.15 SunOS_i386 2017/05/30"

As a guess, I suspect the existence of __SunOS_RELEASE and its value will indicate whether or not you need to provide old, outdated prototypes in place of functions from standard headers.

Also, _sun and its various versions likely only indicates the OS. I'd think you'd need to use __SUNPRO of some type to indicate the Sun/Oracle compiler.

Beka answered 23/4 at 17:59 Comment(0)
D
1

You can use Boost.Predef for a cross-compiler cross-platform solution

#include <boost/predef.h>

// Architecture check
#if BOOST_ARCH_SPARC
    // OS check
    #if BOOST_OS_SOLARIS
        // Compiler check
        #if BOOST_COMP_SUNPRO
        #endif
    #endif
#endif

As specified in the documentation


Boost.Predef also contains other useful macros for platform detection, in summary:

  • BOOST_ARCH_ for system/CPU architecture one is compiling for.
  • BOOST_COMP_ for the compiler one is using.
  • BOOST_LANG_ for language standards one is compiling against.
  • BOOST_LIB_C_ and BOOST_LIB_STD_ for the C and C++ standard library in use.
  • BOOST_OS_ for the operating system we are compiling to.
  • BOOST_PLAT_ for platforms on top of operating system or compilers.
  • BOOST_ENDIAN_ for endianness of the os and architecture combination.
  • BOOST_HW_ for hardware specific features.
  • BOOST_HW_SIMD for SIMD (Single Instruction Multiple Data) detection.
Drawstring answered 25/4 at 7:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.