I'm trying to get a small project compiled but am getting this error, I've been searching around and people get this error mainly because of incorrect file extension, but I don't really think that's the cause here:
gcc -c -W -Wall -ggdb -I. router.c -o router.o
router.c:106: warning: unused parameter ‘hname’
router.c: In function ‘flood_neighbors’:
router.c:464: warning: unused variable ‘bytes_rcvd’
router.c: At top level:
router.c:536: warning: unused parameter ‘fd’
gcc -c -W -Wall -ggdb -I. link_info.h -o link_info.o
gcc -c -W -Wall -ggdb -I. route.h -o route.o
gcc -c -W -Wall -ggdb -I. sequence.h -o sequence.o
gcc -W -Wall -ggdb -I. router.o link_info.o route.o sequence.o -o router
link_info.o: file not recognized: File format not recognized
collect2: ld returned 1 exit status
make: *** [router] Error 1
and my make file looks like:
CC = gcc
INC = -I.
FLAGS = -W -Wall -ggdb
router: router.o link_info.o route.o sequence.o
$(CC) $(FLAGS) $(INC) $^ -o $#
router.o: router.c
$(CC) -c $(FLAGS) $(INC) $< -o $#
sequence.o: sequence.h sequence.h
$(CC) -c $(FLAGS) $(INC) $< -o $#
link_info.o: link_info.h link_info.c
$(CC) -c $(FLAGS) $(INC) $< -o $#
route.o: route.h route.c
$(CC) -c $(FLAGS) $(INC) $< -o $#
What I'm confused on is the rules for three object files are of the same format, but why only the link one yells? Thanks a lot!
I would like to suggest few edits in your makefile.
CC = gcc
INC = -I.
FLAGS = -W -Wall -ggdb
router: router.o link_info.o route.o sequence.o
$(CC) $(FLAGS) $(INC) $^ -o $#
router.o: router.c
$(CC) -c $(FLAGS) $(INC) $< -o $#
sequence.o: sequence.h sequence.h //Where is the c file ?
$(CC) -c $(FLAGS) $(INC) $< -o $#
link_info.o: link_info.h link_info.c //Change the order. Put c file first and then the header
$(CC) -c $(FLAGS) $(INC) $< -o $#
route.o: route.h route.c //Same as above
$(CC) -c $(FLAGS) $(INC) $< -o $#
With recent versions of make you can remove all the object rules because make uses a default rule to build an object from .c or .cpp files. Just leave the rule to build the final executable in place.
For example, change the file so it contains this line only:
router: router.o link_info.o route.o sequence.o
$(CC) $(FLAGS) $(INC) $^ -o $#
Move link_info.o to the end of the list in the router: dependencies and I suspect you'll blow up on route.o instead.
You seem to be compiling a headers as C files. I have no idea what GCC does in that case. In your makefile rules, the .c file must be the first dependency if you are going to use $< to generate the source file to compile.
The link_info: and route: rules have the .c and .h files reversed and the sequence: rule lists the .h file twice!
Related
I am trying to make a C program and have the following makefile:
CC=clang
CFLAGS=-std=c99 -Wall -pedantic
LDFLAGS=
LDLIBS=
OUT=nes_slop
SRC_DIR=src/
OBJ_DIR=obj/
SRCS=$(wildcard $(SRC_DIR)*.c)
OBJS=$(addprefix $(OBJ_DIR),$(notdir $(SRCS:.c=.o)))
MAKE=make
CLEAR=TRUE
all: clean $(OUT)
clean:
rm -i $(OUT) $(OBJS) -f
$(OUT): $(OBJS)
$(CC) $(CFLAGS) $(OBJS) -o $(OUT)
$(OBJS): $(SRCS)
$(CC) -c $(CFLAGS) $(LDLIBS) $< -o $#
It was all well and good until I had more than 1 .c file:
clang -c -std=c99 -Wall -pedantic -lncurses src/gamestate.c -o obj/gamestate.o
clang -c -std=c99 -Wall -pedantic -lncurses src/gamestate.c -o obj/main.o
so, somehow the source file is not being updated, it's always gamestate.c... what's wrong with my makefile? any help is appreciated, thank you
In short, your rule should look something like this:
$(OBJS): %.o: %.c
$(CC) -c $(CFLAGS) $(LDLIBS) $< -o $#
You may also want to read this for how to generate automatic dependencies (so if you change a header file, your c files will automatically regenerate as needed) There's a TL;DR section at the top of that page, if you're not interested in the details.
I am new to c programming, and I am having a problem with making Makefile for it.
I did like
CC = gcc
CFLAGS = -fsanitize=address -g -Wall -Wvla
OUTPUT = prac
all: $(OUTPUT)
mymalloc.o: mymalloc.c mymalloc.h
$(CC) $(CFLAGS) -c $# mymalloc.c
%: %.c
$(CC) $(CFLAGS) -o $# mymalloc.o $^
and I try to make file with just typing "make"
But it keep says
gcc -fsanitize=address -g -Wall -Wvla -o prac mymalloc.o prac.c
clang: error: no such file or directory: 'mymalloc.o'
make: *** [prac] Error 1
whenever I try to make it , did I do something wrong?
Thank you.
Edit)
I got it right with using this!
CC = gcc
CFLAGS = -fsanitize=address -g -Wall -Wvla
DEPS = mymalloc.h
OBJS = prac.o mymalloc.o
%.o: %.c $(DEPS)
$(CC) $(CFLAGS) -c -o $# $<
prac: $(OBJS)
$(CC) $(CFLAGS) -o $# $^
You need to make the executable dependent on mymalloc.o:
%: %.c mymalloc.o
$(CC) $(CFLAGS) -o $# mymalloc.o $^
The dependency tells make that it needs to execute the rule for creating mymalloc.o.
Also your rule for making mymalloc.o is wrong. You need -o before $#:
mymalloc.o: mymalloc.c mymalloc.h
$(CC) $(CFLAGS) -c -o $# mymalloc.c
Otherwise it's trying to use the output file as one of the input files.
I'm trying to change my makefile to redirect the .o to a lib folder (and have the .c in a src folder). I would also like the executables to be at the same level as the makefile.
As for the .h, I have no idea where to put it!
CC = gcc
CFLAGS = -std=c11 -Wpedantic -Wall -Wextra -Wconversion -Werror -fPIC -pthread -D_XOPEN_SOURCE=500 -fstack-protector
LDLIBS = -lrt
RM = rm -f
ARFLAGS = rs
all: server client info_proc info_user
server: server.o header.o
$(CC) $(CFLAGS) -o $# $^ $(LDLIBS)
server.o: server.c header.h
gcc -c server.c
client: client.o header.o
$(CC) $(CFLAGS) -o $# $^ $(LDLIBS)
client.o: client.c header.h
header.o: header.c header.h
gcc -c header.c
info_proc: info_proc.o
info_proc.o: info_proc.c
gcc -c info_proc.c
info_user: info_user.o
info_user.o: info_user.c
gcc -c info_user.c
rmpipe:
$(RM) question_pipe
clean:
$(RM) server client info_proc info_user question_pipe *.o *~$
You could do something like this:
all: main
main: lib/a.o lib/b.o lib/main.o
$(CC) $(CFLAGS) -o $# $^
lib/a.o: a.c
$(CC) $(CFLAGS) -c -o $# $<
lib/b.o: b.c
$(CC) $(CFLAGS) -c -o $# $<
lib/main.o: main.c
$(CC) $(CFLAGS) -c -o $# $<
Or instead of writing your own Makefile you could use one of these build
tools:
GNU Autotools
Cmake
SCons
which on the long run are much easier to maintain than a self-written
Makefile.
I am making my first Makefile for a simple shell system. I need to make library files but for some reason the library section is not working out. In the error message it says the library files do no exist (obviously).
Am I missing something obvious that could fix this? Also, is there any other way I can make this Makefile more efficient?
# Beginning of Makefile
OBJS = obj/shutil.o obj/parser.o obj/sshell.o obj/history.o obj/hash_table.o obj/variables.o
HEADER_FILES = include/shell.h include/parser.h include/history.h include/hash_table.h include/variables.h
EXECUTABLE = sshell
LIBS = lib/libshell.so lib/libparser.so lib/libhistory.so lib/libhash_table.so lib/libvariables.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
#Create the library files
$(LIBS): $(OBJS)
$(CC) $(LIBCFLAGS) -shared -o $(LIBS) $(OBJS)
#Recursively build object files
obj/%.o: src/%.c
$(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
-rm -f .sshell_history.txt
run: $(EXECUTABLE)
(export LD_LIBRARY_PATH=lib; ./$(EXECUTABLE))
# End of Makefile
Thanks!
-Lily Banks
Edit:
Before I tried to change it, here is what I had with regards to library files.
$(LIBS): $(OBJS)
$(CC) -shared -o lib/libparser.a obj/parser.o
$(CC) -shared -o lib/libshell.a obj/shutil.o
$(CC) -shared -o lib/libhistory.a obj/history.o
$(CC) -shared -o lib/libhash_table.a obj/hash_table.o
$(CC) -shared -o lib/libvariables.a obj/variables.o
The problem with this was that it compiled each file five times which is not efficient at all. So what I was trying to do was do it all in one go.
Edit2:
#Create the library files
lib/libparser.so: obj/parser.o
$(CC) $(LIBFLAGS) -shared lib/libparser.a -o $#
lib/libshell.so: obj/shutil.o
$(CC) $(LIBFLAGS) -shared lib/libshell.a -o $#
lib/libhistory.so: obj/history.o
$(CC) $(LIBFLAGS) -shared lib/libhistory.a -o $#
lib/libhash_table.so: obj/hash_table.o
$(CC) $(LIBFLAGS) -shared lib/libhash_table.a -o $#
lib/variables.so: obj/variables.o
$(CC) $(LIBFLAGS) -shared lib/libvariables.a -o $#
Unfortunately, here is the error I am getting:
make: *** No rule to make target `lib/libvariables.so', needed by `sshell'. Stop.
Thoughts?
Edit3:
#Create the library files
lib/libparser.so: obj/parser.o
$(CC) $(LIBFLAGS) -shared $^ -o lib/libparser.a
lib/libshell.so: obj/shutil.o
$(CC) $(LIBFLAGS) -shared $^ -o lib/libshell.a
lib/libhistory.so: obj/history.o
$(CC) $(LIBFLAGS) -shared $^ -o lib/libhistory.a
lib/libhash_table.so: obj/hash_table.o
$(CC) $(LIBFLAGS) -shared $^ -o lib/libhash_table.a
lib/libvariables.so: obj/variables.o
$(CC) $(LIBFLAGS) -shared $^ -o lib/libvariables.a
This works but is there anything else I need to change? Thanks
You need one set of object files for each library. And the -o flag only takes one argument which is the output file, you are trying to output all the library files which you cannot do with one invocation of gcc.
You need to do something like:
lib/libshell.so: obj/sshell.o
$(CC) $(LIBFLAGS) -shared obj/sshell.o -o lib/libshell.so
lib/libparser.so: obj/parser.o
$(CC) $(LIBFLAGS) -shared obj/parser.o -o lib/libparser.so
for each of the libraries.
This line is completely wrong:
$(LIBS): $(OBJS)
$(CC) $(LIBCFLAGS) -shared -o $(LIBS) $(OBJS)
If you expanded all the variables, this line would look like this (adding line breaks for clarity):
lib/libshell.so lib/libparser.so lib/libhistory.so lib/libhash_table.so lib/libvariables.so: \
obj/shutil.o obj/parser.o obj/sshell.o obj/history.o obj/hash_table.o obj/variables.o
gcc -Wall -D_REENTRANT -fPIC -shared -o lib/libshell.so lib/libparser.so lib/libhistory.so \
lib/libhash_table.so lib/libvariables.so obj/shutil.o obj/parser.o obj/sshell.o obj/history.o \
obj/hash_table.o obj/variables.o
Which, it should be clear, is very not right. It's so not right I can't even really tell what you're trying to accomplish. Do you really want to create one shared library for every .o file, where each shared library contains a single .o? If so why are you trying to link both the .o files AND the shared libraries into a single executable?
If you explain what you are really trying to do, at a higher level, we can help.
I am trying to compile my project after adding a new source(processHandling.c) and I am getting this as a result when I 'make'
gcc -gstabs -W -Wall -std=gnu99 -c main.c
gcc -gstabs -W -Wall -std=gnu99 -c inputHandling.c
gcc -gstabs -W -Wall -std=gnu99 -c syscallsWrapper.c
gcc -gstabs -W -Wall -std=gnu99 -o myShell main.o inputHandling.o processHandling.o syscallsWrapper.o
gcc: error: processHandling.o: No such file or directory
make: *** [myShell] Error 1
This is the makefile
CC = gcc
CFLAGS = -gstabs -W -Wall -std=gnu99
myShell: main.o inputHandling.o syscallsWrapper.o
$(CC) $(CFLAGS) -o myShell main.o inputHandling.o processHandling.o syscallsWrapper.o
main.o: main.c
$(CC) $(CFLAGS) -c main.c
inputHandling.o: inputHandling.c
$(CC) $(CFLAGS) -c inputHandling.c
processHandling.o: processHandling.c
$(CC) $(CFLAGS) -c processHandling.c
syscallsWrapper.o: syscallsWrapper.c
$(CC) $(CFLAGS) -c syscallsWrapper.c
clean:
-rm myShell *.o
I tried running make with the -d flag and it seems make for some reason is totally ignoring the rule to compile processHandling.o; what could the problem be?
Also note that if I compile processHandling manually using gcc -c everything works fine.
Add processHandling.o to the dependency list for the myShell target:
myShell: main.o inputHandling.o processHandling.o syscallsWrapper.o
$(CC) $(CFLAGS) -o myShell main.o inputHandling.o processHandling.o syscallsWrapper.o
By the way, using automatic variables can help reduce the repeated file names. For example:
myShell: main.o inputHandling.o processHandling.o syscallsWrapper.o
$(CC) $(CFLAGS) -o $# $^
You need to add "processHandling.o" as a prerequisit of myShell. Otherwise when making myShell, the rule for processHandling.o will not be applied because the makefile thinks that that processHandling.o is not needed for myShell. You can simply add it like this
myShell: main.o inputHandling.o syscallsWrapper.o processHandling.o
$(CC) $(CFLAGS) -o myShell main.o inputHandling.o processHandling.o syscallsWrapper.o
Check if you really have the file processHandling.c. This error implies that the source file has not been found.