Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save agrajag9/c50f404ffdce0df09616a78bf4bb8376 to your computer and use it in GitHub Desktop.
Save agrajag9/c50f404ffdce0df09616a78bf4bb8376 to your computer and use it in GitHub Desktop.
FreeBSD-ports: switch games/mizuma from emulators/wine to emulators/wine-devel and apply Wine PR 7339 to implement create_logical_proc_info. This fixes Cyberpunk 2077.
commit aa0bb49e0355a0853e9019d87a4741fc0ec7cf55
Author: agrajag9 <[email protected]>
Date: Sat May 3 09:00:10 2025 +0000
emulators/wine-devel: implement create_logical_proc_info on FreeBSD
see: wine merge request 7339
https://gitlab.winehq.org/wine/wine/-/merge_requests/7339
diff --git a/emulators/wine-devel/files/patch-configure.ac b/emulators/wine-devel/files/patch-configure.ac
new file mode 100644
index 0000000000..9821845a21
--- /dev/null
+++ b/emulators/wine-devel/files/patch-configure.ac
@@ -0,0 +1,31 @@
+--- configure.ac.orig 2025-04-04 20:12:06 UTC
++++ configure.ac
+@@ -30,6 +30,7 @@ AC_ARG_WITH(dbus, AS_HELP_STRING([--without-dbus]
+ AC_ARG_WITH(coreaudio, AS_HELP_STRING([--without-coreaudio],[do not use the CoreAudio sound support]))
+ AC_ARG_WITH(cups, AS_HELP_STRING([--without-cups],[do not use CUPS]))
+ AC_ARG_WITH(dbus, AS_HELP_STRING([--without-dbus],[do not use DBus (dynamic device support)]))
++AC_ARG_WITH(expat, AS_HELP_STRING([--without-expat],[do not use Expat]))
+ AC_ARG_WITH(ffmpeg, AS_HELP_STRING([--without-ffmpeg],[do not use the FFmpeg library]))
+ AC_ARG_WITH(fontconfig,AS_HELP_STRING([--without-fontconfig],[do not use fontconfig]))
+ AC_ARG_WITH(freetype, AS_HELP_STRING([--without-freetype],[do not use the FreeType library]))
+@@ -1482,6 +1483,20 @@ esac
+ *) WINE_NOTICE_WITH(dbus,[test "x$ac_cv_lib_soname_dbus_1" = "x"],
+ [libdbus ${notice_platform}development files not found, no dynamic device support.]) ;;
+ esac
++
++dnl **** Check for expat ****
++if test "x$with_expat" != "xno" -a `expr "$host_os" : '\(freebsd\).*'` = "freebsd"
++then
++ WINE_PACKAGE_FLAGS(EXPAT,[expat],,,,
++ [AC_CHECK_HEADER([expat.h],
++ [AC_CHECK_LIB(expat,XML_ParserCreate,
++ [AC_DEFINE(HAVE_LIBEXPAT, 1, [Define to 1 if you have the 'expat' library (-lexpat).])],
++ [EXPAT_LIBS=""],
++ [$EXPAT_LIBS])],
++ [EXPAT_LIBS=""])])
++ WINE_NOTICE_WITH(expat,[test "$ac_cv_lib_expat_XML_ParserCreate" != "yes"],
++ [expat ${notice_platform}development files not found, detailed CPU info on FreeBSD won't be supported.])
++fi
+
+ dnl **** Check for libgnutls ****
+ if test "x$with_gnutls" != "xno"
diff --git a/emulators/wine-devel/files/patch-dlls_ntdll_Makefile.in b/emulators/wine-devel/files/patch-dlls_ntdll_Makefile.in
new file mode 100644
index 0000000000..a4c1b37a3f
--- /dev/null
+++ b/emulators/wine-devel/files/patch-dlls_ntdll_Makefile.in
@@ -0,0 +1,13 @@
+--- dlls/ntdll/Makefile.in.orig 2025-04-04 20:12:06 UTC
++++ dlls/ntdll/Makefile.in
+@@ -4,8 +4,8 @@ EXTRAINCL = $(TOMCRYPT_PE_CFLAGS)
+ IMPORTLIB = ntdll
+ IMPORTS = $(TOMCRYPT_PE_LIBS) $(MUSL_PE_LIBS)
+ EXTRAINCL = $(TOMCRYPT_PE_CFLAGS)
+-UNIX_CFLAGS = $(UNWIND_CFLAGS)
+-UNIX_LIBS = $(IOKIT_LIBS) $(COREFOUNDATION_LIBS) $(CORESERVICES_LIBS) $(RT_LIBS) $(PTHREAD_LIBS) $(UNWIND_LIBS) $(I386_LIBS) $(PROCSTAT_LIBS)
++UNIX_CFLAGS = $(UNWIND_CFLAGS) $(EXPAT_CFLAGS)
++UNIX_LIBS = $(IOKIT_LIBS) $(COREFOUNDATION_LIBS) $(CORESERVICES_LIBS) $(RT_LIBS) $(PTHREAD_LIBS) $(UNWIND_LIBS) $(I386_LIBS) $(PROCSTAT_LIBS) $(EXPAT_LIBS)
+
+ EXTRADLLFLAGS = -nodefaultlibs
+ i386_EXTRADLLFLAGS = -Wl,--image-base,0x7bc00000
diff --git a/emulators/wine-devel/files/patch-dlls_ntdll_unix_system.c b/emulators/wine-devel/files/patch-dlls_ntdll_unix_system.c
new file mode 100644
index 0000000000..eb7ff3a721
--- /dev/null
+++ b/emulators/wine-devel/files/patch-dlls_ntdll_unix_system.c
@@ -0,0 +1,249 @@
+--- dlls/ntdll/unix/system.c.orig 2025-04-04 20:12:06 UTC
++++ dlls/ntdll/unix/system.c
+@@ -69,6 +69,10 @@
+ # include <mach/vm_map.h>
+ #endif
+
++#if defined(HAVE_LIBEXPAT)
++# include <expat.h>
++#endif
++
+ #include "ntstatus.h"
+ #define WIN32_NO_STATUS
+ #include "windef.h"
+@@ -1330,6 +1334,235 @@ static NTSTATUS create_logical_proc_info(void)
+ logical_proc_info_add_group( lcpu_no, all_cpus_mask );
+
+ return STATUS_SUCCESS;
++}
++
++#elif defined(__FreeBSD__) || defined(__FreeBSD__kernel__)
++
++/*
++ * str is a comma-separated array of longs, in hexadecimal, in the kernel's
++ * bitness, eg: "f,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" for 4 CPUs. With
++ * CPU_MAXSIZE==1024, and with (sizeof(long)*8)==64, there will be
++ * ceil(1024/64)==16 array entries. CPU IDs fill the longs from first to last,
++ * lowest to highest bit.
++ *
++ * Wine currently doesn't support processor groups, so we only care about
++ * the first ULONG_PTR size bits, others wouldn't fit in the mask.
++ */
++static BOOL parse_cpu_mask(const char *str, ULONG_PTR *mask)
++{
++ *mask = 0;
++ for (; *str && *str != ','; str++)
++ {
++ *mask <<= 4;
++ if ('0' <= *str && *str <= '9')
++ *mask |= *str - '0';
++ else if ('a' <= *str && *str <= 'f')
++ *mask |= 0xa + (*str - 'a');
++ else
++ return FALSE;
++ }
++ return TRUE;
++}
++
++struct group_state {
++ unsigned int cache_level;
++ ULONG_PTR cpu_mask;
++ BOOL is_numa_node;
++ BOOL has_children;
++};
++
++#define MAX_GROUP_LEVELS 10
++
++struct topology_parse_state {
++ NTSTATUS nt_status;
++ DWORD group_level;
++ struct group_state groups[1 + MAX_GROUP_LEVELS];
++
++ unsigned int package_count;
++ unsigned int core_count;
++ unsigned int numa_node_count;
++ ULONG_PTR all_cpus_mask;
++};
++
++static void topology_start_elem(void *user_data, const char *name, const char **attrs)
++{
++ struct group_state *group;
++ struct topology_parse_state *state = user_data;
++ int i;
++
++ if (state->nt_status != STATUS_SUCCESS)
++ return;
++ group = &state->groups[state->group_level];
++
++ if (!strcmp(name, "groups"))
++ ;
++ else if (!strcmp(name, "group"))
++ {
++ group->has_children = TRUE;
++ ++state->group_level;
++ if (state->group_level > MAX_GROUP_LEVELS)
++ {
++ FIXME("excessive <group> element nesting\n");
++ state->nt_status = STATUS_XML_PARSE_ERROR;
++ return;
++ }
++ group = &state->groups[state->group_level];
++ group->cache_level = 0;
++ group->cpu_mask = 0;
++ group->is_numa_node = FALSE;
++ group->has_children = FALSE;
++ for (i = 0; attrs[i]; i += 2)
++ {
++ if (!strcmp(attrs[i], "cache-level"))
++ group->cache_level = atoi(attrs[i+1]);
++ }
++ }
++ else if (!strcmp(name, "cpu"))
++ {
++ for (i = 0; attrs[i]; i += 2)
++ {
++ if (!strcmp(attrs[i], "mask"))
++ parse_cpu_mask(attrs[i+1], &group->cpu_mask);
++ }
++ }
++ else if (!strcmp(name, "flags"))
++ ;
++ else if (!strcmp(name, "flag"))
++ {
++ for (i = 0; attrs[i]; i += 2)
++ {
++ if (!strcmp(attrs[i], "name") && !strcmp(attrs[i+1], "NODE"))
++ group->is_numa_node = TRUE;
++ }
++ }
++ else if (!strcmp(name, "children"))
++ ;
++}
++
++static void topology_end_elem(void *user_data, const char *name)
++{
++ struct topology_parse_state *state = user_data;
++
++ if (state->nt_status != STATUS_SUCCESS)
++ return;
++
++ /* Treat top-level groups as packages, leaf groups as cores */
++ if (!strcmp(name, "group"))
++ {
++ struct group_state *group = &state->groups[state->group_level];
++ state->all_cpus_mask |= group->cpu_mask;
++ if (!group->has_children)
++ {
++ if (!logical_proc_info_add_by_id(RelationProcessorPackage, state->package_count, group->cpu_mask))
++ {
++ state->nt_status = STATUS_NO_MEMORY;
++ return;
++ }
++ TRACE("added processors 0x%016llx to package %u\n", (long long)group->cpu_mask, state->package_count);
++ if (!logical_proc_info_add_by_id(RelationProcessorCore, state->core_count, group->cpu_mask))
++ {
++ state->nt_status = STATUS_NO_MEMORY;
++ return;
++ }
++ TRACE("added processors 0x%016llx to core %u\n", (long long)group->cpu_mask, state->core_count);
++ ++state->core_count;
++ }
++ if (group->is_numa_node)
++ {
++ if (!logical_proc_info_add_numa_node(group->cpu_mask, state->numa_node_count))
++ {
++ state->nt_status = STATUS_NO_MEMORY;
++ return;
++ }
++ TRACE("added processors 0x%016llx to NUMA node %u\n", (long long)group->cpu_mask, state->numa_node_count);
++ ++state->numa_node_count;
++ }
++ /* FreeBSD provides almost no info about caching */
++ if (1 <= group->cache_level && group->cache_level <= 3)
++ {
++ CACHE_DESCRIPTOR cache;
++ cache.Level = group->cache_level;
++ cache.Associativity = 12; /* reasonable default */
++ cache.LineSize = 64; /* reasonable default */
++ cache.Size = 64 * 1024; /* reasonable default */
++ cache.Type = CacheUnified; /* reasonable default */
++ if (!logical_proc_info_add_cache(group->cpu_mask, &cache))
++ {
++ state->nt_status = STATUS_NO_MEMORY;
++ return;
++ }
++ TRACE("added processors 0x%016llx to cache level %u\n", (long long)group->cpu_mask, group->cache_level);
++ }
++ --state->group_level;
++ if (state->group_level == 0)
++ ++state->package_count;
++ }
++}
++
++static NTSTATUS create_logical_proc_info(void)
++{
++#if defined(HAVE_LIBEXPAT)
++ size_t size;
++ int ret;
++ NTSTATUS nt_status = STATUS_SUCCESS;
++ char *topology_spec = NULL;
++ XML_Parser parser = NULL;
++ struct topology_parse_state state = {};
++
++ /* See the smp(4) man page, and https://forums.freebsd.org/threads/number-of-cpus-and-cores.41299/ */
++ ret = sysctlbyname("kern.sched.topology_spec", NULL, &size, NULL, 0);
++ if (ret != 0)
++ {
++ if (errno == ENOENT || errno == ENOTDIR || errno == EISDIR)
++ {
++ FIXME("the kern.sched.topology_spec sysctl does not exist, you need to use sched_ule\n");
++ nt_status = STATUS_NOT_IMPLEMENTED;
++ }
++ else
++ nt_status = STATUS_NO_MEMORY;
++ goto end;
++ }
++ topology_spec = malloc(size);
++ if (topology_spec == NULL)
++ {
++ nt_status = STATUS_NO_MEMORY;
++ goto end;
++ }
++ ret = sysctlbyname("kern.sched.topology_spec", topology_spec, &size, NULL, 0);
++ if (ret != 0)
++ {
++ nt_status = STATUS_NO_MEMORY;
++ goto end;
++ }
++
++ parser = XML_ParserCreate("US-ASCII");
++ if (parser == NULL)
++ {
++ nt_status = STATUS_NO_MEMORY;
++ goto end;
++ }
++ state.nt_status = STATUS_SUCCESS;
++ XML_SetUserData(parser, &state);
++ XML_SetElementHandler(parser, topology_start_elem, topology_end_elem);
++ if (XML_Parse(parser, topology_spec, size-1, XML_TRUE) == XML_STATUS_OK)
++ nt_status = state.nt_status;
++ else
++ {
++ FIXME("failed to parse sysctl kern.sched.topology_spec, expat errorcode %d\n", XML_GetErrorCode(parser));
++ nt_status = STATUS_XML_PARSE_ERROR;
++ }
++ logical_proc_info_add_group(count_bits(state.all_cpus_mask), state.all_cpus_mask);
++
++end:
++ free(topology_spec);
++ if (parser != NULL)
++ XML_ParserFree(parser);
++ return nt_status;
++
++#else
++ FIXME("expat unavailable, cannot parse sysctl kern.sched.topology_spec\n");
++ return STATUS_NOT_IMPLEMENTED;
++#endif
+ }
+
+ #else
diff --git a/emulators/wine-devel/files/patch-include_config.h.in b/emulators/wine-devel/files/patch-include_config.h.in
new file mode 100644
index 0000000000..e11fbb8618
--- /dev/null
+++ b/emulators/wine-devel/files/patch-include_config.h.in
@@ -0,0 +1,12 @@
+--- include/config.h.in.orig 2025-04-04 20:12:06 UTC
++++ include/config.h.in
+@@ -138,6 +138,9 @@
+ /* Define to 1 if you have the <libavutil/avutil.h> header file. */
+ #undef HAVE_LIBAVUTIL_AVUTIL_H
+
++/* Define to 1 if you have the 'expat' library (-lexpat). */
++#undef HAVE_LIBEXPAT
++
+ /* Define to 1 if you have the 'gettextpo' library (-lgettextpo). */
+ #undef HAVE_LIBGETTEXTPO
+
commit bd05cc67f3805fd18da99aff6f0e76823b638f76
Author: agrajag9 <[email protected]>
Date: Sat May 3 08:59:37 2025 +0000
games/mizuma: use emulators/wine-devel instead of emulators/wine
diff --git a/games/mizuma/files/patch-Mizuma b/games/mizuma/files/patch-Mizuma
new file mode 100644
index 0000000000..9724127d98
--- /dev/null
+++ b/games/mizuma/files/patch-Mizuma
@@ -0,0 +1,11 @@
+--- Mizuma.orig 2025-05-03 07:19:49 UTC
++++ Mizuma
+@@ -367,7 +367,7 @@ echo -e "\e[3;5;0;96mSetting up 32-Bit libraries ...\e
+ if [ $online -eq 0 ]; then
+ if [ ! -f "$HOME/.i386-wine-pkg/usr/local/libdata/ldconfig/wine" ]; then
+ echo -e "\e[3;5;0;96mSetting up 32-Bit libraries ...\e[30;48;5;82m\e[0m"
+-/usr/local/share/wine/pkg32.sh install -y wine mesa-dri | zenity --auto-close --percentage=15 --progress --title="$NAME - 32-Bit maintenance" --text="Installing 32-Bit libraries"
++/usr/local/share/wine/pkg32.sh install -y wine-devel mesa-dri | zenity --auto-close --percentage=15 --progress --title="$NAME - 32-Bit maintenance" --text="Installing 32-Bit libraries"
+ MesaDEV=$(pkg info mesa-devel)
+ if [[ $MesaDEV == *"Name : mesa-devel"* ]]; then
+ MD=$(question "It looks like that you have installed mesa-devel, do you like to install mesa-devel for the Wine 32-Bit part too?")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment