是否有**简单**的方法将对象文件创建重定向到Makefile项目的指定目录?

是否有**简单**的方法将对象文件创建重定向到Makefile项目的指定目录?,makefile,Makefile,我工作的项目被组织在一个文件夹中,其中有一个根Makefile,还有很多子项目,每个子项目都是包含自己Makefile的子文件夹 根Makefile将make调用到每个子目录中(make-C命令)。对象文件与源文件在同一级别生成 我想命令root make命令将对象文件生成(和检索)重定向到指定的build_dir中。有没有一个简单的方法可以做到这一点?(而不是修改每个子项目中的每个makefile)。你是说类似于 %: make -C $(dir $@) $(notdir $@) 这

我工作的项目被组织在一个文件夹中,其中有一个根Makefile,还有很多子项目,每个子项目都是包含自己Makefile的子文件夹

根Makefile将make调用到每个子目录中(
make-C
命令)。对象文件与源文件在同一级别生成


我想命令root make命令将对象文件生成(和检索)重定向到指定的build_dir中。有没有一个简单的方法可以做到这一点?(而不是修改每个子项目中的每个makefile)。

你是说类似于

%:
    make -C $(dir $@) $(notdir $@)
这样你就可以

make somedir/sometarget

没有阻止您修改每个Makefile的解决方案


Makefile
s和
make
不是魔法。
Makefile
包含用于编译每个源文件的命令行。因此,为了能够生成指定目录中的所有对象文件,您必须修改每个
Makefile
,以更改此命令行,并添加指示对象文件放置位置的选项。

这是一种黑客行为,但您可以使用编译器包装器和

假设我们有
foo.c

#include <stdio.h>

int main() {
    printf("hi there\n");
    return 0;
}
int bar() {
    return 1;
}
vpath%.o obj
放在Makefile中会告诉
make
obj/
目录中查找对象文件。但是我们需要告诉编译器将对象文件写入
obj/
目录
gcc
没有这样的选项,但我们不必使用
gcc
,我们可以编写自己的编译器包装,通过修改命令行调用
gcc

cc包装器

#!/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[@]}"
现在,所有对象都进入
obj/
make
正确跟踪依赖项


这需要进行一些调整,以便为生产做好准备。您可能希望用Python等可理解的语言重新编写脚本,但这应该有助于您入门。

不,对不起,我不是这个意思。换句话说,我试图问以下问题:是否可以覆盖创建对象文件的“目标”目录?不知道我是否更清楚?是否需要修改Makefile取决于其中的内容。如果compile命令的值类似于
-o$targetdir/…
,则可以传递
$targetdir
的值,否则,您可能需要处理makefile,或者避免使用它们。您的问题只是将目标文件从源目录中分离出来吗?您可以在根makefile中输入命令,以便在生成目标文件后移动它们。这是一个破解,但它会起作用。我或多或少遵循了您的解决方案:两个gloval变量VPATH和CXX。CXX指向我自己的scipts,它查找“-o”g++”选项并添加正确的路径。不管怎么说,对每个人来说,现在对我来说都很有效。
CC=./cc-wrapper

vpath foo obj
vpath %.o obj

foo: foo.o bar.o

clean::
    rm -rf foo.o bar.o foo obj