blob: 5a2f2a36a3d5fdb40d1ba569c696208b4def9b26 [file] [log] [blame]
package builder
import (
"context"
"fmt"
"os"
"os/exec"
"path/filepath"
"strings"
"cloud.google.com/go/storage"
"cos.googlesource.com/cos/tools.git/src/pkg/cos"
"cos.googlesource.com/cos/tools.git/src/pkg/gpuconfig"
"cos.googlesource.com/cos/tools.git/src/pkg/utils"
)
const (
linkerLocation = "/bin/ld"
installDirTemplate = "/install/%s"
defaultFilePermission = 0755
kernelSrcTemplate = "usr/src/linux-headers-*"
)
func kernelSrcDirectory(dirName string) string {
files, err := filepath.Glob(filepath.Join(dirName, kernelSrcTemplate))
if err != nil || len(files) != 1 {
return ""
}
return files[0]
}
func nvidiaInstallerCommand(dirName, runfile string, config gpuconfig.GPUPrecompilationConfig) *exec.Cmd {
cmd := exec.Command(filepath.Join(dirName, runfile), "--kernel-source-path="+kernelSrcDirectory(dirName), "--add-this-kernel", "--no-install-compat32-libs", "--silent", "--accept-license")
cmd.Dir = dirName
return cmd
}
func BuildPrecompiledDriver(ctx context.Context, client *storage.Client, config gpuconfig.GPUPrecompilationConfig) (string, string, error) {
var err error
dirName := fmt.Sprintf(installDirTemplate, config.Version)
if err = os.MkdirAll(dirName, defaultFilePermission); err != nil {
return "", "", fmt.Errorf("failed to create installation dir: %v", err)
}
downloader := gpuconfig.NewGPUArtifactsDownloader(ctx, client, config)
// download NVIDIA runfile
var nvidiaInstaller string
if nvidiaInstaller, err = downloader.DownloadNVIDIARunfile(dirName); err != nil {
return "", "", fmt.Errorf("failed to download NVIDIA runfile: %v", err)
}
// install kernel headers and toolchain
// sets SYSROOT and PATH env vars
if err = cos.InstallCrossToolchain(downloader, dirName); err != nil {
return "", "", fmt.Errorf("failed to install toolchain: %v", err)
}
// set CC CXX env vars from toolchain_env
if err = cos.SetCompilationEnv(downloader); err != nil {
return "", "", fmt.Errorf("failed to set compilation env vars: %v", err)
}
// create symlink to ld - required by NVIDIA driver package
if err = cos.ForceSymlinkLinker(filepath.Join(dirName, linkerLocation)); err != nil {
return "", "", fmt.Errorf("failed to create symlink to COS linker: %v", err)
}
cc := os.Getenv("CC")
if cc == "" {
return "", "", fmt.Errorf("failed to find CC in env")
} else {
// create a wrapper removing -Werror=strict-prototypes from the CC command line.
if err = cos.AddCCWrapperToPath(dirName, dirName, cc); err != nil {
return "", "", fmt.Errorf("failed to create CC wrapper: %v", err)
}
}
// run NVIDIA driver package
if err = os.Chmod(filepath.Join(dirName, nvidiaInstaller), defaultFilePermission); err != nil {
return "", "", err
}
cmd := nvidiaInstallerCommand(dirName, nvidiaInstaller, config)
if err = utils.RunCommandAndLogOutput(cmd, false); err != nil {
return "", "", fmt.Errorf("error running NVIDIA driver installation package: %v", err)
}
outputFileName := strings.Split(nvidiaInstaller, ".run")[0] + "-custom.run"
return dirName, outputFileName, nil
}