gnu make,microsoft nmake和posix标准有多相似/不同?
显然有"哪个操作系统?","哪个编译器?" 和"哪个链接器?",但我具体指的是makefile本身的语法,语义和命令行选项.
如果我根据gnu make的手册编写makefile,那么我需要注意哪些最重要的可移植性问题?
如何使用Make实现简单的回归测试框架?(如果重要的话,我正在使用GNU Make.)
我当前的makefile看起来像这样(为简单起见而编辑):
OBJS = jscheme.o utility.o model.o read.o eval.o print.o
%.o : %.c jscheme.h
gcc -c -o $@ $<
jscheme : $(OBJS)
gcc -o $@ $(OBJS)
.PHONY : clean
clean :
-rm -f jscheme $(OBJS)
Run Code Online (Sandbox Code Playgroud)
我想要进行一系列的回归测试,例如,expr.in测试一个"好"的表达式并unrecognized.in测试一个"坏的" 表达式,其中expr.cmp&unrecognized.cmp是每个的预期输出.手动测试如下所示:
$ jscheme < expr.in > expr.out 2>&1
$ jscheme < unrecognized.in > unrecognized.out 2>&1
$ diff -q expr.out expr.cmp # identical
$ diff -q unrecognized.out unrecognized.cmp
Files unrecognized.out and unrecognized.cmp differ
Run Code Online (Sandbox Code Playgroud)
我想在makefile中添加一组规则,如下所示: …
我一直在寻找一个小时,这些信息似乎无处可寻......
我希望能够提取(并可能使用)通过-j选项传递的请求make"jobs"的数量,或者在Makefile中通过Make子本身来创建自己.
到目前为止我见过的最有希望的是$(MAKEFLAGS)变量,但在我的系统上(如果我这样做,比如make -j2),这个变量的内容只是"--jobserver-fds = 3,4 -j".有没有办法让-j传递的实际工作数量?
我正在运行以下类型的管道:
digestA: hugefileB hugefileC
cat $^ > $@
rm $^
hugefileB:
touch $@
hugefileC:
touch $@
Run Code Online (Sandbox Code Playgroud)
目标hugefileB和hugefileC非常大,需要很长时间才能计算(并需要Make的强大功能).但是一旦创建了digestA,就不需要保留它的依赖关系:它会删除这些依赖关系以释放磁盘空间.
现在,如果我再次调用'make',将重建hugefileB和hugefileC,而digestA已经可以了.
有没有办法告诉'make'避免重新编译依赖项?
注意:我不想在'digestA'的规则中构建两个依赖项.
我有一个目录images/,我想build/images/从Makefile中复制到.该目录可能包含多个级别的子目录.最优雅的方式是什么?我想要:
make运行时都有完整的目录副本(即没有cp -r)images/应自动更新build/images/)make,所以没有rsync或cp -u如果可能的话我正在使用GNU make,因此允许GNU特定的东西.
我有一个仅限订单的先决条件的问题.这些根本不会首先执行.我是否误解了仅限订单的先决条件的工作方式?
以下make脚本:
.PHONY: mefirst mefirst2
mefirst:
@echo "I'm first!"
mefirst2:
@echo "I'm first too!"
normaltarget: normaltarget2 | mefirst2
@echo "normaltarget done"
normaltarget2: a b c
@echo "normaltarget2 done"
helloworld: normaltarget | mefirst
@echo "helloworld done"
.DEFAULT_GOAL := go
go: helloworld
@echo "go done"
a:
@echo a
b:
@echo b
c:
@echo c
Run Code Online (Sandbox Code Playgroud)
...打印出以下内容:
a
b
c
normaltarget2 done
I'm first too!
normaltarget done
I'm first!
helloworld done
go done
Run Code Online (Sandbox Code Playgroud)
......而不是我期望的:
I'm first!
I'm first too!
a
b
c
normaltarget2 done …Run Code Online (Sandbox Code Playgroud) 我们的构建系统中有一个冗长而复杂的Makefile.是否有一种很好的方法可以准确地跟踪为给定的make调用执行哪些目标?
是否有可能在默认情况下禁止命令回显Makefile?
我知道make在--silent模式下运行会这样做,因为它会为每个命令添加前缀@.
我正在寻找一个我可以包含在 Makefile中的命令或节,省去了乱扔垃圾@或让用户手动静音的麻烦.
所以我有这个基于Makefile的构建系统,我的用户觉得它运行得太慢了.为了这个问题,我们将性能定义为确定实际应该做什么所花费的时间.
我可以看到一些优化途径 -
make -C- 但我想先知道我的瓶颈在哪里.由于没有分析的优化是浪费生命,我想问:如何分析Makefile?
假设我继承的系统设计得相当好,即它已经实现了最常见的交易技巧:(主要是)非递归make,ccache,预编译头,自动生成的头依赖等).
......而且只是为了抢占一些可能的答案.我知道可能会有更快更好的构建系统然后GNU制作 - (就个人而言,我迫不及待地想看看CMake的人会对Ninja系统提出什么) - 但遗憾的是,交换构建系统并不在卡片中.
我试图编写一个Makefile与我的源文件和目标文件分开,我似乎无法找到实现这一目标的正确方法.我有两种方法可行,但我希望有人可以指出"正确"的方法来做到这一点.
我的项目被分成一个src和obj文件夹,Makefile与这些文件处于同一级别.
第一种方法使用通配符函数查找源文件,src然后使用文本替换来确定相应的目标文件.
SRC = $(wildcard src/*.cpp)
OBJ = $(SRC:.cpp=.o)
prog: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) $(LIBS) -o prog $(patsubst src/,obj/,$(OBJ))
%.o: %.cpp
$(CC) $(CFLAGS) -c $< -o $(COMPILE)/$(@F)
Run Code Online (Sandbox Code Playgroud)
这似乎有效,但是,每次运行make prog它都会重新编译所有目标文件.该OBJ变量必须具有src/的所有对象的前面,否则我得到了"没有规则,使目标".从好的方面来说,我可以轻松地使用prog 目标中的patsubst 来指定目标文件.
第二种方法类似,但在OBJ变量上使用vpath和文本替换:
vpath = %.cpp src
vpath = %.o obj
SRC = $(wildcard src/*.cpp)
OBJ = $(subst src/,,$(SRC:.cpp=.o))
POBJ = $(patsubst src/,obj/$(SRC:.cpp=.o))
prog: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) $(LIBS) -o prog $(POBJ)
%.o: %.cpp
$(CC) …Run Code Online (Sandbox Code Playgroud) gnu-make ×10
makefile ×9
directory ×1
nmake ×1
optimization ×1
portability ×1
profiling ×1
target ×1
testing ×1
wildcard ×1