I want to generate objects in subdirectory by makefile - makefile

How to specify a subdirectory for the generated .o files, e.g. objsdir, for this code in the make file
cc = gcc
CFLAGS = -o6 -Wall
LIBS = -lm
SOURCES = main.c\
extra.c
OBJECTS = $(SOURCES: .c = .o)
.c.o :; $(cc) -c $(CFLAGS) $<
all : $(OBJECT)
$(cc) -o ...
Actually this is a part of the mkefile code.

I usually use something like this:
cc=gcc
SOURCES=main.c extra.c
OBJECTS=$(patsubst %.c, objsdir/%.o, $(SOURCES))
objsdir/%.o: %.c
echo $^
all: $(OBJECTS)
echo $(OBJECTS)

I actually use this Makefile in general
CC := g++ # This is the main compiler
SRCDIR := src
BUILDDIR := build
TARGETDIR :=bin/
TARGET := pddlcrate
DATADIR := data
SRCEXT := cpp
SOURCES := $(shell find $(SRCDIR) -type f -name *.$(SRCEXT))
OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(SOURCES:.$(SRCEXT)=.o))
CFLAGS := -g # -Wall
#LIB := -pthread -lmongoclient -L lib -lboost_thread-mt -lboost_filesystem-
mt -lboost_system-mt
INC := -I include
$(TARGET): $(OBJECTS)
#echo " Linking..."
#echo " $(CC) $^ -o $(TARGETDIR)$(TARGET) $(LIB)"; $(CC) $^ -o
$(TARGETDIR)$(TARGET) $(LIB)
$(BUILDDIR)/%.o: $(SRCDIR)/%.$(SRCEXT)
#mkdir -p $(BUILDDIR)
#echo " $(CC) $(CFLAGS) $(INC) -c -o $# $<"; $(CC) $(CFLAGS) $(INC) -c - o $# $<
clean:
#echo " Cleaning...";
#echo " $(RM) -r $(BUILDDIR) $(TARGET)"; $(RM) -r $(BUILDDIR) $(TARGET)
for any c++ project with this tree structure
$ tree .
├── Makefile
├── bin
>exefile
├── include
> *.h files
├── obj
> *.o files
├── src
>*.cpp

Related

How to build apps in subfolders with Makefile

I'm trying to write a Makefile that will build apps stored in subfolders. So structure of the folders is as follows:
examples/
Makefile
hello_world/
file1.c
main.c
**hello_world** <- expected build result
example1/
otherfile.c
main.c
**example1** <- expected build result
example2/
main.c
...
**example2** <- expected build result
My Makefile (simplified) looks like this:
EXAMPLES := hello_world example1 example2
SRC = $(wildcard */*.c)
OBJ = ${SRC:.c=.o}
OUT = $(foreach e, $(EXAMPLES), $(addprefix $(e)/,$(e)) )
CC := gcc
all: examples
$(OBJ): $(SRC)
#$(CC) -c $< -o $#
$(OUT): $(OBJ)
$(CC) $(filter $(dir $#)%,$^) -o $# $(LDFLAGS)
clean:
#rm -f $(OUT) $(OBJ)
Is there a way to make it work? Or maybe I should have Makefile in each folder separately?
This rule seems to solve my problem, matches outputs to .o, but filters files that are passed for linking with filter function
$(OUT): $(OBJ)
$(CC) $(filter $(dir $#)%,$^) -o $# $(LDFLAGS)
Replaced old rule:
$(OUT): $(OBJ)
$(CC) $^ -o $#
with
examples: $(OBJ)
$(foreach e, $(EXAMPLES), \
$(CC) $(wildcard $(e)/*.o) -o $(e)/$(e) $(LDFLAGS); \
)
almost works now, after clean, the compilation works as expected, only linking fails ($(wildcard $(e)/*.o) is empty?), after second run examples are created as expected
Inspired by comments by Beta and MadScientist, I think I have a solution:
EXAMPLES := hello_world example1 example2
SRC = $(wildcard */*.c)
OBJ = ${SRC:.c=.o}
OUT = $(foreach e, $(EXAMPLES), $(addprefix $(e)/,$(e)) )
CC := gcc
all: $(OUT)
%.o: %.c
#$(CC) $(CFLAGS) -c $< -o $#
$(OUT): $(OBJ)
#$(CC) $(filter $(dir $#)%,$^) -o $# $(LDFLAGS)
clean:
#rm -f $(OUT) $(OBJ)
.PHONY: all clean

