- 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:
Braden Obrzut 2016-03-13 00:34:35 -05:00
parent 0269aeea80
commit 93be5aca05
10 changed files with 125 additions and 71 deletions

View file

@ -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()

View file

@ -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} )

View file

@ -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;

View file

@ -149,6 +149,8 @@ static const NSOpenGLPixelFormatAttribute NSOpenGLPFAAllowOfflineRenderers = NSO
- (void)setCollectionBehavior:(NSUInteger)collectionBehavior;
@end
typedef NSUInteger NSWindowCollectionBehavior;
#endif // prior to 10.5

View file

@ -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,6 +133,41 @@ void Mac_I_FatalError(const char* const message)
DArgs* Args; // command line arguments
// 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);
/*
killough 1/98:
This fixes some problems with exit handling
during abnormal situations.
The old code called I_Quit() to end program,
while now I_Quit() is installed as an exit
handler and exit() is called to exit, either
normally or abnormally. Seg faults are caught
and the error handler is used, to prevent
being left in graphics mode or having very
loud SFX noise because the sound card is
left in an unstable state.
*/
atexit(call_terms);
atterm(I_Quit);
NSString* exePath = [[NSBundle mainBundle] executablePath];
progdir = [[exePath stringByDeletingLastPathComponent] UTF8String];
progdir += "/";
C_InitConsole(80 * 8, 25 * 8, false);
D_DoomMain();
}
namespace
{
@ -151,7 +186,6 @@ 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",
@ -174,53 +208,7 @@ int OriginalMain(int argc, char** argv)
vid_vsync = true;
fullscreen = true;
try
{
Args = new DArgs(argc, argv);
/*
killough 1/98:
This fixes some problems with exit handling
during abnormal situations.
The old code called I_Quit() to end program,
while now I_Quit() is installed as an exit
handler and exit() is called to exit, either
normally or abnormally. Seg faults are caught
and the error handler is used, to prevent
being left in graphics mode or having very
loud SFX noise because the sound card is
left in an unstable state.
*/
atexit(call_terms);
atterm(I_Quit);
NSString* exePath = [[NSBundle mainBundle] executablePath];
progdir = [[exePath stringByDeletingLastPathComponent] UTF8String];
progdir += "/";
C_InitConsole(80 * 8, 25 * 8, false);
D_DoomMain();
}
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;
}
OriginalMainExcept(argc, argv);
return 0;
}

View 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;
}
}

View file

@ -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()

View file

@ -72,7 +72,7 @@ struct PCXHeader
BYTE padding[54];
};
} FORCE_PACKED;
#pragma pack()
//==========================================================================

View file

@ -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()

View file

@ -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 --------------------------------------------