GCC Linking with .o file - c

I'm trying to compile my code but it isn't working. I got this to compile at school but I can't compile this on my home computer. I can't seem to figure out why. I need this error fixed in order to continue my assignment. Also, this list.o file is the profs file. I have to use this file.
Solutions I've tried kind of?
I've updated gcc to gcc-7.
I've located libc.a
/usr/lib/x86_64-linux-gnu/libc.a
/usr/share/doc/libklibc/README.klibc.arch
Edit: I have tried compiling without -fPIC
gcc -m64 -pthread -Wall -std=c99 -o run main.o as2.o list.o
/usr/bin/ld: list.o: relocation R_X86_64_32S against undefined symbol...
This is from the terminal:
gcc -m64 -pthread -Wall -std=c99 -fPIC -o run main.o as2.o list.o
/usr/bin/ld: list.o: relocation R_X86_64_32S against undefined symbol `headlist' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Nonrepresentable section on output
collect2: error: ld returned 1 exit status
This is my make file:
CC = gcc
CFLAGS = -m64 -pthread -Wall -std=c99 -fPIC
PROG = run
OBJS = main.o as2.o list.o
run: $(OBJS)
$(CC) $(CFLAGS) -o $(PROG) $(OBJS)
main.o: main.c list.h as2.h
$(CC) $(CFLAGS) -c main.c
as2.o: as2.c as2.h list.h
$(CC) $(CFLAGS) -c as2.c
clean:
rm main.o as2.o run
This is my includes:
#include <netinet/in.h>
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include "list.h"
#include "as2.h"
Any ideas/solutions?

EDIT:
changed the spelling from LFLAGS to LDFLAGS to appease some comment.
EDIT:
moved the -c option to appease some comment.
Note: all is normally the first target in a make file.
Note: used := rather than = so the macros would only be evaluated once.
Note: the list.o is already available in the current directory (per the OPs question) so is not compiled in the makefile. But is only linked with the other object files to produce the executable
your makefile seems to have a few oversights. Suggest:
CC := gcc
RM := rm -f
CFLAGS := -ggdb -m64 -pthread -Wall -Wextra -pedantic -std=c99
#LDFLAGS := <-- use the default value
PROG := run
OBJS := main.o as2.o list.o
HDRS := list.h as2.h
.PSEUDO: all clean
all: $(PROG)
$(PROG): $(OBJS)
$(CC) -ggdb -o $(PROG) $(OBJS) $(LDFLAGS)
main.o: main.c $(HDRS)
$(CC) $(CFLAGS) -c main.c -o main.o -I.
as2.o: as2.c $(HDRS)
$(CC) $(CFLAGS) -c as2.c -o as2.o -I.
clean:
$(RM) main.o as2.o run

Related

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 $# $^

Unable to compile with gsl on Mac

I am trying to implement gsl_rng.h on a Montecarlo simulation on my MacBook Pro (13-inch, Mid 2012). The simulation is all written in C. My problem is that gcc-6 complains it cannot find the gsl library despite the compilation flags which I think are fine.
The top of declare.h, which is included in all .c files I am working on:
/* __________________ LIBRARIES ___________________*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <gsl/gsl_rng.h>
The error:
fatal error: gsl/gsl_rng.h: No such file or directory
The compilation flags included in my makefile:
INCLUDE = -I/usr/local/Cellar/gsl/2.4/include
LINK = -L/usr/local/Cellar/gsl/2.4/lib -lgsl -lgslcblas
I installed both gcc-6 and gsl via Homebrew.
How can I make gcc-6 find gsl? Are my flags wrong?
The makefile:
CC = g++-6
CFLAGS = -lm -O3 -ansi -pedantic -Wall -Wextra\
-Wconversion -Wredundant-decls -fmax-errors=7\
-Wunsafe-loop-optimizations -Wmissing-braces\
-Wparentheses
# -Wdouble-promotion
INCLUDE = -I/usr/local/Cellar/gsl/2.4/include
LINK = -L/usr/local/Cellar/gsl/2.4/lib -lgsl -lgslcblas
../bin/bidimensional_MC: random.o functions.o subroutines.o\
main.o
$(CC) -o ../bin/bidimensional_MC random.o functions.o\
subroutines.o main.o $(CFLAGS) $(LINK) $(INLCUDE)
random.o: random.c
$(CC) -c random.c -lm -O3 $(CFLAGS) $(INCLUDE)
functions.o: functions.c
$(CC) -c functions.c $(CFLAGS) $(INCLUDE)
main.o: main.c
$(CC) -c main.c $(CFLAGS) $(INCLUDE)
suboutines.o: subroutines.c
$(CC) -c subroutines.c $(CFLAGS) $(INCLUDE)
clean:
rm *.o
The output of ls /usr/local/Cellar/gsl/2.4/include/gsl/ is:
/usr/local/Cellar/gsl/2.4/include/gsl/gsl_rng.h
The output of ls /usr/local/Cellar/gsl/2.4/include/ is:
gsl/
The output of ls /usr/local/Cellar/gsl/2.4/include/gsl/ is too long to post, but everything is there, as it should.
EXTRA INFORMATION:
I am using g++-6 instead of gcc-6 because the cluster in which I'm going to finally execute the simulation requires code to be C++ compliant.
In the makefile, you have (or, more precisely, at one time claimed to have):
random.o: random.c
$(CC) -c random.c -lm -O3 $(CFLAGS)
You shouldn't specify the library when compiling the object file. Your CFLAGS do not include the ${INCLUDE} (or $(INCLUDE)) macro. You need something like:
random.o: random.c
$(CC) -c random.c -O3 $(CFLAGS) $(INCLUDE)
This is a minimal change; I'd add $(INCLUDE) to CFLAGS (and remove the -lm again — you don't even need that on a Mac though it does no specific harm). I'd also add -Werror -Wmissing-prototypes -Wstrict-prototypes, and using -ansi (aka -std=c90) isn't sensible — it is an archaic standard. You should be using -std=c11.
CFLAGS = -O3 -g -std=c11 -pedantic -Wall -Wextra \
-Wconversion -Wredundant-decls -fmax-errors=7 \
-Wunsafe-loop-optimizations -Wmissing-braces \
-Wparentheses $(INCLUDE) \
-Werror -Wmissing-prototypes -Wstrict-prototypes
Also, I added -g to get debugging code. Always include -g, even with optimization. It doesn't have a run-time cost; it does have a benefit if you need to debug the code. Granted, it isn't as easy to debug optimized code, but you can do more than if you don't have -g. Include it in both the 'compilation to object' and the 'linking' phases.
(And, in point of detail, I'd have a bunch of separate macros so that each flag can be turned on or off independently, rather than having to rewrite the whole of CFLAGS. However, that can await another day.)

What does "linker input file unused because linking not done" mean? (C makefile)

I have created a makefile to compile and link my program, however, I can't figure out why I am getting this error. Is it to do with SDL?
GCC = gcc
CFLAGS = -c -std=c99 -lm -Wall -Wextra -pedantic -O3 -Wfloat-equal -g
SDL = -lSDL2 -lSDL2_ttf -lSDL2_image -lSDL2_mixer
all: ./game
game: global.o display.o player.o entities.o controls.o sound.o menu.o
$(GCC) $(CFLAGS) global.o display.o player.o entities.o controls.o sound.o menu.o -o game
global.o: global.c
$(GCC) $(CFLAGS) $(SDL) global.c
display.o: display.c
$(GCC) $(CFLAGS) $(SDL) display.c
player.o: player.c
$(GCC) $(CFLAGS) $(SDL) player.c
entities.o: entities.c
$(GCC) $(CFLAGS) $(SDL) entities.c
controls.o: controls.c
$(GCC) $(CFLAGS) $(SDL) controls.c
sound.o: sound.c
$(GCC) $(CFLAGS) $(SDL) sound.c
menu.o: menu.c
$(GCC) $(CFLAGS) $(SDL) menu.c
clean:
rm *o game
Your linking command expands to:
gcc -c -std=c99 -lm -Wall -Wextra -pedantic -O3 -Wfloat-equal -g global.o display.o player.o entities.o controls.o sound.o menu.o -o game
which, as you can see, has the -c flag in it. The -c flag tells gcc not to do linking. So it has nothing to actually do. (.o files can only be used for linking, and you've disabled linking, which is why you get that message)
You don't want to use the same flags for compiling and linking. For compiling you probably want -c -std=c99 -Wall -Wextra -pedantic -O3 -Wfloat-equal -g, and for linking you want -lm -lSDL2 -lSDL2_ttf -lSDL2_image -lSDL2_mixer -g.
there are several small oversights in the posted makefile.
Amongst them:
library names are only used during the link step, not the compile step
suggest using the 'wildcard' make operator to get a list of the source files. Then use a patterm replacement operator to get a list of the object files:
for instance:
SRC := $(wildcard *.c)
OBJ := $(SRC:.c=.o)
when a target (all, clean) will not produce a file of the same name, then insert a .PHONY: statement early in the make file:
similarly to:
.PHONY : all clean
the posted make file has no facilities to handle the associated header files, There are several ways to handle that. This follows the OPs lead and does not handle the header files, so changing a header file will not recompile/relink the effected source files.
this line: rm *o game will not remove the name.o files as it is missing the '.' between the root name and the 'o' extension. Also, the '-f' flag should be used with the 'rm' command.
suggest:
rm -f *.o game
this line: all: ./game can create problems
suggest:
all: game
once the list of object files is created (as above) then the compile rules can be reduced:
by using the make operators:
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $# -I.
the -g parameter to the compiler and linker allows for a debugger to be used. If that debugger is gdb then a better parameter is -ggdb
almost always, there is no need to evaluate a macro definition more than once, so rather than using = in a macro definition, use :=
If you want the game to be executable, then insert a chmod command as the last line in the 'link' rule
Suggest reading about the special operators that can be employed in a makefile to help you understand the following, suggested makefile
It is usually best to replace calls to the shell recognized commands with macros.
CC := /user/bin/gcc
RM := /usr/bin/rm
CFLAGS := -c -std=c99 -Wall -Wextra -pedantic -O3 -Wfloat-equal -ggdb
LFLAGS := -std=c99 -O3 -ggdb
SDL := -lSDL2 -lSDL2_ttf -lSDL2_image -lSDL2_mixer
SRC := $(wildcard *.c)
OBJS := $(SRC:.c=.o)
.PHONY : all clean
all: game
game: $(OBJS)
$(CC) $(LFLAGS) $(OBJS) -o $# $(SDL) -lm
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $# -I.
clean:
$(RM) -f *.o game
Do not put -lm or the SDL libraries into CFLAGS, library operands go to the end of the command line. Instead, use an extra variable LDLIBS and modify your game rule like this:
game: global.o display.o player.o entities.o controls.o sound.o menu.o
$(GCC) $(CFLAGS) -o $# global.o display.o player.o entities.o controls.o sound.o menu.o $(LDLIBS)
The -lm operand (it's not an option) and the operands for SDL only apply when linking, thus it should not be part of CFLAGS and should not be specified when compiling without linking (i.e. when -c is supplied).

How to create a makefile?

I need to create a makefile for an assignment I need to run on Linux. I have no idea how to write makefiles.
The structure of the project is as follows:
Logic.h
Max.h which includes Logic using a header guard in the following way:
#ifndef _GUI
#include "Logic.h"
#endif
GUI.h which includes max.h and logic.h in the following way:
#ifndef _GUI
#define _GUI
#include "Logic.h"
#include "Minimax.h"
#endif
prog.h which includes GUI.h (prog is the main file - the main function is there)
All the header files have corresponding .c files that include only their respective header.
GUI.h uses SDL 1.2 so it includes also the following
#include "SDL.h"
#include "SDL_video.h"
I understand that special flags have to be inserted to the makefile so the SDL can run properly.
This is an example of a makefile that includes only one SDL file so it has the flags for sdl and the flags they require for notifying about errors and warnings:
all: sdl_test
clean:
-rm sdl_test.o sdl_test
sdl_test: sdl_test.o
gcc -o sdl_test sdl_test.o -lm -std=c99 -pedantic-errors -g `sdl-config --libs`
sdl_test.o: sdl_test.c
gcc -std=c99 -pedantic-errors -c -Wall -g -lm sdl_test.c `sdl-config --cflags`
But I don't know how to create a makefile for this file (project) structure, and where to put the SDL flag - only for the files that have SDL, or only the file that have SDL and include files that have SDL or all files.
This is a simple example
OBJECTS = sdl_test.o # add more files just separated by spaces -> filename.o
LDFLAGS = -lm `sdl-config --libs`
CFLAGS = -Wall -Werror -pedantic -g3 -O0 # full debugging on
CC = gcc
TARGET = sdl_test
all:
$(CC) -o $(TARGET) $(OBJECTS) $(LDFLAGS)
clean:
#rm $(OBJECTS) $(TARGET)
%.o: %.c
$(CC) $(CFLAGS) -c $<
Don't copy and paste because Makfiles require tabs for indentation.
A quick and dirty Makefile (i.e., one you don't really want to distribute for a finished product) could be just
SRCS = Max.c GUI.c prog.c
OBJS := $(patsubst %.c, %.o, $(SRCS))
.PHONY: all clean
.DEFAULT_GOAL = all
all: sdl_test
clean:
-rm $(OBJS) sdl_test
sdl_test: $(OBJS)
gcc -o $# $^ -lm -std=c99 -pedantic-errors -g `sdl-config --libs`
%.o: %.c
gcc -std=c99 -pedantic-errors -c -Wall -g -lm $< `sdl-config --cflags`
See Make automatic variables for details, but briefly the special make variables mean
$# - the thing that comes before the colon
$< - the first thing that comes after the colon
$^ - everything that comes after the colon

Makefile fails with warning message

This is a makefile that fails to link the .o files to make an executeable.
enter code here
CC = c99
CFLAGS = -g -Wall -Wextra -O0
OBJECTS = main.o getoptions.o
P = testprog
$(P): $(OBJECTS)
$(CC) $(OBJECTS) -o $(P)
main.o : main.c
$(CC) $(CFLAGS) $(OBJECTS) -c main.c
getoptions.o : getoptions.c getoptions.h
$(CC) $(CFLAGS) -c getoptions.o
I get this warning:
gcc: warning: getoptions.o: linker input file unused because linking not done
When I manually use:
c99 *.o -o testprog
linking succeeds.
Two issues here:
First, in your target for getoptions.o, you're passing getoptions.o for the -c option. You should be giving it the value of the source file getoptions.c
Second, get rid of $(OBJECTS) in the target for main.o. You don't need to pass in the object files for this step.
With those fixes you'll get a successful compilation:
c99 -g -Wall -Wextra -O0 -c main.c
c99 -g -Wall -Wextra -O0 -c getoptions.c
c99 main.o getoptions.o -o testprog
Edit:
The target line for main.o should be:
main.o : main.c getoptions.h
That way, if getoptions.h changes, main.o gets rebuilt.

Resources