我在'模块中有C源?目录。它们只是* .c和相应的 .h文件。我也进行了测试'带有测试 .c程序的目录,用于测试模块。最后,我还有一些独立的节目在' progs'目录,它们的名称由* .c mask表示。
我想有一个主要的Makefile,我有命令来编译名为' modules',' progs'和'测试'。但是,我不知道如何定义所有依赖项以便正确编译所有内容。我的试验没有用。
这是最简单的makefile,显然根本不起作用:
COMPILER=gcc
SOURCES=modules progs tests
CFLAGS=-O2 -g -Og -Wall -std=c14
INCLUDES= -Imodules -I. -I../modules # no idea which is needed!
LFLAGS=-lm -lSDL -lSDL_image
all: modules tests progs
modules: modules/*.c modules/*.h
${COMPILER} ${CFLAGS} ${INCLUDES} -c $< -o $@
progs: progs/*.c
${COMPILER} ${CFLAGS} ${INCLUDES} -c $< -o $@ ${LFLAGS}
tests: tests/*.c
${COMPILER} ${CFLAGS} ${INCLUDES} -c $< -o $@ ${LFLAGS}
#%.o: %.c # no idea how to force compiling to modules OR progs, etc.
我听说过CPP和自动创建模块的依赖关系,但我尝试过的任何工作都没有,即使在尝试了gnumakefile帮助示例或其他手册之后也是如此。我的情况有些不同:(
答案 0 :(得分:0)
我认为这个解决方案,我几天前发现的,可以/可以工作:
我拥有的目录是'src','tests'和'utils'。全局Makefile,如下所示:
DIRS = src tests utils
all:
make -C src -f Makefile
make -C tests -f Makefile
make -C utils -f Makefile
clean:
make -C src -f Makefile clean
make -C tests -f Makefile clean
make -C utils -f Makefile clean
.PHONY: all clean ${DIRS}
这很有用,虽然我宁愿选择一些自动解决方案来迭代来自$ {DIRS}的所有目录。对于其中只有三个,我可以输入三次命令。 然后,在每个目录中,它自己的Makefile存在:
在src中:
SOURCES = ${wildcard *.c}
HEADERS = ${SOURCES:.c=.h}
OBJECTS = ${SOURCES:.c=.o}
DEPENDS = ${OBJECTS:.o=.d}
INCLUDE = -I/usr/include/SDL
LDFLAGS = -lm -lSDL -lSDL_image
CCFLAGS = -O2 -g -Wall -pedantic ${INCLUDE}
all: ${OBJECTS}
-include ${DEPENDS}
%.d: %.c
${CPP} ${CCFLAGS} $< -MM -MT ${@:.d=.o} >$@
%.o: %.c
${CC} ${CCFLAGS} -c $< -o $@
clean:
rm -f ${OBJECTS} ${DEPENDS}
.PHONY: clean all
然后,在测试和实用程序中(它们非常相似):
SOURCES = ${wildcard *.c}
OBJECTS = ${SOURCES:.c=.o}
DEPENDS = ${OBJECTS:.o=.d}
PROGRAM = ${patsubst %.c,%,${wildcard test*.c}}
INCLUDE = -I/usr/include/SDL -I../src
LDFLAGS = -lm -lSDL -lSDL_image
CCFLAGS = -O2 -g -Wall -pedantic ${INCLUDE}
all: ${PROGRAM}
test%: test%.o
${CC} ${CCFLAGS} $+ ../src/*.o -o $@ ${LDFLAGS}
#-include ${DEPENDS}
#%.d: %.c
# ${CPP} ${CCFLAGS} $< -MM -MT ${@:.d=.o} >$@
%.o: %.c
${CC} ${CCFLAGS} -c $< -o $@
clean:
rm -f ${PROGRAM} ${OBJECTS} ${DEPENDS}
.PHONY: clean all
在'utils'中我有:
SOURCES = ${wildcard *.c}
OBJECTS = ${SOURCES:.c=.o}
DEPENDS = ${OBJECTS:.o=.d}
PROGRAM = ${SOURCES:.c=}
INCLUDE = -I/usr/include/SDL -I../src
LDFLAGS = -lm -lSDL -lSDL_image
CCFLAGS = -O2 -g -Wall -pedantic ${INCLUDE}
all: calcVariance getScanLine
calcVariance: calcVariance.c
${CC} ${CCFLAGS} $< ../src/*.o -o $@ ${LDFLAGS}
getScanLine: getScanLine.c
${CC} ${CCFLAGS} $< ../src/*.o -o $@ ${LDFLAGS}
%.d: %.c
${CPP} ${CCFLAGS} $< -MM -MT ${@:.d=.o} >$@
%.o: %.c
${CC} ${CCFLAGS} -c $< -o $@
clean:
rm -f ${PROGRAM} ${OBJECTS} ${DEPENDS}
-include ${DEPENDS}
.PHONY: clean all
同样,我没有找到任何好的迭代来自$ {SOURCES}的所有程序,因为一些依赖项没有正确计算,因此我定义并将逐字程序名称放入规则中。也许有人会有一些线索如何做得更好。此外,我了解到使用预处理器自动确定所有依赖项是一个非常好的技巧,这反过来使所有makefile更好,自动化和精确。
缺点: 1.一些自动化程度不高,特别是在'utils'中(我的自动化显而易见的版本被骗了,它试图用getScanLine.o目标文件构建calcVariance,这个文件失败了。
从'src'目录重建后,Make没有从../src/*.o文件中看到新的重建对象。在我重建'src'之后,当我尝试从'tests'或'utils'构建时,没有看到任何变化。我必须强制清理,然后全部重建这些目录。
我觉得这个解决方案不是我能做到的最好的解决方案,因为我对make的工作原理缺乏了解。所以,我认为很多东西都可以改进。任何评论都非常欢迎。