Apollo 10.0
自动驾驶开放平台
plugin_manager.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2023 The Apollo Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *****************************************************************************/
16
18
19#include <dirent.h>
20#include <unistd.h>
21
22#include <memory>
23#include <regex>
24#include <string>
25#include <utility>
26#include <vector>
27
28#include <tinyxml2.h>
29
31#include "cyber/common/file.h"
32#include "cyber/common/log.h"
34
35namespace apollo {
36namespace cyber {
37namespace plugin_manager {
38
40
41bool PluginManager::ProcessPluginDescriptionFile(const std::string& file_path,
42 std::string* library_path) {
43 tinyxml2::XMLDocument doc;
44 if (doc.LoadFile(file_path.c_str()) != tinyxml2::XML_SUCCESS) {
45 AWARN << "fail to process file " << file_path;
46 return false;
47 }
48 const tinyxml2::XMLElement* root = doc.RootElement();
49
50 // TODO(liangjinping): parse as struct
51 *library_path = root->Attribute("path");
52
53 // TODO(liangjinping): parse description file and do something more
54
55 return true;
56}
57
59 const std::string& plugin_description_file_path) {
60 AINFO << "loading plugin from description[" << plugin_description_file_path
61 << "]";
62
63 auto description =
64 std::make_shared<apollo::cyber::plugin_manager::PluginDescription>();
65 if (!description->ParseFromDescriptionFile(plugin_description_file_path)) {
66 return false;
67 }
68
69 if (plugin_description_map_.find(description->name_) !=
70 plugin_description_map_.end()) {
71 AWARN << "plugin [" << description->name_ << "] already loaded";
72 return true;
73 }
74
75 if (!LoadLibrary(description->actual_library_path_)) {
76 AWARN << "plugin description[" << plugin_description_file_path << "] name["
77 << description->name_ << "] load failed, library["
78 << description->actual_library_path_ << "] invalid";
79 return false;
80 }
81
82 plugin_loaded_map_[description->name_] = true;
83 plugin_description_map_[description->name_] = description;
84 for (auto& class_name_pair : description->class_name_base_class_name_map_) {
85 plugin_class_plugin_name_map_[class_name_pair] = description->name_;
86 }
87 AINFO << "plugin description[" << plugin_description_file_path << "] name["
88 << description->name_ << "] load success";
89 return true;
90}
91
98bool FindPlunginIndexPath(const std::string& base_path,
99 std::vector<std::string>* path_list) {
100 // TODO(liangjinping): change to configurable
102 base_path, "cyber_plugin_index", DT_DIR, true, path_list);
103 return count > 0;
104}
105
107 const std::string& plugin_index_path) {
108 std::vector<std::string> plugin_index_list;
109 apollo::cyber::common::FindPathByPattern(plugin_index_path, "", DT_REG, false,
110 &plugin_index_list);
111 bool success = true;
112 for (auto plugin_index : plugin_index_list) {
113 std::string plugin_name = apollo::cyber::common::GetFileName(plugin_index);
114 AINFO << "plugin index[" << plugin_index << "] name[" << plugin_name
115 << "] found";
116 if (plugin_description_map_.find(plugin_name) !=
117 plugin_description_map_.end()) {
118 AWARN << "plugin [" << plugin_name << "] already loaded";
119 continue;
120 }
121
122 auto description = std::make_shared<PluginDescription>(plugin_name);
123 if (!description->ParseFromIndexFile(plugin_index)) {
124 success = false;
125 // invalid index file
126 continue;
127 }
128
129 // if (!class_loader_manager_.LoadLibrary(actual_library_path)) {
130 // success = false;
131 // AWARN << "plugin index[" << plugin_index << "] name[" << plugin_name
132 // << "] load failed, library[" << actual_library_path << "]
133 // invalid";
134 // continue;
135 // }
136 // lazy load
137 plugin_loaded_map_[description->name_] = false;
138 plugin_description_map_[description->name_] = description;
139 for (auto& class_name_pair : description->class_name_base_class_name_map_) {
140 plugin_class_plugin_name_map_[class_name_pair] = description->name_;
141 }
142 AINFO << "plugin index[" << plugin_index << "] name[" << description->name_
143 << "] lazy load success";
144 }
145 return success;
146}
147
149 if (apollo::cyber::common::GetEnv("APOLLO_PLUGIN_SEARCH_IN_BAZEL_OUTPUT") ==
150 "1") {
151 AWARN << "search plugin index path under bazel-bin enabled, it may take "
152 "longer time to load plugins";
153 // enable scanning cyber_plugin_index path under bazel-bin
154 const std::string apollo_root =
155 apollo::cyber::common::GetEnv("APOLLO_ROOT_DIR");
156 // TODO(infra): make it configurable or detect automatically
157 const std::string bazel_bin_path = apollo_root + "/bazel-bin";
158 std::vector<std::string> user_plugin_index_path_list;
159 AINFO << "scanning plugin index path under " << bazel_bin_path;
160 FindPlunginIndexPath(bazel_bin_path, &user_plugin_index_path_list);
161 // load user plugin with higher priority
162 for (auto dir : user_plugin_index_path_list) {
163 AINFO << "loading user plugins from path[" << dir << "]";
165 }
166 }
167
168 std::string plugin_index_path =
169 apollo::cyber::common::GetEnv("APOLLO_PLUGIN_INDEX_PATH");
170 if (plugin_index_path.empty()) {
171 // env not set, use default
172 const std::string apollo_distribution_home =
173 apollo::cyber::common::GetEnv("APOLLO_DISTRIBUTION_HOME");
174 const std::string plugin_index_path =
175 apollo_distribution_home + "/share/cyber_plugin_index";
176 }
177 AINFO << "loading plugins from APOLLO_PLUGIN_INDEX_PATH[" << plugin_index_path
178 << "]";
179 size_t begin = 0;
180 size_t index;
181 do {
182 index = plugin_index_path.find(':', begin);
183 auto p = plugin_index_path.substr(begin, index - begin);
185 AINFO << "loading plugins from plugin index path[" << p << "]";
187 } else {
188 AWARN << "plugin index path[" << p << "] not exists";
189 }
190 begin = index + 1;
191 } while (index != std::string::npos);
192 return true;
193}
194
195bool PluginManager::LoadLibrary(const std::string& library_path) {
196 if (!class_loader_manager_.LoadLibrary(library_path)) {
197 AWARN << "plugin library[" << library_path << "] load failed";
198 return false;
199 }
200 return true;
201}
202
204
205PluginManager* PluginManager::instance_ = new PluginManager;
206
207} // namespace plugin_manager
208} // namespace cyber
209} // namespace apollo
bool LoadLibrary(const std::string &library_path)
static PluginManager * Instance()
get singleton instance of PluginManager
bool LoadInstalledPlugins()
load plugins from installed path
bool LoadPlugin(const std::string &plugin_description_file_path)
load plugin clases from file
bool LoadLibrary(const std::string &library_path)
load library of plugin
bool FindPluginIndexAndLoad(const std::string &plugin_index_path)
find plugin index file and load plugins
bool ProcessPluginDescriptionFile(const std::string &file_path, std::string *library_path)
parse plugin description file and load the library TODO(liangjinping): parse description to struct
#define AINFO
Definition log.h:42
#define AWARN
Definition log.h:43
size_t FindPathByPattern(const std::string &base_path, const std::string &patt, const unsigned char d_type, const bool recursive, std::vector< std::string > *result_list)
Find path with pattern
Definition file.cc:374
std::string GetFileName(const std::string &path, const bool remove_extension)
Definition file.cc:415
std::string GetEnv(const std::string &var_name, const std::string &default_value="")
Definition environment.h:29
bool DirectoryExists(const std::string &directory_path)
Check if the directory specified by directory_path exists and is indeed a directory.
Definition file.cc:207
bool FindPlunginIndexPath(const std::string &base_path, std::vector< std::string > *path_list)
find cyber_plugin_index directory
class register implement
Definition arena_queue.h:37