makefile error: “make: *** No rule to make target …”

I'm trying to use GCC (linux) with a makefile to compile my project.
I get the following error
"No rule to make target 'output/src/main.o', needed by 'test'. Stop."
This is the makefile:
COMPILE_PREX ?=
CC = $(COMPILE_PREX)gcc
SOURCE = $(wildcard src/*.c)
OBJS = $(addprefix ./output/, $(patsubst %.c, %.o, $(SOURCE)))
INCLUDES = -I ./src
CFLAGS += -O2 -Wall -g
LDFLAGS += -lpthread
TARGET = test
$(TARGET): $(OBJS)
$(CC) $(OBJS) $(LDFLAGS) -o $(TARGET)
%.o: %.c
#mkdir -p ./output
$(CC) $(CFLAGS) $(INCLUDES) -o $(addprefix ./output/, $#) -c $<
clean:
rm -rf ./output
This should work. Note the use of mkdir $(#D) to create output directories as needed.
COMPILE_PREX ?=
CC = $(COMPILE_PREX)gcc
SOURCE = $(wildcard src/*.c)
OBJS = $(addprefix output/, $(patsubst %.c, %.o, $(SOURCE)))
INCLUDES = -I src
CFLAGS += -O2 -Wall -g
LDFLAGS += -lpthread
TARGET = test
$(TARGET): $(OBJS)
$(CC) $(OBJS) $(LDFLAGS) -o $(TARGET)
output/%.o: %.c
#mkdir -p $(#D)
$(CC) $(CFLAGS) $(INCLUDES) -o $# -c $<
clean:
rm -rf output
Running it here with make clean test:
rm -rf output
gcc -O2 -Wall -g -I src -o output/src/hello.o -c src/hello.c
gcc output/src/hello.o -lpthread -o test

Makefile objects from .c .cpp and .S sources

I am facing a problem with my makefile. I am trying to compile .c; .cpp and .S files from ./src/. The objects should go into ./obj/ and the binaries into ./bin/. With my current file, it tries to searches for files in ./src/, but tries to compile objectfiles for each extension. So for example, if it finds kernel.cpp, it will try to compile kernel.S and kernel.c, but they are not there, so i get an error.
Here is my code:
TARGET = kernel
CC = gcc
LD = ld
SRCDIR = src
OBJDIR = obj
BINDIR = bin
SRCS = $(wildcard $(SRCDIR)/*.c) $(wildcard $(SRCDIR)/*.cpp) $(wildcard $(SRCDIR)/*.S)
HDR = $(wildcard $(SRCDIR)/*.h)
OBJS = $(SRCS:$(SRCDIR)/%.c=$(OBJDIR)/%.o) $(SRCS:$(SRCDIR)/%.cpp=$(OBJDIR)/%.o) $(SRCS:$(SRCDIR)/%.S=$(OBJDIR)/%.o)
rm = rm -f
ASFLAGS = -m64
CFLAGS = -m64 -Wall -g -fno-stack-protector -nostdinc
LDFLAGS = -m elf_x86_64 -Ttext=0x100000
$(BINDIR)/$(TARGET): $(OBJS)
$(LD) $(OBJS) $(LDFLAGS) -o $#
$(OBJS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
$(CC) $(CFLAGS) -c $< -o $#
$(OBJS): $(OBJDIR)/%.o : $(SRCDIR)/%.cpp
$(CC) $(CFLAGS) -c $< -o $#
$(OBJS): $(OBJDIR)/%.o : $(SRCDIR)/%.S
$(CC) $(ASFLAGS) -c $< -o $#
.PHONY: clean
clean:
$(rm) $(OBJS)
.PHONY: remove
remove:
$(rm) $(BINDIR)/$(TARGET)
I might try to separate SRCS into SRCS_Cpp and so on... But i don't know if that's the best solution. I am pretty new to makefiles^^
I think i found the solution^^
TARGET = kernel
CC = gcc
LD = ld
SRCDIR = src
OBJDIR = obj
BINDIR = bin
SRCS_c = $(wildcard $(SRCDIR)/*.c)
SRCS_cpp = $(wildcard $(SRCDIR)/*.cpp)
SRCS_S = $(wildcard $(SRCDIR)/*.S)
HDR = $(wildcard $(SRCDIR)/*.h)
OBJS = $(SRCS_c:$(SRCDIR)/%.c=$(OBJDIR)/%_c.o) $(SRCS_cpp:$(SRCDIR)/%.cpp=$(OBJDIR)/%_cpp.o) $(SRCS_S:$(SRCDIR)/%.S=$(OBJDIR)/%_S.o)
rm = rm -f
ASFLAGS = -m64
CFLAGS = -m64 -Wall -g -fno-stack-protector -nostdinc
LDFLAGS = -m elf_x86_64 -Ttext=0x100000
$(BINDIR)/$(TARGET): $(OBJS)
$(LD) $(OBJS) $(LDFLAGS) -o $#
$(OBJDIR)/%_c.o : $(SRCDIR)/%.c
$(CC) $(CFLAGS) -c $< -o $#
$(OBJDIR)/%_cpp.o : $(SRCDIR)/%.cpp
$(CC) $(CFLAGS) -c $< -o $#
$(OBJDIR)/%_S.o : $(SRCDIR)/%.S
$(CC) $(ASFLAGS) -c $< -o $#
.PHONY: clean
clean:
$(rm) $(OBJS)
.PHONY: remove
remove:
$(rm) $(BINDIR)/$(TARGET)
Is there something i do wrong? I am trying to compile a kernel without the use of a cross-compiler^^

Automatic dependency processing in Makefile

I have a simple makefile.
IDIR =./include
CC=gcc
CFLAGS=-I$(IDIR)
SRCDIR = ./src
ODIR=obj
LDIR =./lib
LIBS=-lm
SRC = hellomake hellofunc
OBJ = ${SRC:%=$(ODIR)/%.o}
_DEPS = hellomake.h
DEPS = ${_DEPS:%=$(IDIR)/%}
$(ODIR)/%.o: $(SRCDIR)/%.c $(DEPS)
$(CC) -c -o $# $< $(CFLAGS)
hellomake: $(OBJ)
gcc -o $# $^ $(CFLAGS) $(LIBS)
.PHONY: clean
clean:
rm -f $(ODIR)/*.o *~ hellomake
What I don't like about this Makefile is that the dependency generation.
.c.o
Is it possible to teach make file that the .c is in src directory, and .o is in obj directory to make this simple one?
.c.o:
$(CC) -c -o $# $< $(CFLAGS)
header dependency
Is it possible to teach make file that all the c files are recompiled automatically when header files that the c file contains is changed?
Preliminaries
Generating dependencies
gcc's -MM -MG can be used to create the dependencies: gcc -MM -MG src/hellofunc.c -I./include will create hellofunc.o: src/hellofunc.c include/hellomake.h. However, we need to include the .d file itself into the .d file, so we use sed to achieve that goal.
gcc -MM -MG src/hellofunc.c -I./include | sed -e 's#^\(.*\)\.o:#\1.d \1.o:#'
The results will be as follows:
hellofunc.d hellofunc.o: src/hellofunc.c include/hellomake.h
When we want to change the content to include the different directory location, we can modify the sed script.
gcc -MM -MG src/hellofunc.c -I./include | sed -e 's#^\(.*\)\.o:#obj/\1.d obj/\1.o:#'
The results will be as follows:
obj/hellofunc.d obj/hellofunc.o: src/hellofunc.c include/hellomake.h
include
-include $(DEPS) will include the files in DEPS directory, the - in front of the include teaches the make to ignore when the directories does not exits.
Pattern matching and replacement
We can substitute any pattern (%) or pattern that ends with c (%.c) as follows:
OBJDIRS := $(patsubst %, $(OBJDIR)/%, $(MODULES))
OBJS := $(patsubst %.c, $(OBJDIR)/%.o, $(SRCS))
We also can have shorthand form.
DEPS := $(OBJS:.o=.d)
filter
We can select only some of the files with filter, this is an example:
OBJ := $(patsubst %.c, %.o, $(filter %.c, $(SRC)))
Method 1
In this method, we specify the dependency (.d depends on .c), and include the created dependency file with include.
.PHONY: clean depend
CC := gcc
CXX := g++
LD := g++
CP := cp
PROG := hellomake
MODULES := src
OBJDIR := obj
default: $(PROG)
OPTFLAGS := -g -O
CFLAGS += -Wall -Wno-unused-function $(OPTFLAGS) $(patsubst %, -I%, $(MODULES))
GARBAGE := core core.* *.stackdump ./tags $(PROG)
include $(patsubst %, %/module.make, $(MODULES))
OBJ := \
$(patsubst %.c, %.o, $(filter %.c, $(SRC)))
DEP := $(OBJ:.o=.d)
# implicit rules
%.d: %.c
./depends.sh $(CC) `dirname $*.c` $(CFLAGS) $*.c > $#
-include $(DEP)
# Actual targets
depend: $(DEP)
clean:
rm -rf $(PROG) $(OBJ) $(GARBAGE) $(DEP) depends
$(PROG): $(OBJ)
$(LD) -o $# $^ $(LIBS)
Each module should contain the make file (module.make) to specify what files are included in the SRC variable.
`SRC += src/hellofunc.c \
src/hellomake.c`.
This is the script to generate the dependency file:
#!/bin/sh
#echo "## Got: $*"
CC="$1"
DIR="$2"
shift 2
case "$DIR" in
"" | ".")
$CC -MM -MG "$#" | sed -e 's#^\(.*\)\.o:#\1.d \1.o:#'
;;
*)
$CC -MM -MG "$#" | sed -e "s#^\(.*\)\.o:#$DIR/\1.d $DIR/\1.o:#"
;;
esac
This method is simple, but the object files and dependency files are created in the same src directory with these statements.
SRC += src/hellofunc.c src/hellomake.c
OBJ := $(patsubst %.c, %.o, $(filter %.c, $(SRC)))
DEP := $(OBJ:.o=.d)
Method 2
This method creates the object directory, and puts all the generated (intermediate) files into the directory.
It enlists all the modules to specify the actions both for object file and dependency file generation.
In the example, we have only one module, but with multiple modules, we need to duplicate the statements.
obj/src/%.o: src/%.c
$(CC) -c $< -o $# $(CFLAGS)
obj/src/%.d: src/%.c
gcc -MM -MG $< $(CFLAGS) | sed -e 's#^\(.*\)\.o:#obj/src/\1.d obj/src/\1.o:#' > $#
This is the makefile:
.SUFFIX = .o .c
.PHONY: clean
CC := gcc
LD := gcc
PROG := hellomake
OBJDIR = obj
MODULES := src
SRCS := src/hellofunc.c src/hellomake.c
OBJDIRS := $(patsubst %, $(OBJDIR)/%, $(MODULES))
OBJS := $(patsubst %.c, $(OBJDIR)/%.o, $(SRCS))
DEPS := $(OBJS:.o=.d)
default: $(PROG)
CFLAGS += -Wall -Wno-unused-function $(OPTFLAGS) $(patsubst %, -I%, $(MODULES))
CXXFLAGS += $(CFLAGS)
obj/src/%.o: src/%.c
$(CC) -c $< -o $# $(CFLAGS)
$(PROG): $(OBJDIRS) $(OBJS)
$(LD) $(filter %.o, $^) -o $(PROG)
-include $(DEPS)
obj/src/%.d: src/%.c
gcc -MM -MG $< $(CFLAGS) | sed -e 's#^\(.*\)\.o:#obj/src/\1.d obj/src/\1.o:#' > $#
depend: $(DEPS)
GARBAGE := core core.* *.stackdump ./tags $(PROG)
clean:
rm -rf $(PROG) obj/*
$(OBJDIRS):
mkdir -p $#
References
Create directories when generating object files in gcc
How to place object files in separate subdirectory
make deleting dependency files
http://scottmcpeak.com/autodepend/autodepend.html
IDIR = ./include
CC = gcc
CFLAGS = -I$(IDIR)
SRCDIR = src
ODIR = obj
LDIR = ./lib
LIBS = -lm
SRC = hellomake hellofunc
OBJ = ${SRC:%=$(ODIR)/%.o}
_DEPS = hellomake.h
DEPS = ${_DEPS:%=$(IDIR)/%}
%.o: ../$(SRCDIR)/%.c $(DEPS)
$(CC) -c -o $# $< $(CFLAGS)
hellomake: $(OBJ) $(DEPS)
gcc -o $# $^ $(CFLAGS) $(LIBS)

Can not create shared object from object files

I have wrote a makefile to compile a dynamic library. However, output .so file does not contains all of the methods.
I have used this Makefile:
CC=g++
CFLAGS=-fPIC -g
LDFLAGS=-shared
SRCDIR=src
SOURCES=$(shell echo $(SRCDIR)/*.cpp)
HEADERS=$(shell echo $(SRCDIR)/*.h)
OBJECTS=$(SOURCES:.cpp=.o)
LIBDIR=lib
INCDIR=include
LIBRARIES=-lboost_filesystem -lboost_system -lopencv_core -lopencv_highgui -lopencv_imgproc
OUT=$(LIBDIR)/libAgeGender.so
all: $(SOURCES) $(HEADERS) $(OUT)
.cpp.o:
$(CC) $(CFLAGS) $< -o $# $(LDFLAGS)
$(OUT): $(OBJECTS)
$(CC) $(CFLAGS) $(OBJECTS) $(LIBRARIES) -o $# $(LDFLAGS)
clean:
rm -f $(SRCDIR)/*.o *~ $(SRCDIR)/*~ $(OUT)
Then i executed this command to see functions inside of an .o file.
nm SDaisy.o | grep ' T '
00000000000070d6 T _ZN6SDaisy11convolutionERKN2cv3MatESt6vectorIfSaIfEEi
000000000000933e T _ZN6SDaisy12extractDaisyERKN2cv3MatE
0000000000007498 T _ZN6SDaisy14gaussianFilterERKN2cv3MatEff
000000000000854a T _ZN6SDaisy16smoothHistogramsERN2cv3MatE
000000000000c088 T _fini
0000000000005960 T _init
When we look into shared object, we can't see methods.
$ nm libAgeGender.so | grep ' T '
0000000000000578 T _fini
0000000000000438 T _init
How can i make it correctly?
Use the right variables and functions, and let make handle the compilation of .o files.
SRCDIR := src
LIBDIR := lib
INCDIR := include
SRC := $(wildcard $(SRCDIR)/*.cpp)
OBJ := $(SRC:.cpp=.o)
OUT := $(LIBDIR)/libAgeGender.so
CXXFLAGS := -fPIC -g
LDFLAGS := -shared
LDLIBS := -lboost_filesystem -lboost_system \
-lopencv_core -lopencv_highgui -lopencv_imgproc
all: $(OUT)
$(OUT): $(OBJ)
$(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $#

Resources