Added BLOOM_COMPILED_RESOURCES_PATH_OVERRIDE macro to avoid using compiled resources in debug builds

This commit is contained in:
Nav
2021-05-30 19:05:18 +01:00
parent 3c60fee231
commit 602328d9d1
16 changed files with 155 additions and 60 deletions

View File

@@ -34,6 +34,14 @@ set(CMAKE_BUILD_RPATH ${CMAKE_INSTALL_RPATH})
if (${CMAKE_BUILD_TYPE} STREQUAL "Debug")
add_compile_definitions(BLOOM_DEBUG_BUILD)
# BLOOM_COMPILED_RESOURCES_PATH_OVERRIDE can be used to override the file path used for compiled resources.
# We override this path in debug builds to avoid using compiled resources. This makes debugging and small tweaks
# a lot easier, as it removes the need to recompile for each tweak.
# CAUTION: Although convenient, this does add a limitation; the debug build can only be run on the same machine
# that compiled it. Or a machine that has the Bloom source located in the same place.
# See Paths::compiledResourcesPath() for more.
add_compile_definitions(BLOOM_COMPILED_RESOURCES_PATH_OVERRIDE="${CMAKE_CURRENT_SOURCE_DIR}")
# CMAKE_SKIP_BUILD_RPATH needs to be set to true to use Gammaray during development.
# This is because the distributed Qt binaries may not be compatible with the local installation of Gammaray
set(CMAKE_SKIP_BUILD_RPATH true)

View File

