I have the following code:
all: ./source/Listener.java ./source/ServerThread.java ./source/TestClient.java
javac -d target $(find ./source/* | grep .java)
When I run Make, I get this output
javac -d target
error: no source files
Makefile:2: recipe for target 'all' failed
make: *** [all] Error 2
When I run the javac command in bash, it compiles fine. Furthermore, when I run the 'find' section, i get a list of files like I wanted. Additionally, the file paths in line 1 are all accurate.
Any tips?
(I have to use the find function because there are a lot of files in use, and it increases over time. I trimmed it down to 3, but the bug is still there anyway)
CodePudding user response:
As RenaudPacalet said, I had to put an extra $ infront of the second line.
CodePudding user response:
If you want to execute shell commands in a Makefile, use this syntax : $(shell ...)
Warnings :
- The default shell is
sh
(useSHELL
macro definion to change it)- Example :
SHELL=/bin/bash
- Example :
- The dollar (
$
) symbol is special into Makefile and into bash script (if you want use it in shell script espace it with double dollar :$$
).- Example:
$(shell X=a_value; echo $$a_value)
- If you want the current process of sub-shell :
$(shell echo $$$$)
... ugly, no ?
- Example:
- Do you want really call shell? It's not portable. Assume it.
If you search your sources files or what ever, use wildcard
internal make
function.
Examples:
all: x.class y.class z.class
x.class: a.java dir_b/b.java dir_c/c.java
@echo "$$^=$^="
@echo "not portable command ..." $(shell find . -name "*.java")
# Better with deps in target definition
SRCS=$(shell find . -name "*.java")
y.class: $(SRCS)
@echo x_my_command $^
# Really better (portable)
SRCS=$(wildcard */*.java *.java)
z.class: $(SRCS)
@echo y_my_command $^
Output:
$^=a.java dir_b/b.java dir_c/c.java=
not portable command ... ./dir_b/b.java ./dir_c/c.java ./a.java
x_my_command dir_b/b.java dir_c/c.java a.java
y_my_command dir_b/b.java dir_c/c.java a.java