1

Summary: I'm unable to get an example from the pybind11 documentation to compile with g++ inside Docker.

I have a directory with two files, hello.cpp and Dockerfile. The contents of the Dockerfile are

FROM phusion/baseimage:0.11
# Use baseimage-docker's init system
CMD ["/sbin/my_init"]
# Update and install packages
RUN apt update && apt -y upgrade && apt -y install \
    build-essential \
    python3-dev \
    python3-pip 
RUN pip3 install pybind11
# Clean up apt mess
RUN apt clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

The c++ file hello.cpp contains

#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
}

The .cpp content comes from the pybind11 tutorial

To compile inside the container, I figured out where pybind11 lives using

 python3 -c "import pybind11; print(pybind11.get_include());"

Then I figured out where Python.h lives using

 python3-config --includes

I also am using the flags specified by

 python3-config --cflags --ldflags

When I run the following I get an error.

g++ -I /usr/local/lib/python3.6/dist-packages/pybind11/include \
-I /usr/include/python3.6m \
-Wno-unused-result -Wsign-compare -g -fdebug-prefix-map=/build/python3.6-e9shER/python3.6-3.6.9=. -specs=/usr/share/dpkg/no-pie-compile.specs -fstack-protector -Wformat -Werror=format-security  -DNDEBUG -g -fwrapv -O3 -Wall -L/usr/lib/python3.6/config-3.6m-x86_64-linux-gnu \
    -L/usr/lib -lpython3.6m -lpthread -ldl  -lutil -lm  -Xlinker -export-dynamic -Wl,-O1 -Wl,-Bsymbolic-functions \
    -std=c++14 \
    -fPIC \
        hello.cpp

I'm showing a snippet of the top and bottom of the messages.

call_calc.cpp: In function ‘int main()’:
call_calc.cpp:13:9: warning: unused variable ‘n’ [-Wunused-variable]
    int n = result.cast<int>();
        ^
/tmp/ccpr9DIE.o: In function `pybind11_static_get':
/usr/local/lib/python3.6/dist-packages/pybind11/include/pybind11/detail/class.h:48: undefined reference to `PyProperty_Type'
/tmp/ccpr9DIE.o: In function `pybind11_static_set':
/usr/local/lib/python3.6/dist-packages/pybind11/include/pybind11/detail/class.h:54: undefined reference to `PyProperty_Type'
/tmp/ccpr9DIE.o: In function `pybind11::cast_error::set_error() const':
/usr/local/lib/python3.6/dist-packages/pybind11/include/pybind11/detail/common.h:722: undefined reference to `PyExc_RuntimeError'
/usr/local/lib/python3.6/dist-packages/pybind11/include/pybind11/detail/common.h:722: undefined reference to `PyErr_SetString'
/tmp/ccpr9DIE.o: In function `pybind11::detail::translate_exception(std::__exception_ptr::exception_ptr)':
...snipped...
/usr/local/lib/python3.6/dist-packages/pybind11/include/pybind11/cast.h:1052: undefined reference to `PyNumber_Check'
/usr/local/lib/python3.6/dist-packages/pybind11/include/pybind11/cast.h:1053: undefined reference to `PyNumber_Long'
/usr/local/lib/python3.6/dist-packages/pybind11/include/pybind11/cast.h:1056: undefined reference to `PyErr_Clear'
/tmp/ccpr9DIE.o: In function `main':
/usr/local/lib/python3.6/dist-packages/pybind11/include/pybind11/pybind11.h:942: undefined reference to `PyImport_ImportModule'
collect2: error: ld returned 1 exit status

There are a couple related questions 1,2,3 but I am unable to apply those to my situation.

I am able to get the simple function example to work.

When I use

g++ -O3 -Wall -shared -std=c++17 -fPIC `python3 -m pybind11 --includes` example_hello_world_py_inside.cpp

I do get a binary but running the binary triggers a segmentation fault.

Ben
  • 563
  • 1
  • 5
  • 12
  • Hi Ben, did you try compiling with `cmake` ? It could be easier, there are [examples provided on Github](https://github.com/pybind/cmake_example) or [in the documentation](https://pybind11.readthedocs.io/en/stable/compiling.html#cmake-example) – Christian Dec 22 '20 at 18:03

0 Answers0