Why do you need '-lpthread'? - c

So my questions is: Why do you need '-lpthread' at the end of a compiling command?
Why does this command work:
gcc -o name name.c -lpthread
but this won't:
gcc -o name name.c
I am using the pthread.h library in my c code.
I already looked online for some answers but didn't really find anything that answered it understandably

pthread.h is not a library it is just a header file which gives you declaration (not the actual body of function) of functions which you will be using for multi-threading.
using -libpthread or -lpthread while compiling actually links the GCC library pthread with your code. Hence the compiler flag, -libLIBRARY_NAME or -lLIBRARY_NAME is essential.
If you don't include the flags -l or -lib with LIBRARY_NAME you won't be able to use the external libraries.
In this case, say if you are using functions pthread_create and pthread_join, so you'll get an error saying:
undefined reference to `pthread_create'
undefined reference to `pthread_join'

The -l options tells the linker to link in the specified external library, in this case the pthread library.
Including pthread.h allows you to use the functions in the pthread library in you code. However, unlike the functions declared in places like studio.h or stdlib.h, the actual code for the functions in pthread.h are not linked in by default.
So if you use functions from this library and fail to use -lpthread, the linking phase will fail because it will be unable to find functions in the library such as pthread_create, among others.

Related

why -pthread is required as an argument for compiling pthread c programs

Why do when we use pthread.h library function in a c program, to compile it we have to write
gcc program.c -pthread Why doesn't gcc program.c works. Although the simple reason could be
that it includes the pthread library when we specify the -pthread tag. But then we don't pass
any such argument when we include other header files. Is it because that pthread is an external library than what's available from within C?
The functions in libraries such as stdlib.h and stdio.h have implementations in libc.so, which is linked into your executable by default (as if -lc were specified).
Libraries such as math.h and pthread.h are not included in libc.so and hence have to be linked separately. This can be done by passing the -lm and -lpthread arguments respectively.
gcc program.c will actually compile perfectly but the linker will not find the required function definitions used and will hence throw an error.

Using stdlib.h functions directly in assembly

I have to do an assembly (x86) program that takes 2 long numbers from user input, adds them using a function and then prints the result. When I use the read syscall I get a string in ASCII hex code and I can't add the numbers like that. So I wanted to use atol that is a function of stdlib.h to convert the string to long. How can I include libraries in assembly? Is there another way to do this?
I have already tried:
.file "stdlib.h" (I have the lib in the current directory)
error: undefined reference to atol'
compiling stdlib.h with the .s file together using clang
error: stdlib.h: file not recognized: File format not recognized
making a .c file with only #include<stdlib.h> and compiling it with the .s file
error: undefined reference to `atol'
the comads I run are
clang function.s -c -g
ld function.o -o function
The linker complains that atol has not been found because it is a function in the C library, but you didn't tell the linker to add the C library to your program during linking. To fix this, pass -lc to the linker to add the C library during linking:
ld -o function function.o -lc
It is very important that -lc goes last, otherwise the link might not work. This is because the linker picks functions from libraries in the order you specify them. When you specify -lc before function.o, it ignores the library as it doesn't need anything from it right now. Then it sees function.o with an undefined atol and doesn't find a definition, causing the link to fail.
Lastly, when you use the C library, you should start your program from the main function (i.e. rename _start to main) like a normal C program and link through the C compiler:
clang -g -o function function.s
This causes the C library to be linked in automatically and makes initialises it correctly, preventing some weird bugs. If you use any IO functions like printf from the C library, you should also end your program by calling exit so the standard IO streams are flushed correctly.
Note that the stdlib.h file is a red herring. Header files are not needed for programming in assembly. Their purpose is to tell the C compiler what the type of some functions are. This is not needed if you do not use the C compiler. The .file directive does not do what you expect it does.
You added a compilation unit (the .c file) to the project. This introduces the prototype of the functions in the included header file "stdlib.h". What you want is reference to that function. This should be introduced in the assembler file that shall use the function.
Adding a extern statement to the assembler file should do the job. You don't need the C file with the include. You will have to add the corresponding library in the linker settings. But even if you successfully link an EXE file, you probably get a problem, since some functions in the stdlib needs an initialization. You must also call the C run-time initialization function.

"undefined reference to `pow'" even with math.h and the library link -lm [duplicate]

