undefined reference to pthread_create and pthread_join - c

I am trying to build my program but keep getting the same error messages:
undefined reference to pthread_create
undefined reference to pthread_join
I have included pthread.h and in my makefile im compiling with -pthread.
int threadAmount = strtol(nrthr, NULL, 0);
threadAmount--;
if(threadAmount > 0){
pthread_t tids[threadAmount];
for(int i = 0;i < threadAmount; i++){
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_create(&tids[i],&attr,search,&t1);
}
for(int i = 0;i < threadAmount; i++){
pthread_join(tids[i],NULL);
}
}
It's where I'm calling create and join where it's complaining. What could be the problem?
The makefile used to build:
CC=gcc
CFLAGS= -pthread -std=gnu11 -Wall -Wextra -Werror -Wmissing-declarations -Wmissing-prototypes -Werror-implicit-function-declaration -Wreturn-type -Wparentheses -Wunused -Wold-style-definition -Wundef -Wshadow -Wstrict-prototypes -Wswitch-default -Wunreachable-code
all: mfind
list.o: list.c list.h
$(CC) -c list.c $(CFLAGS)
mfind.o: mfind.c list.h
$(CC) -c mfind.c $(CFLAGS)
mfind: mfind.o list.o
$(CC) mfind.o list.o -o mfind
clean:
rm -f *.o mfind
mfind is the main program and list.c is an implemented list.

list.o: list.c list.h
$(CC) -c list.c $(CFLAGS)
mfind.o: mfind.c list.h
$(CC) -c mfind.c $(CFLAGS)
mfind: mfind.o list.o
$(CC) mfind.o list.o -o mfind
It looks like some of your recipes are missing CFLAGS, which includes the option -pthread. I believe it should be:
list.o: list.c list.h
$(CC) $(CFLAGS) -c list.c
mfind.o: mfind.c list.h
$(CC) $(CFLAGS) -c mfind.c
mfind: mfind.o list.o
$(CC) $(CFLAGS) mfind.o list.o -o mfind
...
Its OK to CFLAGS to the output artifact. In fact, you should use the same CFLAGS (and CXXFLAGS) when the compiler driver drives link. You should also always use the compiler driver because it takes care of turning options, like -pthread, -fopenmp and -fsanitize=undefined, into the proper options and libraries for the linker.
If interested, here are the default rule used with GNUmake: Catalogue of Built-In Rules. Notice the recipe for *.c files includes CFLAGS:
Compiling C programs
n.o is made automatically from n.c with a recipe of the form $(CC) $(CPPFLAGS) $(CFLAGS) -c.
If you use the following from the GNU Make manual, then you should also add -pthread to LDFLAGS. But I recommend you follow what the compiler guys tell us, and that is to drive link through the compiler driver.
Linking a single object file
n is made automatically from n.o by running the linker (usually
called ld) via the C compiler. The precise recipe used is $(CC) $(LDFLAGS) n.o $(LOADLIBES) $(LDLIBS).

-pthread doesn't belong in CFLAGS. As you already found, the libraries that are needed must be at the end of the command line options after all the object files. You need to put -pthread in LDLIBS since you have a makefile.
From https://www.gnu.org/software/make/manual/html_node/Implicit-Variables.html:
LDLIBS
Library flags or names given to compilers when they are supposed to invoke the linker, ‘ld’. LOADLIBES is a deprecated (but still supported) alternative to LDLIBS. Non-library linker flags, such as -L, should go in the LDFLAGS variable.

Related

How to resolve GNU make producing a "circular main.c" error

