The following part is commonly found in makefiles.
OBJS := $(SRCS:%.c=$(OBJDIR)/%.o)
$(OBJDIR)/%.o : %.c
$(CC) $(DEFS) $(CFLAGS) -o$# $<
Now my source folder contains both C and C++ files, and I want to link all object files created together using g++. But how do I specify to also also include *.cpp files to get compiled. I mean how do I modify OBJS to also include *.cpp files.
For OBJDIR, maybe, I can do the C++ equivalent like this. I guess the makefile would guess correctly when to use CXX (g++ for C++ files) and when to use CC (gcc for C files).
$(OBJDIR)/%.o : %.cpp
$(CXX) $(DEFS) $(CFLAGS) -o$# $<
But then, how do I add this rule to OBJS?
You want to use:
OBJS := $(addsuffix .o,$(basename $(SRCS)))
then add your pattern rule for building .o from .cpp (unless, as mentioned here, you can just use the built-in rules).
The above strips off the suffix, regardless of what it is, then adds .o to the end.
You may not need a rule for building .o files from corresponding .cpp or .c files at all, as Make comes with default rules for that, and those look a lot like what you present. The key is probably to specify which .o files need to be built in the first place.
I often see that approached by classifying the C sources separately from the C++ sources. Then you might have something like this:
C_SRCS = ...
CPP_SRCS = ...
OBJS = $(C_SRCS:.c=.o) $(CPP_SRCS:.cpp=.o)
all: myprog
myprog: $(OBJS)
$(CXX) $(CFLAGS) $(LDFLAGS) -o $# $(OBJS) $(LIBS)
If you do need your own rules for building .o files from sources, then you could of course add those.
Note also that the above has no dependencies on GNU make extensions, and if that's important to you then you'll want to avoid GNU style pattern rules for building the object files. That's what traditional suffix rules are for.
Related
I have the following makefile that I use to build a program (a kernel, actually) that I'm working on. Its from scratch and I'm learning about the process, so its not perfect, but I think its powerful enough at this point for my level of experience writing makefiles.
AS = nasm
CC = gcc
LD = ld
TARGET = core
BUILD = build
SOURCES = source
INCLUDE = include
ASM = assembly
VPATH = $(SOURCES)
CFLAGS = -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions \
-nostdinc -fno-builtin -I $(INCLUDE)
ASFLAGS = -f elf
#CFILES = core.c consoleio.c system.c
CFILES = $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
SFILES = assembly/start.asm
SOBJS = $(SFILES:.asm=.o)
COBJS = $(CFILES:.c=.o)
OBJS = $(SOBJS) $(COBJS)
build : $(TARGET).img
$(TARGET).img : $(TARGET).elf
c:/python26/python.exe concat.py stage1 stage2 pad.bin core.elf floppy.img
$(TARGET).elf : $(OBJS)
$(LD) -T link.ld -o $# $^
$(SOBJS) : $(SFILES)
$(AS) $(ASFLAGS) $< -o $#
%.o: %.c
#echo Compiling $<...
$(CC) $(CFLAGS) -c -o $# $<
#Clean Script - Should clear out all .o files everywhere and all that.
clean:
-del *.img
-del *.o
-del assembly\*.o
-del core.elf
My main issue with this makefile is that when I modify a header file that one or more C files include, the C files aren't rebuilt. I can fix this quite easily by having all of my header files be dependencies for all of my C files, but that would effectively cause a complete rebuild of the project any time I changed/added a header file, which would not be very graceful.
What I want is for only the C files that include the header file I change to be rebuilt, and for the entire project to be linked again. I can do the linking by causing all header files to be dependencies of the target, but I cannot figure out how to make the C files be invalidated when their included header files are newer.
I've heard that GCC has some commands to make this possible (so the makefile can somehow figure out which files need to be rebuilt) but I can't for the life of me find an actual implementation example to look at. Can someone post a solution that will enable this behavior in a makefile?
EDIT: I should clarify, I'm familiar with the concept of putting the individual targets in and having each target.o require the header files. That requires me to be editing the makefile every time I include a header file somewhere, which is a bit of a pain. I'm looking for a solution that can derive the header file dependencies on its own, which I'm fairly certain I've seen in other projects.
As already pointed out elsewhere on this site, see this page:
Auto-Dependency Generation
In short, gcc can automatically create .d dependency files for you, which are mini makefile fragments containing the dependencies of the .c file you compiled.
Every time you change the .c file and compile it, the .d file will be updated.
Besides adding the -M flag to gcc, you'll need to include the .d files in the makefile (like Chris wrote above).
There are some more complicated issues in the page which are solved using sed, but you can ignore them and do a "make clean" to clear away the .d files whenever make complains about not being able to build a header file that no longer exists.
You could add a 'make depend' command as others have stated but why not get gcc to create dependencies and compile at the same time:
DEPS := $(COBJS:.o=.d)
-include $(DEPS)
%.o: %.c
$(CC) -c $(CFLAGS) -MM -MF $(patsubst %.o,%.d,$#) -o $# $<
The '-MF' parameter specifies a file to store the dependencies in.
The dash at the start of '-include' tells Make to continue when the .d file doesn't exist (e.g. on first compilation).
Note there seems to be a bug in gcc regarding the -o option. If you set the object filename to say obj/_file__c.o then the generated _file_.d will still contain _file_.o, not obj/_file_c.o.
This is equivalent to Chris Dodd's answer, but uses a different naming convention (and coincidentally doesn't require the sed magic. Copied from a later duplicate.
If you are using a GNU compiler, the compiler can assemble a list of dependencies for you. Makefile fragment:
depend: .depend
.depend: $(SOURCES)
rm -f ./.depend
$(CC) $(CFLAGS) -MM $^>>./.depend;
include .depend
There is also the tool makedepend, but I never liked it as much as gcc -MM
You'll have to make individual targets for each C file, and then list the header file as a dependency. You can still use your generic targets, and just place the .h dependencies afterwards, like so:
%.o: %.c
#echo Compiling $<...
$(CC) $(CFLAGS) -c -o $# $<
foo.c: bar.h
# And so on...
Basically, you need to dynamically create the makefile rules to rebuild the object files when the header files change. If you use gcc and gnumake, this is fairly easy; just put something like:
$(OBJDIR)/%.d: %.c
$(CC) -MM -MG $(CPPFLAGS) $< | sed -e 's,^\([^:]*\)\.o[ ]*:,$(#D)/\1.o $(#D)/\1.d:,' >$#
ifneq ($(MAKECMDGOALS),clean)
include $(SRCS:%.c=$(OBJDIR)/%.d)
endif
in your makefile.
Over and above what #mipadi said, you can also explore the use of the '-M' option to generate a record of the dependencies. You might even generate those into a separate file (perhaps 'depend.mk') which you then include in the makefile. Or you can find a 'make depend' rule which edits the makefile with the correct dependencies (Google terms: "do not remove this line" and depend).
Simpler solution: Just use the Makefile to have the .c to .o compilation rule be dependent on the header file(s) and whatever else is relevant in your project as a dependency.
E.g., in the Makefile somewhere:
DEPENDENCIES=mydefs.h yourdefs.h Makefile GameOfThrones.S07E01.mkv
::: (your other Makefile statements like rules
::: for constructing executables or libraries)
# Compile any .c to the corresponding .o file:
%.o: %.c $(DEPENDENCIES)
$(CC) $(CFLAGS) -c -o $# $<
None of the answers worked for me. E.g. Martin Fido's answer suggests gcc can create dependency file, but when I tried that it was generating empty (zero bytes) object files for me without any warnings or errors. It might be a gcc bug. I am on
$ gcc --version gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-16)
So here's my complete Makefile that works for me; it's a combination of solutions + something that wasn't mentioned by anyone else (e.g. "suffix replacement rule" specified as .cc.o:):
CC = g++
CFLAGS = -Wall -g -std=c++0x
INCLUDES = -I./includes/
# LFLAGS = -L../lib
# LIBS = -lmylib -lm
# List of all source files
SRCS = main.cc cache.cc
# Object files defined from source files
OBJS = $(SRCS:.cc=.o)
# # define the executable file
MAIN = cache_test
#List of non-file based targets:
.PHONY: depend clean all
## .DEFAULT_GOAL := all
# List of dependencies defined from list of object files
DEPS := $(OBJS:.o=.d)
all: $(MAIN)
-include $(DEPS)
$(MAIN): $(OBJS)
$(CC) $(CFLAGS) $(INCLUDES) -o $(MAIN) $(OBJS) $(LFLAGS) $(LIBS)
#suffix replacement rule for building .o's from .cc's
#build dependency files first, second line actually compiles into .o
.cc.o:
$(CC) $(CFLAGS) $(INCLUDES) -c -MM -MF $(patsubst %.o,%.d,$#) $<
$(CC) $(CFLAGS) $(INCLUDES) -c -o $# $<
clean:
$(RM) *.o *~ $(MAIN) *.d
Notice I used .cc .. The above Makefile is easy to adjust for .c files.
Also notice importance of these two lines :
$(CC) $(CFLAGS) $(INCLUDES) -c -MM -MF $(patsubst %.o,%.d,$#) $<
$(CC) $(CFLAGS) $(INCLUDES) -c -o $# $<
so gcc is called once to build a dependency file first, and then actually compiles a .cc file. And so on for each source file.
I believe the mkdep command is what you want. It actually scans .c files for #include lines and creates a dependency tree for them. I believe Automake/Autoconf projects use this by default.
I am creating a custom Makefile to to build a C++ Linux application. I have my cpp source files in a folder called src on the same level as the Makefile. So far I have been able to build my object files with the following :
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp | $(OBJ_DIR)
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $#
Now my project is starting to get a bit more complicated and I want subdirectories within src , such as src/common , and also, not every file is a cpp file now but also a c file.
I guess having a separate Makefile for each subdirectory is the best way but I am trying to keep this simple for now with just one Makefile.
I tried the following but doesn't work
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp $(SRC_DIR)/common/%.cpp $(SRC_DIR)/common/%.c | $(OBJ_DIR)
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $#
I could have the Makefile do a shell find to find all cpp and c files but also trying to avoid this.
I'd appreciate any recommendations.
This:
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp $(SRC_DIR)/common/%.cpp $(SRC_DIR)/common/%.c | $(OBJ_DIR)
cannot work; what it says that if make wants to build some file $(OBJ_DIR)/XXX.o and there is no explicit rule, then if and only if ALL the prerequisites $(SRC_DIR)/XXX.cpp, $(SRC_DIR)/common/XXX.cpp, and $(SRC_DIR)/common/XXX.c exist or can be created by make, then the rule will match.
If the same target could be built from multiple different prerequisites you must create multiple rules, one per prerequisite.
Also, it doesn't make sense to compile both C files (.c) and C++ files (.cpp) using the same recipe. C++ compilers use the variables CXX and CXXFLAGS and C compilers use the variables CC and CFLAGS.
As for avoiding find, you can't avoid informing make what files you want to be compiled, in some manner. You either have to list them in your makefile explicitly, or else use some method to generate them dynamically. There's no way around this. You don't have to use find if you don't want to; for example if you know that all the files will be either one or two directories down you could use wildcard, like:
SRCS := $(wildcard $(SRC_DIR)/*.cpp $(SRC_DIR)/*.c $(SRC_DIR)/*/*.cpp $(SRC_DIR)/*/*.c)
Abstract:
I have a .c file and a .cpp file with the same name in the same parent folder. I no longer wish to compile the .c file but doesn't want to remove it from the folder too.
Even though I explicitly specify to compile the .cpp file, the makefile was making use of the .c file. How can I fix this issue?
On renaming file3.c to another name, file3.cpp gets compiled.
Details:
The files present in 'src' folder are:
file1.c
file2.c
file3.c
file3.cpp
file4.cpp
Important extracts from the makefile:
SOURCE_FILES := ./src/file1.c \
./src/file2.c \
./src/file3.cpp \
./src/file4.cpp
OBJS = $(patsubst %.cpp,%.o,$(filter %.cpp, $(SOURCE_FILES))) \
$(patsubst %.c,%.o,$(filter %.c, $(SOURCE_FILES)))
all : $(OBJS)
$(CXX) $(CFLAGS) $(INCLUDES) -o $(PROJECT).bin $(OBJS) $(LDFLAGS) $(LIBRARIES)
.cpp.o:
$(CXX) $(CFLAGS) $(INCLUDES) -c $< -o $#
#echo 'CPP FILE : ' $<
.c.o:
$(CXX) $(CFLAGS) $(INCLUDES) -c $< -o $#
#echo 'C FILE : ' $<
On doing 'make', the log of the echo command gives:
C FILE : ./src/file1.c
C FILE : ./src/file2.c
C FILE : ./src/file3.c
CPP FILE : ./src/file4.cpp
Questions:
How can the above issue be solved?
Is there an easier way to fetch values for my OBJS variable?
The method make uses to pick which of two possible matching rules gets used depends on which version of make you are using. (It changed between 3.81 and 3.82 and I believe got tweaked slightly for 4.0+ but am not certain about that.)
I believe make 3.81 used the last matching rule and make 3.82+ uses the matching rule with the shortest stem (the bit that matches the %) and then the first matching rule between rules that have similar stem lengths.
So it would seem like you are using make 3.81 currently.
In that case it should be possible to simply swap the order of your two rules to get the behavior you want (assuming you always want .cpp files to "win").
Alternatively you could try giving make an explicit prerequisite for the file3.o target instead of letting it guess. (i.e. file3.o: file3.cpp)
That said neither of your explicit suffix rules is necessary as make already contains default rules to build .o files from both .c and .cpp files. (I don't know the relative ordering between them so you likely will need the explicit prerequisite, assuming that works, for the built-in rules to work correctly.)
Also you might want to look at using Pattern Rules instead of Old-Fashioned Suffix Rules just as a point of current practice.
The only improvement to your populating the OBJS variable that I can see, offhand, is to filter on the results and so just filter once.
OBJS = $(filter %.o,$(patsubst %.cpp,%.o,$(SOURCE_FILES)) \
$(patsubst %.c,%.o,$(SOURCE_FILES)))
That said you could also use Substitution References instead of explicit calls to $(patsubst) to shorten that a bit.
OBJS = $(filter %.o,$(SOURCE_FILES:.cpp=.o) $(SOURCE_FILES:.c=.o))
You have rules for both .c ==> .o and .cpp ==> .o.
In your case the rule for file3.c is run first since the newly created file3.o file now exists. Since the target file3.o file exists, there is no reason to compile file3.cpp.
Looking at the make manual, if there are 2 rules for the same target, the last rule is used.
Does anyone have a complete makefile that can do the following:
Rebuilds the project if a HEADER file changes
The cpp files are listed in the makefile
The header files are NOT listed in the makefile
The header files are allowed to have different names than the cpp files
Some of the cpp files do not have header files
I have seen instructions for figuring out how to make the make tool figure out header dependencies, but none of these instructions provide anything remotely resembling a working example. A simple example would be as follows: main.cpp C1.cpp C1.h C2.cpp C2.h
CXX = g++
OBJECTS := main.o C1.o C2.o
all: $(OBJECTS)
%.o : %.cpp
$(CXX) $(CPPFLAGS) -Wall -MMD -c $< -o $#
-include *.d
EDIT: As TobySpeight points out, this won't work if you build an object file, rename or delete one of the prerequisite source or header files, then try to rebuild the object file; the .d file will still require the missing file, and the build will fail. I neglected to include lines to deal with that case:
%.h: ;
%.cpp: ;
(This is effective, but crude. The more precise approach is to put some sed commands in the %.o rule, so as to add specific null rules to the .d file, one for each prerequisite, but the sed commands are ugly, and the approach above is good enough for almost all cases.)
You can also use CMake for this. Everything you need to write is:
add_executable (exec main.cpp C1.cpp C2.cpp)
I've looking to find a simple recommended "minimal" c++ makefile for linux which will use g++ to compile and link a single file and h file. Ideally the make file will not even have the physical file names in it and only have a .cpp to .o transform. What is the best way to generate such a makefile without diving into the horrors of autoconf?
The current dir contains, for example
t.cpp
t.h
and I want a makefile for that to be created. I tried autoconf but its assuming .h is gcc instead of g++. Yes, while not a beginner, I am relearning from years ago best approaches to project manipulation and hence am looking for automated ways to create and maintain makefiles for small projects.
If it is a single file, you can type
make t
And it will invoke
g++ t.cpp -o t
This doesn't even require a Makefile in the directory, although it will get confused if you have a t.cpp and a t.c and a t.java, etc etc.
Also a real Makefile:
SOURCES := t.cpp
# Objs are all the sources, with .cpp replaced by .o
OBJS := $(SOURCES:.cpp=.o)
all: t
# Compile the binary 't' by calling the compiler with cflags, lflags, and any libs (if defined) and the list of objects.
t: $(OBJS)
$(CC) $(CFLAGS) -o t $(OBJS) $(LFLAGS) $(LIBS)
# Get a .o from a .cpp by calling compiler with cflags and includes (if defined)
.cpp.o:
$(CC) $(CFLAGS) $(INCLUDES) -c $<
Here is a generic makefile from my code snippets directory:
SOURCES=$(wildcard *.cpp)
OBJECTS=$(SOURCES:.cpp=.o)
DEPS=$(SOURCES:.cpp=.d)
BINS=$(SOURCES:.cpp=)
CFLAGS+=-MMD
CXXFLAGS+=-MMD
all: $(BINS)
.PHONY: clean
clean:
$(RM) $(OBJECTS) $(DEPS) $(BINS)
-include $(DEPS)
As long as you have one .cpp source producing one binary, you don't need anything more. I have only used it with GNU make, and the dependency generation uses gcc syntax (also supported by icc). If you are using the SUN compilers, you need to change "-MMD" to "-xMMD". Also, ensure that the tab on the start of the line after clean: does not get changed to spaces when you paste this code or make will give you a missing separator error.
Have you looked at SCons?
Simply create a SConstruct file with the following:
Program("t.cpp")
Then type:
scons
Done!
Assuming no preconfigured system-wide make settings:
CXX = g++
CPPFLAGS = # put pre-processor settings (-I, -D, etc) here
CXXFLAGS = -Wall # put compiler settings here
LDFLAGS = # put linker settings here
test: test.o
$(CXX) -o $# $(CXXFLAGS) $(LDFLAGS) test.o
.cpp.o:
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $<
test.cpp: test.h
a fairly small GNU Makefile, using predefined rules and auto-deps:
CC=c++
CXXFLAGS=-g -Wall -Wextra -MMD
LDLIBS=-lm
program: program.o sub.o
clean:
$(RM) *.o *.d program
-include $(wildcard *.d)
Have you looked at OMake ?
OMakeroot
open build/C
DefineCommandVars()
.SUBDIRS: .
OMakefile
.DEFAULT: $(CXXProgram test, test)
Then on Linux or Windows, simply type:
omake
As a bonus, you automatically get:
parallel builds with the -j option (same as make).
MD5 checksums instead of timestamps (build becomes resilient to time synchronization failures).
Automatic and accurate C/C++ header dependencies.
Accurate inter-directory dependencies (something that recursive make does not offer).
Portability (1 build chain to rule them all, immune to path style issues).
A real programming language (better than GNU make).
Some good references on creating a basic Makefile
http://en.wikipedia.org/wiki/Make_(software)
http://mrbook.org/tutorials/make/
http://www.opussoftware.com/tutorial/TutMakefile.htm
http://www.hsrl.rutgers.edu/ug/make_help.html
The first couple in particular have minimal example Makefiles like you were describing. Hope that helps.
SConstruct with debug option:
env = Environment()
if ARGUMENTS.get('debug', 0):
env.Append(CCFLAGS = ' -g')
env.Program( source = "template.cpp" )
florin has a good starting point. I didn't like gnu autoconf so I started there and took the concept further and called it the MagicMakefile. I have 3 versions of it from simple to more complex. The latest is now on github: https://github.com/jdkoftinoff/magicmake
Basically, it assumes you have a standard layout for the source files of your project and uses the wildcard function to create the makefile rules on the fly which are then eval'd, handling header file dependancies, cross compiling, unit tests, install, and packaging.
[edit] At this point I use cmake for all my projects since it generates useful project files for many build systems.
jeff koftinoff
I was hunting around for what a minimal Makefile might look like other than
some_stuff:
#echo "Hello World"
I know I am late for this party, but I thought I would toss my hat into the ring as well. The following is my one directory project Makefile I have used for years. With a little modification it scales to use multiple directories (e.g. src, obj, bin, header, test, etc). Assumes all headers and source files are in the current directory. And, have to give the project a name which is used for the output binary name.
NAME = my_project
FILES = $(shell basename -a $$(ls *.cpp) | sed 's/\.cpp//g')
SRC = $(patsubst %, %.cpp, $(FILES))
OBJ = $(patsubst %, %.o, $(FILES))
HDR = $(patsubst %, -include %.h, $(FILES))
CXX = g++ -Wall
%.o : %.cpp
$(CXX) $(HDR) -c -o $# $<
build: $(OBJ)
$(CXX) -o $(NAME) $(OBJ)
clean:
rm -vf $(NAME) $(OBJ)
If your issues are because autoconf thinks the .h file is a c file, try renaming it to .hpp or .h++