Skip to content

Additional build improvements #13

Open
HelloKayT wants to merge 22 commits intomainfrom
katie/build_improvements
Open

Additional build improvements #13
HelloKayT wants to merge 22 commits intomainfrom
katie/build_improvements

Conversation

@HelloKayT
Copy link

@HelloKayT HelloKayT commented Mar 11, 2026

Bringing in quartz and working with sophisticated external library dependencies required additional infrastructure.

  • Allow multiple src patterns for one library. Code from other repos can rely on files in other folders, but expects to be in the same library
  • Exclude patterns: we need to be able to exclude testbenches/other test code
  • Bring in submodules: quartz has XPM as a submodule and we need that for top-level testbenches

https://github.com/oxidecomputer/redhawk/pull/42/ relies on this version of vw

@HelloKayT HelloKayT requested a review from rcgoodfellow March 13, 2026 17:16
Copy link
Collaborator

@rcgoodfellow rcgoodfellow left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @HelloKayT. Just a few small comments here. Also noticing some things that I had Claude generate that I'm not super thrilled with haha. Created a follow up issue for leveraging vhdl_ls for dependency modeling if we can.

#[serde(default)]
pub commit: Option<String>,
pub src: String,
#[serde(deserialize_with = "string_or_vec")]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is maintaining this parser really necessary or should we just say that this field is always vector-valued and the string case becomes a single element vector? I realize this makes existing vw.toml files backwards compatible, but given i'm the only other user of vw at this point I think, i'm fine with updating my toml files.

Copy link
Author

@HelloKayT HelloKayT Mar 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I think if we're okay with "vector of patterns" as a way to control which source directories to bring into a library, a single element vector works. I'll update to just do a vector

pub repo: String,
pub commit: String,
pub src: String,
#[serde(deserialize_with = "string_or_vec")]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above, I think we can probably avoid the manual parsing here and just make this vector valued all the time.


/// Get cached file dependencies, reading and parsing file if not cached.
pub fn get_dependencies(&mut self, path: &Path) -> Result<&Vec<VwSymbol>> {
if !self.dependencies.contains_key(path) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can avoid the get then unwrap pattern by using the Entry API here.

use std::collections::hash_map::Entry;
// ...
    pub fn get_dependencies(&mut self, path: &Path) -> Result<&Vec<VwSymbol>> {
        let entry = self.dependencies.entry(path.to_path_buf());
        Ok(match entry {
            Entry::Occupied(e) => e.into_mut(),
            Entry::Vacant(e) => {
                let content = fs::read_to_string(path).map_err(|e| {
                    VwError::FileSystem {
                        message: format!("Failed to read file {path:?}: {e}"),
                    }
                })?;
                let deps = parse_file_dependencies(&content)?;
                e.insert(deps)
            }
        })
    }

&mut self,
path: &Path,
) -> Result<&Vec<VwSymbol>> {
if !self.provided_symbols.contains_key(path) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same use of Entry API also applies here.

}

// Find direct entity instantiations (instance_name: entity work.entity_name)
let entity_inst_pattern = r"(?i)\w+\s*:\s*entity\s+work\.(\w+)";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not something that needs to be addressed here, but I seem to recall that we can get a dependency-tree-like-thing from vhdl_ls? I realize this is code that is mostly moved and is not new. So just going to create a tracking issue.

lib_deps.insert(lib_name.clone(), deps);
}

// Topological sort of library names (Kahn's algorithm)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've used the topological sort in the petgraph crate for stuff like this and it's worked out nicely.


/// Get cached entities in file, reading and parsing if not cached.
pub fn get_entities(&mut self, path: &Path) -> Result<&Vec<String>> {
if !self.entities.contains_key(path) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same use of Entry API also applies here.

})??;

// Find the .so file in the workspace target directory (parent of testbench dir)
let lib_name = format!("lib{}.so", package_name.replace('-', "_"));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The following seems to allow things to compile on macos

Suggested change
let lib_name = format!("lib{}.so", package_name.replace('-', "_"));
let ext = if cfg!(target_os = "macos") { "dylib" } else { "so" };
let lib_name = format!("lib{}.{ext}", package_name.replace('-', "_"));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants