Adding a library to my makefile - c

I have set up a makefile that takes the sources main.c, word.c, and trim.c
I also used a library which is called linkedList.a, however even after adding it it does not build as I keep getting undefined references to functions within linkedlist.
The following is my makefile code:
SHELL = /bin/sh
SRCDIR = .
CC = gcc
YACC = bison -y
CDEBUG = -g
COMPLIANCE_FLAGS =
CFLAGS = $(COMPLIANCE_FLAGS) $(CDEBUG) -I. -I$(SRCDIR)
LDFLAGS = -g
LIBRARY_FILES = linkedList.a
linkedList.a: $(LIBRARY_FILES).o
$(RM) -f $(output)
$(AR) cr $(output) $(inputs)
ranlib $(output)
############################################################################################################
# List your sources here.
SOURCES = main.c word.c trim.c
############################################################################################################
############################################################################################################
# list the name of your output program here.
EXECUTABLE = wordCounter
############################################################################################################
# Create the names of the object files (each .c file becomes a .o file)
OBJS = $(patsubst %.c, %.o, $(SOURCES))
include $(SOURCES:.c=.d)
all : $(OBJS) $(EXECUTABLE)
$(EXECUTABLE) : $(OBJS)
$(CC) -o $(EXECUTABLE) $(OBJS)
%.o : %.c #Defines how to translate a single c file into an object file.
echo compiling $<
echo $(CC) $(CFLAGS) -c $<
$(CC) $(CFLAGS) -E $< > $<.preout
$(CC) $(CFLAGS) -S $<
$(CC) $(CFLAGS) -c $<
echo done compiling $<
%.d : %.c #Defines how to generate the dependencies for the given files. -M gcc option generates dependencies.
#set -e; rm -f $#; \
$(CC) $(COMPLIANCE_FLAGS ) -M $< > $#.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $# : ,g' < $#.$$$$ > $#; \
rm -f $#.$$$$
clean : # Delete any and all artifacts from the build. The only thing which is kept is the source code.
rm -f *.o
rm -f *.preout
rm -f *.s
rm -f *.S
rm -f *d
rm -f $(EXECUTABLE)
I feel I added the proper items in the proper places. My best guess is that my library_files is somehow wrong?

