我工作的项目组织在一个带有根Makefile的文件夹中,还有很多子项目,每个子项目都是一个包含自己的makefile的子文件夹。
根Makefile调用make到每个子目录(make -C
命令)。对象文件的生成与源文件处于同一级别。
我想命令root make命令将目标文件生成(和检索)重定向到指定的build_dir。有一个简单的方法吗? (而不是修改每个子项目中的每个Makefile)。
答案 0 :(得分:2)
没有可以阻止您修改每个Makefile的解决方案。
Makefile
和make
并不神奇。 Makefile
包含用于编译每个源文件的命令行。因此,为了能够生成指定目录中的所有目标文件,您必须修改每个Makefile
以更改此命令行添加选项,告诉 where 放置目标文件。
答案 1 :(得分:2)
这是一种黑客行为,但您可以使用编译器包装器和vpath
的组合来完成此操作。
假设我们有foo.c
:
#include <stdio.h>
int main() {
printf("hi there\n");
return 0;
}
和bar.c
:
int bar() {
return 1;
}
将vpath %.o obj
置于Makefile中将告诉make
在obj/
目录中查找目标文件。但我们需要告诉编译器将目标文件写入obj/
目录。 gcc
没有这样的选项 - 但我们不必使用gcc
,我们可以编写自己的编译器包装器,使用修改过的命令行调用gcc
。
cc-wrapper
:
#!/bin/bash
OUTDIR=obj
#
function push() {
# usage: push ARRAYNAME ARG
# adds ARG to the end of ARRAY
eval $1[\${#$1[@]}]="\$2"
}
ARGS=()
change_dir=false
mkdir -p "${OUTDIR}"
for (( i = 1; i <= $#; i++)); do
eval arg="\${$i}"
if $change_dir; then
arg="${OUTDIR}/${arg}"
change_dir=false
fi
if [ -e "${OUTDIR}/${arg}" ]; then
arg="${OUTDIR}/${arg}"
fi
if [ "${arg}" = "-o" ]; then
change_dir=true
fi
push ARGS "${arg}"
done
echo gcc "${ARGS[@]}"
exec gcc "${ARGS[@]}"
这是一个丑陋的shell脚本,但它所做的只是修改一些参数:
-o
,请将obj/
添加到此参数的开头obj/
中的文件,请将obj/
添加到开头然后拨打gcc
。
然后Makefile是:
CC=./cc-wrapper
vpath foo obj
vpath %.o obj
foo: foo.o bar.o
clean::
rm -rf foo.o bar.o foo obj
现在,所有对象都进入obj/
并make
正确跟踪依赖关系。
需要进行一些调整才能让它为生产做好准备 - 你可能希望用像Python这样的易于理解的语言重写脚本 - 但这应该可以帮助你开始。
答案 2 :(得分:0)
你的意思是类似于
的后备目标%:
make -C $(dir $@) $(notdir $@)
这样你就可以了
make somedir/sometarget