diff --git a/Makefile.common b/Makefile.common new file mode 100644 index 000000000..a45f52a6f --- /dev/null +++ b/Makefile.common @@ -0,0 +1,15 @@ +# Common Makefile definitions shared across subprojects +# This file should be included at the top of other Makefiles + +# OS detection +ifeq ($(OS),Windows_NT) + DETECTED_OS := Windows +else + UNAME_S := $(shell uname -s) + ifeq ($(UNAME_S),Linux) + DETECTED_OS := Linux + endif + ifeq ($(UNAME_S),Darwin) + DETECTED_OS := macOS + endif +endif diff --git a/cmd/cli/.gitignore b/cmd/cli/.gitignore index 2312de12f..fe89a5efc 100644 --- a/cmd/cli/.gitignore +++ b/cmd/cli/.gitignore @@ -1,3 +1,4 @@ model-cli +model-cli.exe .idea/ -dist/ \ No newline at end of file +dist/ diff --git a/cmd/cli/Makefile b/cmd/cli/Makefile index d6d5b4aea..079df4e34 100644 --- a/cmd/cli/Makefile +++ b/cmd/cli/Makefile @@ -1,8 +1,8 @@ +include ../../Makefile.common + .PHONY: all build clean link mock unit-tests docs BINARY_NAME=model-cli - -PLUGIN_DIR=$(HOME)/.docker/cli-plugins PLUGIN_NAME=docker-model VERSION ?= @@ -10,23 +10,42 @@ VERSION ?= MACOS_MIN_VERSION := 14.0 MACOS_MIN_VERSION_LDFLAG := -mmacosx-version-min=$(MACOS_MIN_VERSION) +# OS-specific settings +ifeq ($(DETECTED_OS),Windows) + BINARY_EXT := .exe + PLUGIN_DIR := $(USERPROFILE)/.docker/cli-plugins +else + BINARY_EXT := + PLUGIN_DIR := $(HOME)/.docker/cli-plugins +endif + +BINARY_WITH_EXT := $(BINARY_NAME)$(BINARY_EXT) +PLUGIN_WITH_EXT := $(PLUGIN_NAME)$(BINARY_EXT) + all: build build: - @echo "Building $(BINARY_NAME)..." - go build -ldflags="-s -w -X github.com/docker/model-runner/cmd/cli/desktop.Version=$(shell git describe --tags --always --dirty)" -o $(BINARY_NAME) . + @echo "Building $(BINARY_WITH_EXT)..." + go build -ldflags="-s -w -X github.com/docker/model-runner/cmd/cli/desktop.Version=$(shell git describe --tags --always --dirty)" -o $(BINARY_WITH_EXT) . link: - @if [ ! -f $(BINARY_NAME) ]; then \ + @if [ ! -f $(BINARY_WITH_EXT) ]; then \ echo "Binary not found, building first..."; \ $(MAKE) build; \ else \ - echo "Using existing binary $(BINARY_NAME)"; \ + echo "Using existing binary $(BINARY_WITH_EXT)"; \ fi - @echo "Linking $(BINARY_NAME) to Docker CLI plugins directory..." - @mkdir -p $(PLUGIN_DIR) - @ln -sf $(shell pwd)/$(BINARY_NAME) $(PLUGIN_DIR)/$(PLUGIN_NAME) - @echo "Link created: $(PLUGIN_DIR)/$(PLUGIN_NAME)" +ifeq ($(DETECTED_OS),Windows) + @echo "Copying $(BINARY_WITH_EXT) to Docker CLI plugins directory..." + @mkdir -p "$(PLUGIN_DIR)" + @cp -f $(BINARY_WITH_EXT) "$(PLUGIN_DIR)/$(PLUGIN_WITH_EXT)" + @echo "Plugin installed: $(PLUGIN_DIR)/$(PLUGIN_WITH_EXT)" +else + @echo "Linking $(BINARY_WITH_EXT) to Docker CLI plugins directory..." + @mkdir -p "$(PLUGIN_DIR)" + @ln -sf $(shell pwd)/$(BINARY_WITH_EXT) "$(PLUGIN_DIR)/$(PLUGIN_WITH_EXT)" + @echo "Link created: $(PLUGIN_DIR)/$(PLUGIN_WITH_EXT)" +endif install: build link @@ -68,7 +87,7 @@ unit-tests: clean: @echo "Cleaning up..." - @rm -f $(BINARY_NAME) + @rm -f $(BINARY_WITH_EXT) @echo "Cleaned!" docs: diff --git a/llamacpp/Makefile b/llamacpp/Makefile index 6e398a1ca..600f3da9a 100644 --- a/llamacpp/Makefile +++ b/llamacpp/Makefile @@ -1,20 +1,27 @@ -ifeq ($(OS),Windows_NT) - DETECTED_OS := Windows -else - UNAME_S := $(shell uname -s) - ifeq ($(UNAME_S),Linux) - DETECTED_OS := Linux - endif - ifeq ($(UNAME_S),Darwin) - DETECTED_OS := macOS - endif -endif +include ../Makefile.common BUILD_DIR := build INSTALL_DIR := install NATIVE_DIR := native -.PHONY: build clean install-deps build-dir install-dir +# Vulkan SDK version for Windows +VULKAN_VERSION := 1.4.313.2 + +# Architecture detection for Windows +ifeq ($(DETECTED_OS),Windows) + UNAME_M := $(shell uname -m) + ifeq ($(UNAME_M),x86_64) + DETECTED_ARCH := amd64 + else ifeq ($(UNAME_M),aarch64) + DETECTED_ARCH := arm64 + else ifeq ($(UNAME_M),arm64) + DETECTED_ARCH := arm64 + else + DETECTED_ARCH := amd64 + endif +endif + +.PHONY: build clean install-deps install-deps-cuda install-deps-opencl build-dir install-dir build: install-deps ifeq ($(DETECTED_OS),macOS) @@ -48,8 +55,60 @@ else ifeq ($(DETECTED_OS),Linux) @echo "Linux build not implemented yet" @exit 1 else ifeq ($(DETECTED_OS),Windows) - @echo "Windows build not implemented yet" - @exit 1 +ifeq ($(DETECTED_ARCH),amd64) + @echo "Building for Windows AMD64 (CPU with Vulkan)..." + @echo "Configuring CMake..." + PATH="C:/Program Files/LLVM/bin;$$PATH" cmake -B $(BUILD_DIR) \ + -DCMAKE_BUILD_TYPE=Release \ + -DGGML_NATIVE=OFF \ + -DGGML_OPENMP=OFF \ + -DDDLLAMA_BUILD_UTILS=ON \ + -GNinja \ + -DLLAMA_CURL=OFF \ + -DBUILD_SHARED_LIBS=ON \ + -DGGML_BACKEND_DL=ON \ + -DGGML_CPU_ALL_VARIANTS=ON \ + -DGGML_VULKAN=ON \ + "-DCMAKE_C_COMPILER=C:/Program Files/LLVM/bin/clang.exe" \ + "-DCMAKE_CXX_COMPILER=C:/Program Files/LLVM/bin/clang++.exe" \ + "-DCMAKE_RC_COMPILER=C:/Program Files/LLVM/bin/llvm-rc.exe" \ + -S $(NATIVE_DIR) + @echo "Building..." + PATH="C:/Program Files/LLVM/bin;$$PATH" cmake --build $(BUILD_DIR) --config Release + @echo "Installing..." + cmake --install $(BUILD_DIR) \ + --config Release \ + --prefix $(INSTALL_DIR) + @echo "Cleaning install directory..." + rm -f $(INSTALL_DIR)/bin/*.py + rm -rf $(INSTALL_DIR)/lib/cmake + rm -rf $(INSTALL_DIR)/lib/pkgconfig + rm -rf $(INSTALL_DIR)/include + @echo "Build complete! Binaries are in $(INSTALL_DIR)" +else + @echo "Building for Windows ARM64 (CPU)..." + @echo "Configuring CMake..." + cmake -B $(BUILD_DIR) \ + -G Ninja \ + -DCMAKE_C_COMPILER="C:/Program Files/LLVM/bin/clang.exe" \ + -DCMAKE_CXX_COMPILER="C:/Program Files/LLVM/bin/clang++.exe" \ + -DCMAKE_BUILD_TYPE=Release \ + -DGGML_NATIVE=OFF \ + -DLLAMA_CURL=OFF \ + -S $(NATIVE_DIR) + @echo "Building..." + cmake --build $(BUILD_DIR) --config Release + @echo "Installing..." + cmake --install $(BUILD_DIR) \ + --config Release \ + --prefix $(INSTALL_DIR) + @echo "Cleaning install directory..." + rm -f $(INSTALL_DIR)/bin/*.py + rm -rf $(INSTALL_DIR)/lib/cmake + rm -rf $(INSTALL_DIR)/lib/pkgconfig + rm -rf $(INSTALL_DIR)/include + @echo "Build complete! Binaries are in $(INSTALL_DIR)" +endif else @echo "Unsupported OS: $(DETECTED_OS)" @exit 1 @@ -68,8 +127,30 @@ else ifeq ($(DETECTED_OS),Linux) @echo "Linux dependency installation not implemented yet" @exit 1 else ifeq ($(DETECTED_OS),Windows) - @echo "Windows dependency installation not implemented yet" - @exit 1 +ifeq ($(DETECTED_ARCH),amd64) + @echo "Installing build dependencies for Windows AMD64 (CPU with Vulkan)..." + @echo "Installing Ninja..." + choco install ninja -y + @echo "Installing CMake..." + choco install cmake -y --installargs 'ADD_CMAKE_TO_PATH=System' + @echo "Installing LLVM (clang)..." + choco install llvm -y + @echo "Adding LLVM to system PATH..." + @powershell -Command "[System.Environment]::SetEnvironmentVariable('PATH', 'C:\\Program Files\\LLVM\\bin;' + [System.Environment]::GetEnvironmentVariable('PATH', 'Machine'), 'Machine')" || echo "LLVM PATH update attempted" + @if [ -d "/c/VulkanSDK/$(VULKAN_VERSION)" ]; then \ + echo "Vulkan SDK $(VULKAN_VERSION) already installed"; \ + else \ + echo "Installing Vulkan SDK $(VULKAN_VERSION)..."; \ + curl.exe -o "$$TEMP/VulkanSDK-Installer.exe" -L "https://sdk.lunarg.com/sdk/download/$(VULKAN_VERSION)/windows/vulkansdk-windows-X64-$(VULKAN_VERSION).exe"; \ + "$$TEMP/VulkanSDK-Installer.exe" --accept-licenses --default-answer --confirm-command install; \ + powershell -Command "[System.Environment]::SetEnvironmentVariable('VULKAN_SDK', 'C:\\VulkanSDK\\$(VULKAN_VERSION)', 'User')"; \ + powershell -Command "[System.Environment]::SetEnvironmentVariable('PATH', [System.Environment]::GetEnvironmentVariable('PATH', 'User') + ';C:\\VulkanSDK\\$(VULKAN_VERSION)\\bin', 'User')"; \ + echo "Vulkan SDK $(VULKAN_VERSION) installed. Please restart your shell for changes to take effect."; \ + fi +else + @echo "Installing build dependencies for Windows ARM64 (CPU)..." + @echo "Ninja and LLVM should already be installed on ARM64 runners" +endif else @echo "Unsupported OS: $(DETECTED_OS)" @exit 1 @@ -87,9 +168,9 @@ install-dir: help: @echo "Available targets:" - @echo " build - Build llama.cpp (macOS only for now)" - @echo " install-deps - Install build dependencies" - @echo " build-dir - Print build directory path" - @echo " install-dir - Print install directory path" - @echo " clean - Clean build artifacts" - @echo " help - Show this help" + @echo " build - Build llama.cpp (macOS and Windows)" + @echo " install-deps - Install build dependencies (CPU with Vulkan for Windows AMD64)" + @echo " build-dir - Print build directory path" + @echo " install-dir - Print install directory path" + @echo " clean - Clean build artifacts" + @echo " help - Show this help"