Vs code, Python, pybind11, linking error

Hey, guys,
I would like to ask if anyone has solved the problem of building a python module from c++ code. I’ve seen many different tutorials on this topic, but haven’t found a satisfactory answer.

My goal is to be able to run the compilation process in the “pybind11” environment to create a python simulation module. Then switch to the “uno” environment and compile the code into the arduino uno without changing the code. Unfortunately I have a problem with linking pybind11\program.exe please can someone advise me what I am doing wrong?

platformio.ini:

[env:uno]
platform = atmelavr
board = uno
framework = arduino

[env:pybind11]
platform = native
lib_deps = pybind11
build_flags = 
    -IC:/Users/.../AppData/Local/Programs/Python/Python311/Lib/site-packages/pybind11/include  ;přidání cesty k pythonem sztaženému modulu pybind11
    -IC:/Users/.../AppData/Local/Programs/Python/Python311/include

main.cpp

#include "pybind11/pybind11.h"

int add(int a, int b) {
    return a + b;
}

PYBIND11_MODULE(example, m) {
    m.def("add", &add, "A function which adds two numbers");
}

int main()
{

}

compiler output:

Verbose mode can be enabled via `-v, --verbose` option
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Library Manager: Installing pybind11
Warning! Could not find the package with 'pybind11' requirements for your system 'windows_amd64'
Found 1 compatible libraries
Scanning dependencies...
No dependencies
Building in release mode
Compiling .pio\build\pybind11\src\main.o
Linking .pio\build\pybind11\program.exe
C:/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: .pio\build\pybind11\src\main.o:main.cpp:(.text+0xae): undefined reference to `__imp_PyType_IsSubtype'
C:/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: .pio\build\pybind11\src\main.o:main.cpp:(.text+0x123): undefined reference to `__imp__Py_Dealloc'
C:/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: .pio\build\pybind11\src\main.o:main.cpp:(.text+0x2c4): undefined reference to `__imp_PyCFunction_Type'

and many more similar errors folowing.

Thank you for any advice.

This works for me:

[env:uno]
platform = atmelavr
board = uno
framework = arduino

[env:pybind11]
platform = native
extra_scripts = make_shared.py
build_flags =
  -I/usr/include/python3.10
  -I/home/max/.local/lib/python3.10/site-packages/pybind11/include
  -fPIC

with make_shared.py being created at the same level as the platformio.ini and having content:

Import("env")
env.Prepend(LINKFLAGS=["-shared", "-fPIC"])

The crucial thing is the -shared and -fPIC so that it doesn’t try to build a statically linked ELF binary, the implementation of the missing functions will be provided by other libraries at runtime then.

No dependencies
Building in release mode
g++ -o .pio/build/pybind11/src/main.o -c -fPIC -DPLATFORMIO=60108 -Iinclude -Isrc -I/usr/include/python3.10 -I/home/max/.local/lib/python3.10/site-packages/pybind11/include src/main.cpp
g++ -o .pio/build/pybind11/program -shared -fPIC .pio/build/pybind11/src/main.o -L.pio/build/pybind11
====================================================================== [SUCCESS] Took 5.35 seconds ======================================================================
$ file .pio/build/pybind11/program 
.pio/build/pybind11/program: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, BuildID[sha1]=729b1f13cee980bcf8ea477129d2f6f29a3904b1, not stripped

This is in agreement with

https://pybind11.readthedocs.io/en/stable/compiling.html#building-manually