예제 #1
0
파일: file.py 프로젝트: DawidvC/felix
def _copy_or_move(ctx, src, dst, function, function_name):
    """
    Helper function to simplify copies and moves.
    """

    src = Path(src)
    dst = Path(dst).addroot(ctx.buildroot)

    if not dst.exists():
        # if dst ends with the separator, treat it like a directory
        if dst.endswith(os.sep):
            dst.makedirs()
            dst = dst / src.name
        else:
            dst.parent.makedirs()
    elif dst.isdir():
        # If the dst is a directory, we're just copying that file into that
        # directory.
        dst = dst / src.name

    ctx.logger.check(' * %s' % function_name, '%s -> %s' % (src, dst),
        color='yellow')
    function(src, dst)

    return dst
예제 #2
0
파일: file.py 프로젝트: rjeschmi/fbuild
def _copy_or_move(ctx, src, dst, function, function_name):
    """
    Helper function to simplify copies and moves.
    """

    src = Path(src)
    dst = Path(dst).addroot(ctx.buildroot)

    if not dst.exists():
        # if dst ends with the separator, treat it like a directory
        if dst.endswith(os.sep):
            dst.makedirs()
            dst = dst / src.name
        else:
            dst.parent.makedirs()
    elif dst.isdir():
        # If the dst is a directory, we're just copying that file into that
        # directory.
        dst = dst / src.name

    ctx.logger.check(' * %s' % function_name,
                     '%s -> %s' % (src, dst),
                     color='yellow')
    function(src, dst)

    return dst
예제 #3
0
    def __call__(self,
                 src: fbuild.db.SRC,
                 *,
                 break_on_error=True,
                 flags=[],
                 buildroot=None,
                 **kwargs) -> fbuild.db.DSTS:
        buildroot = buildroot or self.ctx.buildroot
        src = Path(src)

        cmd = [
            sys.executable,
            self.exe.relpath(buildroot),
            '--cache-prefix=lpsrc-cache',
            '--trace=sources',
            '--trace=changes',
            '--nocache',
        ]

        if break_on_error:
            cmd.append('--break-on-error')
        cmd.extend(flags)
        cmd.append(src.relpath(buildroot))

        stdout, stderr = self.ctx.execute(
            cmd,
            'iscr extracting',
            src,
            color='green',
            cwd=buildroot,
            env={'PYTHONPATH': Path('buildsystem').relpath(buildroot)},
            **kwargs)

        srcs = []
        dsts = []
        ipk_regex = re.compile('^CREATING .* NAMED FILE SOURCE (.*) \[.*\]')
        file_regex = re.compile('^File (.*) is (NEW|CHANGED|unchanged)')
        for line in io.StringIO(stdout.decode()):
            m = ipk_regex.match(line)
            if m:
                path = Path(m.group(1))
                if not path.exists():
                    # The path may be relative to the .pak file.
                    path = src.parent / path
                srcs.append(path)
            else:
                m = file_regex.match(line)
                if m:
                    dsts.append(Path(m.group(1)))

        #self.ctx.db.add_external_dependencies_to_call(srcs=srcs)

        return dsts
예제 #4
0
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
예제 #5
0
파일: iscr.py 프로젝트: narychen/felix
    def __call__(
        self, src: fbuild.db.SRC, *, break_on_error=True, flags=[], buildroot=None, **kwargs
    ) -> fbuild.db.DSTS:
        buildroot = buildroot or self.ctx.buildroot
        src = Path(src)

        cmd = [
            sys.executable,
            self.exe.relpath(buildroot),
            "--cache-prefix=lpsrc-cache",
            "--trace=sources",
            "--trace=changes",
            "--nocache",
        ]

        if break_on_error:
            cmd.append("--break-on-error")
        cmd.extend(flags)
        cmd.append(src.relpath(buildroot))

        stdout, stderr = self.ctx.execute(
            cmd,
            "iscr extracting",
            src,
            color="green",
            cwd=buildroot,
            env={"PYTHONPATH": Path("buildsystem").relpath(buildroot)},
            **kwargs
        )

        srcs = []
        dsts = []
        ipk_regex = re.compile("^CREATING .* NAMED FILE SOURCE (.*) \[.*\]")
        file_regex = re.compile("^File (.*) is (NEW|CHANGED|unchanged)")
        for line in io.StringIO(stdout.decode()):
            m = ipk_regex.match(line)
            if m:
                path = Path(m.group(1))
                if not path.exists():
                    # The path may be relative to the .pak file.
                    path = src.parent / path
                srcs.append(path)
            else:
                m = file_regex.match(line)
                if m:
                    dsts.append(Path(m.group(1)))

        # self.ctx.db.add_external_dependencies_to_call(srcs=srcs)

        return dsts
