Currently, on Linux, setupext.py explicitly adds /usr/{,local/}include to the search path (because it is listed in get_base_dirs). This can be confirmed by checking e.g. the output of python setup.py build.
This makes it impossible to compile matplotlib using a non-system compiler (e.g., anaconda now provides gcc7.2, see https://www.anaconda.com/blog/developer-blog/utilizing-the-new-compilers-in-anaconda-distribution-5/) that comes with its own headers (in /path/to/env/lib/gcc/x86_64-conda_cos6-linux-gnu/7.2.0/include) which may be incompatible with the system headers. Note that conda's gcc is configured to indeed look into its own headers directory instead of /usr/include.
In the specific case of gcc7.2.0 from anaconda, explicitly adding /usr/include causes it to use /usr/include/math.h instead of its own math.h; Ubuntu's /usr/include/math.h is incompatible because it tries to include bits/mathdef.h and this file is under /usr/lib/gcc/x86_64-linux-gnu/5/include, which is part of the default path of the system gcc but not the conda gcc.
We currently explicitly look up these default paths to check that the include files are actually present, as a fallback in case they exist but no pkg-config information is present. I propose instead to require pkg-config information to be present (as a check that the package is indeed installed) and not try to manually look for the headers.
This would cause a build failure if there is some linux distro that includes the headers for our dependencies without including the pkg-config info, which I am happy to claim to be a bad idea.
This would also mean that if one is using a non-system compiler (e.g., a conda compiler), then one would also need to install freetype/libpng/zlib in a place this compiler knows about (e.g., via a conda package) rather than relying on the system version. Here too I think this is a reasonable restriction (if you know to set up your own non-system compiler you should know how to set up the dependencies properly too...).
/home/alee/miniconda3/envs/test/bin/x86_64-conda_cos6-linux-gnu-cc -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -DFREETYPE_BUILD_TYPE=system -DPY_ARRAY_UNIQUE_SYMBOL=MPL_matplotlib_ft2font_ARRAY_API -DNPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION -D__STDC_FORMAT_MACROS=1 -I/home/alee/miniconda3/envs/test/lib/python3.6/site-packages/numpy/core/include -I/home/alee/miniconda3/envs/test/include/freetype2 -I/usr/local/include -I/usr/include -I. -I/home/alee/miniconda3/envs/test/include/python3.6m -c src/ft2font.cpp -o build/temp.linux-x86_64-3.6/src/ft2font.o
In file included from /home/alee/miniconda3/envs/test/include/python3.6m/pyport.h:194:0,
from /home/alee/miniconda3/envs/test/include/python3.6m/Python.h:50,
from src/mplutils.h:31,
from src/ft2font.cpp:9:
/usr/include/math.h:31:10: fatal error: bits/math-vector.h: No such file or directory
#include <bits/math-vector.h>
^~~~~~~~~~~~~~~~~~~~
compilation terminated.
error: command '/home/alee/miniconda3/envs/test/bin/x86_64-conda_cos6-linux-gnu-cc' failed with exit status 1
Expected outcome
Successful compilation. In the example above, this can be achieved by patching setupext's get_base_dirs to return an empty list -- this works because pkg-config info is available for all packages (so we don't do any manual header lookup ourselves), giving information to gcc about where to find the headers.
Activity
tacaswell commented on Nov 10, 2017
👍 with the caveat that we make sure how to re-inject these paths at configuration time is well documented.
anntzer commented on Nov 10, 2017
That's the job of CFLAGS (or CPLUS_INCLUDE_PATH if you want to be really careful).