Make file building all objects files from same source file - c++

I have a project that contains a obj and a src subfolder.
When I run make with the following Makefile, it builds each .o with the same src.
CXX = g++
CXXINCDIRS = -I./ext/glui/include -I.
CXXLIBDIR = /usr/lib/
SRCDIR = ./src
OBJDIR = ./obj
INCDIR = ./include
BINDIR = ./bin
EXE = $(BINDIR)/brushwork
CXXFLAGS += -W -Wall -Wextra -Weffc++ -std=c++11 $(CXXINCDIRS)
SRC_CXX = $(wildcard $(SRCDIR)/*.cc)
OBJECTS_CXX = $(patsubst $(SRCDIR)/%.cc, $(OBJDIR)/%.o, $(SRC_CXX))
LIBRARY_CXX = -lglut -lGL -lGLU -L/usr/lib -lglui
$(OBJDIR)/%.o: $(SRCDIR)/%.cc
g++ -o $# -c $<
$(EXE): $(OBJECTS_CXX) | $(BINDIR)
$(CXX) $(CXXFLAGS) $(CXXINCDIRS) -o $# $^ $(CXXLIBDIR) $(LIBRARY_CXX)
$(OBJECTS_CXX): $(SRC_CXX) | $(OBJDIR)
$(CXX) $(CXXFLAGS) -c -o $# $<
$(OBJDIR)/%.o: $(SRC_CXX) $(INCDIR)/%.h | $(OBJDIR)
$(CXX) $(CXXFLAGS) -c -o $# $<
$(BINDIR) $(OBJDIR):
mkdir -p $#
When I run the command
make -B -n
I get
mkdir -p obj
g++ -W -Wall -Wextra -Weffc++ -std=c++11 -I./ext/glui/include -I. -c -o obj/tool.o src/tool.cc
g++ -W -Wall -Wextra -Weffc++ -std=c++11 -I./ext/glui/include -I. -c -o obj/base_gfx_app.o src/tool.cc
g++ -W -Wall -Wextra -Weffc++ -std=c++11 -I./ext/glui/include -I. -c -o obj/color_data.o src/tool.cc
g++ -W -Wall -Wextra -Weffc++ -std=c++11 -I./ext/glui/include -I. -c -o obj/main.o src/tool.cc
g++ -W -Wall -Wextra -Weffc++ -std=c++11 -I./ext/glui/include -I. -c -o obj/pixel_buffer.o src/tool.cc
g++ -W -Wall -Wextra -Weffc++ -std=c++11 -I./ext/glui/include -I. -c -o obj/brushwork_app.o src/tool.cc
mkdir -p bin
g++ -W -Wall -Wextra -Weffc++ -std=c++11 -I./ext/glui/include -I. -I./ext/glui/include -I. -o bin/brushwork obj/tool.o obj/base_gfx_app.o obj/color_data.o obj/main.o obj/pixel_buffer.o obj/brushwork_app.o /usr/lib/ -lglut -lGL -lGLU -L/usr/lib -lglui
I am not sure why each obj file is being built with the same src file.
I have tried $(SRCDIR)/%.cc but make complains that there is no recipe for $(SRCDIR)/%.cc
How can I have make build each src file it's respective src file?

For this:
$(OBJDIR)/%.o: $(SRC_CXX) $(INCDIR)/%.h | $(OBJDIR)
$(CXX) $(CXXFLAGS) -c -o $# $<
I think you need this:
$(OBJDIR)/%.o: $(SRCDIR)/%.cc $(INCDIR)/%.h
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $# $<
I'm not sure what this does:
$(OBJECTS_CXX): $(SRC_CXX) | $(OBJDIR)
$(CXX) $(CXXFLAGS) -c -o $# $<
I suspect you should remove it.
And I think you should also remove this:
$(OBJDIR)/%.o: $(SRCDIR)/%.cc
g++ -o $# -c $<
It looks like you had 3 different rules to build your objects (unless I read it wrong).

Related

creating two outputs with Makefile

I want to create a makefile which runs program in C++ once with "CXXFLAGS = -std=c++11 -g -O3 -DTEST -fopenmp" and one time with: "CXXFLAGS = -std=c++11 -g -O3 -fopenmp"
at the end outputs two different files like P1-Test and P1. how can I edit this file?
CXX = g++
CXXFLAGS = -std=c++11 -g -O3 -fopenmp
ifdef code_coverage
GCOV_FLAG := -DTEST
else
GCOV_FLAG :=
endif
all: P1
#echo The program has been compiled
# implicit rule: create x from x.cpp
.cpp:
$(CXX) $(CXXFLAGS) $? -o $#
$(CXX) $(CXXFLAGS) $(GCOV_FLAG) $? -o $#
.PHONY: clean
clean:
$(RM) -r P1 *.dSYM
My suggestion:
CXX = g++
CXXFLAGS = -std=c++11 -g -O3 -fopenmp
all: P1 P1-Test
#echo The program has been compiled
# implicit rule: create x from x.cpp
.cpp:
$(CXX) $(CXXFLAGS) $? -o $#
.PHONY: clean
clean:
$(RM) -r P1 *.dSYM
P1: main.o second.o
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o "$#" $^
P1-Test: CXXFLAGS+=-DTEST
P1-Test: main.o second.o
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o "$#" $^
With sample sources:
File main.cpp
extern void foo(); // should be in second.h or something
int main() { foo(); }
File second.cpp
#include <cstdio>
void foo() {
#ifdef TEST
puts("TEST defined");
#else
puts("TEST not defined");
#endif
}
Results in
$ make -B
g++ -std=c++11 -g -O3 -fopenmp -o "P1" main.cpp second.cpp
g++ -std=c++11 -g -O3 -fopenmp -DTEST -o "P1-Test" main.cpp second.cpp
The program has been compiled
And of course the outputs:
./P1; ./P1-Test
TEST not defined
TEST defined
Alternative
If your .o files are really .PRECIOUS, you might want to build separate copies. Here I split into release/main.o and test/main.o:
CXX = g++
CXXFLAGS = -std=c++11 -g -O3 -fopenmp
all: P1 P1-Test
#echo The program has been compiled
test/%.o: CXXFLAGS+=-DTEST
test/%.o: %.cpp
mkdir -pv $(#D)
$(CXX) $(CXXFLAGS) $? -c -o $#
release/%.o: %.cpp
mkdir -pv $(#D)
$(CXX) $(CXXFLAGS) $? -c -o $#
.PHONY: clean
clean:
$(RM) -rfv P1 P1-Test *.dSYM release/ test/
P1: release/main.o release/second.o
P1-Test: test/main.o test/second.o
P1 P1-Test:
$(CXX) $(CXXFLAGS) -o "$#" $^ $(LDFLAGS)
Which gives:
mkdir -pv release
g++ -std=c++11 -g -O3 -fopenmp main.cpp -c -o release/main.o
mkdir -pv release
g++ -std=c++11 -g -O3 -fopenmp second.cpp -c -o release/second.o
g++ -std=c++11 -g -O3 -fopenmp -o "P1" release/main.o release/second.o
mkdir -pv test
g++ -std=c++11 -g -O3 -fopenmp -DTEST main.cpp -c -o test/main.o
mkdir -pv test
g++ -std=c++11 -g -O3 -fopenmp -DTEST second.cpp -c -o test/second.o
g++ -std=c++11 -g -O3 -fopenmp -o "P1-Test" test/main.o test/second.o
echo The program has been compiled

Make does not generate debug symbols

I have a Makefile as :
CC = g++
#SNAP DEFINITIONS
SNAP = Snap-2.3
SNAPCORE = $(SNAP)/snap-core
GLIB = $(SNAP)/glib-core
CPPFLAGS += -I $(GLIB) -I $(SNAPCORE)
pagerank_debug.o: pagerank.cpp
$(CC) $(CPPFLAGS) -c pagerank.cpp -o pagerank_debug.o
pagerank.o: pagerank.cpp
$(CC) $(CPPFLAGS) -c pagerank.cpp
pr_debug: pagerank_debug.o $(SNAPCORE)/Snap.o
$(CC) -g pagerank_debug.o $(SNAPCORE)/Snap.o -o prd
pr: pagerank.o $(SNAPCORE)/Snap.o
$(CC) pagerank.o $(SNAPCORE)/Snap.o -o pr
.PHONY: clean
clean:
rm *.o prd
On executing make pr_debug, the code is compiled as :
g++ -I Snap-2.3/glib-core -I Snap-2.3/snap-core -c pagerank.cpp -o pagerank_debug.o
g++ -g pagerank_debug.o Snap-2.3/snap-core/Snap.o -o prd
I do not see any debug symbols. What could be a potential issue?
Updated Makefile( Still does not work )
#SNAP DEFINITIONS
SNAP = /Users/myth/Snap-2.3
SNAPCORE = $(SNAP)/snap-core
GLIB = $(SNAP)/glib-core
INCLUDE += -I $(SNAPCORE) -I $(GLIB)
CPPFLAGS += -c -g -Wall
pagerank_debug: pagerank_undirected.cpp
g++ $(INCLUDE) $(CPPFLAGS) pagerank_undirected.cpp -o pagerank_undirected.o
pr_debug: pagerank_debug
g++ -g pagerank_undirected.o $(SNAPCORE)/Snap.o -o pru
.PHONY: clean all
all: pr_debug
clean:
rm *.o pru
-g flag should be added when compiling, so add it to CPPFLAGS:
CPPFLAGS += -I $(GLIB) -I $(SNAPCORE) -g

OpenMP Makefile, -fopenmp won't work

I'm trying to compile my project using a Makefile, but somehow the -fopenmp flag won't work.
Here's the Makefile:
TARGET=isaac
CC=g++
CFLAGS=-Wall -O2 -fopenmp
LDFLAGS=-lm -lpthread -lrt
OBJ=src/main.o src/bhtree.o src/body.o src/configreader.o src/diagnostics.o src/output.o src/quad.o src/timing.o src/vector2.o
isaac: $(OBJ)
$(CC) $(CFLAGS) -o $(TARGET) $(OBJ) $(LDFLAGS)
%.o: src/%.cpp
$(CC) $(CFLAGS) -c $<
clean:
rm src/*.o src/*~ isaac
and here is the output when calling "make"
g++ -c -o src/main.o src/main.cpp
g++ -c -o src/bhtree.o src/bhtree.cpp
g++ -c -o src/body.o src/body.cpp
g++ -c -o src/configreader.o src/configreader.cpp
g++ -c -o src/diagnostics.o src/diagnostics.cpp
g++ -c -o src/output.o src/output.cpp
g++ -c -o src/quad.o src/quad.cpp
g++ -c -o src/timing.o src/timing.cpp
g++ -c -o src/vector2.o src/vector2.cpp
g++ -Wall -O2 -fopenmp -o isaac src/main.o src/bhtree.o src/body.o src/configreader.o src/diagnostics.o src/output.o src/quad.o src/timing.o src/vector2.o -lm -lpthread -lrt
the -fopenmp flag is missing when the source files are compiled, so the finished executable is serial, not parallel.
How can I fix this?
The problem is that your rule does not apply at all. You are free to remove
%.o: src/%.cpp
$(CC) $(CFLAGS) -c $<
and you'll get the same result as before. That's because some predefined rule is used instead of yours (I'm not great makefile expert though).
The core of the problem is that your rule is for ./*.o files, but you need ./src/*.o for isaac. You can change your rule
src/%.o: src/%.cpp
$(CC) $(CFLAGS) -c $<
Or (better) move all autogenerated staff somewhere from src.

Makefile for shared library that only compiles changed files?

I am working on a project where I am creating a .so object as my output that contains several operators for use in another program. I was given a Makefile that works just fine, except it always recompiles every file whenever I run make. Originally this was not an issue, but now that there are upwards of five or more operators in the library, running make is prohibitively slow. The trouble is that for the life of me, I can't figure out how to change this Makefile into one that behaves the way I want since I've never dealt with Makefiles in this format before:
BOOST_LOCATION=/usr/local/boost_1_54_0
CFLAGS=-pedantic -W -Wextra -Wall -Wno-strict-aliasing -Wno-long-long -Wno-unused-parameter -fPIC -D__STDC_FORMAT_MACROS -Wno-system-headers -isystem -O2 -g -DNDEBUG -ggdb3 -D__STDC_LIMIT_MACROS
INC=-I. -DPROJECT_ROOT="\"$(IN_SOURCE_DIR)\"" -I"$(IN_SOURCE_DIR)/include" -I"$(BOOST_LOCATION)"
LIBS=-L"$(IN_SOURCE_DIR)/lib" -shared -Wl,-soname,libname.so -L. -lm
all:
#if test ! -d "$(IN_SOURCE_DIR)"; then echo "Error. Try:\n\nmake IN_SOURCE_DIR=<PATH TO SOURCE TRUNK>"; exit 1; fi
$(CXX) $(CFLAGS) $(INC) -o plugin.cpp.o -c plugin.cpp
$(CXX) $(CFLAGS) $(INC) -o LogicalFile1.cpp.o -c File1/LogicalFile1.cpp
$(CXX) $(CFLAGS) $(INC) -o PhysicalFile1.cpp.o -c File1/PhysicalFile1.cpp
$(CXX) $(CFLAGS) $(INC) -o LogicalFile2.cpp.o -c File2/LogicalFile2.cpp
$(CXX) $(CFLAGS) $(INC) -o PhysicalFile2.cpp.o -c File2/PhysicalFile2.cpp
### etc.
$(CXX) $(CFLAGS) $(INC) -o libname.so \
plugin.cpp.o \
LogicalFile1.cpp.o \
PhysicalFile1.cpp.o \
LogicalFile2.cpp.o \
PhysicalFile2.cpp.o \
### etc \
$(LIBS)
clean:
rm -f *.o *.so
The biggest issue I have is that there is only one rule (all), and I cannot find an example of a Makefile that does this or how to split it into multiple rules.
In this case, it's actually pretty straightforward. Right now, you just have an all target that's doing all the building. You need to break out the compiler invocations and link step into their own rules, and you should be off to the races:
BOOST_LOCATION=/usr/local/boost_1_54_0
CFLAGS=-pedantic -W -Wextra -Wall -Wno-strict-aliasing -Wno-long-long -Wno-unused-parameter -fPIC -D__STDC_FORMAT_MACROS -Wno-system-headers -isystem -O2 -g -DNDEBUG -ggdb3 -D__STDC_LIMIT_MACROS
INC=-I. -DPROJECT_ROOT="\"$(IN_SOURCE_DIR)\"" -I"$(IN_SOURCE_DIR)/include" -I"$(BOOST_LOCATION)"
LIBS=-L"$(IN_SOURCE_DIR)/lib" -shared -Wl,-soname,libname.so -L. -lm
all: plugin.cpp.o LogicalFile1.cpp.o PhysicalFile1.cpp.o LogicalFile2.cpp.o PhysicalFile2.cpp.o
$(CXX) $(CFLAGS) $(INC) -o libname.so \
plugin.cpp.o \
LogicalFile1.cpp.o \
PhysicalFile1.cpp.o \
LogicalFile2.cpp.o \
PhysicalFile2.cpp.o \
### etc \
$(LIBS)
plugin.cpp.o: plugin.cpp | test
$(CXX) $(CFLAGS) $(INC) -o plugin.cpp.o -c plugin.cpp
LogicalFile1.cpp.o: File1/LogicalFile1.cpp | test
$(CXX) $(CFLAGS) $(INC) -o LogicalFile1.cpp.o -c File1/LogicalFile1.cpp
PhysicalFile1.cpp.o: File1/PhysicalFile1.cpp | test
$(CXX) $(CFLAGS) $(INC) -o PhysicalFile1.cpp.o -c File1/PhysicalFile1.cpp
LogicalFile2.cpp.o: File2/LogicalFile2.cpp | test
$(CXX) $(CFLAGS) $(INC) -o LogicalFile2.cpp.o -c File2/LogicalFile2.cpp
PhysicalFile2.cpp.o: File2/PhysicalFile2.cpp | test
$(CXX) $(CFLAGS) $(INC) -o PhysicalFile2.cpp.o -c File2/PhysicalFile2.cpp
test:
#if test ! -d "$(IN_SOURCE_DIR)"; then echo "Error. Try:\n\nmake IN_SOURCE_DIR=<PATH TO SOURCE TRUNK>"; exit 1; fi
clean:
rm -f *.o *.so
.PHONY: all clean test
From this point, you can simplify further, too. You could consolidate all of the compile lines into a single pattern rule, for example.
If you're willing to use the standard formats and built-in rules for make, you can write your entire makefile as easily as this:
ifeq (,$(wildcard $(IN_SOURCE_DIR)/.))
$(error Try: make IN_SOURCE_DIR=<PATH TO SOURCE TRUNK>)
endif
OBJECTS = plugin.o LogicalFile1.o PhysicalFile1.o LogicalFile2.o PhysicalFile2.o ### etc
BOOST_LOCATION = /usr/local/boost_1_54_0
CPPFLAGS = -DNDEBUG -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I. -DPROJECT_ROOT="\"$(IN_SOURCE_DIR)\"" -I"$(IN_SOURCE_DIR)/include" -I"$(BOOST_LOCATION)"
CXXFLAGS = -pedantic -W -Wextra -Wall -Wno-strict-aliasing -Wno-long-long -Wno-unused-parameter -fPIC -Wno-system-headers -isystem -O2 -g -ggdb3
LDFLAGS = -L"$(IN_SOURCE_DIR)/lib" -L.
LDLIBS = -shared -Wl,-soname,libname.so -lm
all: libname.so
libname.so: $(OBJECTS)
$(LINK.cc) $^ $(LDLIBS) -o $#
clean:
rm -f *.o *.so
.PHONY: all clean

makefile to compile multiple sources, with different flags

I have the following makefile:
CC = gcc
SRC = source1.c
EXE = source1
FLAGS = -fopenmp
all: $(src)
$(CC) -o $(EXE) $(SRC) $(FLAGS)
clean:
rm $(EXE)
How can I modify it so I can use multiple sources, some of them compiled with the flag -fopenmp, some of them compiled without. Thanks a lot.
This should get you started: Note how -fopenmp gets added just for source2.c
CC=gcc
SRC=source1.c source2.c
OBJ=$(patsubst %.c,%.o,$(SRC))
EXE=source1
FLAGS= -g -O2
source2.o: FLAGS+=-fopenmp
all: $(EXE)
$(EXE): $(OBJ)
$(CC) -o $# $^ $(FLAGS)
%.o: %.c
$(CC) -c -o $# $^ $(FLAGS)
clean:
rm $(EXE)$
Output of make -Bsn:
gcc -o source1.o source1.c -g -O2
gcc -o source2.o source2.c -g -O2 -fopenmp
gcc -o source1 source1.o source2.o -g -O2
You can define for example, EXTFLAGS=$(FLAGS) -fopenmp, and use EXTFLAGS for some rules.