How can I figure out, from a make rule, what is the value of the make -j argument ? Is there something like an environment variable ? For instance if I run:
make -j4 something
I would like the something rule to display 4. The GNU make manual page suggests communication between the parent make and its children which could probably be used to extract this information. But how ?
Turns out this isn't at all easy actually.
John Graham-Cunning wrote an entire blog post about it here.
Related
here is my Make file.
look at target olmenu-proto1, it depends on olmenu-proto1_yacc.o
But I haven't define any target called olmenu-proto1_yacc.o.
Interestingly, when I invoke make olmenu-proto1,it works!
Strangely enough!
I want to know why it would do this, thank you!
Please include the relevant bits of your makefile in your question, rather than asking people to follow a link to another site. Especially one where it's impossible to view unless you enable a lot of javascript, which many people leave mostly disabled.
In any event, most likely the reason is because make can envision how to create targets by chaining together rules, even if you don't list the prerequisites explicitly. For more information see Chains of Implicit Rules in the GNU make manual.
In writing a function for fish shell I want to know if a lone wildcard (not part of a bigger expression) was used in the command arguments. Fish does the wildcard expansion before passing arguments to my function, so there is no easy way that I can see to do that, aside from check whether the arguments are the same as the output of ls. The inefficiency of that method makes me sad, though. Is there a better way to do this, without going into fish's source code?
EDIT:
Thanks for the input. Specifically, I am looking to add some functionality like zshell has for warning if there is a * in the arguments of rm. I know that there was an issue opened on GitHub specifically about this but I couldn't find the link again. I have typod, for example, rm * .o instead of rm *.o, and accidentally deleted all my code (... which I brought back from git, but still).
EDIT 2:
Here is the issue on GitHub: https://github.com/fish-shell/fish-shell/issues/1511
No, there's no way for a function to tell where its arguments came from. Maybe if you give more details about what you're really trying to accomplish, we can give another suggestion.
So I have a script, myscript.py, that produces a few output files, out/a.pickle, out/b.pickle, and out/c.pickle
And I have a Makefile that has the rule:
out/a.pickle: data/data.csv
myscript.py
Now, If I update the script, firstly, make out/a.pickle says there's nothing to be done here, even though the script has been modified. Isn't make supposed to check to see if things have been updated and then run them? Do I need to add myscript.py as a dependency to out/a.pickle, or something?
Secondly, is there a way to handle the fact that the script has multiple output files? Do I need to create a rule for each?
Make does not examine time stamps on executables. Otherwise, you would have to recompile the universe if gcc or echo or the shell is upgraded, and it's a slippery slope anyway; what if libraries or the kernel also changed in a way which requires you to recompile? You need human intervention at some point anyhow. So the designers of make simply drew the line at explicit dependencies.
(GNU Make has a lot of other built-in implicit dependencies, which are convenient. I vaguely believe that the original make didn't have any built-in dependencies at all. Anybody able to confirm?)
You can declare all the outputs in one rule:
out/a.pickle out/b.pickle out/c.pickle: myscript.py data/data.csv
./$^
(Notice how the script is included in the dependencies now. You might want to change that after the script is considered stable. Then you'll need to change the action as well.)
here I am again with another make issue Im trying to handle (hardly), I have set several values I want make to read, but when I try to change inside a loop it does not work; $(FOUND) stills being the same as it was first, what could I being doing bad? is other way to set variables or to change them into?
here's a part of my code related to this question:
$(shell for d in $(INPUT); \
do \
$(if $(FOUND) -eq 1, REL=$(REL)../); \
$(if $(findstring $(WORD),$(INPUT)), \
echo '$(WORD)../'; FOUND=1)\
done)
$(FOUND) variable is defined outside but want it to change when it gets $(WORD)
any suggestion for that???
thank you so much
There are several things wrong with the code above, so much so that it is difficult to understand your intention. Here is a partial list (sorry if I sound like Microsoft clippy)
The code $(if $(FOUND) -eq 1, REL=$(REL)../), looks like a mix between gnu-make syntax and shell syntax.
Your loop seems to be superfluous. You are not using the loop variable d, and you are using a construct that process the entire sequence. E.g.: $(findstring $(WORD),$(INPUT)
It seems that you are trying to generate code like echo '$(WORD)../', but the context of this code is unclear. If it is outside a rule, the code has no meaning. If it is inside a rule, it will evaluate too late to set a makefile variable. There is a way to work around this problem, but first you need to clarify your intention better.
I can only suspect you intended to have REL=$(REL)/.. or REL=../$(REL) but I can be mistaken.
Lastly it is important to understand that what you really should do in a Makefile is to describe a dependency graph, and let make figure out the order of operation needed to be performed. So a procedural approach such as may inferred from your code above should be minimized.
Edit:
If I read you correctly, you are trying to achieve a tricky goal in Makefile. Let me assure you that your inexperience is not the only stumbling block you have. Writing good Makefiles is hard. If you have any control over this, I strongly suggest to have a look at some other build solutions. For example, cmake can write good Makefiles for you.
If you are trying to calculate a base-dir or a relative-dir, please note that the concept of current-working-directory as saved in $(CURDIR) might or might not be what you expect.
For your question, you can indeed use a GNU make $(foreach ...) construct, but there are several functions that are designed to handle sequences without iterations, that might serve you better.
I'm no Makefile expert, and I was wondering if someone knew of some kind of analyzer or simulator that would start from the top-most Makefile all the way down to the inner-most Makefile, each time showing me the value of each variable and the order in which it goes through rules.
Thank you.
Most implementations of make offer the -d flag which will cause the program to print out everything it is doing, in great detail. The -n flag will cause make to do a dry-run, ie report what it would do but not actually do it.
Be warned, make produces a lot of output so you probably want to redirect it to a file for your later perusal.