يترجم go run البرنامج ويشغّله في خطوة واحدة ولا يحتفظ بملف تنفيذي. ويترجم go build ويترك ملفًا تنفيذيًا في المجلد الحالي. ويترجم go install ويضع الملف التنفيذي في $HOME/go/bin. الثلاثة تترجم إلى شيفرة آلة أصلية؛ ولا يفسّر أي منها شيئًا.
| الأمر | يترجم | يشغّل | يحتفظ بملف تنفيذي | أين يذهب الملف التنفيذي |
|---|---|---|---|---|
go run . | نعم | نعم | لا | مجلد مؤقّت يُحذف بعد ذلك |
go build | نعم | لا | نعم | المجلد الحالي (أو -o path) |
go install | نعم | لا | نعم | $GOBIN، وإلا $GOPATH/bin |
البرنامج التالي هو المستخدم في أمثلة هذه الصفحة. يشغّله المحرّر كما يفعل go run.
go run
يأخذ go run حزمة (عادة .، أي المجلد الحالي) أو قائمة ملفات .go:
go run .
go run main.go
go run ./cmd/server
كل ما يأتي بعد الحزمة يُمرَّر إلى برنامجك كوسائط:
go run . --port 8080 verbose
version: dev
built for: linux/amd64
args: [--port 8080 verbose]
فضّل go run . على go run main.go. تسمية ملف تترجم ذلك الملف وحده، فبمجرّد أن يصير للحزمة ملف ثانٍ، يُبلَّغ عن الدوال المعرّفة فيه بأنها undefined. صفحة الحزم والاستيراد تشرح هذا الخطأ بالتفصيل.
يشغّل go run أيضًا برنامجًا بعيدًا بإصدار محدّد دون تثبيته، وهذا مفيد لمولّدات الشيفرة:
go run golang.org/x/tools/cmd/stringer@v0.30.0 -type=Color
go build
يترجم go build الحزمة الموجودة في المجلد الحالي. لحزمة main يكتب ملفًا تنفيذيًا؛ ولحزمة مكتبة يترجمها ويبلغ عن الأخطاء ويتخلّص من النتيجة.
go mod init example.com/hello
go build
ls
go.mod hello main.go
يتبع اسم الملف التنفيذي هذه القواعد:
| ما تشغّله | اسم الملف التنفيذي |
|---|---|
go build في الوحدة example.com/hello | hello |
go build ./cmd/server | server |
go build main.go | main (باسم الملف الأول) |
go build -o bin/app . | bin/app |
أي مما سبق مع GOOS=windows | الاسم نفسه مع .exe |
شكلان آخران ستستخدمهما باستمرار:
go build ./... # compile every package in the module
go vet ./... # static checks, covered below
تعني ./... "هذا المجلد وكل مجلد تحته". وgo build ./... مع عدة حزم main لا يكتب أي ملف تنفيذي؛ إنه فحص سريع لسؤال "هل يُترجم كل شيء".
خيارات بناء مفيدة
| الخيار | ما يفعله |
|---|---|
-o name | ملف أو مجلد المخرجات |
-v | طباعة أسماء الحزم أثناء ترجمتها |
-race | البناء مع كاشف سباقات البيانات (أبطأ، وملف أكبر؛ للاختبار) |
-trimpath | إزالة مسارات نظام الملفات المحلية من الملف التنفيذي، لبناء قابل للتكرار |
-ldflags "-s -w" | حذف جدول الرموز ومعلومات تتبّع الأخطاء DWARF، فيصغر الملف التنفيذي |
-ldflags "-X main.version=1.4.0" | ضبط متغيّر نصي وقت الربط |
-tags name | تضمين الملفات المحميّة بقيد //go:build name |
الخيار -X هو الطريقة التي تختم بها معظم مشاريع Go رقم الإصدار في الملف التنفيذي. لا يعمل إلا على متغيّرات string على مستوى الحزمة (لا الثوابت):
go build -o app -ldflags "-X main.version=1.4.0" .
./app
version: 1.4.0
built for: linux/amd64
args: []
يسجّل الملف التنفيذي أيضًا إصدارات وحداته، ومنذ Go 1.18 الـ commit الذي بُني منه. يطبعها go version -m ./app، ويستطيع البرنامج قراءتها بـ runtime/debug.ReadBuildInfo.
go install
يبني go install تمامًا مثل go build ثم ينقل الملف التنفيذي إلى $GOBIN، أو إلى $GOPATH/bin عندما لا يكون GOBIN مضبوطًا (افتراضيًا $HOME/go/bin):
go install .
go env GOPATH
أشيع استخدام له هو تثبيت أدوات مكتوبة بـ Go. ومع @version يثبّت برنامجًا دون المساس بـ go.mod:
go install golang.org/x/tools/gopls@latest
go install honnef.co/go/tools/cmd/staticcheck@latest
إذا لم تجد الصدفة أداة بعد ذلك، فإن $HOME/go/bin ليس ضمن PATH. أضف export PATH=$PATH:$(go env GOPATH)/bin إلى ملف إعدادات الصدفة.
الترجمة لمنصّات أخرى بـ GOOS وGOARCH
تستطيع Go البناء لنظام تشغيل أو معالج آخر من أي جهاز، دون أدوات إضافية. اضبط متغيّري بيئة لأمر البناء:
GOOS=linux GOARCH=amd64 go build -o app-linux-amd64 .
GOOS=linux GOARCH=arm64 go build -o app-linux-arm64 .
GOOS=darwin GOARCH=arm64 go build -o app-macos .
GOOS=windows GOARCH=amd64 go build -o app.exe .
في PowerShell تُضبط متغيّرات البيئة بطريقة مختلفة:
$env:GOOS = "linux"; $env:GOARCH = "amd64"; go build -o app-linux .
الأزواج الأشيع:
| GOOS | GOARCH | الهدف |
|---|---|---|
linux | amd64 | معظم الخوادم والحاويات |
linux | arm64 | AWS Graviton، وRaspberry Pi بنظام 64 بت |
darwin | arm64 | أجهزة Mac بمعالجات Apple Silicon |
darwin | amd64 | أجهزة Mac بمعالجات Intel |
windows | amd64 | Windows بنظام 64 بت |
js | wasm | WebAssembly في المتصفح |
يطبع go tool dist list كل زوج مدعوم (48 في Go 1.24).
الترجمة لمنصّات أخرى بهذه السهولة فقط لشيفرة Go الخالصة. الحزمة التي تستخدم cgo (شيفرة C، مثل بعض مشغّلات SQLite) تحتاج مترجم C للمنصّة الهدف. عند الترجمة لمنصّة أخرى يكون cgo معطّلًا افتراضيًا، وضبط CGO_ENABLED=0 صراحة يعطيك أيضًا ملفًا تنفيذيًا ساكنًا بالكامل لـ Linux، وهو ما تريده في صورة حاوية مصغّرة من نوع scratch أو distroless.
go fmt وgo vet
فحصان ينتميان إلى كل سير عمل، وإلى CI.
يعيد go fmt كتابة الملفات بالأسلوب الرسمي الوحيد: مسافات جدولة، وحقول محاذاة، وتباعد موحّد. وهو غلاف حول gofmt -l -w:
go fmt ./...
gofmt -l . # list files that are not formatted; empty output means clean
يبلغ go vet عن شيفرة تُترجم لكنها خاطئة شبه يقينًا. عدم تطابق تنسيقات Printf هو المثال الكلاسيكي:
package main
import "fmt"
func main() {
count := 3
fmt.Printf("%s items\n", count)
}
go vet ./...
# example.com/hello
# [example.com/hello]
./main.go:7:2: fmt.Printf format %s has arg count of wrong type int
يُترجم البرنامج ويطبع %!s(int=3) items، وهذا بالضبط نوع الأخطاء الذي وُجد vet لاكتشافه. من فحوص vet الأخرى: نسخ sync.Mutex بالقيمة، والشيفرة التي لا يمكن الوصول إليها، ووسوم البنى ذات الصيغة الخاطئة، وcontext.CancelFunc لا تُستدعى أبدًا. يشغّل go test جزءًا من هذه الفحوص تلقائيًا؛ أما go build فلا يشغّل أيًا منها.
أوامر go فرعية أخرى
| الأمر | الغرض |
|---|---|
go test ./... | تشغيل الاختبارات |
go mod tidy | إضافة الاعتماديات الناقصة وإزالة غير المستخدمة |
go get pkg@version | إضافة اعتمادية أو تغييرها |
go clean -cache | تفريغ ذاكرة البناء المؤقّتة |
go env | طباعة إعدادات Go |
go doc fmt.Println | عرض التوثيق في الطرفية |
go list -m all | سرد كل وحدة في البناء |
لماذا يكون البناء سريعًا في المرة الثانية
تخزّن Go الحزم المترجمة في ذاكرة البناء المؤقّتة (go env GOCACHE). إعادة البناء تعيد ترجمة الحزم التي تغيّر مصدرها أو اعتمادياتها فقط، فيبدأ go run . على مشروع لم يتغيّر فورًا تقريبًا. إذا تصرّف البناء بغرابة بعد تغيير إصدار Go أو متغيّرات البيئة، يفرّغها go clean -cache؛ ونادرًا ما ستحتاج ذلك.
الأسئلة الشائعة
ما الفرق بين go run وgo build؟
يترجم go run البرنامج في مجلد مؤقّت، ويشغّله، ثم يرمي الملف التنفيذي. أما go build فيترجم البرنامج ويكتب الملف التنفيذي في المجلد الحالي لتشغّله مرة أخرى أو تنسخه إلى مكان آخر. استخدم go run أثناء التطوير وgo build عندما تحتاج الملف التنفيذي.
كيف أحدّد اسم ملف المخرجات في go build؟
استخدم -o: يكتب go build -o myapp . الملف myapp (في Windows اكتب -o myapp.exe بنفسك). دون -o يسمّي go build الملف التنفيذي باسم آخر عنصر في مسار استيراد الحزمة، أو باسم الملف الأول عندما تمرّر ملفات .go، ويضيف .exe عند البناء لـ Windows.
كيف أترجم برنامج Go لـ Linux أو Windows من جهاز آخر؟
اضبط GOOS وGOARCH للبناء: GOOS=linux GOARCH=amd64 go build -o app-linux . أو GOOS=windows GOARCH=amd64 go build . (الذي ينتج ملف .exe). لا حاجة لأدوات إضافية لشيفرة Go الخالصة. يطبع go tool dist list كل زوج مدعوم.
أين يضع go install الملف التنفيذي؟
في $GOBIN إن كان مضبوطًا، وإلا ففي $GOPATH/bin، وهو $HOME/go/bin افتراضيًا. أضف هذا المجلد إلى PATH لتشغيل الأدوات المثبّتة بأسمائها. يثبّت go install example.com/tool@latest أداة دون إضافتها إلى وحدتك.
هل يشغّل go build الأمر go vet؟
لا. يترجم go build فقط. يشغّل go test جزءًا من فحوص go vet تلقائيًا، أما المجموعة الكاملة فشغّلها بنفسك بـ go vet ./...، وعادة في CI بجوار gofmt -l ..