Fix --binary with .cpp PLI filenames under relative directory paths.

This commit is contained in:
Wilson Snyder 2024-09-22 16:47:10 -04:00
parent b17619296a
commit d288488b7f
8 changed files with 145 additions and 1 deletions

View File

@ -59,6 +59,7 @@ Verilator 5.029 devel
* Fix class reference with pin that is a class reference (#5454).
* Fix tracing when name() is empty (#5470). [Sam Shahrestani]
* Fix timing mode not exiting on empty events (#5472).
* Fix --binary with .cpp PLI filenames under relative directory paths.
Verilator 5.028 2024-08-21

View File

@ -213,9 +213,12 @@ public:
const V3StringSet& cppFiles = v3Global.opt.cppFiles();
for (const auto& cppfile : cppFiles) {
of.puts("\t" + V3Os::filenameNonDirExt(cppfile) + " \\\n");
const string dir = V3Os::filenameDir(cppfile);
const string dir
= V3Os::filenameRelativePath(V3Os::filenameDir(cppfile), v3Global.opt.makeDir());
dirs.insert(dir);
}
dirs.insert(V3Os::filenameRelativePath(".", v3Global.opt.makeDir()));
of.puts("\n");
of.puts("# User .cpp directories (from .cpp's on Verilator command line)\n");

View File

@ -253,6 +253,55 @@ string V3Os::filenameRealPath(const string& filename) VL_PURE {
}
}
string V3Os::filenameRelativePath(const string& filename, const string& base) VL_PURE {
const string a = V3Os::filenameRealPath(filename);
const string b = V3Os::filenameRealPath(base);
string result;
if (a == b) return ".";
auto aIt = a.begin();
auto bIt = b.begin();
while (aIt != a.end() && bIt != b.end()) {
// UINFO(9, "fnrp scan " << (aIt - a.begin()) << " " << a.substr(aIt - a.begin()) << endl);
// UINFO(9, "fnrp scan " << (bIt - b.begin()) << " " << b.substr(bIt - b.begin()) << endl);
auto aWordIt = aIt; // position of next slash
for (; aWordIt != a.end(); ++aWordIt) {
if (isSlash(*aWordIt)) break;
}
auto bWordIt = bIt; // position of next slash
for (; bWordIt != b.end(); ++bWordIt) {
if (isSlash(*bWordIt)) break;
}
const string aWord = a.substr(aIt - a.begin(), aWordIt - aIt);
const string bWord = b.substr(bIt - b.begin(), bWordIt - bIt);
if (aWord != bWord) break;
aIt = aWordIt;
bIt = bWordIt;
if (aIt != a.end()) ++aIt; // Skip slash
if (bIt != b.end()) ++bIt; // Skip slash
}
while (bIt != b.end()) {
for (; bIt != b.end(); ++bIt) {
if (isSlash(*bIt)) {
++bIt;
break;
}
}
if (!result.empty()) result += "/";
result += "..";
}
const string aLeft = a.substr(aIt - a.begin());
if (!aLeft.empty()) {
if (!result.empty()) result += "/";
result += aLeft;
}
return filenameCleanup(result);
}
bool V3Os::filenameIsRel(const string& filename) VL_PURE {
#if defined(_MSC_VER)
return std::filesystem::path(filename).is_relative();
@ -452,5 +501,19 @@ void V3Os::selfTest() {
UASSERT_SELFTEST(string, filenameExt("a.a/b.b/f"), "");
UASSERT_SELFTEST(string, filenameExt("a.a/b.b/f.e"), ".e");
UASSERT_SELFTEST(string, filenameNonDirExt("a.a/b.b/f.e"), "f");
UASSERT_SELFTEST(string, filenameRelativePath("/a/b", "/a/b"), ".");
UASSERT_SELFTEST(string, filenameRelativePath("/a/b", "/a/b/c"), "..");
UASSERT_SELFTEST(string, filenameRelativePath("/a/b", "/a/b/c/d"), "../..");
UASSERT_SELFTEST(string, filenameRelativePath("/a/b/x", "/a/b/c/d"), "../../x");
UASSERT_SELFTEST(string, filenameRelativePath("/a/b/x/y", "/"), "a/b/x/y");
UASSERT_SELFTEST(string, filenameRelativePath("/a/b/x/y", "/a/b"), "x/y");
UASSERT_SELFTEST(string, filenameRelativePath("/a/b/x/y", "/a/q"), "../b/x/y");
UASSERT_SELFTEST(string, filenameRelativePath("a/b", "a/b"), ".");
UASSERT_SELFTEST(string, filenameRelativePath("a/b", "a/b/c"), "..");
UASSERT_SELFTEST(string, filenameRelativePath("a/b", "a/b/c/d"), "../..");
UASSERT_SELFTEST(string, filenameRelativePath("a/b/x", "a/b/c/d"), "../../x");
UASSERT_SELFTEST(string, filenameRelativePath("a/b/x/y", ""), "a/b/x/y");
UASSERT_SELFTEST(string, filenameRelativePath("a/b/x/y", "a/b"), "x/y");
UASSERT_SELFTEST(string, filenameRelativePath("a/b/x/y", "a/q"), "../b/x/y");
#endif
}

View File

@ -55,6 +55,8 @@ public:
static string filenameSubstitute(const string& filename);
///< @return realpath of filename
static string filenameRealPath(const string& filename) VL_PURE;
///< @return relative path of filename, relative to base
static string filenameRelativePath(const string& filename, const string& base) VL_PURE;
///< @return filename is relative
static bool filenameIsRel(const string& filename) VL_PURE;

19
test_regress/t/t_dpi_binary.py Executable file
View File

@ -0,0 +1,19 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2024 by Wilson Snyder. This program is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('simulator')
test.pli_filename = "t/t_dpi_binary_c.cpp"
test.compile(v_flags2=[test.pli_filename], verilator_flags2=['--binary'])
test.execute()
test.passes()

View File

@ -0,0 +1,19 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// Copyright 2009 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
module t ();
initial begin
// All Finished is in dpic_final
$finish;
end
import "DPI-C" context function void dpic_final();
final dpic_final();
endmodule

View File

@ -0,0 +1,25 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2009-2009 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
//
//*************************************************************************
#include "t_dpi_binary_c.h"
#include "svdpi.h"
#include <cstdio>
//======================================================================
extern "C" void dpic_final();
void dpic_final() {
printf("%s:\n", __func__);
printf("*-* All Finished *-*\n");
}

View File

@ -0,0 +1,12 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2009-2009 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
//
//*************************************************************************
// Empty file just to check that GCC finds it properly