Merge pull request #3 from OpenZWave/buildfixes

Buildfixes
This commit is contained in:
Justin Hammond 2020-02-09 15:30:36 +08:00 committed by GitHub
commit 2212242632
16 changed files with 880 additions and 33 deletions

View file

@ -2,3 +2,9 @@
This is a Gui for OpenZWave, intended to replace the open-zwave-control-panel eventually.
Work in Progress. Don't expect much right now :)
If you are using the ozwdaemon docker image, you need to allow remote network access to the Docker Image:
```docker run -it --security-opt seccomp=unconfined --device=/dev/ttyUSB0 -v /tmp/ozw:/opt/ozw/config -e MQTT_SERVER="10.100.200.102" -e USBPATH=/dev/ttyUSB0 --network host openzwave/ozwdaemon:latest```
Then in the OZWAdmin gui, when opening a "Remote Connection" specify the IP address of the Host the Docker Image is running on.

View file

@ -1,21 +0,0 @@
#!/bin/bash
if [ $# -lt 3 ]; then
echo "Please Provide the path to the App Bundle and OZW Config Directory and QT Directories"
exit 1
fi
if [ ! -f $1/Contents/Frameworks/libqt-openzwave.1.dylib ]; then
echo "$1/Contents/Frameworks/libqt-openzwave.1.dylib doens't exist"
exit 1
fi
if [ ! -f $2/manufacturer_specific.xml ]; then
echo "$2/manufacturer_specific.xml doesn't exist"
exit 1
fi
if [ ! -f $3/bin/macdeployqt ]; then
echo "$3/bin/macdeployqt does't exist"
exit 1
fi
PATH=`otool -L $1/Contents/Frameworks/libqt-openzwave.1.dylib | grep libopenzwave | awk '{print $1}'`
/usr/bin/install_name_tool -change $PATH "@rpath/${PATH##*/}" $1/Contents/Frameworks/libqt-openzwave.1.dylib
/bin/cp -r $2 $1/Contents/Resources/config/
echo "To Finish Please Run '$3/bin/macdeployqt $1 -verbose=2 -always-overwrite'"

172
ozw-admin.pri Normal file
View file

@ -0,0 +1,172 @@
top_srcdir=$$PWD
top_builddir=$$shadowed($$PWD)
unix {
macx {
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.14
}
!macx: QMAKE_CXXFLAGS += -Wno-deprecated-copy
}
unix {
CONFIG-= no-pkg-config
CONFIG+= link_pkgconfig
!isEmpty(OZW_LIB_PATH) {
!exists($$OZW_LIB_PATH/libopenzwave.so): error("Can't find libopenzwave.so")
!exists($$OZW_INCLUDE_PATH/Manager.h) {
!exists($$OZW_LIB_PATH/cpp/src/Manager.h) {
error("Can't find Manager.h")
} else {
OZW_INCLUDE_PATH=$$OZW_LIB_PATH/cpp/src/
}
}
!exists($$OZW_DATABASE_PATH/manufacturer_specific.xml) {
!exists($$OZW_LIB_PATH/config/manufacturer_specific.xml) {
error("Can't find manufacturer_specific.xml")
} else {
OZW_DATABASE_PATH=$$absolute_path($$OZW_LIB_PATH/config/)
}
}
OZW_LIB_PATH=$$absolute_path($$OZW_LIB_PATH)
OZW_INCLUDE_PATH=$$absolute_path($$OZW_INCLUDE_PATH)
OZW_LIBS="-L$$OZW_LIB_PATH"
OZW_LIBS+="-lopenzwave"
OZW_DATABASE_PATH=$$absolute_path($$OZW_DATABASE_PATH)
message(" ")
message("OpenZWave Summary:")
message(" OpenZWave Library Path: $$OZW_LIB_PATH")
message(" OpenZWave Include Path: $$OZW_INCLUDE_PATH")
message(" OpenZWave Libs Command: $$OZW_LIBS")
message(" OpenZWave Database Path: $$OZW_DATABASE_PATH")
message(" ")
INCLUDEPATH+=$$OZW_INCLUDE_PATH
LIBS+=$$OZW_LIBS
} else {
exists( $$top_srcdir/../open-zwave/cpp/src/) {
message("Found OZW in $$absolute_path($$top_srcdir/../open-zwave/)")
OZW_LIB_PATH = "$$absolute_path($$top_srcdir/../open-zwave/)"
OZW_INCLUDE_PATH = $$absolute_path($$top_srcdir/../open-zwave/cpp/src/)
OZW_LIBS="-L$$OZW_LIB_PATH"
OZW_LIBS+="-lopenzwave"
OZW_DATABASE_PATH = $$absolute_path($$top_srcdir/../open-zwave/config/)
message(" ")
message("OpenZWave Summary:")
message(" OpenZWave Library Path: $$OZW_LIB_PATH")
message(" OpenZWave Include Path: $$OZW_INCLUDE_PATH")
message(" OpenZWave Libs Command: $$OZW_LIBS")
message(" OpenZWave Database Path: $$OZW_DATABASE_PATH")
message(" ")
INCLUDEPATH+=$$OZW_INCLUDE_PATH
LIBS+=$$OZW_LIBS
} else {
packagesExist("libopenzwave") {
PKGCONFIG += libopenzwave
OZW_DATABASE_PATH=$$system($$PKG_CONFIG --variable=sysconfdir libopenzwave)
message(" ")
message("OpenZWave Summary:")
message(" Using OpenZWave from pkg-config:")
message(" CXXFLAGS: $$system($$PKG_CONFIG --cflags libopenzwave)")
message(" LDFLAGS: $$system($$PKG_CONFIG --libs libopenzwave)")
message(" DATABASE: $$system($$PKG_CONFIG --variable=sysconfdir libopenzwave)")
message(" ")
} else {
error("Can't find OpenZWave Library and Headers");
}
}
}
!isEmpty(QTOZW_LIB_PATH) {
!exists($$QTOZW_LIB_PATH/qt-openzwave/libqt-openzwave.so): error("Can't find libqt-openzwave.so")
!exists($$QTOZW_INCLUDE_PATH/qt-openzwave/qtopenzwave.h) {
!exists($$QTOZW_LIB_PATH/qt-openzwave/include/qt-openzwave/qtopenzwave.h) {
error("Can't find Manager.h")
} else {
QTOZW_INCLUDE_PATH=$$QTOZW_LIB_PATH/qt-openzwave/include/
}
}
QTOZW_LIB_PATH=$$absolute_path($$QTOZW_LIB_PATH)
QTOZW_INCLUDE_PATH=$$absolute_path($$QTOZW_INCLUDE_PATH)
QTOZW_INCLUDE_PATH+=$$absolute_path($$QTOZW_INCLUDE_PATH/../../qt-openzwavedatabase/include/)
QTOZW_LIBS="-L$$absolute_path($$QTOZW_LIB_PATH/qt-openzwave/)"
QTOZW_LIBS+="-lqt-openzwave"
QTOZW_LIBS+="-L$$absolute_path($$QTOZW_LIB_PATH/qt-openzwavedatabase/)"
QTOZW_LIBS+="-lqt-openzwavedatabase"
message(" ")
message("QT-OpenZWave Summary:")
message(" QT-OpenZWave Library Path: $$QTOZW_LIB_PATH")
message(" QT-OpenZWave Include Path: $$QTOZW_INCLUDE_PATH")
message(" Qt-OpenZWave Libs Command: $$QTOZW_LIBS")
message(" ")
INCLUDEPATH+=$$QTOZW_INCLUDE_PATH
LIBS+=$$QTOZW_LIBS
} else {
exists($$top_srcdir/../qt-openzwave/qt-openzwave/include/qt-openzwave/qtopenzwave.h) {
message("Found QTOZW in $$absolute_path($$top_srcdir/../qt-openzwave/)")
QTOZW_LIB_PATH = "$$absolute_path($$top_srcdir/../qt-openzwave/qt-openzwave/)"
QTOZW_INCLUDE_PATH = $$absolute_path($$top_srcdir/../qt-openzwave/qt-openzwave/include/)
QTOZW_INCLUDE_PATH += $$absolute_path($$top_srcdir/../qt-openzwave/qt-openzwavedatabase/include/)
QTOZW_LIBS="-L$$QTOZW_LIB_PATH"
QTOZW_LIBS+="-lqt-openzwave"
QTOZW_LIBS+="-L$$absolute_path($$QTOZW_LIB_PATH/../qt-openzwavedatabase/)"
QTOZW_LIBS+="-lqt-openzwavedatabase"
message(" ")
message("QT-OpenZWave Summary:")
message(" QT-OpenZWave Library Path: $$QTOZW_LIB_PATH")
message(" QT-OpenZWave Include Path: $$QTOZW_INCLUDE_PATH")
message(" QT-OpenZWave Libs Command: $$QTOZW_LIBS")
message(" ")
INCLUDEPATH+=$$QTOZW_INCLUDE_PATH
LIBS+=$$QTOZW_LIBS
} else {
packagesExist("libqt-openzwave") {
PKGCONFIG += libqt-openzwave
message(" ")
message("QT-OpenZWave Summary:")
message(" Using QT-OpenZWave from pkg-config:")
message(" CXXFLAGS: $$system($$PKG_CONFIG --cflags libqt-openzwave)")
message(" LDFLAGS: $$system($$PKG_CONFIG --libs libqt-openzwave)")
message(" ")
} else {
error("Can't find QT-OpenZWave Library and Headers");
}
}
}
}
win32 {
CONFIG(debug, debug|release) {
BUILDTYPE = debug
} else {
BUILDTYPE = release
}
message(Checking for $$BUILDTYPE build of OZW)
exists( $$top_srcdir/../open-zwave/cpp/src/) {
message("Found OZW in $$absolute_path($$top_srcdir/../open-zwave/cpp/src)")
INCLUDEPATH += $$absolute_path($$top_srcdir/../open-zwave/cpp/src/)/
INCLUDEPATH += $$absolute_path($$top_srcdir/../qt-openzwave/qt-openzwave/include/)
INCLUDEPATH += $$absolute_path($$top_srcdir/../qt-openzwave/qt-openzwavedatabase/include/)
equals(BUILDTYPE, "release") {
exists( $$absolute_path($$top_srcdir/../open-zwave/cpp/build/windows/vs2010/ReleaseDLL/OpenZWave.dll ) ) {
LIBS += -L$$absolute_path($$top_srcdir/../open-zwave/cpp/build/windows/vs2010/ReleaseDLL) -lopenzwave
OZW_LIB_PATH = $$absolute_path($$top_srcdir/../open-zwave/cpp/build/windows/vs2010/ReleaseDLL)
} else {
error("Can't find a copy of OpenZWave.dll in the ReleaseDLL Directory");
}
} else {
equals(BUILDTYPE, "debug") {
exists ( $$absolute_path($$top_srcdir/../open-zwave/cpp/build/windows/vs2010/DebugDLL/OpenZWaved.dll )) {
LIBS += -L$$absolute_path($$top_srcdir/../open-zwave/cpp/build/windows/vs2010/DebugDLL) -lOpenZWaved
OZW_LIB_PATH = $$absolute_path($$top_srcdir/../open-zwave/cpp/build/windows/vs2010/ReleaseDLL)
} else {
error("Can't find a copy of OpenZWaved.dll in the DebugDLL Directory");
}
}
}
isEmpty(OZW_LIB_PATH) {
error("Can't find a copy of OpenZWave with the right builds");
}
} else {
error("Can't Find a copy of OpenZwave")
}
}

View file

@ -55,6 +55,8 @@ MainWindow::MainWindow(QWidget *parent) :
connect(ui->actionOpen_Log_Window, SIGNAL(triggered()), this, SLOT(openLogWindow()));
connect(ui->actionOpen_Serial_Port, SIGNAL(triggered()), this, SLOT(OpenSerialPort()));
connect(ui->actionOpen_Remote, SIGNAL(triggered()), this, SLOT(OpenRemote()));
connect(ui->action_Close, SIGNAL(triggered()), this, SLOT(CloseConnection()));
connect(ui->actionDevice_Database, SIGNAL(triggered()), this, SLOT(OpenDeviceDB()));
connect(ui->md_helpwindow, &QPushButton::clicked, this, &MainWindow::openMetaDataWindow);
connect(ui->action_Configuration, SIGNAL(triggered()), this, SLOT(openConfigWindow()));
@ -199,7 +201,12 @@ MainWindow::MainWindow(QWidget *parent) :
qDebug() << directory.absoluteFilePath();
if (directory.exists()) {
#ifndef _WIN32
QStringList dirs;
dirs << directory.absoluteFilePath().append("/");
initConfigDatabase(dirs);
#if 0
copyConfigDatabase(directory.absoluteFilePath().append("/"));
#endif
#endif
m_configpath.setPath(directory.absoluteFilePath().append("/config/"));
m_userpath.setPath(directory.absoluteFilePath().append("/config/"));
@ -320,10 +327,36 @@ void MainWindow::QTOZW_Ready() {
this->m_statTimer.start(1000);
}
void MainWindow::OpenRemote() {
bool ok;
QString text = QInputDialog::getText(this, tr("Enter Remote Host"),
tr("Hostname/IP Address:"), QLineEdit::Normal,
"localhost", &ok);
if (!ok)
return;
QUrl server;
server.setHost(text);
server.setPort(1983);
server.setScheme("tcp");
qDebug() << "Connecting to " << server;
this->m_qtozwmanager->initilizeReplica(server);
}
void MainWindow::CloseConnection() {
}
void MainWindow::OpenSerialPort() {
bool ok;
QMessageBox::warning(this, tr("OZW-Admin"),
tr("This is Work In Progress!"),
QMessageBox::Ok);
QString text = QInputDialog::getText(this, tr("Select Serial Port"),
tr("Serial Port:"), QLineEdit::Normal,
this->m_serialport, &ok);

View file

@ -42,6 +42,8 @@ public:
Q_PROPERTY(QString SerialPort MEMBER m_serialport)
public slots:
void OpenSerialPort();
void OpenRemote();
void CloseConnection();
void resizeColumns();
void NodeSelected(QModelIndex,QModelIndex);
void openLogWindow();

View file

@ -907,7 +907,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>98</width>
<width>85</width>
<height>71</height>
</rect>
</property>
@ -1086,6 +1086,8 @@
<bool>false</bool>
</attribute>
<addaction name="actionOpen_Serial_Port"/>
<addaction name="actionOpen_Remote"/>
<addaction name="action_Close"/>
<addaction name="actionOpen_Log_Window"/>
<addaction name="actionDevice_Database"/>
</widget>
@ -1120,6 +1122,22 @@
<string>&amp;Device Database</string>
</property>
</action>
<action name="actionOpen_Remote">
<property name="text">
<string>Open &amp;Remote</string>
</property>
<property name="toolTip">
<string>Open Remote</string>
</property>
</action>
<action name="action_Close">
<property name="text">
<string>&amp;Close</string>
</property>
<property name="toolTip">
<string>Close Local or Remote Connection</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>

View file

@ -5,7 +5,7 @@
#-------------------------------------------------
QT += core gui widgets xml remoteobjects websockets svg
CONFIG += silent
#CONFIG += silent
TARGET = ../ozwadmin
TEMPLATE = app
@ -31,18 +31,18 @@ FORMS += mainwindow.ui \
RESOURCES += \
ozwadmin-main.qrc \
include(../ozw-admin.pri)
#LIBS += ../devicedb-lib/libdevicedb-lib.a ../ozwadmin-widgets/libozwadmin-widgets.a
unix {
target.path = /usr/local/bin
INSTALLS += target
LIBS += -L../devicedb-lib/ -ldevicedb-lib -L../ozwadmin-widgets/ -lozwadmin-widgets
LIBS += -L../../qt-openzwave/qt-openzwave/ -lqt-openzwave -L../../qt-openzwave/qt-openzwavedatabase -lqt-openzwavedatabase
}
windows {
CONFIG(debug, debug|release) {
LIBS += -L..\devicedb-lib\debug\ -L..\ozwadmin-widgets\debug\ -L..\..\qt-openzwave\qt-openzwave\debug\
} else {
LIBS += -L..\devicedb-lib\release\ -L..\ozwadmin-widgets\release\ -L..\..\qt-openzwave\qt-openzwave\release\
LIBS += -L..\devicedb-lib\release\ -L..\ozwadmin-widgets\release\ -L..\..\qt-openzwave\qt-openzwave\release\
}
LIBS += -ldevicedb-lib -lozwadmin-widgets -lqt-openzwave1
message($$LIBS)
@ -51,14 +51,15 @@ windows {
INCLUDEPATH += ../devicedb-lib ../ozwadmin-widgets
INCLUDEPATH += ../../qt-openzwave/qt-openzwave/include/ ../../qt-openzwave/qt-openzwavedatabase/include/
macx: {
LIBS += -framework IOKit -framework CoreFoundation
BUNDLE.files = ../../qt-openzwave/qt-openzwave/libqt-openzwave.1.dylib ../../open-zwave/libopenzwave-1.6.dylib ../../qt-openzwave/qt-openzwavedatabase/libqt-openzwavedatabase.1.dylib
BUNDLE.files = $$OZW_LIB_PATH/libopenzwave-1.6.dylib $$QTOZW_LIB_PATH/libqt-openzwave.1.dylib $$QTOZW_LIB_PATH/../qt-openzwavedatabase/libqt-openzwavedatabase.1.dylib
BUNDLE.path = Contents/Frameworks/
QMAKE_BUNDLE_DATA += BUNDLE
MakeBundle.commands = $$[QT_HOST_BINS]/macdeployqt ../ozwadmin.app && $$top_srcdir/scripts/macdeployqtfix.py ../ozwadmin.app/Contents/MacOS/ozwadmin $$[QT_INSTALL_PREFIX]
QMAKE_EXTRA_TARGETS += MakeBundle
QMAKE_POST_LINK += $$MakeBundle.commands
ICON = res/ozw_logo.icns
}

View file

@ -44,7 +44,9 @@ FORMS += HelpEditorDlg.ui \
bitsetwidget.ui \
nodeflagswidget.ui
INCLUDEPATH += ../devicedb-lib ../ozwadmin-main ../../qt-openzwave/qt-openzwave/include/
include(../ozw-admin.pri)
INCLUDEPATH += ../devicedb-lib ../ozwadmin-main
macx: {

View file

@ -1,2 +0,0 @@
top_srcdir=$$PWD
top_builddir=$$shadowed($$PWD)

11
scripts/Dockerfile Normal file
View file

@ -0,0 +1,11 @@
#DockerFile to build a image capabile of Building AppImages. See build.sh for details
FROM ubuntu:xenial
WORKDIR /opt
RUN apt update && apt-get install -y software-properties-common && add-apt-repository ppa:beineri/opt-qt-5.12.6-xenial && \
apt update && apt-get install -y qt512-meta-minimal qt512remoteobjects rapidjson-dev git g++ cmake make pkgconf bash python wget joe mc libunwind-dev libcurl4-openssl-dev qt512svg qt512websockets mesa-common-dev libgl1-mesa-dev fuse appstream && \
wget https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage && \
wget https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-x86_64.AppImage && \
chmod +x linuxdeploy*.AppImage
VOLUME /opt/buildfiles
ENTRYPOINT /opt/buildfiles/build.sh

16
scripts/build.sh Executable file
View file

@ -0,0 +1,16 @@
#!/bin/bash
#Build File for Docker Image.
#Run docker in this directory with: docker run -it --rm --device /dev/fuse --privileged -v`pwd`:/opt/buildfiles -e DOCKERUSERID=`id -u` -e DOCKERGROUPID=`id -g` <docker image>
cd /opt
git clone https://github.com/OpenZWave/open-zwave.git && cd open-zwave && make -j4 && make install
cd /opt
git clone https://github.com/OpenZWave/qt-openzwave.git && cd qt-openzwave && /opt/qt512/bin/qmake -r && make -j4 && make install
cd /opt
git clone https://github.com/OpenZWave/ozw-admin.git && cd ozw-admin && git checkout buildfixes && /opt/qt512/bin/qmake -r && make -j4 && make install
cd /opt
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib64
export QMAKE=/opt/qt512/bin/qmake
export VERSION=0.1
cd ozw-admin && ../linuxdeploy-x86_64.AppImage --appdir AppDir -e ozwadmin --plugin qt --output appimage -d scripts/ozwadmin.desktop -i scripts/ozwadmin.png
cp /opt/ozw-admin/OZWAdmin-*.AppImage /opt/buildfiles/
chown $DOCKERUSERID:$DOCKERGROUPID /opt/buildfiles/OZWAdmin-*.AppImage

205
scripts/dmgbuild.py Normal file
View file

@ -0,0 +1,205 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import biplist
import os.path
#
# Example settings file for dmgbuild
#
# Use like this: dmgbuild -s settings.py "Test Volume" test.dmg
# You can actually use this file for your own application (not just TextEdit)
# by doing e.g.
#
# dmgbuild -s settings.py -D app=/path/to/My.app "My Application" MyApp.dmg
# .. Useful stuff ..............................................................
application = defines.get('app', '../ozwadmin.app')
appname = os.path.basename(application)
def icon_from_app(app_path):
plist_path = os.path.join(app_path, 'Contents', 'Info.plist')
plist = biplist.readPlist(plist_path)
icon_name = plist['CFBundleIconFile']
icon_root,icon_ext = os.path.splitext(icon_name)
if not icon_ext:
icon_ext = '.icns'
icon_name = icon_root + icon_ext
return os.path.join(app_path, 'Contents', 'Resources', icon_name)
# .. Basics ....................................................................
# Uncomment to override the output filename
# filename = 'test.dmg'
# Uncomment to override the output volume name
# volume_name = 'Test'
# Volume format (see hdiutil create -help)
format = defines.get('format', 'UDBZ')
# Compression level (if relevant)
# compression_level = 9
# Volume size
size = defines.get('size', None)
# Files to include
files = [ application ]
# Symlinks to create
symlinks = { 'Applications': '/Applications' }
# Volume icon
#
# You can either define icon, in which case that icon file will be copied to the
# image, *or* you can define badge_icon, in which case the icon file you specify
# will be used to badge the system's Removable Disk icon. Badge icons require
# pyobjc-framework-Quartz.
#
#icon = '/path/to/icon.icns'
badge_icon = icon_from_app(application)
# Where to put the icons
icon_locations = {
appname: (140, 120),
'Applications': (500, 120)
}
# .. Window configuration ......................................................
# Background
#
# This is a STRING containing any of the following:
#
# #3344ff - web-style RGB color
# #34f - web-style RGB color, short form (#34f == #3344ff)
# rgb(1,0,0) - RGB color, each value is between 0 and 1
# hsl(120,1,.5) - HSL (hue saturation lightness) color
# hwb(300,0,0) - HWB (hue whiteness blackness) color
# cmyk(0,1,0,0) - CMYK color
# goldenrod - X11/SVG named color
# builtin-arrow - A simple built-in background with a blue arrow
# /foo/bar/baz.png - The path to an image file
#
# The hue component in hsl() and hwb() may include a unit; it defaults to
# degrees ('deg'), but also supports radians ('rad') and gradians ('grad'
# or 'gon').
#
# Other color components may be expressed either in the range 0 to 1, or
# as percentages (e.g. 60% is equivalent to 0.6).
background = 'builtin-arrow'
show_status_bar = False
show_tab_view = False
show_toolbar = False
show_pathbar = False
show_sidebar = False
sidebar_width = 180
# Window position in ((x, y), (w, h)) format
window_rect = ((100, 100), (640, 280))
# Select the default view; must be one of
#
# 'icon-view'
# 'list-view'
# 'column-view'
# 'coverflow'
#
default_view = 'icon-view'
# General view configuration
show_icon_preview = False
# Set these to True to force inclusion of icon/list view settings (otherwise
# we only include settings for the default view)
include_icon_view_settings = 'auto'
include_list_view_settings = 'auto'
# .. Icon view configuration ...................................................
arrange_by = None
grid_offset = (0, 0)
grid_spacing = 100
scroll_position = (0, 0)
label_pos = 'bottom' # or 'right'
text_size = 16
icon_size = 128
# .. List view configuration ...................................................
# Column names are as follows:
#
# name
# date-modified
# date-created
# date-added
# date-last-opened
# size
# kind
# label
# version
# comments
#
list_icon_size = 16
list_text_size = 12
list_scroll_position = (0, 0)
list_sort_by = 'name'
list_use_relative_dates = True
list_calculate_all_sizes = False,
list_columns = ('name', 'date-modified', 'size', 'kind', 'date-added')
list_column_widths = {
'name': 300,
'date-modified': 181,
'date-created': 181,
'date-added': 181,
'date-last-opened': 181,
'size': 97,
'kind': 115,
'label': 100,
'version': 75,
'comments': 300,
}
list_column_sort_directions = {
'name': 'ascending',
'date-modified': 'descending',
'date-created': 'descending',
'date-added': 'descending',
'date-last-opened': 'descending',
'size': 'descending',
'kind': 'ascending',
'label': 'ascending',
'version': 'ascending',
'comments': 'ascending',
}
# .. License configuration .....................................................
# Text in the license configuration is stored in the resources, which means
# it gets stored in a legacy Mac encoding according to the language. dmgbuild
# will *try* to convert Unicode strings to the appropriate encoding, *but*
# you should be aware that Python doesn't support all of the necessary encodings;
# in many cases you will need to encode the text yourself and use byte strings
# instead here.
# Recognized language names are:
#
# af_ZA, ar, be_BY, bg_BG, bn, bo, br, ca_ES, cs_CZ, cy, da_DK, de_AT, de_CH,
# de_DE, dz_BT, el_CY, el_GR, en_AU, en_CA, en_GB, en_IE, en_SG, en_US, eo,
# es_419, es_ES, et_EE, fa_IR, fi_FI, fo_FO, fr_001, fr_BE, fr_CA, fr_CH,
# fr_FR, ga-Latg_IE, ga_IE, gd, grc, gu_IN, gv, he_IL, hi_IN, hr_HR, hu_HU,
# hy_AM, is_IS, it_CH, it_IT, iu_CA, ja_JP, ka_GE, kl, ko_KR, lt_LT, lv_LV,
# mk_MK, mr_IN, mt_MT, nb_NO, ne_NP, nl_BE, nl_NL, nn_NO, pa, pl_PL, pt_BR,
# pt_PT, ro_RO, ru_RU, se, sk_SK, sl_SI, sr_RS, sv_SE, th_TH, to_TO, tr_TR,
# uk_UA, ur_IN, ur_PK, uz_UZ, vi_VN, zh_CN, zh_TW
license = {
'default-language': 'en_US',
'licenses': {
'en_US': './LICENSE'
},
}

395
scripts/macdeployqtfix.py Executable file
View file

@ -0,0 +1,395 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
finish the job started by macdeployqtfix
"""
from subprocess import Popen, PIPE
from string import Template
import os
import sys
import logging
import argparse
import re
from collections import namedtuple
QTLIB_NAME_REGEX = r'^(?:@executable_path)?/.*/(Qt[a-zA-Z]*).framework/(?:Versions/\d/)?\1$'
QTLIB_NORMALIZED = r'$prefix/Frameworks/$qtlib.framework/Versions/$qtversion/$qtlib'
QTPLUGIN_NAME_REGEX = r'^(?:@executable_path)?/.*/[pP]lug[iI]ns/(.*)/(.*).dylib$'
QTPLUGIN_NORMALIZED = r'$prefix/PlugIns/$plugintype/$pluginname.dylib'
#BREWLIB_REGEX = r'^//usr/local/.*//(.*)'
BREWLIB_REGEX =r'.*(lib.*openzwave.*dylib)'
BREWLIB_NORMALIZED = r'$prefix/Frameworks/$brewlib'
class GlobalConfig(object):
logger = None
qtpath = None
exepath = None
def run_and_get_output(popen_args):
"""Run process and get all output"""
process_output = namedtuple('ProcessOutput', ['stdout', 'stderr', 'retcode'])
try:
GlobalConfig.logger.debug('run_and_get_output({0})'.format(repr(popen_args)))
proc = Popen(popen_args, stdin=PIPE, stdout=PIPE, stderr=PIPE)
stdout, stderr = proc.communicate(b'')
proc_out = process_output(stdout, stderr, proc.returncode)
GlobalConfig.logger.debug('\tprocess_output: {0}'.format(proc_out))
return proc_out
except Exception as exc:
GlobalConfig.logger.error('\texception: {0}'.format(exc))
return process_output('', exc.message, -1)
def get_dependencies(filename):
"""
input: filename must be an absolute path
Should call `otool` and returns the list of dependencies, unsorted,
unmodified, just the raw list so then we could eventually re-use in other
more specialized functions
"""
GlobalConfig.logger.debug('get_dependencies({0})'.format(filename))
popen_args = ['otool', '-L', filename]
proc_out = run_and_get_output(popen_args)
deps = []
if proc_out.retcode == 0:
# some string splitting
deps = [s.strip().split(' ')[0] for s in proc_out.stdout.splitlines()[1:] if s]
# prevent infinite recursion when a binary depends on itself (seen with QtWidgets)...
deps = [s for s in deps if os.path.basename(filename) not in s]
return deps
def is_qt_plugin(filename):
"""
Checks if a given file is a qt plugin.
Accepts absolute path as well as path containing @executable_path
"""
qtlib_name_rgx = re.compile(QTPLUGIN_NAME_REGEX)
return qtlib_name_rgx.match(filename) is not None
def is_qt_lib(filename):
"""
Checks if a given file is a qt library.
Accepts absolute path as well as path containing @executable_path
"""
qtlib_name_rgx = re.compile(QTLIB_NAME_REGEX)
return qtlib_name_rgx.match(filename) is not None
def is_brew_lib(filename):
"""
Checks if a given file is a brew library
Accepts absolute path as well as path containing @executable_path
"""
qtlib_name_rgx = re.compile(BREWLIB_REGEX)
return qtlib_name_rgx.match(filename) is not None
def normalize_qtplugin_name(filename):
"""
input: a path to a qt plugin, as returned by otool, that can have this form :
- an absolute path /../plugins/PLUGINTYPE/PLUGINNAME.dylib
- @executable_path/../plugins/PLUGINTYPE/PLUGINNAME.dylib
output:
a tuple (qtlib, abspath, rpath) where:
- qtname is the name of the plugin (libqcocoa.dylib, etc.)
- abspath is the absolute path of the qt lib inside the app bundle of exepath
- relpath is the correct rpath to a qt lib inside the app bundle
"""
GlobalConfig.logger.debug('normalize_plugin_name({0})'.format(filename))
qtplugin_name_rgx = re.compile(QTPLUGIN_NAME_REGEX)
rgxret = qtplugin_name_rgx.match(filename)
if not rgxret:
msg = 'couldn\'t normalize a non-qt plugin filename: {0}'.format(filename)
GlobalConfig.logger.critical(msg)
raise Exception(msg)
# qtplugin normalization settings
qtplugintype = rgxret.groups()[0]
qtpluginname = rgxret.groups()[1]
templ = Template(QTPLUGIN_NORMALIZED)
# from qtlib, forge 2 path :
# - absolute path of qt lib in bundle,
abspath = os.path.normpath(templ.safe_substitute(
prefix=os.path.dirname(GlobalConfig.exepath) + '/..',
plugintype=qtplugintype,
pluginname=qtpluginname))
# - and rpath containing @executable_path, relative to exepath
rpath = templ.safe_substitute(
prefix='@executable_path/..',
plugintype=qtplugintype,
pluginname=qtpluginname)
GlobalConfig.logger.debug('\treturns({0})'.format((qtpluginname, abspath, rpath)))
return qtpluginname, abspath, rpath
def normalize_qtlib_name(filename):
"""
input: a path to a qt library, as returned by otool, that can have this form :
- an absolute path /lib/xxx/yyy
- @executable_path/../Frameworks/QtSerialPort.framework/Versions/5/QtSerialPort
output:
a tuple (qtlib, abspath, rpath) where:
- qtlib is the name of the qtlib (QtCore, QtWidgets, etc.)
- abspath is the absolute path of the qt lib inside the app bundle of exepath
- relpath is the correct rpath to a qt lib inside the app bundle
"""
GlobalConfig.logger.debug('normalize_qtlib_name({0})'.format(filename))
qtlib_name_rgx = re.compile(QTLIB_NAME_REGEX)
rgxret = qtlib_name_rgx.match(filename)
if not rgxret:
msg = 'couldn\'t normalize a non-qt lib filename: {0}'.format(filename)
GlobalConfig.logger.critical(msg)
raise Exception(msg)
# qtlib normalization settings
qtlib = rgxret.groups()[0]
qtversion = 5
templ = Template(QTLIB_NORMALIZED)
# from qtlib, forge 2 path :
# - absolute path of qt lib in bundle,
abspath = os.path.normpath(templ.safe_substitute(
prefix=os.path.dirname(GlobalConfig.exepath) + '/..',
qtlib=qtlib,
qtversion=qtversion))
# - and rpath containing @executable_path, relative to exepath
rpath = templ.safe_substitute(
prefix='@executable_path/..',
qtlib=qtlib,
qtversion=qtversion)
GlobalConfig.logger.debug('\treturns({0})'.format((qtlib, abspath, rpath)))
return qtlib, abspath, rpath
def normalize_brew_name(filename):
"""
input: a path to a brew library, as returned by otool, that can have this form :
- an absolute path /usr/local/lib/yyy
output:
a tuple (brewlib, abspath, rpath) where:
- brewlib is the name of the brew lib
- abspath is the absolute path of the qt lib inside the app bundle of exepath
- relpath is the correct rpath to a qt lib inside the app bundle
"""
GlobalConfig.logger.debug('normalize_brew_name({0})'.format(filename))
brewlib_name_rgx = re.compile(BREWLIB_REGEX)
rgxret = brewlib_name_rgx.match(filename)
if not rgxret:
msg = 'couldn\'t normalize a brew lib filename: {0}'.format(filename)
GlobalConfig.logger.critical(msg)
raise Exception(msg)
# brewlib normalization settings
brewlib = rgxret.groups()[0]
templ = Template(BREWLIB_NORMALIZED)
# from brewlib, forge 2 path :
# - absolute path of qt lib in bundle,
abspath = os.path.normpath(templ.safe_substitute(
prefix=os.path.dirname(GlobalConfig.exepath) + '/..',
brewlib=brewlib))
# - and rpath containing @executable_path, relative to exepath
rpath = templ.safe_substitute(
prefix='@executable_path/..',
brewlib=brewlib)
GlobalConfig.logger.debug('\treturns({0})'.format((brewlib, abspath, rpath)))
return brewlib, abspath, rpath
def fix_dependency(binary, dep):
"""
fix 'dep' dependency of 'binary'. 'dep' is a qt library
"""
if is_qt_lib(dep):
qtname, dep_abspath, dep_rpath = normalize_qtlib_name(dep)
elif is_qt_plugin(dep):
qtname, dep_abspath, dep_rpath = normalize_qtplugin_name(dep)
elif is_brew_lib(dep):
qtname, dep_abspath, dep_rpath = normalize_brew_name(dep)
else:
return True
dep_ok = True
# check that rpath of 'dep' inside binary has been correctly set
# (ie: relative to exepath using '@executable_path' syntax)
if dep != dep_rpath:
# dep rpath is not ok
GlobalConfig.logger.info('changing rpath \'{0}\' in binary {1}'.format(dep, binary))
# call install_name_tool -change on binary
popen_args = ['install_name_tool', '-change', dep, dep_rpath, binary]
proc_out = run_and_get_output(popen_args)
if proc_out.retcode != 0:
GlobalConfig.logger.error(proc_out.stderr)
dep_ok = False
else:
# call install_name_tool -id on binary
popen_args = ['install_name_tool', '-id', dep_rpath, binary]
proc_out = run_and_get_output(popen_args)
if proc_out.retcode != 0:
GlobalConfig.logger.error(proc_out.stderr)
dep_ok = False
# now ensure that 'dep' exists at the specified path, relative to bundle
if False and dep_ok and not os.path.exists(dep_abspath):
# ensure destination directory exists
GlobalConfig.logger.info('ensuring directory \'{0}\' exists: {0}'.
format(os.path.dirname(dep_abspath)))
popen_args = ['mkdir', '-p', os.path.dirname(dep_abspath)]
proc_out = run_and_get_output(popen_args)
if proc_out.retcode != 0:
GlobalConfig.logger.info(proc_out.stderr)
dep_ok = False
else:
# copy missing dependency into bundle
qtnamesrc = os.path.join(GlobalConfig.qtpath, 'lib', '{0}.framework'.
format(qtname), qtname)
GlobalConfig.logger.info('copying missing dependency in bundle: {0}'.
format(qtname))
popen_args = ['cp', qtnamesrc, dep_abspath]
proc_out = run_and_get_output(popen_args)
if proc_out.retcode != 0:
GlobalConfig.logger.info(proc_out.stderr)
dep_ok = False
else:
# ensure permissions are correct if we ever have to change its rpath
GlobalConfig.logger.info('ensuring 755 perm to {0}'.format(dep_abspath))
popen_args = ['chmod', '755', dep_abspath]
proc_out = run_and_get_output(popen_args)
if proc_out.retcode != 0:
GlobalConfig.logger.info(proc_out.stderr)
dep_ok = False
else:
GlobalConfig.logger.debug('{0} is at correct location in bundle'.format(qtname))
if dep_ok:
return fix_binary(dep_abspath)
return False
def fix_binary(binary):
"""
input:
binary: relative or absolute path (no @executable_path syntax)
process:
- first fix the rpath for the qt libs on which 'binary' depend
- copy into the bundle of exepath the eventual libraries that are missing
- (create the soft links) needed ?
- do the same for all qt dependencies of binary (recursive)
"""
GlobalConfig.logger.debug('fix_binary({0})'.format(binary))
# loop on 'binary' dependencies
for dep in get_dependencies(binary):
if not fix_dependency(binary, dep):
GlobalConfig.logger.error('quitting early: couldn\'t fix dependency {0} of {1}'.format(dep, binary))
return False
return True
def fix_main_binaries():
"""
list the main binaries of the app bundle and fix them
"""
# deduce bundle path
bundlepath = os.path.sep.join(GlobalConfig.exepath.split(os.path.sep)[0:-3])
# fix main binary
GlobalConfig.logger.info('fixing executable \'{0}\''.format(GlobalConfig.exepath))
if fix_binary(GlobalConfig.exepath):
GlobalConfig.logger.info('fixing plugins')
for root, dummy, files in os.walk(bundlepath):
for name in [f for f in files if os.path.splitext(f)[1] == '.dylib']:
GlobalConfig.logger.info('fixing plugin {0}'.format(name))
if not fix_binary(os.path.join(root, name)):
return False
return True
def main():
descr = """finish the job started by macdeployqt!
- find dependencies/rpaths with otool
- copy missed dependencies with cp and mkdir
- fix missed rpaths with install_name_tool
exit codes:
- 0 : success
- 1 : error
"""
parser = argparse.ArgumentParser(description=descr,
formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument('exepath',
help='path to the binary depending on Qt')
parser.add_argument('qtpath',
help='path of Qt libraries used to build the Qt application')
parser.add_argument('-q', '--quiet', action='store_true', default=False,
help='do not create log on standard output')
parser.add_argument('-nl', '--no-log-file', action='store_true', default=False,
help='do not create log file \'./macdeployqtfix.log\'')
parser.add_argument('-v', '--verbose', action='store_true', default=False,
help='produce more log messages(debug log)')
args = parser.parse_args()
# globals
GlobalConfig.qtpath = os.path.normpath(args.qtpath)
GlobalConfig.exepath = args.exepath
GlobalConfig.logger = logging.getLogger()
# configure logging
###################
# create formatter
formatter = logging.Formatter('%(levelname)s | %(message)s')
# create console GlobalConfig.logger
if not args.quiet:
chdlr = logging.StreamHandler(sys.stdout)
chdlr.setFormatter(formatter)
GlobalConfig.logger.addHandler(chdlr)
# create file GlobalConfig.logger
if not args.no_log_file:
fhdlr = logging.FileHandler('./macdeployqtfix.log', mode='w')
fhdlr.setFormatter(formatter)
GlobalConfig.logger.addHandler(fhdlr)
if args.no_log_file and args.quiet:
GlobalConfig.logger.addHandler(logging.NullHandler())
else:
GlobalConfig.logger.setLevel(logging.DEBUG if args.verbose else logging.INFO)
if fix_main_binaries():
GlobalConfig.logger.info('macdeployqtfix terminated with success')
ret = 0
else:
GlobalConfig.logger.error('macdeployqtfix terminated with error')
ret = 1
sys.exit(ret)
if __name__ == "__main__":
main()

8
scripts/ozwadmin.desktop Normal file
View file

@ -0,0 +1,8 @@
[Desktop Entry]
Name=OZWAdmin
Comment=OpenZWave Administration Gui
Exec=ozwadmin
Type=Application
Icon=ozwadmin
Categories=System;
MimeType=application/x-iso9660-appimage;

BIN
scripts/ozwadmin.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View file

@ -1,6 +1,7 @@
@echo off
cd ..\open-zwave
msbuild /p:Configuration=ReleaseDLL /p:Platform=Win32 cpp\build\windows\vs2010\OpenZWave.sln
msbuild /p:Configuration=DebugDLL /p:Platform=Win32 cpp\build\windows\vs2010\OpenZWave.sln
cd ..\qt-openzwave
qmake -r -tp vc
msbuild /p:Configuration=Release /p:Platform=Win32 qt-openzwave.sln