ไปสร้างอะไร? (ไปสร้างกับไปติดตั้ง)


106

โปรแกรมเมอร์ New Go มักไม่ทราบหรือสับสนว่าคำสั่ง go build พื้นฐานทำอะไร

สร้างgo buildและgo installคำสั่งอะไรกันแน่และพวกเขาวางผลลัพธ์ / เอาต์พุตไว้ที่ไหน


คำตอบ:


125

สิ่งที่goคำสั่งทำขึ้นอยู่กับว่าเราเรียกใช้สำหรับแพ็คเกจ "ปกติ" หรือสำหรับ"main"แพ็คเกจพิเศษ

สำหรับแพ็คเกจ

  • go build  สร้างแพคเกจของคุณแล้วทิ้งผล
  • go installสร้างจากนั้นติดตั้งแพ็คเกจใน$GOPATH/pkgไดเร็กทอรีของคุณ

สำหรับคำสั่ง (แพ็คเกจmain)

  • go build  สร้างคำสั่งและออกผลในไดเรกทอรีการทำงานปัจจุบัน
  • go install$GOPATH/binสร้างคำสั่งในไดเรกทอรีชั่วคราวแล้วย้ายไปยัง

ต้องผ่านgo buildอะไรบ้าง?

คุณสามารถส่งผ่านแพ็คเกจไปยังgo buildแพ็คเกจที่คุณต้องการสร้าง นอกจากนี้คุณยังสามารถส่งผ่านรายการ.goไฟล์จากไดเร็กทอรีเดียวซึ่งจะถือว่าเป็นรายการไฟล์ต้นฉบับที่ระบุแพ็กเกจเดียว

หากไม่มีการจัดเตรียมแพ็กเกจ (พา ธ การนำเข้า) บิวด์จะถูกนำไปใช้กับไดเร็กทอรีปัจจุบัน

เส้นทางการนำเข้าอาจมี"..."สัญลักษณ์แทนอย่างน้อยหนึ่งตัว(ซึ่งในกรณีนี้จะเป็นรูปแบบ ) ...สามารถจับคู่สตริงใดก็ได้เช่นnet/...จับคู่netแพ็กเกจและแพ็กเกจที่อยู่ในโฟลเดอร์ย่อยใด ๆ คำสั่ง

go build ./...

มักใช้ในการสร้างแพ็คเกจในโฟลเดอร์ปัจจุบันและแพ็กเกจทั้งหมดจะถูกเรียกซ้ำ คำสั่งนี้ที่ออกในรูทโปรเจ็กต์จะสร้างโปรเจ็กต์ที่สมบูรณ์

go help packagesสำหรับข้อมูลเพิ่มเติมเกี่ยวกับแพคเกจระบุวิ่ง

เกี่ยวกับโมดูล

การสนับสนุนเบื้องต้นสำหรับโมดูล Go ได้รับการแนะนำใน Go 1.11 และโมดูลกลายเป็นค่าเริ่มต้นโดยเริ่มจาก Go 1.13 เมื่อgoเรียกใช้เครื่องมือจากโฟลเดอร์ที่มีgo.modไฟล์ (หรือหนึ่งในพาเรนต์ของโฟลเดอร์ปัจจุบัน) goเครื่องมือจะทำงานในโหมดรับรู้โมดูล (โหมดเดิมเรียกว่าโหมด GOPATH )

ในโหมดรับรู้โมดูล GOPATH ไม่ได้กำหนดความหมายของการนำเข้าในระหว่างการสร้างอีกต่อไป แต่ยังคงเก็บการอ้างอิงที่ดาวน์โหลด (ใน GOPATH / pkg / mod) และคำสั่งที่ติดตั้ง (ใน GOPATH / bin เว้นแต่จะตั้งค่า GOBIN ไว้)

เมื่อมีการสร้างโมดูลสิ่งที่ถูกสร้างขึ้นจะถูกกำหนดโดยการสร้างรายการ รายการบิลด์เริ่มแรกมีเฉพาะโมดูลหลัก (โมดูลที่มีไดเร็กทอรีที่goรันคำสั่ง) และการอ้างอิงของโมดูลหลักจะถูกเพิ่มลงในรายการบิลด์แบบวนซ้ำ (เพิ่มการอ้างอิงของการอ้างอิงด้วย)

go help modulesสำหรับข้อมูลเพิ่มเติมให้เรียกใช้


