Why is my makefile not making one of the targets? - c

I'm required to submit my program along with a makefile for an assignment but for some reason it is not making the target helper.o even though the command for that step (gcc -Wall -std=c99 -c helper.c) works when I type it into the command line manually. When I type the make command I get this error:
gcc -Wall -std=c99 -c createTweet.c
gcc -Wall -std=c99 -c displayTweets.c
gcc -Wall -std=c99 -c searchTweetsByKeyword.c
gcc -Wall -std=c99 -c countStopWords.c
gcc -Wall -std=c99 -c deleteTweet.c
gcc -Wall -std=c99 -c saveTweetsToFile.c
gcc -Wall -std=c99 -c loadTweetsFromFile.c
gcc -Wall -std=c99 -c sortID.c
gcc -Wall -std=c99 -c addNodeToList.c
cc -c -o mainA3.o mainA3.c
gcc -Wall -std=c99 createTweet.o displayTweets.o searchTweetsByKeyword.o countStopWords.o deleteTweet.o saveTweetsToFile.o loadTweetsFromFile.o sortID.o addNodeToList.o helper.o mainA3.o -o matiwosEyoelA3
gcc: error: helper.o: No such file or directory
make: *** [makefile:2: outputA3] Error 1 '''
Here: is my makefile:
outputA3: createTweet.o displayTweets.o searchTweetsByKeyword.o countStopWords.o deleteTweet.o saveTweetsToFile.o loadTweetsFromFile.o sortID.o addNodeToList.o mainA3.o
gcc -Wall -std=c99 createTweet.o displayTweets.o searchTweetsByKeyword.o countStopWords.o deleteTweet.o saveTweetsToFile.o loadTweetsFromFile.o sortID.o addNodeToList.o helper.o mainA3.o -o outputA3
helper.o: helper.h headerA3.h helper.c
gcc -Wall -std=c99 -c helper.c
createTweet.o: createTweet.c helper.h headerA3.h
gcc -Wall -std=c99 -c createTweet.c
displayTweets.o: displayTweets.c helper.h headerA3.h
gcc -Wall -std=c99 -c displayTweets.c
searchTweetsByKeyword.o: searchTweetsByKeyword.c helper.h headerA3.h
gcc -Wall -std=c99 -c searchTweetsByKeyword.c
countStopWords.o: countStopWords.c helper.h headerA3.h
gcc -Wall -std=c99 -c countStopWords.c
deleteTweet.o: deleteTweet.c helper.h headerA3.h
gcc -Wall -std=c99 -c deleteTweet.c
saveTweetsToFile.o: saveTweetsToFile.c helper.h headerA3.h
gcc -Wall -std=c99 -c saveTweetsToFile.c
loadTweetsFromFile.o: loadTweetsFromFile.c helper.h headerA3.h
gcc -Wall -std=c99 -c loadTweetsFromFile.c
sortID.o: sortID.c helper.h headerA3.h
gcc -Wall -std=c99 -c sortID.c
addNodeToList.o: addNodeToList.c helper.h headerA3.h
gcc -Wall -std=c99 -c addNodeToList.c
clean:
rm *.o outputA3
Why might this be happening?

Your matiwosEyoelA3: ... does not list helper.o as a dependency.
That's a problem because you repeat so many file names and violate the "don't write it twice" rule. Use variables and make's builtin variables like $^.
e.g.
OBJECTS = createTweet.o displayTweets.o searchTweetsByKeyword.o \
countStopWords.o deleteTweet.o saveTweetsToFile.o \
loadTweetsFromFile.o sortID.o addNodeToList.o \
mainA3.o helper.o
outputA3: $(OBJECTS)
gcc -Wall -std=c99 -o $# $^

Your target outputA3: does not depend on helper.o.
Change the first line to -
outputA3: createTweet.o displayTweets.o searchTweetsByKeyword.o countStopWords.o deleteTweet.o saveTweetsToFile.o loadTweetsFromFile.o sortID.o addNodeToList.o mainA3.o helper.o
gcc -Wall -std=c99 createTweet.o displayTweets.o searchTweetsByKeyword.o countStopWords.o deleteTweet.o saveTweetsToFile.o loadTweetsFromFile.o sortID.o addNodeToList.o helper.o mainA3.o -o outputA3
(notice the extra helper.o at the end)
One way to avoid such issues in the future is to use $^ to refer to all the dependencies instead of listing them.
So you can change the target to -
outputA3: createTweet.o displayTweets.o searchTweetsByKeyword.o countStopWords.o deleteTweet.o saveTweetsToFile.o loadTweetsFromFile.o sortID.o addNodeToList.o mainA3.o helper.o
gcc -Wall -std=c99 $^ -o $#
This way you don't have to write the dependencies again and if you miss something you get a linker error telling you which file is missing.

helper.o is not in the list of dependencies for outputA3 target, while it is in the linking list of requisites. This makes make not to compile it, but the linker blames at you because it is not found.
A good idea can be to create a make variable with the set of objects of outputA3, as in:
outputA3_objs = createTweet.o displayTweets.o searchTweetsByKeyword.o countStopWords.o deleteTweet.o saveTweetsToFile.o loadTweetsFromFile.o sortID.o addNodeToList.o helper.o mainA3.o
outputA3: $(outputA3_objs)
gcc -Wall -std=c99 $(outputA3_objs) -o $#
and this way, if you need to change the list, you have to do it in only one place, making your Makefile more robust to changes.

make is much more powerful than what you apparently think. Thanks to the other answers you fixed your Makefile. Here is a bit simpler and less error prone Makefile (for GNU make):
SRC := $(wildcard *.c)
OBJ := $(patsubst %.c,%.o,$(SRC))
CC := gcc
CFLAGS := -Wall -std=c99
outputA3: $(OBJ)
$(CC) $(CFLAGS) $^ -o $#
%.o: %.c helper.h headerA3.h
$(CC) $(CFLAGS) -c $< -o $#
.PHONY: clean
clean:
rm -f $(OBJ) outputA3
This assumes that the executable is outputA3 (as in your own Makefile) and not matiwosEyoelA3 (as in the error messages you show), and that all C files are part of the project. Adapt if needed.
Note: GNU make already knows how to compile and link. If you accept that your executable is named mainA3 instead of outputA3 or matiwosEyoelA3, the following should also work:
CC := gcc
CFLAGS := -Wall -std=c99
mainA3: $(patsubst %.c,%.o,$(wildcard *.c))
%.o: helper.h headerA3.h
.PHONY: clean
clean:
rm -f *.o mainA3

Related

C, Refactoring Makefile

My makefile works however if I erase debutliste.o lecturefichier.o statistiques.o tri.o
from the target compile, it still works I imagine bc they are done in the other .o targets.
Make: link
compile: listechainee.o debutliste.o lecturefichier.o statistiques.o tri.o
listechainee.o: listechainee.c listechainee.h debutliste.o
gcc -g -Wall -Wextra -std=c11 -c listechainee.c
debutliste.o: debutliste.c debutliste.h lecturefichier.o
gcc -g -Wall -Wextra -std=c11 -c debutliste.c
lecturefichier.o: lecturefichier.c lecturefichier.h statistiques.o
gcc -g -Wall -Wextra -std=c11 -c lecturefichier.c
statistiques.o: statistiques.c statistiques.h tri.o
gcc -g -Wall -Wextra -std=c11 -c statistiques.c
tri.o: tri.c
gcc -g -Wall -Wextra -std=c11 -c tri.c
clean:
rm -rf *.o
link: compile
gcc *.o -o tri
If I understand correctly I should delete the debutliste.o lecturefichier.o statistiques.o tri.o that are inside the .o targets bc they will be executed as dependencies from the target compile and it should look like this?
Make: link
compile: listechainee.o debutliste.o lecturefichier.o statistiques.o tri.o
listechainee.o: listechainee.c listechainee.h
gcc -g -Wall -Wextra -std=c11 -c listechainee.c
debutliste.o: debutliste.c debutliste.h
gcc -g -Wall -Wextra -std=c11 -c debutliste.c
lecturefichier.o: lecturefichier.c lecturefichier.h
gcc -g -Wall -Wextra -std=c11 -c lecturefichier.c
statistiques.o: statistiques.c statistiques.h
gcc -g -Wall -Wextra -std=c11 -c statistiques.c
tri.o: tri.c
gcc -g -Wall -Wextra -std=c11 -c tri.c
clean:
rm -rf *.o
link: compile
gcc *.o -o tri
Yes. If you are using GNU Make, you can simplify your makefile (per above) by relying on the fact it already has a catalog of rules. Those rules tells make how to compile c files into object files and how to link object files into a binary. The recursive flag -r for rm makes me nervous so I removed it. You probably don't need a separate link step so I use the standard all target instead of compile:
.PHONY: all clean
CFLAGS:=-g -Wall -Wextra -std=c11
all: tri
clean:
rm -f *.o ./tri
tri: listechainee.o debutliste.o lecturefichier.o statistiques.o tri.o
debutliste.o: debutliste.c debutliste.h
lecturefichier.o: lecturefichier.c lecturefichier.h
listechainee.o: listechainee.c listechainee.h
statistiques.o: statistiques.c statistiques.h
If you want to be fancy you can use a pattern rule %.o: %.c %h that says a given file .o depends on it's corresponding .c and .h files which makes the makefile quite compact:
.PHONY: all clean
CFLAGS:=-g -Wall -Wextra -std=c11
all: tri
clean:
rm -f *.o ./tri
tri: listechainee.o debutliste.o lecturefichier.o statistiques.o tri.o
%.o: %.c %h
$(CC) $(CFLAGS) $(LDFLAGS) -o $# $<
The list of object files is probably just all your c files with a different name. You can write that as:
OBJECTS:=$(patsubst %.c,%.o,$(wildcard *.c))
tri: $(OBJECTS)
However, I don't usually do that step in my projects as the build now become sensitive to temporary .c files that I often create while working.

I've created a Makefile in c that should creates more than one executable, but it does not work

WHAT I NEED TO DO
I'm trying to create a Makefile in c that should create three executable from three different .c files.
I'll want to create Lez4Es1, Lez4Es1v2 and Lez4Es3 as my executable compiling and linking in two different stages.
Something as:
gcc -std=c99 -Wall -pedantic Lez4Es1.c -c
gcc -std=c99 -Wall -pedantic Lez4Es1.o -o Lez4Es1
gcc -std=c99 -Wall -pedantic Lez4Es1v2.c -c
gcc -std=c99 -Wall -pedantic Lez4Es1.v2 -o Lez4Es1v2
gcc -std=c99 -Wall -pedantic Lez4Es3.c -c
gcc -std=c99 -Wall -pedantic Lez4Es3.o -o Lez4Es3
MY SOLUTION
Assuming to have all .c files in the same directory i created this Makefile but it does not work:
CC = gcc
CFLAGS += -std=c99 -Wall -pedantic -g
TARGETS = Lez4Es1 \
Lez4Es1v2 \
Lez4Es3 \
.PHONY: all clean cleanall
% : %.o
$(CC) $(CFLAGS) $^ -o $#
%.o : %.c
$(CC) $(CFLAGS) -c $^
all : $(TARGETS)
clean :
-rm *.o *~ core
cleanall :
-rm *.o *.txt -f $(TARGETS) *~ core
PROBLEMS
When i run $ make it creates executable from .c file and not from .o, this is output of compiler:
$ make
gcc -std=c99 -Wall -pedantic -g Lez4Es1.c -o Lez4Es1
gcc -std=c99 -Wall -pedantic -g Lez4Es1v2.c -o Lez4Es1v2
gcc -std=c99 -Wall -pedantic -g Lez4Es3.c -o Lez4Es3
How to fix to let him do the things i want to do?
There is a method to give executable files a different name than .o files?
Sorry for my bad english and if i didn't explain it well i'm ready to edit it and give you more details, thank you.
Try deleting the built-in rule that creates executables from source files:
% : %.c
(a pattern rule with no recipe cancels that rule).

R_X86_64_PC32 against undefined symbol `WinMain' on cygwin

When I compile my code on the command line, there are no problems:
$ gcc -Wall -O2 -o mess main.c getmatrix.c toktoint.c prtmatrix.c getdist.c
But when I compile via make, it fails:
$ make clean
$ make
/usr/bin/gcc -O2 -Wall -c toktoint.c -o toktoint.o
/usr/bin/gcc -O2 -Wall -c getmatrix.c -o getmatrix.o
/usr/bin/gcc -O2 -Wall -c prtmatrix.c -o prtmatrix.o
/usr/bin/gcc -O2 -Wall -c getdist.c -o getdist.o
/usr/bin/gcc -O2 -Wall -c -o main.o main.c
/usr/bin/gcc -O2 -Wall -o mess toktoint.o
/usr/lib/gcc/x86_64-pc-cygwin/10/../../../../x86_64-pc-cygwin/bin/ld: /usr/lib/gcc/x86_64-pc-cygwin/10/../../../../lib/libcygwin.a(libcmain.o): in function `main':
/usr/src/debug/cygwin-3.1.7-1/winsup/cygwin/lib/libcmain.c:37: undefined reference to `WinMain'
/usr/src/debug/cygwin-3.1.7-1/winsup/cygwin/lib/libcmain.c:37:(.text.startup+0x82): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `WinMain'
collect2: error: ld returned 1 exit status
make: *** [Makefile:44: mess] Error 1
Here is my Makefile:
CC=/usr/bin/gcc
OPTIMIZATION=2
CFLAGS=-O$(OPTIMIZATION) -Wall
LFLAGS=
TARGET=mess
OBJECTS=toktoint.o \
getmatrix.o \
prtmatrix.o \
getdist.o \
main.o
SOURCES=toktoint.c \
getmatrix.c \
prtmatrix.c \
getdist.c \
main.c
HEADERS=getmatrix.h \
toktoint.h \
prtmatrix.h \
getdist.h
all: $(TARGET)
mess: $(OBJECTS)
$(CC) $(CFLAGS) -o $# $<
%.o: %.c %.h
$(CC) $(CFLAGS) -c $< -o $#
clean:
#rm -f $(OBJECTS) $(TARGET)
I tried changing various flags, such as "-m64". And other suggestions which I found on stackoverflow, but no success.
If I compile each module on the command line, it also works:
$ make clean
$ gcc -O2 -Wall -c toktoint.c -o toktoint.o
$ gcc -O2 -Wall -c getmatrix.c -o getmatrix.o
$ gcc -O2 -Wall -c prtmatrix.c -o prtmatrix.o
$ gcc -O2 -Wall -c getdist.c -o getdist.o
$ gcc -O2 -Wall -c main.c -o main.o
$ gcc -Wall -O2 -o mess main.o getdist.o getmatrix.o prtmatrix.o toktoint.o
So it appears the problem is with make or Makefile.
Look at the output from make again, especially the linker line:
/usr/bin/gcc -O2 -Wall -o mess toktoint.o
It does not build with all the object files. Most notably, it misses main.o which I assume contains your main function.
The variable $< is only
The name of the first prerequisite
(from this make manual, emphasis mine).
To get all prerequisites (all object files) use $^:
mess: $(OBJECTS)
$(CC) $(CFLAGS) -o $# $^

error: cannot specify -o when generating multiple output files

How to fix this error?
I am trying to compile the C project, but I get such error
Alekseys-MBP:mmn14 aleksey$ make
gcc -Wall -ansi -pedantic -c -o assembler.o assembler.c
gcc -Wall -ansi -pedantic -c -o utils.o utils.c
gcc -Wall -ansi -pedantic -c -o symbol_table.o symbol_table.c
gcc -Wall -ansi -pedantic -c -o file_scan.o file_scan.c
file_scan.c:323:2: warning: no newline at end of file [-Wnewline-eof]
}
^
1 warning generated.
gcc -Wall -ansi -pedantic -c -o data_block.o data_block.c
gcc -Wall -ansi -pedantic -c -o commands.o commands.c
gcc -Wall -ansi -pedantic assembler.o utils.o symbol_table.o file_scan.o utils.h data_block.o commands.o -o assembler
clang: error: cannot specify -o when generating multiple output files
make: *** [assembler] Error 1
there is my makefile
EXEC_FILE = assembler
C_FILES = assembler.c utils.c symbol_table.c file_scan.c utils.h data_block.c commands.c
H_FILES = common.h symbol_table.h data_block.h commands.h file_scan.h
O_FILES = $(C_FILES:.c=.o)
all: $(EXEC_FILE)
$(EXEC_FILE): $(O_FILES)
gcc -Wall -ansi -pedantic $(O_FILES) -o $(EXEC_FILE)
%.o: %.c $(H_FILES)
gcc -Wall -ansi -pedantic -c -o $# $<
clean:
rm -f *.o $(EXEC_FILE)
What am I doing wrong?
This list of C files:
C_FILES = assembler.c utils.c symbol_table.c file_scan.c utils.h data_block.c commands.c
contains a header, file utils.h.
When this statement:
O_FILES = $(C_FILES:.c=.o)
constructs the list of object files, the substitution .c=.o does not alter utils.h, which results in O_FILES containing a header file. Then this build command:
gcc -Wall -ansi -pedantic $(O_FILES) -o $(EXEC_FILE)
asks GCC to do its default actions with the files, which is to link the object files and write an executable file and to “precompile” (analyze) the header file and write a “precompiled header” data file. Thus, you have two output files.
To fix this, remove utils.h from C_FILES and put it in H_FILES.

gcc builds with -o but not -o3?

My Makefile looks like this:
CC=gcc
CFLAGS=-Wall -Wextra -std=c99 -pedantic
OBJECTS=main.o Scene.o Matrix.o Vector.o Triangle.o Color.o Raster.o
render: $(OBJECTS)
$(CC) $(CFLAGS) -lm -o render -g $(OBJECTS)
rm $(OBJECTS)
clean:
rm -f render*
This builds my executable with no errors, but when I change -o to -o2 or -o3, I get the error:
gcc -Wall -Wextra -std=c99 -pedantic -c -o main.o main.c
gcc -Wall -Wextra -std=c99 -pedantic -c -o Scene.o Scene.c
gcc -Wall -Wextra -std=c99 -pedantic -c -o Matrix.o Matrix.c
gcc -Wall -Wextra -std=c99 -pedantic -c -o Vector.o Vector.c
gcc -Wall -Wextra -std=c99 -pedantic -c -o Triangle.o Triangle.c
gcc -Wall -Wextra -std=c99 -pedantic -c -o Color.o Color.c
gcc -Wall -Wextra -std=c99 -pedantic -c -o Raster.o Raster.c
gcc -Wall -Wextra -std=c99 -pedantic -lm -o3 render -g main.o Scene.o Matrix.o Vector.o Triangle.o Color.o Raster.o
gcc.exe: error: render: No such file or directory
make: *** [render] Error 1
There could be some error in my code detected by the optimization flags, but as I don't get any error messages before this it's hard to know what's going wrong. I'm using MinGW/MSYS on Windows 7.
-o render means create the output file with the name render.
Now you are changing this -o to -o3 which is incorrect. Instead you need to keep -o render as it is and add a -O3 flag for optimization. Note the capital letter O.
-o is the output file flag. You were thinking of -O (capital).

Resources