mirror of https://gitee.com/namelin2022/ollama
committed by
GitHub
11 changed files with 59 additions and 249 deletions
@ -1,192 +0,0 @@ |
|||
//go:build ignore
|
|||
|
|||
package main |
|||
|
|||
import ( |
|||
"cmp" |
|||
"errors" |
|||
"flag" |
|||
"log" |
|||
"os" |
|||
"os/exec" |
|||
"path/filepath" |
|||
"runtime" |
|||
) |
|||
|
|||
// Flags
|
|||
var ( |
|||
flagForce = flag.Bool("f", false, "force re-generation of dependencies") |
|||
flagSkipBuild = flag.Bool("d", false, "generate dependencies only (e.g. skip 'go build .')") |
|||
|
|||
// Flags to set GOARCH and GOOS explicitly for cross-platform builds,
|
|||
// e.g., in CI to target a different platform than the build matrix
|
|||
// default. These allows us to run generate without a separate build
|
|||
// step for building the script binary for the host ARCH and then
|
|||
// runing the generate script for the target ARCH. Instead, we can
|
|||
// just run `go run build.go -target=$GOARCH` to generate the
|
|||
// deps.
|
|||
flagGOARCH = flag.String("target", "", "sets GOARCH to use when generating dependencies and building") |
|||
) |
|||
|
|||
func buildEnv() []string { |
|||
return append(os.Environ(), |
|||
"GOARCH="+cmp.Or(*flagGOARCH, runtime.GOARCH), |
|||
) |
|||
} |
|||
|
|||
func main() { |
|||
log.SetFlags(0) |
|||
flag.Usage = func() { |
|||
log.Printf("Usage: go run build.go [flags]") |
|||
log.Println() |
|||
log.Println("Flags:") |
|||
flag.PrintDefaults() |
|||
log.Println() |
|||
log.Println("This script builds the Ollama server binary and generates the llama.cpp") |
|||
log.Println("bindings for the current platform. It assumes that the current working") |
|||
log.Println("directory is the root directory of the Ollama project.") |
|||
log.Println() |
|||
log.Println("If the -d flag is provided, the script will only generate the dependencies") |
|||
log.Println("and skip building the Ollama server binary.") |
|||
log.Println() |
|||
log.Println("If the -f flag is provided, the script will force re-generation of the") |
|||
log.Println("dependencies.") |
|||
log.Println() |
|||
log.Println("If the -target flag is provided, the script will set GOARCH to the value") |
|||
log.Println("of the flag. This is useful for cross-platform builds.") |
|||
log.Println() |
|||
log.Println("The script will check for the required dependencies (cmake, gcc) and") |
|||
log.Println("print their version.") |
|||
log.Println() |
|||
log.Println("The script will also check if it is being run from the root directory of") |
|||
log.Println("the Ollama project.") |
|||
log.Println() |
|||
os.Exit(1) |
|||
} |
|||
flag.Parse() |
|||
|
|||
log.Printf("=== Building Ollama ===") |
|||
defer func() { |
|||
log.Printf("=== Done building Ollama ===") |
|||
log.Println() |
|||
log.Println("To run the Ollama server, use:") |
|||
log.Println() |
|||
log.Println(" ./ollama serve") |
|||
log.Println() |
|||
}() |
|||
|
|||
if flag.NArg() > 0 { |
|||
flag.Usage() |
|||
} |
|||
|
|||
if !inRootDir() { |
|||
log.Fatalf("Please run this script from the root directory of the Ollama project.") |
|||
} |
|||
|
|||
if err := checkDependencies(); err != nil { |
|||
log.Fatalf("Failed dependency check: %v", err) |
|||
} |
|||
if err := buildLlammaCPP(); err != nil { |
|||
log.Fatalf("Failed to build llama.cpp: %v", err) |
|||
} |
|||
if err := goBuildOllama(); err != nil { |
|||
log.Fatalf("Failed to build ollama Go binary: %v", err) |
|||
} |
|||
} |
|||
|
|||
// checkDependencies does a quick check to see if the required dependencies are
|
|||
// installed on the system and functioning enough to print their version.
|
|||
//
|
|||
// TODO(bmizerany): Check the actual version of the dependencies? Seems a
|
|||
// little daunting given diff versions might print diff things. This should
|
|||
// be good enough for now.
|
|||
func checkDependencies() error { |
|||
var err error |
|||
check := func(name string, args ...string) { |
|||
log.Printf("=== Checking for %s ===", name) |
|||
defer log.Printf("=== Done checking for %s ===\n\n", name) |
|||
cmd := exec.Command(name, args...) |
|||
cmd.Stdout = os.Stdout |
|||
cmd.Stderr = os.Stderr |
|||
err = errors.Join(err, cmd.Run()) |
|||
} |
|||
|
|||
check("cmake", "--version") |
|||
check("gcc", "--version") |
|||
return err |
|||
} |
|||
|
|||
func goBuildOllama() error { |
|||
log.Println("=== Building Ollama binary ===") |
|||
defer log.Printf("=== Done building Ollama binary ===\n\n") |
|||
if *flagSkipBuild { |
|||
log.Println("Skipping 'go build -o ollama .'") |
|||
return nil |
|||
} |
|||
cmd := exec.Command("go", "build", "-o", "ollama", ".") |
|||
cmd.Stdout = os.Stdout |
|||
cmd.Stderr = os.Stderr |
|||
cmd.Env = buildEnv() |
|||
return cmd.Run() |
|||
} |
|||
|
|||
// buildLlammaCPP generates the llama.cpp bindings for the current platform.
|
|||
//
|
|||
// It assumes that the current working directory is the root directory of the
|
|||
// Ollama project.
|
|||
func buildLlammaCPP() error { |
|||
log.Println("=== Generating dependencies ===") |
|||
defer log.Printf("=== Done generating dependencies ===\n\n") |
|||
if *flagForce { |
|||
if err := os.RemoveAll(filepath.Join("llm", "build")); err != nil { |
|||
return err |
|||
} |
|||
} |
|||
if isDirectory(filepath.Join("llm", "build")) { |
|||
log.Println("llm/build already exists; skipping. Use -f to force re-generate.") |
|||
return nil |
|||
} |
|||
|
|||
scriptDir, err := filepath.Abs(filepath.Join("llm", "generate")) |
|||
if err != nil { |
|||
return err |
|||
} |
|||
|
|||
var cmd *exec.Cmd |
|||
switch runtime.GOOS { |
|||
case "windows": |
|||
script := filepath.Join(scriptDir, "gen_windows.ps1") |
|||
cmd = exec.Command("powershell", "-ExecutionPolicy", "Bypass", "-File", script) |
|||
case "linux": |
|||
script := filepath.Join(scriptDir, "gen_linux.sh") |
|||
cmd = exec.Command("bash", script) |
|||
case "darwin": |
|||
script := filepath.Join(scriptDir, "gen_darwin.sh") |
|||
cmd = exec.Command("bash", script) |
|||
default: |
|||
log.Fatalf("Unsupported OS: %s", runtime.GOOS) |
|||
} |
|||
cmd.Dir = filepath.Join("llm", "generate") |
|||
cmd.Stdout = os.Stdout |
|||
cmd.Stderr = os.Stderr |
|||
cmd.Env = buildEnv() |
|||
|
|||
log.Printf("Running GOOS=%s GOARCH=%s %s", runtime.GOOS, runtime.GOARCH, cmd.Args) |
|||
|
|||
return cmd.Run() |
|||
} |
|||
|
|||
func isDirectory(path string) bool { |
|||
info, err := os.Stat(path) |
|||
if err != nil { |
|||
return false |
|||
} |
|||
return info.IsDir() |
|||
} |
|||
|
|||
// inRootDir returns true if the current working directory is the root
|
|||
// directory of the Ollama project. It looks for a file named "go.mod".
|
|||
func inRootDir() bool { |
|||
_, err := os.Stat("go.mod") |
|||
return err == nil |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
package generate |
|||
|
|||
//go:generate bash ./gen_darwin.sh
|
|||
@ -0,0 +1,3 @@ |
|||
package generate |
|||
|
|||
//go:generate bash ./gen_linux.sh
|
|||
@ -0,0 +1,3 @@ |
|||
package generate |
|||
|
|||
//go:generate powershell -ExecutionPolicy Bypass -File ./gen_windows.ps1
|
|||
Loading…
Reference in new issue