help-make
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: Shell for evaluating .SHELLFLAGS


From: Cook, Malcolm
Subject: RE: Shell for evaluating .SHELLFLAGS
Date: Tue, 26 May 2015 23:13:18 +0000


> -----Original Message-----
> From: address@hidden [mailto:help-make-
> address@hidden On Behalf Of Afif Elghraoui
> Sent: Tuesday, May 26, 2015 2:36 PM
> To: address@hidden
> Subject: Re: Shell for evaluating .SHELLFLAGS
> 
> Hi, Malcolm,
> 
> On 05/26/2015 10:16 AM, Cook, Malcolm wrote:
> > Afif,
> >
> > Are you trying to get the output from different SQL recipes to go into
> different files.
> >
> 
> Yes
> 
> > This will be a problem when using sqlite3 as your make .SHELL.
> >
> > Why?  Because the contents of a make recipe is always passed to the
> .SHELL as a parameter.  Never on stdin.  But that is what you need.
> >
> > Why do you need the recipe on stdin?
> >
> > Because meta-commands (aka dot commands) such as .output are limited
> in where they can appear.
> >
> 
> Right. That's why I pass in the meta-commands using the init file with 
> sqlite3's
> -i flag.

This approach will not work if you want to intersperse meta-command with SQL

> > In particular, that are not understood when they appear in the contents of
> a multi-line string as the SQL parameter to sqlite3 .
> >
> > So, the workaround to this problem in general is this one line bash utility
> which you use as the .SHELL instead of sqlite3:
> >
> > #!/bin/env bash
> > ### bash1in: A bash utility script which pipes its last argument to a
> > ### process gained by executing all but its last argument.  Useful in
> > ### Makefiles where you want the recipes to appear on stdin of some
> > ### command other than the usual bash shell.  For example, to write
> > ### recipes in sqlite3 (allowing dot-commands), include the following in
> your Makefile:
> > ###         SHELL=./bash1in
> > ###         .SHELLFLAGS=sqlite3 ${DB}
> > ###         .ONESHELL:  # optional
> > cat <<< "${@:$#}" | "${@:1:$(($# - 1))}"o
> >
> 
> Thanks. That's an interesting way to do it.
> 
> >
> > Now you can write makefiles like this:
> >
> > ### FILE: sqlite3.test.mk - demonstration of using sqlite3 as
> > ### interpreter of Make recipes using utility bash script (in same
> > ### directory) `bash1in`.
> >
> > SHELL=./bash1in
> > .SHELLFLAGS=sqlite3 ${DB}
> > .ONESHELL:
> >
> > ${DB}:
> >     CREATE TABLE greeting (g string );
> >     INSERT INTO greeting values("Hello World");
> >     INSERT INTO greeting values("Hello sqlite3");
> >
> > db.out.schema:
> >     .output $@
> >     .schema
> >
> > db.out.select.%:
> >     .output $@
> >     select * from $*;
> >
> 
> What I have now passes ".output $@" as a shellflag using process
> substitution to make a dynamic sqlite init file for each recipe, so I
> don't have to write this for every rule.

I'm glad you got something working.  I'd be interesting in seeing the details 
of your final working solution.  This sounds like it has many moving parts.  

Also, what about recipes that don't need to generate any output file?  Or 
multiple? Notice in my example the ${DB} rule generates no output.  It should 
probably be labelled as .PHONY.   In my opinion, adding an ".output $@" exactly 
when and where you want to direct recipe output to the target is perspicuous 
(in the realm of makefile afficiandos, at least).

Cheers,

Malcolm
 
> > Which can be run like this:
> >
> >> make -f sqlite3.test.mk DB=db.t
> > CREATE TABLE greeting (g string );
> > INSERT INTO greeting values("Hello World");
> > INSERT INTO greeting values("Hello sqlite3");
> >> make -f sqlite3.test.mk DB=db.t db.out.select.greeting
> > .output db.out.select.greeting
> > select * from greeting;
> >> cat  db.out.select.greeting
> > Hello World
> > Hello sqlite3
> >> make -f sqlite3.test.mk DB=db.t db.out.schema
> > .output db.out.schema
> > .schema
> >> cat  db.out.schema
> > CREATE TABLE greeting (g string );
> >
> > What is nice about this approach is that it works with other interpreters.
> I've used this approach for instance with the R language as the interpreter.
> 
> I'll keep that in mind. I've played around with using R as the make
> SHELL. For that, I was able to get it working by using Rscript rather
> than R as the shell:
> 
> SHELL = /usr/bin/Rscript
> .SHELLFLAGS = --vanilla -e
> 
> that avoids the need for passing inputs on stdin, but it's good to know
> how to make it work with stdin.
> 
> 
> Many thanks and regards
> 
> Afif
> 
> 
> _______________________________________________
> Help-make mailing list
> address@hidden
> https://lists.gnu.org/mailman/listinfo/help-make



reply via email to

[Prev in Thread] Current Thread [Next in Thread]