__main__.py (5500B)
1 #!/usr/bin/env python 2 3 """ 4 Uses the official Khronos-XML specs to generate a 5 GL/GLES/EGL/GLX/WGL Loader made for your needs. Glad currently supports 6 the languages C, D, Nim and Volt. 7 """ 8 from collections import namedtuple 9 import logging 10 import sys 11 12 from glad.opener import URLOpener 13 from glad.spec import SPECS 14 import glad.lang 15 16 17 Version = namedtuple('Version', ['major', 'minor']) 18 19 logger = logging.getLogger('glad') 20 21 22 def main(): 23 import os.path 24 import argparse 25 from argparse import ArgumentParser 26 27 opener = URLOpener() 28 29 def get_spec(value): 30 if value not in SPECS: 31 raise argparse.ArgumentTypeError('Unknown specification') 32 33 spec_cls = SPECS[value] 34 35 if os.path.exists(value + '.xml'): 36 logger.info('using local specification: \'%s.xml\'', value) 37 return spec_cls.from_file(value + '.xml') 38 logger.info('getting \'%s\' specification from SVN', value) 39 return spec_cls.from_svn(opener=opener) 40 41 def ext_file(value): 42 msg = 'Invalid extensions argument' 43 if os.path.exists(value): 44 msg = 'Invalid extensions file' 45 try: 46 with open(value, 'r') as f: 47 return f.read().split() 48 except IOError: 49 pass 50 else: 51 return [v.strip() for v in value.split(',') if v] 52 53 raise argparse.ArgumentTypeError(msg) 54 55 def version(value): 56 if value is None or len(value.strip()) == 0: 57 return None 58 59 v = value 60 if '.' not in v: 61 v = '{}.0'.format(v) 62 63 try: 64 return Version(*map(int, v.split('.'))) 65 except ValueError: 66 pass 67 68 raise argparse.ArgumentTypeError('Invalid version: "{}"'.format(value)) 69 70 def cmdapi(value): 71 try: 72 return dict((p[0], version(p[1])) for p in 73 (list(map(str.strip, e.split('='))) for e in 74 filter(bool, map(str.strip, value.split(','))))) 75 except IndexError: 76 pass 77 78 raise argparse.ArgumentTypeError( 79 'Invalid api-string: "{}"'.format(value) 80 ) 81 82 description = __doc__ 83 parser = ArgumentParser(description=description) 84 85 parser.add_argument('--profile', dest='profile', 86 choices=['core', 'compatibility'], 87 default='compatibility', 88 help='OpenGL profile (defaults to compatibility)') 89 parser.add_argument('--out-path', dest='out', required=True, 90 help='Output path for loader') 91 parser.add_argument('--api', dest='api', type=cmdapi, 92 help='API type/version pairs, like "gl=3.2,gles=", ' 93 'no version means latest') 94 parser.add_argument('--generator', dest='generator', default='d', 95 choices=['c', 'c-debug', 'd', 'nim', 'volt'], required=True, 96 help='Language to generate the binding for') 97 parser.add_argument('--extensions', dest='extensions', 98 default=None, type=ext_file, 99 help='Path to extensions file or comma separated ' 100 'list of extensions, if missing ' 101 'all extensions are included') 102 parser.add_argument('--spec', dest='spec', default='gl', 103 choices=['gl', 'egl', 'glx', 'wgl'], 104 help='Name of the spec') 105 parser.add_argument('--no-loader', dest='no_loader', action='store_true') 106 parser.add_argument('--omit-khrplatform', dest='omit_khrplatform', action='store_true', 107 help='Omits inclusion of the khrplatform.h ' 108 'file which is often unnecessary. ' 109 'Only has an effect if used together ' 110 'with c generators.') 111 parser.add_argument('--local-files', dest='local_files', action='store_true', 112 help='Forces every file directly into the output ' 113 'directory. No src or include subdirectories ' 114 'are generated. ' 115 'Only has an effect if used together ' 116 'with c generators.') 117 parser.add_argument('--quiet', dest='quiet', action='store_true') 118 119 ns = parser.parse_args() 120 121 if not ns.quiet: 122 logging.basicConfig( 123 format='[%(asctime)s][%(levelname)s\t][%(name)-7s\t]: %(message)s', 124 datefmt='%m/%d/%Y %H:%M:%S', level=logging.DEBUG 125 ) 126 127 spec = get_spec(ns.spec) 128 if spec.NAME == 'gl': 129 spec.profile = ns.profile 130 131 api = ns.api 132 if api is None or len(api.keys()) == 0: 133 api = {spec.NAME: None} 134 135 generator_cls, loader_cls = glad.lang.get_generator( 136 ns.generator, spec.NAME.lower() 137 ) 138 139 if loader_cls is None: 140 return parser.error('API/Spec not yet supported') 141 142 loader = loader_cls(api, disabled=ns.no_loader, local_files=ns.local_files) 143 144 logger.info('generating \'%s\' bindings', spec.NAME) 145 with generator_cls( 146 ns.out, 147 spec, 148 api, 149 ns.extensions, 150 loader=loader, 151 opener=opener, 152 local_files=ns.local_files, 153 omit_khrplatform=ns.omit_khrplatform 154 ) as generator: 155 generator.generate() 156 157 logger.info('generating \'%s\' bindings - done', spec.NAME) 158 159 if __name__ == '__main__': 160 main()