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.