c - Makefile:将对象编译到源文件夹

标签 c makefile

我有以下生成文件

# project name (generate executable with this name)
TARGET   = tp3

CC       = gcc -std=c99 -c
# compiling flags here
CFLAGS   = -Wall -I. -Werror-implicit-function-declaration

LINKER   = gcc -o
# linking flags here
LFLAGS   = -Wall

# debug flags here
DFLAGS   = -g -DDEBUG

SOURCES  := $(shell find . -type f -name '*.c')
INCLUDES  := $(shell find . -type f -name '*.h')
OBJECTS  := $(SOURCES:.c=.o)
rm       = rm -rf

$(TARGET): obj
    @$(LINKER) $(TARGET) $(LFLAGS) $(OBJECTS)
    @echo "Linking complete!"

obj: $(SOURCES) $(INCLUDES)
    @$(CC) $(CFLAGS) -DNDEBUG $(SOURCES)
    @echo "Compilation complete!"

#debug:
#   gcc $(DFLAGS) $(SOURCES) -o $(TARGET)   

dobj: $(SOURCES) $(INCLUDES)
    @$(CC) $(CFLAGS) $(DFLAGS) $(SOURCES)
    @echo "dlinking complete!"

debug: dobj
    @$(LINKER) $(TARGET) $(LFLAGS) $(DFLAGS) $(OBJECTS) -o $(TARGET)
    @echo "dcompilation complete!"

run:
    ./tp3

clean:
    @$(rm) $(TARGET) $(OBJECTS) *.dSYM
    @echo "Cleanup complete!"

问题是:我在 CMM/CMM 文件夹中有文件,OBJECTS 假定对象也在 CMM/CMM 文件夹中,但编译器将它们放在根文件夹中。我怎样才能让编译器编译 CMM/CMM 中的 .o 文件或告诉模式替换器 OBJECTS := $(SOURCES:.c=.o) 所有内容都在根文件夹中?

最佳答案

你真正的问题是你没有使用 make 提供的工具来简化你的任务。
此外,您的编译器将所有 .o 文件放在根文件夹中,因为您没有告诉他不要这样做,或者让 make 为您这样做。

这是工作的 Makefile:

EXE :=  tp3
SRC :=  $(shell find . -type f -name '*.c')
OBJ :=  $(SRC:.c=.o)

# Preprocessor flags here
CPPFLAGS    :=  -I.
# Compiler flags here
CFLAGS      :=  -std=c99 -Wall -Werror-implicit-function-declaration

.PHONY: all debug run clean

all: CPPFLAGS += -DNDEBUG
all: $(EXE)

debug: CPPFLAGS += -DDEBUG
debug: CFLAGS += -g
debug: $(EXE)

$(EXE): $(OBJ)
    @echo "Compilation complete!"
    $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
    @echo "Linking complete!"

run:
    ./$(EXE)

clean:
    @$(RM) $(EXE) $(OBJ) *.dSYM
    @echo "Cleanup complete!"

Make 有一组内置变量和规则,您应该使用它们来避免浪费时间和遇到简单的错误。

请注意,此 Makefile 不能很好地处理依赖关系,仅将 .h 文件列表添加到 Makefile 中是不够的。您可以通过让编译器在编译 .o 文件的同时即时创建依赖文件来解决此问题,如下所示:

  • 构建 .d 文件名列表:DEP := $(OBJ:.o=.d),
  • 告诉编译器生成相应的文件,将-MMD -MP开关添加到CPPFLAGS内置变量,
  • 将它们包含在 Makefile 中以便解析它们的内容:-include $(DEP),
  • 不要忘记清理它们,将$(DEP) 添加到clean 目标中的$(RM) 命令。

结果:

EXE :=  tp3
SRC :=  $(shell find . -type f -name '*.c')
OBJ :=  $(SRC:.c=.o)
DEP :=  $(OBJ:.o=.d)

# Preprocessor flags here
CPPFLAGS    :=  -MMD -MP -I.
# Compiler flags here
CFLAGS      :=  -std=c99 -Wall -Werror-implicit-function-declaration

.PHONY: all debug run clean

all: CPPFLAGS += -DNDEBUG
all: $(EXE)

debug: CPPFLAGS += -DDEBUG
debug: CFLAGS += -g
debug: $(EXE)

$(EXE): $(OBJ)
    @echo "Compilation complete!"
    $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
    @echo "Linking complete!"

-include $(DEP)

run:
    ./$(EXE)

clean:
    @$(RM) $(EXE) $(OBJ) $(DEP) *.dSYM
    @echo "Cleanup complete!"

如有任何问题,请继续。

关于c - Makefile:将对象编译到源文件夹,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27161230/

相关文章:

c - 在 Mac OS X 10.6 上编译 SDL 2.0 时出现 libiconv 问题

编译带有依赖项的 .c 文件

c - 如何制作正确的 C makefile

c - C中的级别顺序队列实现

c - 在 C 中使用 sizeof() 运算符时的奇怪情况

c - 将 strtok 存储在数组中 ~ C

c - 是否允许在位字段中使用short或任何其他类型代替int

c - 这段程序代码有什么错误?

c++ - 什么是 g++-3/gcc-3?

makefile - 如何自动检查 makefile 的正确性?