//makefile.conf
.SUFFIXES : .c .o
cc = gcc
CFLAG = -c
OFLAG = -o
O2FLAG = -O2
WPIFLAG = -lwringPi
RM = rm -rf
TARGET_SRCS = main.c
TARGET_OBJS = $(TARGET_SRCS:$.c=$.o)
TARGET_NAMES = $(TARGET_SRCS:$.c=$)
BINARY_NAME = LED_TEST
// makefile
include makefile.conf
$(TARGET_OBJS) : $(TARGET_SRCS)
$(CC) $(O2FLAG) $(CFLAG) $(OFLAG) $^
I'm trying to figure out how gnu make works and how to use it. Yet, I'm a beginner.
I'm trying to use make on my assignment (not mandatory, just my passion) for running simple code which lights up LED by using wiringpi.
Actually there's only one main.c and what I want to make is the makefile that runs
gcc -O2 -c -o main.o main.c
gcc -o main main.o -lwiringPi
Since my last code didn't worked, (constantly getting circular main.c <- main.c dependency dropped error)
I tried to make a code that only runs
gcc -O2 -c -o main.o main.c
but I still get circular main.c error and I don't know what that means.
I tried to look up gnu make manuals but I thought through that, it will take my life to understand.
So I'm trying to see the codes and make one with what I saw.
I think I understand the concept of makefile.conf but still don't understand the function of .SUFFIXES.
I understood it as noticing make that I'll make a rule with .c and .o, codes after that in makefile.conf defines the variables those will be used in makefile.
How can I correct the code? When actual 'assignment' took only five minute including adding comments.
First makefile:
main:
gcc -O2 -c -o main.o main.c
gcc -o main main.o -lwiringPi
When that works perfectly, second makefile:
main: main.o
gcc -o main main.o -lwiringPi
main.o: main.c
gcc -O2 -c -o main.o main.c
When that works perfectly, third makefile:
main: main.o
gcc -o $# $^ -lwiringPi
main.o: main.c
gcc -O2 -c -o $# $<
When that works perfectly, you will be ready for more advanced techniques.
If you are really new, it's often helpful to start off with simple makefiles till you need the extra features.
main: main.c
gcc -O2 -o main -lwiringPi main.c
Note the white space before the gcc is a single tab character.
Once you get the hang of that, you can then substitute various items to make your "make rules" easier to duplicate and maintain. For example, %^ means "every dependent source, so a rewrite of the rule would be
main: main.c
gcc -O2 -o main -lwiringPi $^
Occasionally, you might want to offer easy reconfiguration of the compiler, so if you had a dozen rules, and wanted to configure the compiler all in one place
CC=gcc
main: main.c
$(CC) -O2 -o main -lwiringPi $^
would expand the CC variable to the value gcc at make time. There's an upper limit to the utility of this expansion, for example, if something is "one of many of the same thing" You might not want to declare a variable for that individual item. For example, your WPIFLAG is likely always required, and probably not very successfully reconfigurable. Mabye a loader flags variable makes more sense.
LDFLAGS=-lwiringPi -lm -lwhatever
and a compiler flags variable
CFLAGS=-O2 -Werror -Wfatal-errors
Which would lead to the more sensible
main: main.c
$(CC) $(CFLAGS) -o main $(LDFLAGS) $^
Finally, you can replace the target main in this case, with another special variable. $# which means "the target being built"
main: main.c
$(CC) $(CFLAGS) -o $# $(LDFLAGS) $^
Note that for object files, you are listing all your objects as being dependent on all of your sources. If you want to support independent rules for object building, you need to do something different
main: main.o
$(CC) $(CFLAGS) -o $# $(LDFLAGS) $^
And you'll need rules for each object.
main.o: main.c
$(CC) $(CFLAGS) -c -o $# $(LDFLAGS) $^
but it will become a labor typing this rule for each object. To automate this rule, you will use a pattern based on the file suffixes, and a suffix rule.
.SUFFIXES : .o .c
.c.o :
$(CC) $(CFLAGS) -c $<
Note the rule above relies on the default behavior of $(CC) which is to generate a something.o when something.c is compiled with the -c flag. If you wanted to make the output file explicit
.SUFFIXES : .o .c
.c.o :
$(CC) $(CFLAGS) -c -o $# $<
This Suffix Rule acts as a macro. When someone needs thing.o, it will build it from thing.c if thing.c exists, even if there isn't an explicit rule for thing.c
With this, you can then collect all your object on the original main target. (We will remove CFLAGS, as no compiling will be happening, only linking)
main: main.o other.o first.o list.o end.o
$(CC) -o $# $(LDFLAGS) $^
But some find listing the object to be a pain, and like to put them in a variable
main: $(OBJS)
$(CC) -o $# $(LDFLAGS) $^
which means you will need to declare and set OBJS
OBJS = main.o other.o first.o list.o end.o
But it's sort of weird to track intermediate files, so why not track the actual sources
SOURCES = main.c other.c first.c list.c end.c
Ok, but how will we get the required OBJS from SOURCES? We will derefence SOURCES, modifying the suffixes to .o
OBJS = ${SOURCES:.c=.o}
The end result
SOURCES = main.c other.c first.c list.c end.c
OBJS = ${SOURCES:.c=.o}
CC=gcc
CFLAGS=-O2 -Werror -Wfatal-errors
LDFLAGS=-lwiringPi -lm -lwhatever
.SUFFIXES : .o .c
.c.o :
$(CC) $(CFLAGS) -c -o $# $<
main: ${OBJS}
$(CC) -o $# $(LDFLAGS) $^

