जाओ निर्माण: "पैकेज नहीं मिल सकता" (भले ही GOPATH सेट है)


139

भले ही मैंने GOPATHठीक से सेट किया है, फिर भी मैं अपने खुद के पैकेज खोजने के लिए "गो बिल्ड" या "गो रन" नहीं प्राप्त कर सकता हूं। मैं क्या गलत कर रहा हूं?

$ echo $GOROOT
/usr/local/go

$ echo $GOPATH
/home/mitchell/go

$ cat ~/main.go
package main
import "foobar"
func main() { }

$ cat /home/mitchell/go/src/foobar.go
package foobar

$ go build main.go
main.go:3:8: import "foobar": cannot find package

जब मैं github.com/adonovan/gopl.io/tree/master/ch1/helloworld जाता हूं, तो मैं एक ही समस्या को पूरा करता हूं । इसका कारण यह होगा कि helloworld.go नाम की कोई फाइल नहीं है। जाओ पैकेज नाम और फ़ाइल नाम के मेल से काम मिलता है।
केनी वैन

यह भी हो सकता है कि आपको गो को अपग्रेड करने की आवश्यकता हो। मेरे पास एक समान मुद्दा था जहां एक मॉड्यूल को परिभाषित करने के लिए मेरे पास go.mod का उपयोग करके मौजूदा कोड था। एक परीक्षण मशीन पर मैंने कोड डाउनलोड किया था और इसे संकलित करने की कोशिश कर रहा था लेकिन गो मुझे GOPATH से संबंधित सभी प्रकार की त्रुटियां दे रहा था और मॉड्यूल खोजने में असमर्थ था। यह गो संस्करण 1.7 था। जैसे ही मैंने गो को अपग्रेड किया, इसने बिना किसी समस्या के काम किया।
KyferEz

टाइप यह एक अप-टू-डेट स्पष्टीकरण के लिए टर्मिनल है$ go help gopath
A1rPun

जवाबों:


162

यह काम नहीं करता है क्योंकि आपकी foobar.goस्रोत फ़ाइल नामक निर्देशिका में नहीं है foobargo buildऔर go installनिर्देशिका फ़ाइलों से मेल खाने की कोशिश करें, न कि स्रोत फ़ाइलों की।

  1. $GOPATHएक मान्य निर्देशिका में सेट करें , उदाहरण के लिएexport GOPATH="$HOME/go"
  2. foobar.goकरने के लिए कदम $GOPATH/src/foobar/foobar.goऔर निर्माण ठीक काम करना चाहिए।

अतिरिक्त अनुशंसित कदम:

  1. $GOPATH/binअपने $PATHद्वारा जोड़ें :PATH="$GOPATH/bin:$PATH"
  2. main.goके एक सबफ़ोल्डर में जाएं $GOPATH/src, जैसे$GOPATH/src/test
  3. go install testअब इसमें एक निष्पादन योग्य बनाना $GOPATH/binचाहिए जिसे testआपके टर्मिनल में टाइप करके बुलाया जा सके ।

1
क्या यह बग नहीं है? मेरा GOPATH=/usr/local/go-pkgs, इसलिए गो /usr/local/go-pkgs/src/<package-name>स्रोत के लिए लग रहा है , लेकिन go getइसे अंदर डालता है /usr/local/go-pkgs/src/gopkg.in/<package-name>। मुझे अपने सभी पैकेजों को स्थापित करने के बाद मैन्युअल रूप से क्यों चलना चाहिए? वह मूर्खतापूर्ण है।
जोसिया

3
go get$GOPATH/src/यदि आप कहते हैं go get domain.com/path/to/packageकि यह अंत में समाप्त हो जाएगा तो आम तौर पर संकुल डालता है $GOPATH/src/domain.com/path/to/package। मुझे लगता है कि आप एक पैकेज लाने की कोशिश करेंगे gopkg.in? यदि ऐसा है तो पूरी तरह से व्यवहार का इरादा है और आपको बस उन्हें अपने पूरे नाम के साथ आयात करना चाहिए; जैसे कि डॉक्स मेंimport "gopkg.in/yaml.v1" भी वर्णित है
फस्मत

