Ошибка "package XXX is not in GOROOT" при сборке Go-проекта
Проблема: вы используете устаревший подход без модулей
Ошибка возникает, потому что Go не знает, где искать ваш пакет myapp/utils. В современных версиях Go (1.11+) стандартный способ работы — через Go modules, которые заменяют старую систему с GOPATH. Без модуля Go ищет пакеты только в GOROOT (стандартная библиотека) и GOPATH (ваши проекты, но с определённой структурой).
Решение: инициализируйте модуль
Сделайте корневую папку вашего проекта модулем:
cd ~/projects/myapp
go mod init myapp
Эта команда создаст файл go.mod с содержимым:
module myapp
go 1.21
Теперь Go понимает, что myapp — это имя вашего модуля, и все импорты вида import "myapp/utils" будут искаться внутри этого модуля.
Как теперь собирать проект
Есть два правильных способа:
go build .— собирает текущий пакет (все .go файлы в папке, включая main.go).go build ./...— собирает все пакеты проекта рекурсивно.go run .— запускает без явной сборки.
Почему не работает go build main.go
Когда вы указываете конкретный файл, Go пытается собрать один файл изолированно, игнорируя модуль. Для проектов с несколькими файлами/пакетами всегда используйте сборку пакета (через точку . или путь).
Дополнительные советы для новичков
- Не трогайте
GOPATHиGO111MODULE— современный Go сам всё настраивает. - Файл
go.modдолжен быть в корне проекта, а не в подпапках. - Имена пакетов внутри модуля должны совпадать с именами папок (но это не строгое правило, просто конвенция).
- Внешние зависимости (например, сторонние библиотеки) автоматически подтянутся в
go.sumпри первомgo buildилиgo mod tidy.
Пример правильной структуры после исправления
myapp/
├── go.mod (содержит "module myapp")
├── main.go (import "myapp/utils")
└── utils/
└── helper.go (package utils)
Теперь команды go build . и go run . будут работать без ошибок.
Альтернативный подход: используйте относительные пути в импортах (не рекомендуется)
Если по каким-то причинам вы не хотите использовать модули (например, для очень простых скриптов), можно заменить импорт на относительный путь. Однако это плохая практика и работает только внутри одного проекта:
// main.go
package main
import "./utils"
func main() {
utils.SayHello()
}
Но такой подход сломается, если вы переместите папку проекта или попытаетесь использовать внешние зависимости. В современном Go (1.16+) относительные импорты даже запрещены по умолчанию, и их нужно явно включать через флаг -mod=mod.
Лучшее решение: всегда используйте Go modules
Даже для самых маленьких проектов делайте go mod init. Это занимает 2 секунды и избавляет от кучи проблем. Модули — стандарт де-факто с 2019 года, все инструменты (IDE, линтеры, CI/CD) ожидают именно такую структуру.
Ответов пока нет.
Войдите чтобы оставить ответ
Блоги