Skip to content

Commit

Permalink
NewDevMod system (#5707)
Browse files Browse the repository at this point in the history
* New Devmod System (#5701)

* New dev module system (#5690)

* initial functional draft

* add ugly name thing for now

* fix some issues loading sepertly compiled modules on mac

* fix more mac specific issues

* add shortcuts for manual reload of devmodules , add safety copy to mac

---------

Co-authored-by: Rens <example>

* Update otoolstuff.cpp

* fix windows compile
  • Loading branch information
RensDofferhoff authored Oct 17, 2024
1 parent 9e8887d commit 2d47936
Show file tree
Hide file tree
Showing 16 changed files with 295 additions and 54 deletions.
58 changes: 34 additions & 24 deletions Engine/otoolstuff.cpp → Common/otoolstuff.cpp
Original file line number Diff line number Diff line change
@@ -1,29 +1,26 @@
#include "otoolstuff.h"
#include "stringutils.h"
#include "rbridge.h"
#include <fstream>
#include <boost/algorithm/string/predicate.hpp>
#include "utils.h"
#include "appinfo.h"
#include <iostream>
#include <filesystem>

std::string _system(std::string cmd)
{
const char *root, *relativePath;

if (!rbridge_requestTempFileName("log", &root, &relativePath))
auto path = std::filesystem::temp_directory_path() / "jaspTmpSystem";
std::ofstream ofs(path , std::ofstream::out);
if (!ofs.is_open())
throw std::runtime_error("Cannot open output file for separate R/System cmd!");

std::string path = std::string(root) + "/" + relativePath;

cmd += " > " + path + " 2>&1 ";
cmd += " > " + path.generic_string() + " 2>&1 ";

#ifdef WIN32
cmd = '"' + cmd + '"'; // See: https://stackoverflow.com/questions/2642551/windows-c-system-call-with-spaces-in-command
#endif

system(cmd.c_str());

ofs.close();
std::ifstream readLog(path);
std::stringstream out;

Expand All @@ -36,7 +33,7 @@ std::string _system(std::string cmd)
return out.str();
}

void _moduleLibraryFixer(const std::string & moduleLibraryPath, bool engineCall, bool printStuff)
void _moduleLibraryFixer(const std::string & moduleLibraryPath, bool engineCall, bool printStuff, bool devMod)
{
using namespace boost;

Expand Down Expand Up @@ -117,17 +114,27 @@ void _moduleLibraryFixer(const std::string & moduleLibraryPath, bool engineCall,
{"/opt/X11/lib", framework_resources + "opt/X11/lib"},
};

// Known fix library id's and paths
const std::map<std::string, std::string> ids_to_be_replaced =
{
{"libtbbmalloc.dylib", "@executable_path/../Modules/" + jaspModuleName + "/RcppParallel/lib/libtbbmalloc.dylib"},
{"libtbbmalloc_proxy.dylib", "@executable_path/../Modules/" + jaspModuleName + "/RcppParallel/lib/libtbbmalloc_proxy.dylib"},
{"libtbb.dylib", "@executable_path/../Modules/" + jaspModuleName + "/RcppParallel/lib/libtbb.dylib"}
// Known fix library id's and paths
std::map<std::string, std::string> ids_to_be_replaced;
if(devMod) {
ids_to_be_replaced = {
#ifndef __aarch64__
,{"libgfortran.dylib", framework_resources + "opt/local/gfortran/lib/libgfortran.dylib"}
,{"libquadmath.dylib", framework_resources + "opt/local/gfortran/lib/libquadmath.dylib"}
,{"libgfortran.dylib", framework_resources + "opt/local/gfortran/lib/libgfortran.dylib"}
,{"libquadmath.dylib", framework_resources + "opt/local/gfortran/lib/libquadmath.dylib"}
#endif
};
};
}
else {
ids_to_be_replaced = {
{"libtbbmalloc.dylib", "@executable_path/../Modules/" + jaspModuleName + "/RcppParallel/lib/libtbbmalloc.dylib"},
{"libtbbmalloc_proxy.dylib", "@executable_path/../Modules/" + jaspModuleName + "/RcppParallel/lib/libtbbmalloc_proxy.dylib"},
{"libtbb.dylib", "@executable_path/../Modules/" + jaspModuleName + "/RcppParallel/lib/libtbb.dylib"}
#ifndef __aarch64__
,{"libgfortran.dylib", framework_resources + "opt/local/gfortran/lib/libgfortran.dylib"}
,{"libquadmath.dylib", framework_resources + "opt/local/gfortran/lib/libquadmath.dylib"}
#endif
};
}

auto install_name_tool_cmd = [&](const std::string & replaceThisLine, const std::string & withThisLine)
{
Expand Down Expand Up @@ -188,13 +195,16 @@ void _moduleLibraryFixer(const std::string & moduleLibraryPath, bool engineCall,

}

std::cout << "Signing the modified library\n";
const std::string sign_command = "codesign --force --deep --verbose=4 --timestamp --sign \"" + AppInfo::getSigningIdentity() + "\" " + path.string();
if(!devMod)
{
std::cout << "Signing the modified library\n";
const std::string sign_command = "codesign --force --deep --verbose=4 --timestamp --sign \"" + AppInfo::getSigningIdentity() + "\" " + path.string();

if (printStuff)
std::cout << sign_command << std::endl;
if (printStuff)
std::cout << sign_command << std::endl;

_system(sign_command);
_system(sign_command);
}
}
}
catch(std::filesystem::filesystem_error & error)
Expand Down
2 changes: 1 addition & 1 deletion Engine/otoolstuff.h → Common/otoolstuff.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
/// Depends on otool being present and callable in the users system.

std::string _system( std::string cmd);
void _moduleLibraryFixer(const std::string & moduleLibrary, bool engineCall = false, bool printStuff = false);
void _moduleLibraryFixer(const std::string & moduleLibrary, bool engineCall = false, bool printStuff = false, bool devMod = false);

#endif // OTOOLSTUFF_H
10 changes: 8 additions & 2 deletions Desktop/analysis/analyses.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,8 +305,7 @@ void Analyses::removeAnalysesOfDynamicModule(Modules::DynamicModule * module)

void Analyses::refreshAnalysesOfDynamicModule(Modules::DynamicModule * module)
{
//Log::log() << "void Analyses::refreshAnalysesOfDynamicModule(" << module->toString() << ")" << std::endl;

Log::log() << "void Analyses::refreshAnalysesOfDynamicModule(" << module->toString() << ")" << std::endl;

for(auto & keyval : _analysisMap)
if(keyval.second->dynamicModule() == module)
Expand Down Expand Up @@ -352,6 +351,13 @@ void Analyses::rescanAnalysisEntriesOfDynamicModule(Modules::DynamicModule * mod
removeAnalysisById(size_t(id));
}

void Analyses::reloadQmlAnalysesDynamicModule(Modules::DynamicModule * module)
{
for(auto idAnalysis : _analysisMap)
if(idAnalysis.second->dynamicModule() == module)
idAnalysis.second->analysisQMLFileChanged();
}

void Analyses::refreshAllAnalyses()
{
for(auto idAnalysis : _analysisMap)
Expand Down
1 change: 1 addition & 0 deletions Desktop/analysis/analyses.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ public slots:
void refreshAnalysesOfDynamicModule(Modules::DynamicModule * module);
void replaceAnalysesOfDynamicModule(Modules::DynamicModule * oldModule, Modules::DynamicModule * newModule);
void rescanAnalysisEntriesOfDynamicModule(Modules::DynamicModule * module);
void reloadQmlAnalysesDynamicModule(Modules::DynamicModule * module);
void setChangedAnalysisTitle();
void analysisTitleChangedInResults(int id, QString title);
void setCurrentFormPrevH(double currentFormPrevH);
Expand Down
104 changes: 99 additions & 5 deletions Desktop/components/JASP/Widgets/FileMenu/PrefsAdvanced.qml
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,6 @@ ScrollView
KeyNavigation.tab: githubPatCustomToken
}




Item
{
id: githubPatCustomTokenItem
Expand Down Expand Up @@ -170,7 +167,7 @@ ScrollView
text: preferencesModel.githubPatCustom
onEditingFinished: preferencesModel.githubPatCustom = text

nextEl: generateMarkdown
nextEl: directLibpathDevModEnabled

height: browseDeveloperFolderButton.height
anchors
Expand All @@ -182,7 +179,7 @@ ScrollView

textInput.echoMode: TextInput.Password

KeyNavigation.tab: generateMarkdown
KeyNavigation.tab: directLibpathDevModEnabled
}
}

Expand All @@ -197,6 +194,103 @@ ScrollView
KeyNavigation.tab: cleanModulesFolder

}


CheckBox
{
id: directLibpathDevModEnabled
label: qsTr("Enable direct libpath mode")
checked: preferencesModel.directLibpathEnabled
onCheckedChanged: preferencesModel.directLibpathEnabled = checked
toolTip: qsTr("To use JASP Modules enable this option.")
visible: preferencesModel.developerMode

KeyNavigation.tab: directLibpathFolder
}

Item
{
id: directLibpath
enabled: preferencesModel.directLibpathEnabled
width: parent.width
height: cranRepoUrl.height
visible: preferencesModel.developerMode && preferencesModel.directLibpathEnabled

Label
{
id: directLibPathLabel
text: qsTr("DevModule libpath:")

anchors
{
left: parent.left
verticalCenter: parent.verticalCenter
leftMargin: jaspTheme.subOptionOffset
}
}

PrefsTextInput
{
id: directLibpathFolder

text: preferencesModel.directLibpathFolder
onEditingFinished: preferencesModel.directLibpathFolder = text

nextEl: moduleName

height: browseDeveloperFolderButton.height
anchors
{
left: directLibPathLabel.right
right: parent.right
margins: jaspTheme.generalAnchorMargin
}

KeyNavigation.tab: moduleName
}
}

Item {

id: directDevMod
enabled: preferencesModel.directLibpathEnabled
width: parent.width
height: cranRepoUrl.height
visible: preferencesModel.developerMode && preferencesModel.directLibpathEnabled

Label
{
id: directDevModName
text: qsTr("Developer module name:")

anchors
{
left: parent.left
verticalCenter: parent.verticalCenter
leftMargin: jaspTheme.subOptionOffset
}
}

PrefsTextInput
{
id: moduleName

text: preferencesModel.directDevModName
onEditingFinished: preferencesModel.directDevModName = text

nextEl: cleanModulesFolder

height: browseDeveloperFolderButton.height
anchors
{
left: directDevModName.right
right: parent.right
margins: jaspTheme.generalAnchorMargin
}

KeyNavigation.tab: cleanModulesFolder
}
}

RoundedButton
{
Expand Down
4 changes: 4 additions & 0 deletions Desktop/components/JASP/Widgets/MainWindow.qml
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ Window
Shortcut { onActivated: mainWindow.undo(); sequences: ["Ctrl+Z", Qt.Key_Undo]; context: Qt.ApplicationShortcut; }
Shortcut { onActivated: mainWindow.redo(); sequences: ["Ctrl+Shift+Z", "Ctrl-Y", Qt.Key_Redo]; context: Qt.ApplicationShortcut; }

Shortcut { onActivated: { dynamicModules.refreshDeveloperModule(false, true);} sequences: ["Ctrl+Shift+U"]; context: Qt.ApplicationShortcut; }
Shortcut { onActivated: { dynamicModules.refreshDeveloperModule(true, false);} sequences: ["Ctrl+Shift+R"]; context: Qt.ApplicationShortcut; }
Shortcut { onActivated: { dynamicModules.refreshDeveloperModule(true, true);} sequences: ["Ctrl+Shift+D"]; context: Qt.ApplicationShortcut; }


RibbonBar
{
Expand Down
21 changes: 19 additions & 2 deletions Desktop/components/JASP/Widgets/ModulesMenu.qml
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ FocusScope
focus: currentIndex === -1
activeFocusOnTab: false

readonly property bool folderSelected: preferencesModel.developerFolder != ""
readonly property bool folderSelected: preferencesModel.developerFolder != "" || (preferencesModel.directLibpathEnabled && preferencesModel.directLibpathFolder != "")
}

QTC.ToolSeparator
Expand Down Expand Up @@ -265,11 +265,28 @@ FocusScope
anchors
{
left : parent.left
right : minusButton.left
right : refreshButton.left
verticalCenter : parent.verticalCenter
}
}


MenuButton
{
z: 1
id: refreshButton
visible: !isBundled && !isSpecial
iconSource: jaspTheme.iconPath + "/redo.svg"
width: visible ? height : 0
onClicked: dynamicModules.refreshDeveloperModule();
toolTip: qsTr("Refresh developer module ") + displayText
anchors
{
right : minusButton.left
verticalCenter : parent.verticalCenter
}
}

MenuButton
{
z: 1
Expand Down
16 changes: 16 additions & 0 deletions Desktop/gui/preferencesmodel.cpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@ GET_PREF_FUNC_BOOL( checkUpdates, Settings::CHECK_UPDATES )
GET_PREF_FUNC_INT( maxScaleLevels, Settings::MAX_SCALE_LEVELS )
GET_PREF_FUNC_BOOL( pdfLandscape, Settings::PDF_LANDSCAPE )
GET_PREF_FUNC_INT( pdfPageSize, Settings::PDF_PAGESIZE )
GET_PREF_FUNC_BOOL( directLibpathEnabled, Settings::DIRECT_LIBPATH_ENABLED )
GET_PREF_FUNC_STR( directLibpathFolder, Settings::DIRECT_LIBPATH_FOLDER )
GET_PREF_FUNC_STR( directDevModName, Settings::DIRECT_DEVMOD_NAME )


int PreferencesModel::maxEngines() const
{
Expand Down Expand Up @@ -314,6 +318,9 @@ SET_PREF_FUNCTION( bool, setCheckUpdates, checkUpdates, checkUpdatesCha
SET_PREF_FUNCTION( int, setMaxScaleLevels, maxScaleLevels, maxScaleLevelsChanged, Settings::MAX_SCALE_LEVELS )
SET_PREF_FUNCTION( bool, setPdfLandscape, pdfLandscape, pdfLandscapeChanged, Settings::PDF_LANDSCAPE )
SET_PREF_FUNCTION( int, setPdfPageSize, pdfPageSize, pdfPageSizeChanged, Settings::PDF_PAGESIZE )
SET_PREF_FUNCTION( bool, setDirectLibpathEnabled, directLibpathEnabled, directLibpathEnabledChanged, Settings::DIRECT_LIBPATH_ENABLED )
SET_PREF_FUNCTION( QString, setDirectDevModName, directDevModName, directDevModNameChanged, Settings::DIRECT_DEVMOD_NAME )


void PreferencesModel::setGithubPatCustom(QString newPat)
{
Expand Down Expand Up @@ -551,3 +558,12 @@ QStringList PreferencesModel::_splitValues(const QString &values) const
return QStringList(orderedValues.begin(), orderedValues.end());

}

void PreferencesModel::setDirectLibpathFolder(QString libpath)
{
if (libpath != "")
{
Settings::setValue(Settings::DIRECT_LIBPATH_FOLDER, libpath);
emit directLibpathFolderChanged();
}
}
Loading

0 comments on commit 2d47936

Please sign in to comment.