Your $(EXECUTABLE) rule doesn't mention the library, it just tries to link main.o, word.o and trim.o. So we must rewrite that rule.
First try this from the command line (because we can't do something with Make until we know how to do it without Make):
gcc -o wordCounter main.o word.o trim.o -L. -llinkedList
If this works, then we can write the rule:
$(EXECUTABLE) : $(OBJS) linkedList.a
$(CC) -o $# $(OBJS) -L. -llinkedList
If it doesn't, we'll have to tweak it a little. And some further refinements are possible, once we have the makefile working.

The "all:" line needs enhancement and, yes, LIBRARY_FILES needs changing/splitting. You have an OBJS variable for the executable, but nothing similar for the library. Actually, a bit more to do, as follows ...
(1) Currently, you have one library, but let's go for two:
LIBRARY_FILES += lib1.a
LIBRARY_FILES += lib2.a
(2) We now need two variables, similar to your OBJS, but one for each library:
LIBOBJS1 += abc.o def.o
LIBOBJS2 += ghi.o jkl.o
(3) We now need two rules, one for each library, similar to your rule for your library, but different [Note that most modern "ar" programs do their own ranlib--YMMV]:
lib1.a: $(LIBOBJS1)
ar crv $# $(LIBOBJS1)
lib2.a: $(LIBOBJS2)
ar crv $# $(LIBOBJS2)
(4) Now, change the rule for the executable itself:$(EXECUTABLE): $(OBJS) $(LIBRARY_FILES)
$(CC) -o $(EXECUTABLE) $(OBJS) $(LIBRARY_FILES)
(5) Now, we need to change the "all:" line. With the other rule changes, this can be simplified to:all: $(EXECUTABLE)
(6) Now add a command to the "clean:" target, either: rm -f *.a
Or: rm -f $(LIBRARY_FILES)
(7) Note that care must be taken so that LIBOBJS1/LIBOBJS2 don't overlap with SOURCES/OBJS. That is, you have to decide which sources build the libraries and which ones are strictly for the executable. I think you'll be fine on this, but I didn't see anything that spelled which .c/.o files you wanted to build your library from.
(8) All the build rules should probably be moved down the file after all the symbol definitions

Related

How to make a modular Makefile for a modular c project?

I have a C program that has this code:
#if defined(MATRIX)
#include "Matrix.h"
#elif defined(QTREE)
#include "QTree.h"
#endif
and I want to create a Makefile that given a target passes de -D flag to GCC with the corresponding MACRO so that the correct header + source files are compiled.
Currently I have this Makefile:
# Makefile for compiling the battleship game
C=gcc
STANDARD=c99
HEADER_DIR=includes
ODIR=obj
CFLAGS=$(C) -c -std=$(STANDARD) -I$(HEADER_DIR)
SDIR=src
_OBJS = Battleship.o Game.o Cell.o Ship.o Bitmap.o IO.o Aux.o Matrix.o QTree.o Board.o
OBJS = $(patsubst %,$(ODIR)/%,$(_OBJS))
# Program name
PROG=battleship
$(ODIR)/%.o: $(SDIR)/%.c
$(CFLAGS) -o $# $<
$(PROG1): $(OBJS)
$(C) -o $(PROG) -D MATRIX $(OBJS)
$(PROG2): $(OBJS)
$(C) -o $(PROG) -D QTREE $(OBJS)
.PHONY: game_with_matrix
game_with_matrix: $(PROG1)
.PHONY: game_with_qtree
game_with_qtree: $(PROG2)
.PHONY: clean
clean:
rm -f $(ODIR)/*.o $(PROG)
but it always outputs: make: Nothing to be done for [target].
I don't really know whats wrong :(
EDIT:
when I invoke make I am using either make game_with_matrix or make game_with_qtree.
Thanks in advance!
First, this:
C=gcc
CFLAGS=$(C) -c -std=$(STANDARD) -I$(HEADER_DIR)
$(ODIR)/%.o: $(SDIR)/%.c
$(CFLAGS) -o $# $<
"CFLAGS" is a bad name for that. I strongly advise this:
C=gcc
CFLAGS= -c -std=$(STANDARD) -I$(HEADER_DIR)
$(ODIR)/%.o: $(SDIR)/%.c
$(C) $(CFLAGS) -o $# $<
Now you could add a target-specific variable value:
$(PROG1): CFLAGS += -DMATRIX
$(PROG1): $(OBJS)
$(C) -o $(PROG) $(OBJS)
$(PROG2): CFLAGS += -DQTREE
$(PROG2): $(OBJS)
$(C) -o $(PROG) $(OBJS)
But you haven't yet defined PRG1 nor PROG2, and I see no need for them. Get rid of them and do this:
$(PROG): $(OBJS)
$(C) -o $# $^
game_with_matrix: CFLAGS += -DMATRIX
game_with_matrix: $(PROG)
game_with_qtree: CFLAGS += -DQTREE
game_with_qtree: $(PROG)
Is this the actual makefile you're using? Because you've not defined either the variable PROG1 or the variable PROG2, so if your makefile looks like that that's clearly the problem.
However, even if you fix that this is dangerous. You should not put both types of objects into the same subdirectory. You'll have to remember to always do a make clean when switching between them because make has no way to know if the previous build used the MATRIX or QTREE settings and you'll be trying to link object files compiled with different settings.
You should create two different OBJ directories, one for each, and use them when building that program.

Make implicit rules with GCC: Redirecting *.o

I am trying to get make to do the following with an implicit rule:
obj/lsabase.o : inc/lsabase.h lsabase.c
cc -c lsabase.c && mv lsabase.o obj
I searched for ways to redirect the output of "cc -c .." with compiler options, but didn't find any here.
Also the implicit rule defined for compiling from source to object only lets you use $(CPPFLAGS) and $(CFLAGS).
Does anybody know how to trick make into using this (mv lsabase.o obj) in an implicit rule, so I can put all *.o files in a seperate directory?
obj/lsabase.o : inc/lsabase.h lsabase.c
cc -I"inc" -c lsabase.c -o obj/lsabase.o
I would
avoid doing the mv manually but rather telling gcc to put in the obj dir
let gcc handle the dependencies (by creating .d files)
and here is what I usually do when all my .c files are in a subdir and I want to compile all of them in a parallel dir obj (that I can easily remove):
default: my_code
#add subdirs
DIRS := $(shell find src -type d)
#add include directives for subdirs
CFLAGS += $(DIRS:%=-I%)
#collect all c files
SRCS := $(shell find src/* -name \*.c)
OBJS := $(addprefix obj/, $(SRCS:.c=.o))
DEPS := $(addprefix obj/, $(SRCS:.c=.d))
# this generates a dependency file for every .c
obj/%.d: %.c
# mkdir -p "$(#D)"
# echo "Checking dependencies for $<"
# create and modify dependecy file .d to take into account the location obj (sed magical)
# gcc $(CFLAGS) -MM $< 2>/dev/null | sed -e "s#\(^.*\)\.o:#obj/$(shell dirname $<)/\1.d obj/$(shell dirname $<)/\1.o:#" > $#
#this compiles
obj/%.o : %.c
gcc $(CFLAGS) -c $< -o $#
#this creates the executable
my_code: $(OBJS)
gcc $(OBJS) -o $# $(LDFLAGS)
# this does the magic
-include $(DEPS)
clean:
rm -rf obj
If you're new to Make, this might seem difficult, but it's really powerful once you get through.
you can write the makefile rule this way:
obj/lsabase.o : lsabase.c inc/lsabase.h
<tab>cc $(CFLAGS) -c $< -o $# -Iinc/.
where, in the actual makefile, the <tab> would be replaced with an actual tab character
Notice the *.c file is first in the list of dependencies, so can use the $< shortcut
You mentioned wanting to do this for all the object files..
obj/$.o : %.c inc/%.h
<tab>cc $(CFLAGS) -c $< -o $# -Iinc/.
However, that may not be the most flexible. For maximum flexibility, suggest adding a rule to generate and include dependency files named *.d. Then using:
obj/$.o : %.c %.d
<tab>cc $(CFLAGS) -c $< -o $# -Iinc/.

Makefiles - ar: *.a: No such file or directory.... but there is... it's right there

Trying to compile a friend's code - but he has included no Makefile, I build my own and am perplexed by an issue I've run into.
I think it's best I post the full contents of the Makefile below... I tried to keep it short!
CFLAGS = -Wall -pedantic
LFLAGS =
CC = gcc
RM = /bin/rm -rf
AR = ar rc
RANLIB = ranlib
LIBRARY = const.a read.a descr.a
LIB_SRC = read.c futex.c testy.c
LIB_OBJ = $(patsubst %.c,%.o,$(LIB_SRC))
# pattern rule for object files
%.o: %.c
$(CC) -c $(CFLAGS) $< -o $#
all: $(LIBRARY)
$(LIBRARY): $(LIB_OBJ)
$(AR) $(LIBRARY) $(LIB_OBJ)
$(RANLIB) $(LIBRARY)
clean:
$(RM) $(LIBRARY) $(LIB_OBJ)
.PHONY: depend
depend:
$(CFLAGS) -- $(LIB_SRC) 2>/dev/null
All of the files, const.h, read.h, and descr.h are in the directory in which I call make. Likewise for read.c, futex.c, and testy.c.
The files are entangled in various ways - if I need to show exactly the nature of these entanglements, I will do so.
I 'make' and the compiler alledges:
ar: read.a: No such file or directory
Is it not the case that read.a is supposed to be being produced? Of course it isn't there yet.
I've stared a while now and I feel like this must be something simple I am missing.
This command:
$(AR) $(LIBRARY) $(LIB_OBJ)
expands to this:
ar rc const.a read.a descr.a read.o futex.o testy.o
So when Make tries to build const.a, it tells ar to combine several files into const.a, starting with read.a, and ar complains that there's no such file. (Whether ar could do anything useful with read.a if it did exist is immaterial.)
It's not clear how you want Make to build those libraries, but this might be a step in the right direction:
$(LIBRARY): $(LIB_OBJ)
$(AR) $# $(LIB_OBJ)
$(RANLIB) $#
The automatic variable $# expands to the name of the target. You can use another one for the list of prerequisites ($(LIB_OBJ)), but let's try one new thing at a time.

I need some assistance with Makefile in my project

I'm trying to make a Makefile but I'm having some problems
first I have
2 source files: ~/main.c ~/lib/library.c
1 header file: ~/include/library.h
main.c and library.c both share the same header file library.h
# Compiler options
CC = gcc
INC = -I../include
CFLAGS = -Wall -g -c $(INC)
LIB = -L../lib
LFLAGS = -Wall -g $(LIB)
# Dependencies
LIBS = -libmylib
OBJS = main.o
SRCS = $(OBJS:.o=.c)
EXEC = a.out
# Other rules
RM = rm -rf
TAGS = tags
BAK = Makefile.bak
all: $(EXEC)
#echo ------------------------ Compile Complete ----------------------------
.PHONY: clean depend
$(EXEC): $(OBJS)
$(CC) $(LFLAGS) -o $# $^ $(LIBS)
.c.o:
$(CC) $(INC) -M $^
$(CC) $(CFLAGS) -o $# $<
clean:
$(RM) *.o *~ $(EXEC) $(TAGS) $(BAK)
depend: $(SRCS)
makedepend $(INC) $^
it keeps saying that I it can't make a rule out of library.o
plus I have another question
I acknowledge the fact that when Makefile comes in to action after calling 'make',
and subsequently go to the line .c.o or %c: %o(in GNU enhanced version) and make
.o files. but why doesn't it also call clean and depend automatically?
I've edited some things from the previous version of Makefile
this time, (well pretty similar to the previous problem) even though I
clarified the library path(-I../lib),
the Makefile cannot find the archive file (which I created as libmylib.a in ../lib dir)
now it's driving me crazy
but why doesn't it also call clean and depend automatically?
Because make only builds the target you tell it. If you don't specify one, the first target is built, which in many cases, such as yours, is the 'all' target.

error with makefile (executables)

Hi after a previous problem with not having makedepend installed (now solved), I now have the following error when trying to run my makefile:
$ make
makedepend -- -- -I /usr/include/linux -I include
cp executables
cp: missing destination file operand after `executables'
Try `cp --help' for more information.
make: *** [executables] Error 1
and here is my makefile:
CMDLINE_SRC=$(wildcard commandLine/*.c)
CMDLINE_OBJS = $(CMDLINE_SRC:.c=.o)
EXECUTABLES = $(CMDLINE_SRC:.c=)
LIB_SRC=$(wildcard c/*.c)
LIB_OBJ = $(LIB_SRC:.c=.o)
LIB_OUT = lib/libclinrisk.a
INCLUDES = -I include
# compiler
CC = gcc
CCFLAGS =
LDFLAGS =
# library paths
LIBS = -Llib -lclinrisk -lm
.SUFFIXES: .c
default: dep executables
executables: $(EXECUTABLES)
cp $(EXECUTABLES) executables
$(EXECUTABLES): $(LIB_OUT)
.c:
$(CC) $(INCLUDES) $(LDFLAGS) $< -o $# $(LIBS)
.c.o:
$(CC) $(INCLUDES) $(CCFLAGS) -c $< -o $#
$(LIB_OUT): $(LIB_OBJ)
ar rcs $(LIB_OUT) $(LIB_OBJ)
depend: dep
dep:
makedepend -- $(CFLAGS) -- -I /usr/include/linux $(INCLUDES) $(LIB_SRC)
clean:
rm -f $(LIB_OBJ) $(LIB_OUT) Makefile.bak
rm -f $(CMDLINE_OBJ) $(CMDLINE_PROGS)
rm -f executables/*
what is the problem here? I am new to makefiles! will try figure this out in the meantime.
The problem looks like it's to do with:
cp $(EXECUTABLES) executables
however I'm unaware of a correct pathway to executables...
Thanks.
Nothing in your Makefile code sets the EXECUTABLES variable, so it substitutes to an empty string, which calls cp with just a single argument, thus generating the error.

Resources