OSVR Framework (Internal Development Docs)  0.6-1962-g59773924
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
SearchPath.cpp
Go to the documentation of this file.
1 
11 // Copyright 2015 Sensics, Inc.
12 //
13 // Licensed under the Apache License, Version 2.0 (the "License");
14 // you may not use this file except in compliance with the License.
15 // You may obtain a copy of the License at
16 //
17 // http://www.apache.org/licenses/LICENSE-2.0
18 //
19 // Unless required by applicable law or agreed to in writing, software
20 // distributed under the License is distributed on an "AS IS" BASIS,
21 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 // See the License for the specific language governing permissions and
23 // limitations under the License.
24 
25 // Internal Includes
29 #include <osvr/Util/Verbosity.h>
30 
31 // Library/third-party includes
32 #include <boost/filesystem.hpp>
33 #include <boost/range/iterator_range.hpp>
34 
35 // Standard includes
36 #include <vector>
37 #include <string>
38 #include <algorithm>
39 
40 namespace osvr {
41 namespace pluginhost {
42 
43  using boost::filesystem::directory_iterator;
44  using boost::make_iterator_range;
45  namespace fs = boost::filesystem;
46 
47  SearchPath getPluginSearchPath() {
48  auto exeLocation = fs::path{util::getBinaryLocation()};
49 #ifdef __ANDROID__
50  OSVR_DEV_VERBOSE("Binary location: " << exeLocation);
51 #endif
52  // Should be something like PREFIX/bin or PREFIX/bin/Release (depending
53  // on if we're installed or in a build tree)
54  auto binDir = exeLocation.parent_path();
55 
56 #if defined(_MSC_VER) && defined(CMAKE_INTDIR)
57  if (binDir.filename() == CMAKE_INTDIR) {
63  binDir = binDir.parent_path();
64  }
65 #endif
66 
67  // binDir now normalized to PREFIX/bin
68 
70  SearchPath paths;
71 
72  // Lambda to add a path, if it's not already in the list.
73  auto addUniquePath = [&paths](fs::path const &path) {
74  // OSVR_DEV_VERBOSE("Adding search path " << path);
75  auto pathString = path.generic_string();
76  if (std::find(begin(paths), end(paths), pathString) == end(paths)) {
77  // if we didn't already add this path, add it now.
78  paths.emplace_back(std::move(pathString));
79  }
80  };
81 
82 #ifdef OSVR_PLUGINS_UNDER_BINDIR
83  // If the plugin directory is a subdirectory of where the binaries are,
84  // no need to go up a level before searching.
85  addUniquePath(binDir / OSVR_PLUGIN_SUBDIR);
86 #endif
87 
88  // For each component of the compiled-in binary directory, we lop off a
89  // component from the binary location we've detected, and add it to the
90  // list of possible roots.
91  auto root = binDir.parent_path();
92  std::vector<fs::path> rootDirCandidates;
93  {
94  auto compiledBinDir = fs::path{OSVR_BINDIR};
95  do {
96  rootDirCandidates.push_back(root);
97  root = root.parent_path();
98  compiledBinDir = compiledBinDir.parent_path();
99  } while (!compiledBinDir.empty() && !root.empty());
100  }
101 
102 #ifdef __ANDROID__
103  // current working directory, if different from root
104  auto currentWorkingDirectory = boost::filesystem::current_path();
105  if (currentWorkingDirectory != root) {
106  addUniquePath(currentWorkingDirectory / OSVR_PLUGIN_DIR);
107  }
108 
109 #endif
110 
111  for (auto const &possibleRoot : rootDirCandidates) {
112 
113 #if defined(_MSC_VER) && defined(CMAKE_INTDIR)
114  addUniquePath(possibleRoot / OSVR_PLUGIN_DIR / CMAKE_INTDIR);
115 #endif
116  addUniquePath(possibleRoot / OSVR_PLUGIN_DIR);
117  }
118 
120 
121  return paths;
122  }
123 
124  FileList getAllFilesWithExt(SearchPath const &dirPath,
125  const std::string &ext) {
126  FileList filesPaths;
127 
128  for (const auto &path : dirPath) {
129  fs::path directoryPath(path);
130 
131  // Make sure that directory exists
132  if (!fs::exists(directoryPath)) {
133  continue;
134  }
135 
136  // Get a list of files inside the dir that match the extension
137  for (const auto &pathName : make_iterator_range(
138  directory_iterator(directoryPath), directory_iterator())) {
139  if (!fs::is_regular_file(pathName) ||
140  pathName.path().extension() != ext) {
141  continue;
142  }
143 
144  filesPaths.push_back(pathName.path().generic_string());
145  }
146  }
147 
148  return filesPaths;
149  }
150 
151  std::string findPlugin(SearchPath const &searchPaths,
152  const std::string &pluginName) {
153  for (const auto &searchPath : searchPaths) {
154  if (!fs::exists(searchPath)) {
155  continue;
156  }
157 
158  for (const auto &pluginPathName : make_iterator_range(
159  directory_iterator(searchPath), directory_iterator())) {
162  if (!fs::is_regular_file(pluginPathName)) {
163  continue;
164  }
165 
166  const auto pluginCandidate = fs::path(pluginPathName);
167 
169  if (pluginCandidate.extension().generic_string() !=
170  OSVR_PLUGIN_EXTENSION) {
171  continue;
172  }
173  const auto pluginBaseName =
174  pluginCandidate.filename().stem().generic_string();
177  if ((pluginBaseName == pluginName) ||
178  (pluginBaseName ==
179  pluginName + OSVR_PLUGIN_IGNORE_SUFFIX)) {
180  return pluginPathName.path().generic_string();
181  }
182  }
183  }
184 
185  return std::string();
186  }
187 
188 } // namespace pluginhost
189 } // namespace osvr
FileList getAllFilesWithExt(SearchPath const &dirPath, const std::string &ext)
Get list of files inside the directory with given extension.
Definition: SearchPath.cpp:124
SearchPath getPluginSearchPath()
Find a place where to look for plugins.
Definition: SearchPath.cpp:47
Header.
std::string getBinaryLocation()
Internal, configured header file for verbosity macros.
std::string findPlugin(SearchPath const &searchPaths, const std::string &pluginName)
Given the name of a plugin, find the full path to the plugin library.
Definition: SearchPath.cpp:151
Auto-generated configuration header - do not edit!