1
आह, मैं देख रहा हूँ। मेरी अज्ञानता को दूर करने के लिए धन्यवाद।
जोसिया

10

संपादित करें: चूंकि आपका मतलब GOPATH है, इसलिए fasmat का उत्तर देखें ( उत्कीर्णित )

जैसा कि " मैं कैसे अपना खाता खोजूं? " में उल्लेख किया गया है , आपको xxxएक निर्देशिका में पैकेज डालने की आवश्यकता है xxx

देखें भाषा की युक्ति :

package math

समान PackageNameरूप से साझा करने वाली फ़ाइलों का एक सेट पैकेज का कार्यान्वयन करता है।
एक कार्यान्वयन के लिए आवश्यक हो सकता है कि पैकेज के लिए सभी स्रोत फ़ाइलें समान निर्देशिका में रहें।

कोड संगठन का उल्लेख है:

जब एक प्रोग्राम का निर्माण होता है जो पैकेज को आयात करता है " widget" goआदेश src/pkg/widgetगो रूट के अंदर दिखता है , और तब - यदि पैकेज स्रोत नहीं मिला है - यह src/widgetक्रम में प्रत्येक कार्यक्षेत्र के अंदर खोज करता है ।

("कार्यक्षेत्र" आपके लिए एक पथ प्रविष्टि है GOPATH: यह चर आपके ' src, bin, pkg' होने के लिए कई पथों को संदर्भित कर सकता है)


(मूल उत्तर)

आपको " कैसे कोड लिखना है " में सचित्र के रूप में GOPATH~ पर जाना चाहिए , नहीं ।GOROOT

आयात विवरण को हल करने के लिए Go पथ का उपयोग किया जाता है। इसे गो / बिल्ड पैकेज में लागू और प्रलेखित किया गया है।

GOPATHवातावरण चर सूचियों स्थानों पर जाएं कोड देखने के लिए।
यूनिक्स पर, मूल्य एक बृहदान्त्र-पृथक स्ट्रिंग है।
विंडोज पर, मान एक अर्धविराम से अलग स्ट्रिंग है।
योजना 9 पर, मूल्य एक सूची है।

वह इससे अलग है GOROOT:

गो बाइनरी वितरण मान लेते हैं कि उन्हें /usr/local/go(या c:\Goविंडोज के तहत) स्थापित किया जाएगा , लेकिन उन्हें अलग स्थान पर स्थापित करना संभव है।
यदि आप ऐसा करते हैं, तो आपको GOROOTगो उपकरण का उपयोग करते समय पर्यावरण चर को उस निर्देशिका में सेट करना होगा ।


4
GOPATH की स्थापना के लिए एक लघु वीडियो परिचय भी है
Ulf Holm Nielsen

1
क्षमा करें, मैंने मूल प्रश्न संपादित कर लिया है। हर जगह मैंने कहा कि गरोठ का मतलब मेरा मतलब है GOPATH।
मिशेलसैलाड

3

TL; DR: गो सम्मेलनों का पालन करें! (सबक कठिन तरीका सीखा), पुराने गो संस्करणों की जाँच करें और उन्हें हटा दें। नवीनतम स्थापित करें।

मेरे लिए समाधान अलग था। मैंने एक साझा लिनक्स सर्वर पर काम किया और मेरे GOPATHऔर अन्य पर्यावरण चर की पुष्टि करने के बाद भी कई बार यह काम नहीं किया। मुझे 'पैकेज नहीं मिल रहा' और 'गैर-मान्यता प्राप्त आयात पथ' सहित कई त्रुटियों का सामना करना पड़ा। Golang.org पर निर्देशों द्वारा इस समाधान के साथ पुनः इंस्टॉल करने की कोशिश करने के बाद ( स्थापना रद्द भाग सहित ) अभी भी समस्याओं का सामना करना पड़ा।

मुझे यह महसूस करने के लिए कुछ समय दिया कि अभी भी एक पुराना संस्करण है जिसे अनइंस्टॉल नहीं किया गया है ( go versionफिर which goसे चल रहा है ... DAHH) जो मुझे इस प्रश्न के लिए मिला और आखिरकार हल हो गया।


2

