.cpp to .o files in Makefile - makefile

How can I generate .o file corresponding to all the .cpp files in a directory using Makefile?
I have a directory that contains .cpp files. Now, I want to compile them in .o files. The name of the .o files should be same as corresponding .cpp files. What should I do?
Actually, I already had an implementation but I am not sure how it work
SRCS := $(wildcard $(SRCDIR)/*.cpp)
OBJS := $(SRCS:$(SRCDIR)/%.cpp=$(OBJDIR)/%.o)
$(OBJS): $(OBJDIR)/%.o : $(SRCDIR)/%.cpp
// Recipe //

Try this
SRCS=$(wildcard *.cpp)
OBJS=$(SRCS:.cpp=.o )
%.o: %.cpp
$(CC) -c $< -o $#
Let me add some more explaination to it.
SRCS := $(wildcard $(SRCDIR)/*.cpp) - It will list all the .cpp files under SRCDIR directory and will assign to SRCS
OBJS := $(SRCS:$(SRCDIR)/%.cpp=$(OBJDIR)/%.o) - It will replace all the files with .cpp listed from the above statement to .o ex: main.cpp would be changed to main.o and assigned to OBJS
$(OBJDIR)/%.o : $(SRCDIR)/%.cpp - Object files depends on respective .cpp files and in the rule you can write rule to create object files
The % character can be used for wildcard pattern-matching, to provide generic targets. For example:
%.o: %.c
[TAB] actions
When % appears in the dependency list, it is replaced with the same string that was used to perform substitution in the target.
If the above explanation is not clear just go through the Makefile Basics once and try writing without using special variables and then go to the complex rules.

Related

substituting folder path in $(SOURCES) of a makefile

I am looking for a way to substitute the folder on a list of source files variable within makefile.
Is there something that works here?
I start off by finding my source files
program_C_SRCS := $(wildcard $(SRCDIR)/*.c)
program_CXX_SRCS := $(wildcard $(SRCDIR)/*.cpp)
the results (if I understand GNU makefiles correctly) look typically like
src/main.cpp
src/sensor.cpp
then I build by object files
program_C_OBJS := ${program_C_SRCS:.c=.o}
program_CXX_OBJS := ${program_CXX_SRCS:.cpp=.opp}
this replaces the extensions of my source files as per expected.
Finally, I want to replace "src/" with "obj/"
program_C_OBJPATH := ${subst $(SRCDIR) , $(OBJDIR) , $(program_C_OBJS)}
program_CXX_OBJPATH := ${subst $(SRCDIR) , $(OBJDIR) , $(program_CXX_OBJS)}
However, this does not work.
I have gone through the GNU makefile website to no avail. This solution Makefile to put object files from source files different directories into a single, separate directory? comes close but the objects directory must be explicitly included everywhere and the sources directory does not include source path information.
In my makefile the list of source files include the path and I would prefer that the list of object files include the corresponding object directory, too.
The rest of the makefile tries also to use variables
linking stage
$(program_NAME): $(program_OBJS)
$(CXX) $(CFLAGS) $(CXXFLAGS) $(LDFLAGS) $(program_OBJS) -o "$(program_NAME)"
compile stage
%.opp : %.cpp | mkdirobjdir
$(CXX) $(CFLAGS) $(CXXFLAGS) $(CPPFLAGS) -c -o "$#" "$<"
and finally the rules
main_enose.opp : main_enose.cpp core_enose.cpp core_enose.h
$(OBJDIR)/core_enose.opp : core_enose.cpp core_enose.h
$(OBJDIR)/core_enose.h :
Your problem here is the spaces around the commas in the $(subst) calls. make isn't ignoring them the way you expect it might. It is seeing them as literal values in the string to find, the string to replace and the to do the replacement in.
Remove them.
program_C_OBJPATH := ${subst $(SRCDIR),$(OBJDIR),$(program_C_OBJS)}
program_CXX_OBJPATH := ${subst $(SRCDIR),$(OBJDIR),$(program_CXX_OBJS)}
That said you probably either want to use $(patsubst) to limit where the replacement happens:
program_C_OBJPATH := $(patsubst $(SRCDIR)/%,$(OBJDIR)/%,$(program_C_OBJS))
program_CXX_OBJPATH := $(patsubst $(SRCDIR)/%,$(OBJDIR)/%,$(program_CXX_OBJS))
or you want to use $(notdir) and $(addprefix) to handle stripping all the directory information and adding it back:
program_C_OBJPATH := $(addprefix $(OBJDIR)/,$(notdir $(program_C_OBJS)))
program_CXX_OBJPATH := $(addprefix $(OBJDIR)/,$(notdir $(program_CXX_OBJS)))

Makefile: Can VPATH variable is applied to assigning Makefile variable?

i've tried to write simple makefile for practice.
I have two directories 1. srcs(.c), 2.include(.h)
and try to define SRCS variable that would contain all .c files
in current directory and srcs directory.
and below is my Makefile
CURDIR = $(shell pwd)
OBJDIR = $(CURDIR)/objdir
VPATH = $(CURDIR)/srcs
SRCS = $(wildcard *.c)
OBJS = $(patsubst %.c, %.o, $(SRCS))
all: main
main: $(OBJS)
gcc -o $# $^
$(OBJS): $(SRCS) | $(OBJDIR)
gcc -c -o $# $<
$(OBJDIR):
mkdir objdir
I designate current/src directory as a VPATH to make find
all *.c files in current directory and current/srcs but
it cannot find *.c files in /srcs directory.
May be make cannot us VPATH when it defines the variable in Makefile
right? if it's right please let me know better approach :)
Thanks.
VPATH is for directories make should search to find prerequisites.
It doesn't change where $(wildcard) searches.
VPATH lets you use foo.c (either explicitly or implicitly) in the prerequisite list of a rule and have make look in the current directory and the VPATH directories for the file for it.
If you want SRCS to contain the .c files from the srcs directory then you need to include srcs/*.c in an additional $(wildcard) call in the SRCS assignment.
SRCS = $(wildcard *.c) $(wildcard srcs/*.c)

Why isn't make detecting changes in header dependencies

I'm not sure what I'm doing wrong here. I'm trying to get make to figure out what dependencies my project has for, not only source files, but non-system included header files. I've many resources from this very site related to this subject.
Such as: Makefile header dependencies and Makefile, header dependencies
However, when I do
touch MyHeader.h
as a test to see if this works, my make process fails to rebuild the source files that include this header. So, here's what I have in my makefile (of relevance that is)
CPP=g++
CPPFLAGS=-Iadditional/includes -MMD
CXXFLAGS=-std=c++0x -c
# not every source file in this directory needs to be included in this build
# this is because of shared code with Windows
SOURCESFILTER = File1.cpp File2.cpp
OBJ_DIR=obj
SOURCES = $(filter-out $(SOURCEFILTER),$(wildcard *.cpp))
OBJECTS = $(addprefix $(OBJ_DIR)/,$(SOURCES:.cpp=.o))
DEPENDENCIES = $(OBJECTS:.o=.d)
.PHONY: archive
archive : $(OBJECTS)
ar mylib.a obj/*.o
-include $(DEPENDENCIES)
$(OBJ_DIR)/%.o: $(SOURCES) $(DEPENDENCIES)
$(CPP) $(CPPFLAGS) $(CXXFLAGS) $< -o $#
I've verified that the above process does indeed generate the expected *.d files. I assume that I'm including them correctly. However, as mentioned, as a test I do:
touch MyHeader.h
which is in the same directory as the sources, and rerun the make, none of the source files which include this header are remade. What am I missing?
Andy
First, you cannot include prerequisites in a suffix rule. Even if you could, you certainly would not want to include $(SOURCES) or $(DEPENDENCIES), because that would cause every object to rebuild whenever any source or dependency file changed.
Second, you cannot create the target file in a different directory from where make expects it to be. Make will put the place where it wants to find the target in the variable $#, and you must write the output into that location exactly. If you ever see a rule that modifies the target, such as above where you use obj/$#, that won't work.
Most likely GCC is writing the files as obj/foo.d, but your include is trying to include foo.d but that doesn't exist... but since you used -include make doesn't complain.
I recommend you first write the object files into the local directory and get that working with dependencies. Once that works, then read up on how to write targets to a different directory and/or ask again.
ETA:
Try something like this:
CXX := g++
CPPFLAGS := -Iadditional/includes -MMD
CXXFLAGS := -std=c++0x
# not every source file in this directory needs to be included in this build
# this is because of shared code with Windows
SOURCESFILTER := File1.cpp File2.cpp
OBJ_DIR := obj
SOURCES := $(filter-out $(SOURCEFILTER),$(wildcard *.cpp))
OBJECTS := $(addprefix $(OBJ_DIR)/,$(SOURCES:.cpp=.o))
DEPENDENCIES := $(OBJECTS:.o=.d)
.PHONY: archive
archive: mylib.a
mylib.a: $(OBJECTS)
$(AR) $# $^
-include $(DEPENDENCIES)
$(OBJ_DIR)/%.o: %.cpp
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $# $<

makefile: lint multiple source files and out put to corresponding txt files

I'm trying to run a makefile on a directory such that it runs lint on all the cpp files in that directory and save the output in multiple files with the same names as source files.
e.g. in other words I want to save lint out put for abc.cpp to abc.txt and def.cpp to def.txt and so on for all the unknown number of files to a sub-directory lintfiles.
some thing like the following:-
*lint .ALWAYS:*
--lint-nt $(PATHS) $(OPTIONS) *.cpp > ./lintfiles/%f.txt
make util is not understanding Lint's %f option. I also tried the following but it generates no output.
lintfiles/%.txt: %.cpp
-lint-nt $(PATHS) $(OPTIONS) $# $^
please suggest.
I'm not familiar with pc-lint, but if the syntax is something like
lint-nt -o abc.lint abc.cpp
then this makefile should do the job:
SRC_DIR := src # or whatever
SRCS := $(wildcard $(SRC_DIR)/*.cpp)
LINTS := $(patsubst $(SRC_DIR)/%.cpp, $(SRC_DIR)/lint/%.lint, $(SRCS))
all: $(LINTS)
$(LINTS): $(SRC_DIR)/lint/%.lint : $(SRC_DIR)/%.cpp
lint-nt $(PATHS) $(OPTIONS) -o $# $<

Generating a makefile target dependency from the filename in a stem

Hi I have a makefile I am creating where each .o is represented as a relative path to another directory and has a dependency on a .cpp file in the local directory. My understanding of the problem is that I can't use functions in a rule definition so the rule:
%.o: %.cpp
results in a prerequisite .cpp that is in the same directory as the .o which is not where the cpp is actually located. For example:
../../Tmp/MyClass.o: ../../Tmp/MyClass.cpp <--- WRONG, result of %.o: %.cpp
../../Tmp/MyClass.o: MyClass.cpp <--- RIGHT, how do I do this in an automatic way?
Lastly the output, which is in yet another directory, has a dependency on the .o's so they must all have full relative path information from the beginning:
OBJS := $(addprefix ../../../Tmp/XCode/${PLATFORM}/${CONFIGURATION}/, $(addsuffix .o, $(basename ${SRCS})))
${OUTPUT}: ${OBJS} ; ${AR} $# ${OBJS}
Thanks!
I think kristi's solution will work, but here's another way to do the same thing:
# Here's how you do it:
OBJS := $(addprefix ../../../Tmp/XCode/${PLATFORM}/${CONFIGURATION}/, $(addsuffix .o, $(basename ${SRCS})))
# Here's a slightly cleaner way:
BASEPATH = ../../../Tmp/XCode/$(PLATFORM)/$(CONFIGURATION)
OBJS := $(patsubst %.cc,$(BASEPATH)/%.o,$(SRCS))
# And here's the rule:
$(OBJS): $(BASEPATH)/%.o: %.cc
whatever...
This should work
../../Tmp/%.o: %.cpp
Or use a variable
builddir := ../../Tmp
$(builddir)/%.o: %.cpp

Resources