GCC: How can I make this compiling and linking work? - c

I want to use from the file tester-1.c functions that I defined in libdrm.h and gave implementation in libdrm.c. The three files are on the same folder and use pthread functions.
Their include files are:
libdrm.h
#ifndef __LIBDRM_H__
#define __LIBDRM_H__
#include <pthread.h>
#endif
libdrm.c <- has no main()
#include <stdio.h>
#include <pthread.h>
#include "libdrm.h"
tester-1.c <- has teh main()
#include <stdio.h>
#include <pthread.h>
#include "libdrm.h"
The compiler error for libdrm.c says:
gcc libdrm.c -o libdrm -l pthread
/usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: ld returned 1 exit status
And the compiler errors for tester-1.c say:
gcc tester-1.c -o tester1 -l pthread
/tmp/ccMD91zU.o: In function `thread_1':
tester-1.c:(.text+0x12): undefined reference to `drm_lock'
tester-1.c:(.text+0x2b): undefined reference to `drm_lock'
tester-1.c:(.text+0x35): undefined reference to `drm_unlock'
tester-1.c:(.text+0x3f): undefined reference to `drm_unlock'
/tmp/ccMD91zU.o: In function `thread_2':
tester-1.c:(.text+0x57): undefined reference to `drm_lock'
tester-1.c:(.text+0x70): undefined reference to `drm_lock'
tester-1.c:(.text+0x7a): undefined reference to `drm_unlock'
tester-1.c:(.text+0x84): undefined reference to `drm_unlock'
/tmp/ccMD91zU.o: In function `main':
tester-1.c:(.text+0x98): undefined reference to `drm_setmode'
tester-1.c:(.text+0xa2): undefined reference to `drm_init'
tester-1.c:(.text+0xac): undefined reference to `drm_init'
tester-1.c:(.text+0x10e): undefined reference to `drm_destroy'
tester-1.c:(.text+0x118): undefined reference to `drm_destroy'
All these functions are defined in libdrm.c
What gcc commands should I use to make these files compile and link?

To compile your .c sources to object files, use GCC's -c option. Then you can link the object files to an executable, against the required library:
gcc libdrm.c -c
gcc tester-1.c -c
gcc tester-1.o libdrm.o -o tester1 -lpthread
Doing compiling and linking in one go, as many others have suggested, works fine too. However, it's good to understand that the build process involves both of these stages.
Your build failed, because your translation modules (=source files) required symbols from each other.
libdrm.c alone couldn't produce an executable, because it does not have a main() function.
tester-1.c's linking failed, because the linker wasn't informed about the required symbols defined in libdrm.c.
With -c option, GCC compiles and assembles the source, but skips linking, leaving you with .o files, which can be linked into an executable or packaged into a library.

gcc tester-1.c libdrm.c -o tester1 -l pthread
You need to compile all the source files in one go rather than doing them individually. Either that or compile libdrm.c as a library and then link it with tester1.c when you compile that.

gcc test-1.c libdrm.c -o libdrm -l pthread

Related

Different behavior of undefined reference error on linux gcc during linking with object file vs static library

I have following two source codes and want to link them.
// test.c
#include <stdio.h>
void lib2();
void lib1(){
lib2();
return 0;
}
// main.c
#include <stdio.h>
int main() {
return 0;
}
I've used gcc -c main.c and gcc -c test.c to generate objects files
$ ls *.o
main.o test.o
and I've used ar rcs test.a test.o command to generate static library(test.a) from object file test.o
Then, I tried to build executable by linking main.o with test.a or test.o. As far as I know, a static library file(.a extension) is a kind of simple collection of object files(.o). so I expected both would give same result: error or success. but it didn't.
Linking with the object file gives undefined reference error.
$ gcc -o main main.o test.o
/usr/bin/ld: test.o: in function `lib1':
test.c:(.text+0xe): undefined reference to `lib2'
collect2: error: ld returned 1 exit status
$
but linking with the static library doesn't give any error and success on compilation.
$ gcc -o main main.o test.a
$
Why is this happening? and how can I get undefined reference errors even when linking with static libraries?
If your code contains a function call expression then the language standard requires a function definition exists. (See C11 6.9/3). If you don't provide a definition then it is undefined behaviour with no diagnostic required .
The rule was written this way so that implementation vendors aren't forced to perform analysis to determine if a function is ever called or not; for example in your library scenario the compiler isn't forced to dig around in the library if none of the rest of the code contains anything that references that library.
It's totally up to the implementation what to do, and in your case it decides to give an error in one case and not the other. To avoid this, you can provide definitions for all the functions you call.
You might be able to modify the behaviour in the first case by using linker options such as elimination of unused code sections. Another thing you can do is call lib1() from main() -- this is still not guaranteed to produce an error but is more likely to.
Force the linker to do some work use -flto option and the error will go away.
ld does not search libraries for objects which are not used it only searches for symbols used in object files. Imagine that you have a library where some functions require defined callbacks. If you do not have them in every program you link against the library even if you do not use those functions.
I expected both would give same result: error or success. but it didn't.
Your expectation is incorrect. A good explanation of the difference between .o and .a with respect to linking is here.