예제 #6
0
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
예제 #7
0
파일: __init__.py 프로젝트: rjeschmi/fbuild
        def f(module, include):
            # On case-insensitive but case-preserving filesystems, we need to
            # be careful on how we deal with finding OCaml dependencies. Since
            # OCaml can store a module named List in either list.ml or List.ml,
            # we can't just test if the filename exists since fbuild needs to
            # deal with the exact filenames.  To do that, we'll grab the list
            # of filenames in the directory, then search for the right
            # spelling in that list.

            # Grab the filenames in the directory.
            if include is None:
                dirs = Path.getcwd().listdir()
            else:
                include = Path(include)

                if not include.exists():
                    # We can't search for dependencies in a directory that
                    # doesn't exist, so exit early.
                    return False

                dirs = include.listdir()

            found = False
            for suffix in '.mli', '.ml':
                # Look for the traditional lowercase form.
                path = module[0].lower() + module[1:] + suffix
                if path not in dirs:
                    # That didn't work, so lets try the uppercase form.
                    path = module[0].upper() + module[1:] + suffix
                    if path not in dirs:
                        # Couldn't find it, so just skip this module.
                        continue

                # We found it! Add that file to the dependencies.
                if include is None:
                    deps.append(Path(path))
                else:
                    deps.append(include / path)
                found = True

            return found
예제 #8
0
파일: __init__.py 프로젝트: ACGCross/felix
        def f(module, include):
            # On case-insensitive but case-preserving filesystems, we need to
            # be careful on how we deal with finding OCaml dependencies. Since
            # OCaml can store a module named List in either list.ml or List.ml,
            # we can't just test if the filename exists since fbuild needs to
            # deal with the exact filenames.  To do that, we'll grab the list
            # of filenames in the directory, then search for the right
            # spelling in that list.

            # Grab the filenames in the directory.
            if include is None:
                dirs = Path.getcwd().listdir()
            else:
                include = Path(include)

                if not include.exists():
                    # We can't search for dependencies in a directory that
                    # doesn't exist, so exit early.
                    return False

                dirs = include.listdir()

            found = False
            for suffix in '.mli', '.ml':
                # Look for the traditional lowercase form.
                path = module[0].lower() + module[1:] + suffix
                if path not in dirs:
                    # That didn't work, so lets try the uppercase form.
                    path = module[0].upper() + module[1:] + suffix
                    if path not in dirs:
                        # Couldn't find it, so just skip this module.
                        continue

                # We found it! Add that file to the dependencies.
                if include is None:
                    deps.append(Path(path))
                else:
                    deps.append(include / path)
                found = True

            return found
