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
Related
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.
I want to build a Makefile that looks like below:
binfolder := bin
objs := #...
bins := program1 secondprogram thethirdprogram
all: $(bins)
#does not work, how can I express this?
$(bins):%: $(binfolder)/%
$(binfolder)/%: $(objs) _mainobj_%.o
#g++ ...
Note the line that is not correct, but hopefully convey what I want accomplished. I want to be able to make targets without writing out the path myself, and without having to write an extra line per program. I guess the part of the problem is that i can not just use % alone as a target. How can I solve this?
It looks like your problem is with trailing whitespace:
binfolder := bin #<- notice trailing whitespace.
# bindfolder is actually "bin "...
So now your rule
$(bins):%: $(binfolder)/%
expands to:
program1 secondprogram thethirdprogram:%: bin /%
which is likely causing your problem. To check for things like this, you can add the following:
$(info binfolder is "$(binfolder)")
When I look all over the place for a simple thing and can't find it, it makes me wonder whether I'm doing something completely the wrong way. I have used frameworks where you type make targetname where targetname is not known by the makefile, so it has to pick up targetname as a makefile variable and figure out its dependencies from there. I'm trying to do that, but I can't figure out how, and apparently no one does this, because I can't find anyone talking about how to do it. They talk about everything else under the sun, but not how to get make hooplah to execute using hooplah.html as the top-level target.
A lot of searching and guessing has gotten me as far as the failing makefile below, and I'm so frustrated that here I am risking life and limb by asking a question on SO. In case it keeps me from harm, I'll mention that I've read this SO answer, and this, this, and this, as well as digging through a number of pages in the GNU makefile documentation, all to no avail.
I want to type make page-72 on the command line and get make to treat page-72.html as its top-level dependency throughout the makefile, not just in the top-level rule. The other rules need to know about page-72.html, but I can't figure out how to give them the information.
I've read about MAKECMDGOALS, but it looks like that's only useful for checking for specific target names; I'm looking for something that will allow any target name and treat it as an output filename. Below is what I have. It shows me page-72 due to the % target, and the $#.html dependency works, but no variable I have found yet allows the $#.html rule to know the name of the target that was specified on the command line.
%: $#.html
#echo "Top: dollar-at = $#"
$#.html:
#echo "html: $#, $%, $<, $?, $^, $+, $|, $*"
I get the following output:
html: .html, , , , , , ,
Top: dollar-at = makefile
Top: dollar-at = index
Am I getting this conceptually wrong? Is it just not done this way? Bonus points if anyone can help me get rid of Top: dollar-at = makefile. Cheers
Yes, you are getting it completely wrong :).
In none of the places you looked did anyone attempt to use an automatic variable such as $# in a prerequisite list as you've done above, and in fact that cannot work. Automatic variables are only set within the recipe of a rule, not within the prerequisite list.
As a result, after make expands your targets and prerequisites the $# variable is unset there and it expands to the empty string. So your rules look like this:
%: .html
#echo "Top: dollar-at = $#"
.html:
#echo "html: $#, $%, $<, $?, $^, $+, $|, $*"
Maybe that helps explain why you're getting the output you see.
In a pattern rule the stem (the part that matches the % pattern) must be the same in the target and prerequisite.
You want to write your rule like this:
%: %.html
#echo "Top: dollar-at = $#"
%.html:
#echo "html: $#, $%, $<, $?, $^, $+, $|, $*"
However, I really don't understand what you're trying to do. I don't know what you mean by a "top level dependency throughout the makefile". And I don't see, from the example you've given, how you expect make to build a x.html file.
To write a makefile, you need to create for yourself a set of steps that say: I want to build this target. To build it, it will use these prerequisites. And given those prerequisites, it will use this set of commands. Then, you repeat that recursively for any of the prerequisites that need to be built. You don't have to write rules for source files (things that don't have to be built). They already exist.
Once you have that set of steps it's pretty straightforward to turn them into makefile rules.
The point is that I want to have some dependencies centralized in one variable, but the dependencies themselves are contained in variables.
a=meow
b=squeek
$(a):
touch $#
$(b):
touch $#
targs=$(a) $(b)
all: $(targs)
In the real case rules for a and b differ so I need them to be in separate targets.
When I try to build such a target, only last nested dependency gets executed:
$ make
touch meow
$ ls
. .. Makefile meow
Could anyone please explain me how do I fix the situation or where I'm wrong?
I can make a phony target like targs: $(a) $(b), but if there's a way to keep the structure I mentioned, I'd like to know about it.
Thanks in advance!
UPD: solved. My mistake: instead of running make all I ran make and make executed the first target instead of all.
Make's default is to use the first target in the Makefile. Either move the all target to the beginning or use the following line somewhere in your Makefile
.DEFAULT_GOAL := all
My makefile defines a link command:
prod_link = $(LINK) $(LINK_FLAGS) -o$(PROD_OUT) $(PROD_OBJS)
where $(PROD_OBJS) is a list of object files of the form:
PROD_OBJS = objfile1.obj objfile2.obj objfile3.obj ... objfileN.obj
Now the makefile itself is at the root of my project directory.
It gets messy to have object and listing files at the root, I'd like to put them in a subfolder.
Building and outputing the obj files to a subfolder works, I'm doing it with suffixes and inference:
.s.obj:
$(ASSEMBLY) $(FLAGS) $*.s -o Objects\$*.obj
The problem is to pass the Objects folder to the link command.
I tried:
prod_link = $(LINK) $(LINK_FLAGS) -o$(PROD_OUT) Objects\$(PROD_OBJS)
but only the first file in the list of object files gets the folder's name.
How can I pass the Objects subfolder to all files of my list $(PROD_OBJS)?
EDIT
I tried also
PROD_OBJS = $(patsubst %.ss,Object\%.obj, $(PROD_SRC))
but got:
makefile(51) : fatal error U1000: syntax error : ')' missing in macro invocation
Stop.
This is quite strange...
nmake is not GNUMake, and is rather rubbish. See the NMAKE Reference for details.
As far as your problem goes (translating 1.o 2.o 3.o into d/1.o d/2/o d/3.o), try
OBJS= 1.o 2.o 3.o
# Looks wierd I know, but basically change ' ' to ' d/'
# (and it's not very robust!)
OBJS_WITH_PREFIX= d/$(OBJS: = d/)
!ERROR [$(OBJS_WITH_PREFIX)]
By the way, your pattern rule is lying to nmake. You say .s.obj:, which says "here is how to convert a .s file into a .obj," but then the commands you give actually create the object in a subfolder. You should have started the pattern rule with .s{Objects\}.obj:. See the docs for more details (Search Paths in Rules).
Very late to the party, but in case anyone else runs into the same problem:
This error
makefile(51) : fatal error U1000: syntax error : ')' missing in macro invocation
Stop.
is caused by the fact that the patsubst syntax doesn't seem to be supported by nmake. You can get around this by using the alternative syntax
$(var:suffix=replacement)
instead of
$(patsubst %suffix,%replacement,$(var))
(this is also valid in gnumake).