Makefile 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. # The targets cannot be run in parallel
  2. .NOTPARALLEL:
  3. VERSION := $(shell git describe --tags --always --match "[0-9][0-9][0-9][0-9].*.*")
  4. MSI_VERSION := $(shell git tag -l --sort=v:refname | grep "w" | tail -1 | cut -c2-)
  5. #MSI_VERSION expects the format of the tag to be: (wX.X.X). Starts with the w character to not break cfsetup.
  6. #e.g. w3.0.1 or w4.2.10. It trims off the w character when creating the MSI.
  7. ifeq ($(ORIGINAL_NAME), true)
  8. # Used for builds that want FIPS compilation but want the artifacts generated to still have the original name.
  9. BINARY_NAME := cloudflared
  10. else ifeq ($(FIPS), true)
  11. # Used for FIPS compliant builds that do not match the case above.
  12. BINARY_NAME := cloudflared-fips
  13. else
  14. # Used for all other (non-FIPS) builds.
  15. BINARY_NAME := cloudflared
  16. endif
  17. ifeq ($(NIGHTLY), true)
  18. DEB_PACKAGE_NAME := $(BINARY_NAME)-nightly
  19. NIGHTLY_FLAGS := --conflicts cloudflared --replaces cloudflared
  20. else
  21. DEB_PACKAGE_NAME := $(BINARY_NAME)
  22. endif
  23. DATE := $(shell date -u '+%Y-%m-%d-%H%M UTC')
  24. VERSION_FLAGS := -X "main.Version=$(VERSION)" -X "main.BuildTime=$(DATE)"
  25. ifdef PACKAGE_MANAGER
  26. VERSION_FLAGS := $(VERSION_FLAGS) -X "github.com/cloudflare/cloudflared/cmd/cloudflared/updater.BuiltForPackageManager=$(PACKAGE_MANAGER)"
  27. endif
  28. LINK_FLAGS :=
  29. ifeq ($(FIPS), true)
  30. LINK_FLAGS := -linkmode=external -extldflags=-static $(LINK_FLAGS)
  31. # Prevent linking with libc regardless of CGO enabled or not.
  32. GO_BUILD_TAGS := $(GO_BUILD_TAGS) osusergo netgo fips
  33. VERSION_FLAGS := $(VERSION_FLAGS) -X "main.BuildType=FIPS"
  34. endif
  35. LDFLAGS := -ldflags='$(VERSION_FLAGS) $(LINK_FLAGS)'
  36. ifneq ($(GO_BUILD_TAGS),)
  37. GO_BUILD_TAGS := -tags "$(GO_BUILD_TAGS)"
  38. endif
  39. ifeq ($(debug), 1)
  40. GO_BUILD_TAGS += -gcflags="all=-N -l"
  41. endif
  42. IMPORT_PATH := github.com/cloudflare/cloudflared
  43. PACKAGE_DIR := $(CURDIR)/packaging
  44. PREFIX := /usr
  45. INSTALL_BINDIR := $(PREFIX)/bin/
  46. INSTALL_MANDIR := $(PREFIX)/share/man/man1/
  47. CF_GO_PATH := /tmp/go
  48. PATH := $(CF_GO_PATH)/bin:$(PATH)
  49. LOCAL_ARCH ?= $(shell uname -m)
  50. ifneq ($(GOARCH),)
  51. TARGET_ARCH ?= $(GOARCH)
  52. else ifeq ($(LOCAL_ARCH),x86_64)
  53. TARGET_ARCH ?= amd64
  54. else ifeq ($(LOCAL_ARCH),amd64)
  55. TARGET_ARCH ?= amd64
  56. else ifeq ($(LOCAL_ARCH),i686)
  57. TARGET_ARCH ?= amd64
  58. else ifeq ($(shell echo $(LOCAL_ARCH) | head -c 5),armv8)
  59. TARGET_ARCH ?= arm64
  60. else ifeq ($(LOCAL_ARCH),aarch64)
  61. TARGET_ARCH ?= arm64
  62. else ifeq ($(LOCAL_ARCH),arm64)
  63. TARGET_ARCH ?= arm64
  64. else ifeq ($(shell echo $(LOCAL_ARCH) | head -c 4),armv)
  65. TARGET_ARCH ?= arm
  66. else ifeq ($(LOCAL_ARCH),s390x)
  67. TARGET_ARCH ?= s390x
  68. else
  69. $(error This system's architecture $(LOCAL_ARCH) isn't supported)
  70. endif
  71. LOCAL_OS ?= $(shell go env GOOS)
  72. ifeq ($(LOCAL_OS),linux)
  73. TARGET_OS ?= linux
  74. else ifeq ($(LOCAL_OS),darwin)
  75. TARGET_OS ?= darwin
  76. else ifeq ($(LOCAL_OS),windows)
  77. TARGET_OS ?= windows
  78. else ifeq ($(LOCAL_OS),freebsd)
  79. TARGET_OS ?= freebsd
  80. else ifeq ($(LOCAL_OS),openbsd)
  81. TARGET_OS ?= openbsd
  82. else
  83. $(error This system's OS $(LOCAL_OS) isn't supported)
  84. endif
  85. ifeq ($(TARGET_OS), windows)
  86. EXECUTABLE_PATH=./$(BINARY_NAME).exe
  87. else
  88. EXECUTABLE_PATH=./$(BINARY_NAME)
  89. endif
  90. ifeq ($(FLAVOR), centos-7)
  91. TARGET_PUBLIC_REPO ?= el7
  92. else
  93. TARGET_PUBLIC_REPO ?= $(FLAVOR)
  94. endif
  95. ifneq ($(TARGET_ARM), )
  96. ARM_COMMAND := GOARM=$(TARGET_ARM)
  97. endif
  98. ifeq ($(TARGET_ARM), 7)
  99. PACKAGE_ARCH := armhf
  100. else
  101. PACKAGE_ARCH := $(TARGET_ARCH)
  102. endif
  103. #for FIPS compliance, FPM defaults to MD5.
  104. RPM_DIGEST := --rpm-digest sha256
  105. .PHONY: all
  106. all: cloudflared test
  107. .PHONY: clean
  108. clean:
  109. go clean
  110. .PHONY: cloudflared
  111. cloudflared:
  112. ifeq ($(FIPS), true)
  113. $(info Building cloudflared with go-fips)
  114. cp -f fips/fips.go.linux-amd64 cmd/cloudflared/fips.go
  115. endif
  116. GOOS=$(TARGET_OS) GOARCH=$(TARGET_ARCH) $(ARM_COMMAND) go build -mod=vendor $(GO_BUILD_TAGS) $(LDFLAGS) $(IMPORT_PATH)/cmd/cloudflared
  117. ifeq ($(FIPS), true)
  118. rm -f cmd/cloudflared/fips.go
  119. ./check-fips.sh cloudflared
  120. endif
  121. .PHONY: container
  122. container:
  123. docker build --build-arg=TARGET_ARCH=$(TARGET_ARCH) --build-arg=TARGET_OS=$(TARGET_OS) -t cloudflare/cloudflared-$(TARGET_OS)-$(TARGET_ARCH):"$(VERSION)" .
  124. .PHONY: generate-docker-version
  125. generate-docker-version:
  126. echo latest $(VERSION) > versions
  127. .PHONY: test
  128. test: vet
  129. ifndef CI
  130. go test -v -mod=vendor -race $(LDFLAGS) ./...
  131. else
  132. @mkdir -p .cover
  133. go test -v -mod=vendor -race $(LDFLAGS) -coverprofile=".cover/c.out" ./...
  134. endif
  135. .PHONY: cover
  136. cover:
  137. @echo ""
  138. @echo "=====> Total test coverage: <====="
  139. @echo ""
  140. # Print the overall coverage here for quick access.
  141. $Q go tool cover -func ".cover/c.out" | grep "total:" | awk '{print $$3}'
  142. # Generate the HTML report that can be viewed from the browser in CI.
  143. $Q go tool cover -html ".cover/c.out" -o .cover/all.html
  144. .PHONY: fuzz
  145. fuzz:
  146. @go test -fuzz=FuzzIPDecoder -fuzztime=600s ./packet
  147. @go test -fuzz=FuzzICMPDecoder -fuzztime=600s ./packet
  148. @go test -fuzz=FuzzSessionWrite -fuzztime=600s ./quic/v3
  149. @go test -fuzz=FuzzSessionServe -fuzztime=600s ./quic/v3
  150. @go test -fuzz=FuzzRegistrationDatagram -fuzztime=600s ./quic/v3
  151. @go test -fuzz=FuzzPayloadDatagram -fuzztime=600s ./quic/v3
  152. @go test -fuzz=FuzzRegistrationResponseDatagram -fuzztime=600s ./quic/v3
  153. @go test -fuzz=FuzzNewIdentity -fuzztime=600s ./tracing
  154. @go test -fuzz=FuzzNewAccessValidator -fuzztime=600s ./validation
  155. .PHONY: install-go
  156. install-go:
  157. rm -rf ${CF_GO_PATH}
  158. ./.teamcity/install-cloudflare-go.sh
  159. .PHONY: cleanup-go
  160. cleanup-go:
  161. rm -rf ${CF_GO_PATH}
  162. cloudflared.1: cloudflared_man_template
  163. sed -e 's/\$${VERSION}/$(VERSION)/; s/\$${DATE}/$(DATE)/' cloudflared_man_template > cloudflared.1
  164. install: install-go cloudflared cloudflared.1 cleanup-go
  165. mkdir -p $(DESTDIR)$(INSTALL_BINDIR) $(DESTDIR)$(INSTALL_MANDIR)
  166. install -m755 cloudflared $(DESTDIR)$(INSTALL_BINDIR)/cloudflared
  167. install -m644 cloudflared.1 $(DESTDIR)$(INSTALL_MANDIR)/cloudflared.1
  168. # When we build packages, the package name will be FIPS-aware.
  169. # But we keep the binary installed by it to be named "cloudflared" regardless.
  170. define build_package
  171. mkdir -p $(PACKAGE_DIR)
  172. cp cloudflared $(PACKAGE_DIR)/cloudflared
  173. cp cloudflared.1 $(PACKAGE_DIR)/cloudflared.1
  174. fpm -C $(PACKAGE_DIR) -s dir -t $(1) \
  175. --description 'Cloudflare Tunnel daemon' \
  176. --vendor 'Cloudflare' \
  177. --license 'Apache License Version 2.0' \
  178. --url 'https://github.com/cloudflare/cloudflared' \
  179. -m 'Cloudflare <support@cloudflare.com>' \
  180. -a $(PACKAGE_ARCH) -v $(VERSION) -n $(DEB_PACKAGE_NAME) $(RPM_DIGEST) $(NIGHTLY_FLAGS) --after-install postinst.sh --after-remove postrm.sh \
  181. cloudflared=$(INSTALL_BINDIR) cloudflared.1=$(INSTALL_MANDIR)
  182. endef
  183. .PHONY: cloudflared-deb
  184. cloudflared-deb: cloudflared cloudflared.1
  185. $(call build_package,deb)
  186. .PHONY: cloudflared-rpm
  187. cloudflared-rpm: cloudflared cloudflared.1
  188. $(call build_package,rpm)
  189. .PHONY: cloudflared-pkg
  190. cloudflared-pkg: cloudflared cloudflared.1
  191. $(call build_package,osxpkg)
  192. .PHONY: cloudflared-msi
  193. cloudflared-msi:
  194. wixl --define Version=$(VERSION) --define Path=$(EXECUTABLE_PATH) --output cloudflared-$(VERSION)-$(TARGET_ARCH).msi cloudflared.wxs
  195. .PHONY: github-release-dryrun
  196. github-release-dryrun:
  197. python3 github_release.py --path $(PWD)/built_artifacts --release-version $(VERSION) --dry-run
  198. .PHONY: github-release
  199. github-release:
  200. python3 github_release.py --path $(PWD)/built_artifacts --release-version $(VERSION)
  201. python3 github_message.py --release-version $(VERSION)
  202. .PHONY: r2-linux-release
  203. r2-linux-release:
  204. python3 ./release_pkgs.py
  205. .PHONY: capnp
  206. capnp:
  207. which capnp # https://capnproto.org/install.html
  208. which capnpc-go # go install zombiezen.com/go/capnproto2/capnpc-go@latest
  209. capnp compile -ogo tunnelrpc/proto/tunnelrpc.capnp tunnelrpc/proto/quic_metadata_protocol.capnp
  210. .PHONY: vet
  211. vet:
  212. go vet -mod=vendor github.com/cloudflare/cloudflared/...
  213. .PHONY: fmt
  214. fmt:
  215. goimports -l -w -local github.com/cloudflare/cloudflared $$(go list -mod=vendor -f '{{.Dir}}' -a ./... | fgrep -v tunnelrpc/proto)