My application has Casablanca usage for REST communication iam using it for first time . if i use simple line as below to compile no issues.
g++ -std=c++11 main.cpp x1.cpp x3.cpp x2.cpp -o myfile -lboost_system -lcrypto -lssl -lcpprest
but i tried to write a makefile(i am writing it for first time) for the above as below:
CXX := g++
CXXFLAGS := -std=c++11
LDFLAGS := -L/usr/lib/x86_64-linux-gnu/ -lboost_system -lcrypto -lssl -lcpprest
BUILD := build
OBJ_DIR := $(BUILD)/objects
APP_DIR := $(BUILD)/apps
TARGET := fdvdapp
INCLUDE := -Iinclude/
SRC := $(wildcard *.cpp)
OBJECTS := $(SRC:%.cpp=$(OBJ_DIR)/%.o)
all: build $(TARGET)
$(OBJ_DIR)/%.o: %.cpp
#mkdir -p $(#D)
$(CXX) $(CXXFLAGS) $(INCLUDE) -o $# -c $<
$(TARGET): $(OBJECTS)
#mkdir -p $(#D)
$(CXX) $(CXXFLAGS) $(INCLUDE) $(LDFLAGS) -o $(APP_DIR)/$(TARGET) $(OBJECTS)
.PHONY: all build clean
build:
#mkdir -p $(APP_DIR)
#mkdir -p $(OBJ_DIR)
clean:
rm -rf build/*
the above make dosent seem to work i get errors undefined reference errors for all the libraries used.
what is wrong???
Related
INCDIR=include
SRCDIR=src
SRC = $(wildcard $(SRCDIR)/*.cpp)
DEPS = $(wildcard $(INCDIR)/*.h)
OBJ = $(SRC:.cpp=.o)
CFLAGS = -I$(INCDIR) -Wall -Weffc++ -Wextra -Wsign-conversion
CC=g++
preprocessor: $(OBJ)
$(CC) $(OBJ) -o $# $(CFLAGS)
$(SRCDIR)/%.o: $(SRCDIR)/%.cpp
$(CC) -c $(CFLAGS) $^ -o $#
clean:
rm $(SRCDIR)/*.o preprocessor
This is my current makefile, if I wanted to store my .o files in a sepparate directory, src/obj for example, how would I have to modify it?
Many ways to do it, but according to your own code, you could do:
INCDIR=include
SRCDIR=src
OBJDIR=obj
SRC= $(wildcard $(SRCDIR)/*.cpp)
DEPS= $(wildcard $(INCDIR)/*.h)
OBJ=$(patsubst %.cpp, $(OBJDIR)/%.o, $(notdir $(SRC)))
CFLAGS= -I$(INCDIR) -Wall -Weffc++ -Wextra -Wsign-conversion
CC=g++
$(OBJDIR):
#if ! [ -d $(#) ]; then\
echo "==> creating dir: $(#)";\
mkdir $(#);\
fi
preprocessor: $(OBJDIR) $(OBJ)
$(CC) $(OBJ) -o $# $(CFLAGS)
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
$(CC) -c $(CFLAGS) $^ -o $#
clean:
rm $(OBJDIR)/*.o preprocessor
printobj: $(OBJDIR)
#echo "$(OBJ)"
will output:
$ gmake preprocessor
g++ -c -Iinclude -Wall -Weffc++ -Wextra -Wsign-conversion src/a.cpp -o obj/a.o
g++ -c -Iinclude -Wall -Weffc++ -Wextra -Wsign-conversion src/b.cpp -o obj/b.o
g++ obj/a.o obj/b.o -o preprocessor -Iinclude -Wall -Weffc++ -Wextra -Wsign-conversion
NOTE: the target printobj is just here to output what you could expect, the target $(OBJDIR) ensure your directory exist before creating object files.
The are just a few things to change:
INCDIR := include
SRCDIR := src
OBJDIR := $(SRCDIR)/obj
SRC := $(wildcard $(SRCDIR)/*.cpp)
DEPS := $(wildcard $(INCDIR)/*.h)
OBJ := $(patsubst $(SRCDIR)/%.cpp,$(OBJDIR)/%.o,$(SRC))
CFLAGS := -I$(INCDIR) -Wall -Weffc++ -Wextra -Wsign-conversion
CC := g++
preprocessor: $(OBJ)
$(CC) $^ -o $# $(CFLAGS)
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp | $(OBJDIR)
$(CC) -c $(CFLAGS) $< -o $#
$(OBJDIR):
mkdir -p "$#"
clean:
rm -f $(OBJ) preprocessor
Note some other minor modifications:
the | $(OBJDIR) order-only prerequisite and the $(OBJDIR): rule to ensure the objects directory exists before compiling,
:= instead of = for all make variable assignments because you don't need recursively expanded variables here,
$^ instead of $(OBJ) in the link recipe because using automatic variables in recipes makes them more generic,
$< instead of $^ in the compile recipe because you compile only the first prerequisite, not all of them,
rm -f $(OBJ) preprocessor instead of rm $(SRCDIR)/*.o preprocessor to remove only the object files of the project and avoid errors if none exists.
Good day. I am in a directory, where is Makefile and folders src and bin. How can I compile object files into bin folder and then build an executable file?
I read some instructions and added $(BIN) before %.o, but it didn't helped, object files appear in folder with makefile. Where is the problem?
CC = arm-linux-gnueabihf-gcc
CXX = arm-linux-gnueabihf-g++
CPPFLAGS = -I .
CFLAGS =-g -std=gnu99 -O1 -Wall
CXXFLAGS = -g -std=gnu++11 -O1 -Wall
LDFLAGS = -lrt -lpthread
SRCDIR = src
BIN = bin
SOURCES = $(wildcard $(SRCDIR)/*.cpp) $(wildcard $(SRCDIR)/*.c)*
...
OBJECTS += $(filter %.o,$(SOURCES:%.c=%.o))
OBJECTS += $(filter %.o,$(SOURCES:%.cpp=%.o))
#$(warning OBJECTS=$(OBJECTS))
ifeq ($(filter %.cpp,$(SOURCES)),)
LINKER = $(CC)
LDFLAGS += $(CFLAGS) $(CPPFLAGS)
else
LINKER = $(CXX)
LDFLAGS += $(CXXFLAGS) $(CPPFLAGS)
endif
$(BIN)/%.o:%.c
$(CC) $(CFLAGS) -c $<
$(BIN)/%.o:%.cpp
$(CXX) $(CXXFLAGS) -c $<
all: $(TARGET_EXE)
$(TARGET_EXE): $(OBJECTS)
$(LINKER) $(LDFLAGS) -L. $^ -o $#
.PHONY : dep all run copy-executable debug
dep: depend
depend: $(SOURCES) *.h
echo '# autogenerat`enter code here`ed dependencies' > depend
ifneq ($(filter %.c,$(SOURCES)),)
$(CC) $(CFLAGS) $(CPPFLAGS) -w -E -M $(filter %.c,$(SOURCES)) \
>> depend
endif
ifneq ($(filter %.cpp,$(SOURCES)),)
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -w -E -M $(filter %.cpp,$(SOURCES)) \
>> depend
endif
clean:
rm -f *.o *.a $(OBJECTS) $(TARGET_EXE) connect.gdb depend
...
It's not clear to me how this makefile can works as well as it does, given that you haven't told it where to find the source files (unless you do so in one of the elided sections).
In these rules:
$(BIN)/%.o:%.c
$(CC) $(CFLAGS) -c $<
$(BIN)/%.o:%.cpp
$(CXX) $(CXXFLAGS) -c $<
you tell the compiler to build object files, but you don't specify where to build them, and the default is to build them in the working directory. You can override that with the -o option:
$(BIN)/%.o:%.c
$(CC) $(CFLAGS) -c $< -o $#
$(BIN)/%.o:%.cpp
$(CXX) $(CXXFLAGS) -c $< -o $#
Once you have the object files where you want them (bin/), you must ensure that the linking rule:
$(TARGET_EXE):$(OBJECTS)
$(LINKER) $(LDFLAGS) -L. $^ -o $#
can find them. The best way to do that is to ensure that OBJECTS contains the correct paths to the object files. I'm not sure how to advise you to do that, since from the look of your makefile that variable might not contain what you think it does.
EDIT:
Let's take this in stages.
Suppose we have on source file, src/foo.c. What we want is:
src/foo.c -> bin/foo.o
bin/foo.o -> foo
This requires two rules, which we can write like this:
$(BIN)/%.o: src/%.c
$(CC) $(CFLAGS) -c $< -o $#
$(TARGET_EXE): bin/foo.o
$(LINKER) $(LDFLAGS) -L. $^ -o $#
We actually have many source files, some of which are C++ files. So we must have a rule for them:
$(BIN)/%.o: src/%.cpp
$(CXX) $(CXXFLAGS) -c $< -o $#
and construct a longer list of objects:
OBJECTS := bin/foo.o bin/bar.o bin/baz.o bin/quartz.o...
$(TARGET_EXE): $(OBJECTS)
$(LINKER) $(LDFLAGS) -L. $^ -o $#
(Mixing C and C++ seems unhealthy to me, but never mind.)
And how do we construct that list of objects? We must start with the list of sources which wildcard can produce:
SRC := src
C_SOURCES := $(wildcard $(SRC/*.c)
# this is src/foo.c src/bar.c
SRC := src
CPP_SOURCES := $(wildcard $(SRC/*.cpp)
# this is src/baz.cpp src/quartz.cpp
and then convert them to the object file names we actually want:
BIN := bin
OBJECTS := $(patsubst $(SRC)/%.cpp,$(BIN)/%.o, $(CPP_SOURCES))
OBJECTS += $(patsubst $(SRC)/%.c,$(BIN)/%.o, $(C_SOURCES))
# this is bin/foo.o bin/bar.o bin/baz.o bin/quartz.o
That should give you the effect you want, and if you understand it you will understan why your old makefile did not.
I am trying to adapt a makefile (that I found here) that automatically generates dependencies. However, when I run make I get the following error message:
t#t-XPS-13-9365:~/pf/test$ make
g++ -MT .o/test_resamplers.o -MD -MP -MF .d/test_resamplers.Td -std=c++11 -g -Wall -Wextra -pedantic -I/usr/local/include/UnitTest++ -I/usr/include/eigen3 -I../include -c -o .o/test_resamplers.o test_resamplers.cpp
test_resamplers.cpp:155:1: fatal error: opening dependency file .d/test_resamplers.Td: No such file or directory
}
^
compilation terminated.
Makefile:66: recipe for target '.o/test_resamplers.o' failed
make: *** [.o/test_resamplers.o] Error 1
Perhaps I am using the wrong DEPFLAGS variable in my makefile. I did switch the compiler from clang++ in the example to g++. Here's my makefile:
# output binary
BIN := run_tests
# source files
SRCS := \
main.cpp test_cf_filters.cpp test_resamplers.cpp test_rv_eval.cpp \
test_rv_samp.cpp test_utils.cpp
# intermediate directory for generated object files
OBJDIR := .o
# intermediate directory for generated dependency files
DEPDIR := .d
# object files, auto generated from source files
OBJS := $(patsubst %,$(OBJDIR)/%.o,$(basename $(SRCS)))
# compilers (at least gcc and clang) don't create the subdirectories automatically
$(shell mkdir -p $(dir $(OBJS)) >/dev/null)
# C++ compiler
CXX := g++
# linker
LD := g++
# C++ flags
CXXFLAGS := -std=c++11
# C/C++ flags
CPPFLAGS := -g -Wall -Wextra -pedantic -I/usr/local/include/UnitTest++ -I/usr/include/eigen3 -I../include
# linker flags
LDFLAGS := "-L../bin" "-L/usr/local/lib"
# flags required for dependency generation; passed to compilers
DEPFLAGS = -MT $# -MD -MP -MF $(DEPDIR)/$*.Td
# libraries
LDLIBS := -lpf -lUnitTest++
# compile C++ source files
COMPILE.cc = $(CXX) $(DEPFLAGS) $(CXXFLAGS) $(CPPFLAGS) -c -o $#
# link object files to binary
LINK.o = $(LD) $(LDFLAGS) $(LDLIBS) -o $#
# precompile step
PRECOMPILE =
# postcompile step
POSTCOMPILE = mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d
all: $(BIN)
.PHONY: clean
clean:
$(RM) -r $(OBJDIR) $(DEPDIR)
.PHONY: help
help:
#echo available targets: all dist clean distclean install uninstall check
$(BIN): $(OBJS)
$(LINK.o) $^
$(OBJDIR)/%.o: %.c
$(OBJDIR)/%.o: %.c $(DEPDIR)/%.d
$(PRECOMPILE)
$(COMPILE.c) $<
$(POSTCOMPILE)
$(OBJDIR)/%.o: %.cpp
$(OBJDIR)/%.o: %.cpp $(DEPDIR)/%.d
$(PRECOMPILE)
$(COMPILE.cc) $<
$(POSTCOMPILE)
$(OBJDIR)/%.o: %.cc
$(OBJDIR)/%.o: %.cc $(DEPDIR)/%.d
$(PRECOMPILE)
$(COMPILE.cc) $<
$(POSTCOMPILE)
$(OBJDIR)/%.o: %.cxx
$(OBJDIR)/%.o: %.cxx $(DEPDIR)/%.d
$(PRECOMPILE)
$(COMPILE.cc) $<
$(POSTCOMPILE)
.PRECIOUS = $(DEPDIR)/%.d
$(DEPDIR)/%.d: ;
-include $(DEPS)
You create the object directory with this line:
$(shell mkdir -p $(dir $(OBJS)) >/dev/null)
but you don't create the DEPDIR anywhere, so when the compiler tries to create a file there it fails.
You could add this line to make the dependency directory:
$(shell mkdir -p $(DEPDIR))
Or, add it into the previous shell function.
I compiling my C source files with this code:
CC=clang -std=c11
CFLAGS=-Wall -g
ASSEMBLY=-S -masm=intel
OPTIMIZE=-Ofast
FOLDER_SRC=./src/
FOLDER_BIN=./bin/
FOLDER_ASSEMBLY=./ass/
clean:
rm -f \
$(FOLDER_BIN)1.1-hello $(FOLDER_ASSEMBLY)1.1-hello \
$(FOLDER_BIN)1.2-fahrenheit $(FOLDER_ASSEMBLY)1.2-fahrenheit \
$(FOLDER_BIN)1.2-fahrenheit-floating $(FOLDER_ASSEMBLY)1.2-fahrenheit-floating
all:
$(CC) $(CFLAGS) $(OPTIMIZE) $(FOLDER_SRC)1.1-hello.c -o $(FOLDER_BIN)1.1-hello
$(CC) $(CFLAGS) $(OPTIMIZE) $(FOLDER_SRC)1.2-fahrenheit.c -o $(FOLDER_BIN)1.2-fahrenheit
$(CC) $(CFLAGS) $(OPTIMIZE) $(FOLDER_SRC)1.2-fahrenheit-floating.c -o $(FOLDER_BIN)1.2-fahrenheit-floating
assembly:
$(CC) $(ASSEMBLY) $(OPTIMIZE) $(FOLDER_SRC)1.1-hello.c -o $(FOLDER_ASSEMBLY)1.1-hello
$(CC) $(ASSEMBLY) $(OPTIMIZE) $(FOLDER_SRC)1.2-fahrenheit.c -o $(FOLDER_ASSEMBLY)1.2-fahrenheit
$(CC) $(ASSEMBLY) $(OPTIMIZE) $(FOLDER_SRC)1.2-fahrenheit-floating.c -o $(FOLDER_ASSEMBLY)1.2-fahrenheit-floating
I try to implement some kind of loop to write less. I added this code, but it just generating errors:
FILENAME_SRC := $(wildcard $(FOLDER_SRC)*.c)
FILENAME_BUILD := $(patsubst $(FOLDER_SRC)%.c,%,$(FILENAME_SRC))
echo : $(FILENAME_SRC)
#echo $^
#echo $(FILENAME_BUILD)
build : $(FILENAME_SRC)
$(CC) $(CFLAGS) $(OPTIMIZE) $^ -o $(FILENAME_BUILD)
make echo printing this to the console:
$ make echo
src/1.2-fahrenheit.c src/1.1-hello.c src/1.2-fahrenheit-floating.c
1.2-fahrenheit 1.1-hello 1.2-fahrenheit-floating
make build command generating this error:
$ make build
clang -std=c11 -Wall -g -Ofast src/1.2-fahrenheit.c src/1.1-hello.c src/1.2-fahrenheit-floating.c -o 1.2-fahrenheit 1.1-hello 1.2-fahrenheit-floating
clang.exe: error: no such file or directory: '1.1-hello'
clang.exe: error: no such file or directory: '1.2-fahrenheit-floating'
make: *** [Makefile:21: build] Error 1
I want the expected output to look like when I do make all:
$ make all
clang -std=c11 -Wall -g -Ofast ./src/1.1-hello.c -o ./bin/1.1-hello
clang -std=c11 -Wall -g -Ofast ./src/1.2-fahrenheit.c -o ./bin/1.2-fahrenheit
clang -std=c11 -Wall -g -Ofast ./src/1.2-fahrenheit-floating.c -o ./bin/1.2-fahrenheit-floating
Final solution
CC := clang -std=c11
GCC := gcc -std=c11
CFLAGS := -Wall -g
ASSEMBLY := -Wall -S -masm=intel
OPTIMIZE := -O3 -march=native
SRC := $(wildcard src/*.c)
BIN := $(patsubst src/%.c,bin/%,$(SRC))
ASS := $(patsubst src/%.c,ass/%,$(SRC))
clean:
rm -f bin/* ass/*
build: $(BIN)
$(BIN): bin/%: src/%.c
$(CC) $(CFLAGS) $(OPTIMIZE) $^ -o $#
assembly: $(ASS)
$(ASS): ass/%: src/%.c
$(CC) $(ASSEMBLY) $(OPTIMIZE) $^ -o $#
Really sorry for the clean ass/* though, it cannot be called assembly because the similar folder name in the project.
Your all rule needs to look something like
CC := clang
CFLAGS := -std=c11 -Wall -g -Ofast
targets := bin/1.1-hello bin/1.2-fahrenheit bin/1.2-fahrenheit-floating
.PHONY: all
all: $(targets)
$(targets): bin/%: src/%.c
$(LINK.c) $^ $(LDLIBS) -o $#
so I learned what a Makefile was some time ago, created a template Makefile and all I do is copy and alter the same file for every program I'm doing. I changed it a few times, but it's still a very crude Makefile. How should I improve it? This is an example of my current version:
CC = g++
CFLAGS = -std=gnu++0x -m64 -O3 -Wall
IFLAGS = -I/usr/include/igraph
LFLAGS = -ligraph -lgsl -lgslcblas -lm
DFLAGS = -g -pg
# make all
all: run test
# make a fresh compilation from scratch
fresh: clean test
#makes the final executable binary
run: main.o foo1.o foo2.o
$(CC) $(CFLAGS) $(LFLAGS) $^ -o $#
#makes the test executable with debugging and profiling tags
test: test.o foo1.o foo2.o
$(CC) $(DFLAGS) $(CFLAGS) $(LFLAGS) $^ -o $#
#makes teste.o
teste.o: teste.cpp
$(CC) $(CFLAGS) $(IFLAGS) -c $^ -o $#
#makes main.o
main.o: main.cpp
$(CC) $(CFLAGS) $(IFLAGS) -c $^ -o $#
#file foo1
foo1.o: foo1.cpp
$(CC) $(CFLAGS) $(IFLAGS) -c $^ -o $#
#file foo2
foo2.o: foo2.cpp
$(CC) $(CFLAGS) $(IFLAGS) -c $^ -o $#
clean: clean-test clean-o clean-annoying
clean-test:
rm test-rfv
clean-o:
rm *.o -rfv
clean-annoying:
rm *~ -rfv
Just by visually comparing with other makefiles I saw around in the web, this seems to be not a very bright Makefile. I don't know how they work, but I can see there's significantly less boilerplate and more generic code in them.
Can this can be made better, safer, and easier to particularize for each project?
You don't want to name specific files in a makefile if you can get away with it, and 99% of the time you can. This page shows how to develop a very general makefile. The following is my own makefile, based on that page's info:
SHELL := bash
PROG := pathed.exe
OUTDIRS := bin/debug bin/rel obj/debug obj/rel
PROG_REL := bin/rel/$(PROG)
PROG_DEBUG := bin/debug/$(PROG)
SRCFILES := $(wildcard src/*.cpp)
OBJFILES_REL := $(patsubst src/%.cpp,obj/rel/%.o,$(SRCFILES))
OBJFILES_DEBUG := $(patsubst src/%.cpp,obj/debug/%.o,$(SRCFILES))
DEPFILES := $(patsubst src/%.cpp,obj/%.d,$(SRCFILES))
CFLAGS := -Iinc -Wall -Wextra -MMD -MP
DBFLAGS := -g
RELFLAGS :=
CC := g++
.PHONY: default all testmake debug release clean dirs
default: debug
all: dirs clean debug release
dirs:
#mkdir -p $(OUTDIRS)
debug: $(PROG_DEBUG)
release: $(PROG_REL)
testmake:
#echo OBJFILES_REL = $(OBJFILES_REL)
#echo OBJFILES_DEBUG = $(OBJFILES_DEBUG)
#echo SRCFILES = $(SRCFILES)
#echo DEPFILES = $(DEPFILES)
clean:
rm -f $(OBJFILES_REL) $(OBJFILES_DEBUG) $(DEPFILES) $(PROG)
$(PROG_REL): $(OBJFILES_REL)
$(CC) $(OBJFILES_REL) -o $(PROG_REL)
strip $(PROG_REL)
#echo "---- created release binary ----"
$(PROG_DEBUG): $(OBJFILES_DEBUG)
$(CC) $(OBJFILES_DEBUG) -o $(PROG_DEBUG)
#echo "---- created debug binary ----"
-include $(DEPFILES)
obj/rel/%.o: src/%.cpp
$(CC) $(RELFLAGS) $(CFLAGS) -MF $(patsubst obj/rel/%.o, obj/%.d,$#) -c $< -o $#
obj/debug/%.o: src/%.cpp
$(CC) $(DBFLAGS) $(CFLAGS) -MF $(patsubst obj/debug/%.o, obj/%.d,$#) -c $< -o $#
Do NOT use CC for the C++ compiler. The standard convention is that CC is the C compiler, CXX is the C++ compiler. CFLAGS are flags for the C compiler, CXXFLAGS are flags for the C++ compiler, and CPPFLAGS are flags for the pre-processor (eg, -I or -D flags). Use LDFLAGS for -L flags to the linker, and LDLIBS (or LOADLIBES) for -l flags.
Using the standard conventions is good not just because it makes things easier for others to understand, but also because it allows you to take advantage of implicit rules. If make needs to make a .o file from a .c file and you have not provided a rule, it will use a standard rule and honor the settings of CC, CFLAGS, and CPPFLAGS. If CC is a C++ compiler, things will probably not work.