예제 #9
0
    def _run_flxg(self,
                  src: fbuild.db.SRC,
                  *,
                  includes=[],
                  syntaxes=[],
                  imports=[],
                  flags=[],
                  include_std=True,
                  preparse=False,
                  buildroot=None,
                  **kwargs) -> fbuild.db.DST:
        buildroot = buildroot or self.ctx.buildroot

        src = Path(src)
        #src_buildroot = src.addroot(buildroot)

        print("Buildroot        = " + buildroot)
        print("Src to flxg      = " + src)
        if preparse:
            dst = buildroot / "cache" / "binary" + _getcwd() / src
            dst = dst.replaceext('.par')
        else:
            dst = buildroot / "cache" / "text" + _getcwd() / src
            dst = dst.replaceext('.cpp')

        print("Expected flg dst = " + dst)
        #if src != src_buildroot:
        #    src_buildroot.parent.makedirs()
        #    src.copy(src_buildroot)
        #    src = src_buildroot

        #dst.parent.makedirs()

        cmd = [self.flxg]

        if preparse:
            cmd.append('-c')

        includes = set(includes)
        includes.add(src.parent)
        includes.add(dst.parent)

        imports = list(imports)
        syntaxes = list(syntaxes)
        if include_std:
            imports.insert(0, 'plat/flx.flxh')  # Unix filename correct here
            imports.insert(
                0,
                'concordance/concordance.flxh')  # Unix filename correct here
            syntaxes.insert(
                0, '@grammar/grammar.files')  # Unix filename correct here

        cmd.extend('-I' + i for i in sorted(includes) if Path.exists(i))
        cmd.extend('--syntax=' + i for i in syntaxes)
        cmd.extend('--import=' + i for i in imports)
        cmd.append('--output_dir=' + Path(buildroot) / "cache" / "text")
        cmd.append('--cache_dir=' + Path(buildroot) / "cache" / "binary")
        #cmd.append('--with-comments') # add lots of comments to generated C++ to help debugging
        cmd.extend(flags)

        if include_std:
            cmd.append('std')

        if src.ext == '.flx':
            cmd.append(src.replaceext(''))
        else:
            cmd.append(src)

        self.ctx.execute(cmd,
                         self.flxg.name,
                         '%s -> %s' % (src, dst),
                         color='yellow',
                         **kwargs)

        return dst
예제 #10
0
파일: __init__.py 프로젝트: rjeschmi/fbuild
    def source_dependencies(self, src:fbuild.db.SRC, *,
            includes=(),
            **kwargs) -> fbuild.db.DSTS:
        """Compute the source files this ocaml file depends on."""
        deps = []

        def f(module, include):
            # On case-insensitive but case-preserving filesystems, we need to
            # be careful on how we deal with finding OCaml dependencies. Since
            # OCaml can store a module named List in either list.ml or List.ml,
            # we can't just test if the filename exists since fbuild needs to
            # deal with the exact filenames.  To do that, we'll grab the list
            # of filenames in the directory, then search for the right
            # spelling in that list.

            # Grab the filenames in the directory.
            if include is None:
                dirs = Path.getcwd().listdir()
            else:
                include = Path(include)

                if not include.exists():
                    # We can't search for dependencies in a directory that
                    # doesn't exist, so exit early.
                    return False

                dirs = include.listdir()

            found = False
            for suffix in '.mli', '.ml':
                # Look for the traditional lowercase form.
                path = module[0].lower() + module[1:] + suffix
                if path not in dirs:
                    # That didn't work, so lets try the uppercase form.
                    path = module[0].upper() + module[1:] + suffix
                    if path not in dirs:
                        # Couldn't find it, so just skip this module.
                        continue

                # We found it! Add that file to the dependencies.
                if include is None:
                    deps.append(Path(path))
                else:
                    deps.append(include / path)
                found = True

            return found

        modules = self.modules(src, **kwargs)
        for module in modules:
            if not f(module, None):
                for include in includes:
                    f(module, include)

        if src.endswith('.ml'):
            # The .mli file might not live right next to the .ml file, so
            # search the include path for it.
            mli = Path(src).replaceext('.mli')
            if mli.exists():
                deps.append(mli)
            else:
                # If we generated the .ml file, then perhaps there's a
                # pre-defined .mli file not in the buildroot.
                buildroot = kwargs.get('buildroot') or self.ctx.buildroot
                mli = mli.removeroot(buildroot + os.sep)

                if mli.exists():
                    deps.append(mli)
                else:
                    for include in includes:
                        path = mli.name
                        if include is not None: path = include / path
                        if path.exists():
                            deps.append(path)
                        break

        return deps
