These options are now only applied if compiling with clang.
While it's possible to use libc++ with gcc, it requires a lot of manual
changes, and basicaly no one does it. (libstdc++ with clang is commonly
done on desktop Linux systems, though.)
Don't -D_LIBCPP_ENABLE_ASSERTIONS on clang-17 or later. It's deprecated,
and may result in a compile error. (...though on Android/Termux with
clang-20.1.3, it didn't...)
Newer compilers usually add more warnings, so having -Werror by default
will most likely result in a compile error when new compiler versions
are released.
MSVC: Remove "-D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING". This is no
longer relevant, since we don't support anything older than MSVC 2015.
It seems this was broken since it was initially implemented in v2.0
in commit d732fbc010
([cmake] platform/gcc.cmake: Initial support for detecting DT_RELR.)
because TMP_HAVE_DT_RELR was unset too early.
When compiling with LTO enabled on gcc-14.2.0 (e.g. with Ubuntu 25.04),
the following warning (as error) appeared. Work around it by checking for
str.empty() before resizing the string.
[cmake] gcc.cmake: Remove -Wno-error=aggressive-loop-optimizations, since
it's no longe needed.
In function ‘assign’,
inlined from ‘_S_assign’ at /usr/include/c++/14/bits/basic_string.h:455:23,
inlined from ‘_S_assign’ at /usr/include/c++/14/bits/basic_string.h:450:7,
inlined from ‘_M_replace_aux’ at /usr/include/c++/14/bits/basic_string.tcc:471:17,
inlined from ‘append’ at /usr/include/c++/14/bits/basic_string.h:1499:30,
inlined from ‘resize’ at /usr/include/c++/14/bits/basic_string.tcc:405:14,
inlined from ‘resize’ at /usr/include/c++/14/bits/basic_string.h:1119:21,
inlined from ‘TestBody’ at src/librptext/tests/TextFuncsTest.cpp:513:12:
/usr/include/c++/14/bits/char_traits.h:837:25: error: iteration 9223372036854775807 invokes undefined behavior [-Werror=aggressive-loop-optimizations]
837 | assign(__s[__i], __a);
| ^
/usr/include/c++/14/bits/char_traits.h:836:34: note: within this loop
836 | for (size_t __i = 0; __i < __n; ++__i)
| ^
In function ‘assign’,
inlined from ‘_S_assign’ at /usr/include/c++/14/bits/basic_string.h:455:23,
inlined from ‘_S_assign’ at /usr/include/c++/14/bits/basic_string.h:450:7,
inlined from ‘_M_replace_aux’ at /usr/include/c++/14/bits/basic_string.tcc:471:17,
inlined from ‘append’ at /usr/include/c++/14/bits/basic_string.h:1499:30,
inlined from ‘resize’ at /usr/include/c++/14/bits/basic_string.tcc:405:14,
inlined from ‘resize’ at /usr/include/c++/14/bits/basic_string.h:1119:21,
inlined from ‘TestBody’ at src/librptext/tests/TextFuncsTest.cpp:542:12:
/usr/include/c++/14/bits/char_traits.h:837:25: error: iteration 9223372036854775807 invokes undefined behavior [-Werror=aggressive-loop-optimizations]
837 | assign(__s[__i], __a);
| ^
/usr/include/c++/14/bits/char_traits.h:836:34: note: within this loop
836 | for (size_t __i = 0; __i < __n; ++__i)
| ^
lto1: all warnings being treated as errors
lto-wrapper: fatal error: /usr/bin/c++ returned 1 exit status
compilation terminated.
The same error showed up on armhf and amd64 this time.
Since it's happening in LTO and not the main compiler step, the pragmas
likely aren't working properly. Use -Wno-error=stringop-overread instead.
(cherry picked from commit ec441b4cec)
Adding "-marm -mfpu=neon" fixed compilation, but LTO linking failed:
/usr/lib/gcc/arm-linux-gnueabihf/9/include/arm_neon.h: In function ‘rp_byte_swap_32_array_neon’:
/usr/lib/gcc/armmake[3]: Entering directory '/<<PKGBUILDDIR>>/build'
-linux-gnueabihf/9/include/arm_neon.h:11401:14: fatal error: You must enable NEON instructions (e.g. ‘-mfloat-abi=softfp’ ‘-mfpu=neon’) to use these intrinsics.
11401 | __rv.__o = __builtin_neon_vld2v4si ((const __builtin_neon_si *) __a);
| ^
compilation terminated.
lto-wrapper: fatal error: /usr/bin/c++ returned 1 exit status
I'll need to test this in qemu or similar first before trying it on
Launchpad again. For now, don't enable NEON on armhf.
...except when compiling with MSVC for Windows, since Windows on ARM
mandates NEON on both 32-bit and 64-bit.
(cherry picked from commit 5973d5af91)
From Ubuntu Launchpad:
CMake Error at src/libromdata/CMakeLists.txt:488 (ADD_LIBRARY):
Target "romdata" links to target "pugixml::pugixml" but the target was not
found. Perhaps a find_package() call is missing for an IMPORTED target, or
an ALIAS target is missing?
(cherry picked from commit 5481b385f5)
[librpbyteswap,librptexture] Apply NEON_FLAGS on 32-bit ARM.
The Ubuntu 18.04 armhf build failed to compile:
/<<PKGBUILDDIR>>/src/librpbyteswap/byteswap_neon.c: In function ‘rp_byte_swap_16_array_neon’:
/usr/lib/gcc/arm-linux-gnueabihf/7/include/arm_neon.h:11880:1: error: inlining failed in call to always_inline ‘vst2q_u16’: target specific option mismatch
vst2q_u16 (uint16_t * __a, uint16x8x2_t __b)
^~~~~~~~~
/<<PKGBUILDDIR>>/src/librpbyteswap/byteswap_neon.c:48:3: note: called from here
vst2q_u16(ptr, vec);
^~~~~~~~~~~~~~~~~~~
It seems NEON is disabled by default on armhf.
NOTE: Not rebuilding for armhf on Ubuntu 18.04.
(cherry picked from commit 66c43ccb4a)
The Ubuntu 16.04 Launchpad build for armhf failed due to a potential
alignment issue:
/<<PKGBUILDDIR>>/src/kde/AchQtDBus.cpp: In member function ‘int AchQtDBus::notifyFunc(LibRpBase::Achievements::ID)’:
/<<PKGBUILDDIR>>/src/kde/AchQtDBus.cpp:149:59: error: cast from ‘uchar* {aka unsigned char*}’ to ‘LibRpTexture::argb32_t*’ increases required alignment of target type [-Werror=cast-align]
argb32_t *bits = reinterpret_cast<argb32_t*>(icon.bits());
^
This shouldn't be an actual problem, since rp_image's image data is
always 16-byte aligned.
NOTE: Not rebuilding the Ubuntu 16.04 packages for ARM because of this.
(Both the armhf and arm64 builds were cancelled.)
(cherry picked from commit 5a08131311)
[librpbyteswap,librptexture] If arm_neon.h isn't available, don't compile
any NEON-optimized functions.
Just in case someone wants to build rom-properties for an ancient ARM
system that was introduced before NEON...
clang complains about moc headers due to how automoc handles things:
In file included from build/src/kde/kf5/overlayiconplugin_rom-properties-kf5_autogen/mocs_compilation.cpp:2:
build/src/kde/kf5/overlayiconplugin_rom-properties-kf5_autogen/BKZOEHIFDQ/moc_OverlayIconPluginKF5.cpp:1340:17: error: using namespace directive in global context in header [-Werror,-Wheader-hygiene]
1340 | using namespace RomPropertiesKF5;
| ^
1 error generated.
This clang warning is currently "intentional", though I might rename the
not-virtual open() function later:
In file included from src/libromdata/Handheld/Nintendo3DS.cpp:14:
In file included from src/libromdata/Handheld/Nintendo3DS_p.hpp:19:
src/libromdata/Handheld/../disc/NCCHReader.hpp:193:24: error: 'LibRomData::NCCHReader::open' hides overloaded virtual function [-Werror,-Woverloaded-virtual]
193 | LibRpFile::IRpFilePtr open(int section, const char *filename);
| ^
src/libromdata/../librpbase/disc/IPartition.hpp:104:32: note: hidden overloaded virtual function 'LibRpBase::IPartition::open' declared here: different number of parameters (1 vs 2)
104 | virtual LibRpFile::IRpFilePtr open(const char *filename);
| ^
1 error generated.
Fixes what appears to be a false-positive warning-as-error in the
Release build:
src/librpbase/img/RpPng.cpp: In function ‘LibRpTexture::rp_image_ptr LibRpBase::RpPng::loadPng(png_structp, png_infop)’:
src/librpbase/img/RpPng.cpp:181:42: error: variable ‘color’ might be clobbered by ‘longjmp’ or ‘vfork’ [-Werror=clobbered]
181 | argb32_t color;
| ^~~~~
cc1plus: all warnings being treated as errors
This broke the Ubuntu 22.04 AppVeyor build:
extlib/microtar/src/microtar.c: In function ‘mtar_read_header’:
extlib/microtar/src/microtar.c:111:3: error: ‘__builtin_strncpy’ output may be truncated copying 99 bytes from a string of length 99 [-Werror=stringop-truncation]
111 | strncpy(h->name, rh->name, sizeof(h->name));
| ^
extlib/microtar/src/microtar.c:112:3: error: ‘__builtin_strncpy’ output may be truncated copying 99 bytes from a string of length 99 [-Werror=stringop-truncation]
112 | strncpy(h->linkname, rh->linkname, sizeof(h->linkname));
| ^
cc1: all warnings being treated as errors
Disabled these warnings:
- C4005: macro redefinition (libpng's intprefix.out.tf1 is breaking on this...)
- C4091: 'typedef ': ignored on left of 'tagGPFIDL_FLAGS' when no variable is declared
- C4800: 'BOOL': forcing value to bool 'true' or 'false' (performance warning)
TODO:
- Re-enable C4800 as not-an-error?
- Figure out how to fix libpng's C4005 warnings.
The MSVC build (64-bit, at least...) now builds with no warnings.
Tested using MSVC 2022 17.6.5.
NOTE: /W4 adds a *lot* of warnings that are mostly just noise. Need to
check /W4 and selectively enable at least some of them...
Removed /wd4482. I don't think this warning is relevant anymore.
Warning fixes:
[extlib] Add (unsigned int) casts where necessary.
[librpbase] Config::ImgTypePrio_t, KeyManager::KeyData_t:
- Change `length` from unsigned int to size_t.
The struct is 16 bytes on 64-bit either way, but making it size_t
fixes some conversion warnings.
[librpbase] Hash::Process():
- crc32() returns `unsigned long`, not `uint32_t`, for some reason.
- Also, its length parameter is `unsigned int`, not `size_t`.
- KeyManager::hexStringToBytes(): Take a `size_t` length parameter.
[librpfile] scsi:
- Change cdb_len from `uint8_t` to `size_t`. Using a `uint8_t` argument
doesn't actually save any memory, since it uses 4 bytes on the stack
for 32-bit, and one register on 64-bit, regardless.
- Also, limit the maximum cdb size to 260.
[rp-download] Disable warning C4996 when calling GetVersionEx().
[librptexture] DirectDrawSurface:
- Change some `expected_size` variables from `unsigned int` to `size_t`.
[librptexture] PalmOS_Tbmp:
- Change d->bitmapTypeAddr from `off64_t` to `uint32_t`.
- Change some size variables from `unsigned int` to `size_t`.
- loadTbmp(): v3 transparency: Explicitly cast the transparency value
to uint16_t. (It's stored as a big-endian 32-bit value, but only
16 bits are used.)
- getNextTbmpAddress(): Cast addresses to `uint32_t`. PalmOS executables
are 32-bit and cannot possibly exceed 4 GB.
- FIXME: This function isn't used? (Was it ever used?)
[libromdata]
- DMGPrivate::CartType(): Make `end_offset` constexpr.
- NCCHReader: Add casts for EncSections when using sizeof().
- KeyStoreUIPrivate: binToHexStr(), verifyKeyData():
- Take a `size_t` length parameter.
- WiiUPackagePrivate: Added a parseHexBinary32() wrapper function
that returns `uint32_t` instead of `uint64_t`.
[librpbyteswap/tests]
- BitstuffTest: Cast time(nullptr) to `unsigned int`.
srand() takes `unsigned int`, not `time_t`.
[librpbase/tests]
- RpPngFormatTest: crc32()'s length parameter is `unsigned int`,
not `size_t`.
[libromdata/tests]
- SuperMagicDriveTest: zlib uses `unsigned int`, so cast array sizes
to `unsigned int` instead of changing decompress() to take `size_t`.
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.
On Windows 10 1607+, this flag is equivalent to calling the
SetDefaultDllDirectories() function before the program starts.
We're already calling SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_SYSTEM32)
in librpsecure/win32/restrict-dll.c, but this ensures that it's set even
before the program starts.
Related changes:
- amiiboc: Use delay-loading for libfmt. Otherwise, it fails with
error code 0xC0000135.
- Added a dummy stdafx.h file, required by DelayLoadHelper.c.
- All tests: Set /DEPENDENTLOADFLAG:0xA00 because gtest cannot be
delay-loaded.
- msvc.cmake: Fix linker flags for RelWithDebInfo.
TODO:
- EXE: Show DEPENDENTLOADFLAG.
- Test svrplus.
If the internal libfmt is used, it might not be a valid target.
This fixes a regression from commit 06f2f46655.
([cmake] CheckLibfmt.cmake: Remove FMT_SHARED from INTERFACE_COMPILE_DEFINITIONS.)
This causes parts of `class format_error` to be exported from
libromdata.so, which could result in multiple definitions:
V typeinfo for fmt::v11::format_error
V typeinfo name for fmt::v11::format_error
V vtable for fmt::v11::format_error
NOTE: Not needed for Win32.
Otherwise, if I add -fsanitize in a later run, IFUNC will remain enabled,
resulting in SIGSEGV.
Also, add checks for CFLAGS/CXXFLAGS in specific build types, similar to
libromdata.
- libfmt-6.2.0: Introduced the 'L' format specifier.
- Previously, 'n' was available.
- The 'L' specifier matches C++20 std::format().
- libfmt-7.0.x: Has fixes for the 'L' format specifier; removed 'n'.
- 'n' can be re-enabled with FMT_DEPRECATED_N_SPECIFIER.
- libfmt-7.1.0: Has more fixes for the 'L' format specifier.
- libfmt-8.0.0: Removes the 'n' format specifier entirely.
Since we use the 'L' specifier, we will set a minimum of libfmt-7.1.0.
Ubuntu 20.04 has libfmt-6.1.2; Ubuntu 22.04 has libfmt-8.1.1.
Also, Ubuntu 20.04's libfmt is a static library. It was changed
to a shared library sometime between 20.04 and 22.04.
rp-libfmt.h: Removed macros for compatibility with versions of libfmt
older than 7.1.0.
This significantly reduces the total size. fmt-11.dll's Release build
size is 128 KiB, and it cuts between 16-64 KiB from binaries that use it.
Total size of EXEs and DLLs, with amiiboc.exe and libgnuintl-8.dll,
but without test executables or PDBs:
[MSVC 2022 v17.6.5, Release build]
- Total size of EXEs and DLLs with header-only: 4,332,032
- Total size of EXEs and DLLs with fmt-11.dll: 4,161,536
- Difference: -170,496
With test executables:
- Total size of EXEs and DLLs with header-only: 9,716,224
- Total size of EXEs and DLLs with fmt-11.dll: 7,907,840
- Difference: -1,808,384
TODO: Add Delay-Load checks for fmt-11.dll to e.g. rpcli and the
Win32 UI frontend. (amiiboc and unit tests don't need it.)
Currently used as a header-only build. Will eventually be changed to
build a DLL for Windows and Mac OS X.
Other changes needed to get the Windows version to build with libfmt:
Add #include <fmt/xchar.h> to some files for full wchar_t support
in libfmt. Otherwise, errors like this appear:
src\amiibo-data\amiiboc.cpp(175,8): error C2665: 'fmt::v11::print': no overloaded function could convert all the argument types
extlib\libfmt\include\fmt\base.h(2925,17): message : could be 'void fmt::v11::print<TCHAR*&>(FILE *,fmt::v11::fstring<TCHAR *&>,TCHAR *&)'
src\amiibo-data\amiiboc.cpp(175,8): message : 'void fmt::v11::print<TCHAR*&>(FILE *,fmt::v11::fstring<TCHAR *&>,TCHAR *&)': cannot convert argument 2 from 'wmain::<lambda_1>::()::FMT_COMPILE_STRING' to 'fmt::v11::fstring<TCHAR *&>'
src\amiibo-data\amiiboc.cpp(175,22): message : No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
extlib\libfmt\include\fmt\base.h(2908,17): message : or 'void fmt::v11::print<wmain::<lambda_1>::()::FMT_COMPILE_STRING,TCHAR*&>(fmt::v11::fstring<wmain::<lambda_1>::()::FMT_COMPILE_STRING,TCHAR *&>,wmain::<lambda_1>::()::FMT_COMPILE_STRING &&,TCHAR *&)'
src\amiibo-data\amiiboc.cpp(175,8): message : 'void fmt::v11::print<wmain::<lambda_1>::()::FMT_COMPILE_STRING,TCHAR*&>(fmt::v11::fstring<wmain::<lambda_1>::()::FMT_COMPILE_STRING,TCHAR *&>,wmain::<lambda_1>::()::FMT_COMPILE_STRING &&,TCHAR *&)': cannot convert argument 1 from 'FILE *' to 'fmt::v11::fstring<wmain::<lambda_1>::()::FMT_COMPILE_STRING,TCHAR *&>'
src\amiibo-data\amiiboc.cpp(175,14): message : No constructor could take the source type, or constructor overload resolution was ambiguous
src\amiibo-data\amiiboc.cpp(175,8): message : while trying to match the argument list '(FILE *, wmain::<lambda_1>::()::FMT_COMPILE_STRING, TCHAR *)' [build.vc17_64\src\amiibo-data\amiiboc.vcxproj]
Files modified for xchar.h:
- amiibo-data/amiiboc.cpp
- libromdata/stdafx.h (needed by WiiUPackage)
- libromdata/tests/RomHeaderTest.cpp
NOTE: Only included on Windows. xchar.h was added in libfmt-8.0.0,
which was first added (in Ubuntu LTS releases) in Ubuntu 20.04.
It's not needed on Linux, anyway.
New option USE_INTERNAL_FMT to force the use of the internal copy of
libfmt on Linux, for testing purposes. (...and also for Ubuntu 16.04)
- TODO: Maybe use it on 18.04, etc. for improved performance?
This will replace printf()-style functions in most cases, and will
replace all uses of rp_sprintf() and related.
NOTE: We need to use FMT_STRING() [which we're abbreviating FSTR] if
compiling without C++20 support; otherwise, string format checking won't
be done. We're not targetting C++20 at the moment.
Also, string format checking can't be done when using gettext. This also
applied to printf(), so it's not a big deal per se.
NOTE: Support for C++-style format strings (std::print) was added in
gettext-0.22, so gettext-0.22 will be required in order to update the
.pot and .po files.
FIXME: libfmt has its own "PACKED" definition, which conflicts with our
own. We should rename our "PACKED" to "RP_PACKED".
TODO: Add an internal copy of libfmt for Windows.
FIx an error in the non-clang section that caused the common conformance
flags to be overwritten with the MSVC-only flags. Not sure if this will
break anything, and I can't build with MSVC at the moment...
Move "/Zc:throwingNew" into the same non-clang-cl block as the other
options.
If OFF, this disables rp-download and all associated downloading code
in the GTK and KDE UI frontends (e.g. Update Checker and ProxyForUrl),
and disables ExecRpDownload in libcachemanager.
NOTE: The KF5 and KF6 ThumbnailCreator plugins definitely needed the
NetworkManaer D-Bus interface for isMetered(), but it wasn't linked
in before. This didn't seem to cause a problem, but with the adjustments
for ENABLE_NETWORKING, it's now causing a linker error. Add the
generated D-Bus interface source to the ThumbnailCreator plugins
to fix this.
TODO:
- Don't generate or use the NetworkManager D-Bus interface in
no-network builds.
- Windows UI frontend changes.
- Disable the relevant configuration boxes in rp-config (but don't
remove them entirely).
- Remove functions from the seccomp() whitelists that are no longer
needed because we're not executing rp-download.
The root CMakeLists.txt has a minimum CMake version of 3.5, and
CheckHiddenVisibility.cmake's workarounds are only needed for
CMake 3.2 and earlier.
Set CMP0063 unconditionally (added in CMake 3.3) and set the
CMAKE_<LANG>_VISIBILITY_PRESET and CMAKE_VISIBILITY_INLINES_HIDDEN
variables where CHECK_HIDDEN_VISIBILITY() was called before.
There should effectively be no code changes with this commit.
This fixes the 'negative' errors from lcov's geninfo.
Before:
source files: 600
lines.......: 23.2% (10654 of 45904 lines)
functions...: 22.8% (848 of 3721 functions)
branches....: 15.8% (7572 of 47821 branches)
After:
source files: 600
lines.......: 23.2% (10654 of 45904 lines)
functions...: 22.8% (848 of 3721 functions)
branches....: 15.8% (7572 of 47821 branches)
Effectively no change in coverage, but it's likely more stable.
I'll note that the error was triggering in ASTC decoding, which
uses OpenMP for parallel processing.
- Enable the "new" automoc policy for KDE4.
Otherwise, CMake complains because the old policy doesn't run
automoc on generated sources, e.g. from uic or rcc.
NOTE: Only on Qt4; CMake doesn't show this for Qt5/Qt6.
- Unset KDE4 variables that are marked "deprecatd" in KF5/KF6.
Otherwise, if building for both KDE4 and KF5, a lot of deprecated
variable warnings appear.
- Copy SERVICES_INSTALL_DIR to KDE4_SERVICES_INSTALL_DIR, since it's
used by the KDE4 UI frontend.
EXEC_PROGRAM() is deprecated as of CMake 3.0.
KDEInstallDirs.cmake isn't actually needed and prints warnings due to
some KDE-specific variables not being consistent.
Also remove the "-fpic -fPIC" CFLAGS/CXXFLAGS addition, since we're
handling this using the POSITION_INDEPENDENT_CODE property now.
Warnings from the KF5 version:
CMake Warning (dev) at cmake/libs/RP_FindQt5andKF5.cmake:65 (EXEC_PROGRAM):
Policy CMP0153 is not set: The exec_program command should not be called.
Run "cmake --help-policy CMP0153" for policy details. Use the cmake_policy
command to set the policy and suppress this warning.
Use execute_process() instead.
Call Stack (most recent call first):
src/kde/kf5/CMakeLists.txt:6 (FIND_QT5_AND_KF5)
This warning is for project developers. Use -Wno-dev to suppress it.
CMake Warning at /usr/share/ECM/kde-modules/KDEInstallDirsCommon.cmake:385 (message):
KDE_INSTALL_BINDIR, KDE_INSTALL_LIBDIR and KDE_INSTALL_INCLUDEDIR should
either all be absolute paths or all be relative paths.
Call Stack (most recent call first):
/usr/share/ECM/kde-modules/KDEInstallDirs5.cmake:230 (include)
/usr/share/ECM/kde-modules/KDEInstallDirs.cmake:15 (include)
cmake/libs/RP_FindQt5andKF5.cmake:26 (INCLUDE)
src/kde/kf5/CMakeLists.txt:6 (FIND_QT5_AND_KF5)