Browse Source

FindOpenGL: support finding GLES2 and GLES3

This also makes the EGL component not GLVND-specific, so documentation
and tests are updated accordingly.
Jaswant Panchumarti 2 years ago
parent
commit
beb0a56c86

+ 5 - 0
Help/release/dev/FindOpenGL-gles.rst

@@ -0,0 +1,5 @@
+FindOpenGL-gles
+---------------
+
+* The :module:`FindOpenGL` module gained support for components
+  ``GLES2`` and ``GLES3``.

+ 179 - 10
Modules/FindOpenGL.cmake

@@ -18,8 +18,26 @@ Optional COMPONENTS
 
 .. versionadded:: 3.10
 
-This module respects several optional COMPONENTS: ``EGL``, ``GLX``, and
-``OpenGL``.  There are corresponding import targets for each of these flags.
+This module respects several optional COMPONENTS:
+
+``EGL``
+  The EGL interface between OpenGL, OpenGL ES and the underlying windowing system.
+
+``GLX``
+  An extension to X that interfaces OpenGL, OpenGL ES with X window system.
+
+``OpenGL``
+  The cross platform API for 3D graphics.
+
+``GLES2``
+  .. versionadded:: 3.27
+
+  A subset of OpenGL API for embedded systems with limited capabilities.
+
+``GLES3``
+  .. versionadded:: 3.27
+
+  A subset of OpenGL API for embedded systems with more capabilities.
 
 IMPORTED Targets
 ^^^^^^^^^^^^^^^^
@@ -42,6 +60,14 @@ This module defines the :prop_tgt:`IMPORTED` targets:
   Defined if the system has OpenGL Extension to the X Window System (GLX).
 ``OpenGL::EGL``
   Defined if the system has EGL.
+``OpenGL::GLES2``
+  .. versionadded:: 3.27
+
+  Defined if the system has GLES2.
+``OpenGL::GLES3``
+  .. versionadded:: 3.27
+
+  Defined if the system has GLES3.
 
 Result Variables
 ^^^^^^^^^^^^^^^^
@@ -60,6 +86,10 @@ This module sets the following variables:
  True, if the system has GLX.
 ``OpenGL_EGL_FOUND``
  True, if the system has EGL.
+``OpenGL::GLES2``
+ Defined if the system has GLES2.
+``OpenGL::GLES3``
+ Defined if the system has GLES3.
 ``OPENGL_INCLUDE_DIR``
  Path to the OpenGL include directory.
 ``OPENGL_EGL_INCLUDE_DIRS``
@@ -88,6 +118,14 @@ The following cache variables may also be set:
 ``OPENGL_gl_LIBRARY``
  Path to the OpenGL library.  New code should prefer the ``OpenGL::*`` import
  targets.
+``OPENGL_gles2_LIBRARY``
+  .. versionadded:: 3.27
+
+  Path to the OpenGL GLES2 library.
+``OPENGL_gles3_LIBRARY``
+  .. versionadded:: 3.27
+
+  Path to the OpenGL GLES3 library.
 
 .. versionadded:: 3.10
   Variables for GLVND-specific libraries ``OpenGL``, ``EGL`` and ``GLX``.
@@ -182,7 +220,10 @@ elseif (APPLE)
     OPENGL_glu_LIBRARY
     )
 else()
-  if (CMAKE_SYSTEM_NAME MATCHES "HP-UX")
+  if (CMAKE_ANDROID_NDK)
+    set(_OPENGL_INCLUDE_PATH ${CMAKE_ANDROID_NDK}/sysroot/usr/include)
+    set(_OPENGL_LIB_PATH ${CMAKE_ANDROID_NDK}/platforms/android-${CMAKE_SYSTEM_VERSION}/arch-${CMAKE_ANDROID_ARCH}/usr/lib)
+  elseif (CMAKE_SYSTEM_NAME MATCHES "HP-UX")
     # Handle HP-UX cases where we only want to find OpenGL in either hpux64
     # or hpux32 depending on if we're doing a 64 bit build.
     if(CMAKE_SIZEOF_VOID_P EQUAL 4)
@@ -198,6 +239,13 @@ else()
       /boot/develop/lib/x86)
     set(_OPENGL_INCLUDE_PATH
       /boot/develop/headers/os/opengl)
