我目前正在尝试制作一个可用于多个项目的Makefile,而无需为每个项目更改它。但是我最近开始用C编程并制作Makefile
这是我目前的项目结构。
project
| src
| gd.c, gd.h, geom.c(only file with main function)
| obj // *.o files should be created here
| bin // executable should be created here
| Makefile
这是我到目前为止构建的内容,但我根本不确定如何为编译/链接文件指定子目录。
1 TARGET = projectname
2 LIBS = -lm
3 CC = gcc
4 CFLAGS = -std=c11 -Wall
5 LD = gcc
6 LDFLAGS = -Wall
7
8 SRCDIR = src
9 OBJDIR = obj
10 EXEDIR = bin
11
12 SOURCES =
13 HEADERS =
14 OBJECTS =
15
16 $(EXEDIR)/$(TARGET): $(OBJECTS)
17 $(LD) $(OBJECTS) $(LDFLAGS) -o $@ $(LIBS)
18
19 $(OBJECTS): $(SOURCES) $(HEADERS)
20 $(CC) $(CFLAGS) -c $< -o $@
21
22 .PHONY: clean
23 clean:
24 rm -f *.o
25
26 .PHONY: remove
27 remove: clean
28 rm -f $(EXEDIR)/$(TARGET)
我的问题是:
答案 0 :(得分:1)
如果我理解得很好,你想知道 - 在你的布局中 - 如何设置SOURCES,HEADERS和OBJECTS值,这将使你的Makefile工作。
为此你可以使用正则表达式:
SOURCES = $(wildcard $(SRCDIR)/*.c)
OBJECTS = $(patsubst $(SRCDIR)/%.c,$(OBJDIR)/%.o,$(SOURCES))
HEADERS = $(patsubst %.c,%.h,$(SOURCES))
wildcard
文档here
patsubst
文档here
这是一个简单的答案,如果你想创建一个完全可重用的Makefile,你将不得不处理源子文件夹。例如。
创建对象的规则很奇怪(可能有效)。我认为如果您使用规则一次创建一个具有一个源的对象会更好,例如:
$(OBJDIR)/%.o: $(SRCDIR)/%.c
$(CC) $(CFLAGS) -c $< -o $@
在这种情况下,SOURCES变量变得无用。
此外,我认为HEADERS变量是无用的,因为在编译过程中你没有给gcc标题,而是给gcc ... -I<headers folder>
并且您应该rm -f $(OBJDIR)/*.o
清除obj
文件夹中的目标文件
我忘记了第二个问题,您可以使用shell命令在文件创建之前创建文件夹:
$(OBJDIR)/%.o: $(SRCDIR)/%.c
@mkdir $(OBJDIR)
$(CC) $(CFLAGS) -c $< -o $@