【问题标题】:Makefile object file generation, variable substitution, and other questionsMakefile 目标文件生成、变量替换等问题
【发布时间】:2018-10-17 15:15:37
【问题描述】:

我目前正在尝试为 ac 大学项目创建一个 Makefile,但通读教程对我并没有太大帮助(此外,makefile 不是评估过程的一部分,我们也没有被教导如何去做它)

我的目标是使 makefile 自动化,因此它会自动从 src (src/*.c) 中的 .c 文件创建目标文件,将目标文件放在 bin 文件夹中,并将它们链接到主目录中的可执行文件.

project/
    bin/
        (object files)
    src/
        (source files)
    executable
    Makefile

到目前为止,我已经大致整理了这个 makefile 和测试源代码,但它并没有按照我想要的方式工作,我将在前面解释一下:

#compiler used
COMPILER = gcc

#flags for individual object file compilation
FLAGS = -Wall -ansi -g
#RELEASE
# -Wall -ansi -O3
#DEVELOPMENT
# -Wall -ansi -g

#source .c files
SOURCE = $(wildcard src/*.c)
#object files created
OBJECTS = $(SOURCE:.c=.o)
OBJECTS = $(SOURCE: src/=bin/)

#executable name
EXECUTABLE = app

############################################################

all: $(EXECUTABLE)

$(EXECUTABLE): $(OBJECTS)
    $(COMPILER) $(FLAGS) -o $(EXECUTABLE) $(OBJECTS)

%.o: %.c
    $(COMPILER) $(FLAGS) -c %< -o %@

结果是以下命令:

user@user-lenovo:~/Desktop/C Projects/AED/project$ make
gcc -Wall -ansi -g -o app src/main.c src/test.c

具有讽刺意味的是,它有效,但实际上不应该。它也违背了使用 makefile 的目的,因为一旦检测到更改,所有内容都会重新编译。

首先,我注意到的是 OBJECTS 直接复制了 SOURCE,并没有用 .c 代替 .o,也没有用 src/ 代替 bin/。我试过用 '=' 代替 ':=' 但结果是一样的,而且我一开始不太明白它们之间的区别是什么。例如,我的想法是 src/main.c 变成 bin/main.o。

%.o: %.c
    $(COMPILER) $(FLAGS) -c %< -o %@

这部分也是我用单个目标单独生成所有目标文件的失败尝试。我尝试阅读它,但无法弄清楚这些是如何工作的:'%

我相信它根本没有运行,因为没有显示任何目标文件。

希望您能帮我解决这个问题,在此先感谢!

【问题讨论】:

  • 请只问一个问题并选择一个与之匹配的标题。

标签: c makefile compilation object-files


【解决方案1】:
OBJECTS = $(SOURCE:.c=.o)
OBJECTS = $(SOURCE: src/=bin/)

您在那里分配了两次OBJECTS - 第一个结果被第二个结果覆盖,这不起作用。您想将它们组合成一个这样的语句

OBJECTS=$(SOURCE:src/%.c=bin/%.o)

你的下一个问题是你需要告诉make "bin/whatever.o" 是从 "src/whatever.c" 构建的。目前它会在“bin/”中寻找“whatever.c”

因此,您构建 .o 文件的方法需要添加目录

bin/%.o: src/%.c
    $(COMPILER) $(FLAGS) -c $< -o $@

您还应该使用$@ 而不是%@$&lt; 而不是%&lt;

【讨论】:

    【解决方案2】:
    1. 自动变量使用 $ 前缀扩展,与任何其他变量一样,而不是 %
    2. 由于您的目标文件和源文件位于不同的目录中,您不能简单地%.o: %.c

    试试:

    CC = gcc
    CFLAGS = -Wall -ansi -g
    
    OBJECTS = $(patsubst src/%.c,bin/%.o,$(SOURCE))
    
    bin/%.o: src/%.c
        $(CC) $(CFLAGS) -c $< -o $@
    

    注意:C 编译器的标准 make 变量是 CCCFLAGS 用于标志。最好使用它们。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多