Как выполнить кросс-компиляцию Go программы на macOS?
Пошаговое решение кросс-компиляции в Go на macOS
Вы на правильном пути! Go действительно имеет встроенную поддержку кросс-компиляции без установки дополнительных тулчейнов (если не используете CGo). Ваша ошибка скорее всего связана с тем, что вы выполняете команду не в той директории или используете относительный путь. Давайте разберем всё по порядку.
1. Базовая кросс-компиляция (без CGo)
Для Go-программ, которые не используют CGo (то есть не подключают C-библиотеки), всё работает из коробки. Вот правильные команды для вашего случая:
# Перейдите в директорию с main.go
cd /path/to/your/project
# Для Linux (64-bit)
GOOS=linux GOARCH=amd64 go build -o myapp-linux main.go
# Для Windows (64-bit)
GOOS=windows GOARCH=amd64 go build -o myapp.exe main.go
# Для macOS (Intel)
GOOS=darwin GOARCH=amd64 go build -o myapp-mac main.go
# Для macOS (Apple Silicon M1/M2)
GOOS=darwin GOARCH=arm64 go build -o myapp-mac-arm64 main.go
Обратите внимание на флаг -o — он указывает имя выходного файла. Если его не указать, Go создаст файл с именем директории (или "main" для Windows). Также убедитесь, что вы находитесь в корневой папке модуля (где лежит go.mod).
2. Возможные проблемы и их решения
- Ошибка "cannot find package" — скорее всего вы запускаете команду не из той папки. Убедитесь, что файл
main.goлежит в текущей директории. Выполнитеlsчтобы проверить. - Бинарник не запускается на Linux — проверьте права доступа:
chmod +x myapp-linux. Также убедитесь, что целевая система имеет ту же архитектуру (amd64). - Ошибки с CGo — если ваш код использует C-библиотеки (например, через
import "C"), вам понадобится кросстулчейн. Для этого установитеbrew install FiloSottile/musl-cross/musl-crossи используйтеCC=x86_64-linux-musl-gcc CGO_ENABLED=1.
3. Продвинутый вариант: Makefile для автоматизации
Чтобы не запоминать все команды, создайте Makefile в корне проекта:
.PHONY: build-all
build-all:
GOOS=linux GOARCH=amd64 go build -o bin/myapp-linux main.go
GOOS=windows GOARCH=amd64 go build -o bin/myapp.exe main.go
GOOS=darwin GOARCH=amd64 go build -o bin/myapp-darwin main.go
@echo "Build complete for all platforms!"
Теперь просто запускайте make build-all и все бинарники будут в папке bin/.
4. Проверка результата
Чтобы убедиться, что бинарник собран для нужной платформы, используйте команду file:
$ file myapp-linux
myapp-linux: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped
$ file myapp.exe
myapp.exe: PE32+ executable (console) x86-64 (stripped to external PDB), for MS Windows
Если видите ELF — это Linux, PE — Windows, Mach-O — macOS. Всё работает!
<<Альтернативный подход: использование Docker для кросс-компиляции
Если вы столкнулись с проблемами при кросс-компиляции (например, из-за CGo или сложных зависимостей), можно использовать Docker. Это гарантирует, что сборка происходит в чистом окружении целевой платформы.
# Создайте Dockerfile
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN GOOS=linux GOARCH=amd64 go build -o myapp main.go
# Для запуска (опционально)
FROM alpine:latest
COPY --from=builder /app/myapp /myapp
CMD ["/myapp"]
Затем соберите образ:
docker build -t myapp-linux .
Если вам нужен только бинарник, используйте многоступенчатую сборку и скопируйте его на хост:
docker create --name temp myapp-linux
docker cp temp:/myapp ./myapp-linux
docker rm temp
Этот метод особенно полезен, когда вы работаете с CGo, системными библиотеками или нуждаетесь в точном соответствии окружению продакшена. Docker гарантирует, что бинарник собран в тех же условиях, что и на целевом сервере.