[Companion][Simulator] Add custom qDebug message handler/formatter (#4475)

* [Companion][Simulator] Add custom qDebug message handler/formatter as an option. Keeps support for QT_MESSAGE_PATTERN env. var.

* [Simulator] Show system messages of level qInfo and above in debug console.

* [Simulator] Still capture screenshot to clipboard if path is not accessible (and screenshot results now print to simulator debug console).

* Fix for older CMake.

* [Companion] Do not start debug message handler if app is shutting down, and add null checks before using it; Increase backtrace report depth; Add OTx headers; Add Companion exit status debug; Clean up unused code.

* [Simulator] Add asynchronous FIFO buffer for handling debug output/display more efficiently. (#4488)
(cherry-picked from b12bd7d7be)
This commit is contained in:
Max Paperno
2017-03-02 18:35:00 +01:00
committed by Bertrand Songis
parent 620094e358
commit 00b2799427
14 changed files with 352 additions and 72 deletions
+24
View File
@@ -43,8 +43,16 @@ git_id(GIT_STR)
message(STATUS "OpenTX ${VERSION} @${GIT_STR}")
# options shared by all targets
option(APP_CUSTOM_DBG_HANDLER "Use custom message handler for debug output in all Qt apps." ON)
set(APP_CUSTOM_DBG_LEVEL "0" CACHE STRING
"Debug output level: 0=debug+; 1=info+; 2=warn+; 3=critical+; 4=fatal only.")
set(APP_CUSTOM_DBG_SHOW_FILE "DEFAULT" CACHE STRING
"Show source file names in debug output. 1/0/DEFAULT (default is ON with DEBUG builds).")
option(VERBOSE_CMAKELISTS "Show extra information while processing CMakeLists.txt files." OFF)
option(WARNINGS_AS_ERRORS "Treat any compiler warning as an error (adds -Werror flag)." OFF)
if(WIN32)
set(WIN_EXTRA_LIBS_PATH "C:/Programs" CACHE PATH
"Base path to extra libs/headers on Windows (SDL & pthreads folders should be in here).")
@@ -60,6 +68,22 @@ find_package(Qt5Svg)
if(Qt5Widgets_FOUND)
message(STATUS "Qt Version: ${Qt5Widgets_VERSION}")
list(APPEND APP_COMMON_DEFINES -DSIMU)
list(APPEND APP_COMMON_DEFINES -DQXT_STATIC)
list(APPEND APP_COMMON_DEFINES -DQT_USE_QSTRINGBUILDER) # more efficient QString construction using % operator
if(APP_CUSTOM_DBG_HANDLER)
# provide full qDebug log context to our custom handler. This may also affect libsimulator, which is why it is here
list(APPEND APP_COMMON_DEFINES -DQT_MESSAGELOGCONTEXT)
list(APPEND APP_COMMON_DEFINES -DAPP_DBG_HANDLER_ENABLE=1)
if(APP_CUSTOM_DBG_LEVEL GREATER -1 AND APP_CUSTOM_DBG_LEVEL LESS 5)
list(APPEND APP_COMMON_DEFINES -DAPP_DBG_HANDLER_DEFAULT_LEVEL=${APP_CUSTOM_DBG_LEVEL})
endif()
if(NOT APP_CUSTOM_DBG_SHOW_FILE STREQUAL "DEFAULT" AND (APP_CUSTOM_DBG_SHOW_FILE STREQUAL "1" OR APP_CUSTOM_DBG_SHOW_FILE STREQUAL "0"))
list(APPEND APP_COMMON_DEFINES -DAPP_DBG_HANDLER_SHOW_SRC_PATH=${APP_CUSTOM_DBG_SHOW_FILE})
endif()
else()
list(APPEND APP_COMMON_DEFINES -DAPP_DBG_HANDLER_ENABLE=0)
endif()
else()
message(WARNING "Qt not found! Companion and Simulator builds disabled.")
endif()
+7 -3
View File
@@ -51,8 +51,7 @@ if(SDL_FOUND)
add_definitions(-DJOYSTICKS)
endif()
add_definitions(-DSIMU)
add_definitions(-DQXT_STATIC)
add_definitions(${APP_COMMON_DEFINES}) # set in top-level CMakeLists
if(NOT MSVC)
set(WARNING_FLAGS "${WARNING_FLAGS} -Wall")
@@ -115,6 +114,7 @@ add_subdirectory(thirdparty/qxtcommandoptions)
############# Common lib ###############
set(common_SRCS
appdebugmessagehandler.cpp
boards.cpp
eeprominterface.cpp
radiodata.cpp
@@ -126,7 +126,11 @@ set(common_SRCS
firmwares/opentx/opentxinterface.cpp
)
qt5_wrap_cpp(common_SRCS)
set(common_MOC_HDRS
appdebugmessagehandler.h
)
qt5_wrap_cpp(common_SRCS ${common_MOC_HDRS})
add_library(common ${common_SRCS})
qt5_use_modules(common Core Xml Widgets)
+128
View File
@@ -0,0 +1,128 @@
/*
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* 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.
*/
#include "appdebugmessagehandler.h"
AppDebugMessageHandler::AppDebugMessageHandler(QObject * parent) :
QObject(parent),
m_appDebugOutputLevel(APP_DBG_HANDLER_DEFAULT_LEVEL),
m_showSourcePath(APP_DBG_HANDLER_SHOW_SRC_PATH),
m_showFunctionDeclarations(APP_DBG_HANDLER_SHOW_FUNCTION_DECL)
{
m_srcPathFilter = QRegularExpression("^" APP_DBG_HANDLER_SRC_PATH "[\\\\\\/](.*?)$", QRegularExpression::InvertedGreedinessOption);
m_functionFilter = QRegularExpression("^.+?(\\w+\\().+$");
}
AppDebugMessageHandler * AppDebugMessageHandler::instance()
{
static AppDebugMessageHandler * _instance = NULL;
if(_instance == NULL && !qApp->closingDown())
_instance = new AppDebugMessageHandler(qApp); // Ensure this object is cleaned up when the QApplication exits.
return _instance;
}
void AppDebugMessageHandler::setAppDebugOutputLevel(const quint8 & appDebugOutputLevel)
{
m_appDebugOutputLevel = appDebugOutputLevel;
}
void AppDebugMessageHandler::setShowSourcePath(bool showSourcePath)
{
m_showSourcePath = showSourcePath;
}
void AppDebugMessageHandler::setShowFunctionDeclarations(bool showFunctionDeclarations)
{
m_showFunctionDeclarations = showFunctionDeclarations;
}
void AppDebugMessageHandler::installAppMessageHandler()
{
#if APP_DBG_HANDLER_ENABLE
m_defaultHandler = qInstallMessageHandler(g_appDebugMessageHandler);
#endif
}
void AppDebugMessageHandler::messageHandler(QtMsgType type, const QMessageLogContext & context, const QString & msg)
{
static const char symbols[] = { 'D', 'W', 'E', 'X', 'I' }; // correspond to QtMsgType enum
// normalize types, QtDebugMsg stays 0, QtInfoMsg becomes 1, rest are QtMsgType + 1
quint8 lvl = type;
if (type == QtInfoMsg)
lvl = 1;
else if (type > QtDebugMsg)
++lvl;
if (lvl < m_appDebugOutputLevel && type != QtFatalMsg)
return;
QString msgPattern = QString("[%1] ").arg(symbols[type]);
if (m_showSourcePath) {
QString file = QString("%1::").arg(context.file);
file.replace(m_srcPathFilter, "\\1");
msgPattern.append(file);
}
if (m_showFunctionDeclarations)
msgPattern.append(context.function);
else
msgPattern.append("%{function}()");
msgPattern.append(":%{line} -%{if-category} [%{category}]%{endif} %{message}");
if (type == QtFatalMsg)
msgPattern.append("\nBACKTRACE:\n%{backtrace depth=12 separator=\"\n\"}");
qSetMessagePattern(msgPattern);
if (!m_defaultHandler || receivers(SIGNAL(messageOutput(quint8, const QString &, const QMessageLogContext &)))) {
#if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0))
msgPattern = qFormatLogMessage(type, context, msg);
#else
msgPattern.replace("%{line}", QString::number(context.line));
msgPattern.replace("%{if-category} [%{category}]%{endif}", QString(context.category));
msgPattern.replace("%{message}", msg);
if (!m_showFunctionDeclarations) {
QString func = context.function;
msgPattern.replace(QString("%{function}"), func.replace(m_functionFilter, "\\1)"));
}
#endif
emit messageOutput(lvl, msgPattern, context);
}
// if (QThread::currentThread() == qApp->thread()) // gui thread
if (m_defaultHandler) {
m_defaultHandler(type, context, msg);
}
else {
fprintf(stderr, "%s", qPrintable(msgPattern));
if (type == QtFatalMsg)
abort();
}
}
// Message handler which is installed using qInstallMessageHandler. This needs to be global.
void g_appDebugMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
if (AppDebugMessageHandler::instance())
AppDebugMessageHandler::instance()->messageHandler(type, context, msg);
}
+138
View File
@@ -0,0 +1,138 @@
/*
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* 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.
*/
#ifndef APPDEBUGMESSAGEHANDLER_H
#define APPDEBUGMESSAGEHANDLER_H
#include <cstdlib>
#include <iostream>
#include <QApplication>
#include <QDebug>
#include <QMessageLogContext>
#include <QObject>
#include <QRegularExpression>
#include <QString>
/*
* Custom debug/message handler class to work in conjunction with qDebug() family of functions.
* Formats all stderr output generated by the application in a consistent manner.
* It can also be used by other event listeners to intercept messages they may be interested in (connect to messageOutput() signal).
*
* Include this header to use qInfo() safely with Qt < v5.5 (qInfo becomes alias for qDebug).
*
* Note that the default message format can still be overriden by setting QT_MESSAGE_PATTERN environment variable at _runtime_.
* see: https://doc.qt.io/qt-5/qtglobal.html#qSetMessagePattern
*
* This is an app-wide "global" thread-safe singleton class, use it with AppDebugMessageHandler::instance().
* For example, at start of application:
*
* QApplication app(argc, argv);
* AppDebugMessageHandler::instance()->installAppMessageHandler();
*
* To connect to a signal:
*
* connect(AppDebugMessageHandler::instance(), &AppDebugMessageHandler::messageOutput, this, &DebugOutput::onAppDebugMessage);
*
* This singleton will self-destruct upon QApplication termination.
*
*/
#if defined(QT_DEBUG) || defined(DEBUG)
#define APP_DBG_HANDLER_IS_DBG_BUILD 1
#else
#define APP_DBG_HANDLER_IS_DBG_BUILD 0
#endif
// Enable/disable this custom handler handler entirely
#ifndef APP_DBG_HANDLER_ENABLE
#define APP_DBG_HANDLER_ENABLE 1
#endif
// Default log level (can also be set with setAppDebugOutputLevel()):
// 0 = debug+; 1 = info+; 2 = warn+; 3 = critical+; 4 = fatal only
#ifndef APP_DBG_HANDLER_DEFAULT_LEVEL
#define APP_DBG_HANDLER_DEFAULT_LEVEL 0
#endif
// Include source file path/name in output (filtered with APP_DBG_HANDLER_SRC_PATH)
#ifndef APP_DBG_HANDLER_SHOW_SRC_PATH
#define APP_DBG_HANDLER_SHOW_SRC_PATH APP_DBG_HANDLER_IS_DBG_BUILD
#endif
// Show just the function Class::name vs. full declaration with return and param types
#ifndef APP_DBG_HANDLER_SHOW_FUNCTION_DECL
#define APP_DBG_HANDLER_SHOW_FUNCTION_DECL 0
#endif
// base path for source file name filter, everything after this is kept; RegEx, non-greedy
#ifndef APP_DBG_HANDLER_SRC_PATH
#define APP_DBG_HANDLER_SRC_PATH ".*src"
#endif
// Make sure to include this header if using qInfo()
#if (QT_VERSION < QT_VERSION_CHECK(5, 5, 0))
#if defined(QT_NO_INFO_OUTPUT)
#define qInfo QT_NO_QDEBUG_MACRO
#else
#define qInfo qDebug
#endif
#define QtInfoMsg 4
#endif
class AppDebugMessageHandler : public QObject
{
Q_OBJECT
public:
// This class implements the singleton design pattern and is therefore publicly accessible only through instance().
static AppDebugMessageHandler * instance();
AppDebugMessageHandler(AppDebugMessageHandler const &) = delete;
void operator = (AppDebugMessageHandler const &) = delete;
void setAppDebugOutputLevel(const quint8 & appDebugOutputLevel);
void setShowSourcePath(bool showSourcePath);
void setShowFunctionDeclarations(bool showFunctionDeclarations);
void installAppMessageHandler();
void messageHandler(QtMsgType type, const QMessageLogContext & context, const QString & msg);
private:
// This class implements the singleton design pattern and therefore has only a private constructor.
explicit AppDebugMessageHandler(QObject * parent = Q_NULLPTR);
~AppDebugMessageHandler() { }
QtMessageHandler m_defaultHandler;
QRegularExpression m_srcPathFilter;
QRegularExpression m_functionFilter;
quint8 m_appDebugOutputLevel;
bool m_showSourcePath;
bool m_showFunctionDeclarations;
signals:
void messageOutput(quint8 level, const QString & msg, const QMessageLogContext & context);
};
// Message handler which is installed using qInstallMessageHandler. This needs to be global.
// Use AppDebugMessageHandler::instance()->installAppMessageHandler();
// instead of installing this function directly (it will verify this handler is enabled, etc).
void g_appDebugMessageHandler(QtMsgType, const QMessageLogContext &, const QString &);
#endif // APPDEBUGMESSAGEHANDLER_H
+11 -12
View File
@@ -26,20 +26,15 @@
#include <SDL.h>
#undef main
#endif
#include "appdebugmessagehandler.h"
#include "mainwindow.h"
#include "version.h"
#include "appdata.h"
#include "storage.h"
#if defined _MSC_VER || !defined __GNUC__
#include <windows.h>
#define sleep(x) Sleep(x*1000)
#else
#include <unistd.h>
#endif
#ifdef __APPLE__
#include <QProxyStyle>
#include <QProxyStyle>
class MyProxyStyle : public QProxyStyle
{
@@ -62,11 +57,14 @@ int main(int argc, char *argv[])
#endif
QApplication app(argc, argv);
app.setApplicationName("OpenTX Companion");
app.setOrganizationName("OpenTX");
app.setOrganizationDomain("open-tx.org");
app.setApplicationName(APP_COMPANION);
app.setOrganizationName(COMPANY);
app.setOrganizationDomain(COMPANY_DOMAIN);
app.setAttribute(Qt::AA_DontShowIconsInMenus, false);
if (AppDebugMessageHandler::instance())
AppDebugMessageHandler::instance()->installAppMessageHandler();
g.init();
QStringList strl = QApplication::arguments();
@@ -101,7 +99,7 @@ int main(int argc, char *argv[])
fprintf(stderr, "ERROR: couldn't initialize SDL: %s\n", SDL_GetError());
}
#endif
registerStorageFactories();
registerOpenTxFirmwares();
registerSimulators();
@@ -142,5 +140,6 @@ int main(int argc, char *argv[])
SDL_Quit();
#endif
qDebug() << "COMPANION EXIT" << result;
return result;
}
-6
View File
@@ -61,12 +61,6 @@
#define COMPANION_INSTALLER "companion-windows-%1.exe"
#endif
#if defined _MSC_VER || !defined __GNUC__
#include <windows.h>
#define sleep(x) Sleep(x*1000)
#else
#include <unistd.h>
#endif
#ifdef WIN32
#define OPENTX_NIGHT_COMPANION_DOWNLOADS "http://downloads-22.open-tx.org/nightly/companion/windows"
#else
-7
View File
@@ -33,13 +33,6 @@
#include "storage.h"
#include "radiointerface.h"
#if defined _MSC_VER || !defined __GNUC__
#include <windows.h>
#define sleep(x) Sleep(x*1000)
#else
#include <unistd.h>
#endif
MdiChild::MdiChild(MainWindow * parent):
QWidget(),
parent(parent),
+14
View File
@@ -21,6 +21,7 @@
#include "debugoutput.h"
#include "ui_debugoutput.h"
#include "appdebugmessagehandler.h"
#include "appdata.h"
#include "filteredtextbuffer.h"
@@ -100,6 +101,9 @@ DebugOutput::DebugOutput(QWidget * parent, SimulatorInterface *simulator):
connect(ui->actionToggleFilter, &QAction::toggled, this, &DebugOutput::onFilterToggled);
connect(ui->filterText, &QComboBox::currentTextChanged, this, &DebugOutput::onFilterTextChanged);
if (AppDebugMessageHandler::instance())
connect(AppDebugMessageHandler::instance(), &AppDebugMessageHandler::messageOutput, this, &DebugOutput::onAppDebugMessage);
// send firmware TRACE events to our data collector
m_simulator->installTraceHook(firmwareTraceCb);
}
@@ -108,6 +112,8 @@ DebugOutput::~DebugOutput()
{
saveState();
if (AppDebugMessageHandler::instance())
disconnect(AppDebugMessageHandler::instance(), 0, this, 0);
if (m_dataBufferDevice) {
disconnect(m_dataBufferDevice, 0, this, 0);
@@ -198,6 +204,14 @@ void DebugOutput::onDataBufferOverflow(const qint64 len)
}
}
void DebugOutput::onAppDebugMessage(quint8 level, const QString & msg, const QMessageLogContext & context)
{
if (level > 0) {
firmwareTraceCb(qPrintable(msg));
firmwareTraceCb("\n");
}
}
/*
* UI handlers
*/
+2
View File
@@ -44,6 +44,7 @@ namespace Ui {
}
class QAbstractButton;
class QMessageLogContext;
class FilteredTextBuffer;
using namespace Simulator;
@@ -71,6 +72,7 @@ class DebugOutput : public QWidget
void restoreState();
void processBytesReceived();
void onDataBufferOverflow(const qint64 len);
void onAppDebugMessage(quint8 level, const QString & msg, const QMessageLogContext & context);
void onFilterStateChanged();
void onFilterTextChanged(const QString &);
void onFilterToggled(bool enable);
@@ -122,16 +122,16 @@ void SimulatedUIWidget::captureScreenshot()
if (path.isEmpty())
path = "./";
QDir dir(path);
if (!dir.exists() || !dir.isReadable()) {
// m_simulator->traceCallback("SIMULATOR ERROR - Cannot open screenshot folder, check your settings.\n");
qDebug() << "SIMULATOR ERROR - Cannot open screenshot folder, check your settings.";
return;
if (dir.exists() && dir.isReadable()) {
QStringList fwid = getCurrentFirmware()->getId().split("-", QString::SkipEmptyParts);
QString flavor = fwid.at(qMin(1, fwid.size()));
QString fnpfx = tr("screenshot", "Simulator LCD screenshot file name prefix");
fileName = "%1/%2_%3_%4.png";
fileName = fileName.arg(dir.absolutePath(), fnpfx, flavor, QDateTime::currentDateTime().toString("yy-MM-dd_HH-mm-ss"));
}
else {
qWarning() << "SIMULATOR ERROR - Cannot open screenshot folder, check your settings.";
}
QStringList fwid = getCurrentFirmware()->getId().split("-", QString::SkipEmptyParts);
QString flavor = fwid.at(qMin(1, fwid.size()));
QString fnpfx = tr("screenshot", "Simulator LCD screenshot file name prefix");
fileName = "%1/%2_%3_%4.png";
fileName = fileName.arg(dir.absolutePath(), fnpfx, flavor, QDateTime::currentDateTime().toString("yy-MM-dd_HH-mm-ss"));
}
m_lcd->makeScreenshot(fileName);
}
+5 -5
View File
@@ -22,6 +22,7 @@
#include "ui_simulatorwidget.h"
#include "appdata.h"
#include "appdebugmessagehandler.h"
#include "radiofaderwidget.h"
#include "radioknobwidget.h"
#include "radioswitchwidget.h"
@@ -36,7 +37,6 @@
#include "joystickdialog.h"
#endif
#include <QDebug>
#include <QFile>
#include <iostream>
@@ -332,11 +332,11 @@ bool SimulatorWidget::useTempDataPath(bool deleteOnClose)
setDataPath(tmpDir.path());
tmpDir.setAutoRemove(false);
deleteTempRadioData = deleteOnClose;
qDebug() << __FILE__ << __LINE__ << "Created temporary settings directory" << radioDataPath << "with delteOnClose:" << deleteOnClose;
qDebug() << "Created temporary settings directory" << radioDataPath << "with delteOnClose:" << deleteOnClose;
return true;
}
else {
qDebug() << __FILE__ << __LINE__ << "ERROR : Failed to create temporary settings directory" << radioDataPath;
qCritical() << "ERROR : Failed to create temporary settings directory" << radioDataPath;
return false;
}
}
@@ -381,7 +381,7 @@ bool SimulatorWidget::saveTempData()
if (!(ret = store.write(radioData)))
error = store.error();
else
qDebug() << __FILE__ << __LINE__ << "Saved radio data to file" << file;
qInfo() << "Saved radio data to file" << file;
}
}
@@ -398,7 +398,7 @@ void SimulatorWidget::deleteTempData()
{
if (!radioDataPath.isEmpty()) {
QDir tpath(radioDataPath);
qDebug() << __FILE__ << __LINE__ << "Deleting temporary settings directory" << tpath.absolutePath();
qDebug() << "Deleting temporary settings directory" << tpath.absolutePath();
tpath.removeRecursively();
tpath.rmdir(radioDataPath); // for some reason this is necessary to remove the base folder
}
+4 -3
View File
@@ -26,8 +26,9 @@
#include <QPainter>
#include <QClipboard>
#include <QDir>
#include <QDebug>
#include "appdata.h"
#include "appdebugmessagehandler.h"
class LcdWidget : public QWidget
{
@@ -90,12 +91,12 @@ class LcdWidget : public QWidget
QPainter p(&buffer);
doPaint(p);
if (fileName.isEmpty()) {
qDebug() << "Screenshot saved to clipboard";
QApplication::clipboard()->setPixmap( buffer );
qInfo() << "Screenshot saved to clipboard";
}
else {
qDebug() << "Screenshot" << fileName;
buffer.toImage().save(fileName);
qInfo() << "Screenshot saved to:" << fileName;
}
}
+5 -24
View File
@@ -24,7 +24,6 @@
#include <QLocale>
#include <QString>
#include <QDir>
#include <QDebug>
#include <QTextStream>
#include <QMessageBox>
#if defined(JOYSTICKS) || defined(SIMU_AUDIO)
@@ -33,6 +32,7 @@
#endif
#include "appdata.h"
#include "appdebugmessagehandler.h"
#include "constants.h"
#include "eeprominterface.h"
#include "simulator.h"
@@ -42,16 +42,6 @@
#include "qxtcommandoptions.h"
#include "version.h"
#ifdef WIN32
#include <windows.h>
#ifdef _MSC_VER
#define sleep(x) Sleep(x*1000)
#endif
#endif
#if !defined(_MSC_VER) || defined(__GNUC__)
#include <unistd.h>
#endif
using namespace Simulator;
int finish(int exitCode);
@@ -96,21 +86,15 @@ int main(int argc, char *argv[])
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
#if defined(WIN32) && defined(WIN_USE_CONSOLE_STDIO)
if (!GetConsoleWindow()) {
AllocConsole();
freopen("conin$", "r", stdin);
freopen("conout$", "w", stdout);
freopen("conout$", "w", stderr);
}
SetConsoleTitle(APP_SIMULATOR " Console");
#endif
QApplication app(argc, argv);
app.setApplicationName(APP_SIMULATOR);
app.setOrganizationName(COMPANY);
app.setOrganizationDomain(COMPANY_DOMAIN);
if (AppDebugMessageHandler::instance())
AppDebugMessageHandler::instance()->installAppMessageHandler();
g.init();
QTranslator companionTranslator;
@@ -219,7 +203,7 @@ int main(int argc, char *argv[])
return finish(0);
}
}
qDebug() << __FILE__ << __LINE__ << "profileId=" << profileId << simOptions;
qDebug() << "profileId=" << profileId << simOptions;
if (profileId < 0 || simOptions.firmwareId.isEmpty() || (simOptions.dataFile.isEmpty() && simOptions.dataFolder.isEmpty())) {
showMessage(QObject::tr("ERROR: Couldn't start simulator, missing radio/profile/data file/folder.\n Profile ID: [%1]; Radio ID: [%2];\nData File: [%3]")
@@ -277,9 +261,6 @@ int finish(int exitCode)
#if defined(JOYSTICKS) || defined(SIMU_AUDIO)
SDL_Quit();
#endif
#if defined(WIN32) && defined(WIN_USE_CONSOLE_STDIO)
FreeConsole();
#endif
return exitCode;
}
+5 -3
View File
@@ -10,7 +10,6 @@ set(SIMU_SRC
simudisk.cpp
)
add_definitions(-DSIMU)
remove_definitions(-DCLI)
if(SDL_FOUND)
@@ -29,6 +28,7 @@ if(Qt5Widgets_FOUND)
include_directories(${COMPANION_SRC_DIRECTORY} ${COMPANION_SRC_DIRECTORY}/simulation)
add_library(${SIMULATOR_TARGET} SHARED ${SIMU_SRC} opentxsimulator.cpp)
add_dependencies(${SIMULATOR_TARGET} ${FIRMWARE_DEPENDENCIES})
target_compile_definitions(${SIMULATOR_TARGET} PUBLIC ${APP_COMMON_DEFINES}) # set in top-level CMakeLists
target_link_libraries(${SIMULATOR_TARGET} ${SDL_LIBRARY})
qt5_use_modules(${SIMULATOR_TARGET} Core)
add_custom_target(libsimulator DEPENDS ${SIMULATOR_TARGET})
@@ -57,14 +57,16 @@ use_cxx11() # ensure gnu++11 in CXX_FLAGS with CMake < 3.1
if(FOX_FOUND)
if(SIMU_DISKIO)
add_definitions(-DSIMU_DISKIO)
set(SIMU_SRC ${SIMU_SRC} ${FATFS_DIR}/FatFs/ff.c ${FATFS_DIR}/option/ccsbcs.c)
endif()
add_executable(simu WIN32 ${SIMU_SRC} ${RADIO_SRC_DIRECTORY}/simu.cpp)
add_dependencies(simu ${FIRMWARE_DEPENDENCIES})
target_include_directories(simu PUBLIC ${FOX_INCLUDE_DIR} )
target_link_libraries(simu ${FOX_LIBRARY} pthread ${SDL_LIBRARY})
target_compile_definitions(simu PUBLIC -DSIMU)
if(SIMU_DISKIO)
target_compile_definitions(simu PUBLIC -DSIMU_DISKIO)
endif()
endif()
if(APPLE)