+  elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux")
+    # CMake doesn't support arbitrary globs in search paths.
+    file(GLOB _OPENGL_LIB_PATH
+      # The NVidia driver installation tool on Linux installs libraries to a
+      # `nvidia-<version>` subdirectory.
+      "/usr/lib/nvidia-*"
+      "/usr/lib32/nvidia-*")
   endif()
 
   # The first line below is to make sure that the proper headers
@@ -215,15 +263,20 @@ else()
   )
   find_path(OPENGL_GLX_INCLUDE_DIR GL/glx.h ${_OPENGL_INCLUDE_PATH})
   find_path(OPENGL_EGL_INCLUDE_DIR EGL/egl.h ${_OPENGL_INCLUDE_PATH})
+  find_path(OPENGL_GLES2_INCLUDE_DIR GLES2/gl2.h ${_OPENGL_INCLUDE_PATH})
+  find_path(OPENGL_GLES3_INCLUDE_DIR GLES3/gl3.h ${_OPENGL_INCLUDE_PATH})
   find_path(OPENGL_xmesa_INCLUDE_DIR GL/xmesa.h
     /usr/share/doc/NVIDIA_GLX-1.0/include
     /usr/openwin/share/include
     /opt/graphics/OpenGL/include
   )
+
   list(APPEND _OpenGL_CACHE_VARS
     OPENGL_INCLUDE_DIR
     OPENGL_GLX_INCLUDE_DIR
     OPENGL_EGL_INCLUDE_DIR
+    OPENGL_GLES2_INCLUDE_DIR
+    OPENGL_GLES3_INCLUDE_DIR
     OPENGL_xmesa_INCLUDE_DIR
     )
 
@@ -246,6 +299,17 @@ else()
     PATH_SUFFIXES libglvnd
   )
 
+  find_library(OPENGL_gles2_LIBRARY
+    NAMES GLESv2
+    PATHS ${_OPENGL_LIB_PATH}
+  )
+
+  find_library(OPENGL_gles3_LIBRARY
+    NAMES GLESv3
+          GLESv2 # mesa provides only libGLESv2
+    PATHS ${_OPENGL_LIB_PATH}
+  )
+
   find_library(OPENGL_glu_LIBRARY
     NAMES GLU MesaGLU
     PATHS ${OPENGL_gl_LIBRARY}
@@ -258,6 +322,8 @@ else()
     OPENGL_opengl_LIBRARY
     OPENGL_glx_LIBRARY
     OPENGL_egl_LIBRARY
+    OPENGL_gles2_LIBRARY
+    OPENGL_gles3_LIBRARY
     OPENGL_glu_LIBRARY
     )
 
@@ -338,12 +404,16 @@ else()
           OPENGL_glx_LIBRARY AND
       NOT OPENGL_gl_LIBRARY) OR
      (NOT OPENGL_USE_EGL AND
+      NOT OPENGL_USE_GLES3 AND
+      NOT OPENGL_USE_GLES2 AND
       NOT OPENGL_glx_LIBRARY AND
       NOT OPENGL_gl_LIBRARY) OR
      (NOT OPENGL_USE_EGL AND
           OPENGL_opengl_LIBRARY AND
           OPENGL_glx_LIBRARY) OR
-     (    OPENGL_USE_EGL))
+     (NOT OPENGL_USE_GLES3 AND
+      NOT OPENGL_USE_GLES2 AND
+          OPENGL_USE_EGL))
     list(APPEND _OpenGL_REQUIRED_VARS OPENGL_opengl_LIBRARY)
   endif()
 
@@ -351,13 +421,19 @@ else()
   if((NOT OPENGL_USE_OPENGL AND
       NOT OPENGL_USE_GLX AND
       NOT OPENGL_USE_EGL AND
+      NOT OPENGL_USE_GLES3 AND
+      NOT OPENGL_USE_GLES2 AND
       NOT OPENGL_glx_LIBRARY AND
       NOT OPENGL_gl_LIBRARY) OR
      (    OPENGL_USE_GLX AND
       NOT OPENGL_USE_EGL AND
+      NOT OPENGL_USE_GLES3 AND
+      NOT OPENGL_USE_GLES2 AND
       NOT OPENGL_glx_LIBRARY AND
       NOT OPENGL_gl_LIBRARY) OR
      (NOT OPENGL_USE_EGL AND
+      NOT OPENGL_USE_GLES3 AND
+      NOT OPENGL_USE_GLES2 AND
           OPENGL_opengl_LIBRARY AND
           OPENGL_glx_LIBRARY) OR
      (OPENGL_USE_GLX AND OPENGL_USE_EGL))
