-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathMakefile
173 lines (150 loc) · 6.64 KB
/
Makefile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
SOURCE_OS ?= $(shell uname -s | tr '[:upper:]' '[:lower:]')
SOURCE_ARCH ?= $(shell uname -m)
TARGET_OS ?= $(SOURCE_OS)
TARGET_ARCH ?= $(SOURCE_ARCH)
normalize_arch = $(if $(filter aarch64,$(1)),arm64,$(if $(filter x86_64,$(1)),amd64,$(1)))
# Normalize the source and target arch to arm64 or amd64 for compatibility with go build.
SOURCE_ARCH := $(call normalize_arch,$(SOURCE_ARCH))
TARGET_ARCH := $(call normalize_arch,$(TARGET_ARCH))
# Here we will handle error cases where the host/target combinations are not supported.
SUPPORTED_COMBINATIONS := \
linux-arm64-linux-arm64 \
linux-amd64-linux-amd64 \
linux-amd64-android-arm64 \
darwin-arm64-darwin-arm64 \
darwin-arm64-android-arm64
CURRENT_COMBINATION := $(SOURCE_OS)-$(SOURCE_ARCH)-$(TARGET_OS)-$(TARGET_ARCH)
ifneq (,$(filter $(CURRENT_COMBINATION),$(SUPPORTED_COMBINATIONS)))
$(info Supported combination: $(CURRENT_COMBINATION))
else
$(error Error: Unsupported combination: $(CURRENT_COMBINATION))
endif
ifeq ($(SOURCE_OS),linux)
NPROC ?= $(shell nproc)
else ifeq ($(SOURCE_OS),darwin)
NPROC ?= $(shell sysctl -n hw.ncpu)
else
NPROC ?= 1
endif
BIN_OUTPUT_PATH = bin/$(TARGET_OS)-$(TARGET_ARCH)
TOOL_BIN = bin/gotools/$(shell uname -s)-$(shell uname -m)
FFMPEG_TAG ?= n6.1
FFMPEG_VERSION ?= $(shell pwd)/FFmpeg/$(FFMPEG_TAG)
FFMPEG_VERSION_PLATFORM ?= $(FFMPEG_VERSION)/$(TARGET_OS)-$(TARGET_ARCH)
FFMPEG_BUILD ?= $(FFMPEG_VERSION_PLATFORM)/build
FFMPEG_OPTS ?= --prefix=$(FFMPEG_BUILD) \
--enable-static \
--disable-shared \
--disable-programs \
--disable-doc \
--disable-everything \
--enable-decoder=h264 \
--enable-decoder=hevc \
--enable-network \
--enable-parser=h264 \
--enable-parser=hevc
# Add linker flag -checklinkname=0 for anet https://github.com/wlynxg/anet?tab=readme-ov-file#how-to-build-with-go-1230-or-later.
GO_LDFLAGS := -ldflags="-checklinkname=0"
CGO_LDFLAGS := -L$(FFMPEG_BUILD)/lib
CGO_CFLAGS := -I$(FFMPEG_BUILD)/include
export PKG_CONFIG_PATH=$(FFMPEG_BUILD)/lib/pkgconfig
# If we are building for android, we need to set the correct flags
# and toolchain paths for FFMPEG and go binary cross-compilation.
ifeq ($(TARGET_OS),android)
# amd64 android targets have not been tested, so we do not support them for now.
ifeq ($(TARGET_ARCH),arm64)
# Android build doesn't support most of our cgo libraries, so we use the no_cgo flag.
GO_TAGS ?= -tags no_cgo
# We need the go build command to think it's in cgo mode to support android NDK cross-compilation.
export CGO_ENABLED = 1
NDK_ROOT ?= $(shell pwd)/ndk/$(SOURCE_OS)/android-ndk-r26
# We do not need to handle source arch for toolchain paths.
# On darwin host, android toolchain binaries and libs are mach-O universal
# with 2 architecture targets: x86_64 and arm64.
CC = $(NDK_ROOT)/toolchains/llvm/prebuilt/$(SOURCE_OS)-x86_64/bin/aarch64-linux-android$(API_LEVEL)-clang
export CC
# Android API level is an integer value that uniquely identifies the revision of the Android platform framework API.
# We use API level 30 as the default value. You can change it by setting the API_LEVEL variable.
API_LEVEL ?= 30
FFMPEG_OPTS += --target-os=android \
--arch=aarch64 \
--cpu=armv8-a \
--enable-cross-compile \
--cc=$(CC)
endif
endif
.PHONY: build-ffmpeg tool-install gofmt lint test profile-cpu profile-memory update-rdk module clean clean-all
# We set GOOS, GOARCH, GO_TAGS, and GO_LDFLAGS to support cross-compilation for android targets.
$(BIN_OUTPUT_PATH)/viamrtsp: build-ffmpeg *.go cmd/module/*.go
CGO_LDFLAGS=$(CGO_LDFLAGS) \
GOOS=$(TARGET_OS) GOARCH=$(TARGET_ARCH) go build $(GO_TAGS) $(GO_LDFLAGS) -o $(BIN_OUTPUT_PATH)/viamrtsp cmd/module/cmd.go
$(BIN_OUTPUT_PATH)/discovery: build-ffmpeg *.go cmd/discovery/*.go
CGO_LDFLAGS=$(CGO_LDFLAGS) \
GOOS=$(TARGET_OS) GOARCH=$(TARGET_ARCH) go build $(GO_TAGS) $(GO_LDFLAGS) -o $(BIN_OUTPUT_PATH)/discovery cmd/discovery/cmd.go
tool-install:
GOBIN=`pwd`/$(TOOL_BIN) go install \
github.com/edaniels/golinters/cmd/combined \
github.com/golangci/golangci-lint/cmd/golangci-lint \
github.com/rhysd/actionlint/cmd/actionlint
gofmt:
gofmt -w -s .
lint: gofmt tool-install build-ffmpeg
go mod tidy
export pkgs="`go list -f '{{.Dir}}' ./...`" && echo "$$pkgs" | xargs go vet -vettool=$(TOOL_BIN)/combined
GOGC=50 $(TOOL_BIN)/golangci-lint run -v --fix --config=./etc/.golangci.yaml
test: build-ffmpeg
CGO_CFLAGS=$(CGO_CFLAGS) CGO_LDFLAGS=$(CGO_LDFLAGS) go test -race -v ./...
profile-cpu:
go test -v -cpuprofile cpu.prof -run "^TestRTSPCameraPerformance$$" -bench github.com/viam-modules/viamrtsp
go tool pprof -top cpu.prof > cpu-profile.txt
rm cpu.prof
profile-memory:
go test -v -memprofile mem.prof -run "^TestRTSPCameraPerformance$$" -bench github.com/viam-modules/viamrtsp
go tool pprof -top mem.prof > mem-profile.txt
rm mem.prof
update-rdk:
go get go.viam.com/rdk@latest
go mod tidy
$(FFMPEG_VERSION_PLATFORM):
git clone https://github.com/FFmpeg/FFmpeg.git --depth 1 --branch $(FFMPEG_TAG) $(FFMPEG_VERSION_PLATFORM)
$(FFMPEG_BUILD): $(FFMPEG_VERSION_PLATFORM)
cd $(FFMPEG_VERSION_PLATFORM) && ./configure $(FFMPEG_OPTS) && $(MAKE) -j$(NPROC) && $(MAKE) install
build-ffmpeg: $(NDK_ROOT)
# Only need nasm to build assembly kernels for amd64 targets.
ifeq ($(SOURCE_OS),linux)
ifeq ($(SOURCE_ARCH),amd64)
which nasm || (sudo apt update && sudo apt install -y nasm)
endif
endif
$(MAKE) $(FFMPEG_BUILD)
# Warning: This will download a large file (1.5GB) and extract the contents. If you have
# already downloaded the NDK, you can set the NDK_ROOT variable to the path of the NDK.
$(NDK_ROOT):
ifeq ($(TARGET_OS),android)
ifeq ($(SOURCE_OS),darwin)
wget https://dl.google.com/android/repository/android-ndk-r26d-darwin.dmg && \
hdiutil attach android-ndk-r26d-darwin.dmg && \
mkdir -p $(NDK_ROOT) && \
cp -R "/Volumes/Android NDK r26d"/AndroidNDK11579264.app/Contents/NDK/* $(NDK_ROOT) && \
hdiutil detach "/Volumes/Android NDK r26d" && \
rm android-ndk-r26d-darwin.dmg
endif
ifeq ($(SOURCE_OS),linux)
ifeq ($(SOURCE_ARCH),amd64)
sudo apt update && sudo apt install -y unzip && \
wget https://dl.google.com/android/repository/android-ndk-r26-linux.zip && \
mkdir -p $(dir $(NDK_ROOT)) && \
yes A | unzip android-ndk-r26-linux.zip -d $(dir $(NDK_ROOT)) && \
rm android-ndk-r26-linux.zip
endif
endif
endif
module: $(BIN_OUTPUT_PATH)/viamrtsp
cp $(BIN_OUTPUT_PATH)/viamrtsp bin/viamrtsp
tar czf module.tar.gz bin/viamrtsp
rm bin/viamrtsp
clean:
rm -rf $(BIN_OUTPUT_PATH)/viamrtsp module.tar.gz
clean-all:
rm -rf FFmpeg
git clean -fxd