Skip to content

Instantly share code, notes, and snippets.

@robobenklein
Last active September 16, 2018 00:16
Show Gist options
  • Save robobenklein/9721130752998e812e6e9ce8b5f1092b to your computer and use it in GitHub Desktop.
Save robobenklein/9721130752998e812e6e9ce8b5f1092b to your computer and use it in GitHub Desktop.
CS360 Makefile
# 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))))'
@robobenklein
Copy link
Author

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 the RUNPATH/RPATH mod done by this makefile. (So you can build the shared lib and lab programs separately.)

Lab1 Example:

..
├── include
│   ├── dllist.h
│   ├── fields.h
│   ├── jrb.h
│   ├── jval.h
│   ├── socketfun.h
│   └── wd.h
├── lab1
│   └── famtree.c
├── src
│   ├── dllist.c
│   ├── fields.c
│   ├── jrb.c
│   ├── jval.c
│   ├── socketfun.c
│   └── wd.c
└── other-lab-folders
    ├── lab-things.c
    └── genius.c

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment