gpt4 book ai didi

c - 如何为具有 SRC、OBJ 和 BIN 子目录的 C 项目创建 Makefile?

转载 作者:太空狗 更新时间:2023-10-29 16:15:46 27 4
gpt4 key购买 nike

几个月前,我想出了以下用于学校作业的通用 Makefile:

# ------------------------------------------------
# Generic Makefile
#
# Author: yanick.rochon@gmail.com
# Date : 2010-11-05
#
# Changelog :
# 0.01 - first version
# ------------------------------------------------

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

CC = gcc -std=c99 -c
# compiling flags here
CFLAGS = -Wall -I.

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

SOURCES := $(wildcard *.c)
INCLUDES := $(wildcard *.h)
OBJECTS := $(SOURCES:.c=*.o)
rm = rm -f

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

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

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

这将基本上编译每个 .c.h 文件以生成 .o 文件和可执行文件 projectname 都在同一个文件夹中。

现在,我想稍微插入一下。 如何编写 Makefile 来编译具有以下目录结构的 C 项目?

 ./
./Makefile
./src/*.c;*.h
./obj/*.o
./bin/<executable>

换句话说,我想要一个 Makefile 将 C 源代码从 ./src/ 编译成 ./obj/,然后链接所有内容以创建在 ./bin/.

中可执行

我尝试阅读不同的 Makefile,但我就是无法让它们适用于上面的项目结构;相反,该项目无法编译并出现各种错误。当然,我可以使用成熟的 IDE(Monodelop、Anjuta 等),但老实说,我更喜欢坚持使用 gEdit 和优秀的终端。

有没有大师可以给我一个可行的解决方案,或者关于如何做到这一点的明确信息?谢谢!

** 更新(v4) **

最终解决方案:

# ------------------------------------------------
# Generic Makefile
#
# Author: yanick.rochon@gmail.com
# Date : 2011-08-10
#
# Changelog :
# 2010-11-05 - first version
# 2011-08-10 - added structure : sources, objects, binaries
# thanks to http://stackoverflow.com/users/128940/beta
# 2017-04-24 - changed order of linker params
# ------------------------------------------------

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

CC = gcc
# compiling flags here
CFLAGS = -std=c99 -Wall -I.

LINKER = gcc
# linking flags here
LFLAGS = -Wall -I. -lm

# change these to proper directories where each file should be
SRCDIR = src
OBJDIR = obj
BINDIR = bin

SOURCES := $(wildcard $(SRCDIR)/*.c)
INCLUDES := $(wildcard $(SRCDIR)/*.h)
OBJECTS := $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o)
rm = rm -f


$(BINDIR)/$(TARGET): $(OBJECTS)
@$(LINKER) $(OBJECTS) $(LFLAGS) -o $@
@echo "Linking complete!"

$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
@$(CC) $(CFLAGS) -c $< -o $@
@echo "Compiled "$<" successfully!"

.PHONY: clean
clean:
@$(rm) $(OBJECTS)
@echo "Cleanup complete!"

.PHONY: remove
remove: clean
@$(rm) $(BINDIR)/$(TARGET)
@echo "Executable removed!"

最佳答案

首先,您的 $(OBJECTS) 规则有问题,因为:

  1. 有点不分青红皂白,使所有源成为每个对象的先决条件,
  2. 它经常使用错误的来源(正如您在 file1.ofile2.o 中发现的那样)
  3. 它尝试构建可执行文件而不是停留在对象上,并且
  4. 目标名称 (foo.o) 不是规则实际生成的名称 (obj/foo.o)。

我建议如下:

OBJECTS  := $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o)

$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
$(CC) $(CFLAGS) -c $< -o $@
@echo "Compiled "$<" successfully!"

$(TARGET) 规则存在同样的问题,即目标名称实际上并未描述规则构建的内容。因此,如果您多次键入 make,Make 每次都会重建目标,即使没有理由这样做。一个小的改变修复了:

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

一旦一切就绪,您可能会考虑更复杂的依赖关系处理;如果您修改其中一个头文件,此生成文件将不知道必须重建哪些对象/可执行文件。但这可以等到另一天。

编辑:
抱歉,上面的$(OBJECTS)规则我省略了一部分;我已经改正了。 (我希望我可以在代码示例中使用“strike”。)

关于c - 如何为具有 SRC、OBJ 和 BIN 子目录的 C 项目创建 Makefile?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7004702/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com