OpenZWave / python-openzwave

Python wrapper for openzwave
Other
200 stars 141 forks source link

Fails to build on SmartOS #123

Open bahamas10 opened 6 years ago

bahamas10 commented 6 years ago

I'm currently using this project through Home Assistant on a raspberry pi and it works flawlessly. I want to transition to my more powerful and capable server running SmartOS however the one thing holding me back is getting openzwave/python-openzwave running on my SmartOS Zone.

I'm able to get OpenZWave compiled using this patch, however python-openzwave still fails. Attached is the build log (after manually applying the patch above to the OpenZWave code checked out).

[root@test ~/zwave/python-openzwave]# make build
cd openzwave && make -j 4
make[1]: Entering directory '/root/zwave/python-openzwave/openzwave'
LDFLAGS="" CPPFLAGS="" make -C /root/zwave/python-openzwave/openzwave/cpp/build/ -w -j --jobserver-fds=3,4
make[2]: Entering directory '/root/zwave/python-openzwave/openzwave/cpp/build'
Building OpenZWave Version 1.4-3055-g7a1d2bf6-dirty
Building tinyxmlparser.o
Building tinyxml.o
Building tinyxmlerror.o
Building tinystr.o
Building hid.o
Building aes_modes.o
Building aestab.o
Building aescrypt.o
Building aeskey.o
Building SwitchToggleMultilevel.o
Building ControllerReplication.o
Building DeviceResetLocally.o
Building Basic.o
Building EnergyProduction.o
Building NoOperation.o
Building ThermostatSetpoint.o
Building CommandClasses.o
Building ZWavePlusInfo.o
Building Version.o
Building CRC16Encap.o
Building Battery.o
Building SensorAlarm.o
Building SensorMultilevel.o
Building AssociationCommandConfiguration.o
Building CommandClass.o
Building ThermostatOperatingState.o
Building Powerlevel.o
Building SceneActivation.o
Building ThermostatFanState.o
Building Clock.o
Building Association.o
Building Lock.o
Building SwitchAll.o
Building BasicWindowCovering.o
Building WakeUp.o
Building Protection.o
Building MultiChannelAssociation.o
Building DoorLockLogging.o
Building NodeNaming.o
Building ApplicationStatus.o
Building Hail.o
Building ClimateControlSchedule.o
Building ManufacturerSpecific.o
Building Alarm.o
Building Color.o
Building UserCode.o
Building ThermostatFanMode.o
Building TimeParameters.o
Building MultiInstance.o
Building ThermostatMode.o
Building SwitchToggleBinary.o
Building Configuration.o
Building SwitchBinary.o
Building SwitchMultilevel.o
Building DoorLock.o
Building MeterPulse.o
Building Indicator.o
Building Meter.o
Building Language.o
Building SensorBinary.o
Building MultiCmd.o
Building CentralScene.o
Building Proprietary.o
Building Security.o
Building ValueShort.o
Building ValueSchedule.o
Building ValueBool.o
Building ValueByte.o
Building ValueString.o
Building ValueRaw.o
Building ValueDecimal.o
Building ValueStore.o
Building ValueInt.o
Building ValueButton.o
Building ValueList.o
Building Value.o
Building TimeStamp.o
Building FileOps.o
Building Event.o
Building SerialController.o
Building Mutex.o
Building HidController.o
Building Log.o
Building Stream.o
Building Thread.o
Building Wait.o
Building Controller.o
Building EventImpl.o
Building SerialControllerImpl.o
Building MutexImpl.o
Building LogImpl.o
Building ThreadImpl.o
Building WaitImpl.o
Building TimeStampImpl.o
Building FileOpsImpl.o
Building Notification.o
Building Msg.o
Building Manager.o
Building Node.o
Building Group.o
Building ZWSecurity.o
Building Driver.o
Building Utils.o
Building Scene.o
Building Options.o
Creating vers.cpp
Building vers.o
Linking Static Library
Linking Shared Library
make[2]: Leaving directory '/root/zwave/python-openzwave/openzwave/cpp/build'
LDFLAGS="" CPPFLAGS="" make -C /root/zwave/python-openzwave/openzwave/cpp/examples/MinOZW/ -w -j --jobserver-fds=3,4
make[2]: Entering directory '/root/zwave/python-openzwave/openzwave/cpp/examples/MinOZW'
Building Main.o
Linking /root/zwave/python-openzwave/openzwave/.lib/MinOZW
g++   -L/opt/local/lib -R/opt/local/lib -lusb-1.0  -o /root/zwave/python-openzwave/openzwave/.lib/MinOZW /root/zwave/python-openzwave/openzwave/.lib/Main.o /root/zwave/python-openzwave/openzwave/libopenzwave.so -pthread
Creating Temporary Shell Launch Script
make[2]: Leaving directory '/root/zwave/python-openzwave/openzwave/cpp/examples/MinOZW'
make[1]: Leaving directory '/root/zwave/python-openzwave/openzwave'
python setup-lib.py build --flavor=dev
ImportError in : from wheel.bdist_wheel import bdist_wheel as _bdist_wheel
sysargv ['setup-lib.py', 'build']
NameError in : class bdist_wheel(_bdist_wheel) - Use bdist_egg instead
<pyozw_setup.DevTemplate object at 0x1412858>
{'name': 'libopenzwave', 'sources': ['src-lib/libopenzwave/libopenzwave.pyx'], 'include_dirs': ['openzwave/cpp/src', 'openzwave/cpp/src/value_classes', 'openzwave/cpp/src/platform', 'openzwave/cpp/build/linux'], 'define_macros': [('PY_LIB_VERSION', '0.4.4'), ('PY_SSIZE_T_CLEAN', 1), ('PY_LIB_FLAVOR', 'dev'), ('PY_LIB_BACKEND', 'cython')], 'libraries': ['udev', 'stdc++', 'resolv'], 'extra_objects': ['openzwave/libopenzwave.a'], 'extra_compile_args': [], 'extra_link_args': [], 'language': 'c++'}
['six', 'PyDispatcher>=2.0.5', 'Cython']
running build
running build_openzwave
Found g++ : /opt/local/bin/g++
Found gcc : /opt/local/bin/gcc
Found make : /opt/local/bin/make
Found gmake : /opt/local/bin/gmake
Found pkg-config : None
Clean openzwave in openzwave ... be patient ...
Build openzwave ... be patient ...
running build_ext
cythoning src-lib/libopenzwave/libopenzwave.pyx to src-lib/libopenzwave/libopenzwave.cpp
building 'libopenzwave' extension
creating build
creating build/temp.solaris-2.11-i86pc.64bit-3.6
creating build/temp.solaris-2.11-i86pc.64bit-3.6/src-lib
creating build/temp.solaris-2.11-i86pc.64bit-3.6/src-lib/libopenzwave
gcc -Wno-unused-result -Wsign-compare -DNDEBUG -pipe -O2 -D_FORTIFY_SOURCE=2 -I/usr/include -I/opt/local/include -I/opt/local/include/ncurses -I/opt/local/include/db4 -pipe -O2 -D_FORTIFY_SOURCE=2 -I/usr/include -I/opt/local/include -I/opt/local/include/ncurses -I/opt/local/include/db4 -pipe -O2 -D_FORTIFY_SOURCE=2 -I/usr/include -I/opt/local/include -I/opt/local/include/ncurses -I/opt/local/include/db4 -fPIC -DPY_LIB_VERSION=0.4.4 -DPY_SSIZE_T_CLEAN=1 -DPY_LIB_FLAVOR=dev -DPY_LIB_BACKEND=cython -Iopenzwave/cpp/src -Iopenzwave/cpp/src/value_classes -Iopenzwave/cpp/src/platform -Iopenzwave/cpp/build/linux -I/opt/local/include/python3.6 -c src-lib/libopenzwave/libopenzwave.cpp -o build/temp.solaris-2.11-i86pc.64bit-3.6/src-lib/libopenzwave/libopenzwave.o
src-lib/libopenzwave/libopenzwave.cpp:3:0: warning: "PY_SSIZE_T_CLEAN" redefined
 #define PY_SSIZE_T_CLEAN
 ^
