Makefile 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. VERSION := $(shell git describe --tags --always --match "[0-9][0-9][0-9][0-9].*.*")
  2. MSI_VERSION := $(shell git tag -l --sort=v:refname | grep "w" | tail -1 | cut -c2-)
  3. #MSI_VERSION expects the format of the tag to be: (wX.X.X). Starts with the w character to not break cfsetup.
  4. #e.g. w3.0.1 or w4.2.10. It trims off the w character when creating the MSI.
  5. ifeq ($(ORIGINAL_NAME), true)
  6. # Used for builds that want FIPS compilation but want the artifacts generated to still have the original name.
  7. BINARY_NAME := cloudflared
  8. else ifeq ($(FIPS), true)
  9. # Used for FIPS compliant builds that do not match the case above.
  10. BINARY_NAME := cloudflared-fips
  11. else
  12. # Used for all other (non-FIPS) builds.
  13. BINARY_NAME := cloudflared
  14. endif
  15. ifeq ($(NIGHTLY), true)
  16. DEB_PACKAGE_NAME := $(BINARY_NAME)-nightly
  17. NIGHTLY_FLAGS := --conflicts cloudflared --replaces cloudflared
  18. else
  19. DEB_PACKAGE_NAME := $(BINARY_NAME)
  20. endif
  21. DATE := $(shell date -u '+%Y-%m-%d-%H%M UTC')
  22. VERSION_FLAGS := -X "main.Version=$(VERSION)" -X "main.BuildTime=$(DATE)"
  23. ifdef PACKAGE_MANAGER
  24. VERSION_FLAGS := $(VERSION_FLAGS) -X "github.com/cloudflare/cloudflared/cmd/cloudflared/updater.BuiltForPackageManager=$(PACKAGE_MANAGER)"
  25. endif
  26. LINK_FLAGS :=
  27. ifeq ($(FIPS), true)
  28. LINK_FLAGS := -linkmode=external -extldflags=-static $(LINK_FLAGS)
  29. # Prevent linking with libc regardless of CGO enabled or not.
  30. GO_BUILD_TAGS := $(GO_BUILD_TAGS) osusergo netgo fips
  31. VERSION_FLAGS := $(VERSION_FLAGS) -X "main.BuildType=FIPS"
  32. endif
  33. LDFLAGS := -ldflags='$(VERSION_FLAGS) $(LINK_FLAGS)'
  34. ifneq ($(GO_BUILD_TAGS),)
  35. GO_BUILD_TAGS := -tags "$(GO_BUILD_TAGS)"
  36. endif
  37. ifeq ($(debug), 1)
  38. GO_BUILD_TAGS += -gcflags="all=-N -l"
  39. endif
  40. IMPORT_PATH := github.com/cloudflare/cloudflared
  41. PACKAGE_DIR := $(CURDIR)/packaging
  42. PREFIX := /usr
  43. INSTALL_BINDIR := $(PREFIX)/bin/
  44. INSTALL_MANDIR := $(PREFIX)/share/man/man1/
  45. LOCAL_ARCH ?= $(shell uname -m)
  46. ifneq ($(GOARCH),)
  47. TARGET_ARCH ?= $(GOARCH)
  48. else ifeq ($(LOCAL_ARCH),x86_64)
  49. TARGET_ARCH ?= amd64
  50. else ifeq ($(LOCAL_ARCH),amd64)
  51. TARGET_ARCH ?= amd64
  52. else ifeq ($(LOCAL_ARCH),i686)
  53. TARGET_ARCH ?= amd64
  54. else ifeq ($(shell echo $(LOCAL_ARCH) | head -c 5),armv8)
  55. TARGET_ARCH ?= arm64
  56. else ifeq ($(LOCAL_ARCH),aarch64)
  57. TARGET_ARCH ?= arm64
  58. else ifeq ($(LOCAL_ARCH),arm64)
  59. TARGET_ARCH ?= arm64
  60. else ifeq ($(shell echo $(LOCAL_ARCH) | head -c 4),armv)
  61. TARGET_ARCH ?= arm
  62. else ifeq ($(LOCAL_ARCH),s390x)
  63. TARGET_ARCH ?= s390x
  64. else
  65. $(error This system's architecture $(LOCAL_ARCH) isn't supported)
  66. endif
  67. LOCAL_OS ?= $(shell go env GOOS)
  68. ifeq ($(LOCAL_OS),linux)
  69. TARGET_OS ?= linux
  70. else ifeq ($(LOCAL_OS),darwin)
  71. TARGET_OS ?= darwin
  72. else ifeq ($(LOCAL_OS),windows)
  73. TARGET_OS ?= windows
  74. else ifeq ($(LOCAL_OS),freebsd)
  75. TARGET_OS ?= freebsd
  76. else ifeq ($(LOCAL_OS),openbsd)
  77. TARGET_OS ?= openbsd
  78. else
  79. $(error This system's OS $(LOCAL_OS) isn't supported)
  80. endif
  81. ifeq ($(TARGET_OS), windows)
  82. EXECUTABLE_PATH=./$(BINARY_NAME).exe
  83. else
  84. EXECUTABLE_PATH=./$(BINARY_NAME)
  85. endif
  86. ifeq ($(FLAVOR), centos-7)
  87. TARGET_PUBLIC_REPO ?= el7
  88. else
  89. TARGET_PUBLIC_REPO ?= $(FLAVOR)
  90. endif
  91. ifneq ($(TARGET_ARM), )
  92. ARM_COMMAND := GOARM=$(TARGET_ARM)
  93. endif
  94. ifeq ($(TARGET_ARM), 7)
  95. PACKAGE_ARCH := armhf
  96. else
  97. PACKAGE_ARCH := $(TARGET_ARCH)
  98. endif
  99. #for FIPS compliance, FPM defaults to MD5.
  100. RPM_DIGEST := --rpm-digest sha256
  101. .PHONY: all
  102. all: cloudflared test
  103. .PHONY: clean
  104. clean:
  105. go clean
  106. .PHONY: cloudflared
  107. cloudflared:
  108. ifeq ($(FIPS), true)
  109. $(info Building cloudflared with go-fips)
  110. cp -f fips/fips.go.linux-amd64 cmd/cloudflared/fips.go
  111. endif
  112. GOOS=$(TARGET_OS) GOARCH=$(TARGET_ARCH) $(ARM_COMMAND) go build -v -mod=vendor $(GO_BUILD_TAGS) $(LDFLAGS) $(IMPORT_PATH)/cmd/cloudflared
  113. ifeq ($(FIPS), true)
  114. rm -f cmd/cloudflared/fips.go
  115. ./check-fips.sh cloudflared
  116. endif
  117. .PHONY: container
  118. container:
  119. docker build --build-arg=TARGET_ARCH=$(TARGET_ARCH) --build-arg=TARGET_OS=$(TARGET_OS) -t cloudflare/cloudflared-$(TARGET_OS)-$(TARGET_ARCH):"$(VERSION)" .
  120. .PHONY: generate-docker-version
  121. generate-docker-version:
  122. echo latest $(VERSION) > versions
  123. .PHONY: test
  124. test: vet
  125. ifndef CI
  126. go test -v -mod=vendor -race $(LDFLAGS) ./...
  127. else
  128. @mkdir -p .cover
  129. go test -v -mod=vendor -race $(LDFLAGS) -coverprofile=".cover/c.out" ./...
  130. go tool cover -html ".cover/c.out" -o .cover/all.html
  131. endif
  132. .PHONY: test-ssh-server
  133. test-ssh-server:
  134. docker-compose -f ssh_server_tests/docker-compose.yml up
  135. cloudflared.1: cloudflared_man_template
  136. sed -e 's/\$${VERSION}/$(VERSION)/; s/\$${DATE}/$(DATE)/' cloudflared_man_template > cloudflared.1
  137. install: cloudflared cloudflared.1
  138. mkdir -p $(DESTDIR)$(INSTALL_BINDIR) $(DESTDIR)$(INSTALL_MANDIR)
  139. install -m755 cloudflared $(DESTDIR)$(INSTALL_BINDIR)/cloudflared
  140. install -m644 cloudflared.1 $(DESTDIR)$(INSTALL_MANDIR)/cloudflared.1
  141. # When we build packages, the package name will be FIPS-aware.
  142. # But we keep the binary installed by it to be named "cloudflared" regardless.
  143. define build_package
  144. mkdir -p $(PACKAGE_DIR)
  145. cp cloudflared $(PACKAGE_DIR)/cloudflared
  146. cp cloudflared.1 $(PACKAGE_DIR)/cloudflared.1
  147. fpm -C $(PACKAGE_DIR) -s dir -t $(1) \
  148. --description 'Cloudflare Tunnel daemon' \
  149. --vendor 'Cloudflare' \
  150. --license 'Apache License Version 2.0' \
  151. --url 'https://github.com/cloudflare/cloudflared' \
  152. -m 'Cloudflare <support@cloudflare.com>' \
  153. -a $(PACKAGE_ARCH) -v $(VERSION) -n $(DEB_PACKAGE_NAME) $(RPM_DIGEST) $(NIGHTLY_FLAGS) --after-install postinst.sh --after-remove postrm.sh \
  154. cloudflared=$(INSTALL_BINDIR) cloudflared.1=$(INSTALL_MANDIR)
  155. endef
  156. .PHONY: cloudflared-deb
  157. cloudflared-deb: cloudflared cloudflared.1
  158. $(call build_package,deb)
  159. .PHONY: cloudflared-rpm
  160. cloudflared-rpm: cloudflared cloudflared.1
  161. $(call build_package,rpm)
  162. .PHONY: cloudflared-pkg
  163. cloudflared-pkg: cloudflared cloudflared.1
  164. $(call build_package,osxpkg)
  165. .PHONY: cloudflared-msi
  166. cloudflared-msi:
  167. wixl --define Version=$(VERSION) --define Path=$(EXECUTABLE_PATH) --output cloudflared-$(VERSION)-$(TARGET_ARCH).msi cloudflared.wxs
  168. .PHONY: cloudflared-darwin-amd64.tgz
  169. cloudflared-darwin-amd64.tgz: cloudflared
  170. tar czf cloudflared-darwin-amd64.tgz cloudflared
  171. rm cloudflared
  172. .PHONY: cloudflared-junos
  173. cloudflared-junos: cloudflared jetez-certificate.pem jetez-key.pem
  174. jetez --source . \
  175. -j jet.yaml \
  176. --key jetez-key.pem \
  177. --cert jetez-certificate.pem \
  178. --version $(VERSION)
  179. rm jetez-*.pem
  180. jetez-certificate.pem:
  181. ifndef JETEZ_CERT
  182. $(error JETEZ_CERT not defined)
  183. endif
  184. @echo "Writing JetEZ certificate"
  185. @echo "$$JETEZ_CERT" > jetez-certificate.pem
  186. jetez-key.pem:
  187. ifndef JETEZ_KEY
  188. $(error JETEZ_KEY not defined)
  189. endif
  190. @echo "Writing JetEZ key"
  191. @echo "$$JETEZ_KEY" > jetez-key.pem
  192. .PHONY: publish-cloudflared-junos
  193. publish-cloudflared-junos: cloudflared-junos cloudflared-x86-64.latest.s3
  194. ifndef S3_ENDPOINT
  195. $(error S3_HOST not defined)
  196. endif
  197. ifndef S3_URI
  198. $(error S3_URI not defined)
  199. endif
  200. ifndef S3_ACCESS_KEY
  201. $(error S3_ACCESS_KEY not defined)
  202. endif
  203. ifndef S3_SECRET_KEY
  204. $(error S3_SECRET_KEY not defined)
  205. endif
  206. sha256sum cloudflared-x86-64-$(VERSION).tgz | awk '{printf $$1}' > cloudflared-x86-64-$(VERSION).tgz.shasum
  207. s4cmd --endpoint-url $(S3_ENDPOINT) --force --API-GrantRead=uri=http://acs.amazonaws.com/groups/global/AllUsers \
  208. put cloudflared-x86-64-$(VERSION).tgz $(S3_URI)/cloudflared-x86-64-$(VERSION).tgz
  209. s4cmd --endpoint-url $(S3_ENDPOINT) --force --API-GrantRead=uri=http://acs.amazonaws.com/groups/global/AllUsers \
  210. put cloudflared-x86-64-$(VERSION).tgz.shasum $(S3_URI)/cloudflared-x86-64-$(VERSION).tgz.shasum
  211. dpkg --compare-versions "$(VERSION)" gt "$(shell cat cloudflared-x86-64.latest.s3)" && \
  212. echo -n "$(VERSION)" > cloudflared-x86-64.latest && \
  213. s4cmd --endpoint-url $(S3_ENDPOINT) --force --API-GrantRead=uri=http://acs.amazonaws.com/groups/global/AllUsers \
  214. put cloudflared-x86-64.latest $(S3_URI)/cloudflared-x86-64.latest || \
  215. echo "Latest version not updated"
  216. cloudflared-x86-64.latest.s3:
  217. s4cmd --endpoint-url $(S3_ENDPOINT) --force \
  218. get $(S3_URI)/cloudflared-x86-64.latest cloudflared-x86-64.latest.s3
  219. .PHONY: homebrew-upload
  220. homebrew-upload: cloudflared-darwin-amd64.tgz
  221. aws s3 --endpoint-url $(S3_ENDPOINT) cp --acl public-read $$^ $(S3_URI)/cloudflared-$$(VERSION)-$1.tgz
  222. aws s3 --endpoint-url $(S3_ENDPOINT) cp --acl public-read $(S3_URI)/cloudflared-$$(VERSION)-$1.tgz $(S3_URI)/cloudflared-stable-$1.tgz
  223. .PHONY: homebrew-release
  224. homebrew-release: homebrew-upload
  225. ./publish-homebrew-formula.sh cloudflared-darwin-amd64.tgz $(VERSION) homebrew-cloudflare
  226. .PHONY: github-release
  227. github-release: cloudflared
  228. python3 github_release.py --path $(EXECUTABLE_PATH) --release-version $(VERSION)
  229. .PHONY: github-release-built-pkgs
  230. github-release-built-pkgs:
  231. python3 github_release.py --path $(PWD)/built_artifacts --release-version $(VERSION)
  232. .PHONY: release-pkgs-linux
  233. release-pkgs-linux:
  234. python3 ./release_pkgs.py
  235. .PHONY: github-message
  236. github-message:
  237. python3 github_message.py --release-version $(VERSION)
  238. .PHONY: github-mac-upload
  239. github-mac-upload:
  240. python3 github_release.py --path artifacts/cloudflared-darwin-amd64.tgz --release-version $(VERSION) --name cloudflared-darwin-amd64.tgz
  241. python3 github_release.py --path artifacts/cloudflared-amd64.pkg --release-version $(VERSION) --name cloudflared-amd64.pkg
  242. .PHONY: github-windows-upload
  243. github-windows-upload:
  244. python3 github_release.py --path built_artifacts/cloudflared-windows-amd64.exe --release-version $(VERSION) --name cloudflared-windows-amd64.exe
  245. python3 github_release.py --path built_artifacts/cloudflared-windows-amd64.msi --release-version $(VERSION) --name cloudflared-windows-amd64.msi
  246. python3 github_release.py --path built_artifacts/cloudflared-windows-386.exe --release-version $(VERSION) --name cloudflared-windows-386.exe
  247. python3 github_release.py --path built_artifacts/cloudflared-windows-386.msi --release-version $(VERSION) --name cloudflared-windows-386.msi
  248. .PHONY: tunnelrpc-deps
  249. tunnelrpc-deps:
  250. which capnp # https://capnproto.org/install.html
  251. which capnpc-go # go install zombiezen.com/go/capnproto2/capnpc-go@latest
  252. capnp compile -ogo tunnelrpc/tunnelrpc.capnp
  253. .PHONY: quic-deps
  254. quic-deps:
  255. which capnp
  256. which capnpc-go
  257. capnp compile -ogo quic/schema/quic_metadata_protocol.capnp
  258. .PHONY: vet
  259. vet:
  260. go vet -v -mod=vendor github.com/cloudflare/cloudflared/...
  261. .PHONY: fmt
  262. fmt:
  263. goimports -l -w -local github.com/cloudflare/cloudflared $$(go list -mod=vendor -f '{{.Dir}}' -a ./... | fgrep -v tunnelrpc)