Single file program with PDCurses fails to compile with "undefined reference to"

I have some problems compiling my test program using PDCurses library. I have compiled PDCurses 3.4 with MinGW compiler 8.2.0. In output I have 2 files panel.a and pdcurses.a. I copied them to C:\MinGW\lib plus the header file curses.h in C:\MinGW\include. But when I try to compile test program I have errors. It seems I have done everything correctly according to instructions and how-to`s.
Some testing C code:
#include <C:\MinGW\include\curses.h>
int main () {
initscr();
mvprintw( 5, 5, "Hello, World!" );
getch();
endwin();
return 0;
}
ERRORS:
c:/Users/username/Dropbox/rakshasa/main.c:4: undefined reference to `initscr'
c:/mingw/bin/../lib/gcc/mingw32/8.2.0/../../../../mingw32/bin/ld.exe: c:/Users/username/Dropbox/rakshasa/main.c:5: undefined reference to `mvprintw'
c:/mingw/bin/../lib/gcc/mingw32/8.2.0/../../../../mingw32/bin/ld.exe: c:/Users/username/Dropbox/rakshasa/main.c:6: undefined reference to `stdscr'
c:/mingw/bin/../lib/gcc/mingw32/8.2.0/../../../../mingw32/bin/ld.exe: c:/Users/username/Dropbox/rakshasa/main.c:6: undefined reference to `wgetch'
c:/mingw/bin/../lib/gcc/mingw32/8.2.0/../../../../mingw32/bin/ld.exe: c:/Users/username/Dropbox/rakshasa/main.c:7: undefined reference to `endwin'
I have no idea why it is not compiling properly. It looks like compiler cant find libraries in linking stage but I do not know why.
I was try to compile like
gcc -g main.c -o main.exe
Thanks in advance.
Never use absolute paths in #include directives. Instead of #include <C:\MinGW\include\curses.h> you should put #include <curses.h> and compile with -IC:\MinGW\include flag if needed.
Next you need to link with the relevant library using -lpdcurses. If needed you can add the location of the library using -LC:\MinGW\lib.
So if we split compilation and linking steps you need the following commands:
gcc -g main.c -c -o main.o -IC:\MinGW\include
gcc main.o -o main.exe -lpdcurses -LC:\MinGW\lib
though I think you can leave out the -I and -L flags as they point to the location of your compiler's include and lib folders.
Finally: MinGW is a bit outdated and so is GCC 8.2.0. I recommend you switch to MinGW-w64 (which supports both 32-bit and 64-bit Windows). To get a more recent MinGW-w64 GCC build, you can try the standalone builds from https://winlibs.com/.

C compiler gcc gives linker command failed error [duplicate]

