Closed runiArnsbjornson closed 7 years ago
Hello
This behaviour is created by the way the -j x
mullti-thread option works.
It's pretty simple: when -j is active the makefile take the rule you ask to execute, look for dependencies (in this case the re dependencies are fclean
and all
) and run them in different threads concurently so fclean
and all
rule will be executed at the same time.
The problem is in case of a re
, the fclean rule must be always executed before the all rule, if it's not the case the all rule will just do nothing or recompile missing .o files but not all because fclean
does not have finished to remove all the object files.
the way to fix this is to change the re
rule like this:
re:
@$(MAKE) fclean
@$(MAKE) all
Doing this, the multi-thread option will just act on the all rule because there is nothing to multi-thread in this re
rule.
So what you are saying is you should never put a dependancy like this :
re : clean all @echo \033[32mRe done\033[0m
should the same be done on other make rules ? like the fclean (which has the clean rules dependancy) ? and put it like this :
fclean : @$(MAKE) clean @rm -rf $(NAME) @echo \033[31m Clean done\033[0m
it's pretty hard to find good explanation on the complex parts of makefiles, sorry if i bother with trivials questions
2017-05-03 13:55 GMT+02:00 alelievr notifications@github.com:
Hello
This behaviour is created by the way the -j x mullti-thread option works. It's pretty simple: when -j is active the makefile take the rule you ask to execute, look for dependencies (in this case the re dependencies are fclean and all) and run them in different threads concurently so fclean and all rule will be executed at the same time.
The problem is in case of a re, the fclean rule must be always executed before the all rule, if it's not the case the all rule will just do nothing or recompile missing .o files but not all because fclean does not have finished to remove all the object files.
the way to fix this is to change the re rule like this:
re: @$(MAKE) fclean @$(MAKE) all
Doing this, the multi-thread option will just act on the all rule because there is nothing to multi-thread in this re rule.
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/alelievr/libft-unit-test/issues/30#issuecomment-298890172, or mute the thread https://github.com/notifications/unsubscribe-auth/AVOZERyO3diz0FDUVz9lxyTkeEHhC2FRks5r2GshgaJpZM4NPHL7 .
There is no problem to put dependencies on fclean
rule because we don't matter if an object/executable is deleted before another.
It's the same for the all
rule with all your object files as dependencies, you just want all your source file to be compiled no matter the order so it's not a problem if -j run them concurrently or in a random order.
You need to care about dependencies only when you absolutely want one to be executed bore another:
task1:
@touch test
task2:
@test -r && echo "Hello world !" > test
task3:
@cat test
task4:
@rm test
task: task1 task2 task3 task4
In this Makefile, the task
rule call in order the taskX
dependencies, and they are design to work only if the previous is done.
Here is the result with and without -j option:
As you can see, with -j option, it's a undefined behaviour and without it's stable.
To fix this use @$(MAKE) rule
as i said before but if you you have a list of dependencies which not require the previous to be done it's useless:
task1:
rm -f src1.o
task2:
rm -f src2.o
task3:
rm -f src3.o
task4:
rm -f src4.o
task: task1 task2 task3 task4
This will work perfectly with or without -j option because you can change the dependencies order: if you write task: task4 task3 task1 task2
this will not change the final result which is not the case for the re
rule: if i write re: all fclean
it will not work.
I hope my explanations are not too unclear, here is a pretty good article describing the problem: https://www.cmcrossroads.com/article/pitfalls-and-benefits-gnu-make-parallelization
unable to compile because of the flag used (make -j 3 re) despite compiling perfectly when done myself with the same flags, can't explain it myself