寻找完美的Makefile画布

Mat*_*Mat 5 c gcc makefile

我是计算机工程专业的学生,​​我还有另一个C程序要实现.到目前为止,我总是从以前的项目中创建一个新的Makefile,这需要花时间进行设置.是否有一个我可以使用的Makefile画布是如此强大,以至于我需要提供的是包含main函数的c文件的名称?

我的想法是,对于每个新项目,我创建一个包含它的文件夹Makefile,一个bin文件夹和一个src文件夹.然后我会将一些变量编辑到Makefile(包含main()函数的C文件),然后make自动构建所有内容,将依赖项考虑在内.

你知道这样的Makefile存在吗?

[通过Alexandre C.编辑]:Automake/Autoconf对于仅使用标准库并在标准unix os上运行的这类项目来说是过度的.对于我们需要实现的项目,依赖项(对于要链接的文件)总是可以从".h"包含中推断出来,并且通常涉及的文件非常少.

Mat*_*Mat 0

我想出了以下解决方案:

\n\n
# Author Matthieu Sieben (http://matthieusieben.com)\n# Version 23/10/2012\n#\n# This Makefile is licensed under the Creative Commons Attribution\n# Partage dans les M\xc3\xaames Conditions 2.0 Belgique License.\n# To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/2.0/be/.\n# Use at your own risk.\n#\n# Use Makefile.inc to write you own rules or to overwrite the default values defined here.\n\nSRCDIR  = ./src\nBINDIR  = ./bin\n\nSHELL   = /bin/bash\nCC      = /usr/bin/gcc\nLIBS    =\nCFLAGS  = -Wall -Wextra -Werror\nLDFLAGS =\n\n.PHONY: default all clean distclean\n.SUFFIXES: .c .o\n\n# make "all" the default target\ndefault: all\n\n-include Makefile.inc\n-include Makefile.d\n\nCFLAGS += -I$(SRCDIR)\nifeq ($(DEBUG), 1)\n    CFLAGS += -DDEBUG=1 -ggdb\nelse\n    CFLAGS += -DDEBUG=0 -O2\n    LDFLAGS += -O2\nendif\n\n%.o: %.c\n    @echo "  Compiling `basename $<`";\n    @$(CC) $(CFLAGS) -o $@ -c $<;\n\nclean:\n    @echo "Cleaning compiled files";\n    @find $(SRCDIR) -name "*.o" -exec rm {} \\;\n    @[ -e Makefile.d ] && rm Makefile.d;\n\ndistclean: clean\n    @echo "Removing executables";\n    @find $(BINDIR) -type f -exec rm {} \\;\n\nMakefile.d: $(shell find $(SRCDIR) -type f -name "*.c")\n    @echo "Building dependencies";\n    @for file in `find $(SRCDIR) -name "*.c" -print`; do\\\n        $(CC) $(CFLAGS) -MM -MT $${file/%.c/.o} $$file | tr -d "\\n\\\\" >> Makefile.d.tmp;\\\n        echo -e "\\n" >> Makefile.d.tmp;\\\n    done;\\\n    for file in `find $(SRCDIR) -name "*.c" -exec grep -Hs "main(" {} \\; | cut -f1 -d\':\'`; do\\\n        execname=`basename $$file .c`;\\\n        objs="$${file/%.c/.o}";\\\n        for header in `$(CC) $(CFLAGS) -MM $$file | tr " " "\\n" | grep ".h$$" | sort | uniq | tr "\\n" " "`; do\\\n            if [ -f $${header/%.h/.c} ]; then\\\n                objs+=" $${header/%.h/.o}";\\\n            fi;\\\n            for obj in `grep "^$${header/%.h/.o}" Makefile.d.tmp | tr " " "\\n" | grep ".h$$" | tr "\\n" " "`; do\\\n                if [ -f $${obj/%.h/.c} ]; then\\\n                    objs+=" $${obj/%.h/.o}";\\\n                fi;\\\n            done;\\\n        done;\\\n        objs=`echo -n "$$objs"  | tr " " "\\n" | sort | uniq | tr "\\n" " "`;\\\n        echo "all: $$execname" >> Makefile.d.tmp;\\\n        echo "$$execname: $(BINDIR)/$$execname" >> Makefile.d.tmp;\\\n        echo "$(BINDIR)/$$execname: $$objs" >> Makefile.d.tmp;\\\n        echo "  @echo \\"Linking $$execname\\";" >> Makefile.d.tmp;\\\n        echo "  @\\$$(CC) \\$$(LDFLAGS) -o \\$$@ $$objs \\$$(LIBS);" >> Makefile.d.tmp;\\\n        echo >> Makefile.d.tmp;\\\n    done;\\\n    mv Makefile.d.tmp $@;\\\n
Run Code Online (Sandbox Code Playgroud)\n\n

它不是很健壮,因此请随意提供改进。下面是它的工作原理。\n这里的想法是,对于 中的每个 .c 文件$(SRCDIR),查找包含主函数 ( grep "main(" src/*.c) 的文件。然后,对于每个本地包含,#include "myfile.h"添加myfile.o到该可执行文件的对象列表中,然后在 Makefile.d 中写入上面的行

\n\n

编辑\n这个新版本的脚本支持 bin 文件链接的依赖关系。

\n