I'm getting the following error and can't for the life of me figure out what I'm doing wrong.
$ gcc main.c -o main
Undefined symbols:
"_wtf", referenced from:
_main in ccu2Qr2V.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
main.c:
#include <stdio.h>
#include "wtf.h"
main(){
wtf();
}
wtf.h:
void wtf();
wtf.c:
void wtf(){
printf("I never see the light of day.");
}
Now, if I include the entire function in the header file instead of just the signature, it complies fine so I know wtf.h is being included. Why doesn't the compiler see wtf.c? Or am I missing something?
Regards.
You need to link wtf with your main. Easiest way to compile it together - gcc will link 'em for you, like this:
gcc main.c wtf.c -o main
Longer way (separate compilation of wtf):
gcc -c wtf.c
gcc main.c wtf.o -o main
Even longer (separate compilation and linking)
gcc -c wtf.c
gcc -c main.c
gcc main.o wtf.o -o main
Instead of last gcc call you can run ld directly with the same effect.
You are missing the fact that merely including a header doesn't tell the compiler anything about where the actual implementation (the definitions) of the things declared in the header are.
They could be in a C file next to the one doing the include, they could come from a pre-compiled static link library, or a dynamic library loaded by the system linker when reading your executable, or they could come at run-time user programmer-controlled explicit dynamic loading (the dlopen() family of function in Linux, for instance).
C is not like Java, there is no implicit rule that just because a C file includes a certain header, the compiler should also do something to "magically" find the implementation of the things declared in the header. You need to tell it.

libpdcurses.a setting for Pdcurses

I'm working on a program in which I use PDCurses3.5 functions using i686-w64-mingw32-gcc.exe.
When I compile the program, I keep getting errors such as "undefined reference to 'COLS'", "undefined reference to 'lines'".
I have checked that <curses.h> header and the library package properly installed.
Here is my input line:
> i686-w64-mingw32-gcc.exe set.o read.o elements.o random.o
> -L../standard/test -lplotfit -lplotget -lgfortran -Wl,--subsystem,console -mwindows -o runtime/mingw/result -lm -static -lws2_32 -lpdcurses
And the first part of the error is:
../standard/bin/mingw/menu.o:menu.c:(.text+0xb): undefined reference to `COLS'
../standard/bin/mingw/menu.o:menu.c:(.text+0x16): undefined reference to `COLS'
../standard/bin/mingw/menu.o:menu.c:(.text+0x33): undefined reference to `LINES'
../standard/bin/mingw/menu.o:menu.c:(.text+0x47): undefined reference to `MOVE'
../standard/bin/mingw/menu.o:menu.c:(.text+0x74): undefined reference to `initscr'
...
It seems the program cannot refer to libpdcurses.a in its library file.
What am I doing wrong?
When you use -lpdcurses, the linker looks for libpdcurses.a in certain predefined locations, plus those specified via -L. But, by default, the library is built as pdcurses.a. To link it, you can directly specify its location; e.g.:
gcc -oprogname.exe progname.c pdcurses.a
or
gcc -oprog2.exe prog2.c /pdcurses/win32/pdcurses.a
Alternatively, you can rename the library to libpdcurses.a, and either copy it to a location in the existing search path, or use -L:
gcc -oprogname.exe progname.c -lpdcurses
or
gcc -oprog2.exe prog2.c -L/pdcurses/win32 -lpdcurses

Undefined symbols error when using a header file

I'm getting the following error and can't for the life of me figure out what I'm doing wrong.
$ gcc main.c -o main
Undefined symbols:
"_wtf", referenced from:
_main in ccu2Qr2V.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
main.c:
#include <stdio.h>
#include "wtf.h"
main(){
wtf();
}
wtf.h:
void wtf();
wtf.c:
void wtf(){
printf("I never see the light of day.");
}
Now, if I include the entire function in the header file instead of just the signature, it complies fine so I know wtf.h is being included. Why doesn't the compiler see wtf.c? Or am I missing something?
Regards.
You need to link wtf with your main. Easiest way to compile it together - gcc will link 'em for you, like this:
gcc main.c wtf.c -o main
Longer way (separate compilation of wtf):
gcc -c wtf.c
gcc main.c wtf.o -o main
Even longer (separate compilation and linking)
gcc -c wtf.c
gcc -c main.c
gcc main.o wtf.o -o main
Instead of last gcc call you can run ld directly with the same effect.
You are missing the fact that merely including a header doesn't tell the compiler anything about where the actual implementation (the definitions) of the things declared in the header are.
They could be in a C file next to the one doing the include, they could come from a pre-compiled static link library, or a dynamic library loaded by the system linker when reading your executable, or they could come at run-time user programmer-controlled explicit dynamic loading (the dlopen() family of function in Linux, for instance).
C is not like Java, there is no implicit rule that just because a C file includes a certain header, the compiler should also do something to "magically" find the implementation of the things declared in the header. You need to tell it.

Resources