https://www.gnu.org/software/make/manual/make.html#toc-An-Introduction-to-Makefiles 링크를 참고할 수 있다.
target … : prerequisites …
recipe
…
…
makefile의 활용
make [실행대상 : target]
makefile로 만든 target은 어떻게 사용할까?
"make" 명령어를 통해서 command에 작성한다. 이때, 만들어놓은 target을 활용해 명령을 내리면 target에 정의된 recipe대로 만들어준다.
dockerfile을 만들 때, makefile을 사용한다면 dockerfile에 RUN 명령어에 입력하는 실행코드를 make 명령어로 변경이 가능하다. 만약에 도커 이미지가 하나의 os에서 작동하는 것이 아니라, 여러 os에서 작동이 가능하도록 build하기 위해서는 GOOS를 변경해주고 binary build file의 이름도 하나씩 다르게 적어서 RUN을 시켜야한다...ㅜㅜ
이때, makefile을 사용해보자!!!
dockerfile에서 복잡하게 RUN 뒤의 실행 명령을 적지 않고, 여러 os에서 build하는 부분을 makefile로 작성하고 target을 활용해서 RUN target 명령어를 통해 한줄로 작성하면 코드를 구조화 할 수 있다.
BINARY_NAME=report-project
build:
GOARCH=amd64 GOOS=darwin go build -o ${BINARY_NAME}-darwin cmd/main.go
GOARCH=amd64 GOOS=linux go build -o ${BINARY_NAME}-linux cmd/main.go
GOARCH=amd64 GOOS=windows go build -o ${BINARY_NAME}-windows cmd/main.go
go를 활용한 프로젝트를 할 때 작성했던 makefile이다. build라는 이름을 가지는 target을 설정하고 해당 target의 recipe를 3개의 코드를 작성했다.
그렇다면
make build
로 한다면 어떤일이 일어날까?
target의 recipe들이 실행되어 darwin, linux, windows os를 가지는 build file 3개가 한번에 설치 될 것이다.
그리고 위에서 소개하지는 않았지만 report-project처럼 makefile에서 공통되는 부분은 위에 따로 정의하고 이를 ${}에 넣어서 이용이 가능하도록 makefile 기능이 제공되어 이를 활용했다.
FROM golang:1.19-alpine as builder
WORKDIR /report
COPY ./go.mod ./go.sum ./
RUN go mod download
COPY ./ .
RUN make build
cmd/main.go
# runner 생략
RUN 뒤에 make build를 작성함으로써, 한번에 buildfile를 3개를 만들 수 있다. 이후에 runner에서 원하는 파일을 사용해서 CMD에 넘기거나 사용자가 docker image를 실행할 때 혹은 docker-compose.yaml에서 command에 작성하여 사용하면 된다.
예를 들어
FROM alpine:latest as runner
# 생략
CMD ["./report-project-linux"]
나는 linux 계열의 os를 사용하기에 linux build file을 실행하는 명령을 CMD에 작성해줬다. window를 사용한다면 CMD ["/report-project-window"]를 사용하면 된다.
마지막으로...✍️
docker image 혹은 binary build file을 만들기 위해서 알아놓으면 좋을 것 같아 공유하고 싶어서 작성했다. 이 과정에서 다시한번 makefile을 알아보며 prerequisites와 file을 정의할때의 몇가지 형식(.o, .*a 등)을 새롭게 알게 되었다. 아직은 gnu makefile manual을 다 읽어보지는 않아서 간단한 사용 방법을 활용해 적용해본 것이지만 필요한 것들이 있다면 manual을 참고해서 작성하면 될 것 같다 :)