joe@cit-vax.Caltech.Edu (Joe Beckenbach) (11/03/88)
Okay, all you make wizards out there, a rather silly question: How can I use shell variables to affect make variables? The intended use is to allow multiple selections of multiple compilers in one makefile. Eg, I've got program1, program2, and program3, with compiler1, compiler2; the behavior wanted is: make program1 compiler2 program2 compiler1 program3 where the makefile is: ------------ # Hypothetical makefile for multiple compiler usage # Different compilers (1 is default for makes) compiler1: CC=cc compiler2: CC=mycc # Different programs to be made program1: $(includes1) $(sources1) program2: $(includes2) $(sources2) program3: $(includes3) $(sources3) ------------ Alas, it appears that make not only imposes its aliases before passing the line onward to the execution shell [thus making make variables effectively read-only, overlaid, environment variables invisible to the shell], but also make appears to spawn off a new execution shell for each line [thus making additions to the environment impossible]! Try this: ------------- # Intent: print "ping\nping" pong: eval PUNG=ping ; echo $$PUNG echo $$PUNG ------------- this-vax% make pong eval PUNG=ping ; echo $PUNG ping echo $PUNG this-vax% _ --------------- Several alternatives present themselves that would allow for the same overall effect. Firstly, maintain parallel make files. Secondly, have the makefile adjust itself by using sed, then doing another make. Thirdly, have the makefile adjust a copy of itself and make using the copy. There are others, but none seem as elegant as letting the make variables and environment variables interact.... .... which can be done by making new defaults which ignore make's predefined aliases. But this is even more work than maintaining parallel copies. Any good ideas, aside from changes to make? And commentary on extending make to carry on environment variables, conditional changing of make aliases, and such? [We've already been through the $SHELL/$MAKESHELL discussions.] -- Joe Beckenbach joe@csvax.caltech.edu Caltech 256-80, Pasadena CA 91125 ... or have I not seen enough code yet to throw stones? 1/2 :-)
andrew@alice.UUCP (Andrew Hume) (11/05/88)
the only way i know to communicate between two independently spawned a.out's is the file system. thus, a simple solution might be .c.o: `cat CC` `cat CFLAGS` -c $goo (whatever goo is these days) compiler1: echo compiler1 > CC; echo 'special flags' > CFLAGS and so on. depending on how correct you want things, you may want to have all the .o's depend on CC and CFLAGS.
leo@philmds.UUCP (Leo de Wit) (11/05/88)
In article <8495@cit-vax.Caltech.Edu> joe@cit-vax.caltech.edu (Joe Beckenbach) writes: |Okay, all you make wizards out there, a rather silly question: | How can I use shell variables to affect make variables? Depends on which Make you're using. The System V Make and Sun's Make both add the current environment variables to Makes macros. But for instance Ultrix native Make does not (but there you can use /bin/s5make). | The intended use is to allow multiple selections of multiple |compilers in one makefile. Eg, I've got program1, program2, and program3, |with compiler1, compiler2; the behavior wanted is: | make program1 compiler2 program2 compiler1 program3 |where the makefile is: |------------ |# Hypothetical makefile for multiple compiler usage |# Different compilers (1 is default for makes) |compiler1: | CC=cc |compiler2: | CC=mycc |# Different programs to be made |program1: $(includes1) $(sources1) | |program2: $(includes2) $(sources2) | |program3: $(includes3) $(sources3) | |------------ Unless I'm missing something from your intent, this seems rather obvious: $ make program1 "CC = mycc" etc. will do what you want (this works with any make). The command line supplied macros overrule the makefile supplied ones (the different compiler lines don't work; leave them out; you can however supply one CC macro that will overrule Make's default unless overruled itself by a command line CC macro). However, you can have only one value for a certain macro at the time; to be able to use different values and also to be sure to use the correct compiler for a certain target, you could store this information in the makefile: # entry to make each target with its specific compiler all: $(MAKE) program1 "CC = mycc" $(MAKE) program2 "CC = cc" $(MAKE) program3 and make your targets with: $ make all | Alas, it appears that make not only imposes its aliases before passing |the line onward to the execution shell [thus making make variables effectively |read-only, overlaid, environment variables invisible to the shell], but also |make appears to spawn off a new execution shell for each line [thus making |additions to the environment impossible]! Try this: |------------- [ping-pong example omitted 8-] The spawning of a shell for each generation line is a known fact. About Make variables versus shell variables: these are totally different things (apart from the fact that some Makes DO assign the current environment variables to make macros), so saying make variables are read-only etc. makes no sense (no offense indented!). 'It's all in the quoting': # sample makefile CC = ls all: $(CC) # This is a Make macro, so expanded by make $$CC # This is a shell variable, so expanded by sh # end of sample makefile # sample run with a Make that doesn't use environment vars. $ CC=pwd export CC $ /bin/make ls News bin dead.article etc makefile mbox $CC /usr/leo # end of sample run Another property of Make's macros is that they have only one value, so assigning to the same macro more than once in a makefile has no effect (the last assignment is probably the one that will be used, unless there's also a command line version for that macro). | Any good ideas, aside from changes to make? Maybe mine might be good enough to help you somehow. | And commentary on extending make to carry on environment variables, |conditional changing of make aliases, and such? Read about the Sun's Make. It has diverse enhancements that will interest you. Leo.