diff --git a/Makefile b/Makefile index 05c50f93b783291c165da02a95a06222e63bd126..bccdd8652ac439914386111547bb6203b30fe6ca 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,6 @@ LIBRARIES=libmoberg.so -MOBERG_VERSION=$(shell git describe --tags | sed -e 's/^v//;s/-/./g' ) +MOBERG_VERSION=$(shell git describe --tags \ + | sed -re 's/^v//;s/-(.*)-(.*)$$/.dev\1+\2/') CCFLAGS+=-Wall -Werror -I$(shell pwd) -O3 -g LDFLAGS+=-L$(shell pwd)/build/ -lmoberg PLUGINS:=$(sort $(wildcard plugins/*)) diff --git a/adaptors/python2/.gitignore b/adaptors/python2/.gitignore deleted file mode 100644 index f65eb2942dc78eb04f2d5d1e680fd693a7f484aa..0000000000000000000000000000000000000000 --- a/adaptors/python2/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/__pycache__ -/install \ No newline at end of file diff --git a/adaptors/python2/Makefile b/adaptors/python2/Makefile deleted file mode 100644 index eeb6d4596350123987bb6e5fe0f537587c08584c..0000000000000000000000000000000000000000 --- a/adaptors/python2/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -MOBERG_VERSION=$(shell git describe --tags) - -all: BUILD INSTALL - -.PHONY: BUILD -BUILD: - python2 ./setup.py build - -.PHONY: INSTALL -INSTALL: - MOBERG_VERSION=$(MOBERG_VERSION) python2 \ - ./setup.py install -O1 --prefix=/usr/ --root=./install - -clean: - rm -rf build install diff --git a/adaptors/python2/python-moberg.c b/adaptors/python2/python-moberg.c deleted file mode 100644 index 3ebadf94f8aa1504397e0349e698f8a97e35f947..0000000000000000000000000000000000000000 --- a/adaptors/python2/python-moberg.c +++ /dev/null @@ -1,771 +0,0 @@ -/* - python-moberg.c -- python interface to moberg I/O system - - Copyright (C) 2019 Anders Blomdell <anders.blomdell@gmail.com> - - This file is part of Moberg. - - Moberg is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <https://www.gnu.org/licenses/>. -*/ - -#include <Python.h> -#include <structmember.h> -#include <moberg.h> - -#ifndef Py_UNUSED /* This is already defined for Python 3.4 onwards */ -#ifdef __GNUC__ -#define Py_UNUSED(name) _unused_ ## name __attribute__((unused)) -#else -#define Py_UNUSED(name) _unused_ ## name -#endif -#endif - -static PyTypeObject MobergType; -static PyTypeObject MobergAnalogInType; -static PyTypeObject MobergAnalogOutType; -static PyTypeObject MobergDigitalInType; -static PyTypeObject MobergDigitalOutType; -static PyTypeObject MobergEncoderInType; - -/* - * moberg.Moberg class - */ - -typedef struct { - PyObject_HEAD - struct moberg *moberg; -} MobergObject; - -static void -Moberg_dealloc(MobergObject *self) -{ - if (self->moberg) { - moberg_free(self->moberg); - } - Py_TYPE(self)->tp_free((PyObject *) self); -} - -static PyObject * -Moberg_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - static char *kwlist[] = { NULL }; - if (! PyArg_ParseTupleAndKeywords(args, kwds, "", kwlist)) { - return NULL; - } - MobergObject *self = (MobergObject *) type->tp_alloc(type, 0); - return (PyObject *) self; -} - -static int -Moberg_init(MobergObject *self, PyObject *args, PyObject *kwds) -{ - static char *kwlist[] = { NULL }; - if (! PyArg_ParseTupleAndKeywords(args, kwds, "", kwlist)) { - return -1; - } - self->moberg = moberg_new(); - if (! self->moberg) { - PyErr_SetString(PyExc_OSError, "moberg.Moberg.__init__() failed"); - return -1; - } - return 0; -} - -static PyObject * -Moberg_analog_in(MobergObject *self, PyObject *args) -{ - int index; - if (! PyArg_ParseTuple(args, "i", &index)) { - PyErr_SetString(PyExc_AttributeError, "index"); - return NULL; - } - PyObject *ain_args = Py_BuildValue("Oi", self, index); - PyObject *ain = MobergAnalogInType.tp_new(&MobergAnalogInType, - ain_args, NULL); - /* NB: _AnalogIn.__init__ should never be called */ - Py_DECREF(ain_args); - return ain; -} - -static PyObject * -Moberg_analog_out(MobergObject *self, PyObject *args) -{ - int index; - if (! PyArg_ParseTuple(args, "i", &index)) { - PyErr_SetString(PyExc_AttributeError, "index"); - return NULL; - } - PyObject *aout_args = Py_BuildValue("Oi", self, index); - PyObject *aout = MobergAnalogOutType.tp_new(&MobergAnalogOutType, - aout_args, NULL); - /* NB: _AnalogOut.__init__ should never be called */ - Py_DECREF(aout_args); - return aout; -} - -static PyObject * -Moberg_digital_in(MobergObject *self, PyObject *args) -{ - int index; - if (! PyArg_ParseTuple(args, "i", &index)) { - PyErr_SetString(PyExc_AttributeError, "index"); - return NULL; - } - PyObject *din_args = Py_BuildValue("Oi", self, index); - PyObject *din = MobergDigitalInType.tp_new(&MobergDigitalInType, - din_args, NULL); - /* NB: _DigitalIn.__init__ should never be called */ - Py_DECREF(din_args); - return din; -} - -static PyObject * -Moberg_digital_out(MobergObject *self, PyObject *args) -{ - int index; - if (! PyArg_ParseTuple(args, "i", &index)) { - PyErr_SetString(PyExc_AttributeError, "index"); - return NULL; - } - PyObject *dout_args = Py_BuildValue("Oi", self, index); - PyObject *dout = MobergDigitalOutType.tp_new(&MobergDigitalOutType, - dout_args, NULL); - /* NB: _DigitalOut.__init__ should never be called */ - Py_DECREF(dout_args); - return dout; -} - -static PyObject * -Moberg_encoder_in(MobergObject *self, PyObject *args) -{ - int index; - if (! PyArg_ParseTuple(args, "i", &index)) { - PyErr_SetString(PyExc_AttributeError, "index"); - return NULL; - } - PyObject *ein_args = Py_BuildValue("Oi", self, index); - PyObject *ein = MobergEncoderInType.tp_new(&MobergEncoderInType, - ein_args, NULL); - /* NB: _EncoderIn.__init__ should never be called */ - Py_DECREF(ein_args); - return ein; -} - -static PyMethodDef Moberg_methods[] = { - {"analog_in", (PyCFunction) Moberg_analog_in, METH_VARARGS, - "Return AnalogIn object for channel" - }, - {"analog_out", (PyCFunction) Moberg_analog_out, METH_VARARGS, - "Return AnalogOut object for channel" - }, - {"digital_in", (PyCFunction) Moberg_digital_in, METH_VARARGS, - "Return DigitalIn object for channel" - }, - {"digital_out", (PyCFunction) Moberg_digital_out, METH_VARARGS, - "Return DigitalOut object for channel" - }, - {"encoder_in", (PyCFunction) Moberg_encoder_in, METH_VARARGS, - "Return EncoderIn object for channel" - }, - - {NULL} /* Sentinel */ -}; - -static PyTypeObject MobergType = { - PyVarObject_HEAD_INIT(NULL, 0) - .tp_name = "moberg.Moberg", - .tp_doc = "Moberg objects", - .tp_basicsize = sizeof(MobergObject), - .tp_itemsize = 0, - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - .tp_new = Moberg_new, - .tp_init = (initproc) Moberg_init, - .tp_dealloc = (destructor) Moberg_dealloc, - .tp_methods = Moberg_methods, -}; - -/* - * moberg._AnalogIn class (should never be directly instatiated) - */ - -typedef struct { - PyObject_HEAD - PyObject *moberg_object; - int index; - struct moberg_analog_in channel; -} MobergAnalogInObject; - -static void -MobergAnalogIn_dealloc(MobergAnalogInObject *self) -{ - if (self->moberg_object) { - struct moberg *moberg = ((MobergObject*)self->moberg_object)->moberg; - struct moberg_status status = - moberg_analog_in_close(moberg, self->index, self->channel); - if (! moberg_OK(status)) { - fprintf(stderr, "Failed to close moberg._AnalogIn(%d) [errno=%d]\n", - self->index, status.result); - } - Py_DECREF(self->moberg_object); - } - Py_TYPE(self)->tp_free((PyObject *) self); -} - -static PyObject * -MobergAnalogIn_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - PyObject *moberg_object; - int index; - struct moberg_analog_in channel = {0}; - - static char *kwlist[] = { "moberg", "index", NULL }; - if (! PyArg_ParseTupleAndKeywords(args, kwds, "Oi", kwlist, - &moberg_object, &index)) { - goto err; - } - if (Py_TYPE(moberg_object) != &MobergType) { - PyErr_SetString(PyExc_AttributeError, "moberg argument is not Moberg"); - goto err; - } - struct moberg *moberg = ((MobergObject*)moberg_object)->moberg; - struct moberg_status status = moberg_analog_in_open(moberg, index, &channel); - if (! moberg_OK(status)) { - PyErr_Format(PyExc_OSError, "moberg._AnalogIn(%d) failed with %d", - index, status.result); - goto err; - } - MobergAnalogInObject *self; - self = (MobergAnalogInObject *) type->tp_alloc(type, 0); - if (self == NULL) { goto close; } - Py_INCREF(moberg_object); - self->moberg_object = moberg_object; - self->index = index; - self->channel = channel; - return (PyObject *) self; -close: - status = moberg_analog_in_close(moberg, index, channel); -err: - return NULL; -} - -static int -MobergAnalogIn_init(MobergAnalogInObject *self, PyObject *args, PyObject *kwds) -{ - PyErr_SetString(PyExc_AttributeError, "Not intended to be called"); - return -1; -} - -static PyObject * -MobergAnalogIn_read(MobergAnalogInObject *self, PyObject *Py_UNUSED(ignored)) -{ - double value; - struct moberg_status status = self->channel.read(self->channel.context, - &value); - if (!moberg_OK(status)) { - PyErr_Format(PyExc_OSError, "moberg._AnalogIn(%d).read() failed with %d", - self->index, status.result); - } - return Py_BuildValue("d", value); -} - -static PyMethodDef MobergAnalogIn_methods[] = { - {"read", (PyCFunction) MobergAnalogIn_read, METH_NOARGS, - "Sample and return the AnalogIn value" - }, - {NULL} /* Sentinel */ -}; - -static PyTypeObject MobergAnalogInType = { - PyVarObject_HEAD_INIT(NULL, 0) - .tp_name = "moberg.AnalogIn", - .tp_doc = "AnalogIn objects", - .tp_basicsize = sizeof(MobergAnalogInObject), - .tp_itemsize = 0, - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - .tp_new = MobergAnalogIn_new, - .tp_init = (initproc) MobergAnalogIn_init, - .tp_dealloc = (destructor) MobergAnalogIn_dealloc, - .tp_methods = MobergAnalogIn_methods, -}; - -/* - * moberg._AnalogOut class (should never be directly instatiated) - */ - -typedef struct { - PyObject_HEAD - PyObject *moberg_object; - int index; - struct moberg_analog_out channel; -} MobergAnalogOutObject; - -static void -MobergAnalogOut_dealloc(MobergAnalogOutObject *self) -{ - if (self->moberg_object) { - struct moberg *moberg = ((MobergObject*)self->moberg_object)->moberg; - struct moberg_status status = - moberg_analog_out_close(moberg, self->index, self->channel); - if (! moberg_OK(status)) { - fprintf(stderr, "Failed to close moberg._AnalogOut(%d) [errno=%d]\n", - self->index, status.result); - } - Py_DECREF(self->moberg_object); - } - Py_TYPE(self)->tp_free((PyObject *) self); -} - -static PyObject * -MobergAnalogOut_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - PyObject *moberg_object; - int index; - struct moberg_analog_out channel = {0}; - - static char *kwlist[] = { "moberg", "index", NULL }; - if (! PyArg_ParseTupleAndKeywords(args, kwds, "Oi", kwlist, - &moberg_object, &index)) { - goto err; - } - if (Py_TYPE(moberg_object) != &MobergType) { - PyErr_SetString(PyExc_AttributeError, "moberg argument is not Moberg"); - goto err; - } - struct moberg *moberg = ((MobergObject*)moberg_object)->moberg; - struct moberg_status status = moberg_analog_out_open(moberg, index, &channel); - if (! moberg_OK(status)) { - PyErr_Format(PyExc_OSError, "moberg._AnalogOut(%d) failed with %d", - index, status.result); - goto err; - } - MobergAnalogOutObject *self; - self = (MobergAnalogOutObject *) type->tp_alloc(type, 0); - if (self == NULL) { goto close; } - Py_INCREF(moberg_object); - self->moberg_object = moberg_object; - self->index = index; - self->channel = channel; - return (PyObject *) self; -close: - status = moberg_analog_out_close(moberg, index, channel); -err: - return NULL; -} - -static int -MobergAnalogOut_init(MobergAnalogOutObject *self, PyObject *args, PyObject *kwds) -{ - PyErr_SetString(PyExc_AttributeError, "Not intended to be called"); - return -1; -} - -static PyObject * -MobergAnalogOut_write(MobergAnalogOutObject *self, PyObject *args) -{ - double desired_value, actual_value; - if (! PyArg_ParseTuple(args, "d", &desired_value)) { - goto err; - } - struct moberg_status status = self->channel.write(self->channel.context, - desired_value, - &actual_value); - if (!moberg_OK(status)) { - PyErr_Format(PyExc_OSError, "moberg._AnalogOut(%d).write() failed with %d", - self->index, status.result); - goto err; - } - - return Py_BuildValue("d", actual_value); -err: - return NULL; -} - -static PyMethodDef MobergAnalogOut_methods[] = { - {"write", (PyCFunction) MobergAnalogOut_write, METH_VARARGS, - "Set AnalogOut value" - }, - {NULL} /* Sentinel */ -}; - -static PyTypeObject MobergAnalogOutType = { - PyVarObject_HEAD_INIT(NULL, 0) - .tp_name = "moberg.AnalogOut", - .tp_doc = "AnalogOut objects", - .tp_basicsize = sizeof(MobergAnalogOutObject), - .tp_itemsize = 0, - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - .tp_new = MobergAnalogOut_new, - .tp_init = (initproc) MobergAnalogOut_init, - .tp_dealloc = (destructor) MobergAnalogOut_dealloc, - .tp_methods = MobergAnalogOut_methods, -}; - -/* - * moberg._DigitalIn class (should never be directly instatiated) - */ - -typedef struct { - PyObject_HEAD - PyObject *moberg_object; - int index; - struct moberg_digital_in channel; -} MobergDigitalInObject; - -static void -MobergDigitalIn_dealloc(MobergDigitalInObject *self) -{ - if (self->moberg_object) { - struct moberg *moberg = ((MobergObject*)self->moberg_object)->moberg; - struct moberg_status status = - moberg_digital_in_close(moberg, self->index, self->channel); - if (! moberg_OK(status)) { - fprintf(stderr, "Failed to close moberg._DigitalIn(%d) [errno=%d]\n", - self->index, status.result); - } - Py_DECREF(self->moberg_object); - } - Py_TYPE(self)->tp_free((PyObject *) self); -} - -static PyObject * -MobergDigitalIn_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - PyObject *moberg_object; - int index; - struct moberg_digital_in channel = {0}; - - static char *kwlist[] = { "moberg", "index", NULL }; - if (! PyArg_ParseTupleAndKeywords(args, kwds, "Oi", kwlist, - &moberg_object, &index)) { - goto err; - } - if (Py_TYPE(moberg_object) != &MobergType) { - PyErr_SetString(PyExc_AttributeError, "moberg argument is not Moberg"); - goto err; - } - struct moberg *moberg = ((MobergObject*)moberg_object)->moberg; - struct moberg_status status = moberg_digital_in_open(moberg, index, &channel); - if (! moberg_OK(status)) { - PyErr_Format(PyExc_OSError, "moberg._DigitalIn(%d) failed with %d", - index, status.result); - goto err; - } - MobergDigitalInObject *self; - self = (MobergDigitalInObject *) type->tp_alloc(type, 0); - if (self == NULL) { goto close; } - Py_INCREF(moberg_object); - self->moberg_object = moberg_object; - self->index = index; - self->channel = channel; - return (PyObject *) self; -close: - status = moberg_digital_in_close(moberg, index, channel); -err: - return NULL; -} - -static int -MobergDigitalIn_init(MobergDigitalInObject *self, PyObject *args, PyObject *kwds) -{ - PyErr_SetString(PyExc_AttributeError, "Not intended to be called"); - return -1; -} - -static PyObject * -MobergDigitalIn_read(MobergDigitalInObject *self, PyObject *Py_UNUSED(ignored)) -{ - int value; - struct moberg_status status = self->channel.read(self->channel.context, - &value); - if (!moberg_OK(status)) { - PyErr_Format(PyExc_OSError, "moberg._DigitalIn(%d).read() failed with %d", - self->index, status.result); - } - return Py_BuildValue("O", value ? Py_True: Py_False); -} - -static PyMethodDef MobergDigitalIn_methods[] = { - {"read", (PyCFunction) MobergDigitalIn_read, METH_NOARGS, - "Sample and return the DigitalIn value" - }, - {NULL} /* Sentinel */ -}; - -static PyTypeObject MobergDigitalInType = { - PyVarObject_HEAD_INIT(NULL, 0) - .tp_name = "moberg.DigitalIn", - .tp_doc = "DigitalIn objects", - .tp_basicsize = sizeof(MobergDigitalInObject), - .tp_itemsize = 0, - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - .tp_new = MobergDigitalIn_new, - .tp_init = (initproc) MobergDigitalIn_init, - .tp_dealloc = (destructor) MobergDigitalIn_dealloc, - .tp_methods = MobergDigitalIn_methods, -}; - -/* - * moberg._DigitalOut class (should never be directly instatiated) - */ - -typedef struct { - PyObject_HEAD - PyObject *moberg_object; - int index; - struct moberg_digital_out channel; -} MobergDigitalOutObject; - -static void -MobergDigitalOut_dealloc(MobergDigitalOutObject *self) -{ - if (self->moberg_object) { - struct moberg *moberg = ((MobergObject*)self->moberg_object)->moberg; - struct moberg_status status = - moberg_digital_out_close(moberg, self->index, self->channel); - if (! moberg_OK(status)) { - fprintf(stderr, "Failed to close moberg._DigitalOut(%d) [errno=%d]\n", - self->index, status.result); - } - Py_DECREF(self->moberg_object); - } - Py_TYPE(self)->tp_free((PyObject *) self); -} - -static PyObject * -MobergDigitalOut_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - PyObject *moberg_object; - int index; - struct moberg_digital_out channel = {0}; - - static char *kwlist[] = { "moberg", "index", NULL }; - if (! PyArg_ParseTupleAndKeywords(args, kwds, "Oi", kwlist, - &moberg_object, &index)) { - goto err; - } - if (Py_TYPE(moberg_object) != &MobergType) { - PyErr_SetString(PyExc_AttributeError, "moberg argument is not Moberg"); - goto err; - } - struct moberg *moberg = ((MobergObject*)moberg_object)->moberg; - struct moberg_status status = moberg_digital_out_open(moberg, index, &channel); - if (! moberg_OK(status)) { - PyErr_Format(PyExc_OSError, "moberg._DigitalOut(%d) failed with %d", - index, status.result); - goto err; - } - MobergDigitalOutObject *self; - self = (MobergDigitalOutObject *) type->tp_alloc(type, 0); - if (self == NULL) { goto close; } - Py_INCREF(moberg_object); - self->moberg_object = moberg_object; - self->index = index; - self->channel = channel; - return (PyObject *) self; -close: - status = moberg_digital_out_close(moberg, index, channel); -err: - return NULL; -} - -static int -MobergDigitalOut_init(MobergDigitalOutObject *self, PyObject *args, PyObject *kwds) -{ - PyErr_SetString(PyExc_AttributeError, "Not intended to be called"); - return -1; -} - -static PyObject * -MobergDigitalOut_write(MobergDigitalOutObject *self, PyObject *args) -{ - PyObject *desired; - int actual; - if (! PyArg_ParseTuple(args, "O", &desired)) { - goto err; - } - struct moberg_status status = self->channel.write(self->channel.context, - PyObject_IsTrue(desired), - &actual); - if (!moberg_OK(status)) { - PyErr_Format(PyExc_OSError, "moberg._DigitalOut(%d).write() failed with %d", - self->index, status.result); - goto err; - } - return Py_BuildValue("O", actual ? Py_True: Py_False); -err: - return NULL; -} - -static PyMethodDef MobergDigitalOut_methods[] = { - {"write", (PyCFunction) MobergDigitalOut_write, METH_VARARGS, - "Set DigitalOut value" - }, - {NULL} /* Sentinel */ -}; - -static PyTypeObject MobergDigitalOutType = { - PyVarObject_HEAD_INIT(NULL, 0) - .tp_name = "moberg.DigitalOut", - .tp_doc = "DigitalOut objects", - .tp_basicsize = sizeof(MobergDigitalOutObject), - .tp_itemsize = 0, - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - .tp_new = MobergDigitalOut_new, - .tp_init = (initproc) MobergDigitalOut_init, - .tp_dealloc = (destructor) MobergDigitalOut_dealloc, - .tp_methods = MobergDigitalOut_methods, -}; - -/* - * moberg._EncoderIn class (should never be directly instatiated) - */ - -typedef struct { - PyObject_HEAD - PyObject *moberg_object; - int index; - struct moberg_encoder_in channel; -} MobergEncoderInObject; - -static void -MobergEncoderIn_dealloc(MobergEncoderInObject *self) -{ - if (self->moberg_object) { - struct moberg *moberg = ((MobergObject*)self->moberg_object)->moberg; - struct moberg_status status = - moberg_encoder_in_close(moberg, self->index, self->channel); - if (! moberg_OK(status)) { - fprintf(stderr, "Failed to close moberg._EncoderIn(%d) [errno=%d]\n", - self->index, status.result); - } - Py_DECREF(self->moberg_object); - } - Py_TYPE(self)->tp_free((PyObject *) self); -} - -static PyObject * -MobergEncoderIn_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - PyObject *moberg_object; - int index; - struct moberg_encoder_in channel = {0}; - - static char *kwlist[] = { "moberg", "index", NULL }; - if (! PyArg_ParseTupleAndKeywords(args, kwds, "Oi", kwlist, - &moberg_object, &index)) { - goto err; - } - if (Py_TYPE(moberg_object) != &MobergType) { - PyErr_SetString(PyExc_AttributeError, "moberg argument is not Moberg"); - goto err; - } - struct moberg *moberg = ((MobergObject*)moberg_object)->moberg; - struct moberg_status status = moberg_encoder_in_open(moberg, index, &channel); - if (! moberg_OK(status)) { - PyErr_Format(PyExc_OSError, "moberg._EncoderIn(%d) failed with %d", - index, status.result); - goto err; - } - MobergEncoderInObject *self; - self = (MobergEncoderInObject *) type->tp_alloc(type, 0); - if (self == NULL) { goto close; } - Py_INCREF(moberg_object); - self->moberg_object = moberg_object; - self->index = index; - self->channel = channel; - return (PyObject *) self; -close: - status = moberg_encoder_in_close(moberg, index, channel); -err: - return NULL; -} - -static int -MobergEncoderIn_init(MobergEncoderInObject *self, PyObject *args, PyObject *kwds) -{ - PyErr_SetString(PyExc_AttributeError, "Not intended to be called"); - return -1; -} - -static PyObject * -MobergEncoderIn_read(MobergEncoderInObject *self, PyObject *Py_UNUSED(ignored)) -{ - long value; - struct moberg_status status = self->channel.read(self->channel.context, - &value); - if (!moberg_OK(status)) { - PyErr_Format(PyExc_OSError, "moberg._EncoderIn(%d).read() failed with %d", - self->index, status.result); - } - return Py_BuildValue("l", value); -} - -static PyMethodDef MobergEncoderIn_methods[] = { - {"read", (PyCFunction) MobergEncoderIn_read, METH_NOARGS, - "Sample and return the EncoderIn value" - }, - {NULL} /* Sentinel */ -}; - -static PyTypeObject MobergEncoderInType = { - PyVarObject_HEAD_INIT(NULL, 0) - .tp_name = "moberg.EncoderIn", - .tp_doc = "EncoderIn objects", - .tp_basicsize = sizeof(MobergEncoderInObject), - .tp_itemsize = 0, - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - .tp_new = MobergEncoderIn_new, - .tp_init = (initproc) MobergEncoderIn_init, - .tp_dealloc = (destructor) MobergEncoderIn_dealloc, - .tp_methods = MobergEncoderIn_methods, -}; - -/* - * Module initialization - */ - -#define INITERROR return - -PyMODINIT_FUNC initmoberg(void) -{ - PyObject *m; - if (PyType_Ready(&MobergType) < 0 || - PyType_Ready(&MobergAnalogInType) < 0 || - PyType_Ready(&MobergAnalogOutType) < 0 || - PyType_Ready(&MobergDigitalInType) < 0 || - PyType_Ready(&MobergDigitalOutType) < 0 || - PyType_Ready(&MobergEncoderInType) < 0) { - INITERROR; - } - - static PyMethodDef methods[] = { {NULL, NULL, 0, NULL} }; - m = Py_InitModule("moberg", methods); - if (m == NULL) { - INITERROR; - } - - Py_INCREF(&MobergType); - PyModule_AddObject(m, "Moberg", (PyObject *) &MobergType); - Py_INCREF(&MobergAnalogInType); - PyModule_AddObject(m, "_AnalogIn", (PyObject *) &MobergAnalogInType); - Py_INCREF(&MobergAnalogOutType); - PyModule_AddObject(m, "_AnalogOut", (PyObject *) &MobergAnalogOutType); - Py_INCREF(&MobergDigitalInType); - PyModule_AddObject(m, "_DigitalIn", (PyObject *) &MobergDigitalInType); - Py_INCREF(&MobergDigitalOutType); - PyModule_AddObject(m, "_DigitalOut", (PyObject *) &MobergDigitalOutType); - Py_INCREF(&MobergEncoderInType); - PyModule_AddObject(m, "_EncoderIn", (PyObject *) &MobergEncoderInType); - -} diff --git a/adaptors/python2/setup.py b/adaptors/python2/setup.py deleted file mode 100755 index 2e5fa2fdfa166fde009731479e2986c639f6607a..0000000000000000000000000000000000000000 --- a/adaptors/python2/setup.py +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env python -from distutils.core import setup, Extension - -module = Extension('moberg', - sources = ['python-moberg.c'], - include_dirs=['../..'], - libraries=['moberg']) -longdesc = '''This extension provides bindings to the Moberg I/O library -''' - -try: - import os - VERSION=os.environ['MOBERG_VERSION'] -except KeyError: - VERSION='_UNKNOWN_' - pass - -setup( - name = 'python-moberg', - version = VERSION, - description = 'Python bindings to the Moberg I/O library', - long_description = longdesc, - author = 'Anders Blomdell', - author_email = 'anders.blomdell@control.lth.se', - url = 'http://gitlab.control.lth.se/anders_blomdell/moberg.git', - license = 'GPLv2', - platforms = 'Linux', - ext_modules = [module]) diff --git a/adaptors/python3/.gitignore b/adaptors/python3/.gitignore index f65eb2942dc78eb04f2d5d1e680fd693a7f484aa..f0cab8eb71c04a7bea29990994b7350287dc36a0 100644 --- a/adaptors/python3/.gitignore +++ b/adaptors/python3/.gitignore @@ -1,2 +1,4 @@ /__pycache__ -/install \ No newline at end of file +/install +/dist +/python_moberg.egg-info diff --git a/adaptors/python3/Makefile b/adaptors/python3/Makefile index 486da900f2eb2bb5af6bd79b991ea53fc8ac77ac..3e4c3940657d8f1cc6ed032248456acf59febcfd 100644 --- a/adaptors/python3/Makefile +++ b/adaptors/python3/Makefile @@ -1,15 +1,18 @@ -MOBERG_VERSION=$(shell git describe --tags) +MOBERG_VERSION=$(shell git describe --tags \ + | sed -re 's/^v//;s/-(.*)-(.*)$$/.dev\1+\2/') all: BUILD INSTALL .PHONY: BUILD BUILD: - python3 ./setup.py build + MOBERG_SRC_PATH=$(shell realpath ../..) \ + MOBERG_VERSION=$(MOBERG_VERSION) \ + python3 -m build .PHONY: INSTALL INSTALL: - MOBERG_VERSION=$(MOBERG_VERSION) python3 \ - ./setup.py install -O1 --prefix=/usr/ --root=./install + pip install --prefix=/usr --root=install \ + ./dist/python_moberg-${MOBERG_VERSION}-*.whl clean: - rm -rf build install + rm -rf build install dist python_moberg.egg-info *~ diff --git a/adaptors/python3/README b/adaptors/python3/README new file mode 100644 index 0000000000000000000000000000000000000000..38fd43756184ea70d7075cb6a65a07cde0f5f4ff --- /dev/null +++ b/adaptors/python3/README @@ -0,0 +1 @@ +Moberg support for python3 \ No newline at end of file diff --git a/adaptors/python3/setup.py b/adaptors/python3/setup.py index 2e5fa2fdfa166fde009731479e2986c639f6607a..c8cf0125bc094b8ce6c2ae8acac39f254c60ddce 100755 --- a/adaptors/python3/setup.py +++ b/adaptors/python3/setup.py @@ -1,13 +1,6 @@ #!/usr/bin/env python from distutils.core import setup, Extension -module = Extension('moberg', - sources = ['python-moberg.c'], - include_dirs=['../..'], - libraries=['moberg']) -longdesc = '''This extension provides bindings to the Moberg I/O library -''' - try: import os VERSION=os.environ['MOBERG_VERSION'] @@ -15,6 +8,25 @@ except KeyError: VERSION='_UNKNOWN_' pass +try: + import os + src=os.environ['MOBERG_SRC_PATH'] + INCLUDE_DIRS=[ src ] + LIBRARY_DIRS=[ os.path.join(src, 'build') ] +except KeyError: + INCLUDE_DIRS=None + LIBRARY_DIRS=None + pass + +module = Extension('moberg', + sources = ['python-moberg.c'], + include_dirs=INCLUDE_DIRS, + library_dirs=LIBRARY_DIRS, + libraries=['moberg']) +longdesc = '''This extension provides bindings to the Moberg I/O library +''' + + setup( name = 'python-moberg', version = VERSION, diff --git a/moberg.spec.template b/moberg.spec.template index 63352be9cde04350cfb7ad705d6df7dd81d8dab2..62197cb9df74a0f5ed22dcfd219c4e583b6b6f7a 100644 --- a/moberg.spec.template +++ b/moberg.spec.template @@ -15,8 +15,9 @@ BuildRequires: comedilib-devel BuildRequires: valgrind BuildRequires: libxdg-basedir-devel BuildRequires: java-1.8.0-devel -BuildRequires: python2-devel +BuildRequires: pip BuildRequires: python3-devel +BuildRequires: python3-build BuildRequires: python3-setuptools BuildRequires: julia BuildRequires: git @@ -56,13 +57,6 @@ Requires: %{name}-devel = %{version}-%{release} %description matlab Matlab support files for %{name} -%package python2 -Summary: Python2 support files for %{name} -Requires: %{name} = %{version}-%{release} - -%description python2 -Python2 support files for %{name} - %package python%{python3_pkgversion} Summary: Python3 support files for %{name} Requires: %{name} = %{version}-%{release} @@ -87,7 +81,7 @@ Julia support files for %{name} make MOBERG_VERSION=%{version} %check -make test || true +make test MOBERG_VERSION=%{version} %install rm -rf ${RPM_BUILD_ROOT} @@ -128,20 +122,13 @@ cp adaptors/matlab/*out.c ${RPM_BUILD_ROOT}/opt/matlab/src/moberg cp adaptors/matlab/Makefile.mex ${RPM_BUILD_ROOT}/opt/matlab/src/moberg/Makefile # Python -( - cd adaptors/python2 - export MOBERG_VERSION=%{version} - %{__python2} setup.py install -O1 \ - --root=$RPM_BUILD_ROOT --prefix /usr \ - --record=INSTALLED_python2 -) -( - cd adaptors/python3 - export MOBERG_VERSION=%{version} - %{__python3} setup.py install -O1 \ - --root=$RPM_BUILD_ROOT --prefix /usr \ - --record=INSTALLED_python3 -) +find adaptors/python3/install/ -type f \ + | sed -e 's|adaptors/python3/install/|/|' \ + > adaptors/python3/INSTALLED_python3 +cat adaptors/python3/INSTALLED_python3 | while read f ; do + mkdir -p ${RPM_BUILD_ROOT}/$(dirname $f) + cp adaptors/python3/install/$f ${RPM_BUILD_ROOT}/$f +done # Julia mkdir -p ${RPM_BUILD_ROOT}/opt/julia/local/packages/MobergIO/src @@ -207,9 +194,6 @@ EOF /opt/matlab/src/moberg/* %{_includedir}/moberg4simulink.h -%files python2 -f adaptors/python2/INSTALLED_python2 -%defattr(-,root,root,-) - %files python%{python3_pkgversion} -f adaptors/python3/INSTALLED_python3 %defattr(-,root,root,-) diff --git a/test/Makefile b/test/Makefile index 7ae172c1e5272ecb7c39afd0be65d708946ae12a..d1799e19068f2ebca67ab3b146934285cde23048 100644 --- a/test/Makefile +++ b/test/Makefile @@ -9,7 +9,6 @@ ENV_TEST = LD_LIBRARY_PATH=../build \ JULIA_LOAD_PATH=../adaptors/julia LDFLAGS_test_moberg4simulink = -lmoberg4simulink CCFLAGS_test_moberg4simulink = -I../adaptors/matlab -Wall -Werror -I$(shell pwd) -g -PYTHON2PATH=$(shell realpath ../adaptors/python2/install/usr/lib*/python2*/site-packages) PYTHON3PATH=$(shell realpath ../adaptors/python3/install/usr/lib*/python3*/site-packages) all: @@ -23,7 +22,6 @@ run_c_%:build/% .PHONY: run_py_% run_py_%: %.py - $(ENV_TEST) PYTHONPATH=$(PYTHON2PATH) python2 $*.py $(ENV_TEST) PYTHONPATH=$(PYTHON3PATH) python3 $*.py .PHONY: run_jl_% @@ -33,7 +31,7 @@ run_jl_%: %.jl .PRECIOUS: build/% build/%: %.c | build - $(CC) $(CCFLAGS) $(CCFLAGS_$*) -o $@ $< $(LDFLAGS) $(LDFLAGS_$*) + $(CC) $(CCFLAGS) $(CCFLAGS_$*) -fPIE -o $@ $< $(LDFLAGS) $(LDFLAGS_$*) build: mkdir build