Makefile error message: Nothing to be done - makefile

please I need your help!
In order to get a list of thumbnails associated with a list of photos, I've use the following Makefile (the project's directory has 2 subdirectories thumbs and pictures)
all: $(patsubst pictures/%.jpg, thumbs/%.jpg, $(wilcard pictures/*.jpg))
thumbs/%.jpg: pictures/%.jpg
convert -thumbnail 100 $< $*
The problem is that I always get the same error message "Nothing to be done for 'all'", as if there was no dependencies. :(
Has anybody an explanation for that?

It is a simple typo: just add the missing d to $(wildcard ...)
Make does not throw an error when you make a call to a function that does not exist, so the result of that function call is simply an empty string. This makes your all target have no dependencies, and there you are!
For future reference, I found this error by adding the following line at the beginning of the makefile:
$(info $(patsubst pictures/%.jpg, thumbs/%.jpg, $(wilcard pictures/*.jpg)))
The $(info ...) function will print out to the console, which can be very useful for debugging. In this case, it printed a blank line. To debug further, I tried this:
$(info $(wilcard pictures/*.jpg))
Which also dumped an empty string. At that point, all it took was some careful squinting :)

Related

Makefile example issue regarding dir variable

Hello I am a bit new to makefiles, i know the basics and thought I'd work through an example i found online. However i ran into something that doesn't seem right and i was hopping somone could help clear things up. The example can be found at the following link:
https://riptutorial.com/makefile/example/21376/building-from-different-source-folders-to-different-target-folders
My specific question is regarding the following line:
SOURCEDIRS = $(foreach dir, $(DIRS), $(addprefix $(SOURCEDIR)/, $(dir)))
I was wondering how the makefile could evaluate $(dir) when the dir variable was not assigned anywhere? is dir some sort of pre defined GNU Makefile variable or am i missing something?
Any help is appreciated, thanks
First, look up foreach. The function iterates through $(DIRS), assigning each word of it to dir in turn, and evaluating $(addprefix $(SOURCEDIR)/, $(dir)). This has the effect of prepending $(SOURCEDIR)/ to each word in $(DIRS).
Then look up addprefix. This function can do all of the work by itself, so foreach is completely unnecessary in this example. This will suffice:
SOURCEDIRS = $(addprefix $(SOURCEDIR)/,$(DIRS))

Make: evaluating result of call: recipe commences before first target

I have several files for my GNU make setup. In this.mk, I have
define this_template
THIS = $(1)
THIS_DIR = $(2)
THIS_LIBNAME = $(3)
THIS_EXTERNAL_DIRS = $(4)
...
endef
In my Makefile, I have
include this.mk
... # define VAR1 and VAR2
include util/make.mk
...
util/make.mk contains one line:
$(eval $(call this_template,UTIL,$(VAR1),plutil,$(VAR2)))
However, when I run make, I get
util/make.mk:1: *** recipe commences before first target. Stop.
Reading up on other questions that relate to this error message, what I'm understanding is that this error is caused by evaluating a string which begins in a way that looks like it's inside of a recipe. However, what I'm evaluating does not.
This error means that (a) the line begins with a TAB (or more specifically, with the character defined as .RECIPE_PREFIX if your version of GNU make supports it), and (b) it is not recognized as any sort of make command such as a rule introduction, etc.
Given what you've shared with us here, that cannot happen. So there must be something going on that you haven't shared with us. Maybe one of the other included makefiles is modifying the this_template variable to contain something else.
The way to debug eval problems is always the same no matter what they are: change the eval to info so that make will print out what it will evaluate. This usually makes it pretty obvious what the problem is. So use:
$(info $(call this_template,UTIL,$(VAR1),plutil,$(VAR2)))
$(eval $(call this_template,UTIL,$(VAR1),plutil,$(VAR2)))
and see what make shows you.

Makefile: what is "#-"?

In a makefile I use there is #-, that is not mentioned in any makefile tutorial I could find.. Could you please explain what #- is for?
For example:
#- $(RM) *.o
The at-sign # tells Make to not print the command line before executing it.
(Manual: Recipe echoing)
The minus sign - tells Make to ignore the result of the command and not fail the target if it was unsuccessful.
(Manual: Errors in recipes)
In your case it's just both of them being used, because somebody did not want to pollute the output with the erase command, and did not want to fail the build if anything goes wrong with the deletion either.

GNU Make -- Append to a variable all targets matching a pattern

Before I start, I'll mention that I'm not using GNU Make in this case for building a C/C++ project.
Makefile:
DEST_DIR = build/
SRC_DIR = src/
$(SRC_DIR)a/ : $(SOMETHING_ELSE)
$(DO_SOMETHING_TO_GENERATE_A_DIR)
$(DEST_DIR)% : $(SRC_DIR)%
cp -r $^ $#
ALL_DEPS += <SOMETHING>
... more code which appends to ALL_DEPS ...
.PHONY: all
all : $(ALL_DEPS)
I've got some files not generated via Make rules in $(SRC_DIR). (For the sake of this example, let's say there's a directory $(SRC_DIR)b/ and a file $(SRC_DIR)c .)
I want to append to ALL_DEPS all targets which represent files or directories in $(DEST_DIR) so that "make all" will run all of the available $(DEST_DIR)% rules.
I thought to do something like this:
ALL_DEPS += $(addprefix $(DEST_DIR),$(notdir $(wildcard $(SRC_DIR)*)))
But of course, that doesn't catch anything that hasn't yet been made. (i.e. it doesn't append $(DEST_DIR)a/ to the list because $(SRC_DIR)a/ doesn't yet exist when the $(wildcard ...) invocation is evaluated and the shell doesn't include it in the results returned by the $(wildcard ...) invocation.)
So, rather than a function which finds all (currently-existing) files matching a pattern, I need one which finds all targets matching a pattern. Then, I could do something like this:
ALL_DEPS += $(addprefix $(DEST_DIR),$(notdir $(targetwildcard $(SRC_DIR)*)))
If it matters any, I've got much of the GNU Make code split across multiple files and included by a "master" Makefile. The ALL_DEPS variable is appended to in any of these files which has something to add to it. This is in an attempt to keep the build process modular as opposed to dropping it all in one monster Makefile.
I'm definitely still learning GNU Make, so it's not unlikely that I'm missing something fairly obvious. If I'm just going about this all wrong, please let me know.
Thanks!
It is simply not possible to do what you're trying to do; you're trying to get make to recognise something that doesn't exist.
This is part of the reason why, in general, wildcards are bad (the other being that you can end up including stuff you didn't mean to). The right thing to do here is to explicitly create a list of source files (ls -1 | sed -e 's/\(.*\)/sources+=\1/' > dir.mk) and perform the patsubst transformation on that list.
If you have additional files that are generate as part of the build, then you can append them to that list and their rules will be found as you'd expect.

Make error of mixed implicit and normal rules

When building an open source project I met error of:
make subdir=manual -C manual ..=../ subdir_lib
Makefile:235: *** mixed implicit and normal rules. Stop.
Code from line 235 of the Makefile as follows:
235: $(objpfx)stubs ../po/manual.pot $(objpfx)stamp%:
236: $(make-target-directory)
237: touch $#
That error message is printed by GNU make when you have something that looks like a pattern rule output (containing a %) as well as something that looks like a normal output (no %) on the left-hand side of a : in a rule declaration. For example:
%.pat normal:
#echo $#
So on line 235 of your Makefile, you have managed to put together something that "looks like" that construct. To avoid the error, fix that declaration, most likely by splitting it into two:
%.pat:
#echo $#
normal:
#echo $#
Without seeing the complete makefile that produced this error there's not much more advice we can give you.
I am here to remind the successor, check your path, is there any space in it?
We wasted all afternoon on this!
In my case, the error was due to idiotically putting an extraneous : at the end of the dependency line:
%.o: %.cpp:
g++ -c -o %# $<
Just had this myself and it was due to a hidden space after a "/" in a variable definition i.e.
#accidental/invisible space left after the final "/" i.e...
DESTDIR=path/to/the/destination/directory/
# ...just here ^
#rule to make copies of text files...
$(DESTDIR)%.txt:$(SRCDIR)%.txt
The problem described in this question has been reported here
http://sourceware.org/bugzilla/show_bug.cgi?id=11873
The fix was indeed to split the rule, as suggested by Eric.
Completing Eric Melski answer, you can do this to avoid duplicating code everywhere:
define DEFAULTTARGET :=
#echo $#
endef
%.pat:
${DEFAULTTARGET}
normal:
${DEFAULTTARGET}
Check your path, check where you have saved your projects, there shouldn't be a space in the name of the directory. Save it along with system generated projects directory files if u have imported it from another source
maybe you have "space" character after path.
for example:
(this is a ' ' character at the end)
PATH_OUT = ../lib
then you use
$(PATH_OUT)/1.cc
and you will get this error

Resources