4

I'm trying to find a way to build and run a cpp file with an embedded python interpreter using pybind11.

From this tutorial, it uses CMake but I'm looking for a way to do this without CMake.

Here's what I tried.

In example.cpp:

#include <pybind11/embed.h> // everything needed for embedding
namespace py = pybind11;

int main() {
    py::scoped_interpreter guard{}; // start the interpreter and keep it alive

    py::print("Hello, World!"); // use the Python API
}

And in the Terminal when I run the following: (builds fine)

c++ -O3 -Wall -std=c++11 -undefined dynamic_lookup `python3 -m pybind11 --includes` example.cpp -o example

And then run the binary with

./example

I get the following error:

dyld: Symbol not found: _PyBaseObject_Type Referenced from: /Users/cuinjune/Desktop/pybindtest/./example Expected in: flat namespace in /Users/cuinjune/Desktop/pybindtest/./example zsh: abort ./example

Is there any possible way to properly build and execute a cpp file with an embedded python interpreter using pybind11? (without using CMake)

1 Answer 1

5

Link with the python library, which defines that symbol (and more that you will need).

Assuming a standard installation, that would be no more than adding:

`-lpython`

to the CLI (or -lpython3 etc. if multiple python libraries are present on your system). You could also add instead:

`python3-config --libs`

if your python3 has python3-config installed.

EDIT: based on the comments, the relevant library directory is not available to the linker in your setup. One option is to use the full set of flags instead:

`python3-config --ldflags`

where I'm still assuming that python3-config matches your python3. If not, then the alternative is to get the directory distutils. Prepend with -L and add -lpython or -lpython3 depending on your installation:

-L`python3 -c 'import distutils.sysconfig as ds; print(ds.get_config_var("LIBDIR"))'` -lpython

(And yes, there is also an "LDFLAGS" config_var, but those are the flags for building python and are unlikely what you want.)

Sign up to request clarification or add additional context in comments.

7 Comments

I tried the following: c++ -O3 -Wall -std=c++11 -undefined dynamic_lookup python3-config --libs -lpython python3 -m pybind11 --includes example.cpp -o example but I get ld: library not found for -lpython3.7m error. I also tried -lpython3.7m but same error.
When I try c++ -O3 -Wall -std=c++11 -undefined dynamic_lookup -lpython python3 -m pybind11 --includes example.cpp -o example, it builds fine but when I run the binary, it says dyld: Symbol not found: _PyInstanceMethod_Type.
I updated the answer. The former is the way to go; the latter most likely picks up a python2 library (b/c PyInstanceMethod_Type exists in 3, not in 2).
c++ -O3 -Wall -std=c++11 -undefined dynamic_lookup python3-config --ldflags python3 -m pybind11 --includes example.cpp -o example worked. Thank you so much!
I'm not familiar with Xcode and it would not surprise me if it had direct support for Python since other IDEs do. But when editing the linker flags, you're likely going to have to put in the full flags directly (python3-config is a program, so unless Xcode compiles on a shell, it won't be run). Get the flags by running python3-config --ldflags on the shell, then copy the result to the Other Linker Flags. Since you're not distributing the Xcode build environment, hard-wiring the output should not be a practical problem.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.