请教一个关于 makefile 的问题

2018-11-20 16:17:51 +08:00
 codechaser
objects = display.o main.o

display : $(objects)
	@gcc -o display $(objects)

$(objects) : display.h
	@echo 正在编译程序

.PHONY : clean
clean :
	@-rm $(objects) display
	@-rm *.h.gch

同一个文件夹下面有main.c

#include "display.h"
#include <stdio.h>


int main(void){
    display();
    return 0;
}

display.h:

#ifndef DISPLAY_H_
#define DISPLAY_H_
#define TEST_STRING "I love you three times!"
void display(void);

#endif

display.c:

#include <stdio.h>
#include "display.h"

void display(void) {
    printf("Now %s is displayed.\n",__FILE__);
}

为什么像上面那样写 makefile 会报错?求教。

gcc: error: display.o: 没有那个文件或目录
gcc: error: main.o: 没有那个文件或目录
gcc: fatal error: no input files
compilation terminated.
make: *** [display] 错误 4

刚开始学 makefile,见谅。另外想问一下 makefile 有学的必要吗?

2408 次点击
所在节点    C
15 条回复
jasonyang9
2018-11-20 16:23:58 +08:00
纯乱改的:

```
objects = display.c main.c

display : $(objects)
@gcc -o display $(objects)

$(objects) : display.h
@echo 正在编译程序

.PHONY : clean
clean :
@-rm $(objects) display
@-rm *.h.gch
```
jasonyang9
2018-11-20 16:30:29 +08:00
以上是乱改的,不要跑`make clean`啊!!
shylockhg
2018-11-20 16:49:27 +08:00
你没有编译.o 吧,还是这是隐式规则
shylockhg
2018-11-20 16:51:05 +08:00
$(objects): 等价 main.o display.o : ,目标可以同时定义多个?
tmy
2018-11-20 16:58:39 +08:00
display : $(objects)
@gcc -o display $(objects) 这里相当与 gcc -o display display.o 而不是 display.c,已经有这样的错误提示了,没有指定源代码
codechaser
2018-11-20 17:16:42 +08:00
@tmy 按教程上说法是没有`display.o`它就会生成 display.o
codechaser
2018-11-20 17:17:07 +08:00
@shylockhg 是隐式规则
codechaser
2018-11-20 17:17:52 +08:00
@jasonyang9 这样是可以的,但我想知道为什么像上面那样写不行
codechaser
2018-11-20 17:21:19 +08:00
@jasonyang9 这样写就没问题
```c
objects = display.o main.o

display : $(objects)
@gcc -o display $(objects)

main.o : main.c display.h
@gcc -c main.c
display.o : display.c display.h
@gcc -c display.c
```
ccpp132
2018-11-20 17:22:13 +08:00
这是你自己指定了.o 生成的规则,命令执行成功了却不会产出对应的文件
Machard
2018-11-20 17:35:04 +08:00
```sh
sources = display.c main.c
objects = $(sources:.c=.o)

display : $(objects)
@gcc -o display $(objects)

$(objects) : .o:.c
@gcc -c $< -o $@
@echo 正在编译程序

.PHONY : clean
clean :
@-rm $(objects) display
@-rm *.h.gch
```
Machard
2018-11-20 17:37:03 +08:00
将 clean 中删除.h 语句删除。。。。。
jqin4
2018-11-20 17:58:34 +08:00
jqin4
2018-11-20 18:00:35 +08:00
我学 c 时一节课,现在忘光了,参考一下

# Makefile sample illustrating separate compilation and dependencies.

# Students are welcome to use this as a starter or model, but be sure
# to replace these comments with comments relevant to YOUR assignment
# (including your name and cats login!). If the reader has to wade
# through "junk comments" you will lose credit.

# Explanatory comments follow the ``real code.''
# Everything after the # on any line is a comment

# ===================================================================
# Here we define a few important "make" variables.
# CFLAGS is platform dependent. This one is for Linux.

CC = gcc
CFLAGS = -g -Wall -O0 -std=c99 -D_SVID_SOURCE

# The next line has the first target. Typing "make" without any names
# causes "make" to default to this target.
# A common first target would read "all: hex shuffle" but this is omitted
# because shuffle.c is not in this directory.
#
hex: hex.o readline.o
${CC} -o hex ${CFLAGS} hex.o readline.o

hex.o: hex.c readline.h
${CC} -c ${CFLAGS} hex.c

readline.o: readline.c readline.h
${CC} -c ${CFLAGS} readline.c

shuffle: shuffle.o readline.o
${CC} -o shuffle ${CFLAGS} shuffle.o readline.o

shuffle.o: shuffle.c readline.h
${CC} -c ${CFLAGS} shuffle.c

# ===================================================================
#
# The rest of this file is a tutorial and should not be submitted.
#
# Makefiles are used by the Unix "make" command. Do "man make" for
# (too much) information. A brief summary:

# A "make statement" goes on one or more lines.
# The first of these lines begins in the left margin.
# Subsequent lines of the same "statement" must be indented by
# one tab character (NOT spaces).
# Finally, put a blank line after the whole "statement".
# Make sure you do not have any blanks or tabs at the end of a line.

# THE ABOVE IS VERY IMPORTANT TO FOLLOW STRICTLY ON SOME PLATFORMS.
# READ IT AGAIN.


# Line 1 (the one that is not indented):
# The format is target_name, colon, dependency_names.
# White space is flexible. If this line needs to be continued
# due to a large number of dependencies, end it with backslash (\).
# Lines 2-n:
# The format is tab, unix_command (with make variables, maybe).
# WHAT IT MEANS:
# A "make statement" is like a recursive procedure. It says:
# To update target_name
# first update any of the dependency_name files that are
# not up to date (use them as recursive target_names).
#
# Now, if any dependency_name file is NEWER than the
# target_name file, execute the unix_commands on lines 2-n.
#
# Being a recursive procedure, it better have a base case.
# The base cases are dependency_names that do not exist as targets
# in the Makefile, AND do not conventionally require ``making'',
# because you, the programmer, create them, often with an editor.
# Their mere existence makes them up to date.
#
# Object (.o) files DO require making.
# Even if you do not include a .o file as a target name,
# "make" will try (probably not successfully, unless you are a
# "make" wizard) to make the .o file with a default unix_command,
# if it does not exist in the current directory.
#
# Normal make commands to issue for this Makefile are "make hex" and
# "make shuffle", because these are executable programs as opposed to
# modules. "make" figures out which modules, if any, need to be
# recompiled. If you want to see what make WOULD do, without actually
# having it do anything, type "make -n hex", etc.

# However, if you want to be sure readline.c compiles correctly, before
# you try to use it as a module in another program, do "make readline.o".
# That is not a typo. Re-read the previous sentence.

# Running "make" can generate many error messages. Do
# make hex >& make.log
# to cause the errors to go into the file make.log.
# When "make" finishes you can read the file with "view", "more", or "less".
#
# Many later error messages can be meaningless because they were caused
# by an earlier error. Always try to correct errors in order.
shylockhg
2018-11-21 09:12:51 +08:00
@Machard 这个好像有道理

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/509676

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX