C++ Makefile. .o in different subdirectories - c++

I have some problems trying to put .o files into a separate directory (/build).
Actually, my sources (in /src) contain some subdirectories, and my Makefile only create the .o of the .cpp contained at the first "level". The other .o are just ignored, so, the target cannot be created.
In my /src directory, I have "three levels" (src/first/second/).
Here's the code of the Makefile :
CC=g++
CFLAGS=-W -Wall -ansi -pedantic -s -O3 -Os -std=c++11 -fpermissive
LDFLAGS= -lboost_system -lboost_regex
SRCDIR=src
HEADDIR=include
LIBDIR=build
BINDIR=bin
BIN=LTN
SRC = $(wildcard src/*.cpp src/*/*.cpp src/*/*/*.cpp)
OBJ = $(patsubst %.cpp,$(LIBDIR)/%.o,$(SRC))
all: $(BIN)
LTN: $(OBJ)
$(CC) -o $(BINDIR)/$# $^ $(LDFLAGS)
$(LIBDIR)/$(SRCDIR)/%.o: $(SRCDIR)/%.cpp $(HEADDIR)/%.h
$(CC) -o $# -c $< $(CFLAGS)
.PHONY = clean

You can try this:
CC=g++
CFLAGS=-W -Wall -ansi -pedantic -s -O3 -Os -std=c++11 -fpermissive
LDFLAGS= -lboost_system -lboost_regex
SRCDIR=src
HEADDIR=include
LIBDIR=build
BINDIR=bin
BIN=LTN
SRC=$(shell find . -name '*.cpp')
TMP=$(subst $(SRCDIR),$(LIBDIR), $(SRC))
OBJ=$(patsubst %.cpp,%.o,$(TMP))
all: $(BIN)
LTN: $(OBJ)
#[ ! -d $(BINDIR) ] & mkdir -p $(BINDIR)
$(CC) -o $(BINDIR)/$# $^ $(LDFLAGS)
$(LIBDIR)/%.o: $(SRCDIR)/%.cpp
#[ ! -d $(dir $#) ] & mkdir -p $(dir $#)
$(CC) -o $# -c $< $(CFLAGS)
.PHONY = clean

Related

Im working on a makefile which should build a library and then also include that library when building the entire program

