Location of -lpthread in C Makefile - c

I'm pretty new to Makefiles in C. I am trying to figure out where I would put -lpthread in my makefile so I can implement posix threads in my C program. Below is my Makefile, thanks in advance.
CFLAGS = -g -Wall
LDFLAGS =
CC = gcc
LD = gcc
TARG1 = calc
OBJS1 = calc.o
$(TARG1): $(OBJS1)
$(LD) $(LDFLAGS) $(OBJS1) -o $(TARG1)
clean:
rm -rf $(TARG1) $(OBJS1)

I would recommend not using -l. Instead give GCC -pthread on both the CFLAGS and LDFLAGS variables. This will make sure that preprocessor defines are properly set during the compile and it will link the correct libraries.
This assumes GCC of course. If using Intel icc or LLVM check for the right parameters.

Related

usr/x86_64-unknown-linux-gnu/bin/ld: cannot find -lbsd

A little background for the problem I am having:
I just migrated from Ubuntu Focal Fossa to Mint Cinnamon keeping my home in a partition
libbsd is installed and can be used to compile some test code (I did a "Hello world" test using strlcpy in the main to verify that libbsd was usable)
Basically in order to use this project I have to use a library provided by my school (which compiled without problems in my last system) which is has a testing script that is going to run a test with its own Makefile:
INC=%%%%
INCLIB=$(INC)/../lib
UNAME := $(shell uname)
CFLAGS= -I$(INC) -O3 -I.. -g
NAME= mlx-test
SRC = main.c
OBJ = $(SRC:%.c=%.o)
LFLAGS = -L.. -lmlx -L$(INCLIB) -lXext -lX11 -lm
ifeq ($(UNAME), Darwin)
# mac
CC = clang
else ifeq ($(UNAME), FreeBSD)
# FreeBSD
CC = clang
else
#Linux and others...
CC = gcc
LFLAGS += -lbsd
endif
all: $(NAME)
$(NAME): $(OBJ)
$(CC) -o $(NAME) $(OBJ) $(LFLAGS)
clean:
rm -f $(NAME) $(OBJ) *~ core *.core
re: clean all
mlx would be the name of the library. For who is not familiar with this syntax (I was not) INC=%%%% is going to expand to /usr/include.
The command to compile the test binary expands to:
$ gcc -o mlx-test main.o -L.. -lmlx -L/usr/include/../lib -lXext -lX11 -lm -lbsd
which generates the error
/usr/lib/gcc/x86_64-unknown-linux-gnu/11.3.0/../../../../x86_64-unknown-linux-gnu/bin/ld: cannot find -lbsd
(that path expands to usr/x86_64-unknown-linux-gnu/bin/ld)
Now, this kinda looks like a gcc configuration, in fact I saw something similar in the output of the command gcc --version -v, but only with x86_64-linux-gnu so without the "unkown" part. Also, one of the weird things is that the path that appears in the error actually does not exist in my system.
I already tried reinstalling gcc but with no different result.
I hope the description was clear enough, please let me know if you may need any other detail that I did not think of.

Compiling multiple C and header files with 1 main

[Files in my directory][1]
Need help compiling in a make file.
So I have this link list assignment i'm doing and the directions were.
stringlist.h is supposed to contain the node and the function prototypes
stringlist.c is supposed to have the functions completed that are defined in stringlist.h. BUT stringlist.c is not supposed to contain main at all. Then, namelist.c is supposed to contain main and just have the I/O and its just supposed to call the command functions that are in stringlist.c.
So to compile this we are supposed to create a make file. Whenever I try to I get an error because main doesn't exit in one of the c files. Throughout the term we compiled code like this "gcc -std=gnu99 -m32 -Wall -g -o file file.c"
But it doesn't work.
How would I create the make file? Been spending hours and can't figure it out.
As stated by Jonathan Leffler, the sample Makefile I provided had a few bad ideas. Here's an improvement:
# compiler:
CC = gcc
# compiler flags:
CFLAGS = -g -Wall
# the build target executable:
TARGET = executable
# object files to build:
OBJ = namelist.o stringlist.o
all: $(TARGET)
$(TARGET): $(OBJ)
$(CC) $(CFLAGS) -o $(TARGET) $(OBJ)
Try this:
OBJ := namelist.c stringlist.c
GCC := gcc -g
CFLAGS := -std=gnu99 -m32 -Wall
compile: $(OBJ)
$(GCC) $(CFLAGS) $(OBJ) -o executable

Issues with pthreads compling

