- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我不确定是否有一些我不知道的内置变量或规则,或者 make 是否有问题,或者我只是疯了。
对于我的一个项目,我有一个如下的 makefile:
CC=g++
CFLAGS=-O3 `libpng-config --cflags`
LFLAGS=-lm `libpng-config --ldflags`
OBJS=basic_render.o render.o mandel.o
BINS=basic_render
.PHONY: all clean
all: $(BINS)
clean:
rm -f $(BINS) $(OBJS)
%.o: %.cpp
$(CC) $(CFLAGS) -c -o $@ $<
%: $(OBJS)
$(CC) $(LFLAGS) -o $@ $(OBJS)
构建时,我只想能够运行
make clean
make
构建 BINS 列表中的所有内容。
起初这一切正常,但由于某种原因,在我编辑源文件后行为发生了变化。
在编辑源文件之前:
$ make clean
rm -f basic_render basic_render.o render.o mandel.o
$ make
g++ -O3 `libpng-config --cflags` -c -o basic_render.o basic_render.cpp
g++ -O3 `libpng-config --cflags` -c -o render.o render.cpp
g++ -O3 `libpng-config --cflags` -c -o mandel.o mandel.cpp
g++ -lm `libpng-config --ldflags` -o basic_render basic_render.o render.o mandel.o
rm mandel.o basic_render.o render.o
我可以一遍又一遍地这样做,而且效果很好。在我对 basic_render.cpp
进行更改之后(实际上只是改变了几个常量),它突然变成了这样:
$ make clean
g++ -O3 `libpng-config --cflags` -c -o basic_render.o basic_render.cpp
g++ -O3 `libpng-config --cflags` -c -o render.o render.cpp
g++ -O3 `libpng-config --cflags` -c -o mandel.o mandel.cpp
g++ -lm `libpng-config --ldflags` -o makefile basic_render.o render.o mandel.o
rm mandel.o basic_render.o render.o
makefile:1: warning: NUL character seen; rest of line ignored
makefile:1: *** missing separator. Stop.
不仅make clean
试着编译程序,它编译了basic_render
输出设置在 Makefile
中, 覆盖 Makefile
本身。
编辑后basic_render.cpp
,我看了Makefile
,而且它没有改变,所以我的编辑器并没有改变 makefile 之类的东西。
那么,我做错了什么?
最佳答案
这是您的问题的 MCVE:
$ ls -R
.:
bar.c main.c Makefile
$ cat main.c
extern int bar(void);
int main(void)
{
bar();
return 0;
}
$ cat bar.c
int bar(void)
{
return 42;
}
$ cat Makefile
OBJS := main.o bar.o
BINS := prog
.PHONY: all clean
all: $(BINS)
%: $(OBJS)
$(CC) -o $@ $(OBJS)
clean:
$(RM) $(OBJS) $(BINS)
第一次制作:
$ make
cc -c -o main.o main.c
cc -c -o bar.o bar.c
cc -o prog main.o bar.o
rm bar.o main.o
停下来注意 10.4 Chains of Implicit Rules 的不良后果:
rm bar.o main.o
程序链接后所有目标文件都被自动删除,破坏了目的制作。应归咎于我们自己的隐含规则:
%: $(OBJS)
$(CC) -o $@ $(OBJS)
加上内置的隐式规则1:
%.o: %.c
# recipe to execute (built-in):
$(COMPILE.c) $(OUTPUT_OPTION) $<
它们一起构成了一个隐含的规则链,产生了所有的目标文件成为 intermediate files .
继续,让我们更新源文件:
$ touch main.c
再做一次:
$ make
cc -c -o main.o main.c
cc -c -o bar.o bar.c
cc -o Makefile main.o bar.o
rm bar.o main.o
Makefile:1: warning: NUL character seen; rest of line ignored
Makefile:1: *** missing separator. Stop.
我们的 Makefile 被链接破坏了:
cc -o Makefile main.o bar.o
手册中解释了这种困惑 3.5 How Makefiles Are Remade :
Sometimes makefiles can be remade from other files, such as RCS or SCCS files. If a makefile can be remade from other files, you probably want make to get an up-to-date version of the makefile to read in.
To this end, after reading in all makefiles, make will consider each as a goal target and attempt to update it. If a makefile has a rule which says how to update it (found either in that very makefile or in another one) or if an implicit rule applies to it (see Using Implicit Rules), it will be updated if necessary. After all makefiles have been checked, if any have actually been changed, make starts with a clean slate and reads all the makefiles over again. (It will also attempt to update each of them over again, but normally this will not change them again, since they are already up to date.)
(强调我的)。是否存在适用于 Makefile
的隐含规则?作为目标?是的,它是:
%: $(OBJS)
$(CC) -o $@ $(OBJS)
因为目标模式 %
匹配任何文件。如果我们恢复我们的破坏Makefile 并再次尝试相同的实验,这次是调试:
make -d >debug.log 2>&1
输出将向我们展示:
...
Reading makefiles...
Reading makefile 'Makefile'...
Updating makefiles....
Considering target file 'Makefile'.
Looking for an implicit rule for 'Makefile'.
...
...
Found an implicit rule for 'Makefile'.
...
...
Finished prerequisites of target file 'Makefile'.
Prerequisite 'main.o' is newer than target 'Makefile'.
Prerequisite 'bar.o' is newer than target 'Makefile'.
Must remake target 'Makefile'.
cc -o Makefile main.o bar.o
...
我们可以避免这个结果,也可以避免 self 挫败的自动删除我们的目标文件,通过不使用匹配任何隐式规则来执行我们的链式。通常的做法是通过以下方式从其目标文件制作程序明确的规则,例如
生成文件(二)
OBJS := main.o bar.o
BIN := prog
.PHONY: all clean
all: $(BIN)
$(BIN): $(OBJS)
$(CC) -o $@ $(OBJS)
clean:
$(RM) $(OBJS) $(BIN)
看来您很喜欢让 BINS
成为多个列表的选项程序:
I want to simply be able to run
make clean
make
to build everything in the BINS list.
但是考虑一下:
BINS := prog1 prog2
和食谱:
%: $(OBJS)
$(CC) $(LFLAGS) -o $@ $(OBJS)
作为在 BINS
列表中创建所有内容的方式,您将只创建相同的程序两次,有两个不同的名字。即使你想要这样做,做的方式它将是:
生成文件(三)
OBJS := main.o bar.o
BINS := prog1 prog2
.PHONY: all clean
all: $(BINS)
$(BINS): $(OBJS)
$(CC) -o $@ $(OBJS)
clean:
$(RM) $(OBJS) $(BIN)
运行方式如下:
$ make
cc -c -o main.o main.c
cc -c -o bar.o bar.c
cc -o prog1 main.o bar.o
cc -o prog2 main.o bar.o
[1] 你可以让 GNU Make 向你展示它所有的内置规则,以及所有其他的它针对特定构建的规则,使用 make --print-data-base ...
关于c++ - 我的 makefile 不断 self 编译;我究竟做错了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54546486/
让我们写一个简单的类在我的脑海中解释: class SomeClass { var happyToUsed = 10 } 并创建一个对象 let someObject = SomeClass(
采用 self 的方法与采用 &self 甚至 &mut self 的方法有什么区别? 例如 impl SomeStruct { fn example1(self) { } fn ex
请观察以下代码(Win10上的python 3.6,PyCharm),函数thread0(self)作为线程成功启动,但是 thread1(self)似乎与thread0(self)不同已设置。 se
backbone.js 开始于: //Establish the root object, `window` (`self`) in the browser, or `global` on the s
做的事: self = self.init; return self; 在 Objective-C 中具有相同的效果: self.init() 快速? 例如,在这种情况下: else if([form
我查看了关于堆栈溢出的一些关于使用[weak self]和[unowned self]的问题的评论。我需要确保我理解正确。 我正在使用最新的 Xcode - Xcode 13.4,最新的 macOS
我面临在以下模型类代码中的 self.init 调用或分配给 self 之前使用 self 的错误tableview单元格项目,它发生在我尝试获取表格单元格项目的文档ID之后。 应该做什么?请推荐。
晚上好。 我对在 Swift 中转义(异步)闭包有疑问,我想知道哪种方法是解决它的最佳方法。 有一个示例函数。 func exampleFunction() { functionWithEsca
我需要在内心深处保持坚强的自我。 我知道声明[weak self]就够了外封闭仅一次。 但是guard let self = self else { return }呢? ,是否也足以为外部闭包声明一
代码 use std::{ fs::self, io::self, }; fn rmdir(path: impl AsRef) -> io::Result { fs::remo
我检查了共享相同主题的问题,但没有一个解决我遇到的这种奇怪行为: 说我有一个简单的老学校struct : struct Person { var name: String var age:
我应该解释为什么我的问题不是重复的:TypeError: can only concatenate list (not “str”) to list ...所以它不是重复的,因为该帖子处理代码中出现的
我有一个 trait,它接受一个类型参数,我想说实现这个 trait 的对象也会符合这个类型参数(使用泛型,为了 Java 的兼容性) 以下代码: trait HandleOwner[SELF
这个问题在这里已经有了答案: Why would a JavaScript variable start with a dollar sign? [duplicate] (16 个答案) 关闭 8
我总是找到一些类似的代码newPromise.promiseDispatch.apply(newPromise, message),我不明白为什么不使用newPromise.promiseDispat
我看到类似的模式 def __init__(self, x, y, z): ... self.x = x self.y = y self.z = z ... 非
mysql查询示例: SELECT a1.* FROM agreement a1 LEFT JOIN agreement a2 on a1.agreementType = a2.agreementTy
self.delegate = self; 这样做有什么问题吗?正确的做法是什么? 谢谢,尼尔。 代码: (UITextField*)initWith:(id)sender:(float)X:(flo
为什么要声明self在类中需要的结构中不需要?我不知道是否还有其他例子说明了这种情况,但在转义闭包的情况下,确实如此。如果闭包是非可选的(因此是非转义的),则不需要声明 self在两者中的任何一个。
这个问题已经有答案了: What does the ampersand (&) before `self` mean in Rust? (1 个回答) 已关闭去年。 我不清楚 self 之间有什么区别
我是一名优秀的程序员,十分优秀!