error when trying to link with static c standard library - c

My OS is ubuntu 14.04 32bit and my source program test.c is :
#include <stdio.h>
int main(int argc, char *argv[])
{
printf("test.");
return;
}
I compile it with command :
gcc -S test.c
which output as a test.s file. I assemble it with command :
as -o test.o test.s
then I want to link it with c standard library statically. I searched for libc.a file , located it at /usr/lib/i386-linux-gnu/libc.a. so I tried to link it with command:
ld test.o /usr/lib/i386-linux-gnu/libc.a
but comes out with a lot of error message:
ld: warning: cannot find entry symbol _start; defaulting to 0000000008048210
/usr/lib/i386-linux-gnu/libc.a(backtrace.o): In function `backtrace_helper':
(.text+0x20): undefined reference to `_Unwind_GetIP'
/usr/lib/i386-linux-gnu/libc.a(backtrace.o): In function `backtrace_helper':
(.text+0x45): undefined reference to `_Unwind_GetGR'
/usr/lib/i386-linux-gnu/libc.a(backtrace.o): In function `backtrace_helper':
(.text+0x50): undefined reference to `_Unwind_GetCFA'
/usr/lib/i386-linux-gnu/libc.a(backtrace.o): In function `__backtrace':
(.text+0xb1): undefined reference to `_Unwind_Backtrace'
/usr/lib/i386-linux-gnu/libc.a(iofclose.o): In function `_IO_new_fclose':
(.text+0x1b1): undefined reference to `_Unwind_Resume'
/usr/lib/i386-linux-gnu/libc.a(iofclose.o):(.eh_frame+0x167): undefined reference to `__gcc_personality_v0'
/usr/lib/i386-linux-gnu/libc.a(iofflush.o): In function `_IO_fflush':
(.text+0xd7): undefined reference to `_Unwind_Resume'
/usr/lib/i386-linux-gnu/libc.a(iofflush.o):(.eh_frame+0xdf): undefined reference to `__gcc_personality_v0'
/usr/lib/i386-linux-gnu/libc.a(iofputs.o): In function `_IO_fputs':
(.text+0xf9): undefined reference to `_Unwind_Resume'
/usr/lib/i386-linux-gnu/libc.a(iofputs.o):(.eh_frame+0xdf): undefined reference to `__gcc_personality_v0'
/usr/lib/i386-linux-gnu/libc.a(iofwrite.o): In function `_IO_fwrite':
(.text+0x139): undefined reference to `_Unwind_Resume'
/usr/lib/i386-linux-gnu/libc.a(iofwrite.o):(.eh_frame+0xdf): undefined reference to `__gcc_personality_v0'
/usr/lib/i386-linux-gnu/libc.a(iogetdelim.o): In function `_IO_getdelim':
(.text+0x285): undefined reference to `_Unwind_Resume'
/usr/lib/i386-linux-gnu/libc.a(iogetdelim.o):(.eh_frame+0xdf): undefined reference to `__gcc_personality_v0'
/usr/lib/i386-linux-gnu/libc.a(wfileops.o): In function `_IO_wfile_underflow':
(.text+0x5fc): undefined reference to `_Unwind_Resume'
/usr/lib/i386-linux-gnu/libc.a(wfileops.o):(.eh_frame+0x137): undefined reference to `__gcc_personality_v0'
/usr/lib/i386-linux-gnu/libc.a(fileops.o): In function `_IO_new_file_underflow':
(.text+0x40b): undefined reference to `_Unwind_Resume'
/usr/lib/i386-linux-gnu/libc.a(fileops.o):(.eh_frame+0x1b3): undefined reference to `__gcc_personality_v0'
/usr/lib/i386-linux-gnu/libc.a(strtof_l.o): In function `____strtof_l_internal':
(.text+0xbc6): undefined reference to `__divdi3'
/usr/lib/i386-linux-gnu/libc.a(strtof_l.o): In function `____strtof_l_internal':
(.text+0xc08): undefined reference to `__moddi3'
/usr/lib/i386-linux-gnu/libc.a(strtof_l.o): In function `____strtof_l_internal':
(.text+0x249d): undefined reference to `__divdi3'
/usr/lib/i386-linux-gnu/libc.a(strtod_l.o): In function `____strtod_l_internal':
(.text+0xcc9): undefined reference to `__divdi3'
/usr/lib/i386-linux-gnu/libc.a(strtod_l.o): In function `____strtod_l_internal':
(.text+0xd0b): undefined reference to `__moddi3'
...
...
My question is, why these error messages ? I'm trying to learn how the compiling system works, so instead of knowing how to solve this problem I 'm more desiring to know how it comes this way. It seems that the static C library depends on other libraries, why and what are those libraries ?
EDIT:
I'm doing this because I want to know how things work so I'd rather avoid the gcc script.

You also need crt0 startup object files (in addition of static libc.a), which notably are defining the _start entry point (in your ELF executable) and contain ABI specific (prologue and epilog) code to call your main (and finally process atexit(3) registered handlers and stdio flushing). The low-level libgcc is also needed. Details are complex and implementation specific. To understand them, compile your test code as
gcc -v -static test.c -o mytest
(avoid calling an executable test because it would collide with /usr/bin/test or with the builtin of your shell)
In practice, better at least link with gcc
If you are curious, take advantage that Linux is mostly free software and study the source code (e.g. of GCC, of the C standard library, of binutils, etc...). You might find musl-libc interesting.
I'd rather avoid the gcc script
Technically, gcc is not a script but a driver program (see gcc/gcc.c in the source code of GCC). But it will run ld which indeed runs some linker scripts. The actual compilation is done by cc1 which is started by the gcc program.

You must also link the gcc intrinsic library. The easiest way to do this is to use the gcc front-end to compile and link with the -static option:
gcc -static -o test test.c
If you insist on compiling from assembly, you can do this:
gcc -static -o test test.s
Static linking may not be supported on your system.
EDIT: giving gcc the -v option will tell you what commands it executes.

Related

Compiling using arm-none-eabi-gcc and linking library liba.a error

I am compiling a hello world program in C on a 64-bit Linux machine. I am using a GCC ARM embedded toolchain to cross compile my program on a FOX G20 V board with an ATMEL AT91SAM9G20 processor.
On the first take, I had a few errors when compiling because the program didn't recognize the printf, return etc. functions (the standard C functions). So I decided to make the link between the functions, which I believe are defined in the libc.a library (correct me if I'm wrong), by doing arm-none-eabi-gcc -o hello hello.c libc.a but the outcome still results in errors:
libc.a(lib_a-exit.o): In function `exit':
exit.c:(.text.exit+0x16): undefined reference to `_exit'
libc.a(lib_a-sbrkr.o): In function `_sbrk_r':
sbrkr.c:(.text._sbrk_r+0xc): undefined reference to `_sbrk'
libc.a(lib_a-writer.o): In function `_write_r':
writer.c:(.text._write_r+0x10): undefined reference to `_write'
libc.a(lib_a-closer.o): In function `_close_r':
closer.c:(.text._close_r+0xc): undefined reference to `_close'
libc.a(lib_a-fstatr.o): In function `_fstat_r':
fstatr.c:(.text._fstat_r+0xe): undefined reference to `_fstat'
libc.a(lib_a-isattyr.o): In function `_isatty_r':
isattyr.c:(.text._isatty_r+0xc): undefined reference to `_isatty'
libc.a(lib_a-lseekr.o): In function `_lseek_r':
lseekr.c:(.text._lseek_r+0x10): undefined reference to `_lseek'
libc.a(lib_a-readr.o): In function `_read_r':
readr.c:(.text._read_r+0x10): undefined reference to `_read'
collect2: error: ld returned 1 exit status
I'm really unsure as to why the program still does not recognize the standard functions even though I've linked the library to the application. If anyone has a reason as to why, or a solution as to how I can fix this problem, I would be very grateful.
UPDATE
I've downloaded the glibc library from here. I've compiled and created a static library from the syscalls.c library that I found in newlib-2.1.0/libgloss/arm and when I link the library to my application code, I still get the same error.
Try executing this:
arm-none-eabi-gcc --specs=rdimon.specs -lgcc -lc -lm -lrdimon -o hello hello.c
Your toolkit seems to provide the librdimon.a, a library which provides the basic standard C functions.
I got this error because my binary cannot fit the ROM.
My first error was:
address 0x34000 of arm_flash.elf section `.mmu_tbl' is not within region `ps7_ram_0`
Then I've got the same list of undefined reference errors.
I need to reduce the binary size, by removing new keywords, and all dynamic memory allocation from my C++ code.

