1

I'm trying to run:

SHELL   =/usr/bin/tcsh
foo: 
    @foreach i ( "a" "b" "c")\
    echo $$i\
    end

But I get this error

i: Undefined variable.
make: *** [foo] Error 1

I found this question and answer, but looks like it uses bash, not tcsh.

Community
  • 1
  • 1
Ari
  • 7,251
  • 11
  • 40
  • 70
  • 1
    I don't know what that error is about exactly but I'm not sure you'll be able to get this to work regardless. I didn't think `tcsh` allowed loops all on one line and the line-continuation support in make doesn't keep the lines newline separated as far as I know. You might be able to use `.ONESHELL` in newer make versions to help here though. – Etan Reisner Jan 28 '15 at 20:36
  • make sure make is really honoring your `SHELL = ...`? Just a target with `echo $$SHELL`? Good luck. – shellter Jan 28 '15 at 20:55
  • @EtanReisner: Thanks for teaching me using ONESHELL, but it didn't work in this case. – Ari Jan 28 '15 at 22:06

2 Answers2

1

The short answer is, you should not ever use tcsh, at least not for makefiles. My personal opinion is that it's high time csh and all derivatives were relegated to the dustbin of history, for all purposes. But they definitely are not usable in makefiles.

From that link, note for example: You can't combine multiline constructs in a csh using semicolons.

In addition to the problems they have with single-line scripts, they won't work with make's parallel jobserver support because they do nasty things with file descriptors.

MadScientist
  • 92,819
  • 9
  • 109
  • 136
  • thanks and I agree with your arguments, but for this project I really have to make it work in tcsh. – Ari Jan 28 '15 at 21:41
  • 1
    You can downvote my answer if you want, but the fact remains it won't work. See the link I posted. csh syntax is not capable of writing complex commands on a single line: it REQUIRES newlines. It also won't accept a complex commands containing newlines through the `-c` flag, for whatever reason, so ONESHELL doesn't work. So, unless you're willing to compromise on one of your base requirements then you can't succeed. – MadScientist Jan 28 '15 at 22:53
  • I did not downvote your answer, and I agree with your arguments about bash. It also seems to me that there is no direct way to do this. I just have to use tcsh, so as a workaround, I ended up calling a tcsh script that includes the foreach loop. – Ari Jan 28 '15 at 23:46
1
SHELL = /usr/bin/tcsh
# but we can't use its loop constructs as they're multi-line

foo: 
    @sh -c 'for i in a b c; do echo $$i; done'
reinierpost
  • 8,425
  • 1
  • 38
  • 70
  • Interesting! But I have to run everything in tcsh without shortcuts to other shells. – Ari Jan 29 '15 at 21:20
  • Right, so I take it this is an exercise. I really think you'll need to use another language to do the iteration. You can pick any language you like but it can't be `tcsh`: its two built-in iteration constructs `foreach` and `while` both necessarily span multiple lines, while `make` converts all recipes to single lines. – reinierpost Feb 01 '15 at 18:44
  • Are you allowed to call `tcsh` itself? In that case I know a solution, but it's your exercise so I'll leave finding that up to you. – reinierpost Feb 01 '15 at 18:47