c - Make is only running 'gcc' with no parameters

I'm learning how to use C and Make, but Make is making me tear my hair out. When I run make with all targets I've created it fails, running gcc with no parameters, except one of them randomly works just fine. Here is what happens when I try to build with most of the targets:
$ make strvector.o
gcc
gcc: fatal error: no input files
compilation terminated.
make: *** [vector.o] Error 4
and when I run the one that works:
$ make word.o
gcc -Wall -g -ansi -pedantic -c -o word.o word.c
Here is my makefile:
CC = gcc
CFLAGS = -Wall -g -ansi -pedantic -c -o $# $^
LD = gcc
LDFLAGS =
fw: fw.o vector.o hashtable.o strvector.o
$(LD) $(LDFLAGS) -o fw vector.o hashtable.o strvector.o word.o
fw.o: fw.c vector.o hashtable.o strvector.o word.o
$(CC) $(CFALGS)
vector.o: vector.c word.o
$(CC) $(CFALGS)
hashtable.o: hashtable.c vector.o word.o
$(CC) $(CFLAGS)
word.o: word.c
$(CC) $(CFLAGS)
strvector.o: strvector.c
$(CC) $(CFALGS)
I cannot for the life of me figure out why word.o builds fine but not anything else. If anyone could help that would be much appreciated.
--Edit-- I made a typo. Writing CFALGS instead of CFLAGS. not sure how I missed that one. Thanks guys!
You left out the filenames in the compilation commands.
strvector.o: strvector.c
$(CC) -c $(CFLAGS) -o $# $<
$# gets replaced with the current target, $< is replaced with the current dependency.

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

Undefined reference and linking libraries

I'm experiencing some compilation issues with my dynamic library. It should be linked to main.c but for all references to it I receive "undefined reference to function_name".
The contents of main.c isn't really that important; I include my library:
#include "matrix.h"
Then I have a simple Makefile to link the two.
#Variables
LIB = matrix
# Usual compilation flags
CFLAGS = -std=c99 -Wall -Wextra -g
CPPFLAGS = -I../include -DDEBUG
LDFLAGS = -lm
# Special rules and targets
.PHONY: all clean help
all: $(LIB).o libmatrix.so main
$(LIB).o: $(LIB).c $(LIB).h
$(CC) $(CFLAGS) $(CPPFLAGS) -fPIC -c -o $# $<
libmatrix.so: $(LIB).o
$(CC) $(CFLAGS) -fPIC -shared -o $# $< $(LDFLAGS)
main: main.o libmatrix.so
$(CC) $(CFLAGS) -o $# $< -L -lmatrix
Can anyone direct me to where I might be going wrong? Many thanks in advance.
You probably want -L. not -L in your last line, so:
main: main.o libmatrix.so
$(CC) $(CFLAGS) -o $# $< -L. -lmatrix
You should read Program Library HOWTO and Drepper's paper: How to Write Shared Libraries; you might want to set some -rpath at link time (maybe using -Wl,-rpath,. ...), and you might want to link with -rdynamic ....
Alternatively, set your LD_LIBRARY_PATH environment variable to contain . (I don't recommend that), or install your shared library in /usr/local/lib/ (and add it to /etc/ld.so.conf then run ldconfig). See also dlopen(3), environ(7), ld.so(8), ldconfig(8)

Resources