How to use make file functions with $# to generate prerequisites? - function

I want to extract the name of a prerequisite from the target.
TARS= zabc zbcd zcde zdef
# and I want abc.o to be a prerequisite for zabc
$(TARS): $(patsubst z%,%.o,$#) z.c
gcc -c -o $# $^
However, this is not working.
Consider the following:
TARS= zabc zbcd zcde zdef
# and I want abc.o to be a prerequisite for zabc
$(TARS): $(patsubst z%,%.o,zabc) z.c
gcc -c -o $# $^
Ignore the TARS in above code but this works for make zabc.
So I want to know how to use $# as an argument in the function for getting the prerequisite name.

The short answer is, you can't. Automatic variables, as made clear in the documentation, are only set inside the recipe of a rule, not when expanding the prerequisites. There are advanced features you can take advantage of to work around this, but they are intended only to be used in very complicated situations which this isn't, really.
What you want to do is exactly what pattern rules were created to support:
all: $(TARS)
z%: z%.o z.c
gcc -c -o $# $^
That's all you need.
ETA
GNU make doesn't provide any completion capabilities, so you'll need to figure out where that completion is done and how it works, to know what you need to have in your makefile to have it work. If it only completes on explicit targets, you can either just make them like this:
all: $(TARS)
$(TARS):
z%: z%.o z.c
gcc -c -o $# $^
Or you can use static pattern rules instead:
all: $(TARS)
$(TARS): z%: z%.o z.c
gcc -c -o $# $^
I didn't understand the last sentence in your comment below.

Related

I can not understand the output of patsubst in a makefile

This is the guilty makefile :
$ cat -n example.mak
1 define this
2 $(patsubst $(1)/%.o,%.o,why_this_does/that.o)
3 $(patsubst butnot/%.o,%.o, butnot/but_not_that.o)
4 endef
5
6 why:
7 $(info $(call this, why_this_does) ?)
And this is my question :
$ make -f example.mak
why_this_does/that.o
but_not_that.o ?
make: 'why' is up to date.
The root cause is not in patsubst but in call. The manual has a note:
A final caution: be careful when adding whitespace to the arguments to call. As with other functions, any whitespace contained in the second and subsequent arguments is kept; this can cause strange effects. It’s generally safest to remove all extraneous whitespace when providing parameters to call.
and indeed, if you replace
$(info $(call this, why_this_does) ?)
by
$(info $(call this,why_this_does) ?)
you get what you want.

Does CUPS have properties for "margins"?

I cannot find what properties of CUPS must be used, for printer margins, left/top/etc. Maybe CUPS dont support margins at all? I wanted to add margins support to Lazarus CUPS code.
Not sure if I understand your question correctly...
Note, that the support of controlling margins on the printed paper is dependent on the file type you submit for printing. This may not be supported for the one you want to print!
Assuming you print a TEXT document, here are the controls offered by CUPS lp command to submit the document as a print job to a CUPS printer with a custom page appearance:
lp \
-h cupsserver \
-d printername \
-o cpi=11 \
-o lpi=4 \
-o page-bottom=36 \
-o page-top=72 \
-o page-left=100 \
-o page-right=6 \
textfile.txt
The '-h cupsserver' part is optional and can be skipped if the queue is defined on your localhost. The 'cpi' parameter (characters per inch) determines the width of each character on a line. 'lpi' (lines per inch) works similar. 'page-top/bottom/right/left' is the margin in PostScript points. (72 points are one inch.)
If you submit a PDF file instead of text (which is a format that already internally has cast its page properties, including margins, into its code), the following should work, but I haven't tested it:
lp \
-h cupsserver \
-d printername \
-o fitplot=true \
-o page-bottom=36 \
-o page-top=72 \
-o page-left=100 \
-o page-right=6 \
pdffile.pdf
This should attempt to scale the page contents, but will probably scale more than you expect since it cannot do a "fluid" scaling to respect all the wanted borders (only a "preserve original page ratio" scaling).

how to make a shell script function able to either specify arguments in command line or get them from a pipe?

For example, I want to write a function called fooFun, which will do some process on a PDF file. I'd like to make it able to run on both of the ways as following:
$ fooFun foo.pdf
$ ls *.pdf | fooFun
Any ideas? Thanks.
I don't think you can easily do this with a shell function. A better idea is to make it a script, let it take command line arguments, and achieve the second style with xargs:
ls *.pdf | xargs fooFun
I agree with #larsmans, better to stick with passing arguments as parameters. However, here's how to achieve what you're asking:
foofun() {
local args arg
if [[ $# -eq 0 ]]; then
args=()
# consume stdin
while IFS= read -r arg; do args+=($arg); done
else
args=("$#")
fi
# do something with "${args[#]}"
}

How to generate a clean patch from Mercurial?

The diff command, even using git option, includes path prefixes commonly used on DCS:
--- a/file.ext
+++ b/file.ext
So applying such patches you should need to using -p1 instead of -p0.
Is there any way to generate clean patched from Mercurial?
Mercurial won't emit -p0 patches. As #Ringdig points out, they're very seldom what you want.
You could adapt the see script given in this answer : transforming patch strip level to remove the first directory instead of adding it.
Something like this should work (untested) :
sed \
-e 's!^--- a/!--- !' \
-e 's!^+++ b/!+++ !' \
< p1.patch \
> p0.patch
Assuming your "p1 patch" is in a file named p1.patch, the output will be in p0.patch

How can I wrap qrsh?

I'm trying to write a wrapper for qrsh, the Oracle Grid Engine equivalent to rsh, and am having trouble identifying the command given to it. Consider the following example:
qrsh -cwd -V -now n -b y -N cvs -verbose -q some.q -p -98 cvs -Q log -N -S -d2012-04-09 14:02:08 GMT<2012-04-11 21:53:41 GMT -b
The command in this case starts from cvs. My wrapper needs to be general purpose so I can't look specifically for cvs. Any ideas on how to identify it? One thought is to look for executable commands starting from the end backwards, which will work in this case but won't be robust as "cvs" could appear in an option to itself. The only robust option that I can come up with is to fully implement the qrsh option parser but I'm not thrilled about it since it will need to be updated with qrsh updates and is complicated.
One option is to set QRSH_WRAPPER to echo and run qrsh once. However, this then requires two jobs to be issued instead of one, adding latency and wasting a slot.