<command-line>:0:0: note: this is the location of the previous definition
src-lib/libopenzwave/libopenzwave.cpp: In function 'PyObject* __pyx_pf_12libopenzwave_9PyManager_234getSwitchPoint(__pyx_obj_12libopenzwave_PyManager*, PyObject*, PyObject*, PyObject*, PyObject*, PyObject*)':
src-lib/libopenzwave/libopenzwave.cpp:29570:138: error: invalid conversion from 'int8_t* {aka char*}' to 'int8* {aka signed char*}' [-fpermissive]
     __pyx_v_ret = __pyx_v_self->manager->GetSwitchPoint(__pyx_t_3, __pyx_t_4, (&__pyx_v_ohours), (&__pyx_v_ominutes), (&__pyx_v_osetback));
                                                                                                                                          ^
In file included from src-lib/libopenzwave/libopenzwave.cpp:597:0:
openzwave/cpp/src/Manager.h:1417:8: note: initializing argument 5 of 'bool OpenZWave::Manager::GetSwitchPoint(const OpenZWave::ValueID&, uint8, uint8*, uint8*, int8*)'
   bool GetSwitchPoint( ValueID const& _id, uint8 const _idx, uint8* o_hours, uint8* o_minutes, int8* o_setback );
        ^
src-lib/libopenzwave/libopenzwave.cpp: In function 'PyObject* __pyx_pf_12libopenzwave_9PyManager_272beginControllerCommand(__pyx_obj_12libopenzwave_PyManager*, PyObject*, PyObject*, PyObject*, PyObject*, PyObject*, PyObject*)':
src-lib/libopenzwave/libopenzwave.cpp:32283:204: warning: 'bool OpenZWave::Manager::BeginControllerCommand(uint32, OpenZWave::Driver::ControllerCommand, OpenZWave::Driver::pfnControllerCallback_t, void*, bool, uint8, uint8)' is deprecated (declared at openzwave/cpp/src/Manager.h:1732) [-Wdeprecated-declarations]
 yBool_FromLong(__pyx_v_self->manager->BeginControllerCommand(__pyx_t_1, __pyx_t_2, __pyx_f_12libopenzwave_ctrl_callback, ((void *)__pyx_v_pythonfunc), __pyx_t_3, __pyx_t_4, __pyx_t_5)); if (unl
                                                                                                                                                                                       ^
error: command 'gcc' failed with exit status 1
Makefile:278: recipe for target 'build' failed
make: *** [build] Error 1
[root@test ~/zwave/python-openzwave]# 

The actual error:

src-lib/libopenzwave/libopenzwave.cpp:29570:138: error: invalid conversion from 'int8_t* {aka char*}' to 'int8* {aka signed char*}' [-fpermissive]
     __pyx_v_ret = __pyx_v_self->manager->GetSwitchPoint(__pyx_t_3, __pyx_t_4, (&__pyx_v_ohours), (&__pyx_v_ominutes), (&__pyx_v_osetback));

I believe the issue is with how cython converts the code from python to C(++?) but i'm really out of my area of expertise here. If I run the gcc command that fails manually with -fpermissive it exits cleanly FWIW.

System information

[root@test ~/zwave/python-openzwave]# git rev-parse HEAD
5e318f3265fe2f4c0fb73ebc22fa25cfe24345fe
[root@test ~/zwave/python-openzwave]# (cd openzwave/ && git rev-parse HEAD)
7a1d2bf6e68e41e7ebaee35d5b9bbb8b0269157d
[root@test ~/zwave/python-openzwave]# uname -a
SunOS test.rapture.com 5.11 joyent_20180510T153535Z i86pc i386 i86pc Solaris
[root@test ~/zwave/python-openzwave]# python -V
Python 3.6.4
[root@test ~/zwave/python-openzwave]# cython -V
Cython version 0.28.3
[root@test ~/zwave/python-openzwave]# gcc -v
Using built-in specs.
COLLECT_GCC=/opt/local/gcc49/bin/gcc
COLLECT_LTO_WRAPPER=/opt/local/gcc49/libexec/gcc/x86_64-sun-solaris2.11/4.9.4/lto-wrapper
Target: x86_64-sun-solaris2.11
Configured with: ../gcc-4.9.4/configure --disable-libstdcxx-pch --enable-libssp --enable-languages='c obj-c++ objc go fortran c++' --enable-shared --enable-long-long --with-local-prefix=/opt/local --enable-threads=posix --with-boot-ldflags='-static-libstdc++ -static-libgcc -Wl,-R/opt/local/lib ' --disable-nls --with-gxx-include-dir=/opt/local/gcc49/include/c++/ --without-gnu-ld --with-ld=/usr/bin/ld --with-gnu-as --with-as=/opt/local/bin/gas --prefix=/opt/local/gcc49 --build=x86_64-sun-solaris2.11 --host=x86_64-sun-solaris2.11 --infodir=/opt/local/gcc49/info --mandir=/opt/local/gcc49/man
Thread model: posix
gcc version 4.9.4 (GCC) 

Note: I want to make a pull request to OpenZWave with my patch above for SmartOS support, but would prefer to wait until I can get python-openzwave working as well so I can more thoroughly test it myself.

papertigers commented 6 years ago

I have also been looking into this issue along with @bahamas10. I am able to successfully build python-openzwave via --flavor=dev with a checkout of the patched openzwave. But, I have to use this patch:

diff --git a/pyozw_setup.py b/pyozw_setup.py
index f9d2d21..3d5f9b3 100644
--- a/pyozw_setup.py
+++ b/pyozw_setup.py
@@ -181,7 +181,7 @@ class Template(object):

         elif sys.platform.startswith("sunos"):
             if static:
-                ctx['libraries'] += [ "udev", "stdc++",'resolv' ]
+                ctx['libraries'] += [ "usb-1.0", "stdc++",'resolv' ]
                 ctx['extra_objects'] = [ "{0}/libopenzwave.a".format(self.openzwave) ]
                 ctx['include_dirs'] += [ "{0}/cpp/build/linux".format(self.openzwave) ]
             else:
diff --git a/src-lib/libopenzwave/libopenzwave.pyx b/src-lib/libopenzwave/libopenzwave.pyx
index c35bbe0..262ae6c 100644
--- a/src-lib/libopenzwave/libopenzwave.pyx
+++ b/src-lib/libopenzwave/libopenzwave.pyx
@@ -32,7 +32,7 @@ from libcpp.map cimport map, pair
 from libcpp cimport bool
 #from libc.stdint cimport bint
 from libcpp.vector cimport vector
-from libc.stdint cimport uint16_t,  uint32_t, uint64_t, int32_t, int16_t, uint8_t, int8_t
+from libc.stdint cimport uint16_t,  uint32_t, uint64_t, int32_t, int16_t, uint8_t
 from libc.stdlib cimport malloc, free
 #from libcpp.string cimport string
 from mylibc cimport string
@@ -60,6 +60,8 @@ import warnings
 import six
 from shutil import copyfile

+ctypedef signed char int8_t
+
 # Set default logging handler to avoid "No handler found" warnings.
 import logging
try: # Python 2.7+

What's not clear to me is why int8_t resolves to a char * in one file and a signed char * in another. Anyone know what's up with that?

bibi21000 commented 5 years ago

I you can compile / install openzwave, simply try to use the flavor "shared". But looking at papertigers comment, there seems to have other problems.

@papertigers :

         elif sys.platform.startswith("sunos"):
             if static:
-                ctx['libraries'] += [ "udev", "stdc++",'resolv' ]
+                ctx['libraries'] += [ "usb-1.0", "stdc++",'resolv' ]

This update is specific to smartos or also apply to sunos ? If this is specific, is there a way to identify smartos (in python) ?

Which version of cython is installed on smartos ?

Thanks

bibi21000 commented 5 years ago

Could you try to install the last release (0.4.8). I've updated the setup process according to your changes in openzwave :

Don't know if ldconfig is present on smartos too :

For the problem of int8_t resolving, don't know what happen. Looking at cython code : https://github.com/cython/cython/blob/master/Cython/Includes/libc/stdint.pxd#L9 I should be resolved to

ctypedef signed char int8_t

HTH