1

I have a toy project that's implemented as a C++ library and exposed to Python using a Cython wrapper. After not touching the project for a few months, I tried to build it from scratch today and got the following error.

gcc -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I/Users/standage/anaconda3/include -arch x86_64 -I/Users/standage/anaconda3/include -arch x86_64 -Iinc/ -I/Users/standage/anaconda3/include/python3.6m -c contra.cpp -o build/temp.macosx-10.7-x86_64-3.6/contra.o --std=c++11 -Wno-unused-function
In file included from contra.cpp:506:
In file included from inc/bstree.hpp:13:
inc/node.hpp:20:14: error: no template named 'unique_ptr' in namespace 'std'
        std::unique_ptr< node<Data> > left;
        ~~~~~^
inc/node.hpp:21:14: error: no template named 'unique_ptr' in namespace 'std'
        std::unique_ptr< node<Data> > right;
        ~~~~~^
In file included from contra.cpp:506:
inc/bstree.hpp:35:22: error: no template named 'unique_ptr' in namespace 'std'
        typedef std::unique_ptr< node<Data> > nodeptr;
                ~~~~~^
inc/bstree.hpp:22:20: error: cannot initialize a member subobject of type 'contra_cpp::bstree::nodeptr' (aka 'int') with an rvalue
      of type 'nullptr_t'
        bstree() : _root(nullptr), _count(0) {}
                   ^     ~~~~~~~
4 errors generated.
error: command 'gcc' failed with exit status 1

The error refers to this code below (see here for full context).

#include <memory>

namespace contra_cpp
{

template<typename Data>
class node
{
    public:
        std::unique_ptr< node<Data> > left;
        std::unique_ptr< node<Data> > right;
        Data data;
        int height;

        node<Data>(Data value)
            : left(nullptr), right(nullptr), data(value), height(-1) {}
        node<Data>(Data value, int ht)
            : left(nullptr), right(nullptr), data(value), height(ht) {}
};

} // namespace contra_cpp

There is no error when I compile the C++ code alone, or when I build the Python extension (python setup.py install) on Ubuntu 16.04. The error only appears when I attempt to build the extension on Mac (10.13.4).

My first thought is that the <memory> library isn't being loaded properly, but it seems to be #include-d fine. What could be causing this error?

UPDATE

C++11 support is certainly turned on when compiling. I have the following in my setup.py file...

contra = Extension(
    'contra',
    sources=cythons + sources,
    include_dirs=['inc/'],
    language='c++',
    extra_compile_args=['--std=c++11', '-Wno-unused-function'],
    extra_link_args=['--std=c++11'],
)

...and you can see the --std=c++11 flag being included correctly in the original snippet above.

