parent
278d532368
commit
47253450a4
|
|
@ -54,6 +54,7 @@ Jamie Iles
|
|||
Jan Van Winkel
|
||||
Jean Berniolles
|
||||
Jeremy Bennett
|
||||
Jiacheng Qian
|
||||
Jiuyang Liu
|
||||
John Coiner
|
||||
John Demme
|
||||
|
|
|
|||
|
|
@ -71,15 +71,6 @@ class CMakeEmitter final {
|
|||
cmake_set_raw(of, name, raw_value, cache_type, docstring);
|
||||
}
|
||||
|
||||
// Swap all backslashes for forward slashes, because of Windows
|
||||
static string deslash(const string& s) {
|
||||
std::string res = s;
|
||||
for (char& c : res) {
|
||||
if (c == '\\') c = '/';
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static void emitOverallCMake() {
|
||||
const std::unique_ptr<std::ofstream> of{
|
||||
V3File::new_ofstream(v3Global.opt.makeDir() + "/" + v3Global.opt.prefix() + ".cmake")};
|
||||
|
|
@ -95,9 +86,9 @@ class CMakeEmitter final {
|
|||
*of << "# which becomes available after executing `find_package(verilator).\n";
|
||||
|
||||
*of << "\n### Constants...\n";
|
||||
cmake_set(*of, "PERL", deslash(V3Options::getenvPERL()), "FILEPATH",
|
||||
cmake_set(*of, "PERL", V3Options::getenvPERL(), "FILEPATH",
|
||||
"Perl executable (from $PERL)");
|
||||
cmake_set(*of, "VERILATOR_ROOT", deslash(V3Options::getenvVERILATOR_ROOT()), "PATH",
|
||||
cmake_set(*of, "VERILATOR_ROOT", V3Options::getenvVERILATOR_ROOT(), "PATH",
|
||||
"Path to Verilator kit (from $VERILATOR_ROOT)");
|
||||
|
||||
*of << "\n### Compiler flags...\n";
|
||||
|
|
@ -186,22 +177,22 @@ class CMakeEmitter final {
|
|||
}
|
||||
|
||||
*of << "# Global classes, need linked once per executable\n";
|
||||
cmake_set_raw(*of, name + "_GLOBAL", deslash(cmake_list(global)));
|
||||
cmake_set_raw(*of, name + "_GLOBAL", cmake_list(global));
|
||||
*of << "# Generated module classes, non-fast-path, compile with low/medium optimization\n";
|
||||
cmake_set_raw(*of, name + "_CLASSES_SLOW", deslash(cmake_list(classes_slow)));
|
||||
cmake_set_raw(*of, name + "_CLASSES_SLOW", cmake_list(classes_slow));
|
||||
*of << "# Generated module classes, fast-path, compile with highest optimization\n";
|
||||
cmake_set_raw(*of, name + "_CLASSES_FAST", deslash(cmake_list(classes_fast)));
|
||||
cmake_set_raw(*of, name + "_CLASSES_FAST", cmake_list(classes_fast));
|
||||
*of << "# Generated support classes, non-fast-path, compile with "
|
||||
"low/medium optimization\n";
|
||||
cmake_set_raw(*of, name + "_SUPPORT_SLOW", deslash(cmake_list(support_slow)));
|
||||
cmake_set_raw(*of, name + "_SUPPORT_SLOW", cmake_list(support_slow));
|
||||
*of << "# Generated support classes, fast-path, compile with highest optimization\n";
|
||||
cmake_set_raw(*of, name + "_SUPPORT_FAST", deslash(cmake_list(support_fast)));
|
||||
cmake_set_raw(*of, name + "_SUPPORT_FAST", cmake_list(support_fast));
|
||||
|
||||
*of << "# All dependencies\n";
|
||||
cmake_set_raw(*of, name + "_DEPS", deslash(cmake_list(V3File::getAllDeps())));
|
||||
cmake_set_raw(*of, name + "_DEPS", cmake_list(V3File::getAllDeps()));
|
||||
|
||||
*of << "# User .cpp files (from .cpp's on Verilator command line)\n";
|
||||
cmake_set_raw(*of, name + "_USER_CLASSES", deslash(cmake_list(v3Global.opt.cppFiles())));
|
||||
cmake_set_raw(*of, name + "_USER_CLASSES", cmake_list(v3Global.opt.cppFiles()));
|
||||
if (const V3HierBlockPlan* const planp = v3Global.hierPlanp()) {
|
||||
*of << "# Verilate hierarchical blocks\n";
|
||||
// Sorted hierarchical blocks in order of leaf-first.
|
||||
|
|
@ -221,10 +212,10 @@ class CMakeEmitter final {
|
|||
}
|
||||
*of << "verilate(" << prefix << " PREFIX " << prefix << " TOP_MODULE "
|
||||
<< hblockp->modp()->name() << " DIRECTORY "
|
||||
<< deslash(v3Global.opt.makeDir() + "/" + prefix) << " SOURCES ";
|
||||
<< v3Global.opt.makeDir() + "/" + prefix << " SOURCES ";
|
||||
for (const auto& childr : children) {
|
||||
*of << " "
|
||||
<< deslash(v3Global.opt.makeDir() + "/" + childr->hierWrapper(true));
|
||||
<< v3Global.opt.makeDir() + "/" + childr->hierWrapper(true);
|
||||
}
|
||||
*of << " ";
|
||||
const string vFile = hblockp->vFileIfNecessary();
|
||||
|
|
@ -232,7 +223,7 @@ class CMakeEmitter final {
|
|||
const V3StringList& vFiles = v3Global.opt.vFiles();
|
||||
for (const string& i : vFiles) *of << V3Os::filenameRealPath(i) << " ";
|
||||
*of << " VERILATOR_ARGS ";
|
||||
*of << "-f " << deslash(hblockp->commandArgsFileName(true))
|
||||
*of << "-f " << hblockp->commandArgsFileName(true)
|
||||
<< " -CFLAGS -fPIC" // hierarchical block will be static, but may be linked
|
||||
// with .so
|
||||
<< ")\n";
|
||||
|
|
@ -240,14 +231,14 @@ class CMakeEmitter final {
|
|||
*of << "\n# Verilate the top module that refers to lib-create wrappers of above\n";
|
||||
*of << "verilate(${TOP_TARGET_NAME} PREFIX " << v3Global.opt.prefix() << " TOP_MODULE "
|
||||
<< v3Global.rootp()->topModulep()->name() << " DIRECTORY "
|
||||
<< deslash(v3Global.opt.makeDir()) << " SOURCES ";
|
||||
<< v3Global.opt.makeDir() << " SOURCES ";
|
||||
for (const auto& itr : *planp) {
|
||||
*of << " "
|
||||
<< deslash(v3Global.opt.makeDir() + "/" + itr.second->hierWrapper(true));
|
||||
<< v3Global.opt.makeDir() + "/" + itr.second->hierWrapper(true);
|
||||
}
|
||||
*of << " " << deslash(cmake_list(v3Global.opt.vFiles()));
|
||||
*of << " " << cmake_list(v3Global.opt.vFiles());
|
||||
*of << " VERILATOR_ARGS ";
|
||||
*of << "-f " << deslash(planp->topCommandArgsFileName(true));
|
||||
*of << "-f " << planp->topCommandArgsFileName(true);
|
||||
*of << ")\n";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
10
src/V3Os.cpp
10
src/V3Os.cpp
|
|
@ -76,6 +76,7 @@ VL_DEFINE_DEBUG_FUNCTIONS;
|
|||
// Environment
|
||||
|
||||
string V3Os::getenvStr(const string& envvar, const string& defaultValue) {
|
||||
string ret = "";
|
||||
#if defined(_MSC_VER)
|
||||
// Note: MinGW does not offer _dupenv_s
|
||||
const char* envvalue = nullptr;
|
||||
|
|
@ -83,17 +84,18 @@ string V3Os::getenvStr(const string& envvar, const string& defaultValue) {
|
|||
if (envvalue != nullptr) {
|
||||
const std::string result{envvalue};
|
||||
free(envvalue);
|
||||
return result;
|
||||
ret = result;
|
||||
} else {
|
||||
return defaultValue;
|
||||
ret = defaultValue;
|
||||
}
|
||||
#else
|
||||
if (const char* const envvalue = getenv(envvar.c_str())) {
|
||||
return envvalue;
|
||||
ret = envvalue;
|
||||
} else {
|
||||
return defaultValue;
|
||||
ret = defaultValue;
|
||||
}
|
||||
#endif
|
||||
return VString::escapeStringForPath(ret);
|
||||
}
|
||||
|
||||
void V3Os::setenvStr(const string& envvar, const string& value, const string& why) {
|
||||
|
|
|
|||
|
|
@ -116,6 +116,19 @@ string VString::quoteStringLiteralForShell(const string& str) {
|
|||
return result;
|
||||
}
|
||||
|
||||
string VString::escapeStringForPath(const string &str) {
|
||||
if (str.find(R"(\\)") != string::npos) return str; // if it has been escaped already, don't do it again
|
||||
if (str.find('/') != string::npos) return str; // can be replaced by `__MINGW32__` or `_WIN32`
|
||||
string result;
|
||||
const char space = ' '; // escape space like this `Program Files`
|
||||
const char escape = '\\';
|
||||
for (const char c: str) {
|
||||
if (c == space || c == escape) result.push_back(escape);
|
||||
result.push_back(c);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
string VString::spaceUnprintable(const string& str) {
|
||||
string out;
|
||||
for (const char c : str) {
|
||||
|
|
|
|||
|
|
@ -100,6 +100,9 @@ public:
|
|||
static string quotePercent(const string& str) { return quoteAny(str, '%', '%'); }
|
||||
// Surround a raw string by double quote and escape if necessary
|
||||
// e.g. input abc's becomes "\"abc\'s\""
|
||||
static string escapeStringForPath(const string& str);
|
||||
// Escape path in Windows
|
||||
// e.g. input `C:\Program Files\My Program\My Program.exe` becomes `C:\\Program\ Files\\My\ Program\\My\ Program.exe`
|
||||
static string quoteStringLiteralForShell(const string& str);
|
||||
// Replace any unprintable with space
|
||||
// This includes removing tabs, so column tracking is correct
|
||||
|
|
|
|||
|
|
@ -737,7 +737,7 @@ int main(int argc, char** argv, char** /*env*/) {
|
|||
V3PreShell::boot();
|
||||
|
||||
// Command option parsing
|
||||
v3Global.opt.buildDepBin(argv[0]);
|
||||
v3Global.opt.buildDepBin(VString::escapeStringForPath(argv[0]));
|
||||
const string argString = V3Options::argString(argc - 1, argv + 1);
|
||||
v3Global.opt.parseOpts(new FileLine{FileLine::commandLineFilename()}, argc - 1, argv + 1);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue