Gio
Gio

Reputation: 3340

Python / C++ binding, how to link agains static c++ library (portaudio) with distutils?

I am trying to staticaly link the "c++ portaudio library" against my "C++ demo module" which is a python callable library (module).

I'm doing this with distutils, and in order to perform the static linking, I've added the libportaudio to the extra_objects argument, as follows:

module1 = Extension(
    "demo",
    sources=cppc,
    # TODO remove os dependency
    extra_compile_args=gccArgs,
    # link against shared libraries
    #libraries=[""]
    # link against static libraries
    extra_objects=["./clib-3rd-portaudio/libportaudio.a"]) # << I've added the static lib here

Compiling with "python setup.py build" results in the following linker error:

/usr/bin/ld: ./clib-3rd-portaudio/libportaudio.a(pa_front.o): relocation R_X86_64_32 against `.rodata.str1.8' can not be used when making a shared object; recompile with -fPIC ./clib-3rd-portaudio/libportaudio.a: error adding symbols: Bad value collect2: error: ld returned 1 exit status

So at this point I've tried the obvious, I've added the -fPIC flagg to gccArgs (note extra_compile_args=gccArgs above), as follows:

gccArgs = [
    "-Icsrc",
    "-Icsrc/paExamples",
    "-Icinc-3rd-portaudio",
    "-Icinc-3rd-portaudio/common",
    "-Icinc-3rd-portaudio/linux",
    "-fPIC"] # << I've added the -fPIC flag here

However this results in the exact same error, so I guess the -fPIC flag is not the root cause. I'm probably missing something trivial, but I'm a bit lost here, hope somebody can help.

Upvotes: 1

Views: 1544

Answers (1)

gdlmx
gdlmx

Reputation: 6789

As the error message said, you should recompile the external library libportaudio.a with -fPIC argument, NOT your own codes. That's why it doesn't help to add -fPIC to your extra_compile_args.

Several other posts suggest that the file libportaudio.a cannot be used to build shared library, probably because the default build settings of portaudio don't include -fPIC.

To recompile portaudio correctly, download the source and try to run ./configure with -shared option (or something similar). If you cannot find the proper option, then modify the Makefile and append -fPIC to the extra compile options. You can also compile each object file manually and pack them into libportaudio.a.

Since your target file (libdemo.so) is a shared library, you must make sure ANY object codes included inside are compiled with -fPIC option. To understand why you need this option, please refer to: What does -fPIC mean when building a shared library? and Position Independent Code (PIC) in shared libraries

Upvotes: 1

Related Questions