def __init__(self, ctx, exe='cl', *, pre_flags=[], flags=[], includes=[], macros=[], warnings=[], debug=None, optimize=None, debug_flags=['/Zi'], optimize_flags=['/Ox']): super().__init__(ctx) self.exe = fbuild.builders.find_program(ctx, [exe]) self.pre_flags = pre_flags self.flags = flags self.includes = includes self.macros = macros self.warnings = warnings self.debug = debug self.optimize = optimize self.debug_flags = debug_flags self.optimize_flags = optimize_flags if not self.check_flags(flags): raise fbuild.ConfigFailed('%s failed to compile an exe' % self) if debug_flags and not self.check_flags(debug_flags): raise fbuild.ConfigFailed('%s failed to compile an exe' % self) if optimize_flags and not self.check_flags(optimize_flags): raise fbuild.ConfigFailed('%s failed to compile an exe' % self)
def __init__(self, ctx, exe, src_suffix, *, classpaths=[], sourcepaths=[], debug=False, debug_flags=['-g'], target=None, flags=[]): super().__init__(ctx) self.exe = fbuild.builders.find_program(ctx, [exe]) self.src_suffix = src_suffix self.classpaths = classpaths self.sourcepaths = sourcepaths self.debug = debug self.debug_flags = debug_flags self.target = target self.flags = flags if not self.check_flags([]): raise fbuild.ConfigFailed('%s failed to compile an exe' % self) if debug_flags and not self.check_flags(debug_flags): raise fbuild.ConfigFailed('%s failed to compile an exe' % self)
def __init__(self, ctx, exe, *, pre_flags=(), flags=(), includes=(), macros=(), warnings=(), libpaths=(), libs=(), external_libs=(), debug=None, profile=None, optimize=None, debug_flags=('-g',), profile_flags=('-pg',), optimize_flags=('-O2',), arch=None, machine_flags=(), requires_version=None, requires_at_least_version=None, requires_at_most_version=None): super().__init__(ctx) self.exe = exe self.pre_flags = tuple(pre_flags) self.flags = tuple(flags) self.includes = tuple(includes) self.macros = tuple(macros) self.warnings = tuple(warnings) self.libpaths = tuple(libpaths) self.libs = tuple(libs) self.external_libs = tuple(external_libs) self.debug = debug self.profile = profile self.optimize = optimize self.debug_flags = tuple(debug_flags) self.profile_flags = tuple(profile_flags) self.optimize_flags = tuple(optimize_flags) self.arch = arch self.machine_flags = tuple(machine_flags) if not self.check_flags(flags): raise fbuild.ConfigFailed('%s failed to compile an exe' % self) if debug and debug_flags and not self.check_flags(debug_flags): raise fbuild.ConfigFailed('%s failed to compile an exe' % self) if profile and profile_flags and not self.check_flags(profile_flags): raise fbuild.ConfigFailed('%s failed to compile an exe' % self) if optimize and optimize_flags and not self.check_flags(optimize_flags): raise fbuild.ConfigFailed('%s failed to compile an exe' % self) # Make sure we've got a valid version. fbuild.builders.check_version(ctx, self, self.version, requires_version=requires_version, requires_at_least_version=requires_at_least_version, requires_at_most_version=requires_at_most_version)
def check_version(ctx, builder, version_function, *, requires_version=None, requires_at_least_version=None, requires_at_most_version=None): """Helper function to simplify checking the version of a builder.""" if any(v is not None for v in ( requires_version, requires_at_least_version, requires_at_most_version)): ctx.logger.check('checking %s version' % builder) version_str = version_function() # Convert the version into a tuple version = [] for i in version_str.split('.'): try: version.append(int(i)) except ValueError: # The subversion isn't a number, so just convert it to a # string. version.append(i) version = tuple(version) if requires_version is not None and requires_version != version: msg = 'version %s required; found %s' % ( '.'.join(str(i) for i in requires_version), version_str) ctx.logger.failed(msg) raise fbuild.ConfigFailed(msg) if requires_at_least_version is not None and \ requires_at_least_version > version: msg = 'at least version %s required; found %s' % ( '.'.join(str(i) for i in requires_at_least_version), version_str) ctx.logger.failed(msg) raise fbuild.ConfigFailed(msg) if requires_at_most_version is not None and \ requires_at_most_version < version: msg = 'at most version %s required; found %s' % ( '.'.join(str(i) for i in requires_at_most_version), version_str) ctx.logger.failed(msg) raise fbuild.ConfigFailed(msg) ctx.logger.passed(version_str)
def copy_dll(ctx, fluid): dll = fluid.replaceext('.dll') if not dll.exists(): url = 'https://github.com/midifi/midifi/blob/master/README.md#windows-1' raise fbuild.ConfigFailed('cannot find %s\nsee %s for more info' % (dll, url)) return copy_dll2(ctx, dll)
def _guess_builder(name, functions, ctx, *args, platform=None, platform_options=[], **kwargs): if platform is None: platform = fbuild.builders.platform.guess_platform(ctx, platform) for subplatform, function in functions: if subplatform <= platform: new_kwargs = kwargs.copy() for p, kw in platform_options: if p <= subplatform: new_kwargs.update(kw) # Try to use this compiler. If it doesn't work, skip this compiler # and try another one. try: return fbuild.functools.call(function, ctx, *args, **new_kwargs) except fbuild.ConfigFailed: pass raise fbuild.ConfigFailed('cannot find a %s builder for %s' % (name, platform))
def __init__(self, ctx, exe, *, flags=[]): super().__init__(ctx) self.exe = fbuild.builders.find_program(ctx, [exe if exe else 'ghc']) self.flags = flags if not self.check_flags(flags): raise fbuild.ConfigFailed('%s failed to compile an exe' % self)
def __init__(self, ctx, cc, flags, *, suffix): super().__init__(ctx) self.cc = cc self.flags = tuple(flags) self.suffix = suffix if flags and not cc.check_flags(flags): raise fbuild.ConfigFailed('%s does not support %s flags' % (cc, flags))
def __init__(self, ctx, cl, flags, *, suffix): super().__init__(ctx) self.cl = cl self.flags = flags self.suffix = suffix if flags and not cl.check_flags(flags): raise fbuild.ConfigFailed('%s does not support %s flags' % (cl, flags))
def __init__(self, ctx, exe, *, includes=[], debug=False, flags=[]): super().__init__(ctx) # we split exe in case extra arguments were specified in the name self.exe = fbuild.builders.find_program(ctx, [exe]) self.includes = includes self.debug = debug self.flags = flags if not self.check_flags([]): raise fbuild.ConfigFailed('%s failed to compile an exe' % self)
def __init__(self, ctx, exe, *args, debug_flags=['-g:vars'], optimize=False, optimize_flags=['-optimise'], **kwargs): self.optimize = optimize self.optimize_flags = optimize_flags super().__init__(ctx, exe, '.scala', debug_flags=debug_flags, *args, **kwargs) if optimize_flags and not self.check_flags(optimize_flags): raise fbuild.ConfigFailed('%s failed to compile an exe' % self)
def check_fluid(linker): fluidsynth = Path(linker.prefix + 'fluidsynth' + linker.suffix) fluidsynth = fluidsynth.addroot(Path('fluidsynth') / 'fluidsynth' / 'src') message = textwrap.dedent(''' You need to build Fluidsynth separately first! Try runnung 'cd fluidsynth/fluidsynth; cmake'. (See http://sourceforge.net/p/fluidsynth/wiki/BuildingWithCMake/ for info.) '''.rstrip().lstrip('\n')).replace('\n', ' ', 1) if not fluidsynth.exists(): raise fbuild.ConfigFailed(message) return fluidsynth
def __init__(self, *args, flags=(), cross_compiler=False, **kwargs): self.flags = tuple(flags) # If we're a cross compiler, don't try to execute tests as they'll # probably fail. self.cross_compiler = cross_compiler super().__init__(*args, **kwargs) # ---------------------------------------------------------------------- # Check the builder to make sure it works. self.ctx.logger.check('checking if %s can make objects' % self) try: with self.tempfile_compile('int main() { return 0; }'): self.ctx.logger.passed() except fbuild.ExecutionError as e: raise fbuild.ConfigFailed('compiler failed: %s' % e) self.ctx.logger.check('checking if %s can make libraries' % self) try: with self.tempfile_link_lib('int foo() { return 5; }'): self.ctx.logger.passed() except fbuild.ExecutionError as e: raise fbuild.ConfigFailed('lib linker failed: %s' % e) self.ctx.logger.check('checking if %s can make exes' % self) try: if not self.cross_compiler: self.tempfile_run('int main() { return 0; }') else: with self.tempfile_link_exe('int main() { return 0; }'): pass except fbuild.ExecutionError as e: raise fbuild.ConfigFailed('exe linker failed: %s' % e) else: self.ctx.logger.passed()
def platform_extra(self): get_toolchain = ''' include 'std/felix/toolchain_clang_config'; include 'std/felix/toolchain_interface'; include 'std/felix/flx_pkgconfig'; config_dirs := #Config::std_config.FLX_CONFIG_DIRS; pkgconfig := FlxPkgConfig::FlxPkgConfigQuery config_dirs; toolchain := pkgconfig.getpkgfield1 ('toolchain', 'toolchain'); for arg in #System::args perform if arg.startswith('--toolchain=') perform toolchain = arg.[12 to]; println toolchain; ''' with self.tempfile(get_toolchain) as f: self.ctx.logger.check('detecting toolchain used by flx '\ '(this may take a while!)') try: toolchain = self.uncached_run(f, quieter=1)[0] except: self.ctx.logger.failed() raise fbuild.ConfigFailed('could not detect flx toolchain') else: toolchain = toolchain.decode('utf-8').strip().split('\n')[-1] self.ctx.logger.passed('ok %s' % toolchain) if 'msvc' in toolchain: return {'windows'} elif 'gcc' in toolchain: return {'gcc'} elif 'clang' in toolchain: return {'clang'} else: raise fbuild.ConfigFailed('unknown toolchain %s' % toolchain)
def find_font(ctx) -> fbuild.db.DST: ctx.logger.check('locating arial font') font = None if sys.platform == 'win32': font = Path(os.environ['SYSTEMROOT']) / 'Fonts' / 'Arial.ttf' if not font.exists(): font = None elif sys.platform.startswith('linux'): # Check /etc/fonts/fonts.conf. font_dirs = [] fonts = Path('/etc/fonts/fonts.conf') if not fonts.exists(): ctx.logger.failed() raise fbuild.ConfigFailed('cannot locate fonts.conf') tree = etree.parse(str(fonts)) for element in tree.findall('dir'): path = Path(element.text) if element.attrib.get('prefix') == 'xdg' and \ 'XDG_DATA_HOME' in os.environ: path = path.addroot(os.environ['XDG_DATA_HOME']) try: font = Path(next(path.find('Arial.ttf', include_dirs=False))) except StopIteration: pass else: break if font is None: ctx.logger.failed() raise fbuild.ConfigFailed('cannot locate arial font') else: ctx.logger.passed('ok %s' % font) return font
def _test(self): self.ctx.logger.check('checking flx') failed = False with self.tempfile("println 'Hello, world!';") as f: try: output = self.uncached_run(f, quieter=1) except: self.ctx.logger.failed() raise else: if output[1] or not output[0].rstrip().endswith(b'Hello, world!'): self.ctx.logger.failed() raise fbuild.ConfigFailed( 'flx test program did not give correct output') else: self.ctx.logger.passed()
def __init__(self, ctx, cc, flags, *, suffix): super().__init__(ctx) self.cc = cc self.suffix = suffix flags = tuple(flags) noaggro = ("-fno-aggressive-loop-optimizations", ) if cc.check_flags(noaggro): print( "FLAG -fno-aggressive-loop-optimizations supported and applied" ) flags = flags + noaggro else: print("FLAG -fno-aggressive-loop-optimizations NOT supported") if flags and not cc.check_flags(flags): raise fbuild.ConfigFailed('%s does not support %s flags' % (cc, flags)) self.flags = tuple(flags)
def conversion_map(self, *args, **kwargs): type_pairs = [(name1, name2) for name1, type1 in self.int_types() if type1 is not None for name2, type2 in self.int_types() if type2 is not None] lines = [] for t1, t2 in type_pairs: lines.append('printf("%%d %%d\\n", ' '(int)sizeof((%(t1)s)0 + (%(t2)s)0), ' '(%(t1)s)~3 + (%(t2)s)1 < (%(t1)s)0 + (%(t2)s)0);' % { 't1': t1, 't2': t2 }) code = ''' #include <stdio.h> int main(int argc, char** argv) { %s return 0; } ''' % '\n'.join(lines) try: stdout, stderr = self.builder.tempfile_run(code, *args, **kwargs) except fbuild.ExecutionError: raise fbuild.ConfigFailed('failed to detect type conversions') lookup = {(t.size, t.signed): self.structural_alias(t) for n, t in self.int_types() if t is not None} d = {} for line, (t1, t2) in zip(stdout.decode('utf-8').split('\n'), type_pairs): size, sign = line.split() d[(t1, t2)] = lookup[(int(size), int(sign) == 1)] return d
def __call__(self, ctx, static={}, shared={}, platform=None, platform_options={}, exe=None, **kwargs): """Try to find a set of builders. A static builder will be located using the arguments in *static* combined with *kwargs*, and the shared builder will be located using *shared* arguments combined with *kwargs*. Each """ if platform is None: platform = fbuild.builders.platform.guess_platform(ctx, platform) if exe is not None: tp = identify_compiler(ctx, exe) if tp is None: raise fbuild.ConfigFailed('cannot identify exe given for %s' % name) # Grab only the compiler type pertaining to this guess call. platform |= tp & self.compilers else: # We're open to using all compilers. platform |= self.compilers builders = {'static': static, 'shared': shared} for subplatform, static_function, shared_function in self.functions: if subplatform <= platform: # We need to go through each requested builder and check the compiler. result = fbuild.record.Record() for builder, builder_args in builders.items(): if builder_args is None: result[builder] = None continue if builder == 'static': function = static_function else: function = shared_function # Create a new arg dict, merging both kwargs and the builder-specific args. new_kwargs = copy.deepcopy(kwargs) new_kwargs.update(copy.deepcopy(builder_args)) # Make sure that only the current compiler used for parsing # platform_options. simplified_platform = (platform - self.compilers) | subplatform # Now parse the options. fbuild.builders.platform.parse_platform_options(ctx, simplified_platform, platform_options, new_kwargs) # Try to use this compiler. If it doesn't work, then give up on this # subplatform and move on. try: result[builder] = fbuild.functools.call(function, ctx, exe, platform=platform, **new_kwargs) except fbuild.ConfigFailed: break # If both builders are present in some form, then that means this # function has succeeded. Time to return the result record. if len(result) == 2: return result # If we made it all the way here, then everything failed. raise fbuild.ConfigFailed('cannot find a builder for %s' % platform)
def __init__(self, *args, flags=(), cross_compiler=False, **kwargs): self.flags = tuple(flags) # If we're a cross compiler, don't try to execute tests as they'll # probably fail. self.cross_compiler = cross_compiler super().__init__(*args, **kwargs) # ---------------------------------------------------------------------- # Check the builder to make sure it works. self.ctx.logger.check('checking if %s can make objects' % self) try: with self.tempfile_compile('int main() { return 0; }'): self.ctx.logger.passed() except fbuild.ExecutionError as e: raise fbuild.ConfigFailed('compiler failed: %s' % e) self.ctx.logger.check('checking if %s can make libraries' % self) try: with self.tempfile_link_lib('int foo() { return 5; }'): self.ctx.logger.passed() except fbuild.ExecutionError as e: raise fbuild.ConfigFailed('lib linker failed: %s' % e) self.ctx.logger.check('checking if %s can make exes' % self) try: if not self.cross_compiler: self.tempfile_run('int main() { return 0; }') else: with self.tempfile_link_exe('int main() { return 0; }'): pass except fbuild.ExecutionError as e: raise fbuild.ConfigFailed('exe linker failed: %s' % e) else: self.ctx.logger.passed() self.ctx.logger.check('checking if %s can link lib to exe' % self) with fbuild.temp.tempdir() as dirname: src_lib = dirname / 'templib' + self.src_suffix with open(src_lib, 'w') as f: print(''' #ifdef __cplusplus extern "C" { #endif #if defined _WIN32 || defined __CYGWIN__ __declspec(dllexport) #elif defined __GNUC__ __attribute__ ((visibility ("default"))) #endif int foo() { return 5; } #ifdef __cplusplus } #endif ''', file=f) src_exe = dirname / 'tempexe' + self.src_suffix with open(src_exe, 'w') as f: print(''' #include <stdio.h> #ifdef __cplusplus extern "C" { #endif extern int foo(); #ifdef __cplusplus } #endif int main(int argc, char** argv) { printf("%d", foo()); return 0; }''', file=f) obj = self.uncached_compile(src_lib, quieter=1) lib = self.uncached_link_lib(dirname / 'templib', [obj], quieter=1) obj = self.uncached_compile(src_exe, quieter=1) exe = self.uncached_link_exe(dirname / 'tempexe', [obj], libs=[lib], quieter=1) if self.cross_compiler: self.ctx.logger.passed() else: try: stdout, stderr = self.run([exe], quieter=1) except fbuild.ExecutionError: raise fbuild.ConfigFailed('failed to link lib to exe') else: if stdout != b'5': raise fbuild.ConfigFailed('failed to link lib to exe') self.ctx.logger.passed()
def __init__(self, ctx, exe, *, platform=None, obj_suffix, lib_suffix, includes=(), libs=(), cc=None, c_libs=(), pre_flags=(), flags=(), debug=False, optimize=False, debug_flags=('-g',), optimize_flags=(), ocamldep=None, make_ocamldep=Ocamldep, requires_version=None, requires_at_least_version=None, requires_at_most_version=None): super().__init__(ctx, src_suffix='.ml') self.ocamldep = ocamldep or make_ocamldep(ctx) self.exe = exe self.obj_suffix = obj_suffix self.lib_suffix = lib_suffix self.exe_suffix = fbuild.builders.platform.exe_suffix(ctx, platform) self.includes = tuple(includes) self.libs = tuple(libs) self.cc = cc self.c_libs = tuple(c_libs) self.pre_flags = tuple(pre_flags) self.flags = tuple(flags) self.debug = debug self.optimize = optimize self.debug_flags = tuple(debug_flags) self.optimize_flags = tuple(optimize_flags) # Make sure we've got a valid version. fbuild.builders.check_version(ctx, self, self.version, requires_version=requires_version, requires_at_least_version=requires_at_least_version, requires_at_most_version=requires_at_most_version) # ---------------------------------------------------------------------- # Check the builder to make sure it works. self.ctx.logger.check('checking if %s can make objects' % str(self)) if self.try_compile(): self.ctx.logger.passed() else: raise fbuild.ConfigFailed('%s compiler failed' % str(self)) self.ctx.logger.check('checking if %s can make libraries' % str(self)) if self.try_link_lib(): self.ctx.logger.passed() else: raise fbuild.ConfigFailed('%s lib linker failed' % str(self)) self.ctx.logger.check('checking if %s can make exes' % str(self)) if self.try_link_exe(): self.ctx.logger.passed() else: raise fbuild.ConfigFailed('%s exe linker failed' % str(self)) self.ctx.logger.check('checking if %s can link lib to exe' % str(self)) with fbuild.temp.tempdir() as parent: src_lib = parent / 'lib.ml' with open(src_lib, 'w') as f: print('let x = 5;;', file=f) src_exe = parent / 'exe.ml' with open(src_exe, 'w') as f: print('print_int Lib.x;;', file=f) obj = self.uncached_compile(src_lib, quieter=1) lib = self.uncached_link_lib(parent / 'lib', [obj], quieter=1) obj = self.uncached_compile(src_exe, quieter=1) exe = self.uncached_link_exe(parent / 'exe', [obj], libs=[lib], quieter=1) try: stdout, stderr = self.ctx.execute([exe], quieter=1) except fbuild.ExecutionError: raise fbuild.ConfigFailed('failed to link %s lib to exe' % str(self)) else: if stdout != b'5': raise fbuild.ConfigFailed('failed to link %s lib to exe' % str(self)) self.ctx.logger.passed()
def _guess_builder(name, compilers, functions, ctx, *args, platform=None, platform_extra=set(), platform_options=[], exe=None, **kwargs): if platform is None: platform = fbuild.builders.platform.guess_platform(ctx, platform) if not platform_extra & compilers: if exe is not None: tp = identify_compiler(ctx, exe) if tp is None: raise fbuild.ConfigFailed('cannot identify exe given for ' +\ name) platform_extra |= tp else: platform_extra |= compilers platform |= platform_extra for subplatform, function in functions: # XXX: this is slightly a hack to make sure: # a) Clang can actually be detected # b) Any compilers explicitly listed in platform_extra will have #1 # priority if subplatform - (compilers & platform_extra) <= platform: new_kwargs = copy.deepcopy(kwargs) for p, kw in platform_options: if p <= subplatform: for k, v in kw.items(): if k[-1] in '+-': func = k[-1] k = k[:-1] try: curval = new_kwargs[k] except: if isinstance(v, str): curval = '' elif isinstance(v, list): curval = [] elif isinstance(v, tuple): curval = () if func == '+': curval += v elif func == '-': lst = list(curval) for x in v: lst.pop(lst.index(x)) if isinstance(curval, str): curval = ''.join(lst) else: curval = type(curval)(lst) new_kwargs[k] = curval else: new_kwargs[k] = v # Try to use this compiler. If it doesn't work, skip this compiler # and try another one. try: return fbuild.functools.call(function, ctx, exe, *args, **new_kwargs) except fbuild.ConfigFailed: pass raise fbuild.ConfigFailed('cannot find a %s builder for %s' % (name, platform))