-
Notifications
You must be signed in to change notification settings - Fork 269
patchpkg: patch python to use devbox CUDA libs #2296
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,7 @@ import ( | |
"path" | ||
"path/filepath" | ||
"regexp" | ||
"strings" | ||
) | ||
|
||
//go:embed glibc-patch.bash | ||
|
@@ -42,6 +43,10 @@ type DerivationBuilder struct { | |
|
||
RestoreRefs bool | ||
bytePatches map[string][]fileSlice | ||
|
||
// src contains the source files of the derivation. For flakes, this is | ||
// anything in the flake.nix directory. | ||
src *packageFS | ||
} | ||
|
||
// NewDerivationBuilder initializes a new DerivationBuilder from the current | ||
|
@@ -79,6 +84,9 @@ func (d *DerivationBuilder) init() error { | |
return fmt.Errorf("patchpkg: can't patch gcc using %s: %v", d.Gcc, err) | ||
} | ||
} | ||
if src := os.Getenv("src"); src != "" { | ||
d.src = newPackageFS(src) | ||
} | ||
return nil | ||
} | ||
|
||
|
@@ -95,6 +103,11 @@ func (d *DerivationBuilder) Build(ctx context.Context, pkgStorePath string) erro | |
} | ||
|
||
func (d *DerivationBuilder) build(ctx context.Context, pkg, out *packageFS) error { | ||
// Create the derivation's $out directory. | ||
if err := d.copyDir(out, "."); err != nil { | ||
return err | ||
} | ||
|
||
if d.RestoreRefs { | ||
if err := d.restoreMissingRefs(ctx, pkg); err != nil { | ||
// Don't break the flake build if we're unable to | ||
|
@@ -103,12 +116,19 @@ func (d *DerivationBuilder) build(ctx context.Context, pkg, out *packageFS) erro | |
slog.ErrorContext(ctx, "unable to restore all removed refs", "err", err) | ||
} | ||
} | ||
if err := d.findCUDA(ctx, out); err != nil { | ||
slog.ErrorContext(ctx, "unable to patch CUDA libraries", "err", err) | ||
} | ||
|
||
var err error | ||
for path, entry := range allFiles(pkg, ".") { | ||
if ctx.Err() != nil { | ||
return ctx.Err() | ||
} | ||
if path == "." { | ||
// Skip the $out directory - we already created it. | ||
continue | ||
} | ||
|
||
switch { | ||
case entry.IsDir(): | ||
|
@@ -167,7 +187,7 @@ func (d *DerivationBuilder) copyDir(out *packageFS, path string) error { | |
if err != nil { | ||
return err | ||
} | ||
return os.Mkdir(path, 0o777) | ||
return os.MkdirAll(path, 0o777) | ||
} | ||
|
||
func (d *DerivationBuilder) copyFile(ctx context.Context, pkg, out *packageFS, path string) error { | ||
|
@@ -302,6 +322,69 @@ func (d *DerivationBuilder) findRemovedRefs(ctx context.Context, pkg *packageFS) | |
return refs, nil | ||
} | ||
|
||
func (d *DerivationBuilder) findCUDA(ctx context.Context, out *packageFS) error { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Food for future thought: Is there a way to do this in a more plugin-like way? Maybe we allow built in plugins to use go code (or in the future compile plugins as needed). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like the idea of aligning plugins and patching. This code runs as part of the flake builder (in the nix build sandbox), so plugins would just need something similar. |
||
if d.src == nil { | ||
return fmt.Errorf("patch flake didn't set $src to the path to its source tree") | ||
} | ||
|
||
glob, err := fs.Glob(d.src, "lib/libcuda.so*") | ||
if err != nil { | ||
return fmt.Errorf("glob system libraries: %v", err) | ||
} | ||
if len(glob) != 0 { | ||
err := d.copyDir(out, "lib") | ||
if err != nil { | ||
return fmt.Errorf("copy system library: %v", err) | ||
} | ||
} | ||
for _, lib := range glob { | ||
slog.DebugContext(ctx, "found system CUDA library in flake", "path", lib) | ||
|
||
err := d.copyFile(ctx, d.src, out, lib) | ||
if err != nil { | ||
return fmt.Errorf("copy system library: %v", err) | ||
} | ||
need, err := out.OSPath(lib) | ||
if err != nil { | ||
return fmt.Errorf("get absolute path to library: %v", err) | ||
} | ||
d.glibcPatcher.needed = append(d.glibcPatcher.needed, need) | ||
|
||
slog.DebugContext(ctx, "added DT_NEEDED entry for system CUDA library", "path", need) | ||
} | ||
|
||
slog.DebugContext(ctx, "looking for nix libraries in $patchDependencies") | ||
deps := os.Getenv("patchDependencies") | ||
gcurtis marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if strings.TrimSpace(deps) == "" { | ||
slog.DebugContext(ctx, "$patchDependencies is empty") | ||
return nil | ||
} | ||
for _, pkg := range strings.Split(deps, " ") { | ||
slog.DebugContext(ctx, "checking for nix libraries in package", "pkg", pkg) | ||
|
||
pkgFS := newPackageFS(pkg) | ||
libs, err := fs.Glob(pkgFS, "lib*/*.so*") | ||
if err != nil { | ||
return fmt.Errorf("glob nix package libraries: %v", err) | ||
} | ||
|
||
sonameRegexp := regexp.MustCompile(`(^|/).+\.so\.\d+`) | ||
for _, lib := range libs { | ||
if !sonameRegexp.MatchString(lib) { | ||
continue | ||
} | ||
need, err := pkgFS.OSPath(lib) | ||
if err != nil { | ||
return fmt.Errorf("get absolute path to nix package library: %v", err) | ||
} | ||
d.glibcPatcher.needed = append(d.glibcPatcher.needed, need) | ||
|
||
slog.DebugContext(ctx, "added DT_NEEDED entry for nix library", "path", need) | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
// packageFS is the tree of files for a package in the Nix store. | ||
type packageFS struct { | ||
fs.FS | ||
|
Uh oh!
There was an error while loading. Please reload this page.