예제 #11
0
파일: __init__.py 프로젝트: rjeschmi/fbuild
    def _run(self, dst, srcs, *,
            includes=(),
            libs=(),
            external_libs=(),
            pre_flags=(),
            flags=(),
            debug=None,
            optimize=None,
            custom=False,
            cc=None,
            c_libs=(),
            for_pack=None,
            preprocessor=None,
            buildroot=None,
            **kwargs):
        buildroot = buildroot or self.ctx.buildroot
        libs = tuple(chain(self.libs, external_libs, libs))

        # we need to make sure libraries are built first before we compile
        # the sources
        assert srcs or libs, "%s: no sources or libraries passed in" % dst

        dst = Path(dst).addroot(buildroot)
        dst.parent.makedirs()

        extra_srcs = []
        for lib in libs:
            if Path(lib).exists():
                extra_srcs.append(lib)
            else:
                extra_srcs.append(lib + self.lib_suffix)

        cmd = [self.exe]
        cmd.extend(self.pre_flags)
        cmd.extend(pre_flags)

        if (debug is None and self.debug) or debug:
            cmd.extend(self.debug_flags)

        if (optimize is None and self.optimize) or optimize:
            cmd.extend(self.optimize_flags)

        includes = set(includes)
        includes.update(self.includes)
        includes.add(dst.parent)

        for i in sorted(includes):
            i = Path(i)
            if i.exists():
                cmd.extend(('-I', i))

        if custom:
            cmd.append('-custom')

        cc = cc or self.cc
        if cc:
            cmd.extend(('-cc', cc))

        for lib in chain(self.c_libs, c_libs):
            if Path(lib).exists():
                cmd.extend(('-cclib', lib))
            else:
                cmd.extend(('-cclib', '-l' + lib))

        if preprocessor is not None:
            cmd.extend(('-pp', preprocessor))

        if for_pack is not None:
            cmd.extend(('-for-pack', for_pack))

        cmd.extend(self.flags)
        cmd.extend(flags)
        cmd.extend(('-o', dst))
        cmd.extend(extra_srcs)
        cmd.extend(srcs)

        self.ctx.execute(cmd, str(self),
            '%s -> %s' % (' '.join(extra_srcs + srcs), dst),
            **kwargs)

        return dst
예제 #12
0
파일: flx.py 프로젝트: DawidvC/felix
    def _run_flxg(self, src:fbuild.db.SRC, *,
            includes=[],
            syntaxes=[],
            imports=[],
            flags=[],
            include_std=True,
            preparse=False,
            buildroot=None,
            **kwargs) -> fbuild.db.DST:
        buildroot = buildroot or self.ctx.buildroot

        src = Path(src)
        #src_buildroot = src.addroot(buildroot)

        print("Buildroot        = " + buildroot)
        print("Src to flxg      = " + src)
        if preparse:
            dst = buildroot /"cache"/"binary"+_getcwd()/src
            dst = dst.replaceext('.par')
        else:
            dst =buildroot /"cache"/"text"+_getcwd()/src
            dst = dst.replaceext('.cpp')

        print("Expected flg dst = " + dst)
        #if src != src_buildroot:
        #    src_buildroot.parent.makedirs()
        #    src.copy(src_buildroot)
        #    src = src_buildroot

        #dst.parent.makedirs()

        cmd = [self.flxg]

        if preparse:
            cmd.append('-c')

        includes = set(includes)
        includes.add(src.parent)
        includes.add(dst.parent)

        imports = list(imports)
        syntaxes = list(syntaxes)
        if include_std:
            imports.insert(0, 'plat/flx.flxh')               # Unix filename correct here
            syntaxes.insert(0, '@grammar/grammar.files')     # Unix filename correct here

        cmd.extend('-I' + i for i in sorted(includes) if Path.exists(i))
        cmd.extend('--syntax=' + i for i in syntaxes)
        cmd.extend('--import=' + i for i in imports)
        cmd.append('--output_dir=' + Path(buildroot)/"cache"/"text")
        cmd.append('--cache_dir=' + Path(buildroot)/"cache"/"binary")
        cmd.append('--with-comments') # add lots of comments to generated C++ to help debugging
        cmd.extend(flags)

        if include_std:
            cmd.append('std')

        if src.ext == '.flx':
            cmd.append(src.replaceext(''))
        else:
            cmd.append(src)

        self.ctx.execute(cmd, self.flxg.name, '%s -> %s' % (src, dst),
                color='yellow', **kwargs)

        return dst