यद्यपि स्वीकृत उत्तर पैकेज नामों के साथ निर्देशिकाओं के मिलान की आवश्यकता के बारे में अभी भी सही है, आपको वास्तव में GOPATH का उपयोग करने के बजाय गो मॉड्यूल का उपयोग करने के लिए माइग्रेट करने की आवश्यकता है। इस समस्या का सामना करने वाले नए उपयोगकर्ता GOPATH (जैसा मैं था) के उपयोग के उल्लेखों के बारे में भ्रमित हो सकते हैं, जो अब पुराने हो चुके हैं। इसलिए, मैं इस मुद्दे को साफ करने की कोशिश करूंगा और गो मॉड्यूल का उपयोग करते समय इस मुद्दे को रोकने से जुड़े मार्गदर्शन प्रदान करूंगा।

यदि आप पहले से ही गो मॉड्यूल से परिचित हैं और इस समस्या का सामना कर रहे हैं, तो नीचे मेरे और विशिष्ट अनुभागों को छोड़ दें जिनमें कुछ गो सम्मेलनों को कवर किया गया है जो अनदेखी या भूलना आसान है।

यह मार्गदर्शिका गो मॉड्यूल के बारे में सिखाती है: https://golang.org/doc/code.html

गो मॉड्यूल के साथ परियोजना संगठन

एक बार जब आप गो मॉड्यूल पर माइग्रेट हो जाते हैं, जैसा कि उस लेख में बताया गया है, वर्णित प्रोजेक्ट कोड को व्यवस्थित करें:

एक रिपॉजिटरी में एक या एक से अधिक मॉड्यूल होते हैं। एक मॉड्यूल संबंधित गो संकुल का एक संग्रह है जो एक साथ जारी किया जाता है। गो रिपॉजिटरी में आम तौर पर केवल एक मॉड्यूल होता है, जो रिपॉजिटरी के मूल में स्थित होता है। Go.mod नाम की एक फ़ाइल मॉड्यूल पथ की घोषणा करती है: मॉड्यूल के भीतर सभी पैकेजों के लिए आयात पथ उपसर्ग। मॉड्यूल में अपनी go.mod फ़ाइल के साथ-साथ उस निर्देशिका की उपनिर्देशिका वाली निर्देशिका में पैकेज होते हैं, अगली उपनिर्देशिका तक अन्य go.mod फ़ाइल (यदि हो तो) होती है।

प्रत्येक मॉड्यूल का पथ न केवल अपने पैकेज के लिए एक आयात पथ उपसर्ग के रूप में कार्य करता है, बल्कि यह भी इंगित करता है कि गो कमांड को इसे डाउनलोड करने के लिए कहां देखना चाहिए। उदाहरण के लिए, मॉड्यूल golang.org/x/tools को डाउनलोड करने के लिए, गो कमांड https://golang.org/x/tools (यहां वर्णित अधिक) द्वारा इंगित भंडार से परामर्श करेगा ।

एक आयात पथ एक स्ट्रिंग है जिसका उपयोग पैकेज आयात करने के लिए किया जाता है। पैकेज का आयात पथ इसका मॉड्यूल पथ है जो मॉड्यूल के भीतर अपनी उपनिर्देशिका के साथ जुड़ता है। उदाहरण के लिए, मॉड्यूल github.com/google/go-cmp में निर्देशिका cmp / में एक पैकेज होता है। उस पैकेज का आयात पथ github.com/google/go-cmp/cmp है। मानक लाइब्रेरी के पैकेज में मॉड्यूल पथ उपसर्ग नहीं होता है।

आप इस तरह से अपने मॉड्यूल को इनिशियलाइज़ कर सकते हैं:

$ go mod init github.com/mitchell/foo-app

इसे बनाने के लिए आपके कोड को github.com पर स्थित होने की आवश्यकता नहीं है। हालाँकि, अपने मॉड्यूल्स की संरचना करना सबसे अच्छा अभ्यास है क्योंकि वे अंततः प्रकाशित हो जाएंगे।

एक पैकेज पाने की कोशिश करते समय क्या होता है, यह समझना

