Not sure how we can achieve this, I have two rules with the same output def.out but it depends on two different files (NOT at the same time), one is abc.xml and the other one is def.xml . In the makefile, when I call def.out, how does it know to call the first rule or the 2nd rule? Again, this def.out doesn't depend on abc.xml and def.xml at the same time.
def.out : abc.xml
......
def.out : def.xml
......
One suggestion is don't have two of the same target.
def_abc.out:
and
def_def.out:
... because you DO have to tell the make utility which rule you want to use, don't you? Or if you think the system is going to be able to figure it out on its own, then use the one target, but 'effectively two actions'.
def.out :
(action that tests what times this is)
(if it is "abc.xml time")
make def_abc.out
(else)
make def_def.out
You can add in code as you see fit to rename objects at the right time.
But you asked "how does it know to call the first rule or the 2nd rule?"
and my answer is "you either tell it when you call it, or tell it how to know when you code up the makefile".
Related
Using GNU make, I want to include a file, except if the current target is "clean".
That is, I want to do the equivalent of the following:
ifneq($(TARGET),clean)
-include somefile.txt
endif
But for that, I need a variable whose value is the target given on the command line (here named $(TARGET)). Such a variable does not seem to exist, and I can understand why, because you could have multiple targets on the command line, some of which you might want to include the file for, and others not. Actually, it would be fine if the file is included when there are other targets besides "clean". The only real problem I currently have is that when the file to be included does not exist, Make will try to build it, which is unnecessary when you're about to delete it again when executing the "clean" target.
So, is there another way to accomplish what I want?
You can use MAKECMDGOALS. Use it like this to handle multiple arguments on the command line:
ifeq (clean,$(filter clean,$(MAKECMDGOALS)))
-include somefile.txt
endif
However, this is often fraught because if you run make clean all or whatever, the include file won't be included even though it might be needed for all.
If you really need this to be reliable another way is to use recursion for your "top-level" arguments, running them one at a time in a sub-make.
You could usefully check that if clean is a target then it is the only target. Otherwise strange things can go wrong silently causing much wailing and gnashing of teeth. My most recent Makefile includes the following. (NB tested but not as yet used extensively).
ifeq (clean,$(filter clean,$(MAKECMDGOALS)))
ifneq($(strip $(filter-out clean,$(MAKECMDGOALS)))
$(error ERROR: can not make other targets with clean
endif
endif
I am using gulp for css and js processing. Sometimes I am missing the good old lazyness of the unix make command:
only generate transformed (whatsover, e.g. compilation) files from original files, that have actually changed (based on time stamps).
this is true from stage 1 to 2 (.cpp -> .o), stage 2 to 3 (linking or other stuff) whatever your dependency graph gives...
Make is not limited to source code: You can do image manipulation in several steps (efficiently ‘lazy’ generation of downscaled thumbs for example) or much else. All based on the fairly simple rule: „is at least one of the source files newer in respect to the current output file(s)?“
Unlike gulp, every step generates (more or less temporary) files, not a continuous pipe.
Is there a way, to get the same kind of lazyness in gulp**, i.e. when generating css?
only transform those (less|sass|stylus) files➝css if something changed (on the very respective file)
same for adding in browser prefixes, concat, minify
Admittedly, beyond the first 1 or 2 steps, the output is most likely already a single stream. So any change means ‘touched’. Still, when playing for example with minify options, I'd rather be lazy about the early transpile, prefixing and concat stages (drawing prior results from a temp file). Also on the javascript side ( typeScript, ... )
lazypipe and gulp-cache sound tempting but are something else, if I understand correctly. Saying .watch() is also only a partial answer, for the very first stage.
Is there a more generic approach?
If you're set on using Gulp, then this would seem to be the way to do it. It involves the gulp-cached and gulp-remember plugins.
I have a question, I have been reviewing some code and in one script, the authors use:
if(0){
#do something
}
Any help in what if(0) means?
The author (most likely) put the block of code in an if statement so that they could easily remove it if necessary without having to comment it out (or remove it). Similar to if(true) or if(false), you just need to change one value and it would skip that code.
Upon reviewing the code, developers should remove these kinds of statements once they've finalized all their source code not to confuse others.
Looks like something that will never be executed, since 0 = FALSE. Most probably this is a manual switch to test some code in parenthesis.
The following is a simplified makefile for a problem I'm having:
all: /tmp/makey/../filey
#echo All done
/tmp/filey:
#echo Filey
When I run make it says:
make-3.79.1-p7: * No rule to make target /tmp/makey/../filey', needed byall'. Stop.
Clearly it does not realize that /tmp/makey/../filey is the same as /tmp/filey. Any ideas how I can make this work?
Thanks
Ciao
-- Murali
Newer versions of GNU make have $(abspath ...) and $(realpath ...) functions you can apply to your prerequisites and targets to resolve the paths to the same string. If you've constructed these names yourself (for example, $(PREFIX)/../filey) then you can use $(dir $(PREFIX))filey instead.
Other than that, there's no way to solve this problem. Make uses string matching on targets and if the strings are not identical, they don't match (there's a special case to ignore the simple prefix ./) Even if make understood this distinction (by applying abspath itself to each target name, maybe) it would still not help in the face of symbolic links for example.
The only "real" answer would be for make to understand something about the underlying file system (device IDs and inodes for example) that let you talk about files without referring to their pathname. However, in a portable program like make doing this is problematic.
So this is my .pro file content (AMZI PROLOG) :
room(kitchen).
room(office).
room(hall).
room('dining room').
room(cellar).
door(office, hall).
door(kitchen, office).
door(hall, 'dining room').
door(kitchen, cellar).
door('dining room', kitchen).
location(desk,office).
location(apple,kitchen).
location(flashlight,desk).
location('washing machine',cellar).
location(nani,'washing machine').
location(broccoli,kitchen).
location(crackers,kitchen).
location(computer,office).
location(envelope,desk).
location(stamp,envelope).
location(key,envelope).
edible(apple).
edible(crackers).
tastes_yucky(broccoli).
here(kitchen).
is_located_in(T1,T2):-location(X,T2),is_located_in(T1,X).
What I want to achieve is that if I use, for example, is_located_in(X,office), then the result will be :
X=desk,
X=flashlight,
X=computer,
X=envelope,
X=stamp,
X=key,
no
(in no particular order).
That way, the result will include things that basically located in / on the object in the office, instead of things that located directly in the office.
This is the source : http://www.amzi.com/AdventureInProlog/a8recurs.php
There is stated that the code are fine, but when I test it, it just returned :
no
Please help. Thanks.
Try this (in this order):
is_located_in(T1,T2):-location(T1,T2).
is_located_in(T1,T2):-location(X,T2),is_located_in(T1,X).