Files
prevara/scripts/update-gio.sh

354 lines
15 KiB
Bash
Executable File

#!/bin/bash
# Script to update the vendored gioui.org package
#
# Usage: ./scripts/update-gio.sh [version]
# version: optional gio version (default: latest)
#
# Example:
# ./scripts/update-gio.sh # Update to latest
# ./scripts/update-gio.sh v0.9.0 # Update to specific version
#
# IMPORTANT: After updating, you must re-apply the CGO build constraint patches.
# See the "Patching for cross-compilation" section below.
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(dirname "$SCRIPT_DIR")"
GIO_DIR="$REPO_ROOT/gio"
VERSION="${1:-latest}"
echo "Updating vendored gio to version: $VERSION"
# Determine the module path to download
if [ "$VERSION" = "latest" ]; then
MODULE="gioui.org@latest"
else
MODULE="gioui.org@$VERSION"
fi
# Download the module to get its path
echo "Downloading $MODULE..."
MOD_PATH=$(go mod download -json "$MODULE" | grep -o '"Dir": "[^"]*"' | cut -d'"' -f4)
if [ -z "$MOD_PATH" ]; then
echo "Error: Failed to download module"
exit 1
fi
echo "Module downloaded to: $MOD_PATH"
# Get the actual version
ACTUAL_VERSION=$(go mod download -json "$MODULE" | grep -o '"Version": "[^"]*"' | cut -d'"' -f4)
echo "Actual version: $ACTUAL_VERSION"
# Remove old gio directory
echo "Removing old gio directory..."
rm -rf "$GIO_DIR"
# Copy new gio
echo "Copying new gio..."
mkdir -p "$GIO_DIR"
cp -r "$MOD_PATH"/* "$GIO_DIR"/
# Fix permissions (module cache files are read-only)
echo "Fixing permissions..."
chmod -R u+w "$GIO_DIR"
# Apply CGO build constraint patches for cross-compilation support
echo "Applying CGO build constraint patches..."
# Patch files that require CGO to add cgo build constraint
patch_file() {
local file="$1"
local old_constraint="$2"
local new_constraint="$3"
if [ -f "$file" ]; then
sed -i "s|$old_constraint|$new_constraint|" "$file"
echo " Patched: $file"
fi
}
# app/os_darwin.go - add cgo constraint
if [ -f "$GIO_DIR/app/os_darwin.go" ]; then
# Add build constraint at the top of the file
sed -i '1a\//go:build darwin \&\& cgo\n// +build darwin,cgo' "$GIO_DIR/app/os_darwin.go"
echo " Patched: app/os_darwin.go"
fi
# app/os_macos.go
patch_file "$GIO_DIR/app/os_macos.go" \
"//go:build darwin && !ios" \
"//go:build darwin \&\& !ios \&\& cgo"
# app/os_ios.go
patch_file "$GIO_DIR/app/os_ios.go" \
"//go:build darwin && ios" \
"//go:build darwin \&\& ios \&\& cgo"
# internal/gl/gl_unix.go
patch_file "$GIO_DIR/internal/gl/gl_unix.go" \
"//go:build darwin || linux || freebsd || openbsd" \
"//go:build (darwin || linux || freebsd || openbsd) \&\& cgo"
# internal/vk/vulkan.go
patch_file "$GIO_DIR/internal/vk/vulkan.go" \
"//go:build linux || freebsd" \
"//go:build (linux || freebsd || android) \&\& cgo"
# internal/vk/vulkan_android.go
patch_file "$GIO_DIR/internal/vk/vulkan_android.go" \
"//go:build !nowayland" \
"//go:build android \&\& cgo"
# app/vulkan.go, vulkan_android.go, vulkan_wayland.go, vulkan_x11.go
for f in vulkan.go vulkan_android.go vulkan_wayland.go vulkan_x11.go; do
if [ -f "$GIO_DIR/app/$f" ]; then
# Add cgo to build constraints
sed -i 's/!novulkan$/!novulkan \&\& cgo/' "$GIO_DIR/app/$f"
echo " Patched: app/$f"
fi
done
# gpu/internal/vulkan/vulkan.go
patch_file "$GIO_DIR/gpu/internal/vulkan/vulkan.go" \
"//go:build (linux || freebsd) && !novulkan" \
"//go:build (linux || freebsd || android) \&\& !novulkan \&\& cgo"
# gpu/headless/headless_vulkan.go
patch_file "$GIO_DIR/gpu/headless/headless_vulkan.go" \
"//go:build (linux || freebsd) && !novulkan" \
"//go:build (linux || freebsd) \&\& !novulkan \&\& cgo"
# internal/vk/vulkan_wayland.go and vulkan_x11.go
for f in vulkan_wayland.go vulkan_x11.go; do
if [ -f "$GIO_DIR/internal/vk/$f" ]; then
# Add cgo to build constraints
sed -i 's/!nowayland$\|!nox11$/& \&\& cgo/' "$GIO_DIR/internal/vk/$f"
echo " Patched: internal/vk/$f"
fi
done
# Create stub files for platforms without CGO
echo "Creating stub files for non-CGO builds..."
# Darwin stub
cat > "$GIO_DIR/app/os_darwin_nocgo.go" << 'EOF'
// SPDX-License-Identifier: Unlicense OR MIT
//go:build darwin && !cgo
// +build darwin,!cgo
package app
func osMain() {
panic("gioui: CGO is required for darwin/macOS/iOS builds")
}
func newWindow(win *callbacks, options []Option) {
panic("gioui: CGO is required for darwin/macOS/iOS builds")
}
EOF
echo " Created: app/os_darwin_nocgo.go"
# GL Unix stub
cat > "$GIO_DIR/internal/gl/gl_unix_nocgo.go" << 'EOF'
// SPDX-License-Identifier: Unlicense OR MIT
//go:build (darwin || linux || freebsd || openbsd) && !cgo && !js
// +build darwin linux freebsd openbsd
// +build !cgo
// +build !js
package gl
import (
"errors"
"unsafe"
)
type Context interface{}
type Functions struct{}
func NewFunctions(ctx Context, forceES bool) (*Functions, error) {
return nil, errors.New("gl: CGO is required for OpenGL on this platform")
}
func (f *Functions) ActiveTexture(texture Enum) {}
func (f *Functions) AttachShader(p Program, s Shader) {}
func (f *Functions) BeginQuery(target Enum, query Query) {}
func (f *Functions) BindAttribLocation(p Program, a Attrib, name string) {}
func (f *Functions) BindBuffer(target Enum, b Buffer) {}
func (f *Functions) BindBufferBase(target Enum, index int, b Buffer) {}
func (f *Functions) BindFramebuffer(target Enum, fb Framebuffer) {}
func (f *Functions) BindImageTexture(unit int, t Texture, level int, layered bool, layer int, access, format Enum) {}
func (f *Functions) BindRenderbuffer(target Enum, rb Renderbuffer) {}
func (f *Functions) BindTexture(target Enum, t Texture) {}
func (f *Functions) BindVertexArray(a VertexArray) {}
func (f *Functions) BlendEquation(mode Enum) {}
func (f *Functions) BlendFuncSeparate(srcRGB, dstRGB, srcA, dstA Enum) {}
func (f *Functions) BlitFramebuffer(sx0, sy0, sx1, sy1, dx0, dy0, dx1, dy1 int, mask Enum, filter Enum) {}
func (f *Functions) BufferData(target Enum, size int, usage Enum, data []byte) {}
func (f *Functions) BufferSubData(target Enum, offset int, data []byte) {}
func (f *Functions) CheckFramebufferStatus(target Enum) Enum { return 0 }
func (f *Functions) Clear(mask Enum) {}
func (f *Functions) ClearColor(red, green, blue, alpha float32) {}
func (f *Functions) ClearDepthf(d float32) {}
func (f *Functions) CompileShader(s Shader) {}
func (f *Functions) CopyTexSubImage2D(target Enum, level, xoffset, yoffset, x, y, w, h int) {}
func (f *Functions) CreateBuffer() Buffer { return Buffer{} }
func (f *Functions) CreateFramebuffer() Framebuffer { return Framebuffer{} }
func (f *Functions) CreateProgram() Program { return Program{} }
func (f *Functions) CreateQuery() Query { return Query{} }
func (f *Functions) CreateRenderbuffer() Renderbuffer { return Renderbuffer{} }
func (f *Functions) CreateShader(ty Enum) Shader { return Shader{} }
func (f *Functions) CreateTexture() Texture { return Texture{} }
func (f *Functions) CreateVertexArray() VertexArray { return VertexArray{} }
func (f *Functions) DeleteBuffer(v Buffer) {}
func (f *Functions) DeleteFramebuffer(v Framebuffer) {}
func (f *Functions) DeleteProgram(p Program) {}
func (f *Functions) DeleteQuery(query Query) {}
func (f *Functions) DeleteRenderbuffer(v Renderbuffer) {}
func (f *Functions) DeleteShader(s Shader) {}
func (f *Functions) DeleteTexture(v Texture) {}
func (f *Functions) DeleteVertexArray(a VertexArray) {}
func (f *Functions) DepthFunc(fn Enum) {}
func (f *Functions) DepthMask(mask bool) {}
func (f *Functions) Disable(cap Enum) {}
func (f *Functions) DisableVertexAttribArray(a Attrib) {}
func (f *Functions) DispatchCompute(x, y, z int) {}
func (f *Functions) DrawArrays(mode Enum, first, count int) {}
func (f *Functions) DrawElements(mode Enum, count int, ty Enum, offset int) {}
func (f *Functions) Enable(cap Enum) {}
func (f *Functions) EnableVertexAttribArray(a Attrib) {}
func (f *Functions) EndQuery(target Enum) {}
func (f *Functions) Finish() {}
func (f *Functions) Flush() {}
func (f *Functions) FramebufferRenderbuffer(target, attachment, renderbuffertarget Enum, renderbuffer Renderbuffer) {}
func (f *Functions) FramebufferTexture2D(target, attachment, texTarget Enum, t Texture, level int) {}
func (f *Functions) GenerateMipmap(target Enum) {}
func (f *Functions) GetBinding(pname Enum) Object { return Object{} }
func (f *Functions) GetBindingi(pname Enum, idx int) Object { return Object{} }
func (f *Functions) GetError() Enum { return NO_ERROR }
func (f *Functions) GetFloat(pname Enum) float32 { return 0 }
func (f *Functions) GetFloat4(pname Enum) [4]float32 { return [4]float32{} }
func (f *Functions) GetFramebufferAttachmentParameteri(target, attachment, pname Enum) int { return 0 }
func (f *Functions) GetInteger(pname Enum) int { return 0 }
func (f *Functions) GetInteger4(pname Enum) [4]int { return [4]int{} }
func (f *Functions) GetIntegeri(pname Enum, idx int) int { return 0 }
func (f *Functions) GetProgramBinary(p Program) []byte { return nil }
func (f *Functions) GetProgrami(p Program, pname Enum) int { return 0 }
func (f *Functions) GetProgramInfoLog(p Program) string { return "" }
func (f *Functions) GetQueryObjectuiv(query Query, pname Enum) uint { return 0 }
func (f *Functions) GetRenderbufferParameteri(target, pname Enum) int { return 0 }
func (f *Functions) GetShaderi(s Shader, pname Enum) int { return 0 }
func (f *Functions) GetShaderInfoLog(s Shader) string { return "" }
func (f *Functions) GetString(pname Enum) string { return "" }
func (f *Functions) GetStringi(pname Enum, index int) string { return "" }
func (f *Functions) GetUniformBlockIndex(p Program, name string) uint { return INVALID_INDEX }
func (f *Functions) GetUniformLocation(p Program, name string) Uniform { return Uniform{V: -1} }
func (f *Functions) GetVertexAttrib(index int, pname Enum) int { return 0 }
func (f *Functions) GetVertexAttribBinding(index int, pname Enum) Object { return Object{} }
func (f *Functions) GetVertexAttribPointer(index int, pname Enum) uintptr { return 0 }
func (f *Functions) InvalidateFramebuffer(target, attachment Enum) {}
func (f *Functions) IsEnabled(cap Enum) bool { return false }
func (f *Functions) LinkProgram(p Program) {}
func (f *Functions) MapBufferRange(target Enum, offset, length int, access Enum) []byte { return nil }
func (f *Functions) MemoryBarrier(barriers Enum) {}
func (f *Functions) PixelStorei(pname Enum, param int) {}
func (f *Functions) ReadPixels(x, y, width, height int, format, ty Enum, data []byte) {}
func (f *Functions) RenderbufferStorage(target, internalformat Enum, width, height int) {}
func (f *Functions) Scissor(x, y, width, height int) {}
func (f *Functions) ShaderSource(s Shader, src string) {}
func (f *Functions) TexImage2D(target Enum, level int, internalFormat Enum, width, height int, format, ty Enum) {}
func (f *Functions) TexParameteri(target, pname Enum, param int) {}
func (f *Functions) TexStorage2D(target Enum, levels int, internalFormat Enum, width, height int) {}
func (f *Functions) TexSubImage2D(target Enum, level, xoff, yoff, width, height int, format, ty Enum, data []byte) {}
func (f *Functions) Uniform1f(dst Uniform, v float32) {}
func (f *Functions) Uniform1i(dst Uniform, v int) {}
func (f *Functions) Uniform2f(dst Uniform, v0, v1 float32) {}
func (f *Functions) Uniform3f(dst Uniform, v0, v1, v2 float32) {}
func (f *Functions) Uniform4f(dst Uniform, v0, v1, v2, v3 float32) {}
func (f *Functions) UniformBlockBinding(p Program, uniformBlockIndex uint, uniformBlockBinding uint) {}
func (f *Functions) UnmapBuffer(target Enum) bool { return false }
func (f *Functions) UseProgram(p Program) {}
func (f *Functions) VertexAttribPointer(dst Attrib, size int, ty Enum, normalized bool, stride, offset int) {}
func (f *Functions) Viewport(x, y, width, height int) {}
func uploadBuffer(data []byte) *byte { return nil }
func sliceOf(ptr unsafe.Pointer, cap int) []byte { return nil }
EOF
echo " Created: internal/gl/gl_unix_nocgo.go"
# VK stub
cat > "$GIO_DIR/internal/vk/vulkan_nocgo.go" << 'EOF'
// SPDX-License-Identifier: Unlicense OR MIT
//go:build (linux || freebsd || android) && !cgo
// +build linux freebsd android
// +build !cgo
package vk
import (
"errors"
"unsafe"
)
type (
Instance uintptr
Surface uintptr
)
func CreateInstance(name string, exts ...string) (Instance, error) {
return 0, errors.New("vulkan: CGO is required")
}
func DestroyInstance(inst Instance) {}
func CreateAndroidSurface(inst Instance, window unsafe.Pointer) (Surface, error) {
return 0, errors.New("vulkan: CGO is required for Android")
}
func CreateWaylandSurface(inst Instance, display, surface uintptr) (Surface, error) {
return 0, errors.New("vulkan: CGO is required for Wayland")
}
func CreateXlibSurface(inst Instance, display, window uintptr) (Surface, error) {
return 0, errors.New("vulkan: CGO is required for X11")
}
func DestroySurface(inst Instance, surface Surface) {}
func GetPhysicalDeviceQueueFamilyPropertiesCount(pd uintptr) int {
return 0
}
func GetPhysicalDeviceSurfaceSupport(pd uintptr, queue uint32, surf Surface) bool {
return false
}
EOF
echo " Created: internal/vk/vulkan_nocgo.go"
# Update go.mod
echo "Updating go.mod..."
cd "$REPO_ROOT"
go mod tidy
echo ""
echo "Successfully updated gio to $ACTUAL_VERSION"
echo ""
echo "The go.mod replace directive points to ./gio"
echo ""
echo "Cross-compilation support:"
echo " - Linux: Full support (native CGO)"
echo " - macOS: Compiles without CGO, but panics at runtime"
echo " - Windows: Full support (pure Go)"
echo " - WASM: Full support (pure Go)"
echo " - Android: Requires CGO cross-compiler (NDK)"
echo ""
echo "Note: Some external dependencies (clipboard, typesetting) may have their own"
echo "platform limitations that are outside the scope of this vendoring."