RepoNVIDIANVIDIApublished Oct 1, 2025seen Jun 26

NVIDIA/Dependency-Patterns

Starlark

Open original ↗

Captured source

source ↗
published Oct 1, 2025seen Jun 26captured Aug 30http 200method plain

NVIDIA/Dependency-Patterns

Description: Example dependency patterns for OSS build tools to support

Language: Starlark

License: NOASSERTION

Stars: 1

Forks: 5

Open issues: 0

Created: 2025-10-01T13:46:10Z

Pushed: 2026-07-06T19:44:29Z

Default branch: main

Fork: no

Archived: no

README: SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: MIT

Dependency Patterns Demo Project

A demonstration C project with 5 modular libraries that build into shared objects (.so files) and link into a final main binary. The useful part of this demonstration is the various code generation dependency patterns in each library. Each Makefile has the full set of dependencies manually written. The desire is for them to all be automatically inferred.

Project Structure

public_demo/
├── main.c # Main executable that uses all modules
├── Makefile # Root Makefile to build everything
├── README.md # This file
├── strutils/ # String utilities module (renamed from string)
│ ├── strutils.h # String function declarations
│ ├── strutils.c # String function implementations
│ └── Makefile # Builds libstrutils.so
├── utils/ # Utility functions module
│ ├── utils.h # Utility function declarations
│ ├── memory.c # Memory and array operations
│ ├── validation.c # Validation and conversion functions
│ └── Makefile # Builds libutils.so
├── mathutils/ # Math operations module
│ ├── gen_mathutils_h.pl # Generates mathutils.h
│ ├── gen_mathutils_c.pl # Generates mathutils.c
│ └── Makefile # Builds libmathutils.so
├── io/ # Input/Output operations module
│ ├── io.h # IO function declarations
│ ├── generate_io.py # Generates io_impl/*.c files
│ └── Makefile # Builds libio.so
└── protocol/ # Protocol encoding/decoding module
├── protocol.spec # Protocol message definitions
├── generate_protocol.py # Generates protocol.h and proto_impl/*.c files
└── Makefile # Builds libprotocol.so

Modules

String Utilities Module (libstrutils.so)

  • Build Pattern: Single static source file, header dependency inferable from primary source
digraph strutils {
rankdir = LR
cpp [shape=box]
gcc [shape=box]
ld [shape=box]
"strutils.c" [shape=cylinder]
"strutils.h" [shape=cylinder]
"strutils.c" -> cpp -> "strutils.i" -> gcc -> "strutils.o" -> ld -> "libstrutils.so"
"strutils.h" -> cpp
subgraph dep {
rank="same"
edge [color=red, label=dependency]
"strutils.c" -> "strutils.h"
}
}

Utils Module (libutils.so)

  • Build Pattern: Multi-source static files into a single library, header dependency inferable from primary source
digraph utils {
rankdir = LR
cpp1 [shape=box label=cpp]
cpp2 [shape=box label=cpp]
gcc1 [shape=box label=gcc]
gcc2 [shape=box label=gcc]
ld [shape=box]
"memory.c" [shape=cylinder]
"validation.c" [shape=cylinder]
"utils.h" [shape=cylinder]
"memory.c" -> cpp1 -> "memory.i" -> gcc1 -> "memory.o" -> ld
"validation.c" -> cpp2 -> "validation.i" -> gcc2 -> "validation.o" -> ld
"utils.h" -> { cpp1 cpp2 }
ld -> "libutils.so"
subgraph dep {
rank="same"
edge [color=red, label=dependency]
"memory.c" -> "utils.h"
"validation.c" -> "utils.h"
}
}

Mathutils Module (libmathutils.so)

  • Build Pattern: Source and header generation, header dependency not inferable from primary sources
digraph mathutils {
rankdir = LR
cpp [shape=box]
gcc [shape=box]
ld [shape=box]
"gen_mathutils_c.pl" [shape=cylinder, style=filled, fillcolor=lightblue]
"gen_mathutils_h.pl" [shape=cylinder, style=filled, fillcolor=lightblue]
"gen_mathutils_c.pl" -> "mathutils.c"
"gen_mathutils_h.pl" -> "mathutils.h"
"mathutils.c" -> cpp -> "mathutils.i" -> gcc -> "mathutils.o" -> ld
"mathutils.h" -> cpp
ld -> "libmathutils.so"
subgraph dep {
rank="same"
edge [color=red, label=dependency]
"mathutils.c" -> "mathutils.h"
}
}

IO Module (libio.so)

  • Build Pattern: Source generation, static header, unpredictable generated file names, header dependency inferable from primary source
digraph io {
rankdir = LR
cpp [shape=box]
gcc [shape=box]
ld [shape=box]
"generate_io.py" [shape=cylinder, style=filled, fillcolor=lightblue]
"io.h" [shape=cylinder]
"io_impl_*.c" [style=dashed]
"io_impl_*.i" [style=dashed]
"io_impl_*.o" [style=dashed]
"generate_io.py" -> "io_impl_*.c"
"io_impl_*.c" -> cpp -> "io_impl_*.i" -> gcc -> "io_impl_*.o" -> ld
"io.h" -> cpp
ld -> "libio.so"
subgraph dep {
rank="same"
edge [color=red, label=dependency]
"io_impl_*.c" -> "io.h"
}
}

Protocol Module (libprotocol.so)

  • Build Pattern: Generated header and sources with unpredictable names, header dependency not inferable from primary sources
digraph protocol {
rankdir = LR
cpp [shape=box]
gcc [shape=box]
ld [shape=box]
"generate_protocol.py" [shape=cylinder, style=filled, fillcolor=lightblue]
"protocol.spec" [shape=cylinder, style=filled, fillcolor=lightyellow]
"protocol_*.h" [style=dashed]
"proto_impl_*.c" [style=dashed]
"proto_impl_*.i" [style=dashed]
"proto_impl_*.o" [style=dashed]
"protocol.spec" -> "generate_protocol.py"
"generate_protocol.py" -> "protocol_*.h"
"generate_protocol.py" -> "proto_impl_*.c"
"proto_impl_*.c" -> cpp -> "proto_impl_*.i" -> gcc -> "proto_impl_*.o" -> ld
"protocol_*.h" -> cpp
ld -> "libprotocol.so"
subgraph dep {
rank="same"
edge [color=red, label=dependency]
"proto_impl_*.c" -> "protocol_*.h"
}
}

Build Patterns

Each library demonstrates different dependency inference challenges:

1. Strutils Module - Header Dependency Inferable

  • Build Pattern: Single static source file, header dependency inferable from primary source
  • Dependency Challenge: The Makefile can automatically infer that strutils.c depends on strutils.h by scanning the source file for #include statements
  • Applicable Inference Strategy: Automatic inference from source scanning
  • Build Graph Implications: Simple single-file pipeline that should be reasonably easy to represent

2. Utils Module - Multi-Source with Shared Header

  • Build Pattern: Multi-source static files into a single library, header dependency inferable from primary source
  • Dependency Challenge: Both memory.c and validation.c depend on utils.h, and this can be inferred by scanning each source file
  • Applicable Inference Strategy: Automatic inference from source scanning for each file
  • Build Graph Implications: How to have the top-level depend on libutils.so when it's not describable as a derived product from a single Target...

Excerpt shown — open the source for the full document.