6

I am trying to build a C based Python extension that uses a ffmpeg libraries. Since there are a bunch of libraries I have to import. I used CMake. I followed the instructions from python doc

The build with CMake goes fine without any issues. But when I import the library I get the following exception.

Fatal Python error: PyThreadState_Get: no current thread

I am using mac with python2.7.14 (installed using Brew).

The following is my

CMakeLists.txt

cmake_minimum_required(VERSION 3.11)
project(extractor C)

set(CMAKE_C_STANDARD 99)

set(EXECUTABLE_NAME "extractor")

set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules)

set(EXTRACTOR_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
set(target_dir "bin")

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -std=99")

add_library(${EXECUTABLE_NAME} SHARED src/frame_extractor.c)
# add_library(${EXECUTABLE_NAME} SHARED src/dipoza.c)

# add_executable(${EXECUTABLE_NAME} main.c)
include_directories(".")
find_package(FFmpeg REQUIRED)

if (FFMPEG_FOUND)
    message("Found FFMPEG/LibAV libraries ${FFMPEG_LIBRARIES}")
    include_directories(${FFMPEG_INCLUDE_DIR})
    target_link_libraries(${EXECUTABLE_NAME} ${FFMPEG_LIBRARIES})
else (FFMPEG_FOUND)
    message("cant find libavcodec, libavformat or libavutil. add them manually!!")
endif (FFMPEG_FOUND)

target_link_libraries(${EXECUTABLE_NAME} ${FFMPEG_LIBRARIES})
target_link_libraries (${EXECUTABLE_NAME} "-lm")
target_link_libraries(${EXECUTABLE_NAME} "-framework CoreServices")
target_link_libraries(${EXECUTABLE_NAME} "-framework CoreFoundation")
target_link_libraries(${EXECUTABLE_NAME} "-framework AudioToolbox")
target_link_libraries(${EXECUTABLE_NAME} "-framework VideoToolbox")
target_link_libraries(${EXECUTABLE_NAME} "-framework CoreAudio")
target_link_libraries(${EXECUTABLE_NAME} "-framework CoreMedia")
target_link_libraries(${EXECUTABLE_NAME} "-framework CoreVideo")
target_link_libraries(${EXECUTABLE_NAME} "-framework AVFoundation")
target_link_libraries(${EXECUTABLE_NAME} "-framework Security")
target_link_libraries(${EXECUTABLE_NAME} /usr/lib/libbz2.1.0.dylib)
target_link_libraries(${EXECUTABLE_NAME} /usr/lib/libz.1.dylib)
target_link_libraries(${EXECUTABLE_NAME} /usr/lib/libiconv.dylib)
target_link_libraries(${EXECUTABLE_NAME} /usr/lib/liblzma.dylib)
target_link_libraries(${EXECUTABLE_NAME} /usr/local/lib/libswresample.a)
target_link_libraries(${EXECUTABLE_NAME} /usr/local/Cellar/fdk-aac/0.1.6/lib/libfdk-aac.dylib)
target_link_libraries(${EXECUTABLE_NAME} /usr/local/lib/libx264.dylib)

# Add python dependencies -
# ERROR - It picks up the default version from the machine which is 2.7.10
# find_package( PythonInterp 2.7 REQUIRED)
# find_package(PythonLibs 2.7 REQUIRED)

message("GURU - python include dirs = ${PYTHON_INCLUDE_DIRS}")
message("GURU - python include dirs = ${PYTHON_LIBRARIES}")

set(PYTHON_INCLUDE_DIRS "/usr/local/Cellar/python/2.7.14/Frameworks/Python.framework/Versions/2.7/include/python2.7")
set(PYTHON_LIBRARIES "/usr/local/Cellar/python/2.7.14/Frameworks/Python.framework/Versions/2.7/lib/libpython2.7.dylib")

message("GURU - python include dirs = ${PYTHON_INCLUDE_DIRS}")
message("GURU - python include dirs = ${PYTHON_LIBRARIES}")
# dipoza()
include_directories(${PYTHON_INCLUDE_DIRS})
target_link_libraries(${EXECUTABLE_NAME} ${PYTHON_LIBRARIES})



# Apple creates annoying dylib extension for shared libraries
if(APPLE)
    SET(CMAKE_SHARED_LIBRARY_SUFFIX ".so")
    set(CMAKE_SHARED_LIBRARY_PREFIX "")
endif(APPLE)

Even a simple program like below fails

static PyObject* extractor(PyObject* self, PyObject* args, PyObject* keywds) {
    int width=1280, height=720;
    char *file_path = NULL;

    static char *kwlist[] = {"width", "height", "file_path", NULL};

    if (!PyArg_ParseTupleAndKeywords(args, keywds, "ii|s", kwlist, &width, &height, &file_path)) {
        return NULL;
    }

    printf("input parameters width=%d height=%d file_name=%s", width, height, file_path);
    return NULL;
}

static char extractor_docs[] =
        "add( ): add all elements of the list\n";

static PyMethodDef extractor_methods[] = {
        {"extractor", (PyCFunction)extractor, METH_VARARGS|METH_KEYWORDS, extractor_docs },
        {NULL, NULL, 0, NULL}
};

PyMODINIT_FUNC initextractor(void) {
    Py_InitModule3("extractor", extractor_methods, "Add all ze methods");
}

Thanks a lot for any help in resolving this.

Gatothgaj
  • 1,633
  • 2
  • 16
  • 27
  • 1
    0) Please give a minimal project which reproduces the problem. 1) Using modern CMake (3.11) no need to use so many variables -- use imported targets 2) use `project` w/ `VERSION` and eliminate `EXTRACTOR_VERSION` (which is set incorrectly btw) 3) no need to call `target_link_libraries` so many times -- just list all libs in a single call 4) use `target_include_directories` instead of `include_directories` 5) no need to check `xxx_FOUND` if you provide `REQUIRED` to `find_package` 6) no need to introduce `EXECUTABLE_NAME` variable -- just use `extractor` or `${PROJECT_NAME}` 7) – zaufi Jul 26 '18 at 14:53
  • 7) use `target_compile_options` instead of hack w/ `CMAKE_XXX_FLAGS` 8) provide `CMAKE_BUILD_TYPE` (or set desired default before `project`) instead of giving `-g` 9) use `find_package` instead of hardcoded paths -- most of libs u use have a shipped finder module which provides imported targets (Python, BZip2, ZLIB, & etc) – zaufi Jul 26 '18 at 14:56
  • That's a run-time error. A google search indicates that it's associated when the the module is linked to a python library that is different from the python interpreter being used to import the module. – fdk1342 Dec 24 '18 at 00:44

0 Answers0