@@ -369,6 +445,16 @@ else()
     list(APPEND _OpenGL_REQUIRED_VARS OPENGL_egl_LIBRARY)
   endif()
 
+  # GLVND GLES2 library.
+  if(OPENGL_USE_GLES2)
+    list(APPEND _OpenGL_REQUIRED_VARS OPENGL_gles2_LIBRARY)
+  endif()
+
+  # GLVND GLES3 library.
+  if(OPENGL_USE_GLES3)
+    list(APPEND _OpenGL_REQUIRED_VARS OPENGL_gles3_LIBRARY)
+  endif()
+
   # Old-style "libGL" library: used as a fallback when GLVND isn't available.
   if((NOT OPENGL_USE_EGL AND
       NOT OPENGL_opengl_LIBRARY AND
@@ -381,7 +467,11 @@ else()
   endif()
 
   # We always need the 'gl.h' include dir.
-  list(APPEND _OpenGL_REQUIRED_VARS OPENGL_INCLUDE_DIR)
+  if(OPENGL_USE_EGL)
+    list(APPEND _OpenGL_REQUIRED_VARS OPENGL_EGL_INCLUDE_DIR)
+  else()
+    list(APPEND _OpenGL_REQUIRED_VARS OPENGL_INCLUDE_DIR)
+  endif()
 
   unset(_OPENGL_INCLUDE_PATH)
   unset(_OPENGL_LIB_PATH)
@@ -428,6 +518,18 @@ else()
   set(OpenGL_EGL_FOUND FALSE)
 endif()
 
+if(OPENGL_gles2_LIBRARY AND OPENGL_GLES2_INCLUDE_DIR)
+  set(OpenGL_GLES2_FOUND TRUE)
+else()
+  set(OpenGL_GLES2_FOUND FALSE)
+endif()
+
+if(OPENGL_gles3_LIBRARY AND OPENGL_GLES3_INCLUDE_DIR)
+  set(OpenGL_GLES3_FOUND TRUE)
+else()
+  set(OpenGL_GLES3_FOUND FALSE)
+endif()
+
 # User-visible names should be plural.
 if(OPENGL_EGL_INCLUDE_DIR)
   set(OPENGL_EGL_INCLUDE_DIRS ${OPENGL_EGL_INCLUDE_DIR})
@@ -461,6 +563,7 @@ if(OPENGL_FOUND)
     endif()
     set_target_properties(OpenGL::OpenGL PROPERTIES INTERFACE_INCLUDE_DIRECTORIES
                           "${OPENGL_INCLUDE_DIR}")
+    set(_OpenGL_EGL_IMPL OpenGL::OpenGL)
   endif()
 
   # ::GLX is a GLVND library, and thus Linux-only: we don't bother checking
@@ -481,6 +584,73 @@ if(OPENGL_FOUND)
                           "${OPENGL_GLX_INCLUDE_DIR}")
   endif()
 
+  # ::GLES2 is a GLVND library, and thus Linux-only: we don't bother checking
+  # for a framework version of this library.
+  if(OpenGL_GLES2_FOUND AND NOT TARGET OpenGL::GLES2)
+
+    # Initialize target
+    if(NOT OPENGL_gles2_LIBRARY)
+      add_library(OpenGL::GLES2 INTERFACE IMPORTED)
+    else()
+      if(IS_ABSOLUTE "${OPENGL_gles2_LIBRARY}")
+        add_library(OpenGL::GLES2 UNKNOWN IMPORTED)
+        set_target_properties(OpenGL::GLES2 PROPERTIES
+          IMPORTED_LOCATION "${OPENGL_gles2_LIBRARY}"
+        )
+      else()
+        add_library(OpenGL::GLES2 INTERFACE IMPORTED)
+        set_target_properties(OpenGL::GLES2 PROPERTIES
+          IMPORTED_LIBNAME "${OPENGL_gles2_LIBRARY}"
+        )
+      endif()
+    endif()
+
+    # Attach target properties
+    set_target_properties(OpenGL::GLES2
+      PROPERTIES
+        INTERFACE_INCLUDE_DIRECTORIES
+          "${OPENGL_GLES2_INCLUDE_DIR}"
+    )
+
+    if (OPENGL_USE_GLES2)
+      set(_OpenGL_EGL_IMPL OpenGL::GLES2)
+    endif ()
+
+  endif()
+
+  # ::GLES3 is a GLVND library, and thus Linux-only: we don't bother checking
+  # for a framework version of this library.
+  if(OpenGL_GLES3_FOUND AND NOT TARGET OpenGL::GLES3)
+
+    # Initialize target
+    if(NOT OPENGL_gles3_LIBRARY)
+      add_library(OpenGL::GLES3 INTERFACE IMPORTED)
+    else()
+      if(IS_ABSOLUTE "${OPENGL_gles3_LIBRARY}")
+        add_library(OpenGL::GLES3 UNKNOWN IMPORTED)
+        set_target_properties(OpenGL::GLES3 PROPERTIES
+          IMPORTED_LOCATION "${OPENGL_gles3_LIBRARY}"
+        )
+      else()
+        add_library(OpenGL::GLES3 INTERFACE IMPORTED)
+        set_target_properties(OpenGL::GLES3 PROPERTIES
+          IMPORTED_LIBNAME "${OPENGL_gles3_LIBRARY}"
+        )
+      endif()
+    endif()
+
+    # Attach target properties
+    set_target_properties(OpenGL::GLES3 PROPERTIES
+      INTERFACE_INCLUDE_DIRECTORIES
+        "${OPENGL_GLES3_INCLUDE_DIR}"
+    )
+
+    if (OPENGL_USE_GLES3)
+      set(_OpenGL_EGL_IMPL OpenGL::GLES3)
+    endif ()
+
+  endif()
+
   if(OPENGL_gl_LIBRARY AND NOT TARGET OpenGL::GL)
     # A legacy GL library is available, so use it for the legacy GL target.
     if(IS_ABSOLUTE "${OPENGL_gl_LIBRARY}")
@@ -517,10 +687,9 @@ if(OPENGL_FOUND)
 
   # ::EGL is a GLVND library, and thus Linux-only: we don't bother checking
   # for a framework version of this library.
-  # Note we test for OpenGL::OpenGL as a target.  When this module is updated to
-  # support GLES, we would additionally want to check for the hypothetical GLES
-  # target and enable EGL if either ::GLES or ::OpenGL is created.
-  if(TARGET OpenGL::OpenGL AND OpenGL_EGL_FOUND AND NOT TARGET OpenGL::EGL)
+  # Note we test whether _OpenGL_EGL_IMPL is set. Based on the OpenGL implementation,
+  # _OpenGL_EGL_IMPL will be one of OpenGL::OpenGL, OpenGL::GLES2, OpenGL::GLES3
+  if(_OpenGL_EGL_IMPL AND OpenGL_EGL_FOUND AND NOT TARGET OpenGL::EGL)
     if(IS_ABSOLUTE "${OPENGL_egl_LIBRARY}")
       add_library(OpenGL::EGL UNKNOWN IMPORTED)
       set_target_properties(OpenGL::EGL PROPERTIES IMPORTED_LOCATION
@@ -531,7 +700,7 @@ if(OPENGL_FOUND)
                             "${OPENGL_egl_LIBRARY}")
     endif()
     set_target_properties(OpenGL::EGL PROPERTIES INTERFACE_LINK_LIBRARIES
-                          OpenGL::OpenGL)
+                          "${_OpenGL_EGL_IMPL}")
     # Note that EGL's include directory is different from OpenGL/GLX's!
     set_target_properties(OpenGL::EGL PROPERTIES INTERFACE_INCLUDE_DIRECTORIES
                           "${OPENGL_EGL_INCLUDE_DIR}")

