fix 32bit builds. closes #8625
32 bit build failure summary
Previously described in issue #8625 (comment 2630968343)
Some hash functions and struct asserts expect 64bit values but use size_t which fails on 32bit machines.
Not entirely sure if more code should be changed or added to accommodate for 32bit builds.
-
formid has a size_t assertion for the ESM::FormId struct
-
algorithm has size_t for has functions that look like they should be utin64_t
original issue text
original issue
system:
- void linux (xbps-src build system)
- gcc 14.4.1 20250405
Trying to build openmw for 32bit architectures fails in a few spots. (0.48.0 was fine)
build errors
components/esm/formid.hpp
size_t operator()(const ESM::FormId& formId) const
{
static_assert(sizeof(ESM::FormId) == sizeof(size_t));
size_t is 4 on 32bit, 8 == 4 fails
Above it looks like the FormId struct has 3 uint32 and a string (which should be a pointer). size_t is 4 on 32bit, not 8. Using a hardcode works fine.
patch
--- components/esm/formid.hpp.orig 2025-07-16 08:08:41.922276482 -0400
+++ components/esm/formid.hpp 2025-07-16 08:31:26.832643473 -0400
@@ -49,12 +49,12 @@
template <>
struct hash<ESM::FormId>
{
- size_t operator()(const ESM::FormId& formId) const
+ uint64_t operator()(const ESM::FormId& formId) const
{
- static_assert(sizeof(ESM::FormId) == sizeof(size_t));
- size_t s;
- memcpy(&s, &formId, sizeof(size_t));
- return hash<size_t>()(s);
+ static_assert(sizeof(ESM::FormId) == 8); // 8 uint32_t itmes
+ uint64_t s;
+ memcpy(&s, &formId, sizeof(ESM::FormId));
+ return hash<uint64_t>()(s);
}
};
components/misc/strings/algorithm.hpp
/builddir/openmw-0.49.0/./components/misc/strings/algorithm.hpp:91:31: error: narrowing conversion of '14695981039346656037' from 'long long unsigned int' to 'std::size_t' {aka 'unsigned int'} [-Wnarrowing]
91 | std::size_t hash{ 0xcbf29ce484222325ull };
/builddir/openmw-0.49.0/./components/misc/strings/algorithm.hpp:92:42: error: narrowing conversion of '1099511628211' from 'long long unsigned int' to 'std::size_t' {aka 'unsigned int'} [-Wnarrowing]
92 | constexpr std::size_t prime{ 0x00000100000001B3ull };
|
size_t 32bit issue again where going from (64)longs to size_t does not work. Not sure how this pans out for windows, think type names are different but also don't know the build.
patch
--- components/misc/strings/algorithm.hpp.orig 2025-07-16 08:24:42.712492950 -0400
+++ components/misc/strings/algorithm.hpp 2025-07-16 08:35:08.809678885 -0400
@@ -4,6 +4,7 @@
#include "lower.hpp"
#include <algorithm>
+#include <cstdint>
#include <functional>
#include <string>
#include <string_view>
@@ -88,8 +89,8 @@
constexpr std::size_t operator()(std::string_view str) const
{
// FNV-1a
- std::size_t hash{ 0xcbf29ce484222325ull };
- constexpr std::size_t prime{ 0x00000100000001B3ull };
+ std::uint64_t hash{ 0xcbf29ce484222325ull };
+ constexpr std::uint64_t prime{ 0x00000100000001B3ull };
for (char c : str)
{
hash ^= static_cast<std::size_t>(toLower(c));
Comments
Changing these to uint64 seems like the thing to do, but I'm not sure if there are other places that would need swapped out.
It looks like unint64_t is used in some places : components/esm/indexrefid.hpp
If there's any info that would help or build tests I can help with let me know. But, I don't actually even have morrowwind to test, I was just trying to upgrade because off ffmpeg7 support.