diff options
Diffstat (limited to 'Makefile')
| -rw-r--r-- | Makefile | 370 |
1 files changed, 197 insertions, 173 deletions
@@ -15,204 +15,228 @@ # License for the specific language governing permissions and limitations under # the License. -# Update on each new release!! -RELEASE_VERSION = 0.2.0 +# Update this on each new release, along with the NEWS.md file. +VERSION := v0.3.6 -NAME = fscrypt -PAM_NAME = pam_$(NAME) -PAM_MODULE = $(PAM_NAME).so +NAME := fscrypt +PAM_NAME := pam_$(NAME) -INSTALL ?= install -DESTDIR ?= /usr/local/bin -PAM_MODULE_DIR ?= /lib/security -PAM_CONFIG_DIR ?= /usr/share/pam-configs -MAN_PAGE_DIR ?= /usr/local/share/man +###### Makefile Command Line Flags ###### +# +# BIN: The location where binaries will be built. Default: bin +# DESTDIR: Installation destination directory. Default: "" +# PREFIX: Installation path prefix. Default: /usr/local +# BINDIR: Where to install the fscrypt binary. Default: $(PREFIX)/bin +# PAM_MODULE_DIR: Where to install pam_fscrypt.so. Default: $(PREFIX)/lib/security +# PAM_CONFIG_DIR: Where to install Ubuntu PAM config. Default: $(PREFIX)/share/pam-configs +# If the empty string, then the Ubuntu PAM config will not be installed. +# +# MOUNT: The filesystem where our tests are run. Default: /mnt/fscrypt_mount +# Ex: make test-setup MOUNT=/foo/bar +# Creates a test filesystem at that location. +# Ex: make test-teardown MOUNT=/foo/bar +# Cleans up a test filesystem created with "make test-setup". +# Ex: make test MOUNT=/foo/bar +# Run all integration tests on that filesystem. This can be an existing +# filesystem, or one created with "make test-setup" (this is the default). +# +# CFLAGS: The flags passed to the C compiler. Default: -O2 -Wall +# Ex: make fscrypt "CFLAGS = -O3 -Werror" +# Builds fscrypt with the C code failing on warnings and highly optimized. +# +# LDFLAGS: The flags passed to the C linker. Default empty +# Ex: make fscrypt "LDFLAGS = -static -ldl -laudit -lcap-ng" +# Builds fscrypt as a static binary. +# +# GO_FLAGS: The flags passed to "go build". Default empty +# Ex: make fscrypt "GO_FLAGS = -race" +# Builds fscrypt with race detection for the go code. +# +# GO_LINK_FLAGS: The flags passed to the go linker. Default: -s -w +# Ex: make fscrypt GO_LINK_FLAGS="" +# Builds fscrypt without stripping the binary. -CMD_PKG = github.com/google/$(NAME)/cmd/$(NAME) -PAM_PKG = github.com/google/$(NAME)/$(PAM_NAME) +BIN := bin +export PATH := $(BIN):$(PATH) +PAM_MODULE := $(BIN)/$(PAM_NAME).so -SRC_FILES = $(shell find . -type f -name '*.go' -o -name "*.h" -o -name "*.c") -GO_FILES = $(shell find . -type f -name '*.go' -not -path "./vendor/*") -PROTO_FILES = $(shell find . -type f -name '*.proto' -not -path "./vendor/*") -C_FILES = $(shell find . -type f -name "*.h" -o -name "*.c" -not -path "./vendor/*") -GO_PKGS = $(shell go list ./... | grep -v /vendor/) +###### Setup Build Flags ##### +CFLAGS := -O2 -Wall +# Pass CFLAGS to each cgo invocation. +export CGO_CFLAGS = $(CFLAGS) +# By default, we strip the binary to reduce size. +GO_LINK_FLAGS := -s -w -# IMAGE will be the path to our test ext4 image file. -IMAGE ?= $(NAME)_image +# Flag to embed the version (pulled from tags) into the binary. +TAG_VERSION := $(shell git describe --tags) +VERSION_FLAG := -X "main.version=$(if $(TAG_VERSION),$(TAG_VERSION),$(VERSION))" -# MOUNT will be the path to the filesystem where our tests are run. -# -# Running "make test-setup MOUNT=/foo/bar" creates a test filesystem at that -# location. Be sure to also run "make test-teardown MOUNT=/foo/bar". -# Running "make all MOUNT=/foo/bar" (or "make go") will run all tests on that -# filesystem. By default, it is the one created with "make test-setup". -MOUNT ?= /mnt/$(NAME)_mount -# Only run the integration tests if our root exists. -ifneq ("$(wildcard $(MOUNT))","") -export TEST_FILESYSTEM_ROOT = $(MOUNT) +override GO_LINK_FLAGS += $(VERSION_FLAG) -extldflags "$(LDFLAGS)" +override GO_FLAGS += --ldflags '$(GO_LINK_FLAGS)' +# Use -trimpath if available +ifneq "" "$(shell go help build | grep trimpath)" +override GO_FLAGS += -trimpath endif -# The flags code below lets the caller of the makefile change the build flags -# for fscrypt in a familiar manner. -# CFLAGS -# Change the flags passed to the C compiler. Default = "-O2 -Wall" -# For example: -# make fscrypt "CFLAGS = -O3 -Werror" -# builds the C code with high optimizations, and C warnings fail. -# LDFLAGS -# Change the flags passed to the C linker. Empty by default. -# For example (on my system with additional dev packages): -# make fscrypt "LDFLAGS = -static -ldl -laudit -lcap-ng" -# will build a static fscrypt binary. -# GO_FLAGS -# Change the flags passed to "go build". Empty by default. -# For example: -# make fscrypt "GO_FLAGS = -race" -# will build the Go code with race detection. -# GO_LINK_FLAGS -# Change the flags passed to the Go linker. Default = "-s -w" -# For example: -# make fscrypt GO_LINK_FLAGS="" -# will not strip the binary. - -# Set the C flags so we don't need to set C flags in each CGO file. -CFLAGS ?= -O2 -Wall -export CGO_CFLAGS = $(CFLAGS) +###### Find All Files and Directories ###### +FILES := $(shell find . -path '*/.git*' -prune -o -type f -printf "%P\n") +GO_FILES := $(filter %.go,$(FILES)) +GO_NONGEN_FILES := $(filter-out %.pb.go,$(GO_FILES)) +GO_DIRS := $(sort $(dir $(GO_FILES))) +C_FILES := $(filter %.c %.h,$(FILES)) +PROTO_FILES := $(filter %.proto,$(FILES)) -# By default, we strip the binary to reduce size. -GO_LINK_FLAGS ?= -s -w - -# Pass the version to the command line program (pulled from tags). -TAG_VERSION = $(shell git describe --tags) -VERSION = $(if $(TAG_VERSION),$(TAG_VERSION),$(RELEASE_VERSION)) -VERSION_FLAG = -X "main.version=$(VERSION)" - -# Pass the current date and time to the command line program. -DATE_FLAG = -X "main.buildTime=$(shell date)" -# Add the version, date, and any specified LDFLAGS to any user-specified flags. -override GO_LINK_FLAGS += $(VERSION_FLAG) $(DATE_FLAG) -extldflags "$(LDFLAGS)" -# Add the link flags to any user-specified flags. -override GO_FLAGS += --ldflags '$(GO_LINK_FLAGS)' +###### Build, Formatting, and Linting Commands ###### +.PHONY: default all gen format lint clean +default: $(BIN)/$(NAME) $(PAM_MODULE) +all: tools gen default format lint test + +$(BIN)/$(NAME): $(GO_FILES) $(C_FILES) + go build $(GO_FLAGS) -o $@ ./cmd/$(NAME) -.PHONY: default all +$(PAM_MODULE): $(GO_FILES) $(C_FILES) + go build $(GO_FLAGS) -buildmode=c-shared -o $@ ./$(PAM_NAME) + rm -f $(BIN)/$(PAM_NAME).h -default: $(NAME) $(PAM_MODULE) -all: format lint default test +gen: $(BIN)/protoc $(BIN)/protoc-gen-go $(PROTO_FILES) + protoc --go_out=. --go_opt=paths=source_relative $(PROTO_FILES) -$(NAME): $(SRC_FILES) - go build $(GO_FLAGS) -o $(NAME) $(CMD_PKG) +format: $(BIN)/goimports + goimports -w $(GO_NONGEN_FILES) + clang-format -i -style=Google $(C_FILES) -$(PAM_MODULE): $(SRC_FILES) - go build -buildmode=c-shared $(GO_FLAGS) -o $(PAM_MODULE) $(PAM_PKG) - rm -f $(PAM_NAME).h +lint: $(BIN)/staticcheck $(BIN)/misspell + go vet ./... + staticcheck ./... + misspell -source=text $(FILES) + shellcheck -s bash cmd/fscrypt/fscrypt_bash_completion + ( cd cli-tests && shellcheck -x *.sh) -.PHONY: clean clean: - rm -f $(NAME) $(PAM_MODULE) $(IMAGE) + rm -f $(BIN)/$(NAME) $(PAM_MODULE) $(TOOLS) coverage.out $(COVERAGE_FILES) $(PAM_CONFIG) -# Make sure go files build and tests pass. -.PHONY: test -test: - @go test -p 1 $(GO_FLAGS) $(GO_PKGS) - -# Make sure the protocol buffers are generated -.PHONY: gen -gen: - protoc --go_out=. $(PROTO_FILES) - -# Update the vendored dependencies. -.PHONY: update -update: - govendor init - govendor fetch +missing - govendor add +external - govendor remove +unused - -# Format all the Go and C code -.PHONY: format format-check -format: - goimports -l -w $(GO_FILES) - clang-format -i -style=Google $(C_FILES) +###### Cgroup testdata ###### +.PHONY: gen-cgroup-testdata +gen-cgroup-testdata: + bin/gen-cgroup-testdata -format-check: - @goimports -d $(GO_FILES) \ - | ./input_fail.py "Incorrectly formatted Go files. Run \"make format\"." - @clang-format -i -style=Google -output-replacements-xml $(C_FILES) \ - | grep "<replacement " \ - | ./input_fail.py "Incorrectly formatted C files. Run \"make format\"." - -# Run lint rules (skipping generated files) -.PHONY: lint -lint: - @go tool vet -buildtags=false . - @golint $(GO_PKGS) | grep -v "pb.go" | ./input_fail.py - @megacheck -unused.exported $(GO_PKGS) - -# Create fscrypt's man pages from markdown, requires ronn -MARKDOWN_PAGES = $(wildcard man/*.md) -MAN_PAGES = $(patsubst man/%.md, man/man8/%.gz, $(MARKDOWN_PAGES)) -MANUAL = "fscrypt Manual" -ORG = "fscrypt $(VERSION)" -RONN_FLAGS = -w --manual=$(MANUAL) --organization=$(ORG) - - -man/man8/%.gz: man/%.md - ronn $(RONN_FLAGS) --pipe --roff $< | gzip > $@ - -.PHONY: man -man: $(MAN_PAGES) - -###### Installation commands ##### -.PHONY: install_bin install_pam install uninstall -install_bin: $(NAME) - $(INSTALL) -d $(DESTDIR) - $(INSTALL) $(NAME) $(DESTDIR) - -install_pam: $(PAM_MODULE) - $(INSTALL) -d $(PAM_MODULE_DIR) - $(INSTALL) $(PAM_MODULE) $(PAM_MODULE_DIR) - $(INSTALL) -d $(PAM_CONFIG_DIR) - $(INSTALL) $(PAM_NAME)/config $(PAM_CONFIG_DIR)/$(NAME) - -install_man: $(MAN_PAGES) - $(INSTALL) -d $(MAN_PAGE_DIR)/man8 - $(INSTALL) $(MAN_PAGES) $(MAN_PAGE_DIR)/man8 - mandb - -install: install_bin install_pam install_man +###### Go tests ###### +.PHONY: test test-setup test-teardown + +# If MOUNT exists signal that we should run integration tests. +MOUNT := /tmp/$(NAME)-mount +IMAGE := /tmp/$(NAME)-image +ifneq ("$(wildcard $(MOUNT))","") +export TEST_FILESYSTEM_ROOT = $(MOUNT) +endif + +test: + go test -p 1 ./... -uninstall: - rm -f $(DESTDIR)/$(NAME) $(PAM_MODULE_DIR)/$(PAM_MODULE) $(PAM_CONFIG_DIR)/$(NAME) - -# Install the go tools used for checking/generating the code -.PHONY: go-tools -go-tools: - go get -u github.com/golang/protobuf/protoc-gen-go - go get -u github.com/golang/lint/golint - go get -u github.com/kardianos/govendor - go get -u golang.org/x/tools/cmd/goimports - go get -u honnef.co/go/tools/cmd/megacheck - -##### Setup/Teardown for integration tests (need root permissions) ##### -.PHONY: test-setup test-teardown test-setup: dd if=/dev/zero of=$(IMAGE) bs=1M count=20 mkfs.ext4 -b 4096 -O encrypt $(IMAGE) -F - sudo mkdir -p $(MOUNT) - sudo mount -o rw,loop $(IMAGE) $(MOUNT) + mkdir -p $(MOUNT) + sudo mount -o rw,loop,user $(IMAGE) $(MOUNT) sudo chmod +777 $(MOUNT) test-teardown: sudo umount $(MOUNT) - sudo rmdir $(MOUNT) + rmdir $(MOUNT) rm -f $(IMAGE) -##### Travis CI Commands -.PHONY: travis-setup travis-script -travis-install: go-tools test-setup - go get -u github.com/mattn/goveralls +###### Command-line interface tests ###### +.PHONY: cli-test cli-test-update + +cli-test: $(BIN)/$(NAME) + sudo cli-tests/run.sh + +cli-test-update: $(BIN)/$(NAME) + sudo cli-tests/run.sh --update-output + +# Runs tests and generates coverage +COVERAGE_FILES := $(addsuffix coverage.out,$(GO_DIRS)) +coverage.out: $(BIN)/gocovmerge $(COVERAGE_FILES) + @gocovmerge $(COVERAGE_FILES) > $@ + +%/coverage.out: $(GO_FILES) $(C_FILES) + @go test -coverpkg=./... -covermode=count -coverprofile=$@ -p 1 ./$* 2> /dev/null + +###### Installation Commands (require sudo) ##### +.PHONY: install install-bin install-pam uninstall install-completion +install: install-bin install-pam install-completion + +PREFIX := /usr/local +BINDIR := $(PREFIX)/bin + +install-bin: $(BIN)/$(NAME) + install -d $(DESTDIR)$(BINDIR) + install $< $(DESTDIR)$(BINDIR) -travis-script: lint format-check test default - goveralls -service=travis-ci - @govendor list +missing +external +unused \ - | ./input_fail.py "Incorrect vendored dependencies. Run \"make update\"." +PAM_MODULE_DIR := $(PREFIX)/lib/security +PAM_INSTALL_PATH := $(PAM_MODULE_DIR)/$(PAM_NAME).so +PAM_CONFIG := $(BIN)/config +PAM_CONFIG_DIR := $(PREFIX)/share/pam-configs + +install-pam: $(PAM_MODULE) + install -d $(DESTDIR)$(PAM_MODULE_DIR) + install $(PAM_MODULE) $(DESTDIR)$(PAM_MODULE_DIR) +ifdef PAM_CONFIG_DIR + m4 --define=PAM_INSTALL_PATH=$(PAM_INSTALL_PATH) < $(PAM_NAME)/config > $(PAM_CONFIG) + install -d $(DESTDIR)$(PAM_CONFIG_DIR) + install $(PAM_CONFIG) $(DESTDIR)$(PAM_CONFIG_DIR)/$(NAME) +endif + +COMPLETION_INSTALL_DIR := $(PREFIX)/share/bash-completion/completions + +install-completion: cmd/fscrypt/fscrypt_bash_completion + install -Dm644 $< $(DESTDIR)$(COMPLETION_INSTALL_DIR)/fscrypt + +uninstall: + rm -f $(DESTDIR)$(BINDIR)/$(NAME) \ + $(DESTDIR)$(PAM_INSTALL_PATH) \ + $(DESTDIR)$(COMPLETION_INSTALL_DIR)/fscrypt +ifdef PAM_CONFIG_DIR + rm -f $(DESTDIR)$(PAM_CONFIG_DIR)/$(NAME) +endif + +#### Tool Building Commands #### +TOOLS := $(addprefix $(BIN)/,protoc protoc-gen-go goimports staticcheck gocovmerge misspell) +.PHONY: tools +tools: $(TOOLS) + +$(BIN)/protoc-gen-go: + go build -o $@ google.golang.org/protobuf/cmd/protoc-gen-go +$(BIN)/goimports: + go build -o $@ golang.org/x/tools/cmd/goimports +$(BIN)/staticcheck: + go build -o $@ honnef.co/go/tools/cmd/staticcheck +$(BIN)/gocovmerge: + go build -o $@ github.com/wadey/gocovmerge +$(BIN)/misspell: + go build -o $@ github.com/client9/misspell/cmd/misspell + +# Non-go tools downloaded from appropriate repository +PROTOC_VERSION := 3.6.1 +ARCH := $(shell uname -m) +ifeq (x86_64,$(ARCH)) +PROTOC_ARCH := x86_64 +else ifneq ($(filter i386 i686,$(ARCH)),) +PROTOC_ARCH := x86_32 +else ifneq ($(filter aarch64 armv8l,$(ARCH)),) +PROTOC_ARCH := aarch_64 +endif +ifdef PROTOC_ARCH +PROTOC_URL := https://github.com/google/protobuf/releases/download/v$(PROTOC_VERSION)/protoc-$(PROTOC_VERSION)-linux-$(PROTOC_ARCH).zip +$(BIN)/protoc: + wget -q $(PROTOC_URL) -O /tmp/protoc.zip + unzip -q -j /tmp/protoc.zip bin/protoc -d $(BIN) +else +PROTOC_PATH := $(shell which protoc) +$(BIN)/protoc: $(PROTOC_PATH) +ifneq ($(wildcard $(PROTOC_PATH)),) + cp $< $@ +else + $(error Could not download protoc binary or locate it on the system. Please install it) +endif +endif |