【问题标题】:Makefile generic target ruleMakefile 通用目标规则
【发布时间】:2014-05-06 11:57:02
【问题描述】:

我正在尝试改进我在 makefile 中使用的简单解决方案(用于编译目标的单一规则和用于将所有先前目标链接在一起的附加规则)。 我想出了以下 Makefile(已剪辑):

.PHONY: clean

BASE_DIR = ../

CC = gcc
CROSS_COMPILE = arm-none-eabi-
CFLAGS =-g -I${BASE_DIR}/include 
LDFLAGS =-L${BASE_DIR}/lib -Ttarget.ld -nostdlib 

SOURCES = first.c second.c third.c fourth.c
OBJECTS = $(SOURCES:.c=.o)
EXECUTABLE = $(OBJECTS:.o=)

all: $(EXECUTABLE)

%:
    ${CROSS_COMPILE}$(CC) $(CFLAGS) $(LDFLAGS) $*.c -o $*

clean:
    rm ${EXECUTABLE}

这很好用,但我想将编译和链接过程分开。因此我尝试修改如下:

.PHONY: clean

BASE_DIR = ../

CC = gcc
CROSS_COMPILE = arm-none-eabi-

CFLAGS =-c -g -I${BASE_DIR}/include 
LDFLAGS =-L${BASE_DIR}/lib -Ttarget.ld -nostdlib 

SOURCES = first.c second.c third.c fourth.c
OBJECTS = $(SOURCES:.c=.o)
EXECUTABLE = $(OBJECTS:.o=)

all : $(EXECUTABLE)

%.o : %.c
    @echo "Compiling c file into o file"
    ${CROSS_COMPILE}$(CC) $(CFLAGS) $< -o $@

% : %.o
    @echo "Linking o file into executable"
    ${CROSS_COMPILE}$(CC) $(LDFLAGS) $< -o $@

clean:
    rm ${EXECUTABLE}

这工作正常,然后我调用 Makefile 作为例如make first.o; make first 或者如果我将 EXECUTABLE = $(OBJECTS:.o=) 修改为 EXECUTABLE = $(OBJECTS:.o=.out)% : %.o 修改为 %.out : %.o。但是,如果我尝试以makemake first 调用编译,则使用隐式规则。

我尝试浏览 Makefile 手册,但里面确实有很多信息,我有点困惑。

如何修改 Makefile 以允许同时调用构建单独的目标为make &lt;target&gt; 或所有目标为make

【问题讨论】:

    标签: makefile


    【解决方案1】:

    您描述问题的段落非常混乱且难以理解。提问时,请确保描述问题的部分最清楚:如果您提供示例输出,准确显示您键入的命令和获得的结果,并说明您期望得到的结果,这将很有帮助。

    但是,我的解释是,如果您运行 make first,它使用内置规则直接从 first.c 编译 first,而不是您的模式规则(请注意,内置规则和您的模式规则被认为是“隐式规则”)。

    这是因为 make 将选择“更短”的隐式规则链,因此将首选直接从源代码一步构建可执行文件的规则,而不是两步构建对象然后可执行文件的规则。如果您不想使用内置的隐式规则,那么您需要使用-r 标志调用make,或者通过添加delete it

    % : %.c
    

    (仅此而已)到您的 makefile。

    【讨论】:

    • 如果我的描述令人困惑,我很抱歉,我已尽力说清楚。 “内置规则和您的模式规则都被视为“隐式规则””是什么意思?我提供的规则不被认为是明确的?
    • 没有。显式规则是类似foo: foo.o 的规则:它们具有显式 目标名称。后缀规则 (.c.o) 和模式规则 (%.o : %.c) 没有明确的目标;它们是隐含的规则。 make 默认提供了许多隐式规则,这些是内置规则。
    • 你的问题:重新阅读这个描述,试图想象你对这个问题一无所知:这工作正常,然后我调用 Makefile 例如make first.o; make first 或者如果我将 EXECUTABLE = $(OBJECTS:.o=) 修改为 EXECUTABLE = $(OBJECTS:.o=.out)% : %.o 修改为 %.out : %.o。但是,如果我尝试以makemake first 调用编译,则会使用隐式规则。 你真的清楚吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多