Daniel Standage
  • 8,136
  • 19
  • 69
  • 116
  • Are you actually compiling on a compiler with C++11 support, with C++11 features enabled? – user2357112 Apr 12 '18 at 19:43
  • Make sure you are building the code as C++11 (or C++14, C++17). – Jesper Juhl Apr 12 '18 at 19:43
  • Looks like the build command line does say `--std=c++11`. – user2357112 Apr 12 '18 at 19:45
  • Which Python version, and how did you install it (Apple pre-installed, Python.org installer, Homebrew, Anaconda, etc.)? Don't recent versions use either `cc` or `clang` rather than `gcc` by default on Mac? (It shouldn't matter on 10.13, but there were versions that didn't work a few years back that `distutils` must have had to deal with, and I can't imagine they'd revert to incorrectly hardcoding `gcc` on Mac just because it now happens to work again…) – abarnert Apr 12 '18 at 19:50
  • Never mind the question; I can see by scrolling way to the right that you're using 3.6, and Anaconda. So instead: are you using Cython from Anaconda (whether pre-installed with full Anaconda, or `conda`'d with mini)? – abarnert Apr 12 '18 at 19:53
  • @abarnert I'm using the Anaconda Python distribution. It looks like `python setup.py install` uses gcc and `pip install .` uses clang. ¯\\_(ツ)_/¯ – Daniel Standage Apr 12 '18 at 19:53
  • @abarnert I'm not installing Cython with Anaconda, so it must be using a pip-installed Cython. – Daniel Standage Apr 12 '18 at 19:54
  • I think full Anaconda comes with Cython, but the two smaller distributions don't… but I could be wrong about any part of that. If so, maybe pip-uninstalling it and conda-installing it would make a difference? But first, both for debugging purposes and as a possible workaround—does `pip install .` get the same error, or does it work? – abarnert Apr 12 '18 at 19:56
  • 1
    And if it _does_ work: does `pip`'s `clang` invocation explicitly specify one of the two C++ stdlib options, e.g. via `-stdlib=libc++` or `-lc++`? Because I know `libc++` is the default on OS X with recent versions of `clang`, but it may _not_ be the default if you use the fake-`gcc`-as-front-end-to-`clang` wrapper. – abarnert Apr 12 '18 at 19:57
  • @abarnert The `pip install .` command gives the same error. pip uninstalling cython and reinstalling cython with conda doesn't help. :( – Daniel Standage Apr 12 '18 at 19:59
  • OK, one last thing to try: edit the link and compile args to try all of the following combinations and see if the results are any different: (1) `-stdlib=libc++`, (2) `-stdlib=libc++ -lc++experimental`, (3) `-stdlib=libstdc++`. The first one should be the best option, and also the default (since your command line isn't specifying any of them), so this should be pointless… but it's worth ruling out unless someone has any better ideas to check for. – abarnert Apr 12 '18 at 20:02
  • @abarnert After adding `-stdlib=libc++` to the compile args, I get this. `clang: error: invalid deployment target for -stdlib=libc++ (requires OS X 10.7 or later)` – Daniel Standage Apr 12 '18 at 20:02
  • 1
    OK, that's almost surely nailed down the problem: For some reason, some piece of the chain thinks you need 10.6 support and therefore uses `libstdc++` instead of `libc++` and therefore random chunks of C++11 don't work… But I have no idea _why_ that's happening, or how to fix it. From your output, that `temp.macosx-10.7-x86_64-3.6` in the path, clearly it starts off thinking it's building for 10.7+ rather than 10.6+, and I don't know how to tell where that goes wrong along the way. – abarnert Apr 12 '18 at 20:06
  • @abarnert Explicitly overriding the the system gcc-symlinked clang installation with my homebrew-installed gcc did the trick. See https://github.com/anttttti/Wordbatch/issues/1#issuecomment-357213491. Feels dirty and unnecessary... – Daniel Standage Apr 12 '18 at 20:25
  • Try setting `export MACOSX_DEPLOYMENT_TARGET=10.7` environment variable before compiling. – l'L'l Apr 12 '18 at 20:26
  • @DanielStandage Yeah, that does seem like the wrong solution… but if it works and that one-time workaround is all you need, I’d just do it for now and monitor this question to see if anyone figures out how to debug it and fix it properly. – abarnert Apr 12 '18 at 20:27
  • @abarnert For the moment it works, but it's an unsatisfying solution for any potential user that has to jump through those hoops one day. – Daniel Standage Apr 12 '18 at 20:43
  • @l'L'l Same error as before with `export MACOSX_DEPLOYMENT_TARGET=10.7`. – Daniel Standage Apr 12 '18 at 20:50
  • @DanielStandage: How about adding `-mmacosx-version-min=10.7` to your compile command, any difference? – l'L'l Apr 13 '18 at 01:18
  • 1
    @DanielStandage Agreed 100%, that’s why I suggested just do it for now, but keep monitoring this question for help debugging it further. I wouldn’t accept that as a final answer any more than you want to (unless I’d actually proven to myself it was necessary for reasons I understood, and that any proper fix would be unfeasible, and I doubt that’s how this will turn out). – abarnert Apr 13 '18 at 04:39
  • It should be not `—std=c++11` but `-std=c++11` with only one `-` or am I wrong? – ead May 04 '18 at 20:04

0 Answers0