]> git.cworth.org Git - apitrace/commitdiff
Basic MacOSX tracing support (WIP).
authorJosé Fonseca <jose.r.fonseca@gmail.com>
Sun, 15 May 2011 11:56:59 +0000 (12:56 +0100)
committerJosé Fonseca <jose.r.fonseca@gmail.com>
Sun, 15 May 2011 11:56:59 +0000 (12:56 +0100)
CMakeLists.txt
README
cglapi.py [new file with mode: 0644]
cgltrace.py [new file with mode: 0644]
glimports.hpp
glproc.py

index f76444c08e1521972dfc39f02d5adcd922d4127c..4950f0ebe19ac6c2b6fd6f6b0756197b06835fd6 100755 (executable)
@@ -150,7 +150,7 @@ endif (PNG_FOUND)
 add_custom_command (
     OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/glproc.hpp
     COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/glproc.py > ${CMAKE_CURRENT_BINARY_DIR}/glproc.hpp
-    DEPENDS glproc.py dispatch.py wglapi.py glxapi.py glapi.py gltypes.py stdapi.py
+    DEPENDS glproc.py dispatch.py wglapi.py glxapi.py cglapi.py glapi.py gltypes.py stdapi.py
 )
 
 if (WIN32)
@@ -237,6 +237,37 @@ if (WIN32)
     endif (MINGW)
     install (TARGETS wgltrace RUNTIME DESTINATION wrappers)
 
+elseif (APPLE)
+    include_directories (${X11_INCLUDE_DIR})
+
+    # libGL.dylib
+    add_custom_command (
+        OUTPUT cgltrace.cpp
+        COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/cgltrace.py > ${CMAKE_CURRENT_BINARY_DIR}/cgltrace.cpp
+        DEPENDS cgltrace.py gltrace.py trace.py glxapi.py glapi.py glparams.py gltypes.py stdapi.py
+    )
+
+    add_library (cgltrace SHARED cgltrace.cpp trace_write.cpp os_posix.cpp ${CMAKE_CURRENT_BINARY_DIR}/glproc.hpp)
+
+    set_target_properties (cgltrace PROPERTIES
+        # libGL.dylib
+        OUTPUT_NAME GL
+        # match the version
+        LINK_FLAGS "-compatibility_version 1 -current_version 1.0.0"
+        RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
+        LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
+    )
+
+    target_link_libraries (cgltrace dl)
+
+    # Symbolic link from system's libGL.dylib
+    add_custom_command (
+        OUTPUT ${PROJECT_BINARY_DIR}/wrappers/libGL.system.dylib
+        COMMAND ln -sf /System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib ${PROJECT_BINARY_DIR}/wrappers/libGL.system.dylib
+        DEPENDS cgltrace
+    )
+
+    install (TARGETS cgltrace LIBRARY DESTINATION lib)
 else ()
     include_directories (${X11_INCLUDE_DIR})
 
@@ -256,11 +287,9 @@ else ()
 
     # Prevent symbol relocations internal to our wrapper library to be
     # overwritten by the application.
-    if (NOT APPLE)
-        set_target_properties (glxtrace PROPERTIES
-            LINK_FLAGS "-Wl,-Bsymbolic -Wl,-Bsymbolic-functions"
-        )
-    endif (NOT APPLE)
+    set_target_properties (glxtrace PROPERTIES
+        LINK_FLAGS "-Wl,-Bsymbolic -Wl,-Bsymbolic-functions"
+    )
 
     target_link_libraries (glxtrace dl)
     
diff --git a/README b/README
index 11a47eafd436d20b54fbd688b3f325c908db6aec..0e9ade3bf997c7104f87373e06d0e8c4a88411fb 100644 (file)
--- a/README
+++ b/README
@@ -20,7 +20,7 @@ Requirements to build the GUI (optional):
 * QJSON (tested with version 0.7.1)
 
 
