c++-python-cmake-binding-stdin-line-1-importerror-dynamic-module-does-not-def
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 2.9k
- Forks
- 1.4k
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 1
Description
I am trying to install a module with python and create an extension of a cop files detectc.cpp But after I do
python3 setup.py install
install success. then.
python
import detect
I get error
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: dynamic module does not define module export function (PyInit_detectc)
Files to reproduce:
setup.py
from setuptools import setup, Extension
from setuptools.command.build_ext import build_ext
import os
import platform
import subprocess
import sys
from pprint import pprint
c_module_name = "detectc"
cmake_cmd_args = []
for f in sys.argv:
if f.startswith('-D'):
cmake_cmd_args.append(f)
for f in cmake_cmd_args:
sys.argv.remove(f)
class CMakeBuild(build_ext):
def build_extensions(self):
try:
out = subprocess.check_output(['cmake', '--version'])
except OSError:
raise RuntimeError('Cannot find CMake executable')
for e in self.extensions:
extdir = os.path.abspath(os.path.dirname(self.get_ext_fullpath(e.name)))
cfg = 'Release'
cmake_args = [
'-DPYTHON_EXECUTABLE=/home/ubuntu/anaconda3/envs/dutchman/bin/python',
'-DCMAKE_BUILD_TYPE=%s' % cfg,
'-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_{}={}'.format(cfg.upper(), extdir),
'-DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_{}={}'.format(cfg.upper(), self.build_temp),
# '-DPYTHON_EXECUTABLE={}'.format(sys.executable)
]
build_ext.build_extensions(self)
cmake_args += cmake_cmd_args
print(cmake_args)
print(e.cmake_lists_dir)
if not os.path.exists(self.build_temp):
os.makedirs(self.build_temp)
subprocess.check_call(['cmake', e.cmake_lists_dir] + cmake_args,
cwd=self.build_temp)
subprocess.check_call(['cmake', '--build', '.', '--config', cfg],
cwd=self.build_temp)
class CMakeExtension(Extension):
def __init__(self, name, cmake_lists_dir='.', **kwa):
Extension.__init__(self, name, sources=[], **kwa)
self.cmake_lists_dir = os.path.abspath(cmake_lists_dir)
print(self.cmake_lists_dir)
setup(name='detectc',
version='1.1.0',
description='Generate displacement fields with known volume changes',
author='Martino Pilia',
author_email='martino.pilia@gmail.com',
install_requires=['numpy>=1.15.1'],
ext_modules=[CMakeExtension(c_module_name)],
cmdclass={'build_ext': CMakeBuild},
)
CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(detectc_)
find_package(PythonInterp 3.5 REQUIRED)
# This comes to hand if we also need to use the NumPy C API
exec_program(${PYTHON_EXECUTABLE}
ARGS "-c \"import numpy; print(numpy.get_include())\""
OUTPUT_VARIABLE NUMPY_INCLUDE_DIR
RETURN_VALUE NUMPY_NOT_FOUND
)
set(SRCS "detectc.cpp")
#add_library(detectc_ SHARED ${SRCS})
add_library(detectc_ ${SRCS})
set_target_properties(
detectc_
PROPERTIES
PREFIX ""
OUTPUT_NAME "detectc"
LINKER_LANGUAGE CXX
)
# Find NumPy headers
exec_program(${PYTHON_EXECUTABLE}
ARGS "-c \"import numpy; print(numpy.get_include())\""
OUTPUT_VARIABLE NUMPY_INCLUDE_DIR
RETURN_VALUE NUMPY_NOT_FOUND
)
if(NUMPY_NOT_FOUND)
message(FATAL_ERROR "NumPy headers not found")
endif()
# Find Python headers
exec_program(${PYTHON_EXECUTABLE}
ARGS "-c \"import sysconfig; print(sysconfig.get_paths()['include'])\""
OUTPUT_VARIABLE PYTHON_INCLUDE_DIRS
RETURN_VALUE PYTHON_INCLUDE_DIRS_NOT_FOUND
)
if(PYTHON_INCLUDE_DIRS_NOT_FOUND)
message(FATAL_ERROR "Python headers not found")
endif()
target_include_directories(detectc_ PUBLIC
${PYTHON_INCLUDE_DIRS}
${NUMPY_INCLUDE_DIR}
)
detectc.cpp
#include <python3.5/Python.h>
static PyObject* division(PyObject *self, PyObject *args);
// Exported methods are collected in a table
PyMethodDef method_table[] = {
{"division", division, METH_VARARGS, "Method docstring"},
{NULL, NULL, 0, NULL} // Sentinel value ending the table
};
// A struct contains the definition of a module
PyModuleDef moduledef = {
PyModuleDef_HEAD_INIT,
"detectc", // Module name
"This is the module docstring",
-1, // Optional size of the module state memory
method_table,
NULL, // Optional slot definitions
NULL, // Optional traversal function
NULL, // Optional clear function
NULL // Optional module deallocation function
};
// The module init function
// PyMODINIT_FUNC PyInit__detectc(void) {
// return PyModule_Create(&moduledef);
// }
PyMODINIT_FUNC PyInit_detectc() {
return PyModule_Create(&moduledef);
}
// This is the definition of a method
static PyObject* division(PyObject *self, PyObject *args) {
long dividend, divisor;
if (!PyArg_ParseTuple(args, "ll", ÷nd, &divisor)) {
return NULL;
}
if (0 == divisor) {
PyErr_Format(PyExc_ZeroDivisionError, "Dividing %d by zero!", dividend);
return NULL;
}
return PyLong_FromLong(dividend / divisor);
}
File structure
(---) ubuntu@---:~/robo/ext_test/Detect$ ls
CMakeLists.txt detectc.cpp __init __.py setup.py
I have been stuck on this for 4 days now. There is no way out. Please help!!! Any hints highly appreciated.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with setup.py, CMakeLists.txt, and detectc.cpp, then reproduce the failure using the listed python3 setup.py install and import commands. Compare the extension name, generated artifact, and Python initialization entry point; done means the sample module installs and imports without the reported ImportError.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cmake, cpp, python
- Domain
- build-system
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100