The compile file doesn´t seem to be working - c

I wanted to ask if the following Makefile is correctly written, because the programme doesn´t seem to compile correctly but I´m not sure if the makefile or the code is the problem :
CC = /usr/bin/gcc
CFLAGS = -g -Wall -Wextra -Werror -pthread
DEPS = config.h shmHandling.h gameboard.h thinker.h strTools.h performConnection.h main.h
OBJ = main.o config.o shmHandling.o gameboard.o thinker.o strTools.o performConnection.o
# Link all .o files to program
%.o: %.c $(DEPS)
#echo "-----------------------"
#echo "Linking object files"
$(CC) -o -c $# $< $(CFLAGS)
sysprak-client: $(OBJ)
$(CC) -o $# $^ $(CFLAGS)
# Compile everything and run it with CL params
.PHONY: play
play: sysprak-client
#echo "-----------------------"
#echo "Launching sysprak-client with GameID: $(GAME_ID)"
./sysprak-client -g $(GAME_ID) -p $(PLAYER)
.PHONY: clean
clean:
-rm *.o $(OBJ)
Thanks!

This recipe:
$(CC) -o -c $# $< $(CFLAGS)
shall be:
$(CC) -o $# -c $< $(CFLAGS)
The -o option must be followed by the output file name and $# expands exactly as the name of the target object file. So -o $# is correct while -o -c is not.
Note: the comment before the rule it is part of is wrong. The rule compiles the C source files to object files. It is the following rule that Link all .o files to program. Same with the echo command. You should probably rewrite all this as:
# Compile each .c to .o
%.o: %.c $(DEPS)
#echo "-----------------------"
#echo "Compiling $<"
$(CC) -o $# -c $< $(CFLAGS)
# Link all .o files to program
sysprak-client: $(OBJ)
#echo "Linking object files"
$(CC) -o $# $^ $(CFLAGS)
# Run with CL params
.PHONY: play
play: sysprak-client
#echo "-----------------------"
#echo "Launching sysprak-client with GameID: $(GAME_ID)"
./sysprak-client -g $(GAME_ID) -p $(PLAYER)

Related

Why is this item always executed in the Makefile?

I wrote the following Makefile. But when I execute the make command, the sentence gcc -shared -o ../lib/libCfunc.so objFile/cacheOp.o objFile/fileOp.o objFile/linuxOp.o objFile/commonFunc.o is always executed. Even if I did not modify any files, and executed multiple make commands consecutively.
Doesn't objFile depend on $(libObjs)? Why is only this sentence being executed all the time?
cc=gcc
CFLAGS=-g -O0 -fPIC -lm
libObjs=objFile/cacheOp.o objFile/fileOp.o objFile/linuxOp.o objFile/commonFunc.o
all: objFile test
test: testFunc.c
$(cc) $^ -lCfunc -o $# $(CFLAGS)
objFile: $(libObjs)
gcc -shared -o ../lib/libCfunc.so $(libObjs)
objFile/cacheOp.o: Bodyer/cacheOp.c Header/cacheOp.h Header/cacheDetails.h
$(cc) -c $< -o $# $(CFLAGS)
objFile/fileOp.o: Bodyer/fileOp.c Header/fileOp.h
$(cc) -c $< -o $# $(CFLAGS)
objFile/linuxOp.o : Bodyer/linuxOp.c Header/linuxOp.h
$(cc) -c $< -o $# $(CFLAGS)
objFile/commonFunc.o : Bodyer/commonFunc.c Header/commonFunc.h
$(cc) -c $< -o $# $(CFLAGS)
.PHONY : clean
clean :
-rm $(libObjs)
The objFile file doesn't exist, so Make tries to build it.
Since your rule doesn't actually create a file called objFile, the next time you run Make, the objFile file still doesn't exist, so Make tries to build it again. And so on.

Makefile not compiling all C files in directory

