1

I am testing of running a Python thread in a c program with a simple example like the below

# demo.py
import time

for i in range(1, 101):
    print(i)
    time.sleep(0.1)
// demo.c
#include <Python.h>
#include <pthread.h>
#include <stdio.h>

void *run_python_script(void *arg) {
    Py_Initialize();

    if (!Py_IsInitialized()) {
        fprintf(stderr, "Python initialization failed\n");
        return NULL;
    }

    FILE *fp = fopen("demo.py", "r");
    if (fp == NULL) {
        fprintf(stderr, "Failed to open demo.py\n");
        Py_Finalize();
        return NULL;
    }

    PyRun_SimpleFile(fp, "demo.py");
    fclose(fp);
    Py_Finalize();

    return NULL;
}

int main() {
    pthread_t python_thread;

    if (pthread_create(&python_thread, NULL, run_python_script, NULL) != 0) {
        fprintf(stderr, "Failed to create thread\n");
        return 1;
    }

    pthread_join(python_thread, NULL);
    printf("Python thread has finished. Exiting program.\n");
    return 0;
}

Then I build the above code with the following command

gcc demo.c -o demo -lpthread -I$(python3-config --includes) $(python3-config --ldflags) $(python3-config --cflags)

Then I get the following error:

/usr/bin/ld: /tmp/ccsHQpZ3.o: in function `run_python_script':
demo.c:(.text.run_python_script+0x7): undefined reference to `Py_Initialize'
/usr/bin/ld: demo.c:(.text.run_python_script+0xd): undefined reference to `Py_IsInitialized'
/usr/bin/ld: demo.c:(.text.run_python_script+0x41): undefined reference to `PyRun_SimpleFileExFlags'
/usr/bin/ld: demo.c:(.text.run_python_script+0x50): undefined reference to `Py_Finalize'
/usr/bin/ld: demo.c:(.text.run_python_script+0xab): undefined reference to `Py_Finalize'
collect2: error: ld returned 1 exit status

The python library do exists,


python3-config --ldflags
-L/home/henry/anaconda3/lib/python3.9/config-3.9-x86_64-linux-gnu -L/home/henry/anaconda3/lib  -lcrypt -lpthread -ldl  -lutil -lm -lm


ls -1 ~/anaconda3/lib | grep python
libpython3.9.so
libpython3.9.so.1.0
libpython3.so
python3.9

I have no idea about is link error.

2
  • The error message is telling you that you have not included the name of the Python library, so the linker cannot find the references to the Python calls. You need to check what is generated by the $(python3-config --ldflags) expression to see if it is finding the correct libraries. Commented May 8 at 8:54
  • @OldBoy They do exists, I update the information in the question, that's why it confuses me. Commented May 8 at 8:59

1 Answer 1

3

You need to pass --embed to python3-config because you are embedding a Python interpreter in your program. Observe the difference:

$ python3-config --ldflags
-L/usr/lib/python3.10/config-3.10-x86_64-linux-gnu 
-L/usr/lib/x86_64-linux-gnu  -lcrypt -ldl  -lm -lm

$ python3-config --embed --ldflags
-L/usr/lib/python3.10/config-3.10-x86_64-linux-gnu 
-L/usr/lib/x86_64-linux-gnu -lpython3.10 -lcrypt -ldl  -lm -lm
Sign up to request clarification or add additional context in comments.

Comments

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.