mapnik / python-mapnik

Python bindings for mapnik
GNU Lesser General Public License v2.1
157 stars 90 forks source link

Current hard-coded pycairo flags in setup.py hinder installs where Python and pycairo have different prefixes #234

Open jwilges opened 3 years ago

jwilges commented 3 years ago

Issue

As in the title, the current hard-coded pycairo flags in setup.py hinder installs where Python and pycairo have different prefixes.

Clarification

In a nutshell, if pycairo resides outside of Python's sys.exec_prefix, the current setup.py behavior is incorrect.

See this Dockerfile gist for an example of this issue in a python:3.8-slim-based container that uses Debian's python3-cairo-dev package to provide pycairo.

Reference

Current setup.py:

if os.environ.get("PYCAIRO", "false") == "true":
    try:
        extra_comp_args.append('-DHAVE_PYCAIRO')
        print("-I%s/include/pycairo".format(sys.exec_prefix))
        extra_comp_args.append("-I{0}/include/pycairo".format(sys.exec_prefix))
        #extra_comp_args.extend(check_output(["pkg-config", '--cflags', 'pycairo']).strip().split(' '))
        #linkflags.extend(check_output(["pkg-config", '--libs', 'pycairo']).strip().split(' '))
    except:
        raise Exception("Failed to find compiler options for pycairo")

It looks like someone tried to leverage pkg-config at some point but ultimately disabled it.

Suggestion

I am attaching a patch that aims to give us the best of both worlds: flags sourced from pkg-config when viable with backward compatible fallback flag values when pkg-config detection fails.

This could be rolled up into a slightly better generic pkg-config pattern if other dependencies could benefit from similar behavior but I made the patch solely for pycairo since that was the only preexisting use case of pkg-config in setup.py.

tobwen commented 2 years ago

Thanks for this patch, but maybe we should also expose this as a system variable. I've installed pycairo in a venv and it doesn't come with a pkg-config configuration. So neither the original one nor your code finds the files inside the venv.