From f30e64e604f1392911d262f8d7d3da3d4061f5a6 Mon Sep 17 00:00:00 2001 From: Luka Vandervelden Date: Mon, 6 Apr 2015 22:42:56 +0200 Subject: [PATCH] Automatic rules rulez! (for things like .o files) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - This update also allowed to have a somewhat cleaner support for building libraries. (because the code to generate the rules for the .o files is common, uh) - Such automatic rules are hidden from the Makefiles’ “help” message, as they previously were. - subdirs are expected to have been broken. I should really write a real tool to do this job. In, say, C, maybe? --- Makefile | 8 +++- build.zsh | 96 +++++++++++++++++++++++++---------------------- build/binary.zsh | 29 +++----------- build/library.zsh | 45 ++++++++++++++++++++++ build/ofile.zsh | 34 +++++++++++++++++ 5 files changed, 142 insertions(+), 70 deletions(-) create mode 100644 build/library.zsh create mode 100644 build/ofile.zsh diff --git a/Makefile b/Makefile index 085426b..d0c687d 100644 --- a/Makefile +++ b/Makefile @@ -19,7 +19,7 @@ build.zsh: build.zsh.install: build.zsh @echo ' [IN] $(BINDIR)/build.zsh' - $(Q)mkdir -p '$(DESTDIR)$(BINDIR)/build.zsh' + $(Q)mkdir -p '$(DESTDIR)$(BINDIR)' $(Q)install -m0755 build.zsh $(DESTDIR)$(BINDIR)/build.zsh build.zsh.clean: @@ -74,6 +74,8 @@ $(PACKAGE)-$(VERSION).tar.gz: distdir @echo ' [TAR] $(PACKAGE)-$(VERSION).tar.gz' $(Q)tar czf $(PACKAGE)-$(VERSION).tar.gz \ $(PACKAGE)-$(VERSION)/build/binary.zsh \ + $(PACKAGE)-$(VERSION)/build/library.zsh \ + $(PACKAGE)-$(VERSION)/build/ofile.zsh \ $(PACKAGE)-$(VERSION)/build/script.zsh \ $(PACKAGE)-$(VERSION)/project.zsh \ $(PACKAGE)-$(VERSION)/Makefile @@ -83,6 +85,8 @@ $(PACKAGE)-$(VERSION).tar.xz: distdir @echo ' [TAR] $(PACKAGE)-$(VERSION).tar.xz' $(Q)tar cJf $(PACKAGE)-$(VERSION).tar.xz \ $(PACKAGE)-$(VERSION)/build/binary.zsh \ + $(PACKAGE)-$(VERSION)/build/library.zsh \ + $(PACKAGE)-$(VERSION)/build/ofile.zsh \ $(PACKAGE)-$(VERSION)/build/script.zsh \ $(PACKAGE)-$(VERSION)/project.zsh \ $(PACKAGE)-$(VERSION)/Makefile @@ -92,6 +96,8 @@ $(PACKAGE)-$(VERSION).tar.bz2: distdir @echo ' [TAR] $(PACKAGE)-$(VERSION).tar.bz2' $(Q)tar cjf $(PACKAGE)-$(VERSION).tar.bz2 \ $(PACKAGE)-$(VERSION)/build/binary.zsh \ + $(PACKAGE)-$(VERSION)/build/library.zsh \ + $(PACKAGE)-$(VERSION)/build/ofile.zsh \ $(PACKAGE)-$(VERSION)/build/script.zsh \ $(PACKAGE)-$(VERSION)/project.zsh \ $(PACKAGE)-$(VERSION)/Makefile diff --git a/build.zsh b/build.zsh index 933d62f..0f0ffd7 100755 --- a/build.zsh +++ b/build.zsh @@ -7,6 +7,7 @@ # it were cleaner, more readable and somewhat more documented. # - Using subdirs creates trouble. Really. Don’t do it unless it’s for # completely separate, independent sub-projects. +# Also, they’re unmaintained and probably broken by now. # # WARNINGS and LIMITATIONS: # - Using a relative path in DESTDIR= *will* fail. @@ -162,7 +163,7 @@ done function main { typeset -a prefixes directories - typeset -A ldflags cflags sources type depends install + typeset -A ldflags cflags sources type depends install auto prefixes=( PREFIX '/usr/local' @@ -229,57 +230,60 @@ function main { write "\n\t@:\n" fi - for target in ${targets[@]}; do - ( - typeset -a src - src=($(echo ${sources[$target]})) - local installdir="${install[$target]}" + local target_index=1 + while (($target_index <= ${#targets[@]})); do + local target="${targets[$target_index]}" - if exists "${type[$target]}.build"; then - ${type[$target]}.build - else - if ! exists "${type[$target]}.test"; then - error "No predefined rule for the following type: ${type[$target]}" - error " (expect trouble, nothing’s gonna work!)" - fi + typeset -a src + src=($(echo ${sources[$target]})) + local installdir="${install[$target]}" + + if exists "${type[$target]}.build"; then + ${type[$target]}.build + else + if ! exists "${type[$target]}.test"; then + error "No predefined rule for the following type: ${type[$target]}" + error " (expect trouble, nothing’s gonna work!)" fi + fi - if exists "${type[$target]}.install"; then - ${type[$target]}.install + if exists "${type[$target]}.install"; then + ${type[$target]}.install + else + if [[ -z "${installdir}" ]]; then + error "No install[${type[${target}]}] and no default installation directory." + error "Your “install” rule will be broken!" else - if [[ -z "${installdir}" ]]; then - error "No install[${type[${target}]}] and no default installation directory." - error "Your “install” rule will be broken!" - else - write "${target}.install: \$(DESTDIR)${installdir}" - write "\t@echo '$(IN ${installdir}/${target})'" - write "\t${Q}install -m755 $target \$(DESTDIR)${installdir}/$target" - write - fi - fi - - if exists "${type[$target]}.clean"; then - ${type[$target]}.clean - else - write "${target}.clean:" - write "\t@echo '$(RM ${target})'" - write "\t${Q}rm -f ${target}" + write "${target}.install: \$(DESTDIR)${installdir}" + write "\t@echo '$(IN ${installdir}/${target})'" + write "\t${Q}install -m755 $target \$(DESTDIR)${installdir}/$target" write fi + fi - if exists "${type[$target]}.uninstall"; then - ${type[$target]}.uninstall - else - write "${target}.uninstall:" - write "\t@echo '$(RM "${installdir}/${target}")'" - write "\t${Q}rm -f '\$(DESTDIR)${installdir}/${target}'" - write - fi + if exists "${type[$target]}.clean"; then + ${type[$target]}.clean + else + write "${target}.clean:" + write "\t@echo '$(RM ${target})'" + write "\t${Q}rm -f ${target}" + write + fi - if exists "${type[$target]}.test"; then - ${type[$target]}.test - fi - ) + if exists "${type[$target]}.uninstall"; then + ${type[$target]}.uninstall + else + write "${target}.uninstall:" + write "\t@echo '$(RM "${installdir}/${target}")'" + write "\t${Q}rm -f '\$(DESTDIR)${installdir}/${target}'" + write + fi + + if exists "${type[$target]}.test"; then + ${type[$target]}.test + fi + + ((target_index++)) done for dir in ${directories[@]}; do @@ -428,7 +432,9 @@ function main { write " @echo ''" write " @echo '${fg_bold[white]}Project targets: ${reset_color}'" for T in ${targets[@]}; do - printf " @echo ' - ${fg_bold[yellow]}%-14s${fg[white]}${type[$T]}${reset_color}'\n" "$T" >> $Makefile + if [[ "${auto[$T]}" != true ]]; then + printf " @echo ' - ${fg_bold[yellow]}%-14s${fg[white]}${type[$T]}${reset_color}'\n" "$T" >> $Makefile + fi done write " @echo ''" diff --git a/build/binary.zsh b/build/binary.zsh index e8ad9bb..b79ff3c 100644 --- a/build/binary.zsh +++ b/build/binary.zsh @@ -12,22 +12,10 @@ function binary.build { write for i in ${src[@]}; do - local dirname="$(dirname "$i")" - - write -n "${i%.c}.o: ${i}" - - sed '/^#include "/!d;s/^#include "//;s/"$//' $i | while read h; do - h="$dirname/$h" - - write -n " $h" - done - write - - write "\t@echo '$(CC ${i%.c}.o)'" - write -n "\t$Q\$(CC) \$(CFLAGS) ${cflags[$target]} -c ${i} " - write -n " ${cflags[$target]}" - write " -o ${i%.c}.o" - write + targets+=("${i%.c}.o") + type[${i%.c}.o]=ofile + auto[${i%.c}.o]=true + cflags[${i%.c}.o]="${cflags[$target]}" done } @@ -35,7 +23,7 @@ function binary.install { local install="${install[$target]:-\$(BINDIR)}" write "${target}.install: ${target}" write "\t@echo '$(IN "${install}/${target}")'" - write "\t${Q}mkdir -p '\$(DESTDIR)${install}/${target}'" + write "\t${Q}mkdir -p '\$(DESTDIR)${install}'" write "\t${Q}install -m0755 ${target} \$(DESTDIR)${install}/${target}" write } @@ -53,12 +41,5 @@ function binary.clean { write "\t@echo '$(RM ${target})'" write "\t${Q}rm -f ${target}" write - - for i in ${src[@]}; do - write "${i%.c}.o.clean:" - write "\t@echo '$(RM ${i%.c}.o)'" - write "\t${Q}rm -f ${i%.c}.o" - write - done } diff --git a/build/library.zsh b/build/library.zsh new file mode 100644 index 0000000..68cf3f5 --- /dev/null +++ b/build/library.zsh @@ -0,0 +1,45 @@ + +function library.build { + write -n "${target}:" + for i in ${src[@]}; do + write -n " ${i%.*}.o" + done + write " ${depends[$target]}" + write "\t@echo '$(LD ${target})'" + write -n "\t$Q\$(CC) -o ${target} -shared \$(LDFLAGS)" + write -n " ${src[@]//.c/.o}" + write " ${ldflags[$target]}" + write + + for i in ${src[@]}; do + targets+=("${i%.c}.o") + type[${i%.c}.o]=ofile + auto[${i%.c}.o]=true + cflags[${i%.c}.o]="-fPIC ${cflags[$target]}" + done +} + +function library.install { + local install="${install[$target]:-\$(LIBDIR)}" + write "${target}.install: ${target}" + write "\t@echo '$(IN "${install}/${target}")'" + write "\t${Q}mkdir -p '\$(DESTDIR)${install}'" + write "\t${Q}install -m0755 ${target} \$(DESTDIR)${install}/${target}" + write +} + +function library.uninstall { + local install="${install[$target]:-\$(LIBDIR)}" + write "${target}.uninstall:" + write "\t@echo '$(RM ${install}/${target})'" + write "\t${Q}rm -f '\$(DESTDIR)${install}/${target}'" + write +} + +function library.clean { + write "${target}.clean:" + write "\t@echo '$(RM ${target})'" + write "\t${Q}rm -f ${target}" + write +} + diff --git a/build/ofile.zsh b/build/ofile.zsh new file mode 100644 index 0000000..7c63fe8 --- /dev/null +++ b/build/ofile.zsh @@ -0,0 +1,34 @@ + +function ofile.build { + local dirname="$(dirname "$target")" + write -n "${target}: ${target%.o}.c" + + sed '/^#include "/!d;s/^#include "//;s/"$//' "${target%.o}.c" | \ + while read h; do + h="$dirname/$h" + + write -n " $h" + done + write + + write "\t@echo '$(CC ${target})'" + write -n "\t$Q\$(CC) \$(CFLAGS) ${cflags[$target]} -c ${target%.o}.c " + write -n " ${cflags[$target]}" + write " -o ${target}" + write +} + +function ofile.install { + write "${target}.install:" + write +} + +function ofile.uninstall { + write "${target}.uninstall:" + write +} + +function ofile.clean { + binary.clean "$@" +} +