From 3144f287d1c1a241a49d8203f80cc23911c2d590 Mon Sep 17 00:00:00 2001 From: Kyle Brenneman Date: Tue, 7 Jun 2022 07:50:08 -0600 Subject: [PATCH] Read gl.symbols when generating stubs for libGL.so. Instead of generating symbols for everything in gl.xml, read the symbol list from src/GL/gl.symbols and only generate the functions listed there. That way, when new functions get added to gl.xml, we won't add any more symbols in libGL.so. To do that, if the target parameter to gen_gldispatch_mapi.py is a filename, then it will read that file for symbols instead of calling genCommon.getExportNamesFromRoots. Also added a new genCommon.readSymbolsFile function, which is mostly copied from symbols-check.py. --- src/GLdispatch/vnd-glapi/Makefile.am | 4 +-- src/generate/genCommon.py | 42 +++++++++++++++++++++++++++- src/generate/gen_gldispatch_mapi.py | 11 +++++++- src/generate/meson.build | 13 ++++++++- 4 files changed, 65 insertions(+), 5 deletions(-) diff --git a/src/GLdispatch/vnd-glapi/Makefile.am b/src/GLdispatch/vnd-glapi/Makefile.am index cd8cb65..154f8cc 100644 --- a/src/GLdispatch/vnd-glapi/Makefile.am +++ b/src/GLdispatch/vnd-glapi/Makefile.am @@ -82,8 +82,8 @@ libglapi_gl_la_CPPFLAGS = $(ENTRYPOINT_CPPFLAGS) \ noinst_HEADERS += g_glapi_mapi_gl_tmp.h if HAVE_PYTHON BUILT_SOURCES += g_glapi_mapi_gl_tmp.h -g_glapi_mapi_gl_tmp.h : $(glapi_gen_mapi_deps) - $(glapi_gen_mapi) gl $(glapi_gen_gl_xml) > $@ +g_glapi_mapi_gl_tmp.h : $(glapi_gen_mapi_deps) $(top_srcdir)/src/GL/gl.symbols + $(glapi_gen_mapi) $(top_srcdir)/src/GL/gl.symbols $(glapi_gen_gl_xml) > $@ endif noinst_LTLIBRARIES += libglapi_opengl.la diff --git a/src/generate/genCommon.py b/src/generate/genCommon.py index 5c38d87..86f4500 100644 --- a/src/generate/genCommon.py +++ b/src/generate/genCommon.py @@ -34,7 +34,6 @@ MAPI_TABLE_NUM_DYNAMIC = 4096 _LIBRARY_FEATURE_NAMES = { # libGL and libGLdiapatch both include every function. - "gl" : None, "gldispatch" : None, "opengl" : frozenset(( "GL_VERSION_1_0", "GL_VERSION_1_1", "GL_VERSION_1_2", "GL_VERSION_1_3", "GL_VERSION_1_4", "GL_VERSION_1_5", @@ -76,6 +75,47 @@ def getFunctionsFromRoots(roots): return functions +def readSymbolsFile(symbols_file): + """ + Returns the set of function names based on a list of symbols in a text + file. + """ + symbols = set() + with open(symbols_file) as f: + qualifier_optional = '(optional)' + for line in f.readlines(): + + # Strip comments + line = line.split('#')[0] + line = line.strip() + if not line: + continue + + # Line format: + # [qualifier] symbol + qualifier = None + symbol = None + + fields = line.split() + if len(fields) == 1: + symbol = fields[0] + elif len(fields) == 2: + qualifier = fields[0] + symbol = fields[1] + else: + raise ValueError(symbols_file + ': invalid format: ' + line) + + # The only supported qualifier is 'optional', which means the + # symbol doesn't have to be exported by the library + if qualifier and not qualifier == qualifier_optional: + raise ValueError(symbols_file + ': invalid qualifier: ' + qualifier) + + # For our purposes here, we expect generated functions to be + # mandatory symbols. + if qualifier != qualifier_optional: + symbols.add(symbol) + return symbols + def getExportNamesFromRoots(target, roots): """ Goes through the tags from gl.xml and returns a set of OpenGL diff --git a/src/generate/gen_gldispatch_mapi.py b/src/generate/gen_gldispatch_mapi.py index 8a037d5..5388d6c 100755 --- a/src/generate/gen_gldispatch_mapi.py +++ b/src/generate/gen_gldispatch_mapi.py @@ -34,6 +34,7 @@ Generates the glapi_mapi_tmp.h header file from Khronos's XML file. import sys import xml.etree.ElementTree as etree +import os.path import genCommon @@ -44,7 +45,15 @@ def _main(): roots = [ etree.parse(filename).getroot() for filename in xmlFiles ] allFunctions = genCommon.getFunctionsFromRoots(roots) - names = genCommon.getExportNamesFromRoots(target, roots) + # Technically, libGL.so is only supposed to export OpenGL 1.2 plus + # ARB_multitexture, but in the past, implementations exported everything + # and many applications rely on that. Here, we read a list of symbols from + # a file instead of exporting everything -- buggy applications won't break, + # but libGL.so won't get any *more* symbols added to it. + if os.path.isfile(target): + names = genCommon.readSymbolsFile(target) + else: + names = genCommon.getExportNamesFromRoots(target, roots) functions = [f for f in allFunctions if(f.name in names)] if (target in ("gl", "gldispatch")): diff --git a/src/generate/meson.build b/src/generate/meson.build index 440290a..458bd9b 100644 --- a/src/generate/meson.build +++ b/src/generate/meson.build @@ -23,7 +23,6 @@ foreach t : [['glapi_mapi_tmp.h', 'gldispatch'], - ['g_glapi_mapi_gl_tmp.h', 'gl'], ['g_glapi_mapi_opengl_tmp.h', 'opengl'], ['g_glapi_mapi_glesv1_tmp.h', 'glesv1'], ['g_glapi_mapi_glesv2_tmp.h', 'glesv2']] @@ -43,6 +42,18 @@ foreach t : [['glapi_mapi_tmp.h', 'gldispatch'], set_variable(var, _t) endforeach +# For libGL.so, we read the symbol list from a file instead of generating it +# from the XML files. +_t = custom_target( + 'g_glapi_mapi_gl_tmp.h', + input : ['gen_gldispatch_mapi.py', '../GL/gl.symbols', 'xml/gl.xml', 'xml/gl_other.xml'], + output : 'g_glapi_mapi_gl_tmp.h', + command : [prog_py, '@INPUT0@', '@INPUT1@', '@INPUT2@', '@INPUT3@'], + depend_files : files('genCommon.py'), + capture : true, +) +set_variable('g_glapi_mapi_gl_tmp.h'.underscorify(), _t) + foreach target : ['header', 'source'] ext = target == 'header' ? 'h' : 'c' _t = custom_target(