@@ -9,6 +9,7 @@
#include "Application.hpp"
#include "src/Logger/Logger.hpp"
#include "src/Helpers/Paths.hpp"
#include "SignalHandler/SignalHandler.hpp"
#include "Exceptions/InvalidConfig.hpp"
@@ -149,7 +150,11 @@ int Application::presentHelpText() {
Logger::silence();
// The file help.txt is included in the binary image as a resource. See src/resource.qrc
auto helpFile = QFile(":/compiled/resources/help.txt");
auto helpFile = QFile(QString::fromStdString(
Paths::compiledResourcesPath()
+ "/resources/help.txt"
)
);
if (!helpFile.open(QIODevice::ReadOnly)) {
// This should never happen - if it does, something has gone very wrong
@@ -188,7 +193,11 @@ int Application::initProject() {
*
* We simply copy the template file into the user's working directory.
*/
auto templateConfigFile = QFile(":/compiled/resources/bloom.template.json");
auto templateConfigFile = QFile(QString::fromStdString(
Paths::compiledResourcesPath()
+ "/resources/bloom.template.json"
)
);
if (!templateConfigFile.open(QIODevice::ReadOnly)) {
throw Exception("Failed to open template configuration file - please report this issue at https://bloom.oscillate.io/report-issue");
@@ -333,20 +342,6 @@ void Application::onDebugServerThreadStateChanged(EventPointer<Events::DebugServ
}
}
std::string Application::getApplicationDirPath() {
auto pathCharArray = std::array<char, PATH_MAX>();
if (readlink("/proc/self/exe", pathCharArray.data(), PATH_MAX) < 0) {
throw Exception("Failed to obtain application directory path.");
}
return std::filesystem::path(std::string(pathCharArray.begin(), pathCharArray.end())).parent_path();
}
std::string Application::getResourcesDirPath() {
return Application::getApplicationDirPath() + "/../resources/";
}
bool Application::isRunningAsRoot() {
return geteuid() == 0;
}

View File

@@ -248,20 +248,6 @@ namespace Bloom
*/
void onShutdownApplicationRequest(Events::EventPointer<Events::ShutdownApplication>);
/**
* Returns the path to the directory in which the Bloom binary resides.
*
* @return
*/
static std::string getApplicationDirPath();
/**
* Returns the path to the Resources directory, located in the application directory.
*
* @return
*/
static std::string getResourcesDirPath();
/**
* Checks if the current effective user running Bloom has root privileges.
*

19
src/Helpers/Paths.cpp Normal file
View File

@@ -0,0 +1,19 @@
#include <unistd.h>
#include <array>
#include <filesystem>
#include <climits>
#include <src/Exceptions/Exception.hpp>
#include "Paths.hpp"
using namespace Bloom;
std::string Paths::applicationDirPath() {
auto pathCharArray = std::array<char, PATH_MAX>();
if (readlink("/proc/self/exe", pathCharArray.data(), PATH_MAX) < 0) {
throw Exceptions::Exception("Failed to obtain application directory path.");
}
return std::filesystem::path(std::string(pathCharArray.begin(), pathCharArray.end())).parent_path();
}

43
src/Helpers/Paths.hpp Normal file
View File

@@ -0,0 +1,43 @@
#pragma once
#include <string>
namespace Bloom
{
class Paths
{
public:
/**
* Returns the path to the directory in which the Bloom binary resides.
*
* @return
*/
static std::string applicationDirPath();
/**
* Returns the path to the Resources directory, located in the application directory.
*
* @return
*/
static inline std::string resourcesDirPath() {
return Paths::applicationDirPath() + "/../resources/";
}
/**
* Returns the path to Bloom's compiled resources.
*
* If the debug configuration is enabled, this function will return the absolute path to Bloom's source code,
* meaning we won't use compiled resources for debug builds. This is useful for debugging and tweaking QT UI
* files such as QT stylesheets and UI templates.
* @return
*/
static inline const std::string compiledResourcesPath() {
#ifdef BLOOM_COMPILED_RESOURCES_PATH_OVERRIDE
return std::string(BLOOM_COMPILED_RESOURCES_PATH_OVERRIDE);
#else
return std::string(":/compiled");
#endif
}
};
}

View File

@@ -3,7 +3,7 @@
#include "Insight.hpp"
#include "InsightWorker.hpp"
#include "src/Application.hpp"
#include "src/Helpers/Paths.hpp"
#include "src/Logger/Logger.hpp"
#include "src/Exceptions/InvalidConfig.hpp"
#include "src/Targets/TargetState.hpp"
@@ -49,7 +49,7 @@ void Insight::startup() {
auto targetDescriptor = this->targetControllerConsole.getTargetDescriptor();
#ifndef BLOOM_DEBUG_BUILD
QCoreApplication::addLibraryPath(QString::fromStdString(Application::getApplicationDirPath() + "/plugins"));
QCoreApplication::addLibraryPath(QString::fromStdString(Paths::applicationDirPath() + "/plugins"));
#endif
QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts, true);

View File

@@ -5,14 +5,23 @@
#include "src/Logger/Logger.hpp"
#include "src/Exceptions/Exception.hpp"
#include "src/Application.hpp"
#include "src/Helpers/Paths.hpp"
using namespace Bloom;
using namespace InsightTargetWidgets;
using namespace Exceptions;
AboutWindow::AboutWindow(QWidget* parent): QObject(parent) {
auto aboutWindowUiFile = QFile(":/compiled/Insight/UserInterfaces/InsightWindow/UiFiles/AboutWindow.ui");
auto aboutWindowStylesheet = QFile(":/compiled/Insight/UserInterfaces/InsightWindow/Stylesheets/AboutWindow.qss");
auto aboutWindowUiFile = QFile(QString::fromStdString(
Paths::compiledResourcesPath()
+ "/src/Insight/UserInterfaces/InsightWindow/UiFiles/AboutWindow.ui"
)
);
auto aboutWindowStylesheet = QFile(QString::fromStdString(
Paths::compiledResourcesPath()
+ "/src/Insight/UserInterfaces/InsightWindow/Stylesheets/AboutWindow.qss"
)
);
if (!aboutWindowUiFile.open(QFile::ReadOnly)) {
throw Exception("Failed to open AboutWindow UI file");

View File

@@ -8,6 +8,7 @@
#include "src/Logger/Logger.hpp"
#include "src/Exceptions/Exception.hpp"
#include "src/Targets/TargetDescriptor.hpp"
#include "src/Helpers/Paths.hpp"
using namespace Bloom;
using namespace Bloom::Exceptions;
@@ -25,8 +26,16 @@ void InsightWindow::init(
) {
this->targetDescriptor = targetDescriptor;
auto mainWindowUiFile = QFile(":/compiled/Insight/UserInterfaces/InsightWindow/UiFiles/InsightWindow.ui");
auto mainWindowStylesheet = QFile(":/compiled/Insight/UserInterfaces/InsightWindow/Stylesheets/InsightWindow.qss");
auto mainWindowUiFile = QFile(
QString::fromStdString(Paths::compiledResourcesPath()
+ "/src/Insight/UserInterfaces/InsightWindow/UiFiles/InsightWindow.ui"
)
);
auto mainWindowStylesheet = QFile(
QString::fromStdString(Paths::compiledResourcesPath()
+ "/src/Insight/UserInterfaces/InsightWindow/Stylesheets/InsightWindow.qss"
)
);
if (!mainWindowUiFile.open(QFile::ReadOnly)) {
throw Exception("Failed to open InsightWindow UI file");
@@ -40,7 +49,11 @@ void InsightWindow::init(
this->mainWindowWidget = uiLoader.load(&mainWindowUiFile);
this->mainWindowWidget->setStyleSheet(mainWindowStylesheet.readAll());
application.setWindowIcon(QIcon(":/compiled/Insight/UserInterfaces/InsightWindow/Images/BloomIcon.svg"));
application.setWindowIcon(QIcon(
QString::fromStdString(Paths::compiledResourcesPath()
+ "/src/Insight/UserInterfaces/InsightWindow/Images/BloomIcon.svg"
)
));
this->ioContainerWidget = this->mainWindowWidget->findChild<QWidget*>("io-container");
this->ioUnavailableWidget = this->mainWindowWidget->findChild<QLabel*>("io-inspection-unavailable");
this->mainMenuBar = this->mainWindowWidget->findChild<QMenuBar*>("menu-bar");

View File

@@ -13,7 +13,7 @@ QMainWindow {
min-width: 150px;
max-height: 150px;
max-width: 150px;
image: url(":/compiled/Insight/UserInterfaces/InsightWindow/Images/BloomIcon.svg");
image: url(":/compiled/src/Insight/UserInterfaces/InsightWindow/Images/BloomIcon.svg");
image-position: center;
}

View File

@@ -88,7 +88,7 @@ QMenu#help-menu::separator {
height: 25px;
color: #000;
border: none;
qproperty-icon: url(":/compiled/Insight/UserInterfaces/InsightWindow/Images/RAM.svg");
qproperty-icon: url(":/compiled/src/Insight/UserInterfaces/InsightWindow/Images/RAM.svg");
icon-size: 25px;
}

View File

@@ -9,6 +9,7 @@
#include "DualInlinePackageWidget.hpp"
#include "src/Logger/Logger.hpp"
#include "src/Exceptions/Exception.hpp"
#include "src/Helpers/Paths.hpp"
#include "PinWidget.hpp"
#include "BodyWidget.hpp"
@@ -22,7 +23,11 @@ DualInlinePackageWidget::DualInlinePackageWidget(
QObject* insightWindowObj,
QWidget* parent
): TargetPackageWidget(targetVariant, insightWindowObj, parent) {
auto stylesheetFile = QFile(":/compiled/Insight/UserInterfaces/InsightWindow/TargetWidgets/DIP/Stylesheets/DualInlinePackage.qss");
auto stylesheetFile = QFile(QString::fromStdString(
Paths::compiledResourcesPath()
+ "/src/Insight/UserInterfaces/InsightWindow/TargetWidgets/DIP/Stylesheets/DualInlinePackage.qss"
)
);
stylesheetFile.open(QFile::ReadOnly);
this->setStyleSheet(stylesheetFile.readAll());
@@ -121,4 +126,3 @@ void DualInlinePackageWidget::drawWidget(QPainter& painter) {
height
);
}

View File

@@ -7,6 +7,7 @@
#include "../../InsightWindow.hpp"
#include "QuadFlatPackageWidget.hpp"
#include "src/Helpers/Paths.hpp"
#include "PinWidget.hpp"
#include "BodyWidget.hpp"
@@ -20,7 +21,11 @@ QuadFlatPackageWidget::QuadFlatPackageWidget(
): TargetPackageWidget(targetVariant, insightWindowObj, parent) {
assert((targetVariant.pinDescriptorsByNumber.size() % 4) == 0);
auto stylesheetFile = QFile(":/compiled/Insight/UserInterfaces/InsightWindow/TargetWidgets/QFP/Stylesheets/QuadFlatPackage.qss");
auto stylesheetFile = QFile(QString::fromStdString(
Paths::compiledResourcesPath()
+ "/src/Insight/UserInterfaces/InsightWindow/TargetWidgets//QFP/Stylesheets/QuadFlatPackage.qss"
)
);
stylesheetFile.open(QFile::ReadOnly);
this->setStyleSheet(stylesheetFile.readAll());

View File

@@ -62,8 +62,8 @@
<widget class="QToolButton" name="refresh-io-inspection-btn">
<property name="icon">
<iconset>
<disabledoff>:/compiled/Insight/UserInterfaces/InsightWindow/Images/refresh-disabled.svg</disabledoff>
<normalon>:/compiled/Insight/UserInterfaces/InsightWindow/Images/refresh.svg</normalon>
<disabledoff>:/compiled/src/Insight/UserInterfaces/InsightWindow/Images/refresh-disabled.svg</disabledoff>
<normalon>:/compiled/src/Insight/UserInterfaces/InsightWindow/Images/refresh.svg</normalon>
</iconset>
</property>
<property name="toolTip">

View File

@@ -7,6 +7,7 @@
#include "src/Exceptions/TargetControllerStartupFailure.hpp"
#include "src/Exceptions/DeviceCommunicationFailure.hpp"
#include "src/Application.hpp"
#include "src/Helpers/Paths.hpp"
using namespace Bloom;
using namespace Bloom::Targets;
@@ -87,7 +88,7 @@ void TargetController::startup() {
void TargetController::checkUdevRules() {
auto bloomRulesPath = std::string("/etc/udev/rules.d/99-bloom.rules");
auto latestBloomRulesPath = Application::getResourcesDirPath() + "/UDevRules/99-bloom.rules";
auto latestBloomRulesPath = Paths::resourcesDirPath() + "/UDevRules/99-bloom.rules";
if (!std::filesystem::exists(bloomRulesPath)) {
Logger::warning("Bloom udev rules missing - attempting installation");

View File

@@ -1,7 +1,10 @@
#include <QJsonDocument>
#include <QJsonArray>
#include "PartDescriptionFile.hpp"
#include "src/Targets/Microchip/AVR/Exceptions/PartDescriptionParsingFailureException.hpp"
#include "src/Logger/Logger.hpp"
#include "src/Application.hpp"
#include "src/Helpers/Paths.hpp"
using namespace Bloom::Targets::Microchip::Avr::Avr8Bit::PartDescription;
using namespace Bloom::Targets::Microchip::Avr::Avr8Bit;
@@ -35,7 +38,7 @@ PartDescriptionFile::PartDescriptionFile(const std::string& targetSignatureHex,
if (matchingDescriptionFiles.size() == 1) {
// Attempt to load the XML part description file
auto descriptionFilePath = QString::fromStdString(Application::getApplicationDirPath()) + "/"
auto descriptionFilePath = QString::fromStdString(Paths::applicationDirPath()) + "/"
+ matchingDescriptionFiles.front().toObject().find("targetDescriptionFilePath")->toString();
Logger::debug("Loading AVR8 part description file: " + descriptionFilePath.toStdString());
@@ -102,7 +105,7 @@ void PartDescriptionFile::init(const QDomDocument& xml) {
QJsonObject PartDescriptionFile::getPartDescriptionMapping() {
auto mappingFile = QFile(
QString::fromStdString(Application::getResourcesDirPath() + "/TargetPartDescriptions/AVR/Mapping.json")
QString::fromStdString(Paths::resourcesDirPath() + "/TargetPartDescriptions/AVR/Mapping.json")
);
if (!mappingFile.exists()) {

View File

@@ -1,6 +1,15 @@
<!DOCTYPE RCC>
<RCC version="1.0">
<qresource>
<!--
CAUTION: For aliases, please be sure to use the path of the file, relative to the Bloom project dir, but prefixed
with "/compiled/". See below for examples.
This is required because Bloom does not use compiled resources for debug builds. Instead, it will use the files
located in the Bloom project directory. See comment for BLOOM_COMPILED_RESOURCES_PATH_OVERRIDE macro
in CMakeLists.txt for more.
-->
<!-- The contents of help.txt is presented to the user in response to the invocation of the help command-->
<file alias="/compiled/resources/help.txt">../resources/help.txt</file>
@@ -8,19 +17,19 @@
<file alias="/compiled/resources/bloom.template.json">../resources/bloom.template.json</file>
<!-- QT UI templates for Insight-->
<file alias="/compiled/Insight/UserInterfaces/InsightWindow/UiFiles/InsightWindow.ui">./Insight/UserInterfaces/InsightWindow/UiFiles/InsightWindow.ui</file>
<file alias="/compiled/Insight/UserInterfaces/InsightWindow/UiFiles/AboutWindow.ui">./Insight/UserInterfaces/InsightWindow/UiFiles/AboutWindow.ui</file>
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/UiFiles/InsightWindow.ui">./Insight/UserInterfaces/InsightWindow/UiFiles/InsightWindow.ui</file>
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/UiFiles/AboutWindow.ui">./Insight/UserInterfaces/InsightWindow/UiFiles/AboutWindow.ui</file>
<!-- QT UI stylesheets for Insight-->
<file alias="/compiled/Insight/UserInterfaces/InsightWindow/Stylesheets/InsightWindow.qss">./Insight/UserInterfaces/InsightWindow/Stylesheets/InsightWindow.qss</file>
<file alias="/compiled/Insight/UserInterfaces/InsightWindow/Stylesheets/AboutWindow.qss">./Insight/UserInterfaces/InsightWindow/Stylesheets/AboutWindow.qss</file>
<file alias="/compiled/Insight/UserInterfaces/InsightWindow/TargetWidgets/DIP/Stylesheets/DualInlinePackage.qss">./Insight/UserInterfaces/InsightWindow/TargetWidgets/DIP/Stylesheets/DualInlinePackage.qss</file>
<file alias="/compiled/Insight/UserInterfaces/InsightWindow/TargetWidgets/QFP/Stylesheets/QuadFlatPackage.qss">./Insight/UserInterfaces/InsightWindow/TargetWidgets/QFP/Stylesheets/QuadFlatPackage.qss</file>
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/Stylesheets/InsightWindow.qss">./Insight/UserInterfaces/InsightWindow/Stylesheets/InsightWindow.qss</file>
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/Stylesheets/AboutWindow.qss">./Insight/UserInterfaces/InsightWindow/Stylesheets/AboutWindow.qss</file>
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/TargetWidgets/DIP/Stylesheets/DualInlinePackage.qss">./Insight/UserInterfaces/InsightWindow/TargetWidgets/DIP/Stylesheets/DualInlinePackage.qss</file>
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/TargetWidgets/QFP/Stylesheets/QuadFlatPackage.qss">./Insight/UserInterfaces/InsightWindow/TargetWidgets/QFP/Stylesheets/QuadFlatPackage.qss</file>
<!-- Icons for Insight-->
<file alias="/compiled/Insight/UserInterfaces/InsightWindow/Images/BloomIcon.svg">./Insight/UserInterfaces/InsightWindow/Images/BloomIcon.svg</file>
<file alias="/compiled/Insight/UserInterfaces/InsightWindow/Images/RAM.svg">./Insight/UserInterfaces/InsightWindow/Images/RAM.svg</file>
<file alias="/compiled/Insight/UserInterfaces/InsightWindow/Images/refresh.svg">./Insight/UserInterfaces/InsightWindow/Images/refresh.svg</file>
<file alias="/compiled/Insight/UserInterfaces/InsightWindow/Images/refresh-disabled.svg">./Insight/UserInterfaces/InsightWindow/Images/refresh-disabled.svg</file>
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/Images/BloomIcon.svg">./Insight/UserInterfaces/InsightWindow/Images/BloomIcon.svg</file>
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/Images/RAM.svg">./Insight/UserInterfaces/InsightWindow/Images/RAM.svg</file>
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/Images/refresh.svg">./Insight/UserInterfaces/InsightWindow/Images/refresh.svg</file>
<file alias="/compiled/src/Insight/UserInterfaces/InsightWindow/Images/refresh-disabled.svg">./Insight/UserInterfaces/InsightWindow/Images/refresh-disabled.svg</file>
</qresource>
</RCC>