LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Software (https://www.linuxquestions.org/questions/linux-software-2/)
-   -   shell function inside foreach in Makefile (https://www.linuxquestions.org/questions/linux-software-2/shell-function-inside-foreach-in-makefile-761439/)

germallon 10-12-2009 02:28 PM

shell function inside foreach in Makefile
 
Hello all,

I am trying to append several files together as part of my build process. Say I have the following files:

a.js
b.js
c.js

and I want to have their contents inside a file named "all.js" after the build process is complete.

Here's what I got inside my makefile..

...
..
CAT = $(shell which cat)
MYFILES = $(wildcard $(SRCDIR)/*.js)
DESTFILE = $(DESTDIR)/all.js
..
...
mytarget:
$(foreach FILE, $(MYFILES), $(shell $(CAT) $(FILE) >> $(DESTFILE)))
..
..


After executing "make mytarget" I get the following error:

make: execvp: /path/to/src/dir/a.js : Permission denied
make: *** [mytarget] Error 127

It seems like the shell is attempting to execute the source file (second argument inside the shell function), which is not my intention. How can I stop this?

As you can see, I'm re-directing the output of the cat command to accomplish what I'm looking for. This has worked well in the past, but I'm open to try a different solution.

Thanks in advance.

chrism01 10-14-2009 12:39 AM

Well, I don't know anything about MAKEFILE syntax, but it seems to me that error is consistent with the fact that you've defined CAT to include 'shell', then you call it with shell as well; IOW

$(shell $(CAT)) => $(shell $(shell which cat))

makyo 10-14-2009 10:31 AM

Hi.

Here is a shell script that creates test files, lists the Makefile, and runs make:
Code:

#!/usr/bin/env bash

# @(#) s1        Demonstrate Makefile with wildcards, shell functions.

echo
set +o nounset
LC_ALL=C ; LANG=C ; export LC_ALL LANG
echo "Environment: LC_ALL = $LC_ALL, LANG = $LANG"
echo "(Versions displayed with local utility \"version\")"
version >/dev/null 2>&1 && version "=o" $(_eat $0 $1) make
set -o nounset

# Setup test files.

echo
echo " Makefile:"
cat Makefile

rm -f all.js
echo one > a.js
echo two > b.js
echo thr > c.js

echo
echo " Test files:"
for i in *.js
do
  echo
  echo " File $i:"
  cat $i
done

echo
echo " Results, names of *.js, content of \"all.js\":"
make
ls *.js
echo
cat all.js

exit 0

producing:
Code:

% ./s1

Environment: LC_ALL = C, LANG = C
(Versions displayed with local utility "version")
OS, ker|rel, machine: Linux, 2.6.26-2-amd64, x86_64
Distribution        : Debian GNU/Linux 5.0
GNU bash 3.2.39
GNU Make 3.81

 Makefile:
# Wed Oct 14 09:14:53 CDT 2009

SRCDIR  := .
DESTDIR := .

CAT      := $(shell which cat)
MYFILES  := $(wildcard $(SRCDIR)/*.js)
DESTFILE := $(DESTDIR)/all.js

# Need a command for a rule.
.PHONY: mytarget
mytarget:
        $(foreach FILE, $(MYFILES), $(shell $(CAT) $(FILE) >> $(DESTFILE)))
        @:

 Test files:

 File a.js:
one

 File b.js:
two

 File c.js:
thr

 Results, names of *.js, content of "all.js":
a.js  all.js  b.js  c.js

one
two
thr

See man pages, tutorials for details ... cheers, makyo


All times are GMT -5. The time now is 02:45 PM.