Reputation: 18109
My issue is that in my make file I want to create the directory for all object code before building it and I cannot find a way to do this whithout having it impact the output of make. Also, i want to do it in ONE place and not for each and every object file.
I have tried this:
build: setup exe.i686
setup:
mkdir -p obj
exe.i686: $(OBJS)
@echo 'Building target: $@'
@echo 'Invoking: GCC C++ Linker'
${GCC_LOCATION}/Linux/i686/bin/i686-pc-linux-gnu-g++ $(OBJS) -o "exe.i686" -L...
@echo 'Finished building target: $@'
@echo ' '
where OBJS is all my object code. If I don't run setup first and there is no ./obj directory present the build will fail because of the missing directory when trying to build the object code.
Just to be clear, here is an example of how one object file is built:
./obj/Cell.o: ${CELL_ROOT}/main/cell/Cell/src/Cell.cc
@echo 'Building file: $<'
@echo 'Invoking: GCC C++ Compiler'
$(GCC_C++_BUILD) -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
I don't want to build the object code in the same directory I have my make file.
Now to the actual problem. When I build tarket "build" the first time like this everything works fine:
make build
But if I build it again and there are no updates in my source code (object code is up-to-date) it behaves like this:
[7:37] [user1] [/local/repo/user1/project_x/test/bin] $ make build
mkdir -p obj
[7:37] [user1] [/local/repo/user1/project_x/test/bin] $
In this situation I would have liked make to return the nothing-to-be-done string like this:
[7:37] [user1] [/local/repo/user1/project_x/test/bin] $ make build
make: Nothing to be done for `build'.
[7:41] [user1] [/local/repo/user1/project_x/test/bin] $
This would have been the case if I didn't have to depend on the setup target (which is added to .PHONY). Is the only alternative to do it for each object code file? That would be possible I suppose but I wanted to avoid that if possible as it clutters the make file quite a bit. At least in my opinion.
Thanks
Upvotes: 2
Views: 886
Reputation: 6581
This is similar to the earlier answer, just to make it easier to read:
build: exe.i686
$(OBJS): | obj
obj:
@if [ ! -d obj ]; then mkdir -p obj; fi
exe.i686: $(OBJS)
@echo 'Building target: $@'
...
Upvotes: 1
Reputation: 3302
Your target setup
is always executed because it has no dependency.
You have two choices:
(1) Make a stamp
or use some other mechanism so that there is an actual dependency. The directory itself can be the target but that may incur some wrinkles: see http://www.gnu.org/software/make/manual/html_node/Prerequisite-Types.html for an example.
Modified relevant extract from the linked article:
$(OBJS): | obj
obj:
mkdir $(OBJDIR)
(2) Suppress the output by testing for existence:
setup:
test -d obj || mkdir -p obj
Upvotes: 2