It's only supported by glibc on Linux (and possibly some of the BSDs),
and it adds a lot of complexity. The regular C dispatch functions only
have a few instructions of overhead in most cases.
Adding ARM NEON would have complicated things:
- 32-bit ARMv7: Needs a check on Linux and Android; on Windows, it's
guaranteed to be present.
- 64-bit ARMv8: Always exists.
Set -mssse3 and -msse4.1 on clang-cl. clang-cl normally works like MSVC,
but it doesn't enable SSSE3 or SSE 4.1 intrinsics by default. Instead,
the gcc-style parameters need to be specified.
TODO: Clang also supports some gcc-style warning flags.
This makes it more reliable across different platforms, and it ensures
we don't try using IFUNC if e.g. -fanalysis=address is enabled, since
AddressSanitizer doesn't support it.
config.librpcpu.h now defines HAVE_IFUNC if IFUNC is available.
Note that we're still checking a few things:
- Windows and Mac OS will never have IFUNC.
- glibc-2.11 is required for most architectures.
- glibc-2.18 is required for ARM.
I decided to try building rom-properties with MSVC 2019's ARM compilers,
and it seems to build properly. I can't test it at the moment, though.
CMake changes:
- ${CMAKE_SYSTEM_PROCESSOR} is always set to the host CPU. Check
_MSVC_C_ARCHITECTURE_FAMILY to determine the real CPU, then set
CMAKE_SYSTEM_PROCESSOR accordingly.
- Enable /EHsc if it isn't set already. It's set by CMake for i386
and amd64, but not for ARM or ARM64.
- Minimum subsystem version for ARM and ARM64 is 6.2. (Windows 8)
- Added some Win32 libraries that are included by default on i386 and
amd64, but not on ARM or ARM64.
- Reference: https://pete.akeo.ie/2017/05/compiling-desktop-arm-applications-with.html
Source changes:
- DelayLoadHelper.c, rp-config.c: Added subdirectory names for
ia64, ARM, and ARM64.
- TODO: Consolidate this into a common header file?
FIXME: Maybe we should use RP_LINKER_FLAGS_WIN32_EXE and
RP_LINKER_FLAGS_CONSOLE_EXE on MSVC. (We're using this on gcc.)
Not sure why I used one method or the other...
When building with MinGW-w64, the manifests were being written with "x86"
even for 64-bit, which caused Windows to outright refuse to run the
program with no error message.
The check in platform.cmake checks both CMAKE_CL_64 and sizeof(void*),
so remove the one in platform/win32.cmake.
Also added untested checks for ARM/ARM64.
TODO: Verify cross-compile functionality.
Using MinGW-w64 4.0.6 with gcc-6.2.0.
Note that it still doesn't compile successfully due to missing
functionality in MinGW-w64 4.0.6. I'll try it again with 5.0.1 later.
Note that MinGW-w64 5.0.1 is still missing isolation-aware functionality,
so it won't be able to handle XP theming correctly.
Summary of changes:
- cmake/platform.cmake: MinGW-w64 uses separate crt*.o files for Unicode
instead of a separate entry point. Handle this by removing the "w" from
the Unicode entry point and passing the "-municode" option instead.
- libpng, rpcli, win32: CMake-3.7.2 doesn't add include paths to windres.
Add the include paths manually in order to fix .rc compilation.
- c++11-compat.h: Moved the case-insensitive string comparison macros
from c++11-compat.msvc.h. MinGW-w64 doesn't have the wcs*() functions,
but it does have macros for str*(), so we have to define the macros
only if said macros don't already exist.
- [libcachemgr] CacheManager: gettimeofday() is in time.h on MSVC,
and sys/time.h on MinGW-w64 and other platforms. sys/types.h is
no longer needed.
libromdata:
- RpWin32.cpp: Added more conditionals to the error list in order to
fix compilation with MinGW-w64.
- RpWin32.hpp: Use reinterpret_cast<> for the atomic memory access
functions.
rpcli:
- time_r.h: #define _POSIX_C_SOURCE is required on MinGW-w64 in order
to use the *_r() functions.
- properties.cpp: #include "time_r.h" earlier to prevent time.h from
being included before _POSIX_C_SOURCE is defined.
win32:
- QITab.h: Split the QISearch() defines out of RP_ComBase.h and added
definitions that are missing on MinGW-w64.
- Added an extra '0' in QITAB instances in order to suppress gcc's
"missing initializer" warning. [-Wmissing-field-initializers]
- Moved all COM smart pointers to the top of the file. Disabled some of
them in MSVC builds because they're already defined in comdefsp.h.
- rom-properties.def: Removed the comment and "LIBRARY" statement, since
GNU ld doesn't recognize them.
This is needed because the entry point must be specified manually when
building with MinGW with ASLR enabled.
The entry point should be wmain for Unicode console applications,
so we need to specify wmainCRTStartup instead of mainCRTStartup.
[rpcli] SET_WINDOWS_ENTRYPOINT(rpcli wmain)
Supported by MSVC 2005, MinGW-w64, 64-bit glibc, and 64-bit Mac OS X.
glibc is working on adding 64-bit time_t for 32-bit software.
Support for that has been added using -D_TIME_BITS=64.
32-bit Mac OS X doesn't, and won't, support 64-bit time_t.
References:
- https://lwn.net/Articles/715242/
- https://sourceware.org/glibc/wiki/Y2038ProofnessDesign
This causes zlib, libpng, and possibly others to not export any symbols
in either the .a or .so on Linux, which makes them unusable.
CheckHiddenVisibility.cmake: New macro CHECK_HIDDEN_VISIBILITY().
Use this in the upper-level source directory to apply hidden visibility
to all subprojects. Used in src/CMakeLists.txt.
Since we're using architecture-specific directories now, we don't
need to suffix the DLL.
SetMSVCDebugPath: Fix handling debug paths if OUTPUT_NAME isn't set.
platform.cmake: Removed SET_WINDOWS_TARGET_NAME_ARCH(), since it's
no longer used by anything.
platform.cmake: New function SET_WINDOWS_TARGET_NAME_ARCH().
This function determines the system architecture and appends
it to the specified target's OUTPUT_NAME.
platform.cmake: Call CHECK_LARGE_FILE_SUPPORT(). Note that LFS is
required due to the size of Wii disc images, so if LFS isn't
available, CMake will fail with an error message.
c99-compat.msvcrt.h: #define fseeko() and ftello() to the MSVC
non-standard _fseeki64() and _ftelli64() functions. This was in
Gens/GS II's libcompat/W32U, but I'm not using W32U here.
RpFile_stdio.cpp: Use fseeko() and ftello().
This fixes issue #2.
In addition to reworking RpImage to use libpng and/or GDI+ directly,
this branch adds AppVeyor support for Windows CI. This required
fixing the build system to work with CMake's Visual Studio project
generator, which uses msbuild instead of nmake.
Conflicts:
.travis.yml
CMakeLists.txt
This adds "/MANIFEST:NO" to an individual target. This allows us to use
MSVC's automatic manifest generation for unit tests, while also enabling
custom manifests for the actual rom-properties.dll project.
msvc.cmake: Removed "/MANIFEST:NO" from the default CFLAGS.
[win32] CMakeLists.txt: Use SET_WINDOWS_NO_MANIFEST().
With nmake, CMake's default /SUBSYSTEM is added after our linker flags.
With msbuild, it's added before, which caused console programs like
RpImageLoaderTest to be linked as /SUBSYSTEM:WINDOWS, which failed
due to no WinMain() function.
AppVeyor, a Windows-based CI service, mostly (only?) works with
msbuild instead of nmake, so I need to get everything working.
TODO: /MANIFEST:NO is causing problems with programs that don't have
a manifest resource (RpImageLoaderTest), and RC isn't accepting the
-nologo option for some reason.
Notable changes:
- win32-msvc.cmake: Set RP_LINKER_FLAGS_${_subsystem}_EXE. This variable
is used by a new function to add to target-specific LINK_FLAGS.
- platform.cmake: New function SET_WINDOWS_SUBSYSTEM. This adds the
relevant linker flags. Note that it's only used for MSVC.
- Added SET_WINDOWS_SUBSYSTEM() to all EXE and DLL projects. Note that
the WIN32 flag is not available in ADD_LIBRARY(), so we're not setting
it for the Win32 rom-properties.dll.
- [win32] Append to the target LINK_FLAGS instead of resetting it.
Otherwise, we lose the /SUBSYSTEM flag.
Removed the manual CFLAG testing from platform/gcc.cmake.
Other required changes:
- Removed CMAKE_MINIMUM_REQUIRED() from everything except the
top-level CMakeLists.txt. This interfered with setting the
CMake policy, since each invocation reset the policies to
match the specified minimum version.
- Added NO_POLICY_SCOPE to the cmake/platform.cmake include
in order to allow policy changes within platform.cmake to
propagate to the rest of the project.
We're linking the DLLs and SOs as "MODULE", since they're always loaded
as plugins instead of directly linked into applications. Hence, we need
to set CMAKE_MODULE_LINKER_FLAGS in order to get linker flags to apply
to the modules.
This fixes an issue where "/manifest:no" wasn't being passed to MSVC's
linker, which caused a conflict when adding an isolation-aware manifest
file in order to properly support theming on Windows XP: (MSVC 2010)
CVTRES : fatal error CVT1100: duplicate resource. type:MANIFEST, name:2, language:0x0409
LINK : fatal error LNK1123: failure during conversion to COFF: file invalid or corrupt
LINK Pass 1 failed. with 1105
Some stuff was stripped out, including support for ANSI Windows.
The minimum version I'm officially going to support once I add
Windows support is XP, though 2000 might "just work".