-== Linux ==
+== Linux / Mac OS X ==
 
 Build as:
 
@@ -101,6 +101,22 @@ LD_LIBRARY_PATH:
   export TRACE_LIBGL=/path/to/real/libGL.so.1
   /path/to/application
 
+See the 'ld.so' man page for more information about LD_PRELOAD and
+LD_LIBRARY_PATH environment flags.
+
+
+== Mac OS X ==
+
+Usage on Mac OS X is similar to Linux above, except for the tracing procedure,
+which is instead:
+
+  DYLD_LIBRARY_PATH=/path/to/apitrace/wrappers /path/to/application
+
+Note that although Mac OS X has an LD_PRELOAD equivalent,
+DYLD_INSERT_LIBRARIES, it is mostly useless because it only works with
+DYLD_FORCE_FLAT_NAMESPACE=1 which breaks most applications.  See the 'dyld' man
+page for more details about these environment flags.
+
 
 == Windows ==
 
diff --git a/cglapi.py b/cglapi.py
new file mode 100644 (file)
index 0000000..29ae783
--- /dev/null
+++ b/cglapi.py
@@ -0,0 +1,63 @@
+##########################################################################
+#
+# Copyright 2008-2009 VMware, Inc.
+# All Rights Reserved.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+##########################################################################/
+
+"""CGL API description."""
+
+
+from stdapi import *
+from glapi import glapi
+
+
+CGLError = Enum("CGLError", [
+    "kCGLNoError",     # 0     
+    "kCGLBadAttribute",        # 10000 
+    "kCGLBadProperty", # 10001 
+    "kCGLBadPixelFormat",      # 10002 
+    "kCGLBadRendererInfo",     # 10003 
+    "kCGLBadContext",  # 10004 
+    "kCGLBadDrawable", # 10005 
+    "kCGLBadDisplay",  # 10006 
+    "kCGLBadState",    # 10007 
+    "kCGLBadValue",    # 10008 
+    "kCGLBadMatch",    # 10009 
+    "kCGLBadEnumeration",      # 10010 
+    "kCGLBadOffScreen",        # 10011 
+    "kCGLBadFullScreen",       # 10012 
+    "kCGLBadWindow",   # 10013 
+    "kCGLBadAddress",  # 10014 
+    "kCGLBadCodeModule",       # 10015 
+    "kCGLBadAlloc",    # 10016 
+    "kCGLBadConnection",       # 10017 
+])
+
+CGLContextObj = Opaque("CGLContextObj")
+
+cglapi = API("CGL")
+
+cglapi.add_functions([
+    Function(CGLError, "CGLSetCurrentContext", [(CGLContextObj, "ctx")]),
+    Function(CGLContextObj, "CGLGetCurrentContext", []),
+])
+
diff --git a/cgltrace.py b/cgltrace.py
new file mode 100644 (file)
index 0000000..33765f9
--- /dev/null
@@ -0,0 +1,115 @@
+##########################################################################
+#
+# Copyright 2011 VMware, Inc.
+# All Rights Reserved.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+##########################################################################/
+
+
+"""Cgl tracing generator."""
+
+
+from stdapi import API
+from glapi import glapi
+from cglapi import cglapi
+from gltrace import GlTracer
+
+
+class CglTracer(GlTracer):
+
+    def is_public_function(self, function):
+        # The symbols visible in libGL.dylib can vary, so expose them all
+        return True
+
+
+if __name__ == '__main__':
+    print
+    print '#include <stdlib.h>'
+    print '#include <string.h>'
+    print
+    print '#ifndef _GNU_SOURCE'
+    print '#define _GNU_SOURCE // for dladdr'
+    print '#endif'
+    print '#include <dlfcn.h>'
+    print
+    print '#include "trace_write.hpp"'
+    print
+    print '// To validate our prototypes'
+    print '#define GL_GLEXT_PROTOTYPES'
+    print
+    print '#include "glproc.hpp"'
+    print '#include "glsize.hpp"'
+    print
+
+    api = API()
+    api.add_api(cglapi)
+    api.add_api(glapi)
+    tracer = CglTracer()
+    tracer.trace_api(api)
+
+    print r'''
+
+
+/*
+ * Handle to the true libGL.so
+ */
+static void *libgl_handle = NULL;
+
+
+/*
+ * Lookup a libGL symbol
+ */
+static void * __dlsym(const char *symbol)
+{
+    void *result;
+    if (!libgl_handle) {
+        const char * libgl_filename;
+
+        /* 
+         * Unfortunately we can't just dlopen
+         * /System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib
+         * because DYLD_LIBRARY_PATH takes precedence, even for absolute paths.
+         */
+        libgl_filename = "libGL.system.dylib";
+
+        libgl_handle = dlopen(libgl_filename, RTLD_LOCAL | RTLD_NOW | RTLD_FIRST);
+        if (!libgl_handle) {
+            OS::DebugMessage("error: couldn't load %s\n", libgl_filename);
+            return NULL;
+        }
+    }
+
+    result = dlsym(libgl_handle, symbol);
+
+    if (result == dlsym(RTLD_SELF, symbol)) {
+        OS::DebugMessage("error: symbol lookup recursion\n");
+        OS::Abort();
+        return NULL;
+    }
+
+    return result;
+}
+
+
+PUBLIC
+void * gll_noop = 0;
+
+'''
index 5e8993816a99274c3777784729d6297bd69932b3..720e48a105b93bb54563b8dfcc951386118fcb9d 100644 (file)
@@ -93,4 +93,10 @@ typedef struct _WGLSWAP
 
 #endif /* !_WIN32 */
 