예제 #13
0
파일: __init__.py 프로젝트: ACGCross/felix
    def source_dependencies(self, src:fbuild.db.SRC, *,
            includes=(),
            **kwargs) -> fbuild.db.DSTS:
        """Compute the source files this ocaml file depends on."""
        deps = []

        def f(module, include):
            # On case-insensitive but case-preserving filesystems, we need to
            # be careful on how we deal with finding OCaml dependencies. Since
            # OCaml can store a module named List in either list.ml or List.ml,
            # we can't just test if the filename exists since fbuild needs to
            # deal with the exact filenames.  To do that, we'll grab the list
            # of filenames in the directory, then search for the right
            # spelling in that list.

            # Grab the filenames in the directory.
            if include is None:
                dirs = Path.getcwd().listdir()
            else:
                include = Path(include)

                if not include.exists():
                    # We can't search for dependencies in a directory that
                    # doesn't exist, so exit early.
                    return False

                dirs = include.listdir()

            found = False
            for suffix in '.mli', '.ml':
                # Look for the traditional lowercase form.
                path = module[0].lower() + module[1:] + suffix
                if path not in dirs:
                    # That didn't work, so lets try the uppercase form.
                    path = module[0].upper() + module[1:] + suffix
                    if path not in dirs:
                        # Couldn't find it, so just skip this module.
                        continue

                # We found it! Add that file to the dependencies.
                if include is None:
                    deps.append(Path(path))
                else:
                    deps.append(include / path)
                found = True

            return found

        modules = self.modules(src, **kwargs)
        for module in modules:
            if not f(module, None):
                for include in includes:
                    f(module, include)

        if src.endswith('.ml'):
            # The .mli file might not live right next to the .ml file, so
            # search the include path for it.
            mli = Path(src).replaceext('.mli')
            if mli.exists():
                deps.append(mli)
            else:
                # If we generated the .ml file, then perhaps there's a
                # pre-defined .mli file not in the buildroot.
                buildroot = kwargs.get('buildroot') or self.ctx.buildroot
                mli = mli.removeroot(buildroot + os.sep)

                if mli.exists():
                    deps.append(mli)
                else:
                    for include in includes:
                        path = mli.name
                        if include is not None: path = include / path
                        if path.exists():
                            deps.append(path)
                        break

        return deps
예제 #14
0
파일: __init__.py 프로젝트: ACGCross/felix
    def _run(self, dst, srcs, *,
            includes=(),
            libs=(),
            external_libs=(),
            pre_flags=(),
            flags=(),
            debug=None,
            optimize=None,
            custom=False,
            cc=None,
            c_libs=(),
            for_pack=None,
            preprocessor=None,
            buildroot=None,
            **kwargs):
        buildroot = buildroot or self.ctx.buildroot
        libs = tuple(chain(self.libs, external_libs, libs))

        # we need to make sure libraries are built first before we compile
        # the sources
        assert srcs or libs, "%s: no sources or libraries passed in" % dst

        dst = Path(dst).addroot(buildroot)
        dst.parent.makedirs()

        extra_srcs = []
        for lib in libs:
            if Path(lib).exists():
                extra_srcs.append(lib)
            else:
                extra_srcs.append(lib + self.lib_suffix)

        cmd = [self.exe]
        cmd.extend(self.pre_flags)
        cmd.extend(pre_flags)

        if (debug is None and self.debug) or debug:
            cmd.extend(self.debug_flags)

        if (optimize is None and self.optimize) or optimize:
            cmd.extend(self.optimize_flags)

        includes = set(includes)
        includes.update(self.includes)
        includes.add(dst.parent)

        for i in sorted(includes):
            i = Path(i)
            if i.exists():
                cmd.extend(('-I', i))

        if custom:
            cmd.append('-custom')

        cc = cc or self.cc
        if cc:
            cmd.extend(('-cc', cc))

        for lib in chain(self.c_libs, c_libs):
            if Path(lib).exists():
                cmd.extend(('-cclib', lib))
            else:
                cmd.extend(('-cclib', '-l' + lib))

        if preprocessor is not None:
            cmd.extend(('-pp', preprocessor))

        if for_pack is not None:
            cmd.extend(('-for-pack', for_pack))

        cmd.extend(self.flags)
        cmd.extend(flags)
        cmd.extend(('-o', dst))
        cmd.extend(extra_srcs)
        cmd.extend(srcs)

        self.ctx.execute(cmd, str(self),
            '%s -> %s' % (' '.join(extra_srcs + srcs), dst),
            **kwargs)

        return dst