+ 108 - 21
Tests/FindOpenGL/Test/CMakeLists.txt

@@ -44,28 +44,115 @@ else()
   add_test(NAME test_comp_glx_novnd COMMAND test_comp_glx_novnd)
 endif()
 
-# EGL is only available on Linux+GLVND at present.
-if(OpenGL_TEST_VND)
-  find_package(OpenGL COMPONENTS OpenGL EGL)
-  if(OpenGL_EGL_FOUND)
-    add_executable(test_comp_egl main.c)
-    target_link_libraries(test_comp_egl PRIVATE OpenGL::OpenGL OpenGL::EGL)
-    add_test(NAME test_comp_egl COMMAND test_comp_egl)
-    # EGL-only code should not link to GLX.
-    execute_process(COMMAND ldd test_comp_egl
-                    OUTPUT_VARIABLE LDD_OUT
-                    ERROR_VARIABLE LDD_ERR)
-    if("${LDD_OUT}" MATCHES "GLX")
-      message(FATAL_ERROR "EGL-only code links to GLX!")
-    endif()
+find_package(OpenGL COMPONENTS OpenGL EGL)
+if(OpenGL_EGL_FOUND)
+  add_executable(test_comp_egl main.c)
+  target_link_libraries(test_comp_egl PRIVATE OpenGL::OpenGL OpenGL::EGL)
+  add_test(NAME test_comp_egl COMMAND test_comp_egl)
+  # EGL-only code should not link to GLX.
+  get_target_property(iface_libs OpenGL::EGL INTERFACE_LINK_LIBRARIES)
+  if(iface_libs MATCHES "GLX")
+    message(FATAL_ERROR "EGL-only code links to GLX!")
+  endif()
+endif()
+
+# all three COMPONENTS together.
+find_package(OpenGL COMPONENTS OpenGL EGL GLX)
+if(OpenGL_EGL_FOUND AND OpenGL_GLX_FOUND)
+  add_executable(test_comp_both main.c)
+  target_link_libraries(test_comp_both PRIVATE OpenGL::OpenGL OpenGL::EGL
+                        OpenGL::GLX)
+  add_test(NAME test_comp_both COMMAND test_comp_both)
+endif()
+
+find_package(OpenGL COMPONENTS GLES2)
+if(OpenGL_GLES2_FOUND)
+  add_executable(test_comp_gles2 main_gles2.c)
+  target_link_libraries(test_comp_gles2 PRIVATE OpenGL::GLES2)
+  add_test(NAME test_comp_gles2 COMMAND test_comp_gles2)
+  # GLES2-only code should not link to OpenGL
+  get_target_property(iface_libs test_comp_gles2 LINK_LIBRARIES)
+  if(iface_libs MATCHES "OpenGL::OpenGL")
+    message(FATAL_ERROR "GLES2-only code links to OpenGL!")
   endif()
