Build c program for release and build - c

The original makefile comes for Release build.
Original
APP:= deepstream-app
TARGET_DEVICE = $(shell gcc -dumpmachine | cut -f1 -d -)
NVDS_VERSION:=5.0
LIB_INSTALL_DIR?=/opt/nvidia/deepstream/deepstream-$(NVDS_VERSION)/lib/
APP_INSTALL_DIR?=/opt/nvidia/deepstream/deepstream-$(NVDS_VERSION)/bin/
ifeq ($(TARGET_DEVICE),aarch64)
CFLAGS:= -DPLATFORM_TEGRA
endif
SRCS:= $(wildcard *.c)
SRCS+= $(wildcard ../../apps-common/src/*.c)
INCS:= $(wildcard *.h)
PKGS:= gstreamer-1.0 gstreamer-video-1.0 x11
OBJS:= $(SRCS:.c=.o)
CFLAGS+= -I../../apps-common/includes -I../../../includes -DDS_VERSION_MINOR=0 -DDS_VERSION_MAJOR=5
LIBS+= -L$(LIB_INSTALL_DIR) -lnvdsgst_meta -lnvds_meta -lnvdsgst_helper -lnvdsgst_smartrecord -lnvds_utils -lm \
-lgstrtspserver-1.0 -ldl -Wl,-rpath,$(LIB_INSTALL_DIR)
CFLAGS+= `pkg-config --cflags $(PKGS)`
LIBS+= `pkg-config --libs $(PKGS)`
all: $(APP)
%.o: %.c $(INCS) Makefile
$(CC) -c -o $# $(CFLAGS) $<
$(APP): $(OBJS) Makefile
$(CC) -o $(APP) $(OBJS) $(LIBS)
install: $(APP)
cp -rv $(APP) $(APP_INSTALL_DIR)
clean:
rm -rf $(OBJS) $(APP)
Modified for both Release and Debug
APP:= deepstream-app
DEBUGAPP:= deepstream-app-debug
TARGET_DEVICE = $(shell gcc -dumpmachine | cut -f1 -d -)
NVDS_VERSION:=5.0
LIB_INSTALL_DIR?=/opt/nvidia/deepstream/deepstream-$(NVDS_VERSION)/lib/
APP_INSTALL_DIR?=/opt/nvidia/deepstream/deepstream-$(NVDS_VERSION)/bin/
ifeq ($(TARGET_DEVICE),aarch64)
CFLAGS:= -DPLATFORM_TEGRA
endif
SRCS:= $(wildcard *.c)
SRCS+= $(wildcard ../../apps-common/src/*.c)
INCS:= $(wildcard *.h)
PKGS:= gstreamer-1.0 gstreamer-video-1.0 x11
OBJS:= $(SRCS:.c=.o)
CFLAGS+= -I../../apps-common/includes -I../../../includes -DDS_VERSION_MINOR=0 -DDS_VERSION_MAJOR=5
LIBS+= -L$(LIB_INSTALL_DIR) -lnvdsgst_meta -lnvds_meta -lnvdsgst_helper -lnvdsgst_smartrecord -lnvds_utils -lm \
-lgstrtspserver-1.0 -ldl -Wl,-rpath,$(LIB_INSTALL_DIR)
CFLAGS+= `pkg-config --cflags $(PKGS)`
LIBS+= `pkg-config --libs $(PKGS)`
all: $(APP)
%.o: %.c $(INCS) Makefile
$(CC) -c -o $# $(CFLAGS) $<
%.o: %.c $(INCS) Makefile
$(CC) -g3 -c -o $# $(CFLAGS) $<
$(APP): $(OBJS) Makefile
$(CC) -o $(APP) $(OBJS) $(LIBS)
$(DEBUGAPP): $(OBJS) Makefile
$(CC) -g3 -o $(DEBUGAPP) $(OBJS) $(LIBS)
install: $(APP)
cp -rv $(APP) $(DEBUGAPP) $(APP_INSTALL_DIR)
clean:
rm -rf $(OBJS) $(APP) $(DEBUGAPP)
But it doesn't produce deepstream-app-debug. What should I change for both release and debug?

You can add the DEBUGAPP to the target all:
# This belongs in the makefile:
all: $(APP) $(DEBUGAPP)
This will build both APP and DEBUGAPP, if you call make like you used to do it most probably.
However, you can give make any target as an argument without further changing the makefile:
# This is a command in your shell:
make deepstream-app-debug

Related

Makefile is not creating a directory

Teacher gave us this makefile for compiling two C files and storing the objects into a directory called object. It compiles the programs fine however it doesn't store their objects into the directory, and it also doesn't even create the directory. Not sure what to do and could really use some help.
This is my make file
CC = clang
CFLAGS = -g -Wall
OBJDIR = object
HDRS = $(wildcard *.h)
SRCS = $(wildcard *.c)
OBJS = $(addprefix $(OBJDIR)/, $(SRCS:.c=.o))
.PHONY: all
all: client server
# WARNING: must have a tab before each definition
$(OBJDIR)/client.o: client.c $(HDRS) $(OBJDIR)
$(CC) $(CFLAGS) -c client.c -o object/client.o
$(OBJDIR)/server .o: server.c $(HDRS) $(OBJDIR)
$(CC) $(CFLAGS) -c server.c -o object/server.o
$(OBJDIR)/%.o: %.c $(HDRS) $(OBJDIR)
$(CC) $(CFLAGS) -c $*.c -o object/$*.o
$(OBJDIR):
mkdir $(OBJDIR)
.PHONY: clean
clean:
rm -f $(TARGET) $(OBJS)
All I had to do was add multiple targets to the makefile and change all to target the targets
CC = clang
CFLAGS = -g -Wall
# TODO: rename the target to something meaningful!
TARGET = client server
OBJDIR = object
HDRS = $(wildcard *.h)
SRCS = $(wildcard *.c)
OBJS = $(addprefix $(OBJDIR)/, $(SRCS:.c=.o))
.PHONY: all
all: $(TARGET)
# WARNING: *must* have a tab before each definition
$(TARGET): $(OBJDIR) $(OBJS)
$(CC) $(CFLAGS) $(OBJDIR)/protocol.o $(OBJDIR)/$#.o -o $#
$(OBJDIR)/%.o: %.c $(HDRS) $(OBJDIR)
$(CC) $(CFLAGS) -c $*.c -o object/$*.o
$(OBJDIR):
mkdir $(OBJDIR)
.PHONY: clean
clean:
rm -f $(TARGET) $(OBJS)

Include glib library in Makefile

I'm not an expert of Makefile.
In my program I'm using hashtables of glib.h so in my Makefile I wrote this:
exec: bin/test
bin/test
clean:
rm -f build/* bin/*
CFLAGS = -g -Wall -Wpedantic -Wno-padded -O $(shell pkg-config --cflags --libs glib-2.0)
INCLUDES = include/*.h
COMMON_DEPS = $(INCLUDES) Makefile
build/%.o: src/%.c $(COMMON_DEPS)
$(CC) $(CFLAGS) -c $< -o $#
bin/test: /* functions.o*/ $(COMMON_DEPS)
$(CC) -o bin/test /* functions.o*/
But when I execute the Makefile I receive a list of these error messages:
...
functions.c: undefined reference to "g_str_hash"
functions.c: undefined reference to "g_str_equal"
...
I don't understand why
At the end I solved it in this way:
exec: bin/test
bin/test
clean:
rm -f build/* bin/*
CFLAGS = -g -Wall -Wpedantic -Wno-padded -O $(shell pkg-config --cflags glib-2.0)
LFLAGS = $(shell pkg-config --libs glib-2.0)
INCLUDES = include/*.h
COMMON_DEPS = $(INCLUDES) Makefile
build/%.o: src/%.c $(COMMON_DEPS)
$(CC) $(CFLAGS) -c $< -o $#
bin/test: /*functions.o */ $(COMMON_DEPS)
$(CC) -o bin/test /*functions.o */ $(LFLAGS)
The crux of the problem is that you're including the link flags in the compile command rather than the link command itself.
Remove --libs glib-2.0 from CFLAGS and add it to a new variable LFLAGS that can be used on the link line...
exec: bin/test
bin/test
clean:
rm -f build/* bin/*
CFLAGS = -g -Wall -Wpedantic -Wno-padded -O $(shell pkg-config --cflags glib-2.0)
LFLAGS = $(shell pkg-config --libs glib-2.0)
INCLUDES = include/*.h
COMMON_DEPS = $(INCLUDES) Makefile
build/%.o: src/%.c $(COMMON_DEPS)
$(CC) $(CFLAGS) -c $< -o $#
bin/test: /* functions.o*/ $(COMMON_DEPS)
$(CC) $(LFLAGS) -o bin/test /* functions.o*/
[Note: I've left the rest of the makefile untouched but the dependency specification for bin/test does look very odd.]

makefile not updating .o file with respectively with .h file

I have following make file :-
VER = Debug
CC = gcc
objectfiles = Getstr.o ui.o ustreqsol.o main.o
pkg = `pkg-config --cflags --libs gtk+-3.0`
obj = $(addprefix objs/,$(objectfiles))
../$(VER)/Calculator: $(obj)
$(CC) -o $# $(obj) $(pkg)
./objs/ui.o:ui.c
$(CC) -c -o $# $< $(pkg)
./objs/main.o:main.c
$(CC) -c -o $# $< $(pkg)
./objs/%.o: %.c %.h
$(CC) -c -o $# $<
clean:
-rm ../$(VER)/Calculator
-rm /objs/*
and follwing files in my src dir:-
$ ls
Getstr.c main.c Makefile objs ui.c ui.h ustreqsol.c ustreqsol.h
objs is directory. Whenver I change ustreqsol.h file it compiles ustreqsol.c file but not in case for ui.h file
$ touch ustreqsol.h
$ make
gcc -c -o objs/ustreqsol.o ustreqsol.c
gcc -o ../Debug/Calculator objs/Getstr.o objs/ui.o objs/ustreqsol.o objs/main.o `pkg-config --cflags --libs gtk+-3.0`
$ make
make: '../Debug/Calculator' is up to date.
$ touch ui.h
$ make
make: '../Debug/Calculator' is up to date.
As a noob in makefiles i have no idea why is this happening
The reason ui.c is not being rebuilt is because you explictly said ui.h is not a dependency:
./objs/ui.o:ui.c
$(CC) -c -o $# $< $(pkg)
For the general dependency you have set up:
./objs/%.o: %.c %.h
$(CC) -c -o $# $<
The dependency list only takes effect for files that you didn't explicitly set them for, such as ustreqsol.c.
You need to add targets for each object file specifying the dependencies for each one. The targets can be blank, as the %.o target will fill in what to do.
For example:
./objs/ustreqsol.o: ustreqsol.c ustreqsol.h ui.h
./objs/ui.o: ui.c ui.h
./objs/main.o: main.c ui.h ustreqsol.h
./objs/Getstr.o: Getstr.c
./objs/%.o: %.c %.h
$(CC) -c -o $# $<

Makefile - compiling library and executable when no changes made

So, I can understand what the problem is here, but I can't quite figure out how to fix it -- Because it is compiling files from a different directory, but throwing the .a library file and executable into the root...It seems that the makefile is expecting them to be in their source directory, and that's why it rebuilds every time even when no changes are made.
Problem is, my school is very strict on folder structure, so it needs to compile exactly how it is, I just need to figure out how to let the makefile know the executable and library file DO exist, in the root directory.
Here is my Makefile:
NAME = fillit
LIB = libft.a
CC = gcc
CFLAGS = -Wall -Wextra -Werror
RM = /bin/rm -rf
SRC = main.c validation.c create_piece.c game_board.c solver.c tables.c \
trimmer.c
LIBSRC = ft_putchar.c ft_putstr.c ft_strcpy.c ft_strnew.c ft_strdel.c \
ft_strequ.c ft_putendl.c ft_error.c
LIBLIST := $(shell ls -1 libft | grep .c$$)
LIBOBJ := $(LIBLIST:.c=.o)
LIBOBJ := $(addprefix libft/, $(LIBOBJ))
SRCLIST := $(shell ls -1 src | grep .c$$)
SRCOBJ := $(SRCLIST:.c=.o)
SRCOBJ := $(addprefix src/, $(SRCOBJ))
.PHONY: all $(NAME) lib
all: $(NAME)
libft/%.o: libft/%.c
$(CC) $(CFLAGS) -c -o $# $<
src/%.o: src/%.c
$(CC) $(CFLAGS) -c -o $# $<
lib:
ar rc $(LIB) $(LIBOBJ)
ranlib $(LIB)
debug:
$(CC) $(CFLAGS) $(addprefix libft/, $(LIBLIST)) $(addprefix src/, $(SRCLIST)) -g -o fillit
$(NAME): $(LIBOBJ) $(SRCOBJ) lib
$(CC) $(CFLAGS) $(SRCOBJ) -L. -lft -o fillit
clean:
$(RM) $(SRCOBJ)
$(RM) $(LIBOBJ)
fclean: clean
$(RM) $(NAME)
$(RM) $(LIB)
re: fclean all
re-db: fclean debug
It's working fine for compiling the .o files, it only does that once, but if I continue to type make, it still compiles this part:
➜ fillit git:(master) ✗ make
ar rc libft.a libft/ft_memset.o libft/ft_putchar.o libft/ft_putendl.o libft/ft_putstr.o libft/ft_strcpy.o libft/ft_strdel.o libft/ft_strequ.o libft/ft_strnew.o
ranlib libft.a
gcc -Wall -Wextra -Werror src/create_piece.o src/game_board.o src/main.o src/solver.o src/tables.o src/trimmer.o src/validation.o -L. -lft -o fillit
Want to thank kaylum for pointing me in the right direction, I have figured out how to solve this problem. I changed lib to $(LIB) and removed $(NAME) and lib from the phony list. Working makefile:
NAME = fillit
LIB = libft.a
CC = gcc
CFLAGS = -Wall -Wextra -Werror
RM = /bin/rm -rf
SRC = main.c validation.c create_piece.c game_board.c solver.c tables.c \
trimmer.c
LIBSRC = ft_putchar.c ft_putstr.c ft_strcpy.c ft_strnew.c ft_strdel.c \
ft_strequ.c ft_putendl.c ft_error.c
LIBLIST := $(shell ls -1 libft | grep .c$$)
LIBOBJ := $(LIBLIST:.c=.o)
LIBOBJ := $(addprefix libft/, $(LIBOBJ))
SRCLIST := $(shell ls -1 src | grep .c$$)
SRCOBJ := $(SRCLIST:.c=.o)
SRCOBJ := $(addprefix src/, $(SRCOBJ))
.PHONY: all
all: $(NAME)
libft/%.o: libft/%.c
$(CC) $(CFLAGS) -c -o $# $<
src/%.o: src/%.c
$(CC) $(CFLAGS) -c -o $# $<
$(LIB):
ar rc $(LIB) $(LIBOBJ)
ranlib $(LIB)
debug:
$(CC) $(CFLAGS) $(addprefix libft/, $(LIBLIST)) $(addprefix src/, $(SRCLIST)) -g -o fillit
$(NAME): $(LIBOBJ) $(SRCOBJ) $(LIB)
$(CC) $(CFLAGS) $(SRCOBJ) -L. -lft -o $(NAME)
clean:
$(RM) $(SRCOBJ)
$(RM) $(LIBOBJ)
fclean: clean
$(RM) $(NAME)
$(RM) $(LIB)
re: fclean all
re-db: fclean debug

Makefile does not find rule for object

I have a beginner's question about a Makefile. I have a very simple makefile containing:
SHELL = /bin/sh
CC = gcc
CFLAGS = -lm -std=c99 -g -o0
EXEC = test
BUILDDIR = build
OBJDIR = obj
SOURCES = $(shell cat sources.list)
DEPS = $(shell cat headers.list)
OBJ = $(SOURCES:.c=.o)
OBJECTS = $(patsubst %,$(OBJDIR)/%,$(OBJ))
all: $(OBJECTS)
$(CC) $(CFLAGS) $(OBJECTS) -o $(BUILDDIR)/$(EXEC)
$(OBJDIR)/%.o: %.c $(DEPS)
$(CC) -c $< -o $#
clean:
rm -f $(BUILDDIR)/$(EXEC) $(OBJDIR)/*.o
My Problem is, if I try to use this Makefile to compile, it returns the error message:
there is no rule for the target obj/Name.o
What am I doing wrong?
After the first few comments and further research I got to this working Version, but it does not create the object files in the obj folder, so it is not what I aim for
SHELL = /bin/sh
CC = gcc
CFLAGS = -lm -std=c99 -g -o0
EXEC = test
BUILDDIR = build
OBJDIR = obj
SOURCES = $(shell cat sources.list)
DEPS = $(shell cat headers.list)
OBJ = $(SOURCES:.c=.o)
OBJECTS = $(patsubst %,$(OBJDIR)/%,$(OBJ))
all: $(BUILDDIR)/$(EXEC)
$(BUILDDIR)/$(EXEC): $(OBJ)
$(CC) $(CFLAGS) $(OBJ) -o $(BUILDDIR)/$(EXEC)
%.o: %.c $(DEPS)
$(CC) -c $< -o $#
clean:
rm -f $(BUILDDIR)/$(EXEC) $(OBJDIR)/*.o
Are all the files in headers.list present at the right place ?
By the way, this is not a good way to handle dependencies on headers. You should take a look at -MP and -MDD and other options of your preprocessor to generate dependencies.
A classical makefile which should do what you need:
SHELL=/bin/bash
CC=gcc
CFLAGS=-std=c99 -g -o0
LDFLAGS=-lm
EXEC=test
BUILDDIR=build/
OBJDIR=obj/
SOURCES=$(shell cat sources.list)
OBJECTS=$(patsubst %.c,$(OBJDIR)%.o,$(notdir $(SOURCES)))
vpath %.c $(sort $(dir $(SOURCES)))
.PHONY:all mrproper clean depends
all:$(BUILDDIR)$(EXEC)
$(BUILDDIR)$(EXEC):$(OBJECTS)|$(BUILDDIR)
$(CC) $(CFLAGS) $^ -o $# $(LDFLAGS)
$(OBJDIR)%.o:%.c|$(OBJDIR)
$(CC) -c $< -o $#
$(BUILDDIR) $(OBJDIR):
mkdir $#
mrproper:clean
rm -f $(BUILDDIR)$(EXEC)
clean:
rm -f $(OBJECTS)
depends:
#rm -f dependencies.mk
#for i in $(SOURCES); do $(CC) -MM $$i -MT $(OBJDIR)`basename $$i | sed s:.c$$:.o:` >> dependencies.mk; done
include $(wildcard dependencies.mk)
If something is not clear, let me know.
Usage:
make depends
make

Resources