mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-23 20:42:24 +00:00
- Fixed: Modern versions of GCC on PowerPC inserted padding to the end of pragma packed structures.
- Worked aorund modern GCC bug where C++ exceptions in Objective-C++ code would result in an ICE (bug is already on their tracker, but I doubt it will be fixed unless I decide to dig into the issue myself). - Turn off fused floating point instructions since these can cause slight deviations in floating point code. - Use -static-libgcc when compiling on the Mac with GCC since we need to use a custom version of GCC to do so now. - Note: ZDoom will currently still crash on exit on PowerPC since it seems to be deciding that NameManager needs to be destructed before the console commands.
This commit is contained in:
parent
0269aeea80
commit
93be5aca05
10 changed files with 125 additions and 71 deletions
|
@ -167,6 +167,11 @@ else()
|
|||
set( ALL_C_FLAGS "" )
|
||||
set( REL_C_FLAGS "" )
|
||||
set( DEB_C_FLAGS "" )
|
||||
|
||||
# If we're compiling with a custom GCC on the Mac (which we know since g++-4.2 doesn't support C++11) statically link libgcc.
|
||||
if( APPLE AND "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" )
|
||||
set( ALL_C_FLAGS "-static-libgcc" )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set( CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} ${REL_LINKER_FLAGS}" )
|
||||
|
@ -193,7 +198,7 @@ option(FORCE_INTERNAL_GME "Use internal gme" ON)
|
|||
# Fast math flags, required by some subprojects
|
||||
set( ZD_FASTMATH_FLAG "" )
|
||||
if( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE )
|
||||
set( ZD_FASTMATH_FLAG "-ffast-math" )
|
||||
set( ZD_FASTMATH_FLAG "-ffast-math -ffp-contract=fast" )
|
||||
elseif( MSVC )
|
||||
set( ZD_FASTMATH_FLAG "/fp:fast" )
|
||||
endif()
|
||||
|
|
|
@ -465,28 +465,28 @@ if( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE )
|
|||
set( CMAKE_C_FLAGS "-Wno-unused-result ${CMAKE_C_FLAGS}" )
|
||||
set( CMAKE_CXX_FLAGS "-Wno-unused-result ${CMAKE_CXX_FLAGS}" )
|
||||
endif()
|
||||
set( CMAKE_C_FLAGS "-Wall -Wextra -Wno-unused -Wno-unused-parameter -Wno-missing-field-initializers ${CMAKE_C_FLAGS}" )
|
||||
set( CMAKE_CXX_FLAGS "-Wall -Wextra -Wno-unused -Wno-unused-parameter -Wno-missing-field-initializers ${CMAKE_CXX_FLAGS}" )
|
||||
set( CMAKE_C_FLAGS "-Wall -Wextra -Wno-unused -Wno-unused-parameter -Wno-missing-field-initializers -ffp-contract=off ${CMAKE_C_FLAGS}" )
|
||||
set( CMAKE_CXX_FLAGS "-Wall -Wextra -Wno-unused -Wno-unused-parameter -Wno-missing-field-initializers -ffp-contract=off ${CMAKE_CXX_FLAGS}" )
|
||||
|
||||
# Use the highest C++ standard available since VS2015 compiles with C++14
|
||||
# but we only require C++11. The recommended way to do this in CMake is to
|
||||
# probably to use target_compile_features, but I don't feel like maintaining
|
||||
# a list of features we use.
|
||||
CHECK_CXX_COMPILER_FLAG( "-std=c++14" CAN_DO_CPP14 )
|
||||
CHECK_CXX_COMPILER_FLAG( "-std=gnu++14" CAN_DO_CPP14 )
|
||||
if ( CAN_DO_CPP14 )
|
||||
set ( CMAKE_CXX_FLAGS "-std=c++14 ${CMAKE_CXX_FLAGS}" )
|
||||
set ( CMAKE_CXX_FLAGS "-std=gnu++14 ${CMAKE_CXX_FLAGS}" )
|
||||
else ()
|
||||
CHECK_CXX_COMPILER_FLAG( "-std=c++1y" CAN_DO_CPP1Y )
|
||||
CHECK_CXX_COMPILER_FLAG( "-std=gnu++1y" CAN_DO_CPP1Y )
|
||||
if ( CAN_DO_CPP1Y )
|
||||
set ( CMAKE_CXX_FLAGS "-std=c++1y ${CMAKE_CXX_FLAGS}" )
|
||||
set ( CMAKE_CXX_FLAGS "-std=gnu++1y ${CMAKE_CXX_FLAGS}" )
|
||||
else ()
|
||||
CHECK_CXX_COMPILER_FLAG( "-std=c++11" CAN_DO_CPP11 )
|
||||
CHECK_CXX_COMPILER_FLAG( "-std=gnu++11" CAN_DO_CPP11 )
|
||||
if ( CAN_DO_CPP11 )
|
||||
set ( CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}" )
|
||||
set ( CMAKE_CXX_FLAGS "-std=gnu++11 ${CMAKE_CXX_FLAGS}" )
|
||||
else ()
|
||||
CHECK_CXX_COMPILER_FLAG( "-std=c++0x" CAN_DO_CPP0X )
|
||||
CHECK_CXX_COMPILER_FLAG( "-std=gnu++0x" CAN_DO_CPP0X )
|
||||
if ( CAN_DO_CPP0X )
|
||||
set ( CMAKE_CXX_FLAGS "-std=c++0x ${CMAKE_CXX_FLAGS}" )
|
||||
set ( CMAKE_CXX_FLAGS "-std=gnu++0x ${CMAKE_CXX_FLAGS}" )
|
||||
endif ()
|
||||
endif ()
|
||||
endif ()
|
||||
|
@ -645,6 +645,7 @@ set( PLAT_COCOA_SOURCES
|
|||
posix/cocoa/i_input.mm
|
||||
posix/cocoa/i_joystick.cpp
|
||||
posix/cocoa/i_main.mm
|
||||
posix/cocoa/i_main_except.cpp
|
||||
posix/cocoa/i_system.mm
|
||||
posix/cocoa/i_timer.cpp
|
||||
posix/cocoa/i_video.mm
|
||||
|
@ -681,6 +682,7 @@ elseif( APPLE )
|
|||
|
||||
set_source_files_properties( posix/osx/zdoom.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources )
|
||||
set_source_files_properties( "${FMOD_LIBRARY}" PROPERTIES MACOSX_PACKAGE_LOCATION Frameworks )
|
||||
set_source_files_properties( posix/osx/iwadpicker_cocoa.mm PROPERTIES COMPILE_FLAGS -fobjc-exceptions )
|
||||
else()
|
||||
set( SYSTEM_SOURCES_DIR posix posix/sdl )
|
||||
set( SYSTEM_SOURCES ${PLAT_POSIX_SOURCES} ${PLAT_SDL_SOURCES} )
|
||||
|
|
|
@ -123,6 +123,18 @@ typedef TMap<int, PClassActor *> FClassMap;
|
|||
#define NO_SANITIZE
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
// With versions of GCC newer than 4.2, it appears it was determined that the
|
||||
// cost of an unaligned pointer on PPC was high enough to add padding to the
|
||||
// end of packed structs. For whatever reason __packed__ and pragma pack are
|
||||
// handled differently in this regard. Note that this only needs to be applied
|
||||
// to types which are used in arrays or sizeof is needed. This also prevents
|
||||
// code from taking references to the struct members.
|
||||
#define FORCE_PACKED __attribute__((__packed__))
|
||||
#else
|
||||
#define FORCE_PACKED
|
||||
#endif
|
||||
|
||||
#include "basictypes.h"
|
||||
|
||||
extern bool batchrun;
|
||||
|
|
|
@ -149,6 +149,8 @@ static const NSOpenGLPixelFormatAttribute NSOpenGLPFAAllowOfflineRenderers = NSO
|
|||
- (void)setCollectionBehavior:(NSUInteger)collectionBehavior;
|
||||
@end
|
||||
|
||||
typedef NSUInteger NSWindowCollectionBehavior;
|
||||
|
||||
#endif // prior to 10.5
|
||||
|
||||
|
||||
|
|
|
@ -67,7 +67,6 @@ EXTERN_CVAR(Bool, fullscreen )
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
|
@ -78,6 +77,9 @@ void (*TermFuncs[MAX_TERMS])();
|
|||
const char *TermNames[MAX_TERMS];
|
||||
size_t NumTerms;
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
// Expose this for i_main_except.cpp
|
||||
void call_terms()
|
||||
{
|
||||
while (NumTerms > 0)
|
||||
|
@ -86,8 +88,6 @@ void call_terms()
|
|||
}
|
||||
}
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
|
||||
void addterm(void (*func)(), const char *name)
|
||||
{
|
||||
|
@ -133,48 +133,11 @@ void Mac_I_FatalError(const char* const message)
|
|||
DArgs* Args; // command line arguments
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
const int ARGC_MAX = 64;
|
||||
|
||||
int s_argc;
|
||||
char* s_argv[ARGC_MAX];
|
||||
|
||||
TArray<FString> s_argvStorage;
|
||||
|
||||
bool s_restartedFromWADPicker;
|
||||
|
||||
|
||||
void NewFailure()
|
||||
{
|
||||
I_FatalError("Failed to allocate memory from system heap");
|
||||
}
|
||||
|
||||
|
||||
int OriginalMain(int argc, char** argv)
|
||||
{
|
||||
printf(GAMENAME" %s - %s - Cocoa version\nCompiled on %s\n\n",
|
||||
GetVersionString(), GetGitTime(), __DATE__);
|
||||
|
||||
seteuid(getuid());
|
||||
std::set_new_handler(NewFailure);
|
||||
|
||||
// Set LC_NUMERIC environment variable in case some library decides to
|
||||
// clear the setlocale call at least this will be correct.
|
||||
// Note that the LANG environment variable is overridden by LC_*
|
||||
setenv("LC_NUMERIC", "C", 1);
|
||||
setlocale(LC_ALL, "C");
|
||||
|
||||
// Set reasonable default values for video settings
|
||||
|
||||
const NSSize screenSize = [[NSScreen mainScreen] frame].size;
|
||||
vid_defwidth = static_cast<int>(screenSize.width);
|
||||
vid_defheight = static_cast<int>(screenSize.height);
|
||||
vid_vsync = true;
|
||||
fullscreen = true;
|
||||
|
||||
try
|
||||
// Newer versions of GCC than 4.2 have a bug with C++ exceptions in Objective-C++ code.
|
||||
// To work around we'll implement the try and catch in standard C++.
|
||||
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61759
|
||||
void OriginalMainExcept(int argc, char** argv);
|
||||
void OriginalMainTry(int argc, char** argv)
|
||||
{
|
||||
Args = new DArgs(argc, argv);
|
||||
|
||||
|
@ -204,23 +167,48 @@ int OriginalMain(int argc, char** argv)
|
|||
C_InitConsole(80 * 8, 25 * 8, false);
|
||||
D_DoomMain();
|
||||
}
|
||||
catch(const CDoomError& error)
|
||||
{
|
||||
const char* const message = error.GetMessage();
|
||||
|
||||
if (NULL != message)
|
||||
namespace
|
||||
{
|
||||
fprintf(stderr, "%s\n", message);
|
||||
Mac_I_FatalError(message);
|
||||
|
||||
const int ARGC_MAX = 64;
|
||||
|
||||
int s_argc;
|
||||
char* s_argv[ARGC_MAX];
|
||||
|
||||
TArray<FString> s_argvStorage;
|
||||
|
||||
bool s_restartedFromWADPicker;
|
||||
|
||||
|
||||
void NewFailure()
|
||||
{
|
||||
I_FatalError("Failed to allocate memory from system heap");
|
||||
}
|
||||
|
||||
exit(-1);
|
||||
}
|
||||
catch(...)
|
||||
int OriginalMain(int argc, char** argv)
|
||||
{
|
||||
call_terms();
|
||||
throw;
|
||||
}
|
||||
printf(GAMENAME" %s - %s - Cocoa version\nCompiled on %s\n\n",
|
||||
GetVersionString(), GetGitTime(), __DATE__);
|
||||
|
||||
seteuid(getuid());
|
||||
std::set_new_handler(NewFailure);
|
||||
|
||||
// Set LC_NUMERIC environment variable in case some library decides to
|
||||
// clear the setlocale call at least this will be correct.
|
||||
// Note that the LANG environment variable is overridden by LC_*
|
||||
setenv("LC_NUMERIC", "C", 1);
|
||||
setlocale(LC_ALL, "C");
|
||||
|
||||
// Set reasonable default values for video settings
|
||||
|
||||
const NSSize screenSize = [[NSScreen mainScreen] frame].size;
|
||||
vid_defwidth = static_cast<int>(screenSize.width);
|
||||
vid_defheight = static_cast<int>(screenSize.height);
|
||||
vid_vsync = true;
|
||||
fullscreen = true;
|
||||
|
||||
OriginalMainExcept(argc, argv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
34
src/posix/cocoa/i_main_except.cpp
Normal file
34
src/posix/cocoa/i_main_except.cpp
Normal file
|
@ -0,0 +1,34 @@
|
|||
// Workaround for GCC Objective-C++ with C++ exceptions bug.
|
||||
|
||||
#include "doomerrors.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
// Import some functions from i_main.mm
|
||||
void call_terms();
|
||||
void Mac_I_FatalError(const char* const message);
|
||||
void OriginalMainTry(int argc, char** argv);
|
||||
|
||||
void OriginalMainExcept(int argc, char** argv)
|
||||
{
|
||||
try
|
||||
{
|
||||
OriginalMainTry(argc, argv);
|
||||
}
|
||||
catch(const CDoomError& error)
|
||||
{
|
||||
const char* const message = error.GetMessage();
|
||||
|
||||
if (NULL != message)
|
||||
{
|
||||
fprintf(stderr, "%s\n", message);
|
||||
Mac_I_FatalError(message);
|
||||
}
|
||||
|
||||
exit(-1);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
call_terms();
|
||||
throw;
|
||||
}
|
||||
}
|
|
@ -100,14 +100,14 @@ typedef struct tagITFILEHEADER
|
|||
DWORD reserved2;
|
||||
BYTE chnpan[64];
|
||||
BYTE chnvol[64];
|
||||
} ITFILEHEADER, *PITFILEHEADER;
|
||||
} FORCE_PACKED ITFILEHEADER, *PITFILEHEADER;
|
||||
|
||||
typedef struct MODMIDICFG
|
||||
{
|
||||
char szMidiGlb[9*32]; // changed from CHAR
|
||||
char szMidiSFXExt[16*32]; // changed from CHAR
|
||||
char szMidiZXXExt[128*32]; // changed from CHAR
|
||||
} MODMIDICFG, *LPMODMIDICFG;
|
||||
} FORCE_PACKED MODMIDICFG, *LPMODMIDICFG;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ struct PCXHeader
|
|||
|
||||
BYTE padding[54];
|
||||
|
||||
};
|
||||
} FORCE_PACKED;
|
||||
#pragma pack()
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -13,7 +13,7 @@ struct FZipEndOfCentralDirectory
|
|||
DWORD DirectorySize;
|
||||
DWORD DirectoryOffset;
|
||||
WORD ZipCommentLength;
|
||||
};
|
||||
} FORCE_PACKED;
|
||||
|
||||
// FZipFileInfo
|
||||
struct FZipCentralDirectoryInfo
|
||||
|
@ -36,7 +36,7 @@ struct FZipCentralDirectoryInfo
|
|||
DWORD ExternalAttributes;
|
||||
DWORD LocalHeaderOffset;
|
||||
// file name and other variable length info follows
|
||||
};
|
||||
} FORCE_PACKED;
|
||||
|
||||
// FZipLocalHeader
|
||||
struct FZipLocalFileHeader
|
||||
|
@ -53,7 +53,7 @@ struct FZipLocalFileHeader
|
|||
WORD NameLength;
|
||||
WORD ExtraLength;
|
||||
// file name and other variable length info follows
|
||||
};
|
||||
} FORCE_PACKED;
|
||||
|
||||
|
||||
#pragma pack()
|
||||
|
|
|
@ -60,6 +60,17 @@
|
|||
#define __cdecl
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
// With versions of GCC newer than 4.2, it appears it was determined that the
|
||||
// cost of an unaligned pointer on PPC was high enough to add padding to the
|
||||
// end of packed structs. For whatever reason __packed__ and pragma pack are
|
||||
// handled differently in this regard. Note that this only needs to be applied
|
||||
// to types which are used in arrays.
|
||||
#define FORCE_PACKED __attribute__((__packed__))
|
||||
#else
|
||||
#define FORCE_PACKED
|
||||
#endif
|
||||
|
||||
#ifndef __BIG_ENDIAN__
|
||||
#define MAKE_ID(a,b,c,d) ((a)|((b)<<8)|((c)<<16)|((d)<<24))
|
||||
#define LittleShort(x) (x)
|
||||
|
@ -150,7 +161,7 @@ typedef struct
|
|||
UINT32 UncompressedSize; // 22
|
||||
WORD NameLength; // 26
|
||||
WORD ExtraLength; // 28
|
||||
} LocalFileHeader;
|
||||
} FORCE_PACKED LocalFileHeader;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -171,7 +182,7 @@ typedef struct
|
|||
WORD InternalAttributes;
|
||||
UINT32 ExternalAttributes;
|
||||
UINT32 LocalHeaderOffset;
|
||||
} CentralDirectoryEntry;
|
||||
} FORCE_PACKED CentralDirectoryEntry;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -183,7 +194,7 @@ typedef struct
|
|||
UINT32 DirectorySize;
|
||||
UINT32 DirectoryOffset;
|
||||
WORD ZipCommentLength;
|
||||
} EndOfCentralDirectory;
|
||||
} FORCE_PACKED EndOfCentralDirectory;
|
||||
//#pragma pack(pop)
|
||||
|
||||
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
||||
|
|
Loading…
Reference in a new issue