I would like to store all paths to headers in separate file. I'm going to generate file with paths dynamically, to avoid re-creating Makefile whenever paths change.
Is that possible?
Yes, you can generate the file, let's call it paths.inc, so it looks like, for example:
INCLUDEPATH=path1:path2
and then include the file in your main Makefile
include paths.inc
and use the variable defined in it: ${INCLUDEPATH}
Makefile
paths_mk := paths.mk
-include $(paths_mk)
$(paths_mk) :
# Rule to generate paths.mk
include_flags = $(include_paths:%=-I%)
CPPFLAGS += $(include_flags)
%.o : %.c
$(CC) $(CPPFLAGS) $(CFLAGS) -o $# -c $<
paths.mk
# Auto-generated file.
include_paths := ...
Related
I'm trying to make a makefile that doesn't recompile my program if I delete my object files...because my .c files are up to date, how can I do this?
I try to do this but it doesn't work
SRC = main.c file.c file1.c
OBJ = $(SRC:c=o)
%.o: %.c
gcc -c $< -o $#
name = program
all: $(NAME)
$(NAME): $(SRC) ; $(OBJ)
gcc $(OBJ) -o $(NAME)
Thank! To solve my problem i'm must add special target .INTERMEDIATE or .SECONDARY like this:
More details on this issue can be found at the link Chains of Implicit Rules provided by Henry.
SRC = main.c file.c file1.c
OBJ = $(SRC:c=o)
%.o: %.c
gcc -c $< -o $#
NAME = program
all: $(NAME)
$(NAME): $(SRC) ; $(OBJ)
gcc $(OBJ) -o $(NAME)
.SECONDARY: $(OBJ)
Well, that is basically impossible.
To create the binary, you need the object files. To create the object files you need the source files.
The binary is up to date if it is newer than the up to date object files. And the object files are up to date if they are newer than the source files.
There is no direct route from the binary to the source files. Deleting the object files will always rebuild your source code.
Update: It is possible (as pointed below), but not easy. And IMHO the makefile complexity added is not worth it. Just keep the object files. Instead change the makefile to put you object files in a separate directory away from the source code.
I am a newbie in creating makefiles, and would be glad if someone could help me.
I have created several header files (for function declarations) and corresponding .c programs (8 in total), for the function definitions (including the main function). These are listed in the .../include/ directory. Additionally, I have created another directory for the storing the output files : .../bin/ after compilation. I tried to link the .o files, but was unsuccessful. I have attached a small piece of the makefile code (similar one taken from the internet) :
CC = g++
CFLAGS = -Wall -O3
INC_DIR := /media/sf_~share/151*/Codes/include
OBJ_DIR := /media/sf_~share/151*/Codes/obj
INC_FILES := $(wildcard $(INC_DIR)/%.c)
OBJ_FILES := $(patsubst $(INC_DIR)/%.c, $(OBJ_DIR)/%.o, $(INC_FILES))
all : $(APP)
$(APP) : $(OBJ_FILES)
$(CC) $(CFLAGS) -o $# $^
$(OBJ_DIR)/%.o : $(INC_DIR)/%.c
$(CC) $(CFLAGS) -o $# $<
clean:
rm -f *.o $(APP)
I would be glad if someone could either suggest me a different code, or rectify this as it is.
There are a few mistakes in your Makefile:
Wildcard usage
You should use *.c rather than %.c for wildcard expansion, like this:
INC_FILES := $(wildcard $(INC_DIR)/*.c)
Patsubst usage
You don't need to specify the full pattern $(INC_DIR)/%.c for patsubst, instead, simply use:
OBJ_FILES := $(patsubst %.c, %.o, $(INC_FILES))
Missing $(APP) value
I don't know if you simply forgot to add this to the sample or not, but since $(APP) is an empty string, the makefile says:
make: Nothing to be done for `all'.
Adding APP := program triggers a build for all the *.c files in include.
I have a makefile from an example project, and it unfortunately forces a re-build when any single file in the project changes. I do not have a lot of experience with makefiles, so I'm not sure how to solve this problem.
The makefile defines the files to compile as a single variable SRCS like shown below. Of course, there are about 40 files in this list, in quite a few different directories.
SRCS = \
../../src/file1.c \
../../src/file2.c
Then later it defines the build rules for each .o file generated from each .c file.
$(OBJ_PATH)/%.o: $(SRCS)
$(CC) $(FLAGS) $(filter %/$(subst .o,.c,$(notdir $#)), $(SRCS)) -o $#
According to make running with the -d option, all of the object files must be compiled again when a single .c file changes because $(SRCS) is defined as a dependency above.
How can I change this so if a single file changes only the 1 .o file must be compiled again?
Another solution would be using vpath. Example code:
OBJ_PATH := build
SRCS := \
src/foodir/foo.c \
src/bardir/bar.c
OBJS := $(addprefix $(OBJ_PATH)/,$(notdir $(SRCS:%.c=%.o)))
vpath %.c $(dir $(SRCS))
all: $(OBJS)
$(OBJ_PATH)/%.o: %.c
$(CC) $(FLAGS) $< -o $#
Your recipe was written by somebody knowledgeable about makefiles; it is almost correct. The one correction is, to move the $(filter) statement to the prerequisite line. In this case, that is where it needs to be.
Once it is there, you need to make a few additional adjustments, which you can read about in the manual. So, like this:
PERCENT := %
.SECONDEXPANSION:
$(OBJ_PATH)/%.o: $$(filter $$(PERCENT)/$$(subst .o,.c,$$(notdir $$#)), $(SRCS))
$(CC) $(FLAGS) $< -o $#
Something like this will also work.
SRCS = \
../../src/file1.c \
../../src/file2.c
# Set prerequisites for each output .o file from the matching .c file
$(foreach src,$(SRCS),$(eval $(OBJ_PATH)/$(notdir $(src:.c=.o)): $(src)))
# Create pattern rule with no additional prerequisites.
$(OBJ_PATH)/%.o:
$(CC) $(FLAGS) $< -o $#
So it occurred to me that an, in some senses, even more minimal change would be:
$(OBJ_PATH)/%.o: $(SRCS)
file='$(filter %/$(subst .o,.c,$(notdir $#)), $?)'; [ "$$file" ] && \
$(CC) $(FLAGS) "$$file" -o $#
Usually in a Makefile you do not put the specific .c files as dependencies.
Generally, you list the .o files as dependencies of the main executable.
Make has internal rules for figuring out how to build a .o file from a .c file,
you can override these with your own special rule, or often just changing a few
config variables is sufficient.
A complete tutorial on make is longer than I want to type in this box, but there are plenty of them available with a quick web search.
This question already has answers here:
Building multiple executables with similar rules
(5 answers)
Closed 9 years ago.
I am having a directory called test where make file should be. i am having subdirectory called sub1, sub2, sub3.
test/Makefile
test/sub1
test/sub2
test/sub3
I want to create exe1 by compiling sub1, exe2 by compiling sub2 and exe3 from sub3.
Can i add more than one directory in vpath?? or any other solution
You could simply have a very simple makefile in the test directory, just going into the subdirectories and calling makefiles in them. The subdirectories have makefiles that builds normally, but simply put the executable in the parent directory.
First of all: Yes you could add more than one directory in vpath. Each entry is separated with a colon ':'
vpath %.c test/sub1:test/sub2:test/sub3
But you'll getting into trouble as soon you have the same filename (with different content) in two directories. Consider:
test/Makefile
test/sub1/main.c
test/sub1/foo.c
test/sub1/bar.c
...
test/sub2/main.c
test/sub2/blish.c
test/sub3/blash.c
...
test/sub3/main.c
test/sub3/okEnoughForNow.c
And your makefile containing:
vpath %.c sub1:sub2:sub3
exe1.exe : main.c foo.c bar.c
gcc -o $# $^
exe2.exe : main.c blish.c blash.c
gcc -o $# $^
exe3.exe : main.c okEnoughForNow.c
gcc -o $# $^
The result would be:
gcc -o exe1.exe sub1/main.c sub1/foo.c sub1/bar.c
gcc -o exe2.exe sub1/main.c sub2/blish.c sub2/blash.c
gcc -o exe3.exe sub1/main.c sub3/okEnoughForNow.c
As you can see, all exe's contain sub1/main.c as this is the main.c found first; Its path appears first on the vpath.
Joachim's Approach is definitive a simple, and very common solution. I would choose it as well if the programs in your subfolders are completely unrelated: You could have in each directory a makefile containing something like:
SRC := $(wildcard *.c)
%.exe : $(SRC)
gcc -o $# $^
Assuming, all .c files in each of your sub* shall be part of your program, and there are no subfolders in your sub's. Otherwise you'll need a different approach to scan your .c files, or specify them individually.
In your main makefile you can run for each subfolder a new instance of make, using those makefiles. Which gives you a main Makefile like:
# Get all subfolders name without trailing slash
PROGS := $(patsubst %/,%,$(wildcard */))
# Each subfolder can be made by calling make in
# that folder. A file prog.exe is created.
.PHONY : $(PROGS)
$(PROGS) :
$(MAKE) -C $# prog.exe
# Now every .exe depends on its subfolder, calls
# Make there - see rule above and copies the
# prog.exe from there into the root, with the name
# of the subfolder. (Alternatively you could use
# mv instead of cp)
%.exe : %
cp $</prog.exe $#
Assuming the name of your .exe is the same as the directory name and all subfolders are containing programs.
However, calling make from a running make instance (recursive make) can cause a real headache as soon as there are any dependencies between the generated files of the subfolders.
Another solution:
A different approach whithout using recursive make is having rules dynamically created. In that case your main Makefile could look like this. (I'm again assuming all subfolders are containing programs, all subfolders are flat, and all .c files in those subfolders are part of your program) This has the advantage that you'll have to maintain just one makefile, and there can be any dependency between the different programs. But still it has the disadvantage that you cannot manage your different programs seperately.
That's the complete makefile:
%.exe :
gcc -o $# $^
PROGS := $(patsubst %/,%,$(wildcard */))
$(foreach P,$(PROGS),$(eval OBJ_$(P) := $(wildcard $(P)/*.c)))
$(foreach P,$(PROGS),$(eval $(P).exe : $(OBJ_$(P))))
.PHONY : all
all : $(addsuffix .exe,$(PROGS)
We're starting with a rule for compiling: Any .exe is generated by invoking gcc having all prerequisites as source files.
%.exe :
gcc -o $# $^
Then, next step is to obtain all "programs" by scanning for all subfolders and stripping off the trailing slash
PROGS := $(patsubst %/,%,$(wildcard */))
The next step is to create for each program a variable containig all Sources. Note the eval function expands, and passes everything to make as it has been written in the Makefile.
$(foreach P,$(PROGS),$(eval SRC_$(P) := $(wildcard $(P)/*.c)))
Thus the line above, with your sub1, sub2 and sub3 will become:
SRC_sub1 := $(wildcard sub1/*.c)
SRC_sub2 := $(wildcard sub2/*.c)
SRC_sub3 := $(wildcard sub3/*.c)
The eval function can even be used to create rules:
$(foreach P,$(PROGS),$(eval $(P).exe : $(SRC_$(P))))
So this will expand to (assuming the file structure in the example above)
sub1.exe : sub1/main.c sub1/foo.c sub1/bar.c
sub2.exe : sub2/main.c sub2/blish.c sub2/blash.c
sub3.exe : sub3/main.c sub3/okEnoughForNow.c
Now we have three rules without a recipe. Make says "if you have a rule without recipe, and an implicit rule that matches can be found, this rule is used with the prerequisites added from the rule that does not have the recipe" Thus, for those 3 rules the implicit rule of %.exe above applies.
Basically that's the trick. For your convenience you can add
.PHONY : all
all : $(addsuffix .exe,$(PROGS))
So make all makes everything.
Extension:
If you'd like to be able to make the .o files seperately as well, you could add one more implicit rule like:
%.o : %.c
gcc -c -o $# $<
and make your programs dependent on the .o rather than on the .c files:
$(foreach P,$(PROGS),$(eval OBJ_$(P) := $(patsubst %.c,%.o,$(wildcard $(P)/*.c))))
$(foreach P,$(PROGS),$(eval $(P).exe : $(OBJ_$(P))))
Then you'll have your .exe dependend on the .o that can be found by changing .c into .o after scanning all sources. Via the implicit rule chain %.o : %.c make will know what to do.
I am programming an UDP client server application in the C programming language; I want to automatically compile 2 sources files and 3 header files whenever the dependencies change so I decided to use the make utility.
The makefile target is called "edit" :
edit : server_UDP.o client_UDP.o \
gcc -o edit server_UDP.o client_UDP.o \
client_UDP.o : client_UDP.c cliHeader_UDP.h wrapHeader.h
gcc -c client_UDP.c
server_UDP.o : server_UDP.c servHeader_UDP.h wrapHeader.h
gcc -c server_UDP.c
It doesn't trigger a recompile when I change a few lines of code in wrapHeader.h.
How do to I modify the edit makefile rule(s) when there is a change in wrapHeader.h to recompile server_UDP and client_UDP ?
**note : wrapHeader.h is the main header
cliHeader_UDP.h : include "wrapHeader.h"
servHeader_UDP.h : include "wrapHeader.h"
I think what you want are Make dependency files.
You can specify the compiler to generate a dependency file for you with the '-MMD -MP' arguments, which create a new file with the same name as the source file except with the extension *.d, in the same folder as your source.
The dependency file contains all the headers the code depends on, which will lead to GNU make compiling your source file if a header it uses is modified.
An example dependency file enabled makefile:
# Makefile
CC := gcc
LD := g++
# The output executable.
BIN := program
# Toolchain arguments.
CFLAGS :=
CXXFLAGS := $(CFLAGS)
LDFLAGS :=
# Project sources.
C_SOURCE_FILES := mysourcefile1.c src/myothersrc.c
C_OBJECT_FILES := $(patsubst %.c,%.o,$(C_SOURCE_FILES))
# The dependency file names.
DEPS := $(C_OBJECT_FILES:.o=.d)
all: $(BIN)
clean:
$(RM) $(C_OBJECT_FILES) $(DEPS) $(BIN)
rebuild: clean all
$(BIN): $(C_OBJECT_FILES)
$(LD) $(C_OBJECT_FILES) $(LDFLAGS) -o $#
%.o: %.c
$(CC) -c -MMD -MP $< -o $# $(CFLAGS)
# Let make read the dependency files and handle them.
-include $(DEPS)
This should work for your situation:
SOURCES := server_UDP.c client_UDP.c
OBJECTS := $(patsubst %.c,%.o,$(SOURCES))
DEPS := $(OBJECTS:.o=.d)
edit: $(OBJECTS)
gcc -o edit $(OBJECTS)
%.o: %.c
gcc -c $< -o $#
-include $(DEPS)
You did not say that edit.c includes your two specific headers, but I guess it must, if it links to the objects.
This is exactly the scenario where makepp plays out one of its strengths: If you follow the convention that for every .o file you need to link there is an include statement of a corresponding name (in your case that would be client_UDP.h & server_UDP.h) then makepp will figure everything out itself, besides detecting the header files as dependencies.
This even works recursively, so if you had a wrapHeader.c (where there is no corresponding include statement in edit.c), that would get automatically compiled and linked.
So you don't need a makefile. But if you want to avoid calling makepp edit everytime, then you can create a one-liner
edit:
You will only need to learn make syntax, if you have more complex requirements. But if you do, there is no limit. Besides doing almost all that GNU make can, there are lots more useful things, and you can even extend your makefiles with some Perl programming.