The project I work on is organised in one folder with a root Makefile, and a lot of sub-project each one being a subfolder containing its own makefile.
The root Makefile invokes make into each subdirectory (make -C
command). Object files are generated at the same level as the source files.
I would like to order the root make command to redirect object file generation(and retrieving) into a specified build_dir. Is there a simple way of doing this ? (Instead of modifiying every Makefiles in every sub-project).
It's kind of a hack, but you can do this with a combination of a compiler wrapper and vpath
.
Suppose we have foo.c
:
#include <stdio.h>
int main() {
printf("hi there\n");
return 0;
}
and bar.c
:
int bar() {
return 1;
}
Putting vpath %.o obj
inside the Makefile will tell make
to look inside the obj/
directory for object files. But we need to tell the compiler to write object files into the obj/
directory. gcc
has no such option—but we don’t have to use gcc
, we can write our own compiler wrapper that calls gcc
with a modified command line.
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[@]}"
It’s an ugly shell script, but all it's doing is modifying some arguments:
-o
, add obj/
to the start of this oneobj/
, add obj/
to the startand then calling gcc
.
Then the Makefile is:
CC=./cc-wrapper
vpath foo obj
vpath %.o obj
foo: foo.o bar.o
clean::
rm -rf foo.o bar.o foo obj
Now, all your objects go in obj/
and make
tracks dependencies correctly.
It'll take some tuning to make this ready for production—you'll probably want to rewrite the script in a comprehensible language like Python—but this should help you get started.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With