9.3.1 `zenoh-go` 개발 환경 구축

9.3.1 zenoh-go 개발 환경 구축

C 환경 설정(9.2.1)에서 CMake와 파일 복사로 고통받았다면, Go 환경 구축은 마치 마법처럼 쉽다.
구글이 만든 go mod 생태계 덕분에, zenoh-go 패키지를 끌어오는 것은 명령어 한 줄로 정리된다.

하지만 주의할 것이 하나 있다.
zenoh-go 는 순수 Go 언어(Pure Go)로 작성된 패키지가 아니다. 밑바닥은 여전히 Rust(zenoh-c) 엔진이 돌고 있기 때문에 CGO 라는 언어 횡단 다리를 뚫어야만 컴파일이 성공한다. 이 장에서는 의존성부터 CGO까지 서버를 이륙시킬 세팅을 마스터한다.

1. Go 모듈 환경 설정 및 패키지 의존성 관리

빈 폴더에서부터 시작하는 백엔드 프로젝트 이륙 지침(Take-off checklist)이다.

1.0.1 [Runbook] 모듈 및 패키지 흡수 전술

1. 프로젝트 초기화

mkdir my-zenoh-backend && cd my-zenoh-backend
go mod init my-zenoh-backend

2. Zenoh 심장(Package) 이식

## 공식 이클립스 저장소에서 zenoh-go 를 내려받는다.
go get github.com/eclipse-zenoh/zenoh-go

이 명령어 한 줄이 떨어지면, Go 컴파일러는 Github에서 최신 zenoh-go 소스코드를 다운받아 go.mod 에 버전을 기록한다.
그런데 이 다운로드된 패키지 안에는 숨겨진 비밀이 있다. go get 이 동작하는 순간 화면엔 안보이지만 내부적으로 미리 빌드된 OS별 zenoh-c 라이브러리 파일(.a, .so, .dylib)이 함께 딸려온다는 것이다.

C 프로그래머들이 직접 소스코드를 빌드해서 링킹하던 생고생을, Go 바인딩 제작진들이 미리 다 구워놓은 라이브러리를 패키지 안에 동봉해 줌으로써 완벽히 해결해 버렸다! 당신은 그냥 코드만 짜면 된다.

2. CGO 환경 구성 및 OS별(Linux, Windows, macOS) 빌드 요건

앞선 섹션에서 “다 준비되어 있다“고 했지만, 조건이 하나 붙는다.
당신의 컴퓨터에 최소한의 “C 소스코드를 컴파일 할 수 있는 도구” 가 깔려있어야만 Go 컴파일러가 CGO를 이용해 zenoh-c 다리를 용접(Link)할 수 있다.

2.0.1 [Runbook] OS별 CGO 툴체인 구축 전술

1. Linux (가장 흔한 서버, Ubuntu/Debian)
단순히 build-essential 패키지만 있으면 끝이다.

sudo apt update
sudo apt install build-essential
## 설치 후 gcc --version 이 정상 동작하는지 반드시 확인하라.
## gcc가 없으면 go build 가 CGO 에러를 뿜으며 즉사한다.

2. macOS (개발망 주로 사용)
Apple이 제공하는 xcode 커맨드라인 툴스면 충분하다.

xcode-select --install
## 이 명령어가 끝나고 cc --version 이 뜨면 합격이다.

3. Windows (가장 까다로움)
Windows는 태생적으로 GCC가 없기 때문에 순수 go build 로 CGO를 뚫을 수 없다. 가장 확실한 방법은 TDM-GCC나 MSYS2 를 까는 것이다.

  • MSYS2 터미널 실행 후 pacman -S mingw-w64-x86_64-gcc 설치
  • 환경 변수 PATHC:\msys64\mingw64\bin 을 등록

2.0.2 CGO 활성화 플래그 (중요)

go build 를 칠 때 기본적으로 CGO가 켜져(CGO_ENABLED=1) 있지만, 가끔 Dockerfile 안의 경량 알파인(Alpine) 리눅스 등에서는 CGO_ENABLED=0 으로 기본 세팅되어 있는 경우가 있다.
이 경우 무조건 명시적으로 CGO_ENABLED=1 go build . 를 때려야만 Zenoh 라이브러리가 백엔드 덩어리에 붙을 수 있다. C 언어 라이브러리를 심어야 하니까!

3. 경량화 및 크로스 플랫폼 빌드 최적화

Mac (M1칩) 노트북에서 코딩을 끝마치고, 클라우드의 리눅스 서버(x86_64)나 혹은 더 작은 싱글 보드(ARM)로 코드를 밀어 넣어야 할 때(Cross-Compilation) 문제가 터진다.

순수 Go 언어는 GOOS=linux GOARCH=amd64 go build 한 줄이면 교차 컴파일이 환상적으로 동작하지만, zenoh-go 는 무조건 CGO 를 요구하기 때문에 단순히 OS 지시자만 바꾼다고 크로스 컴파일이 되지 않는다. 타겟 OS의 C 언어 크로스 컴파일러(예: aarch64-linux-gnu-gcc)를 Go 컴파일러에게 명시적으로 물려줘야 한다!

3.0.1 [Runbook] 크로스 랭귀지 & 크로스 OS 컴파일 팩토리

Mac 랩탑에서 라즈베리 파이(ARM64 Linux)용 백엔드를 굽는 전술이다.

1. Mac에서 리눅스/ARM 용 크로스 C 툴체인 설치
(macOS 에서는 brew 를 통해 aarch64-linux-musl-cross 같은 툴체인을 먼저 깔아야 한다. 윈도우라면 WSL2를 경유하는 게 가장 정신 건강에 이롭다.)

2. 환경변수 융단 폭격 빌드

## 운영체제: Linux
## 아키텍처: ARM64
## CGO 타겟 컴파일러: 방금 깐 ARM 타겟 C 십자컴파일러
## 링커: 역시 ARM 타겟 링커

CGO_ENABLED=1 \
GOOS=linux \
GOARCH=arm64 \
CC=aarch64-linux-gnu-gcc \
CXX=aarch64-linux-gnu-g++ \
go build -ldflags="-s -w" -o zenoh_backend_arm main.go

[경량화 팁] -ldflags="-s -w"
Go 빌드 옵션 중에 디버그 심볼(.dSYM)과 DWARF 정보를 통째로 날려버리는(Strip) 파라미터다.
15MB짜리 바이너리 파일이 10MB 밑으로 극단적으로 다이어트 된다. 도커(Docker) 컨테이너의 파드(Pod) 이미지를 1MB 라도 줄여 배포 시간을 줄이고 싶다면, 무조건 포함해야 하는 상용 배포의 국룰 옵션이다.