Cannot find libcrypto library error

When i am trying to compile a C code which uses openssl 'crypto' library functions with comand line -lcrypto with gcc 4.4.3 it gives an error
`#ubu:$ gcc -ggdb aes_m.c -Werror -Wall -I /usr/local/ssl/include/ -lcrypto -o aes
/usr/bin/ld: cannot find -lcrypto
collect2: ld returned 1 exit status`
what can be the reason for this??
I have already gone through this discussion ld cannot find an existing library but that does not help.
locate command results in
$ locate libcrypto
/home/abhi/Downloads/openssl-1.0.1b/libcrypto.a
/home/abhi/Downloads/openssl-1.0.1b/libcrypto.pc
/lib/libcrypto.so.0.9.8
/lib/i486/libcrypto.so.0.9.8
/lib/i586/libcrypto.so.0.9.8
/lib/i686/cmov/libcrypto.so.0.9.8
/usr/lib/libcrypto.so.0.9.8
/usr/lib/vmware-tools/lib32/libcrypto.so.0.9.8
/usr/lib/vmware-tools/lib32/libcrypto.so.0.9.8/libcrypto.so.0.9.8
/usr/lib/vmware-tools/lib64/libcrypto.so.0.9.8
/usr/lib/vmware-tools/lib64/libcrypto.so.0.9.8/libcrypto.so.0.9.8
/usr/local/ssl/lib/libcrypto.a
/usr/local/ssl/lib/pkgconfig/libcrypto.pc
Can someone please help on this or point out any mistake i am doing
# Daniel Roethlisberger tried using the -L flag but that resulted in these errors
gcc -ggdb aes_m.c -Werror -Wall -I /usr/local/ssl/include/ -L /usr/local/ssl/lib -lcrypto -o aes
/usr/local/ssl/lib/libcrypto.a(dso_dlfcn.o): In function `dlfcn_globallookup':
dso_dlfcn.c:(.text+0x2d): undefined reference to `dlopen'
dso_dlfcn.c:(.text+0x43): undefined reference to `dlsym'
dso_dlfcn.c:(.text+0x4d): undefined reference to `dlclose'
/usr/local/ssl/lib/libcrypto.a(dso_dlfcn.o): In function `dlfcn_pathbyaddr':
dso_dlfcn.c:(.text+0x8f): undefined reference to `dladdr'
dso_dlfcn.c:(.text+0xe9): undefined reference to `dlerror'
/usr/local/ssl/lib/libcrypto.a(dso_dlfcn.o): In function `dlfcn_bind_func':
dso_dlfcn.c:(.text+0x4b1): undefined reference to `dlsym'
dso_dlfcn.c:(.text+0x590): undefined reference to `dlerror'
/usr/local/ssl/lib/libcrypto.a(dso_dlfcn.o): In function `dlfcn_bind_var':
dso_dlfcn.c:(.text+0x611): undefined reference to `dlsym'
dso_dlfcn.c:(.text+0x6f0): undefined reference to `dlerror'
/usr/local/ssl/lib/libcrypto.a(dso_dlfcn.o): In function `dlfcn_unload':
dso_dlfcn.c:(.text+0x755): undefined reference to `dlclose'
/usr/local/ssl/lib/libcrypto.a(dso_dlfcn.o): In function `dlfcn_load':
dso_dlfcn.c:(.text+0x837): undefined reference to `dlopen'
dso_dlfcn.c:(.text+0x8ae): undefined reference to `dlclose'
dso_dlfcn.c:(.text+0x8f5): undefined reference to `dlerror'
collect2: ld returned 1 exit status
Many thanks
Add -L /usr/local/ssl/lib/ into the GCC command line, before the -lcrypto. Since you are building against the OpenSSL headers under /usr/local/ssl, you also need to link against the actual library under the same prefix (even though you only appear to have a static one installed there, that may or may not be your intention; you may need to properly reinstall your OpenSSL built from source).
(edit) To fix the dlopen() and friends not being found by the linker, add -ldl into the GCC command line. -ldl tells the linker to also link against libdl.so, which is the shared library containing dlopen(), dlsym(), dlclose() etc.; these functions are used by OpenSSL internally and thus, -ldl is an indirect dependency when using -lcrypto (on Linux). Because you are linking to a static version of libcrypto, you need to explicitly link against all indirect dependencies.
If you are not familiar with linking to the proper libraries, I'd suggest you use OpenSSL as installed from your Operating System package manager; it might save you some trouble.
This might be relevant for people who tried to build their own openssl from source and then use it to compile other programs (in my case Git)
During configuration of openssl, add 'shared' option:
./config shared
This will create the required shared library libcrypto.so. You'll find more in the INSTALL file.
Also, if you run into this error during 'make'
"....can not be used when making a shared object
recompile with -fPIC
./config shared -fPIC

Problem with library libpq in Debian

I'm installing postgresql 8.4 in Debian, put program testlibpq.c from http://www.postgresql.org/docs/9.0/interactive/libpq-example.html to directory which have file libpq-fe.h, but after compilation gcc write me
testlibpq.c:(.text+0x4a): undefined reference to `PQconnectdb'
testlibpq.c:(.text+0x5a): undefined reference to `PQstatus'
testlibpq.c:(.text+0x6f): undefined reference to `PQerrorMessage'
testlibpq.c:(.text+0xa9): undefined reference to `PQexec'
testlibpq.c:(.text+0xb9): undefined reference to `PQresultStatus'
testlibpq.c:(.text+0xcf): undefined reference to `PQerrorMessage'
testlibpq.c:(.text+0xf5): undefined reference to `PQclear'
testlibpq.c:(.text+0x10d): undefined reference to `PQclear'
testlibpq.c:(.text+0x121): undefined reference to `PQexec'
... e.t.c. What I must suppose to do to correct work?
Looks like you're not linking the PostgreSQL library. You should be compiling testlibpq.c with something like this:
gcc -o testlibpq testlibpq.c -lpq
The -lpq tells the linker to link against the PostgreSQL library and that's where PQconnectdb and friends come from.
You may need to tell the compiler where to find the libraries and headers as well, if so then something like this should sort that out:
gcc -o testlibpq -I$(pg_config --includedir) -L$(pg_config --libdir) -o testlibpq $(pg_config --libs)

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.