INC_DIR = ./include
SRC_DIR = ./src
OBJ_DIR = ./obj
SRC_FILES = $(wildcard $(SRC_DIR)/*.cpp))
H_FILES = $(wildcard $(INC_DIR)/*.cpp)
OBJ_FILES=$(patsubst $(SRC_DIR)/%.cc,$(OBJ_DIR)/%.o,$(SRC_FILES)
TARGET = PT3
CC = g++
CFLAGS = - fPIC -c -Wall -Werror -pedantic -std=c++11 -Wno-c++11-extensions
CPPFLAGS = $(addprefix -I, $(INC_DIR))
clean:
rm -f $(OBJECTS) $(TARGET)
all: $(TARGET)
$(TARGET): $(OBJECTS)
$(CC) $(CFLAGS) $(CPPFLAGS) -o $# $^
%.o: %.cc
$(CC) $(CFLAGS) $(CPPFLAGS) -o $# -c $<
g++ -shared -fPIC -o libtest.so $(OBJECTS)
main.o: main.cc
$(CC) $(CFLAGS) $(CPPFLAGS) -L/pt3/lib -o maintest main.cc -libtest
this is currently what I have and i know its not syntactically right or remotely working but Im getting stuck on creating the shared library so I dont even know what else wouldnt compile.**
INC_DIR = ./include
SRC_DIR = ./src
SRC_FILES = $(sort $(shell find $(SRC_DIR) -name '*.cc'))
OBJ_FILES = $(SRC_FILES:.cc=.o)
TARGET = PT3
CC = g++
CFLAGS = -fPIC -Wall -Werror -pedantic -std=c++11 -Wno-c++11-extensions
CPPFLAGS = $(addprefix -I, $(INC_DIR))
#clean:
# rm -f $(OBJECTS) $(TARGET)
all: $(TARGET)
$(TARGET): $(OBJ_FILES)
$(CC) $(CFLAGS) $(CPPFLAGS) -o $# $^
%.o: %.cc
$(CC) $(CFLAGS) $(CPPFLAGS) -o $# -c $<
libtest.so: $(OBJ_FILES)
$(CC) -shared -fPIC -o $# $^
maintest: main.o libtest.so
$(CC) $(CFLAGS) $(CPPFLAGS) -L. -o maintest main.o -libtest
this is what i rewrote the code to however Im getting a no input files error, but Im not sure if thats coming from a wrong read / failure to get into the required folders, or due to possibly missing a -o or -c?
Ive worked on the code some more following the suggestions and have come to this:
CXX = g++
CXXFLAGS := -Wall -Werror -pedantic -std=c++11 -Wno-c++11-extensions
SRC_FILES = $(wildcard $(SRC_DIR)/*.cpp)
OBJECTS=$(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(SRC_FILES))
INC_DIR = include
SRC_DIR = src
OBJ_DIR = obj
TEST_DIR = tests
LIB_DIR = lib
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
$(CXX) $(CXXFLAGS) -fPIC -Iinclude -o $# -c $<
clean:
rm -f $(OBJECTS) $(TEST_DIR)/main.o
$(LIB_DIR)/libtest.so: $(OBJECTS)
#echo frank
$(CXX) -shared -fPIC -o $# $^
$(TEST_DIR)/main.o: $(TEST_DIR)/main.cc
$(CXX) $(CXXFLAGS) -Iinclude -o $# -c $<
maintest: $(TEST_DIR)/main.o $(LIB_DIR)/libtest.so
$(CXX) $(CXXFLAGS) -Llib -Iinclude -o $# $< -ltest
everything seems to compile fine however when running the maintest program it returns an error saying: error while loading shared libraries: libtest.so: cannot open shared object file: No such file or directory
thanks for the suggestions so far I feel like Im on the verge of actually getting the makefile working as intended
You've already written the recipe for the library (which builds it in the working directory -- we can change that later if you want):
g++ -shared -fPIC -o libtest.so $(OBJECTS)
The next step is to put it into a rule:
libtest.so: $(OBJECTS)
g++ -shared -fPIC -o libtest.so $(OBJECTS)
Then clean it up:
libtest.so: $(OBJECTS)
g++ -shared -fPIC -o $# $^
It looks as if you want the executable to be maintest, so let's write a rule for that:
maintest: main.o libtest.so
$(CC) $(CFLAGS) $(CPPFLAGS) -L. -o maintest main.o -ltest
Give that a try. We can make further adjustments once that much works.
EDIT: I see that there are a few other problems in your makefile. Your variables won't work as written. Do you name your source files "foo.cc" or "foo.cpp"?
EDIT: I can see that we'll have to do this in stages.
Step 1. Try this:
CXX = g++
CXXFLAGS := -Wall -Werror -pedantic -std=c++11 -Wno-c++11-extensions
INC_DIR = include
SRC_DIR = src
OBJ_DIR = obj
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
$(CXX) $(CXXFLAGS) -Iinclude -o $# -c $<
Try to build one or two object files with this, as in make obj/foo.o.
Step 2. Add a rule for main.o, and test it:
$(OBJ_DIR)/main.o: main.cc
$(CXX) $(CXXFLAGS) -Iinclude -o $# -c $<
Step 3. Add a "do nothing" rule for the library, and verify that it builds all of the objects:
SRC_FILES = $(wildcard $(SRC_DIR)/*.cpp)
OBJECTS=$(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(SRC_FILES))
libtest.so: $(OBJECTS)
#echo doing nothing
Step 4. Change the library rule to actually build the library:
libtest.so: $(OBJECTS)
$(CXX) -shared -fPIC -o $# $^
Step 5. Add a rule to build the test:
maintest: main.o libtest.so
$(CXX) $(CXXFLAGS) -L. -o $# $< -ltest

linux C++ gmake "No rule to make target"

It's been a couple decades since I've had to manage makefiles. I've checked existing answers here, as well as googling elsewhere. When I use the target: $(BIN)/$(EXECUTABLE): $(OBJECTS)
I'm stumped as to why my makefile is failing with:
$ make
make: *** No rule to make target 'src/SRecord.o', needed by 'bin/main'. Stop.
Here's the Makefile:
# execute `make D='-g'` to make with debug symbols
DEFS := $(D)
CC := gcc $(DEFS)
CFLAGS := -std=c99 -Wall -Wextra
CXX := g++ $(DEFS)
CXXFLAGS := -std=c++17 -Wall -Wextra
BIN := bin
SRC := src
INCLUDE := include
LIB := lib
#LIBSOURCES := $(wildcard $(LIB)/*.cpp)
#LIBOBJECTS := $(LIBSOURCES:%.cpp=%.o)
#OBJECTS := $(subst $(LIB)/,,$(LIBOBJECTS))
SOURCES := $(wildcard $(SRC)/*.cpp)
OBJECTS := $(SOURCES:%.cpp=%.o)
# SOURCES := \
# $(SRC)/main.cpp \
# $(SRC)/SerialPort.cpp \
# $(SRC)/ShadowUpdate.cpp \
# $(SRC)/SRecord.cpp
# OBJECTS := \
# $(SRC)/SerialPort.o \
# $(SRC)/ShadowUpdate.o \
# $(SRC)/SRecord.o
EXECUTABLE := main
#
# Targets
#
.PHONY: clean all
all: $(BIN)/$(EXECUTABLE)
clean:
$(RM) $(BIN)/$(EXECUTABLE)
$(RM) $(OBJECTS)
run: all
./$(BIN)/$(EXECUTABLE)
# $(BIN)/$(EXECUTABLE): $(SRC)/*
$(BIN)/$(EXECUTABLE): $(OBJECTS)
$(CXX) $(CXXFLAGS) -I$(INCLUDE) -L$(LIB) $^ -o $#
#
# Dependencies - must be at end of makefile
#
DEPDIR := .d
$(shell mkdir -p $(DEPDIR) >/dev/null)
DEPFLAGS = -MT $# -MMD -MP -MF $(DEPDIR)/$*.Td
POSTCOMPILE = #mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d && touch $#
%.o: %.c
%.o: %.c $(DEPDIR)/%.d
$(CC) -c -o $*.o $(DEPFLAGS) $(CFLAGS) $<
$(POSTCOMPILE)
%.o: %.cpp
%.o: %.cpp $(DEPDIR)/%.d
$(CXX) -c -o $*.o $(DEPFLAGS) $(CXXFLAGS) $<
$(POSTCOMPILE)
$(DEPDIR)/%.d: ;
.PRECIOUS: $(DEPDIR)/%.d
include $(wildcard $(patsubst %,$(DEPDIR)/%.d,$(basename $(SOURCES))))
It works with the commented out target: # $(BIN)/$(EXECUTABLE): $(SRC)/*
But, I want to be able to have a more complex project than simply listing all the source files as dependencies to the executable.
Here's my file tree:
src/
src/SerialPort.cpp
src/SRecord.cpp
src/ShadowUpdate.cpp
src/main.cpp
include
include/ShadowUpdate.h
include/SerialPort.h
include/SRecord.h
include/the_exo.h
bin/
bin/main
Makefile
lib/
.d/
The automatic dependency generation isn't working either, even though it is straight from GNU's website.
Think about what the % expands to in
%.o: %.cpp $(DEPDIR)/%.d
plugging in src/SRecord.o:
src/SRecord.o: src/SRecord.cpp .d/src/SRecord.d
Can you see the issue? Try the following instead
$(SRC)/%.o: $(SRC)/%.cpp $(SRC)/$(DEPDIR)/%.d
You won't need the lines that override the built-in recipes (%.o: %.cpp), get rid of them.
For clarity to anyone looking for the answer in the future, I'm posting my revised Makefile:
BIN := bin
SRC := src
INCLUDE := include
LIB := lib
# execute `make D='-g'` to make with debug symbols
DEFS := $(D)
CC := gcc $(DEFS)
CFLAGS := -I$(INCLUDE) -std=c99 -Wall -Wextra
CXX := g++ $(DEFS)
CXXFLAGS := -I$(INCLUDE) -std=c++17 -Wall -Wextra
#LIBSOURCES := $(wildcard $(LIB)/*.cpp)
#LIBOBJECTS := $(LIBSOURCES:%.cpp=%.o)
#OBJECTS := $(subst $(LIB)/,,$(LIBOBJECTS))
SOURCES := $(wildcard $(SRC)/*.cpp)
OBJECTS := $(SOURCES:%.cpp=%.o)
EXECUTABLE := main
#
# Targets
#
.PHONY: clean all
all: $(BIN)/$(EXECUTABLE)
clean:
$(RM) $(BIN)/$(EXECUTABLE)
$(RM) $(OBJECTS)
run: all
./$(BIN)/$(EXECUTABLE)
$(BIN)/$(EXECUTABLE): $(OBJECTS)
$(CXX) $(CXXFLAGS) -L$(LIB) $^ -o $#
#
# Dependencies - must be at end of makefile
#
DEPDIR := $(SRC)/.d
$(shell mkdir -p $(DEPDIR) >/dev/null)
DEPFLAGS = -MT $# -MMD -MP -MF $(DEPDIR)/$*.Td
POSTCOMPILE = #mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d && touch $#
%.o: %.c
%.o: %.c $(DEPDIR)/%.d
$(CC) -c -o $# $(DEPFLAGS) $(CFLAGS) $<
$(POSTCOMPILE)
%.o: %.cpp
$(SRC)/%.o: $(SRC)/%.cpp $(DEPDIR)/%.d
$(CXX) -c -o $# $(DEPFLAGS) $(CXXFLAGS) $<
$(POSTCOMPILE)
$(DEPDIR)/%.d: ;
.PRECIOUS: $(DEPDIR)/%.d
include $(wildcard $(patsubst %,$(DEPDIR)/%.d,$(basename $(SOURCES))))
To clarify my comment to the above answer, if I comment out the "override" target (%.o: %.cpp), here's the output:
$ make clean; make
rm -f bin/main
rm -f src/SRecord.o src/SerialPort.o src/ShadowUpdate.o src/main.o
g++ -Iinclude -std=c++17 -Wall -Wextra -c -o src/SRecord.o src/SRecord.cpp
g++ -Iinclude -std=c++17 -Wall -Wextra -c -o src/SerialPort.o src/SerialPort.cpp
g++ -Iinclude -std=c++17 -Wall -Wextra -c -o src/ShadowUpdate.o src/ShadowUpdate.cpp
g++ -Iinclude -std=c++17 -Wall -Wextra -c -o src/main.o src/main.cpp
g++ -Iinclude -std=c++17 -Wall -Wextra -Llib src/SRecord.o src/SerialPort.o src/ShadowUpdate.o src/main.o -o bin/main
Clearly, the dependencies are not being made. My rule was not executed.
But, with the empty %.o: %.cpp target in place, the make performs as expected:
$ make clean; make
rm -f bin/main
rm -f src/SRecord.o src/SerialPort.o src/ShadowUpdate.o src/main.o
g++ -c -o src/SRecord.o -MT src/SRecord.o -MMD -MP -MF src/.d/SRecord.Td -Iinclude -std=c++17 -Wall -Wextra src/SRecord.cpp
g++ -c -o src/SerialPort.o -MT src/SerialPort.o -MMD -MP -MF src/.d/SerialPort.Td -Iinclude -std=c++17 -Wall -Wextra src/SerialPort.cpp
g++ -c -o src/ShadowUpdate.o -MT src/ShadowUpdate.o -MMD -MP -MF src/.d/ShadowUpdate.Td -Iinclude -std=c++17 -Wall -Wextra src/ShadowUpdate.cpp
g++ -c -o src/main.o -MT src/main.o -MMD -MP -MF src/.d/main.Td -Iinclude -std=c++17 -Wall -Wextra src/main.cpp
g++ -Iinclude -std=c++17 -Wall -Wextra -Llib src/SRecord.o src/SerialPort.o src/ShadowUpdate.o src/main.o -o bin/main

C++ Makefile missing separator in .dep

On OS X Mavericks i am trying to build a project using the following Makefile:
CC=g++
EXECUTABLE=minigi
SRC_DIR=src
INTERM_DIR=obj
INCLUDES=-I $(SRC_DIR) -I /usr/local/Cg/examples/OpenGL/glew/include/
LIBS=-L/usr/local/lang/NVIDIA_GPU_Computing_SDK/sdk/C/common/lib/linux/ -lpng -stdc++ -lGL -lGLU -lGLEW -lSDLmain -lSDL -lgomp
CFLAGS_COMMON=$(INCLUDES)
CFLAGS=$(CFLAGS_COMMON) -O3 -DNDEBUG -fopenmp
#CFLAGS=$(CFLAGS_COMMON) -g -O0 -D_DEBUG
SOURCE_FILES=$(shell find $(SRC_DIR) -iname '*.cpp')
DEP_FILES=$(SOURCE_FILES:$(SRC_DIR)/%.cpp=./$(INTERM_DIR)/%.dep)
OBJ_FILES=$(SOURCE_FILES:$(SRC_DIR)/%.cpp=./$(INTERM_DIR)/%.o)
all: $(EXECUTABLE)
clean:
rm -rf obj $(EXECUTABLE)
.PHONY: clean all
.SUFFIXES:
.SUFFIXES:.o .dep .cpp .h
$(INTERM_DIR)/%.dep: $(SRC_DIR)/%.cpp
mkdir -p `dirname $#`
printf `dirname $#`/ > $#
$(CC) $(CFLAGS_COMMON) $< -MM | sed -r -e 's,^(.*)\.o\s*\:,\1.o $# :,g' >> $#
ifneq ($(MAKECMDGOALS),clean)
-include $(DEP_FILES)
endif
$(INTERM_DIR)/%.o: $(SRC_DIR)/%.cpp
mkdir -p $(INTERM_DIR)
$(CC) $(CFLAGS) -c $< -o $#
$(EXECUTABLE): $(OBJ_FILES)
$(CC) $^ $(LIBS) -o $#
However, when I type make I get the following error:
obj/app/sdl_gl_appliacation.dep:1: *** missing separator. Stop.
The file obj/app/sdl_gl_application.dep looks as follows:
-n obj/app/
As I know very little about makefiles (and did not write the posted one) every help would be appreciated.
P.S.
I modified the line printf dirname $#/ > $# . In the original file there was an echo -n but that is not working on OS X.
Well, let's clean this up a little bit.
The way the dependencies are handled really is ugly, GCC can do it for you automatically.
EXECUTABLE := minigi
SRC_DIR := src
OBJ_DIR := obj
SRC_FILES := $(wildcard $(SRC_DIR)/*.cpp)
OBJ_FILES := $(SRC_FILES:$(SRC_DIR)/%.cpp=$(OBJ_DIR)/%.o)
DEP_FILES := $(OBJ_FILES:.o=.d)
LDLIBS := -lpng -lstdc++ -lGL -lGLU -lGLEW -lSDLmain -lSDL -lgomp
LDFLAGS := -L/usr/local/lang/NVIDIA_GPU_Computing_SDK/sdk/C/common/lib/linux/
CPPFLAGS := -MMD -MP -DNDEBUG -fopenmp -I $(SRC_DIR) -I /usr/local/Cg/examples/OpenGL/glew/include/
CXXFLAGS := -O3
.PHONY: all clean
all: $(EXECUTABLE)
clean:
$(RM) -r $(OBJ_DIR) $(EXECUTABLE)
$(EXECUTABLE): $(OBJ_FILES)
$(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $#
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp | $(OBJ_DIR)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $# -c $<
$(OBJ_DIR):
mkdir $#
ifeq "$(MAKECMDGOALS)" ""
-include $(DEP_FILES)
endif
Some quick notes :
You're using C++, so you should use $(CXX) instead of $(CC) which is used for C code.
Along with this, you should use $(CXXFLAGS) instead of $(CFLAGS).
$(CPPFLAGS) is meant for preprocessor flags (-I, -D, or -fopenmp which is a compile-time flag).
-MMD -MP preprocessor flags will auto-generate dependency files when compiling. Learn more.
$(LDFLAGS) is meant for linker flags such as -L flags.
$(LDLIBS) is meant for linker libs such as -l flags
Avoid using the $(shell ) function since it will be executed every time the variable is expanded when assigned with the = operator instead of the := operator. $(wildcard ) is more suited for the job of listing files.

gnu make. recompile unchanged files only

Help me with makefile, please. I want `make' to recompile only files that have been changed. Here is my makefile:
ROOT_DIR= ..
BUILD_TYPE= Release
BUILD_DIR= $(ROOT_DIR)/$(BUILD_TYPE)
O_DIR= $(BUILD_DIR)/obj
TARGETS= ftp_auto_backup sftp_auto_backup
CXX= g++
CXXFLAGS= -DBOOST_THREAD_USE_LIB -O3 -Wall -fmessage-length=0
FTP_LDFLAGS= -static-libstdc++ -static-libgcc -s -L $(ROOT_DIR)/lib/Release -l:libboost_thread-mgw46-mt-1_49.a -l:libcommon.a \
-l:libfile.a -l:libfilesearcher.a -l:libftpclient.a -l:libftplib.a -l:libdbclient.a -l:libsqlite3.a -l:libscheduler.a -l:libws2_32.a
SFTP_LDFLAGS= -static-libstdc++ -static-libgcc -s -L $(ROOT_DIR)/lib/Release -l:libboost_thread-mgw46-mt-1_49.a -l:libcommon.a \
-l:libfile.a -l:libfilesearcher.a -l:libdbclient.a -l:libsqlite3.a -l:libscheduler.a -l:libsftpclient.a -l:libws2_32.a -l:libssh.dll
OBJECTS= appconfig.o backuplauncher.o clientbackup.o main.o
LD_OBJECTS= $(addprefix $(O_DIR)/,$(OBJECTS))
all: init $(TARGETS)
debug: CXXFLAGS= -O0 -g3 -Wall -fmessage-length=0
debug: BUILD_TYPE= Debug
debug: all
init:
#mkdir -p $(BUILD_DIR)
#mkdir -p $(O_DIR)
ftp_auto_backup: set_type_ftp $(OBJECTS)
$(CXX) -o $(BUILD_DIR)/$#.exe $(LD_OBJECTS) $(FTP_LDFLAGS)
sftp_auto_backup: set_type_sftp $(OBJECTS)
$(CXX) -o $(BUILD_DIR)/$#.exe $(LD_OBJECTS) $(SFTP_LDFLAGS)
set_type_ftp:
$(eval CXXFLAGS+=-DPROJECT_TYPE=FTP)
set_type_sftp:
$(eval CXXFLAGS+=-DPROJECT_TYPE=SFTP)
%.o: %.cpp
$(CXX) -c $(CXXFLAGS) $< -o $(O_DIR)/$#
clean:
rm -rf $(addprefix $(ROOT_DIR)/Release/obj/,$(OBJECTS)) $(addprefix $(ROOT_DIR)/Debug/obj/,$(OBJECTS))
rm -rf $(addprefix $(ROOT_DIR)/Release/,$(addsuffix .exe,$(TARGETS))) $(addprefix $(ROOT_DIR)/Debug/,$(addsuffix .exe,$(TARGETS)))
Yes, I know about Generating Prerequisites Automatically, but should I really use it?
Thanks in advance!
Your targets depend on objects in the current directory, not in obj/. Change to this:
ftp_auto_backup: set_type_ftp $(LD_OBJECTS)
$(CXX) -o $(BUILD_DIR)/$#.exe $(LD_OBJECTS) $(FTP_LDFLAGS)
sftp_auto_backup: set_type_sftp $(LD_OBJECTS)
$(CXX) -o $(BUILD_DIR)/$#.exe $(LD_OBJECTS) $(SFTP_LDFLAGS)
# (...)
$(O_DIR)/%.o: %.cpp
$(CXX) -c $(CXXFLAGS) $< -o $#
And yes, if you want your object files to recompile not only when you change the .cpp file, but also when you change the header (.h) files, you need to generate those prerequisites...
I suppose that %.o : %.cpp is not enough, you should use VPATH to let know make where the sources are:
vpath %.cpp src

creating a makefile for multiple targets

i have created a Makefile which i would change so, that it will generate more then one target when i run make.
In my program i use self predefined macros (e.g. TIME, REG and _DEBUG ) and i would like to have my Makefile i that way that it will generate one target with out predefined macros, one with REG and another one with REG and TIME.
I hope that what i wish is a reasonable wish from Makefile, if not, then please let me know.
P.S.:
recommendations would be gladly excepted
I am using
Here is my Makefile:
CXX = g++
SOURCES = random.cpp
OBJECTS = $(SOURCES:.cpp=.o)
EXECUTABLE = random-64bit
DEBUG = -g -p -ggdb
CXXFLAGS = -Wall -ansi -pedantic -W -pipe -O3 -std=gnu++0x -march=native \
--fast-math -ftree-vectorize -ffast-math -D NDEBUG \
-D TIME -D REG -D _DEBUG
#CXXFLAGS+=$(DEBUG)
DEPS = def_type.hpp \
ls_regression.hpp \
network.hpp \
statistics.hpp \
knot.hpp \
nachbarn.hpp \
$(SOURCES:.cpp=.hpp) \
zufallszahlengenerator.hpp
INCLUDES = -I/home/phymihsa/eigen/ -I/home/phymihsa/boost_1_48_0
LIBPATH = -L/usr/local/lib64
LDFLAGS = -lm
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS) $(DEPS)
$(CXX) $(LIBPATH) $(OBJECTS) -o $#
.cpp.o: $<
$(CXX) $(LIBPATH) $(INCLUDES) $(LDFLAGS) $(CXXFLAGS) -c $<
%.o: %.cpp
$(CXX) $(LIBPATH) $(INCLUDES) $(LDFLAGS) $(CXXFLAGS) -c $<
.PHONY: clean
clean:
rm -rf $(OBJECTS) $(EXECUTABLE) *~ p1 *.o
EDIT
Based on the answer of #trojanfoe, i would to know if it is possible to use arrays
OBJECTS = $(SOURCES:.cpp=_none.o) $(SOURCES:.cpp=_reg.o) $(SOURCES:.cpp=_reg_time.o)
EXECUTABLE = $(SOURCES:.cpp=_none) $(SOURCES:.cpp=_reg) $(SOURCES:.cpp=_reg_time)
instead of each one writing each one specific?
Here is what i was searching for:
CXX = g++
OPTIONS := none reg reg_inter reg_time
none_CXXFLAGS :=
reg_CXXFLAGS := -D REG
reg_inter_CXXFLAGS := $(reg_CXXFLAGS) -D INTERMEDIATE_STEP
reg_time_CXXFLAGS := $(reg_CXXFLAGS) -D TIME
EXECUTABLES = $(addprefix random_,$(OPTIONS))
DEBUG = -g3 -p -ggdb
CXXFLAGS = -Wall -ansi -pedantic -W -pipe -O3 -std=gnu++0x -march=core2 -mtune=core2 \
--fast-math -ftree-vectorize -ffast-math -D NDEBUG
CXXFLAGS+=$(DEBUG)
DEPS = def_type.hpp \
ls_regression.hpp \
network.hpp \
statistics.hpp \
knot.hpp \
nachbarn.hpp \
zufallszahlengenerator.hpp
INCFLAGS = -I/usr/include/eigen3 -I/usr/include/boost_1_48
LIBPATH = -L/usr/lib64
LDFLAGS = -lm
.PHONY: all
all: $(EXECUTABLES)
random_%: random_%.o
$(CXX) $(LDFLAGS) $(LIBPATH) $^ -o $#
random_%.o : random.cpp $(DEPS)
$(CXX) $(INCFLAGS) $(CXXFLAGS) $($*_CXXFLAGS) -c $< -o $#
.PHONY: clean
clean:
rm -rf $(OBJECTS) $(EXECUTABLES) *~ p1 *.o
in this solution there is a use of variables instead of writing each time the all text
regards
You'll need to generate 3 different versions of the object file from random.cpp and 3 different executables. Note $(CXXFLAGS) contains flags common across all 3 targets and I've also moved $(DEPS) to be a dependency of the object files, not the executable.
CXX = g++
SOURCES = random.cpp
OBJECTS = $(SOURCES:.cpp=.o)
EXECUTABLE = random-64bit
DEBUG = -g -p -ggdb
CXXFLAGS = -Wall -ansi -pedantic -W -pipe -O3 -std=gnu++0x -march=native \
--fast-math -ftree-vectorize -ffast-math -D NDEBUG -D _DEBUG
#CXXFLAGS+=$(DEBUG)
DEPS = def_type.hpp \
ls_regression.hpp \
network.hpp \
statistics.hpp \
knot.hpp \
nachbarn.hpp \
$(SOURCES:.cpp=.hpp) \
zufallszahlengenerator.hpp
INCLUDES = -I/home/phymihsa/eigen/ -I/home/phymihsa/boost_1_48_0
LIBPATH = -L/usr/local/lib64
LDFLAGS = -lm
all: random_none random_reg random_reg_time
random_none: random_none.o
$(CXX) $(LDFLAGS) $(LIBPATH) random_none.o -o $#
random_reg: random_reg.o
$(CXX) $(LDFLAGS) $(LIBPATH) random_reg.o -o $#
random_reg_time: random_reg_time.o
$(CXX) $(LDFLAGS) $(LIBPATH) random_reg_time.o -o $#
random_none.o: random.cpp $(DEPS)
$(CXX) $(INCLUDES) $(CXXFLAGS) -c $<
random_reg.o: random.cpp $(DEPS)
$(CXX) $(INCLUDES) $(CXXFLAGS) -D REG -c $<
random_reg_time.o: random.cpp $(DEPS)
$(CXX) $(INCLUDES) $(CXXFLAGS) -D REG -D TIME -c $<
.PHONY: clean
clean:
rm -rf *.o random_none random_reg random_reg_time *~ p1
For each file, create one target per compile flag variant.
Say you have a program that depends on two files, foo.cc and bar.cc. You want to compile a debug and a release version. You'll do something like this:
DEBUG = -g -Wall -D DEBUG
RELEASE = ...
foo_debug.o: foo.cc
g++ -o foo_debug.o -c foo.cc $(DEBUG)
foo_release.o: foo.cc
g++ -o foo_release.o -c foo.cc $(RELEASE)
# Same thing for bar ...
main_debug: foo_debug.o bar_debug.o
g++ -o main_debug foo_debug.o bar_debug.o
main_release: foo_release.o bar_release.o
g++ -o main_release foo_release.o bar_release.o