Iam working with gcc and MinGW on a Windows platform. I have a directory containing two *.c files:
main.c and funcs.c
I am using the following makefile:
CC=gcc
CFLAGS=-c
LDFLAGS=
SOURCEDIR = src
BUILDDIR = build
SOURCES=$(wildcard $(SOURCEDIR)/*.c)
OBJECTS=$(patsubst $(SOURCEDIR)/%.c,$(BUILDDIR)/%.o,$(SOURCES))
LIBRARIES=-L/mingw64/lib
INC= -I./include
EXECUTABLE=testLink
VPATH = src include build
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) $(LIBRARIES) -o ./dist/$#
$(OBJECTS): $(SOURCES)
$(CC) $(INC) $(CFLAGS) $< -o $#
Which should take the *.c files and generate *.o files with the same name. However I get the following output on make -
$ make
gcc -I./include -c src/funcs.c -o build/funcs.o
gcc -I./include -c src/funcs.c -o build/main.o
gcc build/funcs.o build/main.o -L/mingw64/lib -o ./dist/testLink
followed of course by a bunch of multiple definition errors. As you can see from the first two lines it is taking the same *.c file and compiling it twice into two different *.o files.
I am new to makefiles but I assume it is something wrong with my $(OBJECTS) rule and I'm pretty sure it's the $< which is causing the problem. I'm trying to create a generic makefile which will always work on my projects which have the same directory structure and take .c files turn them into .o files and link. Am I going about this entirely the wrong way or is there a simple fix to my makefile?
Thanks!
James
This rule:
$(OBJECTS): $(SOURCES)
$(CC) $(INC) $(CFLAGS) $< -o $#
expands to:
funcs.o main.c: funcs.c main.c
$(CC) $(INC) $(CFLAGS) $< -o $#
which is equivalent to:
funcs.o: funcs.c main.c
$(CC) $(INC) $(CFLAGS) $< -o $#
main.o: funcs.c main.c
$(CC) $(INC) $(CFLAGS) $< -o $#
$< refers to the first dependency (funcs.c) so your Makefile is trying to generate both funcs.o and main.o from the same source.
You just want a generic rule using % wildcard matching:
%.o: %.c
$(CC) $(INC) $(CFLAGS) $< -o $#
See https://www.gnu.org/software/make/manual/html_node/Pattern-Rules.html
Jeff pointed the mistake in his answer (all objects depend on all sources: that isn't a generic compilation rule for c sources).
However, the generic rule must have source & object paths. To sum it up, just replace
$(OBJECTS): $(SOURCES)
$(CC) $(INC) $(CFLAGS) $< -o $#
by
$(BUILDDIR)/%.o : $(SOURCEDIR)/%.c
$(CC) $(INC) $(CFLAGS) $< -o $#
(as explained in How to generate a Makefile with source in sub-directories using just one makefile)
note that this kind of dependency test doesn't take included .h files into account, so it's only intended for first builds. Modifying .h files afterwards doesn't trigger a compilation since the header files are not listed as dependencies.

make: excluding main.c from rule that .o file depends on .h file

I have a C project with a bunch of source files and their headers:
one.c
one.h
two.c
two.h
I also have a main.c, but that has no .h file with it:
main.c
I have this in my Makefile:
# Use gcc to make object files from C files.
_build/%.o: %.c %.h
#mkdir -p _build
#echo
#echo Compiling $<
$(CC) $(CFLAGS) $< -o $#
This is fine for one.o and two.o. But it's no good for main.o, which does not have a main.h on which to depend. Make then throws this error.
make: *** No rule to make target `_build/main.o', needed by `all'. Stop.
How can I best treat main.c specially?
Add a separate static pattern rule
_build/%.o: %.c
#mkdir -p _build
#echo
#echo Compiling $<
$(CC) $(CFLAGS) $< -o $#
_build/one.o _build/two.o: _build/%.o: %.h
Even better, use dependency generation
OBJS := $(addprefix _build/,main.o one.o two.o)
DEPS := $(OBJS:.o=.d)
CPPFLAGS := -MMD -MP
.PHONY: all clean
all: $(OBJS)
$(OBJS): _build/%.o: %.c | _build
$(CC) $(CFLAGS) $(CPPFLAGS) -c -o $# $<
_build: ; mkdir -p $#
clean: ; $(RM) -r _build
-include $(DEPS)

Set Option in MakeFile to send object files to specific Folder

I made a test makefile using an online tutorial. It works, but I also want to have all of my .o files go to a specific sub-folder. Is there a way to do this using a makefile? Here is what I have so far.
CC=gcc # specifies the compiler to use.
CFLAGS=-I. # specifies to look in the current directory.
DEPS = path_tools.h # DEPS stores each .h file to be added.
OBJ = checkpath.o path_tools.o # OBJ stores each object file to compile.
%.o: %.c $(DEPS)
$(CC) -c -o $# $< $(CFLAGS)
checkpath.exe: $(OBJ)
gcc -o $# $^ $(CFLAGS)
For GNU make you can use this Makefile.
ODIR:=obj
CC:=gcc
CFLAGS:=-I.
DEPS:=path_tools.h
OBJ_:= checkpath.o path_tools.o
OBJ:=$(addprefix $(ODIR)/, $(OBJ_))
PROG=checkpath.exe
all:$(PROG)
$(OBJ): $(DEPS)
$(ODIR)/%.o: %.c
$(CC) -c -o $# $&lt $(CFLAGS)
$(PROG): $(OBJ)
$(CC) -o $# $^ $(CFLAGS)
clean:
rm -f $(OBJ) $(PROG)
You can pass the path of your folder to makefile to create and put the results in.
To pass parameter to makefile:
make DPATH=your-path
To use in makefile:
$(DPATH)
Create this path and add it to head of your *.o files as a path.

How to extend makefile to compose library?

I have a makefile which does what I want with the compilation but I want it also to make a library instead of only object files.
CC=gcc
CFLAGS=-g -Wall
DEPS = tree.h
OBJ = main.o tree.o
%.o: %.c $(DEPS)
$(CC) -c -o $# $< $(CFLAGS)
tree: $(OBJ)
$(CC) -o $# $^ $(CFLAGS)
clean:
rm -f *.o tree
Now I want the makefile to be something like this:
gcc -Wall -g -c tree.c
ar -r libtree.a tree.o
gcc main.c -o main -ltree -L.
./main
What I have to add to my existing makefile?
This should do what you want:
%.o: %.c $(DEPS)
$(CC) -c -o $# $< $(CFLAGS)
lib%.a: %.o
ar -r $# $^
main: $(OBJ) $(DEPS:%.h=lib%.a)
$(CC) -o $# $^ $(CFLAGS) $(DEPS:%.h=-l%) -L.
Note that this only works in GNU Make (in particular, the % in $(DEPS:%.h=lib%.a) is a GNU-specific extension).

Resources