โดยทั่วไปคุณสามารถใช้go buildเพื่อตรวจสอบว่าสามารถสร้างแพ็คเกจได้ (พร้อมกับการอ้างอิง) ในขณะที่go install(ถาวร) ติดตั้งผลลัพธ์ในโฟลเดอร์ที่เหมาะสมของไฟล์$GOPATH.

go build จะยุติโดยเงียบหากทุกอย่างเรียบร้อยและจะให้ข้อความแสดงข้อผิดพลาดแก่คุณหากไม่สามารถสร้าง / คอมไพล์แพ็กเกจได้

เมื่อใดก็ตามที่goเครื่องมือติดตั้งแพ็กเกจหรือไบนารีเครื่องมือนั้นจะติดตั้งการอ้างอิงใด ๆ ก็ตามที่มีดังนั้นการรันgo installจะติดตั้งแพ็กเกจที่โปรแกรมของคุณขึ้นอยู่กับ (พร้อมใช้งานแบบสาธารณะแพ็คเกจ "go gettable") โดยอัตโนมัติ

สำหรับการเริ่มต้นอย่างเป็นทางการอ่านวิธีการเขียนรหัสไปหน้า

ข้อมูลเพิ่มเติมเกี่ยวกับgoเครื่องมือ: Command go

คุณยังสามารถขอความช่วยเหลือเพิ่มเติมได้โดยเรียกใช้คำสั่งต่อไปนี้:

go help build

นอกจากนี้ยังเป็นที่น่าสังเกตว่าการเริ่มต้นด้วย Go 1.5 go installจะลบไฟล์ปฏิบัติการที่สร้างโดยgo build(ที่มา ):

หาก 'go install' (โดยไม่มีอาร์กิวเมนต์หมายถึงไดเร็กทอรีปัจจุบัน) สำเร็จให้ลบไฟล์ปฏิบัติการที่เขียนโดย "go build" ออกหากมี สิ่งนี้หลีกเลี่ยงการทิ้งไบนารีเก่าไว้เบื้องหลัง ...

ในการทำรายการให้เสร็จสมบูรณ์ให้go runรวบรวมแอปพลิเคชันของคุณไว้ในโฟลเดอร์ชั่วคราวและเริ่มไบนารีที่ปฏิบัติการได้ เมื่อแอปออกไปแอปจะล้างไฟล์ชั่วคราวอย่างเหมาะสม

คำถามที่ได้รับแรงบันดาลใจจาก Dave Cheney's What does go build build?


1
ดูเหมือนแปลกที่ go install ไม่อัปเดตไฟล์ปฏิบัติการหากเหมือนกับที่ติดตั้งไว้ก่อนหน้านี้ ... มีข้อมูลเชิงลึกที่นี่ไหม
Scott Stensland

14

สำหรับแพ็คเกจ:

go build: สร้างแพ็คเกจของคุณจากนั้นทิ้งผลลัพธ์

ที่จะไม่เป็นจริงหลังจากไป 1.10 (ไตรมาสที่ 1 ปี 2018) ขอบคุณ CL 68116และCL 75473 ดูหัวข้อนี้ที่ฉันอ้างอิงที่นี่

go buildและgo installคำสั่งสร้างอะไรกันแน่

เมื่อใดก็ตามที่เครื่องมือ go ติดตั้งแพ็กเกจหรือไบนารีมันจะติดตั้งการอ้างอิงใด ๆ ก็ตามที่มีดังนั้นการรัน go install จะติดตั้งแพ็กเกจที่โปรแกรมของคุณขึ้นอยู่กับ (พร้อมใช้งานแบบสาธารณะแพ็คเกจ "go gettable") โดยอัตโนมัติ

จริงๆแล้ว ... go installจะเปลี่ยนไปด้วย Go 1.10 นอกเหนือจากแคชใหม่:

ว่า " go installคำสั่ง" ไม่ได้ติดตั้งการอ้างอิงของแพคเกจชื่อ ( CL 75850 )

ถ้าคุณเรียกใช้ " go install foo" fooสิ่งเดียวที่มีการติดตั้ง

