标准:Makefile是一个GNU Make Makefile - 我对makepp,qmake,cmake等不感兴趣.他们都很好(特别是cmake),但这是为了工作和工作,我们使用GNU Make.最佳解决方案是纯Makefile解决方案,而不是解析为您制作的shell脚本.
我也不想做一个"继续失败"的解决方案 - 如果它被破坏了,它就会被打破,需要修复.
情况就是这样,我有一个并行构建多个目录的makefile - 如果其中一个失败,当然整个构建失败,但直到所有运行都运行完成(或失败).这意味着make实际失败的原因被埋没在make的输出结尾任意远的地方.
这是我所拥有的一个例子:
all: $(SUBDIRS)
SUBDIRS = \
apple \
orange \
banana \
pineapple \
lemon \
watermelon \
grapefruit
$(SUBDIRS):
cd $@ && $(MAKE) $(MFLAGS) 2>&1 | sed -e "s/^/$(notdir $(@)): /g"
Run Code Online (Sandbox Code Playgroud)
如果我运行'make -j 5'并且'orange'碰巧失败了 - 我想在make过程结束时看到这样的表
apple - passed
orange - FAILED
banana - passed
pineapple - passed
lemon - passed
Run Code Online (Sandbox Code Playgroud)
我考虑过&& echo"传递"> .result || echo"FAILED"> .result,但仍需要某种TRAP或__onexit()清理命令在退出时打印它们.
任何Makefile ninjas都有一个pure-makefile解决方案吗?
un-edit - 我的解决方案实际上并没有按照我希望的方式工作..简而言之!
(编辑:基于@Michael反馈的问题更准确)
在bash中,我经常使用参数扩展:以下命令default value在$VARNAME未设置时打印" " ,否则打印VARNAME内容.
echo ${VARNAME:-default value} #if VARNAME empty => print "default value"
echo ${VARNAME-default value} #if VARNAME empty => print "" (VARNAME string)
Run Code Online (Sandbox Code Playgroud)
我没有在GNU上找到类似的功能make.我终于在我写的Makefile:
VARNAME ?= "default value"
all:
echo ${VARNAME}
Run Code Online (Sandbox Code Playgroud)
但我对这个解决方案不满意:它总是创建变量VARNAME,这可能会改变某些makefile上的行为.
有没有更简单的方法来获取未设置变量的默认值?
我有这样的设置:
/Makefile
/foo/Makefile
/foo/bar/Makefile
/foo/baz/Makefile
Run Code Online (Sandbox Code Playgroud)
顶级Makefile包含一个调用的任务/foo/Makefile.此生成文件会在生成文件的子目录的列表(bar,baz在本例中).对于每个子目录,它调用Makefile:
$(SUB_DIRS):
$(MAKE) -C $@
Run Code Online (Sandbox Code Playgroud)
这对all任务来说是好的.但如果我想做别的事,我就会陷入困境.是否有可能将目标传递给子makefile列表?例如:
$(SUB_DIRS):
$(MAKE) -C $@ <task>
clean: $(SUB_DIRS)-clean # or something?
Run Code Online (Sandbox Code Playgroud)
或者我的整个概念是错的?
我想做一个语言依赖目标.特别是:我有一个源文件,我想创建不同的对象,其中添加到相应的语言文件夹.单个源文件在C-Flags中会有所不同,编译器会得到.只要我以静态方式使用它,它就可以正常工作.
de/info.o en/info.o es/info.o : info.c
$(ECHO) (DEP) $< for $@
Run Code Online (Sandbox Code Playgroud)
现在我想,如果它有点动态,那将是很好的,以防我将添加一个新的语言依赖文件.所以我使用了一个通配符如下:
de/%.o en/%.o es/%.o : %.c
$(ECHO) (DEP) $< for $@
Run Code Online (Sandbox Code Playgroud)
但现在它只是制造了第一个目标而忽略了其余的目标.Make-Debug打印以下内容:
Successfully remade target file `de/info.o'.
Considering target file `en/info.o'.
File `en/info.o' was considered already.
Run Code Online (Sandbox Code Playgroud)
以防万一:不,对象不存在.所以没有目标,但是现有的依赖,所以make应该执行规则.
编辑:找到该问题的解决方案.
define FOO
$(1)/%.o : %.c
$(ECHO) $$< for $(1)
endef
$(foreach lang,$(LANGUAGE_LIST), $(eval $(call FOO,$(lang))))
Run Code Online (Sandbox Code Playgroud)
灵感来自:http://www.gnu.org/software/make/manual/make.html#Eval-Function
由于条件指令ifeq经常用于比较从变量(通常包含空格)扩展的单词,我们可能希望并且实际上需要 Make来去除任何前导或尾随空格.
事实上,你可能有一个相反的观点,即Make应该逐字记录ifeq条件的所有参数,因为用户可能已经将这些空格作为"测试"的一部分,并打算让这些空白进行决策在评估此ifeq指令时,factor 为true或false.
我无法决定,哪一个更正确.
事实上,我并不孤单!
让自己无法决定,哪一个是正确的.因此,它可能会也可能不会剥离前导或尾随空格.
实际上,有时它只会剥离前导空格.
不令人失望,Make有时会 剥离尾随空格.
当然,检查的案例太多了,所以我只会"做"其中的几个.
makefile(VERSION 1)是:
ifeq ( a, a)
all::
echo 'true'
else
all::
echo 'false'
endif
Run Code Online (Sandbox Code Playgroud)
执行,我得到:
$ make -r
echo 'false'
false
Run Code Online (Sandbox Code Playgroud)
makefile(VERSION 2)是:
ifeq (a ,a )
all::
echo 'true'
else
all::
echo 'false'
endif
Run Code Online (Sandbox Code Playgroud)
执行,我得到:
$ make -r
echo 'false'
false
Run Code Online (Sandbox Code Playgroud)
makefile(VERSION 3)是:
ifeq …Run Code Online (Sandbox Code Playgroud) 我试图用MinGW/MSYS编译freetype是不成功的
这是我做的:
从cmd.exe我切换到MSYS:
C:\temp\freetype-2.3.5-1\src\freetype\2.3.5\freetype-2.3.5>bash
Run Code Online (Sandbox Code Playgroud)
然后调用configure脚本
bash-3.1$ ./configure
FreeType build system -- automatic system detection
The following settings are used:
platform unix
compiler cc
configuration directory ./builds/unix
configuration rules ./builds/unix/unix.mk
If this does not correspond to your system or settings please remove the file
`config.mk' from this directory then read the INSTALL file for help.
Otherwise, simply type `make' again to build the library,
or `make refdoc' to build the API reference (the latter needs …Run Code Online (Sandbox Code Playgroud) 使用GNU-make时,我的Makefile有一些模式规则:
%.o:%.c
gcc $< -o:$@
Run Code Online (Sandbox Code Playgroud)
这个规则由我添加.
但是当我确实犯了它时会给出一个错误,说没有规则来制作目标%.o并且不会构建目标.
有时,还有其他行为.当我说第一次做时它没有构建目标(它给出错误说没有规则来制作目标),但是当我说立即再次制作时,它确实构建正确.
因此,当我明确指定每个源文件时,它会首次自行构建目标.
编辑:我在Centos上使用GNU-make(v6.3我猜,不确定).这可能是一些权限/用户ID /组ID问题吗?
有什么指示可以了解可能发生的事情和解决方案吗?
谢谢,-AD.
与当运行GNU-制定规则-jN化妆创建jobserver跨submakes管理岗位数.此外,您可以通过为其添加前缀来"将作业服务器环境"传递给制作配方+- 例如:
target :
+./some/complex/call/to/another/make target
Run Code Online (Sandbox Code Playgroud)
现在我代替子make,我有一个(python)脚本运行一些复杂的打包操作(对于make来说太复杂).它可以遇到的一个动作实际上可以产生一个make命令.
package.stamp : $(DEPS)
+./packaging.py $(ARGS)
touch $@
Run Code Online (Sandbox Code Playgroud)
现在,当在packaging.py中调用make命令时
make[1]: warning: jobserver unavailable: using -j1. Add `+' to parent make rule.
Run Code Online (Sandbox Code Playgroud)
这是有道理的,因为无论是make设置的环境,都可能没有被python尊重或传递.
是否可以jobserver通过python程序将引用传递给子make-如果是这样,怎么样?
我想将带有源的目录与带有目标的目录分开。似乎从 Makefile 更改当前工作目录应该是最简单的解决方案。
由于以下缺点,明确的目标路径是不够的:
另请参阅Pauls 的规则 #3:
如果目标构建在当前工作目录中,那么生活是最简单的。
关于 VPATH——我也同意要求开发人员“在运行 make 之前切换到目标目录是一种痛苦”。
我在使用automake时遇到了以下错误.我知道你可以把AUTOMAKE_OPTIONS = subdir-objects"放在Makefile.am的顶部.但是如何为所有文件设置这种行为,所以我不需要逐个进行呢?
Makefile.am:454: warning: source file 'libs/esl/src/esl_threadmutex.c' is in a subdirectory,
Makefile.am:454: but option 'subdir-objects' is disabled
Makefile.am:454: warning: source file 'libs/esl/ivrd.c' is in a subdirectory,
Makefile.am:454: but option 'subdir-objects' is disabled
Makefile.am:454: warning: source file 'libs/esl/src/esl_json.c' is in a subdirectory,
Makefile.am:454: but option 'subdir-objects' is disabled
Makefile.am:454: warning: source file 'libs/esl/src/esl_buffer.c' is in a subdirectory,
Makefile.am:454: but option 'subdir-objects' is disabled
tests/unit/unit.mk:6: warning: source file 'tests/unit/switch_event.c' is in a subdirectory,
tests/unit/unit.mk:6: but option 'subdir-objects' is disabled
Makefile.am:854: 'tests/unit/unit.mk' …Run Code Online (Sandbox Code Playgroud)