यहां एक शानदार लेख है जो पैकेज या मॉड्यूल प्राप्त करने की कोशिश करने पर क्या होता है, इसके बारे में बात करता है: https://medium.com/rungo/anatomy-of-modules-in-go-c8274d215c16 यह चर्चा करता है कि पैकेज कहाँ संग्रहीत है और क्या होगा यदि आप पहले से ही गो मॉड्यूल का उपयोग कर रहे हैं, तो आपको यह समझने में मदद मिलेगी कि आपको यह त्रुटि क्यों हो रही है।

सुनिश्चित करें कि आयातित समारोह का निर्यात किया गया है

ध्यान दें कि यदि आपको किसी अन्य फ़ाइल से फ़ंक्शन को एक्सेस करने में समस्या हो रही है, तो आपको यह सुनिश्चित करने की आवश्यकता है कि आपने अपना फ़ंक्शन निर्यात किया है। जैसा कि मैंने पहले दिए गए लिंक में वर्णित किया है, एक फ़ंक्शन को निर्यात करने के लिए एक ऊपरी-केस पत्र के साथ शुरू होना चाहिए और अन्य पैकेजों में आयात करने के लिए उपलब्ध कराया जाना चाहिए।

निर्देशिकाओं के नाम

एक और महत्वपूर्ण विवरण (जैसा कि स्वीकृत उत्तर में बताया गया है) यह है कि निर्देशिकाओं के नाम आपके पैकेजों के नामों को परिभाषित करते हैं। (आपका पैकेज के नाम अपनी निर्देशिका नाम से मेल करने की जरूरत है।) आप यहाँ इस बात का उदाहरण देख सकते हैं: https://medium.com/rungo/everything-you-need-to-know-about-packages-in-go-b8bac62b74cc के साथ उस ने कहा, आपकी mainविधि (यानी, आपके आवेदन का प्रवेश बिंदु) वाली फाइल इस आवश्यकता से मुक्त है।

एक उदाहरण के रूप में, मुझे इस तरह की संरचना का उपयोग करते समय अपने आयातों के साथ समस्या थी:

/my-app
├── go.mod
├── /src
   ├── main.go
   └── /utils
      └── utils.go

मैं utilsअपने mainपैकेज में कोड आयात करने में असमर्थ था ।

हालाँकि, एक बार जब मैंने main.goइसकी अपनी उपनिर्देशिका में डाल दिया , जैसा कि नीचे दिखाया गया है, मेरे आयात ने ठीक काम किया:

/my-app
├── go.mod
├── /src
   ├── /app
   |  └── main.go
   └── /utils
      └── utils.go

उस उदाहरण में, मेरी go.mod फ़ाइल इस तरह दिखती है:

module git.mydomain.com/path/to/repo/my-app

go 1.14

जब मैंने एक संदर्भ जोड़ने के बाद main.go को सहेजा utils.MyFunction(), तो मेरी IDE स्वचालित रूप से इस तरह मेरे पैकेज के संदर्भ में खींची गई:

import "git.mydomain.com/path/to/repo/my-app/src/my-app"

(मैं गोल कोड के साथ वीएस कोड का उपयोग कर रहा हूं।)

ध्यान दें कि आयात पथ में पैकेज में उपनिर्देशिका शामिल थी।

एक निजी रेपो से निपटना

यदि कोड एक निजी रेपो का हिस्सा है, तो आपको एक्सेस को सक्षम करने के लिए एक git कमांड चलाना होगा। अन्यथा, आप अन्य त्रुटियों का सामना कर सकते हैं। इस लेख में उल्लेख किया गया है कि निजी गितुब, बिटबकेट, और गिटलैब रिपोज के लिए कैसे करें: https://medium.com/cloud-native-the-gathering/go-modules-ith-pStreet-git-git रिपॉजिटरी-डीएफ़ 68 ९ ५०६b डीबी ४ इस मुद्दे पर भी यहां चर्चा की गई है: निजी रिपॉजिटरी "गो टू गो" का उचित तरीका क्या है?


-6

क्या आपने अपने 'पथ' पर जाने की निरपेक्ष निर्देशिका को जोड़ने की कोशिश की है?

export PATH=$PATH:/directory/to/go/

$ PATH को गो पैकेज के लिए अपने रास्ते से कोई लेना देना नहीं है।
csgeek
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.