From 5cfe6a9c1ee66d810a5f40bedc57442dafd4b40d Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Fri, 8 Nov 2024 19:29:56 +0100 Subject: [PATCH 1/4] reduce OS ifdefs, refactor getting dirs and filenames from paths to files --- backends/cxxrtl/cxxrtl_backend.cc | 16 +--------------- frontends/ast/simplify.cc | 8 ++------ frontends/verilog/preproc.cc | 6 +----- kernel/io.cc | 19 +++++++++++++++++++ kernel/io.h | 2 ++ 5 files changed, 25 insertions(+), 26 deletions(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 48710aff8..d575b5879 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -637,20 +637,6 @@ std::string escape_cxx_string(const std::string &input) return output; } -std::string basename(const std::string &filepath) -{ -#ifdef _WIN32 - const std::string dir_seps = "\\/"; -#else - const std::string dir_seps = "/"; -#endif - size_t sep_pos = filepath.find_last_of(dir_seps); - if (sep_pos != std::string::npos) - return filepath.substr(sep_pos + 1); - else - return filepath; -} - template std::string get_hdl_name(T *object) { @@ -2858,7 +2844,7 @@ struct CxxrtlWorker { } if (split_intf) - f << "#include \"" << basename(intf_filename) << "\"\n"; + f << "#include \"" << name_from_file_path(intf_filename) << "\"\n"; else f << "#include \n"; f << "\n"; diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 81018e137..97abf7452 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -30,6 +30,7 @@ #include "libs/sha1/sha1.h" #include "frontends/verilog/verilog_frontend.h" #include "ast.h" +#include "kernel/io.h" #include #include @@ -4474,12 +4475,7 @@ std::unique_ptr AstNode::readmem(bool is_readmemh, std::string mem_file std::ifstream f; f.open(mem_filename.c_str()); if (f.fail()) { -#ifdef _WIN32 - char slash = '\\'; -#else - char slash = '/'; -#endif - std::string path = location.begin.filename->substr(0, location.begin.filename->find_last_of(slash)+1); + std::string path = parent_from_file_path(*location.begin.filename); f.open(path + mem_filename.c_str()); yosys_input_files.insert(path + mem_filename); } else { diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc index 1858edc97..7675bab62 100644 --- a/frontends/verilog/preproc.cc +++ b/frontends/verilog/preproc.cc @@ -895,11 +895,7 @@ frontend_verilog_preproc(std::istream &f, // if the include file was not found, it is not given with an absolute path, and the // currently read file is given with a path, then try again relative to its directory ff.clear(); -#ifdef _WIN32 - fixed_fn = filename.substr(0, filename.find_last_of("/\\")+1) + fn; -#else - fixed_fn = filename.substr(0, filename.rfind('/')+1) + fn; -#endif + fixed_fn = parent_from_file_path(filename) + fn; ff.open(fixed_fn); } if (ff.fail() && fn.size() > 0 && fn_relative) { diff --git a/kernel/io.cc b/kernel/io.cc index 9e9eb9fb0..dfdb56d16 100644 --- a/kernel/io.cc +++ b/kernel/io.cc @@ -391,6 +391,25 @@ void append_globbed(std::vector& paths, std::string pattern) copy(globbed.begin(), globbed.end(), back_inserter(paths)); } +#ifdef _WIN32 +const char* const OS_PATH_SEP = "/\\"; +#else +const char* const OS_PATH_SEP = "/"; +#endif + +std::string name_from_file_path(std::string path) { + size_t sep_pos = path.find_last_of(OS_PATH_SEP); + if (sep_pos != std::string::npos) + return path.substr(sep_pos + 1); + else + return path; +} + +// Includes OS_PATH_SEP at the end if present +std::string parent_from_file_path(std::string path) { + return path.substr(0, path.find_last_of(OS_PATH_SEP)+1); +} + void format_emit_unescaped(std::string &result, std::string_view fmt) { result.reserve(result.size() + fmt.size()); diff --git a/kernel/io.h b/kernel/io.h index b3922bef0..171f47a80 100644 --- a/kernel/io.h +++ b/kernel/io.h @@ -470,6 +470,8 @@ void remove_directory(std::string dirname); bool create_directory(const std::string& dirname); std::string escape_filename_spaces(const std::string& filename); void append_globbed(std::vector& paths, std::string pattern); +std::string name_from_file_path(std::string path); +std::string parent_from_file_path(std::string path); YOSYS_NAMESPACE_END From 79cd4e08c4dc1828e697da722973c1be4c3d69ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emil=20Ji=C5=99=C3=AD=20Tywoniak?= Date: Tue, 23 Sep 2025 17:38:14 +0200 Subject: [PATCH 2/4] io: use std::filesystem --- kernel/io.cc | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/kernel/io.cc b/kernel/io.cc index dfdb56d16..45aa496b0 100644 --- a/kernel/io.cc +++ b/kernel/io.cc @@ -2,6 +2,7 @@ #include "kernel/log.h" #include #include +#include #if !defined(WIN32) #include @@ -398,16 +399,21 @@ const char* const OS_PATH_SEP = "/"; #endif std::string name_from_file_path(std::string path) { - size_t sep_pos = path.find_last_of(OS_PATH_SEP); - if (sep_pos != std::string::npos) - return path.substr(sep_pos + 1); - else - return path; + return std::filesystem::path(path).filename().string(); } // Includes OS_PATH_SEP at the end if present std::string parent_from_file_path(std::string path) { - return path.substr(0, path.find_last_of(OS_PATH_SEP)+1); + auto parent = std::filesystem::path(path).parent_path(); + if (parent.empty()) { + return ""; + } + // Add trailing separator to match original behavior + std::string result = parent.string(); + if (!result.empty() && result.back() != std::filesystem::path::preferred_separator) { + result += std::filesystem::path::preferred_separator; + } + return result; } void format_emit_unescaped(std::string &result, std::string_view fmt) From d1a628ab2664accf6cb58189c75e05c91c198695 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emil=20Ji=C5=99=C3=AD=20Tywoniak?= Date: Tue, 23 Sep 2025 17:38:32 +0200 Subject: [PATCH 3/4] CI: bump WASI SDK from 19 to 27 --- .github/workflows/extra-builds.yml | 4 ++-- Makefile | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/extra-builds.yml b/.github/workflows/extra-builds.yml index 503145e97..b22a399db 100644 --- a/.github/workflows/extra-builds.yml +++ b/.github/workflows/extra-builds.yml @@ -73,8 +73,8 @@ jobs: persist-credentials: false - name: Build run: | - WASI_SDK=wasi-sdk-19.0 - WASI_SDK_URL=https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-19/wasi-sdk-19.0-linux.tar.gz + WASI_SDK=wasi-sdk-27.0-x86_64-linux + WASI_SDK_URL=https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-27/wasi-sdk-27.0-x86_64-linux.tar.gz if ! [ -d ${WASI_SDK} ]; then curl -L ${WASI_SDK_URL} | tar xzf -; fi FLEX_VER=2.6.4 diff --git a/Makefile b/Makefile index b744763c8..04395a5a0 100644 --- a/Makefile +++ b/Makefile @@ -282,12 +282,11 @@ ifeq ($(WASI_SDK),) CXX = clang++ AR = llvm-ar RANLIB = llvm-ranlib -WASIFLAGS := -target wasm32-wasi --sysroot $(WASI_SYSROOT) $(WASIFLAGS) +WASIFLAGS := -target wasm32-wasi $(WASIFLAGS) else CXX = $(WASI_SDK)/bin/clang++ AR = $(WASI_SDK)/bin/ar RANLIB = $(WASI_SDK)/bin/ranlib -WASIFLAGS := --sysroot $(WASI_SDK)/share/wasi-sysroot $(WASIFLAGS) endif CXXFLAGS := $(WASIFLAGS) -std=$(CXXSTD) $(OPT_LEVEL) -D_WASI_EMULATED_PROCESS_CLOCKS $(filter-out -fPIC,$(CXXFLAGS)) LINKFLAGS := $(WASIFLAGS) -Wl,-z,stack-size=1048576 $(filter-out -rdynamic,$(LINKFLAGS)) From 1eb5181700e980a9a10c7c607e06c98755f8bc10 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 14 Oct 2025 14:12:24 +1300 Subject: [PATCH 4/4] Add tests/verilog/local_include.* `read_verilog` supports checking both the current directory and the source directory for relative includes. Make sure we aren't regressing that. --- tests/verilog/.gitignore | 2 ++ tests/verilog/local_include.sh | 30 ++++++++++++++++++++++++++++++ tests/verilog/local_include.v | 4 ++++ 3 files changed, 36 insertions(+) create mode 100755 tests/verilog/local_include.sh create mode 100644 tests/verilog/local_include.v diff --git a/tests/verilog/.gitignore b/tests/verilog/.gitignore index 3702f10cf..d3e8690d5 100644 --- a/tests/verilog/.gitignore +++ b/tests/verilog/.gitignore @@ -4,3 +4,5 @@ /roundtrip_proc_1.v /roundtrip_proc_2.v /assign_to_reg.v +/subdir +/temp_foo.v diff --git a/tests/verilog/local_include.sh b/tests/verilog/local_include.sh new file mode 100755 index 000000000..c10c7411b --- /dev/null +++ b/tests/verilog/local_include.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +set -eu + +# only works with read_verilog +yosys='../../yosys -f verilog' +test='-p hierarchy' +subdir=subdir +source=local_include.v +include=temp_foo.v + +# no include file should fail +rm -f $include +echo "logger -expect error $include 1; read_verilog $source" | $yosys + +# both files local +echo 'module foo (input a, output b); assign b = a; endmodule' > $include +$yosys $test $source + +# include local to cwd +mkdir -p $subdir +cp -t $subdir $source +$yosys $test $subdir/$source + +# include local to source +mv -t $subdir $include +$yosys $test $subdir/$source + +# include local to source, and source is given as an absolute path +$yosys $test $(pwd)/$subdir/$source diff --git a/tests/verilog/local_include.v b/tests/verilog/local_include.v new file mode 100644 index 000000000..a677e888e --- /dev/null +++ b/tests/verilog/local_include.v @@ -0,0 +1,4 @@ +`include "temp_foo.v" +module top (input x, output y); + foo bar (.a(x), .b(y)); +endmodule