what does "linker input file unused because linking not done" means - c

hi im trying to create a shared object for my native library to be accessed by my java project but when i run the makefile i get the error unable to link
here's my makefile
LIB_FILE = ../lib/libpktartintf.so
SRCS := $(wildcard *.c)
OBJS := $(SRCS:.c=.o)
DEPS := $(OBJS:.o=.d)
CC = gcc
INCFLAGS = -I../include
CFLAGS += $(INCFLAGS) -Wall -MMD -MP
LDFLAGS = -shared
$(LIB_FILE): $(OBJS)
$(CC) -c $(LDFLAGS) $(CFLAGS) -o $# $<
.PHONY: clean
clean:
rm -f *.o *.d $(LIB_FILE)
-include $(DEPS)
when I "make" it im getting the following error
gcc -c -shared -I../include -Wall -MMD -MP -o ../lib/libpktartintf.so pktartintf.o
gcc: warning: pktartintf.o: linker input file unused because linking not done
any idea why

Related

"clang: error: cannot specify -o when generating multiple output files" fix

I'm trying to compile my C project using clang (I'm on MacOS Monterry) and a Makefile, but I keep getting the same error from clang in the command line:
> make
gcc -c src/ji.c src/main.c -o src/ji.o
clang: error: cannot specify -o when generating multiple output files
make: *** [src/ji.o] Error 1
These are the only files I have in the project so far:
src/main.c
src/ji.c
include/ji.h
The Makefile looks like this:
cc = gcc
src = $(wildcard src/*.c)
obj = $(src:.c=.o)
exec = ji
$(exec): $(obj)
$(cc) -Iinclude $< -o build/$#
%.o: %.c
$(cc) -c $(src) -o $#
clean:
-rm src/*.o
-rm ji
From YouTube videos I've seen, this should be the ideal Makefile for the project but no matter what I change I get the error.
There are a few issues:
-Iinclude needs to be on the %.o: %.c rule command
In %.o: %.c, we don't want $(src) but rather $<
We want patsubst to get the .o list obj
The $(exec) target doesn't match the -o option
The clean doesn't match the placement of the executable
Here's a refactored version (e.g. one way to do this--there are others):
cc = gcc
src = $(wildcard src/*.c)
obj = $(patsubst %.c,%.o,$(src))
exec = build/ji
$(exec): $(obj)
mkdir -p build
$(cc) $^ -o $#
%.o: %.c
$(cc) -c $< -o $# -Iinclude
clean:
rm -f src/*.o
rm -fr build
Here's the output of make:
gcc -c src/ji.c -o src/ji.o -Iinclude
gcc -c src/main.c -o src/main.o -Iinclude
mkdir -p build
gcc src/ji.o src/main.o -o build/ji
Here's the output of make clean:
rm -f src/*.o
rm -fr build

Makefile compilation warning (libftprintf.a the table of contents is empty (no object file members in the libr ary define global symbols)

I am trying to compile my Makefile to make library from different directories. The library is successfully compiled but I am facing the following warning
/Applications/Xcode.app/Contents/Developer/usr/bin/make -C ./libft
make[1]: Nothing to be done for `all'.
gcc -Wall -Werror -Wextra -c srcs/ft*.c libft/ft*.c -I ./includes
ar rcs libftprintf.a srcs/ft*.c libft/ft*.c*****
warning: /Applications/Xcode.app/Contents/Developer/Toolchains/Xcod
eDefault.xctoolchain/usr/bin/ranlib: archive library: libftprintf.a
the table of contents is empty (no object file members in the libr
ary define global symbols)
Please kindly advise on how to solve this warning. The structure of my directory is as follow:
steh#u90z01s01 printf % ls
Makefile includes main.c libft srcs
My Makefile is as following
NAME := libftprintf.a
CC := gcc
AR := ar rcc
CFLAGS:= -Wall -Werror -Wextra -c
SRCS = srcs/ft*.c libft/ft*.c
INCLUDES = ./includes
OBJ_FILES = $(SRCS:%.c = %.o)
$(NAME): $(OBJ_FILES)#.fr
$(MAKE) -C ./libft
$(CC) $(CFLAGS) $(SRCS) -I $(INCLUDES)
$(AR) $(NAME) $(OBJ_FILES)
all: $(NAME)
clean:
#echo "Cleaning..."
rm -rf $(NAME) ft*.o
fclean:
rm -rf $(NAME)
re: fclean all
norm:
#norminette $(LIB_FILES)
.PHONY: clean fclean all re norm
This is my latest code
NAME := libftprintf.a
CC := gcc
AR := ar rcs
CFLAGS := -Wall -Werror -Wextra -c
SRCS = ./libft/ft*.c ./srcs/ft*.c
OBJS = ft*.o
LIBFT = ./libft
INC = ./includes
# Colors
GREEN= \033[1;32m
RED= \033[1;31m
all: $(NAME)
$(NAME):
#make re -C $(LIBFT)
#$(CC) $(CFLAGS) $(SRCS) -I $(INC)
#$(AR) $(NAME) $(OBJS)
#ranlib $(NAME)
#echo "$(GREEN)ft_printf compiled!"

Adding a different object directory for Make

I want my make file to ouput (Object files .o) to a different subdirectory for example OBJECTS_DIR="./build"
I also want my .exe to be placed in DIST_DIR="./dist"
My make file below works(compiles & links) but in the same path.
# vars
CXX = g++
CXXFLAGS = -c89 -Wall -g
CC = gcc
CFLAGS = -Wall -g
SOURCES_C = main.c A.c B.c C.c D.c E.c
INCLUDES=
OBJECTS_DIR=./build
DIST_DIR=./dist
PROGRAM = main
OBJECTS = $(SOURCES_C:.c=.o)
debug := CFLAGS
all debug: $(PROGRAM)
$(PROGRAM): $(INCLUDES) $(OBJECTS)
$(LINK.c) -o $# $(OBJECTS)
clean:
rm -f $(PROGRAM) $(OBJECTS)
How can I achieve outputing .o files to OBJECTS_DIR and then linking from OBJECTS_DIR & outputing the .exe to DIST_DIR.
Updated based on user recommendations:
# vars
CXX = g++
CXXFLAGS = -Wall -g
CC = gcc
CFLAGS = -std=c89 -Wall -g
SOURCES_C = main.c A.c B.c C.c D.c E.c
OBJECTS_DIR := build
OBJECTS := $(SOURCES_C:%.c=$(OBJECTS_DIR)/%.o)
INCLUDES :=
DIST_DIR := dist
PROGRAM := $(DIST_DIR)/main
OBJECTS = $(SOURCES_C:.c=.o)
debug := CFLAGS
all debug: $(PROGRAM)
$(PROGRAM): $(INCLUDES) $(OBJECTS)
$(CC) -o $# $(OBJECTS)
clean:
rm -f $(PROGRAM)
rm -f $(OBJECTS)
I updated my Make & its works as expected.I have always relied on the IDE's to generate my Makefile.
1) Is there any issues that Im not aware of?
2) What is the point of the .PHONY (Still not getting that).
Thanks
The following makefile has not been tested
Note the use of ':=' for defining macros, so the macro only needs to be evaluated once
Note: the '.PHONY:' statements are to tell make that no file with the associated name (clean, all) will be generated
edited per Chris Dodd comments
CC := /usr/bin/gcc
RM := /bin/rm
CFLAGS := -Wall -g -Wextra -Wconversion -pedantic -std=gnu11
SOURCES_C := main.c A.c B.c C.c D.c E.c
OBJECTS_DIR := build
DIST_DIR := dist
PROGRAM := $(DIST_DIR)/main
OBJECTS := $(SOURCES_C:.c=$(OBJECTS_DIR)/%.o)
.PHONY: all
all: $(PROGRAM)
$(PROGRAM): $(OBJECTS)
$(CC) -o $# $(OBJECTS)
$(OBJECT_DIR)/%.o:%.c
$(CC) $(CFLAGS) -c %$< -o $#
.PHONY: clean
clean:
rm -f $(PROGRAM)
rm -f $(OBJECTS)

Makefile: wildcard and patsubst does not change file source names

I am trying to write a Makefile for my project, all the *.c and *.h files are in a folder called src, and the Makefile looks like this --
CC := gcc
CFLAGS := -g -Wall -ansi -pedantic -std=gnu99
LDFLAGS := -lm
INCLUDES := $(wildcard src/*.h)
IFLAGS := $(addprefix -I/,$(INCLUDES))
SRC := $(wildcard src/*.c)
OBJS := $(patsubst %.c, %.o, $(SRC))
APP := app
all: $(OBJS)
$(APP): $(OBJS)
$(CC) $(CFLAGS) $< -o $# $(LDFLAGS)
$(OBJS): $(SRC) $(INCLUDES)
$(CC) $(CFLAGS) $(IFLAGS) -c $< -o $#
clean:
rm -rf $(OBJS)
rm -rf *.out
rm -f $(APP)
At this point I am not building the executable, just trying to compile them to object files, so when I run, I am getting this output --
gcc -g -Wall -ansi -pedantic -std=gnu99 -I/src/structure.h -I/src/rng.h -c src/allocate.c -o src/allocate.o
gcc -g -Wall -ansi -pedantic -std=gnu99 -I/src/structure.h -I/src/rng.h -c src/allocate.c -o src/auxiliary.o
gcc -g -Wall -ansi -pedantic -std=gnu99 -I/src/structure.h -I/src/rng.h -c src/allocate.c -o src/decode.o
gcc -g -Wall -ansi -pedantic -std=gnu99 -I/src/structure.h -I/src/rng.h -c src/allocate.c -o src/display.o
You can see that in each gcc invocation, the source file names do not change, they are all always src/allocate.c why ? However, the object names are correctly expanded like src/allocate.o, src/auxiliary.o and src/decode.oetc.
It seems you've mixed up some things here.
They are basically two type of rules you need to use here, and they both share the same syntax:
targets : prerequisites
recipe
When you write this:
$(APP): $(OBJS)
$(CC) $(CFLAGS) $< -o $# $(LDFLAGS)
You're saying to make that you want to create $(APP), and to do that you need $(OBJS) to exist or to be created.
Now when you write this:
$(OBJS): $(SRC) $(INCLUDES)
$(CC) $(CFLAGS) $(IFLAGS) -c $< -o $#
You're telling make you want to create a list of .o files, and for each individual file that you need all $(SRC) and $(INCLUDES).
Since in the recipe you're using $<, which is a shortcut for the first entry in the prerequisites list, you always end up with the same source file being compiled.
To do what you want, you must abstract things a little bit and tell make "Here is how I want you to build any .o file that depends on a corresponding .c". That is the job of pattern rules:
%.o: %.c
$(CC) $(CPPFLAGS) $(CFLAGS) -o $# -c $<
Ultimately, your Makefile should look like this:
APP := app
SRC := $(wildcard src/*.c)
OBJ := $(SRC:.c=.o)
CFLAGS := -W -Wall -g -std=c99 -pedantic
LDLIBS := -lm
all: $(OBJS)
$(APP): $(OBJ)
$(CC) $(LDFLAGS) $^ $(LDLIBS) -o $#
clean:
$(RM) $(APP) $(OBJ)
Note another couple of things here that you missed:
The -I preprocessor flag (that should be placed in the CPPFLAGS variable) accept a directory, not a file.
The -ansi compiler flag is a synonym of -std=c89. You're using -std=gnu99 right after so that one will be picked ultimately
You don't need to list your header files at all. Don't bother.
Don't use the -r flag of the rm command without care, you'll end up removing folders. It is not used to remove multiple files but to remove recursively, read up your man.
You used $< instead of $^ at the linking phase, so your executable will miss many object files.
To address the comments:
GNU make has a lot of predefined rules, functions and variables that you should be using before rolling your own. It has basic rules for compiling and linking C and C++ programs, among other, this is why your Makefile does not need te redefine the %.o: %c rule that already exists.
You can see all of these by typing this in your favorite shell:
$ make -p > predefined.mk
$(RM), $(CC) are one of these predefined variables, you can see by yourself what they actually contain.
Now, as many users are concerned with header files dependencies, let's adress this issue. You won't have to manually do that, modern compilers like GCC and Clang do this for you once you set them up.
The dependencies for each .c file will be generated in a .d file that must be included in the Makefile.
To tell the compiler to generate these files while compiling, you need to pass a preprocessor flag:
CPPFLAGS := -MMD
Now the dependencies are auto-generated, we need to include them:
DEP := $(OBJ:.o=.d)
-include $(DEP)
You'd also want to clean them:
clean:
$(RM) $(APP) $(OBJ) $(DEP)
Now your Makefile looks like this:
APP := app
SRC := $(wildcard src/*.c)
OBJ := $(SRC:.c=.o)
DEP := $(OBJ:.o=.d)
CPPFLAGS := -MMD
CFLAGS := -W -Wall -g -std=c99 -pedantic
LDLIBS := -lm
all: $(OBJS)
$(APP): $(OBJ)
$(CC) $(LDFLAGS) $^ $(LDLIBS) -o $#
clean:
$(RM) $(APP) $(OBJ) $(DEP)
-include $(DEP)
Last point: the syntax $(SRC:.c=.o) is a shortcut for $(SRC:%.c=%.o) which is also a shortcut for $(patsubst %.c,%.o,$(SRC)).

Sample makefile for gcc

Is there any sample makefile project that only consists of .c and .h files?
I am using gcc, Windows 8.1
I found this, but it does not work:
#########################
# customise these
CFILES := sampleA.c main.c sampleB.
PROG := prog
CFLAGS := -Wall -Wextra -g
LDFLAGS :=
########################
# -MMD generates dependencies while compiling
CFLAGS += -MMD
CC := gcc
OBJFILES := $(CFILES:.c=.o)
DEPFILES := $(CFILES:.c=.d)
$(PROG) : $(OBJFILES)
$(LINK.o) $(LDFLAGS) -o $# $^
clean :
rm -f $(PROG) $(OBJFILES) $(DEPFILES)
-include $(DEPFILES)
I get the following error:
undefined reference to sendto#24,socket#12,inte_addre#4, htons#04,bind#12, select#20,recvfrom#24, WSAGetLastError#0,WSAStartup#8,ioctlsocket#12
You can refer the below Makefile
exe ?= prog
CC = gcc
CFLAGS = -g -Wall -Wextra -MMD
LDFLAGS =
all: $(exe)
$(exe) : sampleA.c sampleB.c main.c
$(CC) $(CFLAGS) $^ -o $#
clean:
-rm $(exe)
Here prog is output executable at the end of make.
You are missing some required library, wsock32 and ws2_32 if I'm not mistaken.
Use this Makefile:
EXE := prog.exe
SRC := $(wildcard *.c)
OBJ := $(SRC:.c=.o)
DEP := $(OBJ:.o=.d)
CC := gcc
CPPFLAGS := -MMD -MP
CFLAGS := -W -Wall -g
LDFLAGS :=
LDLIBS := -lwsock32 -lws2_32
.PHONY: all clean fclean re
all: $(EXE)
$(EXE): $(OBJ)
$(CC) $(LDFLAGS) $^ $(LDLIBS) -o $#
clean:
$(RM) $(OBJ) $(DEP)
fclean: clean
$(RM) $(EXE)
re: fclean all
-include $(DEP)

Resources