Statically link ncurses to program

I'm having some problems statically linking ncurses to one of my programs
Here's a really simple sample program:
#include<ncurses.h>
int main(){
initscr();
printw("Hello world\n");
refresh();
getch();
endwin();
return 0;
}
When I compile it with
gcc -static -lncurses hello_curses.c -o curses
I get these errors:
/tmp/ccwHJ6o1.o: In function `main':
curses_hello.c:(.text+0x5): undefined reference to `initscr'
curses_hello.c:(.text+0x14): undefined reference to `printw'
curses_hello.c:(.text+0x1b): undefined reference to `stdscr'
curses_hello.c:(.text+0x20): undefined reference to `wrefresh'
curses_hello.c:(.text+0x27): undefined reference to `stdscr'
curses_hello.c:(.text+0x2c): undefined reference to `wgetch'
curses_hello.c:(.text+0x31): undefined reference to `endwin'
collect2: ld returned 1 exit status
I'm a little confused why this isn't working. What am I missing here?
You need to pass -l options at the end of the command line:
gcc -static hello_curses.c -o curses -lncurses
When the compiler encounters -lfoo, it links in all the symbols from foo that have been requested by a previous file. If you put -lfoo at the beginning, no symbol has been requested yet, so no symbol gets linked.
Edit:
I think the real problem is that you need to specify your -l option at the end of the command. I just tried it the way you had it and reproduced your error. If I put -l:libncurses.a at the end of the line then it works. All without the -static option BTW.
I think what is happening is that you have a dynamic library for ncurses but you have used the -static option which means to not use any dynamic libraries. I suspect you do not actually have a static version of the ncurses library i.e. one ending with a .a suffix.
If you want to link with the static version (.a) of ncurses rather than the dynamic version (.so) then temporarily remove the symlink for libncurses.so so that the linker picks up the .a file instead. Alternatively copy the .a file somewhere else and add that to an earlier search path.
Alternatively if your linker supports it (eg. ld) then you could specify -l:libncurses.a instead of -lncurses.
I just spent a few hours on an ARM processor, trying to get it to work, as the accepted answer didn't work for me.
Here are my findings:
Apparently
gcc -static hello_curses.c -o curses -lncurses
works on an x64 processor, but not on an ARM processor.
When I tried with the above line, I still got all the "undefined reference errors" (and a lot more) of the OP.
You need to also link against libtinfo.a, and note that sequence matters.
This is the correct command line that works:
gcc -static hello_curses.c -o curses -lncurses -ltinfo
If you mix up the sequence, then it won't work...
gcc -static hello_curses.c -o curses -ltinfo -lncurses
undefined reference to `unctrl'
Of course this also works if you use the :lib syntax
This compiles
gcc -static hello_curses.c -o curses -l:libncursesw.a -l:libtinfo.a
This does not compile
gcc -static hello_curses.c -o curses -l:libtinfo.a -l:libncursesw.a
Oh how I like gcc...
This program should never have been allowed to graduate from kindergarden
(.text+0x2a8): undefined reference to cur_term'
/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_color.o):
In functioninit_pair': (.text+0x2ac): undefined reference to
cur_term'
/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_color.o):
In functioninit_pair': (.text+0x50a): undefined reference to tparm'
/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_color.o):
In functioninit_pair': (.text+0x518): undefined reference to
_nc_putp'
/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_color.o):
In functioninit_color': (.text+0x552): undefined reference to
cur_term'
/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_color.o):
In functioninit_color': (.text+0x556): undefined reference to
cur_term'
/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_color.o):
In functioninit_color': (.text+0x5e4): undefined reference to
tparm'
/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_color.o):
In functioninit_color': (.text+0x5f2): undefined reference to
_nc_putp'
/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_color.o):
In functioncan_change_color': (.text+0x740): undefined reference to
cur_term'
/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_color.o):
In functioncan_change_color': (.text+0x744): undefined reference to
cur_term'
/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_color.o):
In functionhas_colors': (.text+0x768): undefined reference to
cur_term'
/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_color.o):
In functionhas_colors': (.text+0x76c): undefined reference to
cur_term'
/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_color.o):
In functioncolor_content': (.text+0x7c2): undefined reference to
cur_term'
/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_color.o):(.text+0x7c6):
more undefined references tocur_term' follow
/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_color.o):
In function _nc_do_color': (.text+0x8de): undefined reference to
tparm'
/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_color.o):
In function _nc_do_color': (.text+0x8e6): undefined reference to
tputs'
/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_color.o):
In function _nc_do_color': (.text+0x958): undefined reference to
tputs'
/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_color.o):
In function set_foreground_color': (.text+0x62): undefined reference
totputs'
/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_color.o):
In function set_background_color': (.text+0xa2): undefined reference
totputs'
/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_hline.o):
In function whline': (.text+0xec): undefined reference toacs_map'
/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_hline.o):
In function whline': (.text+0xf0): undefined reference toacs_map'
/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_add_wch.o):
In function wadd_wch': (.text+0x4fe): undefined reference to
TABSIZE'
/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_add_wch.o):
In function wadd_wch': (.text+0x502): undefined reference to
TABSIZE'
/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_add_wch.o):
In function wecho_wchar': (.text+0x6d8): undefined reference to
TABSIZE'
/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_add_wch.o):
In function wecho_wchar': (.text+0x6dc): undefined reference to
TABSIZE'
/usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_wunctrl.o):
In function wunctrl': (.text+0x30): undefined reference tounctrl'
collect2: error: ld returned 1 exit status

Resources