使用GNU make,是否可以创建一组在使用"--jobs"选项时永远不会同时安排的目标?
为了使这更具体,请考虑表单的makefile
p1: ...deps... # no parallelization conflicts (can run at the same time as p*, e*)
...rules...
p2: ...deps... # no parallelization conflicts (can run at the same time as p*, e*)
...rules...
p3: ...deps... # no parallelization conflicts (can run at the same time as p*, e*)
...rules...
e1: ...deps... # cannot run at same time as any other e*
...rules...
e2: ...deps... # cannot run at same time as any other e*
...rules...
e3: ...deps... …Run Code Online (Sandbox Code Playgroud) 获取当前正在执行的makefile所在目录的正确方法是什么?
我正在使用export ROOT=$(realpath $(dir $(lastword $(MAKEFILE_LIST))))并遇到一些问题,当使用完全相同的选项运行make时,会导致ROOT的值不同.大约90%的时间它具有正确的值,但在剩余的10%中有许多无效路径.
我正在尝试在我的项目中创建一个子目录(让我们称之为$PROJECT/child),它需要../Makefile.inc从其父项中提取Makefile(让我们称之为)$PROJECT/Makefile.inc.后来我想复制$PROJECT/child到其他地方,以便它可以独立运行$PROJECT.
有一个共同的Makefile需要包含在两个项目中并在复制子目录时发货,我希望它包含在两种情况中.所以我想我会在child构建过程中链接它,如果找不到的话.(我不想只是包含../Makefile.inc,因为当我复制项目时,这将消失,我不希望调用构建系统负责将其Makefile.inc放置到位.)
有了这些限制,这是一个可怕的黑客攻击,我已经想到这样做,在$PROJECT/child/Makefile:
HACK = $(shell test -f Makefile.inc || ln -f ../Makefile.inc .)
include $(HACK)Makefile.inc
Run Code Online (Sandbox Code Playgroud)
注意第二个命令上的额外特殊管道胶带.我必须实际包括,$(HACK)即使它最终$(shell ...)会变空,以便评估.;-)
是否有更清洁的方法来实现这一目标?
实际上我有一个库'cryptopp',我想要的是,当我对文件进行任何更改并发出make命令时,它应该处理在源目录中的任何文件中所做的更改.好吧,cryptoopp的GNUMake文件负责处理'.cpp'文件中的'if',而不是'.h'文件中的更改.
那么我可以在cryptopp的'GNUMakefile'中进行哪些更改,以便它查看所有已修改的头文件并重新编译依赖于'modified'头文件的所有文件.
我希望通过这个小脚本总结出我想要实现的目标.
DIRS = dir1 dir2 dir3 dir4 ...
OBJS =
all: GENERATE_OBJECT_FILES
GENERATE_OBJECT_FILES:
for curr_dir in $(DIRS); \
do \
$(join $(OBJS), `ls $${curr_dir}/*.o`); \
done
echo $(OBJS);
Run Code Online (Sandbox Code Playgroud)
如何使用Makefile中的脚本完成此操作?
我创建了一个用于makefile的宏:
TODO_MSG = $(warning TODO: $(1))
$(call TODO_MSG, This part of the msg displays fine, but this part does not)
Run Code Online (Sandbox Code Playgroud)
我可以通过以下方式解决这个问题:
BLAH := $(shell perl -e 'print join( " ", 2..200 )'
COMMA := ,
TODO_MSG = $(warning TODO:$(1)$(strip $(foreach x,${BLAH},$(if $(${x}),${COMMA}$(${x}))))
Run Code Online (Sandbox Code Playgroud)
...但我很好奇是否有任何东西可以为变量宏提供更明确的支持.
我遇到了这个Makefile(是通过一个名为sendip的开源项目找到的)
我对此文件有两个困惑-
.c文件在哪里被指定为依赖项?虽然所有像图书馆ipv6.so,tcp.so正在生成细,但此行是负责呢?我认为这是行.....对吗?
%.so: %.c $(LIBS)
$(CC) -o $@ $(CFLAGS) $(LIBCFLAGS) $+ $(LIBS)
Run Code Online (Sandbox Code Playgroud)
但$(LIBS)只指定一些.o文件。这是$+在做什么吗?
2,我从未听说过$+。我试图找到它,并在许多人来了,如同$?,$@,$<等,但从来没有见过这个。我认为它的行为类似,$?但仍然需要.c指定依赖关系。
生成文件:
#configureable stuff
PREFIX ?= /usr/local
BINDIR ?= $(PREFIX)/bin
MANDIR ?= $(PREFIX)/share/man/man1
LIBDIR ?= $(PREFIX)/lib/sendip
#For most systems, this works
INSTALL ?= install
#For Solaris, you may need
#INSTALL=/usr/ucb/install
CFLAGS= -fPIC -fsigned-char -pipe -Wall -Wpointer-arith -Wwrite-strings \
-Wstrict-prototypes -Wnested-externs -Winline -Werror -g -Wcast-align …Run Code Online (Sandbox Code Playgroud) 我正在尝试将make变量的值转储到文件中以供进一步处理.
到目前为止,我已经能够使用以下规则将值打印到命令行:
print-%:
@echo '$*=$($*)'
Run Code Online (Sandbox Code Playgroud)
您使用命令行调用的
make print-VAR
Run Code Online (Sandbox Code Playgroud)
我真的不想在stdout上,但打印到文件.GNU Make"文件"功能看起来像我应该使用的东西:http: //www.gnu.org/software/make/manual/html_node/File-Function.html#File-Function
该页面立即跳转到一个复杂的例子中,所以我已经实现了以下但似乎无法使它工作:它将@echo打印到stdout,但当我查看我的目录时没有output.txt文件.
printf-%:
@echo '$*=$($*)'
$(file > output.txt,$($*))
Run Code Online (Sandbox Code Playgroud)
我错过了什么?
编辑:好吧,看起来我可以使用
@echo '$($*)' > output.txt
Run Code Online (Sandbox Code Playgroud)
做我想做的事,但这仍然无法解释为什么我的文件调用不起作用.
当前的Makefile有这样的东西:
target1 : lib1.a lib2.a
target2 : lib1.a lib3.a
target3 : lib3.a
lib1.a:
$(MAKE) -C sub_dir all
Run Code Online (Sandbox Code Playgroud)
我想更改这个Makefile,以便在目标所依赖的任何地方lib1.a,它总是运行命令" $(MAKE) -C sub_dir all".换句话说,在上面的例子中,target1和target2将始终运行" $(MAKE) -C sub_dir all".有什么方法可以做到吗?
我知道以下不起作用:
target1 : lib2.a
$(MAKE) -C sub_dir all
target2 : lib3.a
$(MAKE) -C sub_dir all
target3 : lib3.a
Run Code Online (Sandbox Code Playgroud)
因为如果lib2.a没有更新,则该命令不会运行.我有一个限制,我只控制lib1.a,我无法改变lib2.a的构建方式.
任何帮助表示赞赏!
[ 更新 ]我最终得到了以下解决方案:
target1 : lib1.a lib2.a
target2 : lib1.a lib3.a
target3 : lib3.a
lib1.a: relay
.PHONY: relay
relay:
$(MAKE) -C sub_dir all
Run Code Online (Sandbox Code Playgroud)
嗨Etan,您指出的GNU帮助说FORCE不如.PHONY效率高,但从您的解释来看,在我看来FORCE更好.我误解了吗?你能评论我的解决方案吗?
A有一个制作目标foo/%.bar.它匹配以下文件:
foo/x/y/z.bar
foo/a.bar
现在,我想要一个prereq.o必须与文件位于同一文件夹中的先决条件.bar.因此,对于foo/x/y/z.bar先决条件应该是foo/x/y/prereq.o,foo/a.bar应该是foo/prereq.o.
怎么做到这一点?
我尝试使用这样的dir功能:
foo/%.bar : foo/$(dir %)prereq.o
但是,这不起作用,因为在扩展模式之前评估函数.那么它是怎样工作的?