add all .cpp files in a directory in make? - makefile

is there a way to include all .cpp files in make?
I tried this and it does not work
# the build command
error_app: error_reporting.cpp $(INCLUDE_PATH)%.cpp
$(CC) $(CFLAGS) $^ -o $(DEBUG_PATH)$#.exe
is manually typing it the only way?
# the build command
error_app: error_reporting.cpp $(INCLUDE_PATH)error_checker.cpp $(INCLUDE_PATH)error_report.cpp
$(CC) $(CFLAGS) $^ -o $(DEBUG_PATH)$#.exe

$(wildcard $(INCLUDE_PATH)/*.cpp).
There's also a recursive alternative to wildcard here if you want to include subdirectories as well.
Also, don't add .exe to output filenames. MinGW will add it automatically, and it's unnecessary on Linux. And don't forget .PHONY if your target name doesn't match the filename it generates.

Related

Create object files in one folder from different source folders

I am creating a Makefile of a Keil based project. I have a working Makefile now, but I have manually written rules for all the source files, something like this:
out/abc.o: ../../../src/modules/abc.c
ARMCC -o $# $(FLAGS) $^
out/def.o: ../../../src/utilities/def.c
ARMCC -o $# $(FLAGS) $^
out/xyz.o: src/xyz.c
ARMCC -o $# $(FLAGS) $^
which has become kinda long. The object files need to be in one directory(/out), but the source files are in different levels and in various folders like utilities, modules etc. Is there a way to shorten my Makefile so that it scans these different levels of source files and creates the object files?
EDIT:
A follow-up question to the answer. My linker rule is something like this, along with the VPATH addition. I added one directory to VPATH and others are still explicitly compiled.
OBJECT_FILES=out/abc.o out/def.o out/xyz.o
out/binary.axf: $(OBJECT_FILES)
ARMLINK $(MANY_FLAGS) $^ -o $#
VPATH=../a/b/c/module
out/%.o : %.c
$(CC) $(C_FLAGS) $(INCLUDE_PATH) -o $# --depend out/%.d $<
I now get an error that there is no rule for abc.o. abc.c which is present in the directory specified in VPATH under module
*** No rule to make target `out/abc.o', needed by `out/binary.axf'. Stop.
You can use VPATH for this. It can search a list of directories for source files. Assuming you can come up with the list of directories:
VPATH = ../../../src src
CC = ARMCC
out/%.o : %.c
$(CC) -o $# $(CFLAGS) -c $<

Object file directory per compiler option combinations

I was reading gnu make section 10.5.4 "How patterns match" and it does not sound like I can do what I want.
I want to setup a directory structure where my source code is in one directory, and there are sub-directories to hold object files.
One sub-directory for each build configuration.
So I might have these files
a.c
debug/a.o # compiled with -g
release/a.o # compiled with -O
So I would like to make rules like this
debug/%.o : %.c
gcc -c -g %.c -o $#
release/%.o : %.c
gcc -c -O %.c -o $#
But section 10.5.4 tells me a match on "debug/a.o" will make the stem be "debug/a" so gnu make
will look for the source file at "debug/a.c" which is not what I want.
Is there a way to get GNU make to help me ?
Your makefile will work as written.
From that section of the manual:
When the target pattern does not contain a slash (and it usually does
not), directory names in the file names are removed from the file name
before it is compared with the target prefix and suffix. After the
comparison of the file name to the target pattern, the directory
names, along with the slash that ends them, are added on to the
prerequisite file names generated from the pattern rule's prerequisite
patterns... [bold added]
Your target patterns do contain slashes.
Try it if you don't believe me.
EDIT:
Correction: in the commands you should use $< rather than %.c.
CC=gcc
DEBUGFLAGS=-g
RELEASEFLAGS=-O
debug/%.o : %.c
$(CC) $(DEBUGFLAGS) -c $< -o $#
release/%.o : %.c
$(CC) $(RELEASEFLAGS) -c $< -o $#

Makefile - Pattern Rule as a dependency

I've ha makefile with following entries. Will the first rule depend on the secon rule ? So that it builds all the .o files from second files ?
all:$(PROG)
$(PROG): *.o
$(LD) -o $(PROG) -c $< $(LFLAGS)
%.o : %.c
$(CC) $(CFLAGS) -o $# -c $<
To be specific if i invoke 'make all' will it invoke the second rule if no *.o files were found ?
All other Variables have usual meaning .
No, that will not work. When you run your makefile for the first time, are there any .o files? No. So the expression *.o will expand to nothing.
Of course, your recipe for $(PROG) doesn't actually use any of the object files anyway, as written.
You can do something like this (although personally I prefer to simply list the files out by hand; it's not very common to create all new files so it's not much effort, and it's safer than just trying to grab every file in the directory):
SOURCES := $(wildcard *.c)
OBJECTS := $(SOURCES:%.c=%.o)
$(PROG): $(OBJECTS)

generic make rule assitance when placing files into different folders

I have a make rule like this. I want it to define a generic rule that describes transformation of any C file into compiled Object file. It works fine, but i want to keep my C files in one folder and output files in another.
Here is the relevant snippet from Makefile itself:
.SUFFIXES .c .o
.c.o :
$(GCC) -c $(CFLAGS) $< -o $#
I want to modify this makefile rule to tell make to find the source (C) files in one folder, let's say $(C_DIR), run GCC and then and put OBJ files into $(O_DIR) ?
You cannot do that with suffix rules. In order to do that you'll have to use non-POSIX-standard make features. GNU make (the standard make on GNU/Linux systems for example, and available for pretty much any other platform) provides pattern rules that can do this:
SRCS = foo.c bar.c baz.c
OBJS = $(addprefix $(O_DIR)/,$(SRCS))
all: $(OBJS)
$(O_DIR)/%.o : $(C_DIR)/%.c
$(CC) -c $(CPPFLAGS) $(CFLAGS) -o $# $<

Makefile trouble, clarification needed

The following is the Makefile i use. All is well, except for .o should be created in obj/ directory and it's not.
What am i doing wrong please?
After making sure that
src directory contains a.cpp
target directory exists and is empty
obj directory exists and is empty
When make is ran, i see
g++ -pedantic -Wall -c src/a.cpp -o /Users/me/Dropbox/dev/c++/hott/obj/src/a.o
when it should be
g++ -pedantic -Wall -c src/a.cpp -o /Users/me/Dropbox/dev/c++/hott/obj/a.o
What am i doing wrong please?
UPDATE: Nothing seems to change when hardcoding path and not relying on pwd resolution
If you use -o you have to specify the filename, not just the output path. Try:
$(CC) $(FLAGS) $(SOURCES) $(OBJ)/$#
This question may help, too:
What do the makefile symbols $# and $< mean?
Also, you may want to call FLAGS something like CFLAGS, meaning "the flags for compilation".
Edit
Note that you are not using make efficiently, because you are always recompiling all your .o files from your .cpp files. You should instead use a Pattern Rule, so that Make can have rules to only build what is necessary. (ie. "To build any .o file from a .cpp file, do this: ___") 
%.o : %.c
$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $#
You could edit this to include $(OBJ) before the $#.
All is ok when used like this. A small modification from what Jonathon suggested

Resources