From 0adb78923813db97910ad433cec4dc35d56a6d2c Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Thu, 9 Feb 2017 18:33:18 -0500 Subject: [PATCH] Add --relative-includes. --- Changes | 2 ++ Makefile.in | 2 ++ bin/verilator | 7 +++++++ src/V3Options.cpp | 9 +++++++- src/V3Options.h | 3 ++- src/V3Os.cpp | 10 +++++++++ src/V3Os.h | 1 + src/V3PreShell.cpp | 9 ++++---- test_regress/t/t_flag_relinc.pl | 21 +++++++++++++++++++ test_regress/t/t_flag_relinc.v | 10 +++++++++ .../chip/t_flag_relinc_sub.v | 15 +++++++++++++ .../include/t_flag_relinc.vh | 8 +++++++ 12 files changed, 91 insertions(+), 6 deletions(-) create mode 100755 test_regress/t/t_flag_relinc.pl create mode 100644 test_regress/t/t_flag_relinc.v create mode 100644 test_regress/t/t_flag_relinc_dir/chip/t_flag_relinc_sub.v create mode 100644 test_regress/t/t_flag_relinc_dir/include/t_flag_relinc.vh diff --git a/Changes b/Changes index 77161b5a7..73634096c 100644 --- a/Changes +++ b/Changes @@ -7,6 +7,8 @@ The contributors that suggested a given feature are shown in []. Thanks! ** Add -FI option to force includes,msg2146. [Amir Gonnen] +** Add --relative-includes. [Rob Stoddard] + **** Fix 2009 localparam syntax, msg2139. [Galen Seitz] diff --git a/Makefile.in b/Makefile.in index 235862d9b..a7acd8afe 100644 --- a/Makefile.in +++ b/Makefile.in @@ -132,6 +132,8 @@ DISTFILES_INC = $(INFOS) .gitignore Artistic COPYING COPYING.LESSER \ test_verilated/vgen*.pl \ test_regress/t/t*/*.sv* \ test_regress/t/t*/*.v* \ + test_regress/t/t*/*/*.sv* \ + test_regress/t/t*/*/*.v* \ test_regress/t/*.cpp \ test_regress/t/*.h \ test_regress/t/*.dat \ diff --git a/bin/verilator b/bin/verilator index abe8359a0..64577b7ad 100755 --- a/bin/verilator +++ b/bin/verilator @@ -324,6 +324,7 @@ descriptions in the next sections for more information. --private Debugging; see docs --public Debugging; see docs -pvalue+= Overwrite toplevel parameter + --relative-includes Resolve includes relative to current file --report-unoptflat Extra diagnostics for UNOPTFLAT --savable Enable model save-restore --sc Create SystemC output @@ -1023,6 +1024,12 @@ inlining. This will also turn off inlining as if all modules had a Overwrites the given parameter(s) of the toplevel module. See -G for a detailed description. +=item --relative-includes + +When a file references an include file, resolve the filename relative to +the path of the referencing file, instead of relative to the current +directory. + =item --report-unoptflat Extra diagnostics for UNOPTFLAT warnings. This includes for each loop, the diff --git a/src/V3Options.cpp b/src/V3Options.cpp index eecc61b00..df8a4e48a 100644 --- a/src/V3Options.cpp +++ b/src/V3Options.cpp @@ -339,7 +339,7 @@ string V3Options::filePathCheckOneDir(const string& modname, const string& dirna return ""; } -string V3Options::filePath (FileLine* fl, const string& modname, +string V3Options::filePath (FileLine* fl, const string& modname, const string& lastpath, const string& errmsg) { // Error prefix or "" to suppress error // Find a filename to read the specified module name, // using the incdir and libext's. @@ -355,6 +355,11 @@ string V3Options::filePath (FileLine* fl, const string& modname, if (exists!="") return exists; } + if (m_relativeIncludes) { + string exists = filePathCheckOneDir(modname, lastpath); + if (exists!="") return V3Os::filenameRealPath(exists); + } + // Warn and return not found if (errmsg != "") { fl->v3error(errmsg+modname); @@ -710,6 +715,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char else if ( onoff (sw, "-public", flag/*ref*/) ) { m_public = flag; } else if ( !strncmp(sw, "-pvalue+", strlen("-pvalue+"))) { addParameter(string(sw+strlen("-pvalue+")), false); } else if ( onoff (sw, "-report-unoptflat", flag/*ref*/) ) { m_reportUnoptflat = flag; } + else if ( onoff (sw, "-relative-includes", flag/*ref*/) ) { m_relativeIncludes = flag; } else if ( onoff (sw, "-savable", flag/*ref*/) ) { m_savable = flag; } else if ( !strcmp (sw, "-sc") ) { m_outFormatOk = true; m_systemC = true; m_systemPerl = false; } else if ( onoff (sw, "-skip-identical", flag/*ref*/) ) { m_skipIdentical = flag; } @@ -1226,6 +1232,7 @@ V3Options::V3Options() { m_preprocNoLine = false; m_public = false; m_reportUnoptflat = false; + m_relativeIncludes = false; m_savable = false; m_skipIdentical = true; m_stats = false; diff --git a/src/V3Options.h b/src/V3Options.h index 2b129aaba..2b829427e 100644 --- a/src/V3Options.h +++ b/src/V3Options.h @@ -89,6 +89,7 @@ class V3Options { bool m_profileCFuncs;// main switch: --profile-cfuncs bool m_public; // main switch: --public bool m_reportUnoptflat; // main switch: --report-unoptflat + bool m_relativeIncludes; // main switch: --relative-includes bool m_savable; // main switch: --savable bool m_systemC; // main switch: --sc: System C instead of simple C++ bool m_skipIdentical;// main switch: --skip-identical @@ -344,7 +345,7 @@ class V3Options { // METHODS (file utilities using these options) string fileExists (const string& filename); - string filePath (FileLine* fl, const string& modname, const string& errmsg); + string filePath(FileLine* fl, const string& modname, const string& lastpath, const string& errmsg); void filePathLookedMsg(FileLine* fl, const string& modname); V3LangCode fileLanguage(const string &filename); static bool fileStatDir (const string& filename); diff --git a/src/V3Os.cpp b/src/V3Os.cpp index ff93ba69e..1e18a4f98 100644 --- a/src/V3Os.cpp +++ b/src/V3Os.cpp @@ -25,6 +25,8 @@ #include #include #include +#include +#include #include #include #include @@ -141,6 +143,14 @@ string V3Os::filenameSubstitute (const string& filename) { } +string V3Os::filenameRealPath(const string& filename) { + // Get rid of all the ../ behavior in the middle of the paths. + // If there is a ../ that goes down from the 'root' of this path it is preserved. + char retpath[PATH_MAX]; + realpath(filename.c_str(), retpath); + return string(retpath); +} + bool V3Os::filenameIsRel(const string& filename) { return (filename.length()>0 && filename[0] != '/'); } diff --git a/src/V3Os.h b/src/V3Os.h index 84494edb0..d8b08a125 100644 --- a/src/V3Os.h +++ b/src/V3Os.h @@ -41,6 +41,7 @@ public: static string filenameNonDirExt (const string& filename) { return filenameNonExt(filenameNonDir(filename)); } ///< Return basename of filename static string filenameDir (const string& filename); ///< Return directory part of filename static string filenameSubstitute (const string& filename); ///< Return filename with env vars removed + static string filenameRealPath(const string& fn); ///< Return realpath of filename static bool filenameIsRel (const string& filename); ///< True if relative // METHODS (directory utilities) diff --git a/src/V3PreShell.cpp b/src/V3PreShell.cpp index ce36aeada..8e628cf2f 100644 --- a/src/V3PreShell.cpp +++ b/src/V3PreShell.cpp @@ -33,6 +33,7 @@ #include "V3PreProc.h" #include "V3File.h" #include "V3Parse.h" +#include "V3Os.h" //###################################################################### @@ -102,7 +103,7 @@ protected: // Preprocess s_filterp = filterp; - bool ok = preprocOpen(fl, s_filterp, modname, errmsg); + bool ok = preprocOpen(fl, s_filterp, modname, "", errmsg); if (!ok) return false; while (!s_preprocp->isEof()) { @@ -116,10 +117,10 @@ protected: if (modname[0]=='/' || modname[0]=='\\') { fl->v3warn(INCABSPATH,"Suggest `include with absolute path be made relative, and use +include: "<filename()), "Cannot find include file: "); } - bool preprocOpen (FileLine* fl, V3InFilter* filterp, const string& modname, + bool preprocOpen (FileLine* fl, V3InFilter* filterp, const string& modname, const string& lastpath, const string& errmsg) { // Error message or "" to suppress // Returns true if successful // Allow user to put `defined names on the command line instead of filenames, @@ -127,7 +128,7 @@ protected: string ppmodname = s_preprocp->removeDefines (modname); // Open include or master file - string filename = v3Global.opt.filePath (fl, ppmodname, errmsg); + string filename = v3Global.opt.filePath (fl, ppmodname, lastpath, errmsg); if (filename=="") return false; // Not found UINFO(2," Reading "<{vlt} or $Self->skip("Verilator only test"); + +compile ( + v_flags2 => ["--relative-includes", + "--lint-only $Self->{t_dir}/t_flag_relinc_dir/chip/t_flag_relinc_sub.v"], + make_top_shell => 0, + make_main => 0, + verilator_make_gcc => 0, + ); + +ok(1); +1; diff --git a/test_regress/t/t_flag_relinc.v b/test_regress/t/t_flag_relinc.v new file mode 100644 index 000000000..c9cdf700f --- /dev/null +++ b/test_regress/t/t_flag_relinc.v @@ -0,0 +1,10 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// Copyright 2017 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. + +module t; + t_flag_relinc_sub sub (); +endmodule diff --git a/test_regress/t/t_flag_relinc_dir/chip/t_flag_relinc_sub.v b/test_regress/t/t_flag_relinc_dir/chip/t_flag_relinc_sub.v new file mode 100644 index 000000000..dd38e5e9d --- /dev/null +++ b/test_regress/t/t_flag_relinc_dir/chip/t_flag_relinc_sub.v @@ -0,0 +1,15 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// Copyright 2017 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. + +`include "../include/t_flag_relinc.vh" + +module t_flag_relinc_sub (); + initial begin + `all_finished; + $finish; + end +endmodule diff --git a/test_regress/t/t_flag_relinc_dir/include/t_flag_relinc.vh b/test_regress/t/t_flag_relinc_dir/include/t_flag_relinc.vh new file mode 100644 index 000000000..6a19cfbdc --- /dev/null +++ b/test_regress/t/t_flag_relinc_dir/include/t_flag_relinc.vh @@ -0,0 +1,8 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// Copyright 2017 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. + +`define all_finished $write("*-* All Finished *-*\n")