this is my first time posting here, so sorry if this ends up in the wrong place. I am trying to compile some code I've downloaded from a GitHUb repository and am running make from the MSYS Shell. There is a problem with the makefile that has the common make rules. When I run make, I get the following error:
C:\Mios32/include/makefile/common.mk:143: *** multiple target patterns. Stop.
Since I'm a complete beginner with regard to make and makefile, I can't find the problem. Here's the code from common.mk file from line 152 to 154:
# rule to create .elf file
$(PROJECT_OUT)/$(PROJECT).elf: $(ALL_OBJS)
#$(CC) $(CFLAGS) $(ALL_OBJS) $(LIBS) $(LDFLAGS) -o$#
Lmk if I need to upload the whole common makefile. Thanks
You can find documentation on error messages in the GNU make manual.
This error means that you have a static pattern rule, with multiple patterns (% characters) in the target. Your line is here:
$(PROJECT_OUT)/$(PROJECT).elf: $(ALL_OBJS)
The only way to know what the problem is, is to find the values of the PROJECT_OUT, PROJECT, and ALL_OBJS variables. No doubt they contain colon characters and/or percent characters.
The make program is a tool developed on UNIX, well before "driver letters", backslash as directory separators, etc. were popularized by Microsoft. As such, its syntax is geared towards UNIX systems where : is not expected in pathnames, backslash is an escape character, etc.
If you want to build software on Windows that was developed for POSIX systems such as GNU/Linux and MacOS, you'll have to do some work translating pathnames between them. You should not use drive-letter-qualified paths when working with makefiles, and you should not use any paths containing whitespace, and you should always use forward-slashes (/) as directory separators, never backslashes.
Related
I'm working on a rather large project in pure C, and for various reasons we are not using CMake.
We have a good system which uses various shell commands to require very little maintanence. It will automatically find new headers and C files and add the headers to the dependencies and will compile the C files and include them in the output. However, we've gotten to the point where any changes we make to the header files becomes a problem because it requires a recompilation of the entire project, rather than just the C files that include it directly or indirectly.
I've worked on a system to ensure that the only header files which are added as dependencies are ones which are required by the C file itself (recursively up the tree).
I had thought I would be able to solve this myself, but it seems that make has rather inconsistent rules for expansion of variables.
The solution I came up with was to try to use ag and get all the includes out of the file. This works as intended, and I pipe it into tr so that I can ensure that no newlines are added, thereby messing up make. The issue that I'm having though is in determining which file to search in. This is the recipe that it's using for the section in question:
$(GAMEOBJDIR)/%.o : $(GAMEDIR)/%.c $(shell ag -o '(?<=(^#include "))(.*?)(?=("$$))' $(GAMEDIR)/%.c | tr '\n' ' ')
$(CC) $(CFLAGS) $(if $(RELEASE),$(RELFLAGS),$(DBFLAGS)) -c -o $# $<
The problem is that $(GAMEDIR)/%.c is expanding to src/game/%.c and not src/game/<filename>.c. I'm unsure how to fix this issue based on the expansion rules of make.
Once I can figure this out I'll be able to make sure this walks up the chain of header files too, but until I can get this figured out I have no reason to work on that.
Make's rules for expansion are completely consistent... but sometimes they aren't what people want. That's not the same thing :)
Rules for expansion are explained in the manual. In your case you're working with a prerequisite list which means the variables are expanded as the makefile is parsed. That includes the shell command and all other variables. Because you are working with a pattern rule, it means that at the time the makefile is parsed it doesn't match any particular file, it's just defining the pattern rule itself. So, % can't be expanded here. It will be expanded later, when make starts walking the dependency graph and trying to locate ways to build targets.
In general your method cannot work efficiently. You could defer the expansion of these parts of the prerequisites list using Secondary Expansion. However, that means every time make wants to TRY to use this pattern it will run these commands--that will just be slow.
Have you considered using a more standard way to manage detecting prerequisites? Try reading this description for example to see if it would work for you.
I want to make install(sudo make install) using path with space and dot. (e.g. /Applications/Sample App.app/Contents/Resources)
However, following error invoked.
ginstall: target 'App.app/Contents/Resources/lib/libserialport.a' is not a directory
If I use the path with only space, sudo make install really works well with \ escape character.
Makefiles and pathnames which contain spaces do not mix well. Make uses whitespace to split strings into lists. For example, of you write this:
SOURCES = foo.c bar.c baz.c
OBJECTS = $(patsubst %.c,%.o, $(SOURCES))
program: $(OBJECTS)
Then make will treat the variables SOURCES and OBJECTS as lists of strings, split on whitespace characters, and program will depend on the three items foo.o, bar.o, baz.o.
Make does not know at all that some strings should not be split this way (because they refer to pathnames). Like many early scripting languages, it is completely based on string interpolation. This is true for the shell script fragments used to write the build steps as well.
There are some workarounds possible, but they all depend on how variables are used within the makefile. Recursive makefiles can pose additional problems if the contents of these variables are passed down explicitly to the invoked make command using the shell.
In some cases, the fix is rather simple, so if there is an install rule like this:
install: program
$(INSTALL) -m 755 program $(DESTDIR)$(bindir)/program
It may be sufficient to add quotes, like this:
install: program
$(INSTALL) -m 755 program "$(DESTDIR)$(bindir)/program"
But this really depends on the makefile in question.
If the project uses automake (like libserialport), the simplest solution is to use the DESTDIR support in the generated makefile to install the whole thing to a path which does not contain spaces, and then move it to the final destination afterwards. This assumes that the project does not internally embed the final installation path, though.
I'm maintaining a (horrendously complicated) Makefile, and in some recipes I saw the following:
$(#:.h=.h.d)
I have absolutely no clue as to how to interpret this, or whether there's any documentation on those characters. Obviously, Google won't work because it thinks I'm typing gibberish.
I saw a related question about #:H, but this is GNU make instead of BSD make.
This is a variable reference with a substitution: $(VAR:FROM=TO). It means the value of the variable VAR, but for each whitespace-separated word in the value, if the word ends with the suffix FROM, it is replaced by the suffix TO.
In this case, the variable is #, the filename of the target of the rule (with special handling for archive members). If the target of the rule ends with .h, then .d is added at the end.
A common file naming convention is to use .d for a list of dependencies. The file foo.h.d presumably contains dependencies for rules to compile source files that include foo.h (so, in practice, foo.d.h would contains foo.h and the headers that it includes).
By the way, this is portable syntax. There is another slightly more wordy syntax which is common (supported by both GNU and BSD make) but not POSIX: $(#:%.h=%.h.d) where the % acts as a wildcard; this syntax allows a prefix to be substituted in addition to a suffix. There is yet another syntax to do the same thing in GNU make: call the function patsubst, written $(patsubst %.h,%.h.d,$#) — it's arguably less cryptic, but because the portable syntax has existed for decades, it's commonly used even in makefiles that otherwise require GNU make.
Is there a mechanism in make to allow for default global implicit rules that are available anywhere, similar to the built-in rules?
Make provides some built-inimplicit rules for compiling C/C++/Fortran files, without even requiring a Makefile for simple cases. However, when compiling other languages (e.g. Go programming language files), a Makefile is always required. I would like to extend my Makeenvironment to have implicit rules available by default.
This is not normally desirable, as it would cause your Makefile to be less portable; it wouldn't work on somebody else's machine if they didn't have it set up that way.
However, if you want to do this, create a "global" Makefile somewhere with your default rules for Go files, then add its path to the MAKEFILES environment variable. This global Makefile will be processed before any Makefile when you run "make", just as if you had included its source at the top of the file.
I'm assuming you're referring to the fact that you can do
make hello.o
and make will automatically know how to make the .o from a .c file (or indeed from a .f or .p, if one exists) - but you want to do this for custom file types (say, building a .bar from a .foo.
The most portable way of doing this is as follows (in your Makefile):
.SUFFIXES: .foo .bar
.foo.bar:
foo2bar -in $> -out $#
The first line (.SUFFIXES) warns make that you'll be treating these as special suffixes; the second line says "here's a recipe for making a .bar from a .foo. The third line gives the command for doing this - $> and $# get changed by make to the input and output filenames.
NOTE: The indent for the third line MUST be a tab character.
A much more flexible method, that only works with GNU make, is to use its support for implicit rules. If you can guarantee you'll be using GNU make then this is probably to be recommended.
While I agree with dmazzoni, I just though I'd add my make recipe for a Go Makefile:
# Include default Golang Make magic
include $(GOROOT)/src/Make.$(GOARCH)
# Hack the following line
your_program: your_program.$O
$(LD) -o $# $^
# Compiles .go-files into architecture-specific binaries
%.$O: %.go
$(GC) -o $# $^
clean:
rm your_program *.$O
(Note: the $O is DOLLAR + UPPERCASE-o - not zero!)
While I haven't tested it on all the machines I have available, i believe it should port fairly well.
I have been having troubles getting my makefiles to work the way I want. First off, I would like to say this is POSIX make, as in http://www.opengroup.org/onlinepubs/009695399/utilities/make.html I am needing my build system to work with both BSDs and GNUs(Linux).
What I am wanting is a zero maintenance makefile. I want it to just compile all .c and .asm files in src/ and place the object files in objs/ and then to link everything in objs/ to a binary file.
I can do a lot, but I can't get it to separate the source and obj files.
I am ok if this requires a little built-in shell scripting (using POSIX defined /bin/sh), but I can just not get the dependencies to work right. I want it to only build the object file if the source file is newer.
My closest is this:
${C_OBJS}: ${HDRS} ${*:objs/%=src/%}.c
${CC} ${CFLAGS} -c ${*:objs/%=src/%}.c -o $*.o
This has the problem that I must still specify C_OBJS=objs/foo.o and such and also it is just barely not POSIX and therefore, compiles with BSD make but not GNU make.
The POSIX version of make does not explicitly support file names with slashes in them, nor does it make provision for separating source files in a different directory from the object files. And, as noted by #caskey, it does not support any notation using '%' characters, though it notes that such rules exist and recommends that they be reserved for use as metacharacters.
Consequently, you probably cannot do what you want with standard POSIX make.
In practice, you can often do what you seek with specific implementations of make, but the resulting makefile has limited portability.
Consider using a makefile generation systems of some sort - cmake or the auto-tools (autoconf, libtool, automake, etc). Or one of the many reworkings of the basic concepts of make:
scons
ant
cake
cook
bras
...and a dozen I've forgotten or not heard of...
POSIX make doesn't support constructs like?
objs/%.o : src/%.c
${CC} ${CFLAGS} -c $< -o $#
Forgot the question mark at the end, hope that makes my comment more clear.