This question already has answers here:
Undefined reference to `pow' and `floor'
(6 answers)
Closed 2 years ago.
I'm using math.h and the -lm option to compile. I have tried all of:
gcc -o ssf ssf_tb.c ssf.c -lm
gcc -o ssf ssf_tb.c -lm ssf.c
gcc -o -lm ssf -lm ssf_tb.c ssf.c
but the error:
undefined reference to 'pow'
happens on all cases.
Put the -lm at the end of the line.
gcc processes the arguments that specify inputs to the final program in the order they appear on the command line. The -lm argument is passed to the linker, and the ssf.c argument, for example, is compiled, and the resulting object file is passed to the linker.
The linker also processes inputs in order. When it sees a library, as -lm specifies, it looks to see if that library supplies any symbols that the linker currently needs. If so, it copies the modules with those symbols from the library and builds them into the program. When the linker sees an object module, it builds that object module into the program. After bringing an object module into the program, the linker does not go back and see if it needs anything from earlier libraries.
Because you listed the library first, the linker did not see anything that it needed from the library. If you list the object module first, the linker will bring the object module into the program. In the process of doing this, the linker will make a list of all the undefined symbols that the object needs. Then, when the linker sees the library, it will see that the library supplies definitions for those symbols, and it will bring the modules with those symbols into the program.

How can I link with my own pthread library

I want to make some modifications to the pthread library used for my program. That is why I want to link with my own modified pthread library. I can take the source code in glibc for pthread, modify it and use that for my programs.
Normally you use the flag -pthread for linking with the original pthread library. How do I specify in my makefile to link with my own library.
Just use the -L option to specify the directory where your custom lib is present and use -l option to specify the name of your library.
For Ex:
-L/root/x/mylib -lmypthread
In this case your lib name should libmypthread.so
Refer to http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html for more details.
To ensure that the library is found for loading when you execute your program, do
export LD_LIBRARY_PATH = $(LD_LIBRARY_PATH):/root/x/mylib
-pthread is equivalent to -lpthread -D_REENTRANT with gcc/glibc. You can do the same, but with a different link argument (-lname-of-library).
Don't use -pthread. It is an undocumented GCC option, probably for compatibility with some other (Solaris?) compilers.
The -D_REENTRANT definition which it -pthread enables is completely unnecessary in glibc; none of the headers depend on this macro for thread safety. (The last of such mechanisms were removed from the glibc headers in 1998!) Simply linking in -lpthread is enough to switch glibc functions to thread safe mode, and -lpthread can be substituted with your own library, like the other answer says.
Compile the library in a different name, e.g., libmypthread.so and put it in one of the directories contained in your LD_LIBRARY_PATH environment variable (or add a new directory). Now you can use -lmypthread to link to your library.

Problem in compiling C function with threading on Fedora

When I try to compile a C-program with multithreading in Fedora, I get the following error.
The file name is abc.c
abc.c:(.text+0x39): undefined reference to `pthread_create'
abc.c:(.text+0x61): undefined reference to `pthread_create'
abc.c:(.text+0x79): undefined reference to `pthread_join'
abc.c:(.text+0x8d): undefined reference to `pthread_join'
I checked in /usr/include and I found that pthread.h is present. Also I tried copying pthread.h to the same directory as abc.c
How do I resolve these linking errors?
As pointed out by George you must link with the thread library
gcc -o abc abc.c -pthread
The reason you are getting those errors is because during the linking stage the compiler tries to fill in all the slots where it had placed placeholders for method calls that it knew were defined but currently did not know their locations because the appropriate library had not been linked yet. As pointed out by caf using the -pthread flag in both compiling and linking stages allows for the compiler to make smarter choices about what it needs to use to be thread-safe in certain conditions.

Resources