Makefile including another make file? - makefile

I have to create a make file and it is dependent on some other make file.
Now , the other file defines the targets. So I am asking whether I can have targets in both the files or not.
TARGET = 0
ifeq ($(TARGET),0)
CC = gcc
CFLAGS = -g -lpthread -lrt -O3 -Wall -lm
else
CC=arm-v7a15v3r1-linux-gnueabi-gcc
CFLAGS = -lpthread -lrt -O3 -g -mcpu=cortex-a9 -ftree-vectorize
endif
PNG_INC_DIR = lpng167/inc
ZLIB_INC_DIR = zlib128/inc
DEFINES = -DZ_SOLO
pngsrc = lpng167/src/png.c\
lpng167/src/pngerror.c\
lpng167/src/pngget.c\
lpng167/src/pngmem.c\
lpng167/src/pngpread.c\
lpng167/src/pngread.c\
lpng167/src/pngrio.c\
lpng167/src/pngrtran.c\
lpng167/src/pngrutil.c\
lpng167/src/pngset.c\
lpng167/src/pngtrans.c
zlibsrc = zlib128/src/adler32.c\
zlib128/src/crc32.c\
zlib128/src/infback.c\
zlib128/src/inffast.c\
zlib128/src/inflate.c\
zlib128/src/inftrees.c\
zlib128/src/uncompr.c\
zlib128/src/zutil.c
testsrc = lpng167/src/pngtest.c
PNGOBJS = $(pngsrc:.c=.o)
ZLIBOBJS = $(zlibsrc:.c=.o)
TESTOBJS = $(testsrc:.c=.o)
EXE = pngtest
all: $(EXE)
$(EXE):$(ZLIBOBJS) $(PNGOBJS) $(TESTOBJS)
$(CC) $(CFLAGS) $(DEFINES) $(PNGOBJS) $(TESTOBJS) $(ZLIBOBJS) -o $(EXE)
%.o : %.c $(PNG_INC_DIR)/*.h $(ZLIB_INC_DIR)/*.h
#echo $<
#$(CC) $(CFLAGS) -I$(PNG_INC_DIR) -I$(ZLIB_INC_DIR) $(DEFINES) -c $< -o $#
.PHONY: clean
clean:
-#$(RM) -f $(ZLIBOBJS) $(PNGOBJS) $(TESTOBJS) $(EXE) 2> /dev/null
This is the first make file which defines its own targets.
the other make file is a system make file thats too big too format , that defines dynamic targets according to the machine type. This is the link.
The current make file which has no targets is
EXECUTABLE := subM
CCFILES := SubFilHost.cpp
include ../../common/common_opencl.mk
I am really new to this make file thing, and the more I try to get this, the more it confuses.
Any help would be grateful;
Thanks
Piyush

Including a makefile is the same as cutting and pasting the contents of that makefile into the current makefile. So you can have targets in both makefiles as long as they don't conflict. You can only have one recipe per static target per makefile. However, you can define a target with just prerequisites as many times as you like. So you can do:
foo: bar1
foo: bar2
echo "hello world"
You cannot do:
foo:
echo "hello world1"
foo:
echo "hello world2"
(Ok, you can, but make spits out some warnings, and only runs the last rule). For pattern rules, you can have a pattern rule and a static rule which would resolve to the same target. So, you could do:
%.o: %.c
echo "used pattern rule"
foo.o: foo.c
echo "used static rule"
In this case, make would run the best match -- which would be the static rule for foo.c. You can also have multiple patterns which overlap a target, and make will not complain. In this case, make runs the best match only.
John

Related

Run a command for the nth target with the nth dependancy

I am having some confusion about how the '$<' and '$#' macros can be used with a list of elements. My ultimate goal is to compile a directory of C source files into executables with the same name, no extensions. Also I do not want to make object files.
Here is a simple makefile which I would like to upgrade using the macros.
CC = gcc -ansi -std=c99
CCFLAGS = -Wall -pedantic -O3
all : progA progB progC
progA : progA.c
$(CC) $(CCFLAGS) $< -o $#
progB : progB.c
$(CC) $(CCFLAGS) $< -o $#
progC : progC.c
$(CC) $(CCFLAGS) $< -o $#
This works fine, but I don't like the redundancy of the commands. I have found a workaround that works, and a near solution, but was hoping there might be a clear option.
workaround:
CC = gcc -ansi -std=c99
CCFLAGS = -Wall -pedantic -O3
PRGS := $(patsubst %.c,%,$(wildcard *.c))
all :
make $(PRGS)
% : *.c
$(CC) $(CCFLAGS) $#.c -o $#
What I don't like here is the call to make within the command. Running 'make' delivers a message in my terminal that looks something like this:
make[1]: Entering directory '/path/to/dir'
...actual commands...
make[1]: Leaving directory '/path/to/dir'
I am assuming this has to do with opening the same makefile and the [1] refers to the second file descriptor in the open file table (or something along those lines).
near solution:
CC = gcc -ansi -std=c99
CCFLAGS = -Wall -pedantic -O3
SRCS := $(wildcard *.c)
PRGS := $(patsubst %.c,%,$(SRCS))
all : $(PRGS)
$(PRGS) : $(SRCS)
$(CC) $(CCFLAGS) $< -o $#
This almost works, except it is always grabbing the first dependancy!
..... progA.c -o progA
..... progA.c -o progB
..... progA.c -o progC
So, does anyone have a cleaner method to my 'workaround' or perhaps a solution to my 'near solution'? Is there anyway to match the nth target to the nth dependency when running the command?
Thanks!
The $(PRGS): $(SRCS) change is just incorrect. It lists every source file as the prerequisites of every target.
You want to set the prerequisites of the all target to be every program you want built by default. To do that you want to use all: $(PRGS). Not a recipe of calling make again like you had originally.
(If you did want to keep the manual recursive call to make you could use make --no-print-directory on that call to avoid the message but that is still the wrong approach (and if you were going to do that you'd want to use $(MAKE) to handle arguments to the original make correctly.)
A second problem with your original makefile is the use of *.c in the prerequisite list of the % target. That sets the prerequisites of every target to be every *.c file in the directory. That's not what you want. You want each target to have its own .c file as its prerequisite.
You want:
all: $(PRGS)
%: %.c
$(CC) $(CCFLAGS) $#.c -o $#
That being said make has a built-in rule for exactly that foo.c -> foo compilation so you should just use that. That rule uses the $(CC) and $(CFLAGS) variables. So just set those to what you want and you are done.
So this makefile should do what you want. (Note how I moved some arguments to CFLAGS instead of CC. CC should generally, to my knowledge, by the compiler itself and not any arguments.)
CC = gcc
CFLAGS = -ansi -std=c99 -Wall -pedantic -O3
PRGS := $(patsubst %.c,%,$(wildcard *.c))
all : $(PRGS)

Makefile not executing to the end

I have the following makefile but it just executes the 1st command where it builds me the .o files and not the .so files. What am I doing wrong?
Thanks,
SHELL = /bin/sh
CC = gcc
CFLAGS = -g -Wall
LDFLAGS = -shared
TARGET = Stepper.so
SOURCES = $(shell echo ./*.c)
HEADERS = $(shell echo ./*.h)
OBJECTS = $(SOURCES:.c=.o)
LIBS = liblua523.a
PREFIX = $(DESTDIR)/usr/local
BINDIR = $(PREFIX)/bin
$(OBJECTS): $(SOURCES) $(HEADERS)
$(CC) $(CFLAGS) -c $(SOURCES) -o $(OBJECTS)
$(TARGET): $(OBJECTS)
$(CC) $(LDFLAGS) -o $(TARGET) $(OBJECTS) $(LIBS)
clean:
rm $(OBJECTS)
Unless you specify a different target on the command line, make always builds the first real target found in the makefile. In this case, the first real target is the first object file, so that's all that's built.
This is why you typically see makefiles with a first target of all or similar, which just depends on the various other targets you want built during a standard invocation of "make" with no arguments.
However, your makefile is really not right, in a number of ways. The fact that it's running it all means you actually only have one source file. As soon as you have >1 it will fail.
This:
SOURCES = $(shell echo ./*.c)
is not very efficient; you should use wildcard here:
SOURCES = $(wildcard ./*.c)
This rule:
$(OBJECTS): $(SOURCES) $(HEADERS)
$(CC) $(CFLAGS) -c $(SOURCES) -o $(OBJECTS)
Tells make, "for every object file, if any source file or any header file has changed, recompile it". Basically, it means that if you change ANYTHING in the directory, EVERYTHING will rebuild. If you want that you might as well write a shell script and not bother with make at all.
Further, the compiler will fail when you have >1 source file, as it will try to run:
gcc -g -Wall -c foo.c bar.c -o foo.o bar.o
which is not right.
You don't need to define this rule at all; make has a built-in rule which knows how to build an object file from a source file. Just replace it with this:
$(OBJECTS): $(HEADERS)
(no recipe) so make knows that the objects depend on the headers as well as the source. Note this is not ideal since all objects rebuild if any header changes but it's fine for a simple program.

Understanding a makefile

I am talking about this question where the person has updated his final solution with a makefile for the task. I am having a hard time understanding how it's done.
There is a rule:
$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
#$(CC) $(CFLAGS) -c $< -o $#
which I am unable to understand, but by intuition I know what it will be doing. Almost everything else is pretty much clear. Thanks!
This is a static pattern rule. The first field is a list of targets, the second is a target pattern which Make uses to isolate a target's "stem", the third is the prerequisite pattern which Make uses to construct the list of prerequisites.
Suppose you have
SRCDIR = src
OBJDIR = obj
OBJECTS = obj/foo.o obj/bar.o obj/baz.o
$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
#$(CC) $(CFLAGS) -c $< -o $#
If you make obj/foo.o, Make first identifies this rule as the one to use (since obj/foo.o is in the target list $(OBJECTS)), matches it against the target pattern obj/%.o and finds that the stem (the part matched by the wildcard %) is foo, then plugs that into the prereq pattern src/%.c and finds that the prerequisite is src/foo.c.
If you've also defined the variables
CC = gcc
CFLAGS = -thisflag -thatflag=something
Then the command in the rule becomes
#gcc -thisflag -thatflag=something -c src/foo.c -o obj/foo.o
(Note that $< is the first prerequisite and $# is the target name.)
In answer to your other question: Yes, a makefile can handle a dependency on a header file (x.h) so that if the header has been modified, Make will rebuild the target. No, this makefile doesn't do that. You can modify the makefile by hand, adding rules like
a.o: x.h
assuming you know what the inclusions actually are, or you can have the makefile do it automatically, which is an advanced technique you probably shouldn't attempt yet.
This line is explaining how to obtain the object files (.o) from the source (.c), it avoids having to repeat the line for each .c file.
The objects will be in OBJDIR and the sources in SRCDIR
$(CC) will contain the compiler, CFLAGS will contain the options for the compiler and -c tells gcc to compile the source into objects.
For example:
CC = gcc
CFLAGS = -g -Wall
can be converted into
gcc -g -Wall -c test.c -o test.o

How to write a simpler makefile for a lot of single-c-file programmes?

I want to write a lot of tiny example programmes for one same library, each needs gcc $(OtherOpt) -o xxx -lthelibname xxx.c.
How to write a Makefile without dozens of tagret lines ?
Pattern rules are your friend for these situations. As long as your targets all match a predictable pattern -- and they do in this case, as they are all of the form "create foo from foo.c" -- you can write a single pattern rule that will be used for all of the targets:
OtherOpt=-Wall -g
all: $(patsubst %.c,%,$(wildcard *.c))
%: %.c
gcc $(OtherOpt) -o $# -lthelibname $<
Now you can either run simply make to build all your apps, or make appname to build a specific app. Here I've created a single pattern rule that will be used anytime you want to create something from something.c. I used the $# automatic variable, which will expand to the name of the output, and the $< variable, which will expand to the name of the first prerequisite, so that the command-line is correct regardless of the specific app being built. Technically you don't need the all line, but I figured you probably didn't want to always have to type in the name(s) of the apps you want to build.
Also, technically you can probably get away without having any of this makefile, because GNU make already has a built-in pattern rule for the %: %.c relationship! I mention this option only for completeness; personally, I prefer doing things the way I've shown here because it's a little bit more explicit what's going on.
%.o: %.c
gcc $(OtherOpt) -c -o $# -lthelibname $<
That compiles all .c files to their .o files (object code) of the same base name. Then in your actual target(s), you would include all necessary .o files as dependencies and use gcc $(OtherOpt) -o $# $^ -lthelibname, assuming I'm not misunderstanding how your build is set up.
Some versions of make also support the suffix rule .c.o to be ALMOST the same thing as %.o: %.c, but the suffix rules can't have any dependencies. Writing .c.o: foo.h tells make to compile "foo.h" to "foo.c.o" rather than requiring "foo.h" as a dependency of any file with a .c suffix as %.o: %.c foo.h would correctly do.
I learnd from http://sourceforge.net/projects/gcmakefile/
LDLIB = -lpthread
LDFLAGS = -Wl,-O1 -Wl,--sort-common -Wl,--enable-new-dtags -Wl,--hash-style=both $(LDLIB)
SRCDIRS =
SRCEXTS = .c .C .cc .cpp .CPP .c++ .cxx .cp
CFLAGS = -pipe -march=core2 -mtune=generic -Wfloat-equal \
#-Wall -pedantic
ifeq ($(SRCDIRS),)
SRCDIRS = .
endif
SOURCES = $(foreach d,$(SRCDIRS),$(wildcard $(addprefix $(d)/*,$(SRCEXTS))))
TARGET = $(addprefix bin/,$(basename $(SOURCES)))
all: $(TARGET)
ls -l $(TARGET)
bin/%: %.c dir
gcc $(CFLAGS) $(LDFLAGS) -o $# $<
dir:
#-mkdir bin
.PHONY : clean
clean:
-rm $(TARGET)
-rmdir bin

How to instruct Makefile to use different compilers

I have to build my code for two different platforms at once using two different compilers and libraries. How can I do this with single make file.
Currently my makefile contents are given below. How can I instruct it to change the compiler to gcc within the same makefile?
VPATH = /root/Documents/project/src
CROSS_COMPILE = /opt/compilers/bin/compiler1
CXX = $(CROSS_COMPILE)-g++
CC = $(CROSS_COMPILE)-gcc
AS = $(CROSS_COMPILE)-as
AR = $(CROSS_COMPILE)-ar
NM = $(CROSS_COMPILE)-nm
LD = $(CROSS_COMPILE)-ld
OBJDUMP = $(CROSS_COMPILE)-objdump
OBJCOPY = $(CROSS_COMPILE)-objcopy
RANLIB = $(CROSS_COMPILE)-ranlib
STRIP = $(CROSS_COMPILE)-strip
CFLAGS = -c -Wall -D_REENTRANT -DACE_HAS_AIO_CALLS -D_GNU_SOURCE -DACE_HAS_EXCEPTIONS -D__ACE_INLINE__
LDFLAGS = -L. -L/etc/ACE_wrappers/lib
CPPFLAGS += -I/etc/ACE_wrappers -I/etc/ACE_wrappers/ace
LDLIBS = -lACE
OUTPUT_DIRECTORY=/root/Documents/bin
OBJ=/root/Documents/obj
ifneq ($(OUTPUT_DIRECTORY),)
all: $(OUTPUT_DIRECTORY)
$(OUTPUT_DIRECTORY):
-#$(MKDIR) "$(OUTPUT_DIRECTORY)"
endif
ifneq ($(OBJ),)
all: $(OBJ)
$(OBJ_DIR):
-#$(MKDIR) "$(OBJ)"
endif
SOURCES=File_1.cpp File_2.cpp
OBJECTS=$(SOURCES:%.cpp=$(OBJ)/%.o)
$(OBJ)/%.o: %.cpp
#echo Building Objects
$(CC) $(CFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c -o $# $<
EXECUTABLE=MyExecutable
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
#echo $(SOURCES)
$(CC) $(LDFLAGS) $(OBJECTS) $(LDLIBS) -o $(OUTPUT_DIRECTORY)/$#
File_1.o:File_1.cpp
File_1.o:File_1.cpp
.PHONY: clean
clean:
rm $(OBJECTS) $(OUTPUT_DIRECTORY)/$(EXECUTABLE)
I'd start by putting all the platform-specific defines in a separate makefile. That way you can do:
include $(TARGET).make
Where $(TARGET).make defines CC and other variables for each particular platform. Then you can call make recursively setting TARGET to what you want. Something like:
build:
$(MAKE) TARGET=platform1 all
$(MAKE) TARGET=platform2 all
But really there are many, many ways in which you can achieve the same thing.
Use autoconf. When you configure the project with ./configure, it will automatically choose the one available.
That would be a lot easier to read if the linebreaks were properly preserved in your post.
Anyway, I expect that you're going to have to have two copies of a number of things in the Makefile, such that it's of the form
all : all-platform1 all-platform2
stuff-platform1 : requirements
$(CC1) whatever
stuff-platform2 : requirements
$(CC2) whatever
It's possible that you might be able to auto-generate a makefile like this, to save some effort though.

Resources