3 #include <wx/filename.h>
4 #include <wx/platinfo.h>
9 #include "model/base_platform.h"
11 #include "model/ocpn_utils.h"
12 #include "model/plugin_paths.h"
22 static std::vector<std::string> split(
const std::string& s,
char delimiter) {
23 std::vector<std::string> tokens;
25 std::istringstream tokenStream(s);
26 while (std::getline(tokenStream, token, delimiter)) {
27 tokens.push_back(token);
32 static std::string expand(
const std::string& s) {
35 return fn.GetFullPath().ToStdString();
46 void PluginPaths::initWindowsPaths() {
52 m_libdirs.push_back(m_userLibdir);
55 m_bindirs = m_libdirs;
58 m_datadirs.push_back(m_userDatadir);
62 const string platform_dir = g_BasePlatform->
GetPluginDir().ToStdString();
63 const string winPluginBaseDir =
65 m_userLibdir = winPluginBaseDir;
66 m_userBindir = winPluginBaseDir;
67 m_userDatadir = winPluginBaseDir;
69 m_libdirs.push_back(m_userLibdir);
70 m_libdirs.push_back(g_BasePlatform->
GetPluginDir().ToStdString());
71 m_bindirs = m_libdirs;
73 m_datadirs.push_back(platform_dir +
"\\plugins");
74 m_datadirs.push_back(winPluginBaseDir);
77 void PluginPaths::initFlatpackPaths() {
80 const string flathome = m_home +
"/.var/app/org.opencpn.OpenCPN";
81 m_userLibdir = flathome +
"/lib";
82 m_userBindir = flathome +
"/bin";
83 m_userDatadir = flathome +
"/data";
85 m_libdirs.push_back(flathome +
"/lib");
86 m_libdirs.push_back(
"/app/extensions/lib/opencpn");
87 m_libdirs.push_back(
"/app/lib/opencpn");
89 m_bindirs.push_back(flathome +
"/bin");
90 m_bindirs.push_back(
"/app/extensions/bin");
91 m_bindirs.push_back(
"/app/bin");
93 m_datadirs.push_back(flathome +
"/data/plugins");
94 m_datadirs.push_back(
"/app/extensions/share/opencpn/plugins");
95 m_datadirs.push_back(
"/app/share/opencpn/plugins");
98 void PluginPaths::initLinuxPaths() {
104 m_libdirs.push_back(m_userLibdir);
107 m_bindirs = m_libdirs;
110 m_datadirs.push_back(m_userDatadir);
114 m_userLibdir = m_home +
"/.local/lib";
115 m_userBindir = m_home +
"/.local/bin";
116 m_userDatadir = m_home +
"/.local/share";
118 std::vector<std::string> base_plugin_paths;
119 #if defined(__WXGTK__) || defined(__WXQT__)
120 char exe_buf[100] = {0};
121 ssize_t len = readlink(
"/proc/self/exe", exe_buf, 99);
124 wxFileName fn(exe_buf);
125 std::string path = fn.GetPath().ToStdString();
126 base_plugin_paths.push_back(expand(path +
"/../lib/opencpn"));
127 if(g_BasePlatform->GetOSDetail()->osd_arch.find(
"64") != string::npos) {
128 base_plugin_paths.push_back(expand(path +
"/../lib64/opencpn"));
130 base_plugin_paths.push_back(expand(path +
"/../lib32/opencpn"));
135 const char*
const envdirs = getenv(
"OPENCPN_PLUGIN_DIRS");
136 string dirlist = envdirs ? envdirs :
"~/.local/lib/opencpn";
137 m_libdirs = split(dirlist,
':');
138 for (
auto& dir : m_libdirs) {
141 for (
auto &base_plugin_path : base_plugin_paths) {
142 if (envdirs == 0 && dirlist.find(base_plugin_path) == string::npos) {
143 if(ocpn::exists(base_plugin_path)) {
144 m_libdirs.push_back(base_plugin_path);
148 m_bindirs = m_libdirs;
149 for (
auto& dir : m_bindirs) {
152 size_t pos = dir.rfind(
"/lib/opencpn");
153 if (pos == string::npos) {
154 pos = dir.rfind(
"/lib64/opencpn");
156 dir = pos == string::npos ? dir : dir.substr(0, pos) +
"/bin";
158 const char*
const xdg_data_dirs = getenv(
"XDG_DATA_DIRS");
159 dirlist = xdg_data_dirs ? xdg_data_dirs :
"~/.local/lib";
160 m_datadirs = split(dirlist,
':');
161 for (
auto& dir : m_datadirs) {
162 dir +=
"/opencpn/plugins";
164 for (
auto &base_plugin_path : base_plugin_paths) {
165 if (xdg_data_dirs == 0 && dirlist.find(base_plugin_path) == string::npos) {
166 m_datadirs.push_back(base_plugin_path +
"/plugins");
171 void PluginPaths::initApplePaths() {
174 const string mac_home = m_home +
"/Library/Application Support/OpenCPN";
175 m_userLibdir = mac_home +
"/Contents/PlugIns";
176 m_userBindir = m_userLibdir;
177 m_userDatadir = mac_home +
"/Contents";
179 m_libdirs.push_back(m_userLibdir);
180 wxFileName fn_exe(g_BasePlatform->GetExePath());
181 fn_exe.RemoveLastDir();
183 fn_exe.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR).ToStdString() +
185 m_libdirs.push_back(exeLibDir);
187 m_bindirs = m_libdirs;
189 m_datadirs.push_back(m_userDatadir);
190 m_datadirs.push_back(
"/Applications/OpenCPN.app/Contents/PlugIns");
193 void PluginPaths::initAndroidPaths() {
196 const string platform_dir = g_BasePlatform->
GetPluginDir().ToStdString();
199 platform_dir +
"/manPlug";
201 platform_dir +
"/manPlug";
207 m_libdirs.push_back(m_userLibdir);
208 m_libdirs.push_back(expand(platform_dir));
210 m_bindirs = m_libdirs;
213 PluginPaths::PluginPaths() {
216 wxString wxHome(
"unusable-$HOME");
217 wxGetEnv(
"HOME", &wxHome);
218 m_home = wxHome.ToStdString();
220 auto osSystemId = wxPlatformInfo::Get().GetOperatingSystemId();
221 if (osSystemId & wxOS_WINDOWS) {
223 }
else if (g_BasePlatform->isFlatpacked()) {
225 }
else if (osSystemId & wxOS_UNIX_LINUX) {
226 #ifdef __OCPN__ANDROID__
231 }
else if (osSystemId & wxOS_MAC) {
234 wxString os_name = wxPlatformInfo::Get().GetPortIdName();
235 wxLogMessage(_T(
"OS_NAME: ") + os_name);
236 if (os_name.Contains(_T(
"wxQT"))) {
239 wxLogWarning(
"PluginPaths: Unknown platform");
static PluginPaths * getInstance()
Return the singleton instance.
Global variables reflecting command line options and arguments.