How to create make file for only object and header file? - c

I'm performing blackbox testing using a set.h interface where I have no access to set.c, I've been provided with the object file set.o and I'm required to write a bunch of tests in a main.c file for the set. How do I create a makefile that would include set.o, set.h and main.c?
**I already have the set.o file so I don't have to regenerate it using set.c
I'm confused because I only know how to do this using the complete files.
Here's my template
CC = clang
CFLAGS = -g -Wall
PROG = example
HDRS = set.h
SRCS = main.c
OBJDIR = object
OBJS = $(OBJDIR)/main.o $(OBJDIR)/set.o
# compiling rules
$(PROG): $(OBJS) $(OBJDIR)
$(CC) $(CFLAGS) $(OBJS) -o $(PROG)
$(OBJDIR)/set.o: set.h $(HDRS) $(OBJDIR)
$(CC) $(CFLAGS) -c set.h -o $(OBJDIR)/set.o
$(OBJDIR)/main.o: main.c $(HDRS) $(OBJDIR)
$(CC) $(CFLAGS) -c main.c -o $(OBJDIR)/main.o
$(OBJDIR):
mkdir $(OBJDIR)
clean:
rm -f $(PROG) $(OBJS)

If you already have the set.o file there is no need to create a rule for it, just use it. Also note I got rid of the mkdir because if you already have a set.o, it should already be in objects/ right?
CC = clang
CFLAGS = -g -Wall
PROG = example
HDRS = set.h
SRCS = main.c
OBJDIR = object
OBJS = $(OBJDIR)/main.o
# compiling rules
$(PROG): $(OBJS)
$(CC) $(CFLAGS) $(OBJS) $(OBJDIR)/set.o -o $(PROG)
$(OBJDIR)/main.o: main.c $(HDRS)
$(CC) $(CFLAGS) -c main.c -o $(OBJDIR)/main.o
clean:
rm -f $(PROG) $(OBJS)

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)

Makefile doesn't match obj file

I have to work in a C project and i have problem with the make. The file structure is:
dir
--/bin
--/src
all the sources files (.c)
--/includes
all the includes (.h)
makefile
makefile is:
CC = gcc
RES =
_OBJ = paciente.o utils.o obrasocial.o pacienteobrasocial.o orm.o
profespecialidad.o profesional.o especialidad.o turnos.o $(RES)
LINKOBJ = main.o utils.o $(RES)
MAINOBJ = main.o
MAINSRC= main.c
LIBS = -L"/usr/lib"
IDIR =/includes
INCS = -I$(IDIR)
BIN = tpfinalc
_DEPS = config.h utils.h
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))
ODIR=/bin
CFLAGS = $(INCS) $(LIBS) -lpq
RM = rm -f
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
SDIR = /src
_SRC = especialidad.c obrasocial.c orm.c paciente.c
pacienteobrasocial.c profesional.c profespecialidad.c turnos.c utils.c
SRC = $(patsubst %,$(SDIR)/%,$(_SRC))
VPATH = src
.PHONY: all all-before all-after clean clean-custom
all: all-before tpfinalc all-after clean
$(BIN): $(OBJ)
$(CC) $(LINKOBJ) -o tpfinalc $(CFLAGS)
$(ODIR)/$(MAINOBJ): MAINSRC $(DEPS)
$(CC) -c MAINSRC -o $(ODIR)/$(MAINOBJ) $(CFLAGS)
$(ODIR)/%.o: %.c $(DEPS)
$(CC) -c -o $# $< $(CFLAGS)
I guess that this should'be correct, but when I make my c files the console indicates that there isn't any rule to build bin/paciente.
Anyone have an idea why? Thanks You.
One error is that /includes is an absolute path which does not exist (same applies to all other paths here). What you need is a relative path: includes or, if you like typing, ./includes.
Another error is that you omit paths in the dependencies and rules, so that make never finds your files. E.g.:
$(ODIR)/%.o: %.c $(DEPS)
$(CC) -c -o $# $< $(CFLAGS)
Should really be:
bin/%.o: src/%.c $(DEPS)
$(CC) -c -o $# $< $(CFLAGS)
All paths should be relative to the current directory, which is where your makefile is.

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

Using a Makefile to store object files in two different directories? [C]

