From d4634526fdf1121f0d5c37eaa31e965936808cb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Brammer?= Date: Fri, 29 Jan 2016 18:29:46 +0100 Subject: [PATCH] GL: Switch from GLEW to Epoxy Epoxy automatically fetches the extension functions on demand, including the GLX context creation functions. This means that you can't test the function pointers for NULL anymore, because they're always set to a resolver function until the first call. Instead, you have to check for the availability of an extension by the extension's name. Thanks to Isilkor for catching these. On windows, epoxy invalidates all extension function pointers when the GL context changes. This means we need to have an active context at all times we call an extension function (like wglGetPixelFormatAttribivARB) or else the code will jump to an invalid pointer. On the other hand, we do not need to make it reinitialize the pointers ourselves. Epoxy automatically uses an alias for a function if the requested name is not available, like glDebugMessageCallbackARB instead of glDebugMessageCallback. It also does not have the problem with varying parameter types for that function. So switch to it while removing GLDEBUGPROCARB_USERPARAM_IS_CONST. --- CMakeLists.txt | 12 +-- cmake/FindEpoxy.cmake | 31 ++++++++ cmake/FindGLEW.cmake | 63 ---------------- config.h.cmake | 4 - src/editor/C4ConsoleCocoa.mm | 4 +- src/editor/C4EditorWindowController.mm | 4 +- src/graphics/C4DrawGL.cpp | 38 ++++------ src/graphics/C4DrawGL.h | 4 +- src/graphics/C4DrawGLCtx.cpp | 75 ++----------------- src/graphics/C4DrawGLMac.mm | 8 -- src/graphics/C4Shader.h | 6 +- src/platform/C4AppDelegate+MainMenuActions.mm | 4 +- src/platform/C4AppMac.mm | 8 +- src/platform/C4WindowController.mm | 4 +- src/platform/C4WindowGTK.cpp | 2 +- tools/osx_bundle_libs | 2 +- 16 files changed, 72 insertions(+), 197 deletions(-) create mode 100644 cmake/FindEpoxy.cmake delete mode 100644 cmake/FindGLEW.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index ca8049359..3b403ac2e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -251,14 +251,8 @@ endif() include_directories(SYSTEM ${TinyXML_INCLUDE_DIRS}) find_package(OpenGL) -find_package(GLEW REQUIRED) -include_directories(${GLEW_INCLUDE_DIRS}) -add_definitions(${GLEW_DEFINITIONS}) -# On some platforms, GLEW declares the userParam parameter of -# GLDEBUGPROCARB as const void *, and on other platforms, it's void *. -# Test which one works here. -set(CMAKE_REQUIRED_INCLUDES "${GLEW_INCLUDE_DIRS}") -CHECK_CXX_SOURCE_COMPILES("#include \nvoid GLAPIENTRY OpenGLDebugProc(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const char* message, const void* userParam) {}\nint main() { GLDEBUGPROCARB proc = &OpenGLDebugProc; }" GLDEBUGPROCARB_USERPARAM_IS_CONST) +find_package(Epoxy REQUIRED) +include_directories(${Epoxy_INCLUDE_DIRS}) if(USE_GTK AND UNIX) FINDLIB(X11_LIBRARIES X11) @@ -1096,7 +1090,7 @@ target_link_libraries(openclonk ${SDL2_LIBRARIES} ${Audio_LIBRARIES} ${GETOPT_LIBRARIES} - ${GLEW_LIBRARIES} + ${Epoxy_LIBRARIES} ${OPENGL_LIBRARIES} ${TinyXML_LIBRARIES} ${X11_LIBRARIES} diff --git a/cmake/FindEpoxy.cmake b/cmake/FindEpoxy.cmake new file mode 100644 index 000000000..3a21755f4 --- /dev/null +++ b/cmake/FindEpoxy.cmake @@ -0,0 +1,31 @@ +# OpenClonk, http://www.openclonk.org +# +# Copyright (c) 2016, The OpenClonk Team and contributors +# +# Distributed under the terms of the ISC license; see accompanying file +# "COPYING" for details. +# +# "Clonk" is a registered trademark of Matthes Bender, used with permission. +# See accompanying file "TRADEMARK" for details. +# +# To redistribute this file separately, substitute the full license texts +# for the above references. + +# Locate Epoxy. +# This module defines +# Epoxy_INCLUDE_DIRS - a list of directories that need to be added to the include path +# Epoxy_LIBRARIES - a list of libraries to link against to use Epoxy +# Epoxy_FOUND - if false, Epoxy cannot be used + +find_path(Epoxy_INCLUDE_DIR epoxy/gl.h) +mark_as_advanced(Epoxy_INCLUDE_DIR) +find_library(Epoxy_LIBRARY epoxy) +mark_as_advanced(Epoxy_LIBRARY) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Epoxy REQUIRED_VARS Epoxy_LIBRARY Epoxy_INCLUDE_DIR) + +if (Epoxy_FOUND) + set(Epoxy_LIBRARIES "${Epoxy_LIBRARY}") + set(Epoxy_INCLUDE_DIRS "${Epoxy_INCLUDE_DIR}") +endif() diff --git a/cmake/FindGLEW.cmake b/cmake/FindGLEW.cmake deleted file mode 100644 index a897064cf..000000000 --- a/cmake/FindGLEW.cmake +++ /dev/null @@ -1,63 +0,0 @@ -# OpenClonk, http://www.openclonk.org -# -# Copyright (c) 2015, The OpenClonk Team and contributors -# -# Distributed under the terms of the ISC license; see accompanying file -# "COPYING" for details. -# -# "Clonk" is a registered trademark of Matthes Bender, used with permission. -# See accompanying file "TRADEMARK" for details. -# -# To redistribute this file separately, substitute the full license texts -# for the above references. - -# Locate GLEW. -# This module defines -# GLEW_INCLUDE_DIRS - a list of directories that need to be added to the include path -# GLEW_LIBRARIES - a list of libraries to link against to use GLEW -# GLEW_DEFINITIONS - a list of compile-time macros that need to be defined to use GLEW -# GLEW_FOUND - if false, GLEW cannot be used - -find_path(GLEW_INCLUDE_DIR GL/glew.h PATH_SUFFIXES) -mark_as_advanced(GLEW_INCLUDE_DIR) - -# Read GLEW version from header -if (GLEW_INCLUDE_DIR AND EXISTS "${GLEW_INCLUDE_DIR}/GL/glew.h") - file(STRINGS "${GLEW_INCLUDE_DIR}/GL/glew.h" glew_version_str REGEX "^VERSION .+") - string(REGEX REPLACE "^VERSION (.+)" "\\1" GLEW_VERSION_STRING "${glew_version_str}") - unset(glew_version_str) -endif() - -# On OS other than Windows, it doesn't matter whether we confuse the shared -# library and the static one. On Windows, we need to #define GLEW_STATIC if -# (and only if) we're linking against the static library. "glew32" may match -# the static library on MinGW, so we have to test for that explicitly. -find_library(GLEW_STATIC_LIBRARY glew32s) -mark_as_advanced(GLEW_STATIC_LIBRARY) -find_library(GLEW_SHARED_LIBRARY NAMES GLEW glew32) -mark_as_advanced(GLEW_SHARED_LIBRARY) - -if (GLEW_SHARED_LIBRARY) - set(GLEW_LIBRARY "${GLEW_SHARED_LIBRARY}") - if (WIN32 AND MINGW AND GLEW_SHARED_LIBRARY MATCHES "\\.a$") - # not actually a shared library - set(GLEW_DEFINITIONS "-DGLEW_STATIC") - else() - set(GLEW_DEFINITIONS) - endif() -elseif (GLEW_STATIC_LIBRARY) - set(GLEW_LIBRARY "${GLEW_STATIC_LIBRARY}") - set(GLEW_DEFINITIONS "-DGLEW_STATIC") -endif() - -include(FindPackageHandleStandardArgs) -if (NOT "${CMAKE_VERSION}" VERSION_LESS "2.8.3") - find_package_handle_standard_args(GLEW VERSION_VAR GLEW_VERSION_STRING REQUIRED_VARS GLEW_LIBRARY GLEW_INCLUDE_DIR) -else() - find_package_handle_standard_args(GLEW GLEW_LIBRARY GLEW_INCLUDE_DIR) -endif() - -if (GLEW_FOUND) - set(GLEW_LIBRARIES "${GLEW_LIBRARY}") - set(GLEW_INCLUDE_DIRS "${GLEW_INCLUDE_DIR}") -endif() diff --git a/config.h.cmake b/config.h.cmake index 7f7589dc3..7139cbe8a 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -89,10 +89,6 @@ /* MP3 music */ #cmakedefine USE_MP3 1 -/* Define to 1 if the userParam parameter to GLDEBUGPROCARB is const, as the - spec requires. */ -#cmakedefine GLDEBUGPROCARB_USERPARAM_IS_CONST 1 - /* Glib */ #cmakedefine WITH_GLIB 1 diff --git a/src/editor/C4ConsoleCocoa.mm b/src/editor/C4ConsoleCocoa.mm index 97098431d..3965f10ac 100644 --- a/src/editor/C4ConsoleCocoa.mm +++ b/src/editor/C4ConsoleCocoa.mm @@ -13,8 +13,6 @@ * for the above references. */ -#include - #include #include #include @@ -34,6 +32,8 @@ #include #include +#include + #import #import "C4AppDelegate.h" #import "C4EditorWindowController.h" diff --git a/src/editor/C4EditorWindowController.mm b/src/editor/C4EditorWindowController.mm index d555265ca..cf7035d70 100644 --- a/src/editor/C4EditorWindowController.mm +++ b/src/editor/C4EditorWindowController.mm @@ -12,8 +12,6 @@ * To redistribute this file separately, substitute the full license texts * for the above references. */ - -#include #include #include @@ -21,6 +19,8 @@ #include #include +#include + #import #import #import diff --git a/src/graphics/C4DrawGL.cpp b/src/graphics/C4DrawGL.cpp index d4bb7ef1b..8f05f5e75 100644 --- a/src/graphics/C4DrawGL.cpp +++ b/src/graphics/C4DrawGL.cpp @@ -80,13 +80,7 @@ namespace } } -#ifdef GLDEBUGPROCARB_USERPARAM_IS_CONST -#define USERPARAM_CONST const -#else -#define USERPARAM_CONST -#endif - - void GLAPIENTRY OpenGLDebugProc(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const char* message, USERPARAM_CONST void* userParam) + void GLAPIENTRY OpenGLDebugProc(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const char* message, const void* userParam) { const char *msg_source = MsgSourceToStr(source); const char *msg_type = MsgTypeToStr(type); @@ -100,8 +94,6 @@ namespace } } -#undef USERPARAM_CONST - CStdGL::CStdGL(): pMainCtx(0), CurrentVBO(0), NextVAOID(VAOIDs.end()) { @@ -276,10 +268,8 @@ bool CStdGL::PrepareSpriteShader(C4Shader& shader, const char* name, int ssc, C4 void CStdGL::ObjectLabel(uint32_t identifier, uint32_t name, int32_t length, const char * label) { -#ifdef GL_KHR_debug - if (glObjectLabel) + if (has_khr_debug) glObjectLabel(identifier, name, length, label); -#endif } CStdGLCtx *CStdGL::CreateContext(C4Window * pWindow, C4AbstractApp *pApp) @@ -295,16 +285,20 @@ CStdGLCtx *CStdGL::CreateContext(C4Window * pWindow, C4AbstractApp *pApp) pMainCtx = pCtx; LogF(" gl: Create first %scontext...", Config.Graphics.DebugOpenGL ? "debug " : ""); } - bool success = pCtx->Init(pWindow, pApp); - if (Config.Graphics.DebugOpenGL && glDebugMessageCallbackARB) + if (!pCtx->Init(pWindow, pApp)) + { + Log(" gl: failed to create context."); + delete pCtx; + return NULL; + } + has_khr_debug = epoxy_has_gl_extension("GL_KHR_debug") || epoxy_gl_version() >= 43; + if (Config.Graphics.DebugOpenGL && (has_khr_debug || epoxy_has_gl_extension("GL_ARB_debug_output"))) { if (first_ctx) Log(" gl: Setting OpenGLDebugProc callback"); - glDebugMessageCallbackARB(&OpenGLDebugProc, nullptr); - glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); -#ifdef GL_KHR_debug - if (GLEW_KHR_debug) + glDebugMessageCallback(&OpenGLDebugProc, nullptr); + glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); + if (has_khr_debug) glEnable(GL_DEBUG_OUTPUT); -#endif } // First context: Log some information about hardware/drivers // Must log after context creation to get valid results @@ -317,7 +311,7 @@ CStdGLCtx *CStdGL::CreateContext(C4Window * pWindow, C4AbstractApp *pApp) if (Config.Graphics.DebugOpenGL) { // Dump extension list - if (glGetStringi) + if (epoxy_is_desktop_gl() && epoxy_gl_version() >= 30) { GLint gl_extension_count = 0; glGetIntegerv(GL_NUM_EXTENSIONS, &gl_extension_count); @@ -342,10 +336,6 @@ CStdGLCtx *CStdGL::CreateContext(C4Window * pWindow, C4AbstractApp *pApp) } } } - if (!success) - { - delete pCtx; Error(" gl: Error creating secondary context!"); return NULL; - } // creation selected the new context - switch back to previous context RenderTarget = NULL; pCurrCtx = NULL; diff --git a/src/graphics/C4DrawGL.h b/src/graphics/C4DrawGL.h index 1a0642e0d..6f6227f60 100644 --- a/src/graphics/C4DrawGL.h +++ b/src/graphics/C4DrawGL.h @@ -24,7 +24,7 @@ #include #endif -#include +#include #ifdef USE_COCOA #import "ObjectiveCAssociated.h" @@ -206,6 +206,8 @@ protected: std::set VAOIDs; std::set::iterator NextVAOID; + bool has_khr_debug; + public: // Create a new (unique) VAO ID. A VAO ID is a number that identifies // a certain VAO across all OpenGL contexts. This indirection is needed diff --git a/src/graphics/C4DrawGLCtx.cpp b/src/graphics/C4DrawGLCtx.cpp index a8b6cd01f..18f388fcc 100644 --- a/src/graphics/C4DrawGLCtx.cpp +++ b/src/graphics/C4DrawGLCtx.cpp @@ -57,7 +57,7 @@ void CStdGLCtx::SelectCommon() #ifdef USE_WGL -#include +#include static PIXELFORMATDESCRIPTOR pfd; // desired pixel format static HGLRC hrc = 0; @@ -70,7 +70,7 @@ static HGLRC hrc = 0; static std::vector EnumeratePixelFormats(HDC hdc) { std::vector result; - if(!wglGetPixelFormatAttribivARB) return result; + if(!epoxy_has_wgl_extension(hdc, "WGL_ARB_pixel_format")) return result; int n_formats; int attributes = WGL_NUMBER_PIXEL_FORMATS_ARB; @@ -262,14 +262,6 @@ bool CStdGLCtx::Init(C4Window * pWindow, C4AbstractApp *pApp) try { tempContext.reset(new GLTempContext); - glewExperimental = GL_TRUE; - GLenum err = glewInit(); - if(err != GLEW_OK) - { - // Problem: glewInit failed, something is seriously wrong. - pGL->Error(reinterpret_cast(glewGetErrorString(err))); - return false; - } } catch (const WinAPIError &e) { @@ -318,7 +310,7 @@ bool CStdGLCtx::Init(C4Window * pWindow, C4AbstractApp *pApp) else { // create context - if (wglCreateContextAttribsARB) + if (epoxy_has_wgl_extension(hDC, "WGL_ARB_create_context")) { const int attribs[] = { WGL_CONTEXT_FLAGS_ARB, Config.Graphics.DebugOpenGL ? WGL_CONTEXT_DEBUG_BIT_ARB : 0, @@ -348,17 +340,6 @@ bool CStdGLCtx::Init(C4Window * pWindow, C4AbstractApp *pApp) if (hrc) { Select(); - // After selecting the new context, we have to reinitialize GLEW to - // update its function pointers - the driver may elect to expose - // different extensions depending on the context attributes - glewExperimental = GL_TRUE; - GLenum err = glewInit(); - if (err != GLEW_OK) - { - // Uh. This is a problem. - pGL->Error(reinterpret_cast(glewGetErrorString(err))); - return false; - } this_context = contexts.insert(contexts.end(), this); return true; @@ -370,6 +351,7 @@ bool CStdGLCtx::Init(C4Window * pWindow, C4AbstractApp *pApp) std::vector CStdGLCtx::EnumerateMultiSamples() const { + assert(hrc != 0); std::vector result; std::vector vec = EnumeratePixelFormats(hDC); for(unsigned int i = 0; i < vec.size(); ++i) @@ -422,20 +404,10 @@ bool CStdGLCtx::PageFlip() } #elif defined(USE_GTK) -#include -#include +#include #include #include -namespace { -void InitGLXPointers() -{ - glXGetVisualFromFBConfig = (PFNGLXGETVISUALFROMFBCONFIGPROC)(glXGetProcAddress((const GLubyte*)"glXGetVisualFromFBConfig")); - glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC)(glXGetProcAddress((const GLubyte*)"glXChooseFBConfig")); - glXCreateNewContext = (PFNGLXCREATENEWCONTEXTPROC)(glXGetProcAddress((const GLubyte*)"glXCreateNewContext")); -} -} - CStdGLCtx::CStdGLCtx(): pWindow(0), ctx(0), this_context(contexts.end()) { } void CStdGLCtx::Clear(bool multisample_change) @@ -468,22 +440,6 @@ bool CStdGLCtx::Init(C4Window * pWindow, C4AbstractApp *) // store window this->pWindow = pWindow; Display * const dpy = gdk_x11_display_get_xdisplay(gdk_display_get_default()); - InitGLXPointers(); - if (!glXGetVisualFromFBConfig || !glXChooseFBConfig || !glXCreateNewContext) - { - return pGL->Error(" gl: Unable to retrieve GLX 1.4 entry points"); - } - XVisualInfo *vis_info = glXGetVisualFromFBConfig(dpy, pWindow->Info); - // Create base context so we can initialize GLEW - GLXContext dummy_ctx = glXCreateContext(dpy, vis_info, 0, True); - XFree(vis_info); - glXMakeCurrent(dpy, pWindow->renderwnd, dummy_ctx); - glewExperimental = GL_TRUE; - GLenum err = glewInit(); - if (err != GLEW_OK) - { - return pGL->Error((const char*)glewGetErrorString(err)); - } // Create Context with sharing (if this is the main context, our ctx will be 0, so no sharing) const int attribs[] = { @@ -495,7 +451,7 @@ bool CStdGLCtx::Init(C4Window * pWindow, C4AbstractApp *) }; GLXContext share_context = (pGL->pMainCtx != this) ? static_cast(pGL->pMainCtx->ctx) : 0; - if (glXCreateContextAttribsARB) + if (epoxy_has_glx_extension(dpy, gdk_x11_get_default_screen(), "GLX_ARB_create_context")) { int (*oldErrorHandler) (Display *, XErrorEvent *) = XSetErrorHandler(GLXErrorHandler); ctx = glXCreateContextAttribsARB(dpy, pWindow->Info, share_context, True, attribs); @@ -507,20 +463,9 @@ bool CStdGLCtx::Init(C4Window * pWindow, C4AbstractApp *) ctx = glXCreateNewContext(dpy, pWindow->Info, GLX_RGBA_TYPE, share_context, True); } - glXMakeCurrent(dpy, None, NULL); - glXDestroyContext(dpy, dummy_ctx); - // No luck? if (!ctx) return pGL->Error(" gl: Unable to create context"); if (!Select(true)) return pGL->Error(" gl: Unable to select context"); - // init extensions - glewExperimental = GL_TRUE; - err = glewInit(); - if (GLEW_OK != err) - { - // Problem: glewInit failed, something is seriously wrong. - return pGL->Error(reinterpret_cast(glewGetErrorString(err))); - } this_context = contexts.insert(contexts.end(), this); return true; @@ -600,14 +545,6 @@ bool CStdGLCtx::Init(C4Window * pWindow, C4AbstractApp *) ctx = SDL_GL_CreateContext(pWindow->window); // No luck at all? if (!Select(true)) return pGL->Error(" gl: Unable to select context"); - // init extensions - glewExperimental = GL_TRUE; - GLenum err = glewInit(); - if (GLEW_OK != err) - { - // Problem: glewInit failed, something is seriously wrong. - return pGL->Error(reinterpret_cast(glewGetErrorString(err))); - } this_context = contexts.insert(contexts.end(), this); return true; diff --git a/src/graphics/C4DrawGLMac.mm b/src/graphics/C4DrawGLMac.mm index 0164c123c..fd46fc703 100644 --- a/src/graphics/C4DrawGLMac.mm +++ b/src/graphics/C4DrawGLMac.mm @@ -588,14 +588,6 @@ bool CStdGLCtx::Init(C4Window * pWindow, C4AbstractApp *) setObjectiveCObject(ctx); // No luck at all? if (!Select(true)) return pGL->Error(" gl: Unable to select context"); - // init extensions - glewExperimental = GL_TRUE; // Init GL 3.0+ function pointers - GLenum err = glewInit(); - if (GLEW_OK != err) - { - // Problem: glewInit failed, something is seriously wrong. - return pGL->Error(reinterpret_cast(glewGetErrorString(err))); - } // set the openglview's context auto controller = pWindow->objectiveCObject(); if (controller && controller.openGLView) diff --git a/src/graphics/C4Shader.h b/src/graphics/C4Shader.h index edfbbf795..867181679 100644 --- a/src/graphics/C4Shader.h +++ b/src/graphics/C4Shader.h @@ -22,11 +22,7 @@ #include "StdMeshMath.h" #include "C4Surface.h" -#ifdef _WIN32 -#include -#endif - -#include +#include // Shader version const int C4Shader_Version = 150; // GLSL 1.50 / OpenGL 3.2 diff --git a/src/platform/C4AppDelegate+MainMenuActions.mm b/src/platform/C4AppDelegate+MainMenuActions.mm index 45bbd9674..66d56bb8e 100644 --- a/src/platform/C4AppDelegate+MainMenuActions.mm +++ b/src/platform/C4AppDelegate+MainMenuActions.mm @@ -13,13 +13,13 @@ * for the above references. */ -#include - #include #include #include #include +#include + #import "C4AppDelegate+MainMenuActions.h" #import "C4DrawGLMac.h" #import "C4EditorWindowController.h" diff --git a/src/platform/C4AppMac.mm b/src/platform/C4AppMac.mm index 459f844e3..2c750931f 100644 --- a/src/platform/C4AppMac.mm +++ b/src/platform/C4AppMac.mm @@ -16,14 +16,14 @@ // based on SDL implementation -#include -#include - #include +#include "C4App.h" + #include #include -#include "C4App.h" +#include + #import #ifndef USE_CONSOLE diff --git a/src/platform/C4WindowController.mm b/src/platform/C4WindowController.mm index 5f7e4f7d3..4fec6c82a 100644 --- a/src/platform/C4WindowController.mm +++ b/src/platform/C4WindowController.mm @@ -13,8 +13,6 @@ * for the above references. */ -#include - #include #include #include @@ -22,6 +20,8 @@ #include #include +#include + #import "C4WindowController.h" #import "C4DrawGLMac.h" #import "C4EditorWindowController.h" diff --git a/src/platform/C4WindowGTK.cpp b/src/platform/C4WindowGTK.cpp index 157ac4cb0..a3b539315 100644 --- a/src/platform/C4WindowGTK.cpp +++ b/src/platform/C4WindowGTK.cpp @@ -42,7 +42,7 @@ #ifdef GDK_WINDOWING_X11 #include #include -#include +#include // Some helper functions for choosing a proper visual diff --git a/tools/osx_bundle_libs b/tools/osx_bundle_libs index 548a48826..1f3689f69 100755 --- a/tools/osx_bundle_libs +++ b/tools/osx_bundle_libs @@ -23,7 +23,7 @@ _otool="${OTOOL:-otool}" _install_name_tool="${INSTALL_NAME_TOOL:-install_name_tool}" # This regexp should match every lib we want to bundle. -_libs_to_bundle=".*?/lib(jpeg|GLEW|llvm|SDL|SDL_mixer|freetype|ogg|vorbis|vorbisfile|z\.|png[0-9]*|alut)\.[^ ]+\.dylib" +_libs_to_bundle=".*?/lib(jpeg|epoxy|llvm|SDL|SDL_mixer|freetype|ogg|vorbis|vorbisfile|z\.|png[0-9]*|alut)\.[^ ]+\.dylib" if [ -n "${TARGET_BUILD_DIR}" ]; then cd "${TARGET_BUILD_DIR}"