使所有C文件递归
我真的无法进入makefiles。在以前的项目中,我在生成文件中硬编码了所有编译任务:使所有C文件递归,c,makefile,C,Makefile,我真的无法进入makefiles。在以前的项目中,我在生成文件中硬编码了所有编译任务: all: compile_a compile_b compile_c compile_a: ${CC} ${CFLAGS} ${A_SRC} -o ${A_OUT} 等等 但是,由于最新的项目比以前的每个项目都有更多的文件,我想写更好的make任务,当然也要写更少的字符,因为make对我的眼睛并不友好(这让他们很痛苦)!:-P 我想要的是: 一项任务可以管理所有项目(只需makeprojectn
all: compile_a compile_b compile_c
compile_a:
${CC} ${CFLAGS} ${A_SRC} -o ${A_OUT}
等等
但是,由于最新的项目比以前的每个项目都有更多的文件,我想写更好的make任务,当然也要写更少的字符,因为make对我的眼睛并不友好(这让他们很痛苦)!:-P
我想要的是:
- 一项任务可以管理所有项目(只需
或makeprojectname
,你知道吗?)makeall
- 每个要编译的C文件都有一个任务(我读了一些关于
语法的内容,但没有真正理解)%.o:%.C
- 一个链接任务(如何获取所有.o文件并链接它们而不进行硬编码?)
- 一项清洁任务(哦,我能做到!)
bin (binary goes here!)
src
some
directories
are
here
我不知道我是否需要对象文件的目录,我把它们放在/bin
中,我认为这已经足够好了,不是吗
也许我只是需要一个能用简单的语言解释的人
编辑:
正如有人指出的那样,没有真正的问题,所以这里是:
- 如何将所有C文件递归编译到
bin/(文件名).o
- 如何在不知道文件名的情况下链接“bin/”中的所有
文件.o
也许这会有所帮助。不必讨论makefiles的细节,请使用*作为您的优势 i、 e 试试这个:
CC = gcc
CFLAGS = -c -Wall -g -Os
LD = $(CC)
LDFLAGS = -lfoo
TARGET = MyProject
OBJECTS = $(patsubst %.c, %.o, $(wildcard *.c))
all: $(TARGET)
$(TARGET): $(OBJECTS)
$(LD) -o $@ $^ $(LDFLAGS)
# You don't even need to be explicit here,
# compiling C files is handled automagically by Make.
%.o: %.c
$(CC) $(CFLAGS) $^ -o $@
clean:
rm $(TARGET) $(OBJECTS)
我经常将
通配符
函数与foreach
函数结合使用,以实现您想要实现的功能
如果源代码位于src/
中,并且希望将二进制文件放入bin/
中,则myMakefile
的基本结构如下所示:
SOURCES=$(shell find src -type f -iname '*.c')
OBJECTS=$(foreach x, $(basename $(SOURCES)), $(x).o)
TARGET=bin/MyProject
$(TARGET): $(OBJECTS)
$(CC) $^ -o $@
clean:
rm -f $(TARGET) $(OBJECTS)
我通常利用make内置的隐式规则和预定义变量()。您实际上并没有问任何问题。你在哪一部分有问题?你真正想做什么?用makefile建立一个像样的构建系统要比看起来的工作量大得多。尝试使用CMake或SCons之类的构建工具。编辑:最困难的部分是将
.c
和.h
文件之间的依赖关系放入Makefile,有一些工具可以帮助实现这一点,但这很麻烦。嗯,我想我现在理解了%.o
语法,但是如何调用它,比如说/src/foo/bar/somefile.c
?-编辑:算了吧,我想我有这个角色!我认为应该是$(TARGET):$(OBJECTS)
,链接发生在该配方中,然后是all:$(TARGET)
,没有显式配方。否则,就没有构建MyProject的方法,而“所有”都依赖于此。这并不能完全回答OP的问题,后者要求递归生成文件。这将只编译顶级文件夹中的所有内容。@JamieBullock这很容易修复:可以使用$(shell find.-name“*.c”)
,而不是$(通配符…
),这将把所有.o
文件放在源代码树中,但我认为最好将它们放在bin/
中,不是吗?我不认为所有对象文件都位于单独的文件夹中有什么好处。如果只是为了在ls
之后看不到人口过多的文件夹,还有其他方法。此外,我不记得我编译的任何程序都有单独的目标文件文件夹。不起作用:1)第二行将只使用碰巧在那里的*.o
文件2)它假定所有内容都在同一目录中。此外,输出文件应该是规则的目标。
SOURCES=$(shell find src -type f -iname '*.c')
OBJECTS=$(foreach x, $(basename $(SOURCES)), $(x).o)
TARGET=bin/MyProject
$(TARGET): $(OBJECTS)
$(CC) $^ -o $@
clean:
rm -f $(TARGET) $(OBJECTS)