ก่อนหน้านี้มันหลากหลาย หากการอ้างอิงล้าสมัย " go install" จะติดตั้งการอ้างอิงด้วย
การติดตั้งการอ้างอิงโดยปริยายระหว่าง " go install" ทำให้เกิดความสับสนและปวดหัวอย่างมากสำหรับผู้ใช้ แต่ก่อนหน้านี้จำเป็นต้องเปิดใช้งานการสร้างแบบเพิ่มหน่วย
ไม่อีกแล้ว.
เราคิดว่าความหมายใหม่ " install what I said" จะเข้าใจได้ง่ายขึ้นมากโดยเฉพาะอย่างยิ่งเนื่องจากมีความชัดเจนจากรายงานข้อบกพร่องที่ผู้ใช้หลายคนคาดหวังไว้แล้ว
การติดตั้งการอ้างอิงในระหว่างการ "บังคับgo install" ให้ใช้ใหม่ " go install -i"โดยการเปรียบเทียบกับ " go build -i" และ " go test -i"

ความจริงที่ว่า " go install" ใช้เพื่อติดตั้งการอ้างอิงที่สร้างขึ้นใหม่ทำให้เกิดความสับสนบ่อยที่สุดเมื่อใช้ร่วมกับ-aซึ่งหมายถึง " force rebuild of all dependencies"
ตอนนี้ " go install -a myprog" จะบังคับให้สร้างการอ้างอิงทั้งหมดขึ้นใหม่ทั้งหมดmyprogรวมทั้งmyprogตัวมันเอง แต่myprogจะได้รับการติดตั้งเท่านั้น (การอ้างอิงที่สร้างขึ้นใหม่ทั้งหมดจะยังคงถูกบันทึกไว้ใน
บิลด์แคชแน่นอน) การทำให้เคสนี้ทำงานได้อย่างเข้าใจมากขึ้นเป็นสิ่งสำคัญอย่างยิ่งเมื่อใช้ร่วมกับการวิเคราะห์ความล้าสมัยตามเนื้อหาเนื่องจากเห็นเหตุผลที่ดีในการสร้างการอ้างอิงใหม่บ่อยกว่าเดิม ซึ่งจะเพิ่มจำนวนความสับสน "เหตุใดการอ้างอิงของฉันจึงได้รับการติดตั้ง"
ตัวอย่างเช่นหากคุณเรียกใช้ " go install -gcflags=-N myprog" นั่นจะเป็นการติดตั้งไฟล์myprogสร้างขึ้นโดยไม่มีการปรับแต่งคอมไพลเลอร์ แต่จะไม่ติดตั้งแพ็กเกจที่myprogใช้จากไลบรารีมาตรฐานอีกต่อไปโดยไม่มีการปรับแต่งคอมไพลเลอร์


ไม่go buildทำget? cannot find package "github.com/spf13/cobra" in any of:…ผมได้สร้างข้อผิดพลาด ไม่รู้จะบอกยังไงถึงจะได้ ฉันจำเป็นต้องได้รับอย่างชัดเจนหรือไม่?
ctrl-alt-delor

@ ctrl-alt-delor กับ Go รุ่นไหน? โครงการของคุณมีgo.modไฟล์อยู่หรือไม่
VonC

go version go1.11.4 linux/amd64. ไม่รู้เรื่อง go.mod ฉันกำลังสร้างใหม่https://github.com/cbroglie/mustache/blob/master/cmd/mustache/main.goมันแปลกเพราะฉันเพิ่งสร้างแพ็คเกจทั้งหมดและใช้ตัวอย่างนี้เป็นฐานและฉันได้สร้างเวอร์ชันพื้นฐานที่ใช้งานได้ (แต่ไม่ได้ใช้ไลบรารีนี้) ฉันไม่เห็นว่ามันไม่ได้ติดตั้งกับแพ็คเกจหนวด
ctrl-alt-delor

@ Ctrl-Alt-Delor เพื่อ cobr เป็น vendored github.com/cbroglie/mustache/tree/master/cmd/mustache/vendor/... GOPATH ของคุณตั้งค่าถูกต้องหรือไม่?
VonC

ฉันได้ค้นพบสิ่งที่คุณพบแล้ว แพคเกจอยู่ในไดเร็กทอรีย่อยของผู้จำหน่าย: นี่คือสาเหตุที่ไม่ได้รับการติดตั้ง อย่างไรก็ตามฉันไม่รู้ว่าทำไมถึงไม่ติดตั้งตอนนี้ในบิลด์ หรือวิธีใช้ไดเร็กทอรีผู้ขาย (ถ้าฉันคัดลอกไปยังไดเร็กทอรีของฉัน)
ctrl-alt-delor
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.