+endif()
+
+# GLES2 and EGL together.
+find_package(OpenGL COMPONENTS GLES2 EGL)
+if(OpenGL_GLES2_FOUND AND OpenGL_EGL_FOUND)
+  add_executable(test_comp_gles2_egl main_gles2.c)
+  target_link_libraries(test_comp_gles2_egl PRIVATE OpenGL::GLES2
+                        OpenGL::EGL)
+  add_test(NAME test_comp_gles2_egl COMMAND test_comp_gles2_egl)
+  # GLES2-EGL-only code should not link to OpenGL or GLX
+  get_target_property(iface_libs test_comp_gles2_egl LINK_LIBRARIES)
+  if(iface_libs MATCHES "OpenGL::OpenGL")
+    message(FATAL_ERROR "GLES2-only code links to OpenGL!")
+  endif()
+  if(iface_libs MATCHES "GLX")
+    message(FATAL_ERROR "GLES2-EGL-only code links to GLX!")
+  endif()
+endif()
 
-  # all three COMPONENTS together.
-  find_package(OpenGL COMPONENTS OpenGL EGL GLX)
-  if(OpenGL_EGL_FOUND AND OpenGL_GLX_FOUND)
-    add_executable(test_comp_both main.c)
-    target_link_libraries(test_comp_both PRIVATE OpenGL::OpenGL OpenGL::EGL
-                          OpenGL::GLX)
-    add_test(NAME test_comp_both COMMAND test_comp_both)
+# GLES2 and GLX together.
+find_package(OpenGL COMPONENTS GLES2 GLX)
+if(OpenGL_GLES2_FOUND AND OpenGL_GLX_FOUND)
+  add_executable(test_comp_gles2_glx main_gles2.c)
+  target_link_libraries(test_comp_gles2_glx PRIVATE OpenGL::GLES2
+                        OpenGL::GLX)
+  add_test(NAME test_comp_gles2_glx COMMAND test_comp_gles2_glx)
+  # GLES2-GLX-only code should not link to OpenGL or EGL
+  get_target_property(iface_libs test_comp_gles2_glx LINK_LIBRARIES)
+  if(iface_libs MATCHES "OpenGL::OpenGL")
+    message(FATAL_ERROR "GLES2-only code links to OpenGL!")
+  endif()
+  if(iface_libs MATCHES "EGL")
+    message(FATAL_ERROR "GLES2-GLX-only code links to EGL!")
+  endif()
+endif()
+
+find_package(OpenGL COMPONENTS GLES3)
+if(OpenGL_GLES3_FOUND)
+  add_executable(test_comp_gles3 main_gles3.c)
+  target_link_libraries(test_comp_gles3 PRIVATE OpenGL::GLES3)
+  add_test(NAME test_comp_gles3 COMMAND test_comp_gles3)
+  # GLES3-only code should not link to OpenGL.
+  get_target_property(iface_libs test_comp_gles3 LINK_LIBRARIES)
+  if(iface_libs MATCHES "OpenGL::OpenGL")
+    message(FATAL_ERROR "GLES3-only code links to OpenGL!")
+  endif()
+endif()
+
+# GLES3 and EGL together.
+find_package(OpenGL COMPONENTS GLES3 EGL)
+if(OpenGL_GLES3_FOUND AND OpenGL_EGL_FOUND)
+  add_executable(test_comp_gles3_egl main_gles3.c)
+  target_link_libraries(test_comp_gles3_egl PRIVATE OpenGL::GLES3
+                        OpenGL::EGL)
+  add_test(NAME test_comp_gles3_egl COMMAND test_comp_gles3_egl)
+  # GLES3-EGL-only code should not link to OpenGL or GLX
+  get_target_property(iface_libs test_comp_gles3_egl LINK_LIBRARIES)
+  if(iface_libs MATCHES "OpenGL::OpenGL")
+    message(FATAL_ERROR "GLES3-only code links to OpenGL!")
+  endif()
+  if(iface_libs MATCHES "GLX")
+    message(FATAL_ERROR "GLES3-EGL-only code links to GLX!")
+  endif()
+endif()
+
+# GLES3 and GLX together.
+find_package(OpenGL COMPONENTS GLES3 GLX)
+if(OpenGL_GLES3_FOUND AND OpenGL_GLX_FOUND)
+  add_executable(test_comp_gles3_glx main_gles3.c)
+  target_link_libraries(test_comp_gles3_glx PRIVATE OpenGL::GLES3
+                        OpenGL::GLX)
+  add_test(NAME test_comp_gles3_glx COMMAND test_comp_gles3_glx)
+  # GLESr-GLX-only code should not link to OpenGL or EGL
+  get_target_property(iface_libs test_comp_gles3_glx LINK_LIBRARIES)
+  if(iface_libs MATCHES "OpenGL::OpenGL")
+    message(FATAL_ERROR "GLES3-only code links to OpenGL!")
+  endif()
+  if(iface_libs MATCHES "EGL")
+    message(FATAL_ERROR "GLES3-GLX-only code links to EGL!")
   endif()
 endif()

+ 17 - 0
Tests/FindOpenGL/Test/main_gles2.c

@@ -0,0 +1,17 @@
+#ifdef _WIN32
+#  error "GLES2 cannot be tested on WIN32 platforms."
+#endif
+#ifdef __APPLE__
+#  error "GLES2 cannot be tested on macOS platform."
+#else
+#  include <GLES2/gl2.h>
+#endif
+
+#include <stdio.h>
+
+int main()
+{
+  /* Reference a GL symbol without requiring a context at runtime.  */
+  printf("&glGetString = %p\n", &glGetString);
+  return 0;
+}

+ 17 - 0
Tests/FindOpenGL/Test/main_gles3.c

@@ -0,0 +1,17 @@
+#ifdef _WIN32
+#  error "GLES3 cannot be tested on WIN32 platforms."
+#endif
+#ifdef __APPLE__
+#  error "GLES3 cannot be tested on macOS platform."
+#else
+#  include <GLES3/gl3.h>
+#endif
+
+#include <stdio.h>
+
+int main()
+{
+  /* Reference a GL symbol without requiring a context at runtime.  */
+  printf("&glGetString = %p\n", &glGetString);
+  return 0;
+}