From d4d6f640d0e2bdef99511572f0c27e9c940edace Mon Sep 17 00:00:00 2001 From: Dmitry Karasik Date: Wed, 14 May 2025 15:36:35 +0200 Subject: [PATCH] MacOSX: allow build with homebrew and its emulated MesaGL This change comes from Prima::OpenGL that is build with Prima that uses lots of homebrew libraries, and is actually advised to be build on homebrew. The problem comes with the libraries that are implicitly dependant on the native /opt/X11 libraries, and any program that is compiled with both set of Xlibs (and by extention, GL libs), dumps core. A possibile solution to this is to let OpenGL::Modern to use homebrew libraries, but that comes with a price, native mac gl will not be used, but the slow emulated MesaGL will be used instead. --- Makefile.PL | 44 ++++++++++++++++++++++++++++++++++++++++++-- README.md | 4 ++++ glew.c | 29 ++++++++++++++++++----------- 3 files changed, 64 insertions(+), 13 deletions(-) diff --git a/Makefile.PL b/Makefile.PL index d1dc6de..53a40fa 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -3,6 +3,39 @@ use ExtUtils::MakeMaker; use Devel::CheckLib 'assert_lib'; use Config; +sub pkg_config($$) +{ + my ($cmd, $lib) = @_; + $cmd =~ s/_/-/g; + my $x = `pkg-config --$cmd $lib 2>/dev/null`; + chomp $x; + return $x; +} + +sub check_homebrew +{ + # native libs and homebrew libs coredump if used together + return unless $^O eq 'darwin'; + return unless $ENV{WITH_HOMEBREW}; + my $found = 0; + my %ret; + for my $lib (qw(x11 gl glew)) { + my $v = pkg_config modversion => $lib; + next unless $v =~ /^\d/; + chomp $v; + print "found homebrew with $lib $v\n"; + $ret{inc} .= ' ' . pkg_config cflags => $lib; + $ret{lib} .= ' ' . pkg_config libs => $lib; + $found++; + } + unless ( 3 == $found ) { + print "** warning: to use homebrew, x11 gl and glew have to be installed\n"; + return; + } + $ret{lib} =~ s/-lGL\b// while 1 < @{[$ret{lib} =~ m/-lGL\b/g]}; + return %ret; +} + my $include = "-I. -Iinclude"; my $libs; my $define = "-DGLEW_NO_GLU -DGLEW_STATIC"; @@ -13,8 +46,15 @@ if ( $^O eq 'MSWin32' ) { } elsif ( $^O eq 'cygwin' ) { $libs = '-lGL -lX11'; } elsif ( $^O eq 'darwin' ) { - $DYNS = { 'OTHERLDFLAGS' => '-framework OpenGL' }; - $define .= " -Wno-compound-token-split-by-macro -DGL_SILENCE_DEPRECATION"; + my %hb = check_homebrew; + if ( keys %hb ) { + $libs = $hb{lib}; + $include .= $hb{inc}; + $define .= " -DGLEW_HOMEBREW"; + } else { + $DYNS = { 'OTHERLDFLAGS' => '-framework OpenGL' }; + $define .= " -Wno-compound-token-split-by-macro -DGL_SILENCE_DEPRECATION"; + } } else { $libs = '-lGL -lX11'; } diff --git a/README.md b/README.md index 4f3ef49..ad0a129 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,10 @@ To install this module type the following: or cpan or cpanm. +### MacOSX + +To build with homebrew and it's emulated MesaGL, run `env WITH_HOMEBREW=1 perl Makefile.PL`. + ## COPYRIGHT AND LICENCE Copyright (C) 2017 by Chris Marshall diff --git a/glew.c b/glew.c index d1b20a6..5f3df53 100644 --- a/glew.c +++ b/glew.c @@ -36,6 +36,10 @@ #include GLEW_INCLUDE #endif +#if defined(__APPLE__) && !defined(GLEW_HOMEBREW) +# define GLEW_APPLE_NATIVE +#endif + #if defined(GLEW_OSMESA) # define GLAPI extern # include @@ -51,7 +55,7 @@ # undef NOGDI # endif # include -#elif !defined(__ANDROID__) && !defined(__native_client__) && !defined(__HAIKU__) && (!defined(__APPLE__) || defined(GLEW_APPLE_GLX)) +#elif !defined(__ANDROID__) && !defined(__native_client__) && !defined(__HAIKU__) && (!defined(GLEW_APPLE_NATIVE) || defined(GLEW_APPLE_GLX)) # include #endif @@ -97,7 +101,7 @@ void* dlGetProcAddress (const GLubyte* name) } #endif /* __sgi || __sun || GLEW_APPLE_GLX */ -#if defined(__APPLE__) +#if defined(GLEW_APPLE_NATIVE) #include #include #include @@ -153,12 +157,15 @@ void* NSGLGetProcAddress (const GLubyte *name) #endif } #endif /* MAC_OS_X_VERSION_10_3 */ -#endif /* __APPLE__ */ +#endif /* GLEW_APPLE_NATIVE */ /* * Define glewGetProcAddress. */ -#if defined(GLEW_REGAL) +#if defined(GLEW_HOMEBREW) +# define glewGetProcAddress(name) (*glXGetProcAddressARB)(name) +#elif defined(GLEW_REGAL) +# define glewGetProcAddress(name) (*glXGetProcAddressARB)(name) # define glewGetProcAddress(name) regalGetProcAddress((const GLchar *)name) #elif defined(GLEW_OSMESA) # define glewGetProcAddress(name) OSMesaGetProcAddress((const char *)name) @@ -166,7 +173,7 @@ void* NSGLGetProcAddress (const GLubyte *name) # define glewGetProcAddress(name) eglGetProcAddress((const char *)name) #elif defined(_WIN32) # define glewGetProcAddress(name) wglGetProcAddress((LPCSTR)name) -#elif defined(__APPLE__) && !defined(GLEW_APPLE_GLX) +#elif defined(GLEW_APPLE_NATIVE) && !defined(GLEW_APPLE_GLX) # define glewGetProcAddress(name) NSGLGetProcAddress(name) #elif defined(__sgi) || defined(__sun) || defined(__HAIKU__) # define glewGetProcAddress(name) dlGetProcAddress(name) @@ -231,7 +238,7 @@ static GLuint _glewStrCopy(char *d, const char *s, char c) } #if !defined(GLEW_OSMESA) -#if !defined(__APPLE__) || defined(GLEW_APPLE_GLX) +#if !defined(GLEW_APPLE_NATIVE) || defined(GLEW_APPLE_GLX) static GLboolean _glewStrSame (const GLubyte* a, const GLubyte* b, GLuint n) { GLuint i=0; @@ -303,7 +310,7 @@ static GLboolean _glewStrSame3 (const GLubyte** a, GLuint* na, const GLubyte* b, * string returned by glGetString might be in read-only memory. */ #if !defined(GLEW_OSMESA) -#if !defined(__APPLE__) || defined(GLEW_APPLE_GLX) +#if !defined(GLEW_APPLE_NATIVE) || defined(GLEW_APPLE_GLX) static GLboolean _glewSearchExtension (const char* name, const GLubyte *start, const GLubyte *end) { const GLubyte* p; @@ -19746,7 +19753,7 @@ GLenum GLEWAPIENTRY wglewInit () return GLEW_OK; } -#elif !defined(__ANDROID__) && !defined(__native_client__) && !defined(__HAIKU__) && (!defined(__APPLE__) || defined(GLEW_APPLE_GLX)) +#elif !defined(__ANDROID__) && !defined(__native_client__) && !defined(__HAIKU__) && (!defined(GLEW_APPLE_NATIVE) || defined(GLEW_APPLE_GLX)) PFNGLXGETCURRENTDISPLAYPROC __glewXGetCurrentDisplay = NULL; @@ -20821,7 +20828,7 @@ GLenum glxewInit () return GLEW_OK; } -#endif /* !defined(__ANDROID__) && !defined(__native_client__) && !defined(__HAIKU__) && (!defined(__APPLE__) || defined(GLEW_APPLE_GLX)) */ +#endif /* !defined(__ANDROID__) && !defined(__native_client__) && !defined(__HAIKU__) && (!defined(GLEW_APPLE_NATIVE) || defined(GLEW_APPLE_GLX)) */ /* ------------------------------------------------------------------------ */ @@ -20872,7 +20879,7 @@ GLenum GLEWAPIENTRY glewInit (void) return r; #elif defined(_WIN32) return wglewInit(); -#elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) /* _UNIX */ +#elif !defined(GLEW_APPLE_NATIVE) || defined(GLEW_APPLE_GLX) /* _UNIX */ return glxewInit(); #else return r; @@ -27059,7 +27066,7 @@ GLboolean GLEWAPIENTRY wglewIsSupported (const char* name) return ret; } -#elif !defined(GLEW_OSMESA) && !defined(GLEW_EGL) && !defined(__ANDROID__) && !defined(__native_client__) && !defined(__HAIKU__) && !defined(__APPLE__) || defined(GLEW_APPLE_GLX) +#elif !defined(GLEW_OSMESA) && !defined(GLEW_EGL) && !defined(__ANDROID__) && !defined(__native_client__) && !defined(__HAIKU__) && !defined(GLEW_APPLE_NATIVE) || defined(GLEW_APPLE_GLX) GLboolean glxewIsSupported (const char* name) {