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)

Zack Lee
  • 2,784
  • 6
  • 35
  • 77

1 Answers1

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.)

Wim Lavrijsen
  • 3,453
  • 1
  • 9
  • 21
  • 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. – Zack Lee Jan 04 '20 at 07:20
  • 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`. – Zack Lee Jan 04 '20 at 07:24
  • 1
    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). – Wim Lavrijsen Jan 04 '20 at 08:43
  • **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! – Zack Lee Jan 04 '20 at 10:01
  • Could you please teach me how to add ``python3-config --ldflags`` into an Xcode project? I tried adding it to `Other Linker Flags` but it generates an error. – Zack Lee Jan 04 '20 at 10:22
  • 1
    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. – Wim Lavrijsen Jan 04 '20 at 16:57
  • Thank you so much! Based on your answer, I followed `Listing 2 Getting linker flags` section from https://developer.apple.com/library/archive/technotes/tn2328/_index.html and it worked perfectly. – Zack Lee Jan 04 '20 at 20:14