顶层目录中的Makefile问题,子目录中的源代码问题

顶层目录中的Makefile问题,子目录中的源代码问题,makefile,subdirectory,Makefile,Subdirectory,我有一个名为project的目录 它包含两个子目录,分别称为client和server,以及一个名为makefile的makefile client和server分别获得了名为client.c和server.c的源文件 我在属于该目录的源的子目录中没有任何单独的makefile。所有构建都由单个makefile完成。Makefile代码为 FLAGS=-W-Wall-g-pthread SERV=./server/server.c#我的服务器代码 CLI=./client/client.c#我的

我有一个名为
project
的目录

它包含两个子目录,分别称为
client
server
,以及一个名为
makefile
的makefile

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

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

FLAGS=-W-Wall-g-pthread
SERV=./server/server.c#我的服务器代码
CLI=./client/client.c#我的客户端代码
构建:svr cnt
svr:$(服务)
cc$(标志)$(服务)-o./server/server.out
cnt:$(CLI)
cc$(标志)$(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/
    目录中
  • 使用
    makesvr
    ,编译
    server/server.c
    ,并将其可执行文件输出到
    server/
    目录中
  • 使用
    make,编译
    server/server.c
    client/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

但对它不太满意。我确信我想做的事情非常简单,应该有一些方便的方法。那我该怎么做呢?

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

当makefile选择要重建的目标(“cnt”是这些目标之一)时,它会将目标文件的更新时间与其预请求的更新时间进行比较。由于在运行“make cnt”时,名为cnt的文件不存在,因此名为so的目标被认为需要更新。因此,命令运行并不会产生名为CNT的强>文件,因此下一次运行也会考虑更新。 有两种可能的解决办法。第一个是为目标指定与规则命令将生成的文件相同的名称。所以,你可能会这样结束:

client/client.out: $(CLI)
    cc $(FLAGS) $(CLI) -o ./client/client.out
顺便说一下,你的问题与目录无关。您还应该阅读.PHONY指令,使用$(CC)而不是CC并阅读,这可能非常有用。

尝试以下方法:

SERVO =./server/server.out CLIO =./client/client.out .PHONY: srv cnt build build: svr cnt svr: $(SERVO) cnt: $(CLIO) $(SERVO) $(CLIO): %.out : %.c cc $(FLAGS) $^ -o $@ 伺服=./server/server.out CLIO=./client/client.out .虚假:srv cnt构建 构建:svr cnt svr:$(伺服) cnt:$(CLIO) $(伺服)$(CLIO):%。输出:%.c cc$(标志)$^-o$@ 现在,您可以制作srv、cnt或只是制作。

你可以做一些稍微复杂一些的事情,但现在这就足够了。

我不能理解。我在制作makefile方面没有太多经验,所以我想稍后我会阅读手册。现在我将继续将cnt复制到我的客户机目录。谢谢。好的,但无论您是否真的需要,您每次都会重新制作client.out。