Last active
September 16, 2018 00:16
-
-
Save robobenklein/9721130752998e812e6e9ce8b5f1092b to your computer and use it in GitHub Desktop.
CS360 Makefile
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# CS360 makefile | |
# original by robobenklein / bklein3@utk | |
# GPLv3 license | |
# contact me if this breaks for some reason, | |
# but it's not my fault if you delete your programs using this | |
# plug: join the UTKCS discord! | |
CC:=gcc | |
VARS_OLD := $(.VARIABLES) | |
CUR_DIR := $(shell pwd) | |
# LOG_DIR := $(CUR-DIR)/make-logs | |
mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST))) | |
current_dir := $(notdir $(patsubst %/,%,$(dir $(mkfile_path)))) | |
# venv_dir := ~/.cs140-cfapi-venv | |
# canvas_dir := cs140/makefile_uploaded | |
dirname = $(patsubst %/,%,$(dir $1)) | |
lab:=$(notdir $(current_dir)) | |
tardir:=$(abspath $(dir $(mkfile_path))) | |
tarfile:=$(tardir)/$(lab)_$(shell date --rfc-3339=date 2>/dev/null || python -c 'import datetime;print(str(datetime.date.today()))').tar.gz | |
SOURCEDIR := . | |
SRCS := $(shell find $(SOURCEDIR) -name '*.c') | |
H_FILES := $(shell find $(SOURCEDIR) -name '*.h') | |
CLASSDIR := $(notdir $(patsubst %/,%,$(dir $(current_dir)/../..))) | |
# lib headers: | |
INCLUDES := $(CLASSDIR)/include | |
# multi-lab libs, etc: | |
SHARED_C_FILES := $(shell find $(CLASSDIR)/src -name '*.c') | |
SHARED_C_OBJS = $(SHARED_C_FILES:.c=.o) | |
SHARED_C_LIB := libcs360.so | |
C_MAINS := $(shell grep -m 1 -nwl -e '^int main' $(SRCS) /dev/null | tr '\n' ' ') | |
PROGS = $(patsubst %.c,%,$(C_MAINS)) | |
CFLAGS := -fPIC -std=gnu11 -g -I$(INCLUDES) | |
LDFLAGS := -fPIC -shared | |
RPATHFLAGS := -Wl,-rpath=./ | |
# Check that given variables are set and all have non-empty values, | |
# die with an error otherwise. | |
# https://stackoverflow.com/questions/10858261/abort-makefile-if-variable-not-set | |
# Params: | |
# 1. Variable name(s) to test. | |
# 2. (optional) Error message to print. | |
check_defined = \ | |
$(strip $(foreach 1,$1, \ | |
$(call __check_defined,$1,$(strip $(value 2))))) | |
__check_defined = \ | |
$(if $(value $1),, \ | |
$(error Undefined $1$(if $2, ($2)))) | |
# .PHONY: all | |
all: $(PROGS) #$(SHARED_C_LIB) | |
# sources: $(C_MAINS) | |
# outputs: $(PROGS) | |
# $(SRCS:.c=.d):%.d:%.c | |
# $(CC) $(CFLAGS) -MMD -MP $< >$@ | |
# include $(SRCS:.c=.d) | |
$(SHARED_C_LIB): $(SHARED_C_OBJS) | |
# building shared: $@ | |
$(CC) ${LDFLAGS} -o $@ $^ | |
$(PROGS): %: %.c $(SHARED_C_LIB) | |
# building: $@ | |
$(CC) $(CFLAGS) $(RPATHFLAGS) -o $@ $^ | |
.PHONY: clean | |
clean: | |
# removing things: | |
gvfs-trash --force $(PROGS) $(SHARED_C_LIB) $(SHARED_C_OBJS) | |
tar: | |
# lab: $(lab) | |
tar -cvzf $(TAR_FLAGS) $(tarfile) $(C_FILES) $(H_FILES) | |
# upload: update-cfapi | |
# @:$(call check_defined, FILE, usage: `make upload FILE=path/to/file`) | |
# $(venv_dir)/bin/python $(venv_dir)/cfapi/post-file.py "$(FILE)" -D $(canvas_dir) | |
# @echo -e 'File uploaded to \033[36mhttps://utk.instructure.com/files/folder/self/$(canvas_dir)' | |
# uptar: tar update-cfapi | |
# $(venv_dir)/bin/python $(venv_dir)/cfapi/post-file.py $(tarfile) -D tars | |
# @echo -e 'File uploaded to \033[36mhttps://utk.instructure.com/files/folder/self/tars\033[0m' | |
.PHONY: update | |
update: | |
which curl | |
$(eval updatefile = /tmp/${USER}.update.makefile ) | |
curl -fsSL https://gist.githubusercontent.com/robobenklein/9721130752998e812e6e9ce8b5f1092b/raw/Makefile > $(updatefile) | |
test -s $(updatefile) | |
gvfs-trash $(mkfile_path) | |
mv $(updatefile) $(mkfile_path) | |
test -s $(mkfile_path) | |
# if the updated version doesn't work, the old Makefile is in your trash, probably ~/.local/share/Trash/ | |
# if there's a problem with the latest version, report bugs to [email protected] | |
# thanks for using my Makefile! | |
# update-cfapi: | |
# test -d $(venv_dir) || virtualenv $(venv_dir) | |
# $(venv_dir)/bin/pip install -U requests | |
# $(eval updatefile = /tmp/${USER}.update.makefile.post-file.py ) | |
# curl -fsSL https://gist.githubusercontent.com/robobenklein/9c67cfebed431003aa11cabbbf4438a3/raw/post-file.py > $(updatefile) | |
# test -s $(updatefile) | |
# mkdir -p $(venv_dir)/cfapi | |
# mv $(updatefile) $(venv_dir)/cfapi/post-file.py | |
.PHONY: help | |
help: | |
@echo -e '\033[36mCS360 makefile\033[0m by \033[31mrobobenklein\033[0m aka \033[36mbklein3\033[0m' | |
@echo -e 'Running \033[36mmake\033[0m will compile these files: ' | |
@echo -e ' \033[44m$(C_MAINS)\033[0m' | |
@echo -e 'into these output programs: ' | |
@echo -e ' \033[44m$(PROGS)\033[0m' | |
@echo -e 'only if the source files have changed, so no need to recompile irrelevant parts' | |
@echo -e '' | |
@echo -e 'When done with a lab, you can use `make tar` to tar.gz your .cpp files' | |
@echo -e 'which will put all of these files: ' | |
@echo -e ' \033[44m$(C_FILES) $(H_FILES)\033[0m' | |
@echo -e 'into a tar.gz file here: \033[36m$(tarfile)\033[0m' | |
@echo -e '' | |
@echo -e 'If you want to know what a make command will do before you run it,' | |
@echo -e ' use \033[36mmake -n\033[0m in place of \033[36mmake\033[0m and make will show you the commands without running them' | |
@echo -e 'Note that things beginning with a \033[36m#\033[0m are comments!' | |
@echo -e '' | |
@echo -e 'If you have feedback, bugs, or suggestions, email me! <\033[[email protected]\033[0m>' | |
.PHONY: makefiledebug | |
makefiledebug: | |
@echo -e '$(foreach v, $(filter-out $(VARS_OLD) VARS_OLD,$(.VARIABLES)), $(info $(v) = $($(v))))' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Just as I brought the CS140 Makefile upon the world, here is my attempt at doing the same for CS360.
This requires a bit more structure from your project: Place the library sources/headers one dir up from your lab directories.
These will be built into a shared library object
libcs360.so
that will be dynamically loaded with theRUNPATH
/RPATH
mod done by this makefile. (So you can build the shared lib and lab programs separately.)Lab1 Example: