0

我有一个名为project.

client它包含两个名为and的子目录server和一个名为Makefile.

clientserver分别获得了名为client.c和的源文件server.c

对于属于该目录的源,我在子目录中没有任何单独的 makefile。所有构建都由单个 makefile 完成。Makefile代码是

FLAGS = -W -Wall -g -pthread

SERV =./server/server.c      #My server code 
CLI =./client/client.c       #My client code

build:svr cnt

svr: $(SERV) 
    cc $(FLAGS) $(SERV) -o ./server/server.out
cnt: $(CLI)
    cc $(FLAGS) $(CLI) -o ./client/client.out

现在我跑了make cnt,它回复了

cc -W -Wall -g -pthread ./client/client.c -o ./client/client.out

问题是所有后续make cnt命令最终​​都会再次编译并输出上述文本,即使我没有更改./client/client.c

我被困在这里。不知道该怎么办。

我想做的是:

  • make cnt,编译client/client.c并输出其目录下的可执行client/文件
  • 使用make svr,编译server/server.c并在目录中输出其可执行文件server/
  • 并使用make, compile bothserver/server.c andclient/client.c` 并将其可执行文件输出到各自的目录中

但是由于我没有调用任何可执行文件svr并且 `cnt 我遇到的问题没有解决。

如果我将目标更改为./client/client.out而不是cnt然后调用make client/client.out,那会很好,正是我需要的,但我不想make client/client.out在终端中输入长命令

我得到的解决方法如下

cnt: $(CLI)
         cc $(FLAGS) $(CLI) -o cnt
         cp cnt ./client/client.out

但对它不是很满意。我确定我想做的事情真的很简单,应该有一些方便的方法来做这件事。那么我该怎么做呢?

4

2 回答 2

2

让我们制定你想要的。您希望不重建名为“cnt”的目标。您编写的makefile 对client.out 文件一无所知,因为它只出现在规则内的shell 命令中。Make 程序不会从 shell 命令中读取信息,它只会在那里进行替换并执行它们。

当 makefile 选择它将重建的目标(`cnt' 是这些目标之一)时,它会将目标文件的更新时间与其先决条件的更新时间进行比较。由于在您运行“make cnt”时,名为 cnt 的文件不存在,因此名为 so 的目标被认为需要更新。所以命令运行并且没有产生名为 cnt 的文件,所以下一次 make run 也会考虑更新它。

有两种可能的解决方案。第一个是为目标提供与文件相同的名称,规则命令将生成该名称。所以,你最终可能是这样的:

client/client.out: $(CLI)
    cc $(FLAGS) $(CLI) -o ./client/client.out

顺便说一句,您的问题与目录无关。您还应该阅读 .PHONY 指令,使用 $(CC) 而不是 cc 并阅读gnu make manual,这可能会很有帮助。

于 2009-08-23T18:44:47.303 回答
0

试试这个:

伺服 =./server/server.out
CLIO =./client/client.out

.PHONY: srv cnt 构建
构建:svr cnt
服务端:$(伺服)
cnt:$(CLIO)

$(SERVO) $(CLIO): %.out : %.c
    cc $(标志) $^ -o $@

现在您可以制作 srv制作 cnt或只制作.
您可以做一些更复杂的事情,但现在这应该足够了。

于 2009-08-24T16:36:39.957 回答