예제 #15
0
파일: flx.py 프로젝트: eccstartup/felix
    def _run_flxg(
        self,
        src: fbuild.db.SRC,
        *,
        includes=[],
        syntaxes=[],
        imports=[],
        flags=[],
        include_std=True,
        preparse=False,
        buildroot=None,
        **kwargs
    ) -> fbuild.db.DST:
        buildroot = buildroot or self.ctx.buildroot

        src = Path(src)
        # src_buildroot = src.addroot(buildroot)

        print("Buildroot        = " + buildroot)
        print("Src to flxg      = " + src)
        if preparse:
            dst = buildroot / "cache" / "binary" + _getcwd() / src
            dst = dst.replaceext(".par")
        else:
            dst = buildroot / "cache" / "text" + _getcwd() / src
            dst = dst.replaceext(".cpp")

        print("Expected flg dst = " + dst)
        # if src != src_buildroot:
        #    src_buildroot.parent.makedirs()
        #    src.copy(src_buildroot)
        #    src = src_buildroot

        # dst.parent.makedirs()

        cmd = [self.flxg]

        if preparse:
            cmd.append("-c")

        includes = set(includes)
        includes.add(src.parent)
        includes.add(dst.parent)

        imports = list(imports)
        syntaxes = list(syntaxes)
        if include_std:
            imports.insert(0, "plat/flx.flxh")  # Unix filename correct here
            syntaxes.insert(0, "@grammar/grammar.files")  # Unix filename correct here

        cmd.extend("-I" + i for i in sorted(includes) if Path.exists(i))
        cmd.extend("--syntax=" + i for i in syntaxes)
        cmd.extend("--import=" + i for i in imports)
        cmd.append("--output_dir=" + Path(buildroot) / "cache" / "text")
        cmd.append("--cache_dir=" + Path(buildroot) / "cache" / "binary")
        cmd.extend(flags)

        if include_std:
            cmd.append("std")

        if src.ext == ".flx":
            cmd.append(src.replaceext(""))
        else:
            cmd.append(src)

        self.ctx.execute(cmd, self.flxg.name, "%s -> %s" % (src, dst), color="yellow", **kwargs)

        return dst
예제 #16
0
    def _run_flxg(self, src:fbuild.db.SRC, *,
            includes=[],
            syntaxes=[],
            imports=[],
            flags=[],
            include_std=True,
            preparse=False,
            buildroot=None,
            **kwargs) -> fbuild.db.DST:
        buildroot = buildroot or self.ctx.buildroot

        src = Path(src)
        src_buildroot = src.addroot(buildroot)

        dst = src.addroot(buildroot)

        if preparse:
            dst = dst.replaceext('.par')
        else:
            dst = dst.replaceext('.cpp')

        if src != src_buildroot:
            src_buildroot.parent.makedirs()
            src.copy(src_buildroot)
            src = src_buildroot

        dst.parent.makedirs()

        cmd = [self.flxg]

        if preparse:
            cmd.append('-c')

        includes = set(includes)
        includes.add(src.parent)
        includes.add(dst.parent)

        imports = list(imports)
        syntaxes = list(syntaxes)
        if include_std:
            imports.insert(0, 'plat/flx.flxh')
            syntaxes.insert(0, '@grammar/grammar.files')

        cmd.extend('-I' + i for i in sorted(includes) if Path.exists(i))
        cmd.extend('--syntax=' + i for i in syntaxes)
        cmd.extend('--import=' + i for i in imports)
        cmd.append('--output_dir=' + dst.parent)
        cmd.extend(flags)

        if include_std:
            cmd.append('std')

        if src.ext == '.flx':
            cmd.append(src.replaceext(''))
        else:
            cmd.append(src)

        self.ctx.execute(cmd, self.flxg.name, '%s -> %s' % (src, dst),
                color='yellow', **kwargs)

        return dst