Error in Makefile during a simple check for existing file - makefile

within a makefile I need to check if a file exists. Regarding to this answer from holms, I tried it in this way:
all:
ifeq ("","$(wildcard testFile)")
echo "File exists"
else
echo "File is missing"
endif
Nevertheless I get this error:
ifeq ("","")
/bin/sh: 1: Syntax error: word unexpected (expecting ")")
Makefile:3: recipe for target 'all' failed
make: *** [all] Error 2
Where is my mistake and how to interpret this syntax error message?

You've tabbed the make syntax lines, so make is passing them to your shell, get rid of the tabs (also reverse the conditional and remove the quotes)
all:
ifeq (,$(wildcard testFile))
echo File is missing
else
echo File exists
endif

Related

How do I exclude test files from makefile shell command?

I'm tyring to exclude test files in my makefile shell command.
When i run the following makefile target,
api-run:
${API_COMPOSE} sh -c "go run -mod=vendor cmd/serverd/*.go"
I get this error
go: cannot run *_test.go files (cmd/serverd/router_test.go)
make: *** [api-run] Error 1
I've tried adjusting the command into
api-run:
${API_COMPOSE} sh -c "for file in \$(ls cmd/serverd/*.go | grep -v _test.go); do go run -mod=vendor \$file; done"
but end up getting this error
sh: 1: Syntax error: "done" unexpected (expecting "do")
make: *** [api-run] Error 2

Checking the existance for a File in a Makefile

I have been trying to check the existence of a file in a Makefile without success:
I tried:
.PHONY test:
ifeq ($(shell test -e "/opt/local/bin/lame" && echo -n "yes"),"yes")
#echo 'File exists'
else
#echo 'File does not exist'
endif
I always get "File does not exist" when I run make test. And yes the file does exist!
I also tried the following:
.PHONY test:
ifeq ($(shell echo -n "yes"),"yes")
#echo 'File exists'
else
#echo 'File does not exist'
endif
Again, I always get "File does not exist" when I run make test.
So I must not be using the conditional test right.
what I am missing here?
I found a way to check for the existence of the file in a Makefile using wildcard. See below:
.PHONY test:
ifneq ("$(wildcard /opt/local/bin/lame)","")
#echo 'File exists'
else
#echo 'File does not exist'
endif
I am still confused why my precious attempt did not work.

Makefile Target Pattern with %

I am new to makefile.
All I want is, when a specific C file will be changed, I want to run one command. And finally from one folder, any of the C file will be changed then I want to run the same command with that filename.
.e.g.
ceedling test:filename
I have simple file called unittest.mk. I am not sure the following approach is correct or not.
I am ruinning the following command to run this file.
make -f unittest.mk StartUnitTest
Here is the unittest.mk file:
TEST_OBJS += \
D:\ModApp\Apps\Paymark\ModApp_Paymark\build\test\out\test_txn_admin.o
D:\ModApp\Apps\Paymark\ModApp_Paymark\build\test\out\test_txn_admin.o: D:\ModApp\Apps\Paymark\ModApp_Paymark\test\test_txn_admin.c
echo $(*F)
echo $#
echo $<
StartUnitTest:
#echo Start Unit Test
$(TEST_OBJS)
#echo End Unit Test
When I run this file, it is giving the following error.
Start Unit Test
D:\ModApp\Apps\Paymark\ModApp_Paymark\build\test\out\test_txn_admin.o
D:\ModApp\Apps\Paymark\ModApp_Paymark\build\test\out\test_txn_admin.o
process_begin: CreateProcess(D:\ModApp\Apps\Paymark\ModApp_Paymark\build\test\out\test_txn_admin.o, D:\ModApp\Apps\Paymark\ModApp_Paymark\build\test\out\test_txn_admin.o, ...) failed.
make (e=193): Error 193
make: *** [StartUnitTest] Error 193
Finally once this will work, actually I want a target pattern with % as the following:
D:\ModApp\Apps\Paymark\ModApp_Paymark\build\test\out\%.o: D:\ModApp\Apps\Paymark\ModApp_Paymark\test\%.c
echo $(*F)
echo $#
echo $<
I have found the issue. I have changed the target "StartUnitTest" to the following and it is working now. Removed the echo messages.
StartUnitTest: $(TEST_OBJS)
Thank you MadScientist. the "make -d" does helped me to find the issue.

Check existence of a directory in Makefile

I want that my Makefile creates a directory if it doesn't already exist on OS X. Otherwise I would use mkdir -p, but it deletes whatever the directory already contains and I don't want that. Here's what I've tried so far:
all:
DIR=../../aether3d_build
ifneq ("$(wildcard $(DIR))","")
mkdir $(DIR)
endif
It causes the following error:
DIR=../../aether3d_build
ifneq ("","")
/bin/sh: -c: line 0: syntax error near unexpected token `"",""'
/bin/sh: -c: line 0: `ifneq ("","")'

is the common Makefile idiom "> $#" (redirecting output to the target) wrong?

It is hard to believe, but it seems to me that the common Makefile idiom "> $#" is wrong. In particular, a target whose rule has a command that fails but uses this redirection will fail the first time around but not subsequent times. This is because even though the command fails, the redirection "succeeds" in the sense of creating an up-to-date (albeit zero-length) target.
It seems to me that the correct thing to do is to redirect to a temporary and on success rename this temporary to the target.
Here's and example Makefile:
bad-target:
command-that-will-fail > $#
good-target:
command-that-will-fail > $#.tmp || ( rm $#.tmp; false )
mv $#.tmp $#
clean:
rm -f bad-target good-target
And here's a sequence of commands illustrating the problem and its solution:
$ make clean
rm -f bad-target good-target
$ make bad-target
command-that-will-fail > bad-target
/bin/sh: command-that-will-fail: not found
make: *** [bad-target] Error 127
$ make bad-target
make: `bad-target' is up to date.
$ make good-target
command-that-will-fail > good-target.tmp || ( rm good-target.tmp; false )
/bin/sh: command-that-will-fail: not found
make: *** [good-target] Error 1
$ make good-target
command-that-will-fail > good-target.tmp || ( rm good-target.tmp; false )
/bin/sh: command-that-will-fail: not found
make: *** [good-target] Error 1
If you're using GNU make, you may also add the .DELETE_ON_ERROR special target to your makefile. This will cause make to delete the output file if there is an error during execution of the commands for that file:
all: foo.o
foo.o:
echo bogus! > $#
exit 1
.DELETE_ON_ERROR:
Here's an example of this makefile in action:
$ gmake
echo bogus! > foo.o
exit 1
gmake: *** [foo.o] Error 1
gmake: *** Deleting file `foo.o'
This is easier to use than your version, since you need not modify every rule in the makefile.
Perhaps this is an obvious solution, but many common commands provide a -o flag or similar. So instead of output redirection, you should use the rule:
target: target.dep
some_command target.dep -o $#
If the command fails, the output file will not be created. I haven't had many occasions to use output redirection in makefiles.
Yes, this is definitely something to bear in mind.
But sometimes you're OK with the command failing and you don't want to retry it, because the error would only repeat itself.
In that case leaving an empty result is OK. Just don't make subsequent processing count on there being meaningful content in that file.

Resources