我怎样才能让目标取决于具体的文件名?

问题描述 投票:0回答:3

我试图用Makefile管理在我的项目数的任务(例如包装它的分布)。不过,我不能找到一种方法,依赖于特定的文件名,而不是一些自动魔法。见例如:

+   $ cat Makefile
dist: ctl
        echo "package it here"

+   $ tree
.
├── ctl
└── Makefile

0 directories, 2 files

+   $ make
echo "package it here"
package it here

正如你所看到的,这工作正常。但它停止工作,当我创建的文件ctl.hctl.c的时刻:

+   $ touch ctl.{h,c}

+   $ make
cc     ctl.c   -o ctl
/usr/bin/ld: /usr/lib/gcc/x86_64-pc-linux-gnu/8.2.1/../../../../lib/Scrt1.o: in function `_start':
(.text+0x24): undefined reference to `main'
collect2: error: ld returned 1 exit status
make: *** [<builtin>: ctl] Error 1

+   $ tree
.
├── ctl.c
├── ctl.h
└── Makefile

0 directories, 3 files

我的假设是,make试图聪明,并认为ctlctl.c编译的程序。这是不是这样的情况。我怎样才能制止这种行为?

c++ c makefile gnu-make automake
3个回答
2
投票

该“隐含规则”创建ctl从当没有明确规定的规则创建ctl.c ctl时才使用。举例来说,如果ctl应该从源文件ctlcmd.ccommon.c进行编译,然后写:

ctl: ctlcmd.o common.o
        $(CC) $(CFLAGS) -o $@ $^

(该.o文件将使用另一种隐性规则.c文件被创建。)

如果ctl并不需要在所有(例如它是一个手写脚本)来重新创建,那么你可以为它编写的虚拟规则,如下所示:

# `ctl` is a hand-written file, don't try to recreate it from anything
ctl:
        touch ctl

你也应该写一些规则来告诉做什么它应该ctl.c做。


2
投票

请自带了一堆的模式规则,它力图相当难用。其中一人说,如何创建可执行foofoo.c的。这就是发生在你身上。

我个人不喜欢激烈的这些规则,通常使用-R参数禁用它们。

$ ls
ctl  ctl.c  Makefile

$ make -R
echo "package it here"
package it here

$ make
cc     ctl.c   -o ctl
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
make: *** [ctl] Error 1

现在,它不是很好,要求你的用户必须使用一定的参数。前一种方法是简单地取消所有的潜规则。您可以销毁文件的扩展,使得认为作为一个模式规则的适用候选人名单。一个简单的SUFFIXES:会做。

$ ls
ctl  ctl.c  Makefile

$ cat Makefile
.SUFFIXES:
dist: ctl
       echo "package it here"

$ make
echo "package it here"
package it here

0
投票

通常make假定所有目标将创建一个同名的文件。如果没有依赖关系被指定为你的榜样ctlmake试图猜测的依赖,例如,如果你有一个文件ctl.c它假定它可以使用标准的规则建立从ctl ctl.c

假设你的目标distctl绝不应建立为文件,你可以通过添加一行声明为伪目标

.PHONY: dist ctl

看到https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html

© www.soinside.com 2019 - 2024. All rights reserved.