I need to modify the Makefile I have to store only the object file associated with "record.c" into the bin folder. Here is what my directory structure looks like before executing Make.
bin/
include/
-hash_table.h
-history.h
-parser.h
-record.h
-shell.h
-variables.h
lib/
obj/
src/
-hash_table.c
-history.c
-parser.c
-record.c
-shutil.c
-sshell.c
-variables.c
...and here is the Makefile:
# Beginning of Makefile
SRC = src/shutil.c src/parser.c src/sshell.c src/history.c src/hash_table.c src/variables.c src/record.c
OBJS = obj/shutil.o obj/parser.o obj/sshell.o obj/history.o obj/hash_table.o obj/variables.o bin/record.o //<----
HEADER_FILES = include/shell.h include/parser.h include/history.h include/hash_table.h include/variables.h include/record.h
EXECUTABLE = sshell
LIBS = lib/libshell.so lib/libparser.so lib/libhistory.so lib/libhash_table.so lib/libvariables.so lib/librecord.so
LIBCFLAGS = $(CFLAGS) -D_REENTRANT -fPIC
CFLAGS = -Wall
CC = gcc
# End of configuration options
#What needs to be built to make all files and dependencies
all: $(EXECUTABLE)
#Create the main executable
$(EXECUTABLE): $(OBJS) $(LIBS)
$(CC) -o $(EXECUTABLE) obj/sshell.o -Llib -lparser -lshell -lhistory -lhash_table -lvariables -lrecord
#Create the library files
lib/libparser.so: obj/parser.o
$(CC) $(LIBFLAGS) -shared $^ -o $#
lib/libshell.so: obj/shutil.o
$(CC) $(LIBFLAGS) -shared $^ -o $#
lib/libhistory.so: obj/history.o
$(CC) $(LIBFLAGS) -shared $^ -o $#
lib/libhash_table.so: obj/hash_table.o
$(CC) $(LIBFLAGS) -shared $^ -o $#
lib/libvariables.so: obj/variables.o
$(CC) $(LIBFLAGS) -shared $^ -o $#
lib/librecord.so: bin/record.o //<----
$(CC) $(LIBFLAGS) -shared $^ -o $#
#Recursively build object files
obj/%.o: src/%.c //<---- I feel like this is causing the problem.
$(CC) $(CFLAGS) -I./include/ -c $< -o $#
#Define dependencies for objects based on header files
#We are overly conservative here, parser.o should depend on parser.h only
$(OBJS) : $(HEADER_FILES)
clean:
-rm -f $(EXECUTABLE) obj/*.o lib/*.so lib/*.a bin/*.o
-rm -f .sshell_history.txt
run: $(EXECUTABLE)
(export LD_LIBRARY_PATH=lib; ./$(EXECUTABLE))
# End of Makefile
With what I have done (most likely completely off) it doesn't compile record.c and says bin/record.o does not exist. I am not really experienced with Makefiles so I am wondering if I can have some help. Thanks!
Try using the rule .c.o instead of obj/%.o: src/%.c
Edit:
If that doesn't work, maybe adding the following rule will do the job:
bin/%.o: src/%.c
$(CC) $(CFLAGS) -I./include/ -c $< -o $#

make: *** No rule to make target `gcc', needed by `libmy.so'. Stop

I would like to compile .c files to a .so (shared library).
And I don't understand why, I have that makefile that makes me an error:
LIB = libmy.so
SRC = lib.c
CC = gcc
OBJ = $(CC) -c -fPIC $(SRC)
all: $(LIB)
re: fclean all
$(LIB): $(OBJ)
$(CC) -shared -fPIC $(OBJ) -o $(LIB)
clean:
$(RM) $(OBJ)
fclean: clean
$(RM) $(LIB)
Thanks in advance for helping.
The problem is in the following line:
$(LIB): $(OBJ)
When expanded this becomes:
libmy.so : gcc -c -fPIC lib.c
Hence the error.
What you probably wanted was :
OBJ = lib.o
To save you having to manually convert all .c source files to .o you can use a rule like this instead of OBJ = lib.o:
OBJ = $(SRC:%.c=%.o)
This creates a variable OBJ containing a list of all the files in SRC with any .c extension changed to .o. eg. If we had SRC = foo.c bar.c then the rule above would automatically expand to:
OBJ = foo.o bar.o
$(LIB): $(OBJ)
expands to
libmy.so: gcc -c -fPIC $(SRC)
ie you put your recipe into the depency list, and make rightfully complains.
Personally, I'd write the makefile like this:
CC := gcc
RM := rm -f
LIB := libmy.so
OBJ := lib.o
GARBAGE := $(OBJ)
.PHONY: all clean realclean
all: $(LIB)
$(LIB): LDFLAGS += -shared
$(LIB): $(OBJ)
$(CC) $(LDFLAGS) -o $# $<
$(OBJ): CFLAGS += -fPIC
$(OBJ): %.o : %.c
$(CC) $(CFLAGS) -c -o $# $<
realclean: GARBAGE += $(LIB)
clean realclean:
$(RM) $(GARBAGE)
Note that your original version did not contain a rule to make $(OBJ). If you wanted to use the implicit one, you would need to add -fPIC to CFLAGS.
That works :
LIB = libmy.so
SRC = lib.c
CC = gcc
OBJ = $(SRC:.c=.o)
all: $(LIB)
re: fclean all
$(LIB):
$(CC) -c -fPIC $(SRC)
$(CC) -shared -fPIC $(SRC) -o $(NAME)
clean:
$(RM) $(OBJ)
fclean: clean
$(RM) $(LIB)
I just need OBJ = $(SRC:.c=.o) in fclean

Resources