+#ifdef __APPLE__
+
+#include <OpenGL/CGLCurrent.h>
+
+#endif /* __APPLE__ */
+
 #endif /* _GLIMPORTS_HPP_ */
index 29031b7002798c70da499d5b51ff2e0bbeb2b482..067017b7f9bdf9a89deb327ec21fde385fed48d8 100644 (file)
--- a/glproc.py
+++ b/glproc.py
@@ -34,6 +34,7 @@ from dispatch import Dispatcher
 from glapi import glapi
 from glxapi import glxapi
 from wglapi import wglapi
+from cglapi import cglapi
 
 
 # See http://www.opengl.org/registry/ABI/
@@ -422,9 +423,13 @@ class GlDispatcher(Dispatcher):
         print '     static inline PROC __stdcall __wglGetProcAddress(const char * lpszProc);'
         print '#  else'
         print '#    define __getPublicProcAddress(name) __dlsym(name)'
-        print '#    define __getPrivateProcAddress(name) __glXGetProcAddressARB((const GLubyte *)(name))'
         print '     static void * __dlsym(const char *symbol);'
-        print '     static inline __GLXextFuncPtr __glXGetProcAddressARB(const GLubyte * procName);'
+        print '#    ifdef __APPLE__'
+        print '#      define __getPrivateProcAddress(name) __getPublicProcAddress(name)'
+        print '#    else'
+        print '#      define __getPrivateProcAddress(name) __glXGetProcAddressARB((const GLubyte *)(name))'
+        print '       static inline __GLXextFuncPtr __glXGetProcAddressARB(const GLubyte * procName);'
+        print '#    endif'
         print '#  endif'
         print '#  define __abort() Trace::Abort()'
         print '#endif /* !RETRACE */'
@@ -453,6 +458,10 @@ if __name__ == '__main__':
     dispatcher.dispatch_api(glxapi)
     print '#endif /* !_WIN32 */'
     print
+    print '#ifdef __APPLE__'
+    dispatcher.dispatch_api(cglapi)
+    print '#endif /* __APPLE__ */'
+    print
     dispatcher.dispatch_api(glapi)
     print
     print '#endif /* !_GLPROC_HPP_ */'