참고:
Go Module과 Package를 사용하는 방법이 Go Version에 따라 다를 수 있다.
아래 예제는 Go 1.17을 이용한 예제이고, 아마 Go 1.11 이상을 사용하는 경우라면 아래 설명이 잘 맞을 것이다.
여담:
나는 본업이 Go Language를 사용해서 개발하는 개발자가 아니다보니, 2~3년에 한번 잠깐 GoLang을 이용해서 개발하려고 하면 Go Package와 Module 때문에 시간을 허비하게 된다.
그래서 오늘은 기왕 스터디한 것을 2~3년 뒤에 또 GoLang을 사용할 일이 있을 경우, 쉽게 Package와 Module 개념을 습득하기 위해 예제를 통해서 메모를 할까 한다.
Go PKG를 다루기 위해서는 크게 3가지 방식이 있다.
방식 A
$GOPATH 경로를 설정하고, 이 $GOPATH 경로 안에서만 Package를 사용하는 방법. (암묵적 Module 사용하기)
방식 B <-- 가장 많은 개발자가 선호하는 방식이 아닐까 생각한다.
Module을 명시적으로 선언(go mod init x.y.z)하고, 내가 원하는 폴더 어디에서든 Go Source Code를 작성하는 방법.
방식 C
go ven를 이용해서 현재 디렉토리 하위에서 모든 Package를 사용하는 방법.
각 Package 사용 방식에 대해서 아래에서 세부적으로 다룬다.
$GOPATH 경로를 선언하여 Package를 사용하는 방식
설명보다는 예제 코드를 보는 것이 좋을 듯~~~
$ vi ~/.bash_profile ... export GOPATH=$(go env GOPATH) ... $ . ~/.bash_profile $ echo $GOPATH /Users/sejong/go $ cd $GOPATH ## ## 이제부터는 $GOPATH/src 디렉토리 밑에서만 코드를 작성해야 한다. ## $ mkdir -p src/myexample $ cd src/myexample $ mkdir myPkgAlpha $ cd myPkgAlpha $ vi example.go package myPkgAlpha import "fmt" # 주의: 패키지 외부에서 참조할 수 있도록 함수 이름은 대문자로 시작해야 한다. func MyExamplePrint() { fmt.Println("My Alpha PKG") } $ cd .. $ vi main.go package main import ( "fmt" "myexample/myPkgAlpha" ) func main() { fmt.Println("This is main package.") myPkgAlpha.MyExamplePrint() } $ go mod init myexample $ go mod tidy $ go build $ ./myexample This is main package. My Alpha PKG $ tree . ├── go.mod ├── main.go ├── myPkgAlpha │ └── example.go └── myexample $
$GOPATH 경로가 아닌, 나만의 별도의 Project 폴더에서 Go Module 사용하는 방식
Go module을 사용하면 $GOPATH 경로가 아닌 아무 곳(디렉토리)에서 Go Source Code를 작성할 수 있는 자유가 생긴다.
긴 설명은 생략하고, 아래 예제처럼 Go Package와 Module을 사용하면 된다.
## ## 새로운 프로젝트를 위한 폴더를 만들자~ ## $ mkdir go-mod-pkg-example $ cd go-mod-pkg-example ## ## Go Package를 만들자. (myPkgAA) ## 주의사항: package 이름과 folder 이름을 동일하게 작성해야 한다. ## $ mkdir myPkgAA $ cd myPkgAA ## ## 아래와 같이 myPkgAA 패키지에 대한 코드를 작성한다. ## $ vi example.go package myPkgAA const ( COMPANY = "Sejong Inc" LOCATION = "Seoul Korea" ) ## ## Package가 1개만 있으면 심심하니까, 하나 더 만들자. (mypkg_bb) ## $ cd .. $ mkdir mypkg_bb $ cd mypkg_bb ## ## 아래와 같이 mypkg_bb 패키지에 대한 코드를 작성한다. ## $ vi example.go package mypkg_bb import ( "fmt" ) // NOTE: 함수 이름은 대문자로 시작해야 한다. func DoSomething(company string, location string) { fmt.Println("[In mypkg_bb]") fmt.Println(" Company :", company) fmt.Println(" Location :", location) } ## ## 위에서 작성한 Package를 사용하는 Go Module Code를 작성하자. ## $ go mod init myexample.cncf/sejong/myexample $ vi main.go // NOTE: package 이름을 main 으로 한다. package main // NOTE: 이 module의 이름이 "myexample.cncf/sejong/myexample" 이었기 때문에 // myPkgAA 패키지를 import하려면 아래처럼 경로를 작성해야 한다. import ( "myexample.cncf/sejong/myexample/myPkgAA" "myexample.cncf/sejong/myexample/mypkg_bb" ) func main() { mypkg_bb.DoSomething(myPkgAA.COMPANY, myPkgAA.LOCATION) } ## 솔직히, 위 예제 패키지(로컬 패키지)만 이용하는 경우에는 아래 tidy 명령을 필요 없다. ## 그러나 main.go 파일에서 외부 pkg를 import 한 것도 포함했다면, ## 아래처럼 tidy 명령을 수행해야 한다. $ go mod tidy $ go build $ ./myexample [In mypkg_bb] Company : Sejong Inc Location : Seoul Korea $ tree . ├── go.mod ├── main.go ├── myPkgAA │ └── example.go ├── myexample └── mypkg_bb └── example.go $
Vendor 방식의 패키지 관리
vendor 디렉토리에 특정 버전의 외부 패키지들을 저장 시킨 뒤 빌드에 참여시킴으로써 버전 일관성 문제를 해결 할 수 있다.
그리고 다운로드 불가한 외부 패키지를 어떻게든 한번만 구할 수만 있다면 다운로드 불가 문제도 피할 수 있다.
Container Image처럼 내가 작성한 Go Module 소스 코드가 있는 폴더에 의존성이 있는 모든 Package를 vendor/ 폴더 디렉토리에 다운로드 받는 다는 것이 가장 큰 특징이다.
자세한 내용은 아래 Go Module Vendoring 문서를 참고할 것 !!!
https://go.dev/ref/mod#go-mod-vendor
Go Modules Reference - The Go Programming Language
go.dev
## 코드를 작성한 상태에서 아래 명령을 실행~ $ mkdir MyExampleApp $ vi main.go ... ... $ go mod vendor $ ls main.go vendor/
'Golang' 카테고리의 다른 글
Golang 예제 - Source IP address를 지정한 TCP Client 구현 (Source IP Address Binding) (0) | 2023.09.20 |
---|---|
go build 할 때 app version, build date, dev note를 추가하는 방법 (0) | 2022.07.05 |
Golang REST API (0) | 2022.02.11 |
Go 언어 - Cobra Library를 이용하여 CLI Command 구현 (0) | 2021.11.24 |
golang cross compile (0) | 2021.11.03 |