Creating makefile c++ that stores .o to a directory - c++

Here is an example of how my datas are stored :
\Program
main.cpp
makefile
\Part1
file1.cpp
file1.h
file2.cpp
etc
\Part2
file3.cpp
file4.cpp
file4.h
etc..
\Part3
file5.cpp
file5.h
etc..
\Objects
file1.o
file2.o
file3.o
file4.o
I think you understood.
My problem is that whatever I try my makefile does not work
clang: error: no input files
or
Undefined symbols for architecture x86_64:
Well, I tried to learn by myself how to build a makefile. I leant the easiest way like :
all:exe
exe: Objects/file1.o Objects/file2.o Objects/file3.o Objects/file4.o Objects/file5.o .....
$(CPP) $(LFLAGS) Objects/file1.o Objects/file2.o Objects/file3.o ... -o exe
And then, for each .o I ask the makefile to do like :
Objects/file1.0: Part1/file1.cpp
$(CPP) $(CFLAGS) -o $(OBJ/file1).o Part1/file1.o
But I keep having this issue :
makefile:XX: warning: overriding commands for target .o'
makefile:XX: warning: ignoring old commands for target.o'
For every file
I tried to learn how to build makefile more proprelly but it's quite difficult. I tried many, many things and it doesn't work.
Here is what I mean when I say a proper way to write makefile
ALL_CPP=Part1/*.cpp, Part2/*.cpp, Part3/*.cpp, Part4/*.cpp
CPP_FILES := $(wildcard $(ALL_CPP))
OBJ_FILES = $(patsubst $(ALL_CPP),Objects/%.o,$(CPP_FILES))
main: $(OBJ_FILES)
g++ -o $# $^
Objects/%.o: Animal/%.cpp
g++ $(CFLAGS) -c -o $# $<
Objects/%.o: Enclos/%.cpp
g++ $(CFLAGS) -c -o $# $<
Objects/%.o: Menu/%.cpp
g++ $(CFLAGS) -c -o $# $<
Objects/%.o: Zoo/%.cpp
g++ $(CFLAGS) -c -o $# $<
But of course it doesn't work.
My question is :
How to create a makefile which would work in an environment like mine (with different subfolder) and which would store the .o in a dedicated folder.
I worked using xcode but unfortunately I want a menu where you can navigate using the arrows which doesn't work on the xcode console.

Your second attempt was pretty close.
The problem is with this line
OBJ_FILES = $(patsubst $(ALL_CPP),Objects/%.o,$(CPP_FILES))
The first argument to $(patsubst) is the pattern to match but $(ALL_CPP) isn't a pattern. You want dir/%.c for each directory there. You could make that list of patterns if you really wanted to but there's a better way to do it.
You really have two transformations here. One to replace any leading directory with Objects and one to replace .cpp with .o.
So do them separately.
Use a Substitution Reference for the first part:
OBJ_FILES := $(CPP_FILES:.cpp=.o)
and the notdir and addprefix file name functions for the second part:
OBJ_FILES := $(addprefix Objects/,$(notdir $(OBJ_FILES))
and that should make things work.

Related

When do files in C++ with direct & indirect dependencies have to be recompiled and when is a new linking of the executable sufficient? [duplicate]

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.

Makefile with multiple separate *.cpp files to output separate *.exe files in different dir

I am stuck, writing my Makefile.
Directory structure:
.\
Makefile
.\src\*.cpp(s)
.\bin
Desire: What I want to achieve with one Makefile.
Run: make
Output (Terminal):
g++ -g -Wall -c -o src/program1.o src/program1.cpp
g++ -g -Wall -c -o src/program2.o src/program2.cpp
g++ -g -Wall -c -o src/program3.o src/program3.cpp
g++ -g -Wall -c -o src/program4.o src/program4.cpp
Output (in /bin/)
program1.exe
program2.exe
program3.exe
program4.exe
EDIT:
CXX = g++
CXXFLAGS = -Wall -g3 -O0
SRC := ${wildcard src/*.cpp}
OBJS := $(SRC:.cpp=.o)
BIN := $(SRC:src/%.cpp=bin/%)
.PHONY: all
all: $(BIN)
$(BIN): $(OBJS)
$(CXX) -c $(CXXFLAGS) -o $(OBJS)
bin/%: src/%.o
$(CXX) -o $# $^
Error:
g++: warning: linker input file unused because linking not done
The introductory parts of the GNU make manual describe that all: $(BIN) creates a target all that depends on a target bin. That means make will try to create bin. Then you have $(BIN): $(OBJS) which says bin depends on all the object files, so make will try to create all the object files. Then there's a recipe for that rule that says, after you've created the object files run this command, which links together all the object files into a single program (bin).
So make is doing exactly what you asked it to do.
The problem is that is apparently not what you want it to do.
In your question you write, then take the original filenames of each *.cpp and add that to the executable which I don't fully understand, but I assumed that you want to link all the objects into a single executable, which is what your makefile does.
But then later you write: How can I output to bin directory and generate the correct executables?, but you never define what "correct executables" means, and this makes it sound like you want to turn each individual object file into its own executable; that's clearly not what your makefile does.
So before you can tell make what you want, first you have understand clearly what you want so you can write it in your makefile. And if you need us to help you write it into your makefile, you need to explain it clearly in your question so we can understand it.
Cheers!
ETA
OK so you want every source file to compile into an object file, then every object file to compile to a separate binary.
First compute the names of all the binaries you want to build:
SRCS := $(wildcard src/*.cpp)
BINS := $(SRCS:src/%.cpp=bin/%)
Now make a rule that depends on all the binaries:
all: $(BINS)
Now make a pattern rule that tells make how to build each one of those binaries:
bin/% : src/%.o
$(CXX) $(CXXFLAGS) -o $# $^ $(LDLIBS)
Now you're actually done, because make already has a built-in rule that knows how to build a .o file into the same directory where the .c file lives, so it can figure out how to build the src/x.o files on its own.
Try something like:
SRC:=${wildcard src/*.cpp}
OBJ:=$(patsubst %.cpp,%.o,${patsubst src/%,bin/%,${SRC}}}
to get the list of the object files, and the rule:
obj/%.o : src/%.cpp
${CXX} -o $# -c $<
for compiling into the right location.
EDIT You have now clarified that each file is a separate main.
SRC:=${wildcard src/*.cpp}
BIN:=$(patsubst %.cpp,,${patsubst src/%,bin/%,${SRC}}}
to get the list of the object files, and the rule:
bin/% : src/%.cpp
${CXX} -o $# $<
will write each output as an executable in bin. To kick it off:
all : ${BIN}

Using ifeq in makefile to compile either C or CPP file

I want to compile all the files located in src/ directory to bc/%.bc.
Because I use the std=c++17 flags which can not be used with .c files, I tried this :
bc/%.bc: src/%.*
ifeq '$(suffix $^)' '.c'
emcc $^ -o $#
else
em++ $^ -o $# -std=c++17
endif
But it does not work, the condition ifeq is always false (same when I replace '.c' with '.cpp').
Is there a way to achieve a separate compilation based on file suffix ?
There's more than one way to do it. The best is probably to separate the rule into two rules, one for .c and one for .cpp:
bc/%.bc: src/%.c
emcc $< -o $#
bc/%.bc: src/%.cpp
em++ $^ -o $# -std=c++17
Then you need a way to construct a list of the files you want. (You need this anyway, since that src/%.* doesn't work the way you think.)
SRC_FILES := $(wildcard src/%.*)
TARTGETS := $(patsubst src/%, bc/%.bc, $(basename $(SRC_FILES)))
And a default rule to build everything:
$(TARGETS):

makefile picks the same source file again and again for different objects

I am trying to write a makefile, suppose I have 4 source files in a directory src/app/:
src/app/file1.cpp
src/app/file2.cpp
src/app/file3.cpp
src/app/file4.cpp
and I want to create different object files (i.e. file1.o, file2.o etc.) into another directory called obj/. In the makefile, I am defining the variables like this:
$(SRC) := $(wildcard src/app/*.cpp)
$(OBJ) := $(addprefix obj/,$(notdir $(SRC:.cpp=.o)))
and my commands are like this:
all: $(OBJ)
$(OBJ): $(SRC)
$(CC) $(CFLAGS) -I/src/app/app.h -c $< -o $#
so when I run make, I see these operations:
g++ -g -Wall -I/src/app/app.h -c src/app/file1.cpp -o obj/file1.o
g++ -g -Wall -I/src/app/app.h -c src/app/file1.cpp -o obj/file2.o
g++ -g -Wall -I/src/app/app.h -c src/app/file1.cpp -o obj/file3.o
g++ -g -Wall -I/src/app/app.h -c src/app/file1.cpp -o obj/file4.o
You can see, the object files have different names but the source file is the same. How do I fix it ?
Please note that I can't use %.o: %.cpp since I have other targets in my makefile for different purposes.
If you can't use
obj/%.o: src/app/%.cpp
then the second simplest way is to add $(OBJ): to the front:
$(OBJ): obj/%.o: src/app/%.cpp
It's called "static pattern rules" - look it up in the GNU Make manual.
I have found a way to solve this (thanks to Zereges for the idea):
$(RGAOBJ): $(RGASRC)
$(CC) $(CFLAGS) -I/src/app/app.h -c \
$(addprefix src/app/,$(notdir $(#:.o=.cpp))) -o $#
I think there is a better way to do.
So any other pointer will be helpful.
The $< variable picks up the first dependency. It is used with generic targets which have variable targets and produce different results. The compile target would match a pattern as target and have a generic dependency. The first target doesn't change in your case.
Your constraint of not being able to use a generic rule is entirely defeating the purpose of the $< variable. A somewhat naive work-around is to translate the destination name back into the source, e.g.,
$(OBJ): $(SRC)
$(CC) $(CFLAGS) -I/src/app/app.h -c $(#:%.o=%.cpp) -o $#
The problem with that approach is that no all object files depend on all source files. As a result, every time one of the source files is changed all object files are produced. For tiny projects and source that may be viable. On anything which I'd consider a real project neither of these conditions holds.
My understanding on your statement on not being able to use pattern rules is that you already have rules for the same pattern but you need to build some targets with some special rules. A work around for that situation is to build targets with a custom suffix which actually build something different and just use a marker file to prevent unnecessary rebuilds. For example:
all: $(OBJ:%=%.custom)
%.o.custom: %.cpp
$(CC) $(CFLAGS) -W -I/src/app/app.h -c $< -o $(#:%.custom=%) && touch $#

Creating static library from multiple sources

I'm trying to create a Makefile that, among other things, outputs some library1.a, that I will reuse afterwards to create an executable. Now here's my dilemma: I want to make the this process generic, so that I don't have to edit the Makefile each time I add some files. Here's what I have in mind:
#Declare phony targets
.PHONY: all clean build_utils
#Compiler
CXX = g++
#Flags
CXXFLAGS = -Wall -Wextra -Wconversion -Werror -pedantic -std=c++0x -O2
#Directories
OUTPUT_DIR = _output/linux
INTERMEDIATE_DIR = _intermediate/linux
UTILS_DIR = utils
all: $(OUTPUT_DIR)/libUtils.a
$(OUTPUT_DIR)/libUtils.a:
ar rcs $# $(INTERMEDIATE_DIR)/utils/$(patsubst %.cpp, %.o, $(wildcard $(UTILS_DIR)/ *.cpp))
#create .o files in %INTERMEDIATE_DIR/utils
build_utils: $(UTILS_DIR)/ *.cpp $(UTILS_DIR)/ *.h
$(CXX) -c $(CXXFLAGS) $^ -o ## What must be placed here? ##
So, basically, I want all the object files to be created in a temporary directory and then to be archived in libUtils.a, but I can't figure out how to ask the compiler to output multiple object files based on the input files. Basically, my standards impose that for each .cpp file, I should get an object file, but I'm not sure how to do this. I don't want to create a separate target for each .o file, because it's too messy.
You can use a wildcard rule like the following to compile each C++ source file separately:
%.o: %.cpp
$(CXX) $< $(CXXFLAGS) $#
After adding -c -o at the end of your CXXFLAGS. Then capture the result of the patsubst expression somewhere, like:
OBJECTS = $(patsubst %.cpp, %.o, $(wildcard $(UTILS_DIR)/*.cpp))
... and have the $(OUTPUT_DIR)/libUtils.a rule depend upon $(OBJECTS).
So, after many hours of digging, here's what I've managed to come up with:
#Build object files
$(INTERMEDIATE_DIR)/$(UTILS_DIR)/%.o: $(UTILS_DIR)/%.cpp $(UTILS_DIR)/%.h
mkdir -p $(INTERMEDIATE_DIR)/$(UTILS_DIR)
$(CXX) $< $(LIBCXXFLAGS) -o $#
$(INTERMEDIATE_DIR)/$(FUNCTIONS_DIR)/%.o: $(FUNCTIONS_DIR)/%.cpp $(FUNCTIONS_DIR)/%.h
mkdir -p $(INTERMEDIATE_DIR)/$(FUNCTIONS_DIR)
$(CXX) $< $(LIBCXXFLAGS) -o $#
#create the library archives
$(OUTPUT_DIR)/libUtils.a: $(patsubst %.cpp, $(INTERMEDIATE_DIR)/%.o, $(wildcard $(UTILS_DIR)/ *.cpp))
ar rcs $# $^
$(OUTPUT_DIR)/libFunctions.a: $(patsubst %.cpp, $(INTERMEDIATE_DIR)/%.o, $(wildcard $(FUNCTIONS_DIR)/ *.cpp))
ar rcs $# $^
#Builds the libraries
libs: $(OUTPUT_DIR)/libUtils.a $(OUTPUT_DIR)/libFunctions.a
#Main target
all: libs
The nice part about it is that I don't have to edit it each time I add a file. I think it can be made even more abstract than this, by having a single generic target which builds the object files, but that seems a bit too much.
PS: Thanks Martin for giving me a good idea on what to use! :)
LE: It seems that it's very hard to convince SO to not try to do syntax highlighting. Not even the <pre></pre> tag helps when dealing with /*...