From 9466461ce026b23aec7c97472a00e2d2d16a5095 Mon Sep 17 00:00:00 2001 From: Xav101 Date: Sat, 14 Jan 2023 00:35:30 -0600 Subject: [PATCH] engine: preliminary support for SGI IRIX (#1211) * Added definitions for IRIX * Patchset to get dedicated server to compile on IRIX. * Cleaned up debug statements in wscript * Potential bug in IRIX implementation of isnan? For now just use the portable macro. * Include the platform port files in the build * Temporary execution script for setting appropriate library search paths to the right locations in the build directory. This should probably get replaced with a more permanent script at some point which lives in the same directory as the normal xash binary, or be replaced by a solution that sets the rpath during config or modifies rpath during install. * Clean up formatting and remove unneeded debugging statements * Added GPL copyright notice and description * Moved to irix platform folder and edited script * Re-introduced _inline macro * Replace spaces with tabs Co-authored-by: Xav101 --- common/xash3d_types.h | 4 ++++ engine/common/sys_con.c | 3 +++ engine/common/whereami.c | 27 +++++++++++++++++++++ engine/platform/irix/dladdr.c | 39 +++++++++++++++++++++++++++++++ engine/platform/irix/dladdr.h | 35 +++++++++++++++++++++++++++ engine/platform/irix/xash-exec | 9 +++++++ engine/platform/posix/lib_posix.c | 3 +++ engine/platform/posix/net.h | 3 +++ engine/platform/posix/sys_posix.c | 8 ++++--- engine/wscript | 3 +++ public/build.c | 2 ++ public/build.h | 3 +++ public/buildenums.h | 3 +++ public/xash3d_mathlib.h | 3 +++ wscript | 8 +++++++ 15 files changed, 150 insertions(+), 3 deletions(-) create mode 100644 engine/platform/irix/dladdr.c create mode 100644 engine/platform/irix/dladdr.h create mode 100755 engine/platform/irix/xash-exec diff --git a/common/xash3d_types.h b/common/xash3d_types.h index 7c1f3a84..adca2246 100644 --- a/common/xash3d_types.h +++ b/common/xash3d_types.h @@ -4,6 +4,10 @@ #include "build.h" +#if XASH_IRIX +#include +#endif + #if XASH_WIN32 #include // off_t #endif // _WIN32 diff --git a/engine/common/sys_con.c b/engine/common/sys_con.c index 67c5d3bb..b0a241a6 100644 --- a/engine/common/sys_con.c +++ b/engine/common/sys_con.c @@ -22,6 +22,9 @@ GNU General Public License for more details. #endif #include #include +#if XASH_IRIX +#include +#endif // do not waste precious CPU cycles on mobiles or low memory devices #if !XASH_WIN32 && !XASH_MOBILE_PLATFORM && !XASH_LOW_MEMORY diff --git a/engine/common/whereami.c b/engine/common/whereami.c index 4d3401a1..e7958363 100644 --- a/engine/common/whereami.c +++ b/engine/common/whereami.c @@ -795,6 +795,33 @@ int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length) return length; } +#elif defined(__sgi) + +/* + * These functions are stubbed for now to get the code compiling. + * In the future it may be possible to get these working in some way. + * Current ideas are checking the working directory for a binary with + * the same executed name and reading links, or worst case just searching + * through the entirety of the filesystem that's readable by the user. + * + * I'm not sure it's actually possible to find the absolute path via a + * direct method on IRIX. Its implementation of /proc is a fairly barebones + * SVR4 implementation. Other UNIXes (e.g. Solaris) have extensions to /proc + * that make finding the absolute path possible but these don't exist on IRIX. + */ + +WAI_FUNCSPEC +int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length) +{ + return -1; +} + +WAI_FUNCSPEC +int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length) +{ + return -1; +} + #else #error unsupported platform diff --git a/engine/platform/irix/dladdr.c b/engine/platform/irix/dladdr.c new file mode 100644 index 00000000..a7985dba --- /dev/null +++ b/engine/platform/irix/dladdr.c @@ -0,0 +1,39 @@ +/* +dladdr.c - dladdr implementation for SGI IRIX +Copyright (C) 2022 Xav101 +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +*/ + +/* + * From SGI IRIX's 'man dladdr' + * + * does not contain a prototype for dladdr or definition of + * Dl_info. The #include in the SYNOPSIS line is traditional, + * but contains no dladdr prototype and no IRIX library contains an + * implementation. Write your own declaration based on the code below. + * + * The following code is dependent on internal interfaces that are not + * part of the IRIX compatibility guarantee; however, there is no future + * intention to change this interface, so on a practical level, the code + * below is safe to use on IRIX. + * + * + * + * The following code has been reproduced from the manpage. + */ + +#include "dladdr.h" + +int dladdr(void *address, Dl_info* dl) +{ + void *v; + v = _rld_new_interface(_RLD_DLADDR, address, dl); + return (int)v; +} diff --git a/engine/platform/irix/dladdr.h b/engine/platform/irix/dladdr.h new file mode 100644 index 00000000..f4a4162b --- /dev/null +++ b/engine/platform/irix/dladdr.h @@ -0,0 +1,35 @@ +/* +dladdr.h - dladdr prototypes for SGI IRIX +Copyright (C) 2022 Xav101 +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +*/ + +/* See engine/platform/irix/dladdr.c for the requirement for this implementation */ + +#ifndef DLADDR_IRIX_H +#define DLADDR_IRIX_H + +#include +#ifndef _RLD_INTERFACE_DLFCN_H_DLADDR +#define _RLD_INTERFACE_DLFCN_H_DLADDR +typedef struct Dl_info { + const char * dli_fname; + void * dli_fbase; + const char * dli_saddr; + int dli_version; + int dli_reserved1; + long dli_reserved[4]; +} Dl_info; +#endif +#define _RLD_DLADDR 14 + +int dladdr(void *address, Dl_info* dl); + +#endif diff --git a/engine/platform/irix/xash-exec b/engine/platform/irix/xash-exec new file mode 100755 index 00000000..c5c3c8c1 --- /dev/null +++ b/engine/platform/irix/xash-exec @@ -0,0 +1,9 @@ +#!/usr/sgug/bin/bash + +# Build path +export LD_LIBRARYN32_PATH=$PWD/filesystem:$LD_LIBRARYN32_PATH + +# Install path +export LD_LIBRARYN32_PATH=$PWD:$LD_LIBRARYN32_PATH + +exec $PWD/build/engine/xash diff --git a/engine/platform/posix/lib_posix.c b/engine/platform/posix/lib_posix.c index abfd46ad..746b73e7 100644 --- a/engine/platform/posix/lib_posix.c +++ b/engine/platform/posix/lib_posix.c @@ -16,6 +16,9 @@ GNU General Public License for more details. #include "platform/platform.h" #if XASH_LIB == LIB_POSIX #include +#ifdef XASH_IRIX +#include "platform/irix/dladdr.h" +#endif #include "common.h" #include "library.h" #include "filesystem.h" diff --git a/engine/platform/posix/net.h b/engine/platform/posix/net.h index 03b57d27..91ba7562 100644 --- a/engine/platform/posix/net.h +++ b/engine/platform/posix/net.h @@ -24,6 +24,9 @@ GNU General Public License for more details. #include #include #include +#if XASH_IRIX +#include +#endif #define WSAGetLastError() errno #define WSAEINTR EINTR diff --git a/engine/platform/posix/sys_posix.c b/engine/platform/posix/sys_posix.c index 328d11db..c5371f98 100644 --- a/engine/platform/posix/sys_posix.c +++ b/engine/platform/posix/sys_posix.c @@ -158,9 +158,11 @@ void Platform_Shutdown( void ) {} double Platform_DoubleTime( void ) { struct timespec ts; - - clock_gettime(CLOCK_MONOTONIC, &ts); - +#if XASH_IRIX + clock_gettime( CLOCK_SGI_CYCLE, &ts ); +#else + clock_gettime( CLOCK_MONOTONIC, &ts ); +#endif return (double) ts.tv_sec + (double) ts.tv_nsec/1000000000.0; } diff --git a/engine/wscript b/engine/wscript index 0b7ef631..8195d772 100644 --- a/engine/wscript +++ b/engine/wscript @@ -132,6 +132,9 @@ def build(bld): if bld.env.DEST_OS == 'linux': source += bld.path.ant_glob(['platform/linux/*.c']) + if bld.env.DEST_OS == 'irix': + source += bld.path.ant_glob(['platform/irix/*.c']) + if bld.env.DEST_OS == 'dos': source += bld.path.ant_glob(['platform/dos/*.c']) source += bld.path.ant_glob(['platform/stub/s_stub.c']) diff --git a/public/build.c b/public/build.c index e619dfb2..758ef738 100644 --- a/public/build.c +++ b/public/build.c @@ -107,6 +107,8 @@ const char *Q_PlatformStringByID( const int platform ) return "haiku"; case PLATFORM_SERENITY: return "serenity"; + case PLATFORM_IRIX: + return "irix"; } assert( 0 ); diff --git a/public/build.h b/public/build.h index f05e1b59..b2ff2c2d 100644 --- a/public/build.h +++ b/public/build.h @@ -66,6 +66,7 @@ Then you can use another oneliner to query all variables: #undef XASH_FREEBSD #undef XASH_HAIKU #undef XASH_IOS +#undef XASH_IRIX #undef XASH_JS #undef XASH_LINUX #undef XASH_LITTLE_ENDIAN @@ -110,6 +111,8 @@ Then you can use another oneliner to query all variables: #define XASH_HAIKU 1 #elif defined __serenity__ #define XASH_SERENITY 1 + #elif defined __sgi + #define XASH_IRIX 1 #elif defined __APPLE__ #include #define XASH_APPLE 1 diff --git a/public/buildenums.h b/public/buildenums.h index 525f9fd1..872975ad 100644 --- a/public/buildenums.h +++ b/public/buildenums.h @@ -38,6 +38,7 @@ GNU General Public License for more details. #define PLATFORM_DOS4GW 9 #define PLATFORM_HAIKU 10 #define PLATFORM_SERENITY 11 +#define PLATFORM_IRIX 12 #if XASH_WIN32 #define XASH_PLATFORM PLATFORM_WIN32 @@ -61,6 +62,8 @@ GNU General Public License for more details. #define XASH_PLATFORM PLATFORM_HAIKU #elif XASH_SERENITY #define XASH_PLATFORM PLATFORM_SERENITY +#elif XASH_IRIX + #define XASH_PLATFORM PLATFORM_IRIX #else #error #endif diff --git a/public/xash3d_mathlib.h b/public/xash3d_mathlib.h index 4b6e9412..259c79fb 100644 --- a/public/xash3d_mathlib.h +++ b/public/xash3d_mathlib.h @@ -77,6 +77,9 @@ GNU General Public License for more details. #define Q_round( x, y ) (floor( x / y + 0.5f ) * y ) #define Q_rint(x) ((x) < 0.0f ? ((int)((x)-0.5f)) : ((int)((x)+0.5f))) +#ifdef XASH_IRIX +#undef isnan +#endif #ifdef isnan // check for C99 isnan #define IS_NAN isnan #else diff --git a/wscript b/wscript index bcd4011e..6442bc1b 100644 --- a/wscript +++ b/wscript @@ -244,6 +244,14 @@ def configure(conf): cxxflags += conf.filter_cxxflags(compiler_optional_flags, cflags) cflags += conf.filter_cflags(compiler_optional_flags + c_compiler_optional_flags, cflags) + # check if we need to use irix linkflags + if conf.env.DEST_OS == 'irix' and conf.env.COMPILER_CC == 'gcc': + linkflags.remove('-Wl,--no-undefined') + linkflags.append('-Wl,--unresolved-symbols=ignore-all') + # check if we're in a sgug environment + if 'sgug' in os.environ['LD_LIBRARYN32_PATH']: + linkflags.append('-lc') + conf.env.append_unique('CFLAGS', cflags) conf.env.append_unique('CXXFLAGS', cxxflags) conf.env.append_unique('LINKFLAGS', linkflags)