It seems I'm having issues with the pthread when I try compiling with a Makefile:
/csapp.c:462: undefined reference to `pthread_create'
I think it might have something to do with the -lpthread?
Here is my Makefile (yes they are tabbed once):
CC = gcc
CFLAGS = -Wall -g
LDFLAGS = -lpthread
OBJS = proxy.o csapp.o
all: proxy
proxy: $(OBJS)
csapp.o: csapp.c
$(CC) $(CFLAGS) -c csapp.c
proxy.o: proxy.c
$(CC) $(CFLAGS) -c proxy.c
clean:
rm -f *~ *.o proxy
I believe your problem is with LDFLAGS.
From 10.3 Variables Used by Implicit Rules:
LDFLAGS Extra flags to give to compilers when they are supposed to invoke the linker, ld, such as -L. Libraries (-lfoo) should be added to the LDLIBS variable instead.
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.
So try:
LDLIBS = -lpthread

Using Make for compiling C

I am trying to learn make to make my compiling easier as I learn C.
I am attempting to do:
gcc -Wall -g 3.c -o 3 -lm
using
CC = gcc
CFLAGS = -Wall -g
clean:
rm -f 3
but I don't know how and where to put -lm in the makefile. I've looked for tutorials online but they haven't specifically addressed the "-lm" option, or if they do it is without little explanation and doesn't work in my situation.
You need a "target" in which to execute the gcc command. Like:
CC = gcc
CFLAGS = -Wall -g
all:
gcc -Wall -g 3.c -o 3 -lm
clean:
rm -f 3
Then you can just replace parts of the "all" command, with your macros; CFLAGS, for example would probably have the "-lm".
It might help if you ran "make -n", that will tell you what make would do if it were to run.
Often you'll see library specific flags in a LIBS variable, e.g.:
CC = gcc
CFLAGS = -Wall -g -I/some/include/directory
LIBS = -lm -L/some/library/directory
all:
$(CC) $(CFLAGS) $(LIBS) 3.c -o 3
The variable you are looking for is called LDLFAGS. From §10.3 of the GNU Make manual:
LDFLAGS
Extra flags to give to compilers when they are supposed to invoke the linker, ‘ld’.
So, simply do:
LDFLAGS += -lm
Hope it helps.
An extremely good tutorial: Make Tutorial: How-To Write A Makefile
and here is a good generic makefile I wrote:
http://pastebin.com/PCk0gNtE
The part that would most interest you would be this section:
# C Preprocessor Flags
CPPFLAGS +=
# compiler flags
CFLAGS += -ansi -Wall -Wextra -pedantic-errors
# libraries to link to ( m == math )
program_LIBRARIES := m
# LDFLAGS is the variable to hold linker flags
LDFLAGS += $(foreach library,$(program_LIBRARIES),-l$(library))
GNU make defines a lot of default rules. For C compilation and linking, those rules are:
n.o is made automatically from n.c with a recipe of the form ‘$(CC) $(CPPFLAGS) $(CFLAGS) -c’.
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)’.
So the way to add "-lm" option to the linker is by defining:
LDLIBS = -lm
Then when you run make with your Makefile, you following commands will be run:
gcc -Wall -g -c 3.c
gcc 3.o -o 3 -lm
(note that make will compile your C program in 2 steps, first creating the object file 3.o then linking the object file into the executable 3)
(see http://www.gnu.org/software/make/manual/ for the GNU make manual)

Compiling to 32-bit using make

I am trying to compile a very simple program using the -m32 flag.
If I try to do this using gcc -m32 it works just fine(I have the needed libs)
Yet, when I add this flag to my flags in a makefile, I get a weird error
This is the makefile that I have
CC=gcc
CFLAGS=-m32 -O1 -W -Wall -pedantic -std=c99
all: main.o
$(CC) -o main main.o
rm main.o
clean:
rm main
The error that I receive is the following
gcc -o main main.o
/usr/bin/ld: i386 architecture of input file `main.o' is incompatible with i386:x86-64 output
collect2: ld returned 1 exit status
make: *** [all] Error 1
Can someone please tell me what does this mean? and how can I fix it?
As for the code, the code does NOTHING except printing 'hello world'
I am using GCC 4.4.3 under Linux 2.6.35 64-bits
Your mistake is that you don't pass -m32 to the linker.
You actually need to change your Makefile to look like this:
CC=gcc
CFLAGS=-m32 -O1 -W -Wall -pedantic -std=c99
LDFLAGS = -m32
all: main.o
$(CC) $(LDFLAGS) -o main main.o
rm main.o
clean:
rm main
An even better approach would be the following Makefile:
CC=gcc
CFLAGS=-m32 -O1 -W -Wall -pedantic -std=c99
LDFLAGS=-m32
.INTERMEDIATE: main.o
all: main
main: main.o
clean:
-rm main
In the later you just say that main depends on main.o and GNU Make will invoke the linker with the LDFLAGS as arguments for you as it invokes the compiler with the CFLAGS as arguments for the main.o
"The targets which .INTERMEDIATE depends on are treated as intermediate files. See section Chains of Implicit Rules. .INTERMEDIATE with no dependencies marks all file targets mentioned in the makefile as intermediate." Special Built-in Target Names
You should inform the linker as well about the architecture being 32-bit. Try adding
LD = $(CC)
LDFLAGS = -m32
to your Makefile and change
$(CC) -o main main.o
to
$(LD) $(LDFLAGS) -o main $^
and it shoud work.
(Why it worked? If you use GCC to compile and link your code in one step, all the relevant flags and options will be passed down not only to the compiler but to the linker as well.)

Resources