2 * yosys -- Yosys Open SYnthesis Suite
4 * Copyright (C) 2014 Clifford Wolf <clifford@clifford.at>
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 #include "kernel/yosys.h"
22 #ifdef YOSYS_ENABLE_PLUGINS
27 # include <boost/algorithm/string/predicate.hpp>
29 # include <boost/filesystem.hpp>
34 std::map
<std::string
, void*> loaded_plugins
;
36 std::map
<std::string
, void*> loaded_python_plugins
;
38 std::map
<std::string
, std::string
> loaded_plugin_aliases
;
40 #ifdef YOSYS_ENABLE_PLUGINS
41 void load_plugin(std::string filename
, std::vector
<std::string
> aliases
)
43 std::string orig_filename
= filename
;
45 if (filename
.find('/') == std::string::npos
)
46 filename
= "./" + filename
;
49 if (!loaded_plugins
.count(filename
) && !loaded_python_plugins
.count(filename
)) {
51 if (!loaded_plugins
.count(filename
)) {
56 boost::filesystem::path
full_path(filename
);
58 if(strcmp(full_path
.extension().c_str(), ".py") == 0)
60 std::string
path(full_path
.parent_path().c_str());
61 filename
= full_path
.filename().c_str();
62 filename
= filename
.substr(0,filename
.size()-3);
63 PyRun_SimpleString(("sys.path.insert(0,\""+path
+"\")").c_str());
65 PyObject
*module_p
= PyImport_ImportModule(filename
.c_str());
69 log_cmd_error("Can't load python module `%s'\n", full_path
.filename().c_str());
72 loaded_python_plugins
[orig_filename
] = module_p
;
73 Pass::init_register();
77 void *hdl
= dlopen(filename
.c_str(), RTLD_LAZY
|RTLD_LOCAL
);
78 if (hdl
== NULL
&& orig_filename
.find('/') == std::string::npos
)
79 hdl
= dlopen((proc_share_dirname() + "plugins/" + orig_filename
+ ".so").c_str(), RTLD_LAZY
|RTLD_LOCAL
);
81 log_cmd_error("Can't load module `%s': %s\n", filename
.c_str(), dlerror());
82 loaded_plugins
[orig_filename
] = hdl
;
83 Pass::init_register();
90 for (auto &alias
: aliases
)
91 loaded_plugin_aliases
[alias
] = orig_filename
;
94 void load_plugin(std::string
, std::vector
<std::string
>)
96 log_error("This version of yosys is built without plugin support.\n");
100 struct PluginPass
: public Pass
{
101 PluginPass() : Pass("plugin", "load and list loaded plugins") { }
102 void help() YS_OVERRIDE
104 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
106 log(" plugin [options]\n");
108 log("Load and list loaded plugins.\n");
110 log(" -i <plugin_filename>\n");
111 log(" Load (install) the specified plugin.\n");
113 log(" -a <alias_name>\n");
114 log(" Register the specified alias name for the loaded plugin\n");
117 log(" List loaded plugins\n");
120 void execute(std::vector
<std::string
> args
, RTLIL::Design
*design
) YS_OVERRIDE
122 std::string plugin_filename
;
123 std::vector
<std::string
> plugin_aliases
;
124 bool list_mode
= false;
127 for (argidx
= 1; argidx
< args
.size(); argidx
++)
129 if ((args
[argidx
] == "-i") && argidx
+1 < args
.size() && plugin_filename
.empty()) {
130 plugin_filename
= args
[++argidx
];
133 if ((args
[argidx
] == "-a") && argidx
+1 < args
.size()) {
134 plugin_aliases
.push_back(args
[++argidx
]);
137 if (args
[argidx
] == "-l") {
143 extra_args(args
, argidx
, design
, false);
145 if (!plugin_filename
.empty())
146 load_plugin(plugin_filename
, plugin_aliases
);
152 if (loaded_plugins
.empty() and loaded_python_plugins
.empty())
154 if (loaded_plugins
.empty())
156 log("No plugins loaded.\n");
158 log("Loaded plugins:\n");
160 for (auto &it
: loaded_plugins
)
161 log(" %s\n", it
.first
.c_str());
164 for (auto &it
: loaded_python_plugins
)
165 log(" %s\n", it
.first
.c_str());
168 if (!loaded_plugin_aliases
.empty()) {
170 int max_alias_len
= 1;
171 for (auto &it
: loaded_plugin_aliases
)
172 max_alias_len
= max(max_alias_len
, GetSize(it
.first
));
173 for (auto &it
: loaded_plugin_aliases
)
174 log("Alias: %-*s %s\n", max_alias_len
, it
.first
.c_str(), it
.second
.c_str());