def pyx2obj(pyxpath, objpath=None, interm_c_dir=None, cwd=None,
            logger=None, full_module_name=None, only_update=False,
            metadir=None, include_numpy=False, include_dirs=None,
            cy_kwargs=None, gdb=False, cplus=None, **kwargs):
    """
    Convenience function

    If cwd is specified, pyxpath and dst are taken to be relative
    If only_update is set to `True` the modification time is checked
    and compilation is only run if the source is newer than the
    destination

    Parameters
    ----------
    pyxpath: path string
        path to Cython source file
    objpath: path string (optional)
        path to object file to generate
    interm_c_dir: path string (optional)
        directory to put generated C file.
    cwd: path string (optional)
        working directory and root of relative paths
    logger: logging.Logger (optional)
        passed onto `simple_cythonize` and `src2obj`
    full_module_name: string (optional)
        passed onto `simple_cythonize`
    only_update: bool (optional)
        passed onto `simple_cythonize` and `src2obj`
    metadir: path string (optional)
        passed onto src2obj
    include_numpy: bool (optional)
        Add numpy include directory to include_dirs. default: False
    include_dirs: iterable of path strings (optional)
        Passed onto src2obj and via cy_kwargs['include_path']
        to simple_cythonize.
    cy_kwargs: dict (optional)
        keyword arguments passed onto `simple_cythonize`
    gdb: bool (optional)
        convenience: cy_kwargs['gdb_debug'] is set True if gdb=True,
        default: False
    cplus: bool (optional)
        Indicate whether C++ is used. default: auto-detect using `pyx_is_cplus`
    **kwargs: dict
        keyword arguments passed onto src2obj

    Returns
    -------
    Absolute path of generated object file.

    """
    assert pyxpath.endswith('.pyx')
    cwd = cwd or '.'
    objpath = objpath or '.'
    interm_c_dir = interm_c_dir or os.path.dirname(objpath)

    abs_objpath = get_abspath(objpath, cwd=cwd)

    if os.path.isdir(abs_objpath):
        pyx_fname = os.path.basename(pyxpath)
        name, ext = os.path.splitext(pyx_fname)
        objpath = os.path.join(objpath, name+objext)

    cy_kwargs = cy_kwargs or {}
    cy_kwargs['output_dir'] = cwd
    if cplus is None:
        cplus = pyx_is_cplus(pyxpath)
    cy_kwargs['cplus'] = cplus
    if gdb:
        cy_kwargs['gdb_debug'] = True
    if include_dirs:
        cy_kwargs['include_path'] = include_dirs

    interm_c_file = simple_cythonize(
        pyxpath, destdir=interm_c_dir,
        cwd=cwd, logger=logger,
        full_module_name=full_module_name,
        only_update=only_update, **cy_kwargs)

    include_dirs = include_dirs or []
    if include_numpy:
        import numpy
        numpy_inc_dir = numpy.get_include()
        if numpy_inc_dir not in include_dirs:
            include_dirs.append(numpy_inc_dir)

    flags = kwargs.pop('flags', [])
    needed_flags = ('-fwrapv', '-pthread')
    if not cplus:
        needed_flags += ('-Wstrict-prototypes',)  # not really needed..
    for flag in needed_flags:
        if flag not in flags:
            flags.append(flag)

    options = kwargs.pop('options', [])

    if kwargs.pop('strict_aliasing', False):
        raise CompilationError("Cython req. strict aliasing to be disabled.")

    if 'pic' not in options:
        options.append('pic')
    if 'warn' not in options:
        options.append('warn')

    # Let's be explicit about standard
    if cplus:
        std = kwargs.pop('std', 'c++98')
    else:
        std = kwargs.pop('std', 'c99')

    return src2obj(
        interm_c_file,
        objpath=objpath,
        cwd=cwd,
        only_update=only_update,
        metadir=metadir,
        include_dirs=include_dirs,
        flags=flags,
        std=std,
        options=options,
        logger=logger,
        inc_py=True,
        strict_aliasing=False,
        **kwargs)