How to link a function which is never referenced in C - c

The linker's default behavior is to exclude all functions which is never referenced. However I want to include such a function for debugging purpose : when program runs abnormally, I can manually set PC to the address of this function and giving some information output.
Is there a way to do so?

The linker's default behavior is to exclude all functions which is never referenced.
That statement is false for all linkers I am familiar with: if you explicitly list the object file in which foo() is defined on the link line, then foo() is always included in the executable or shared library being linked (well, except when you specify --function-sections -Wl,--gc-sections on the link line).
It is true that if foo() is defined in an object file, and that object file is in an archive library, and that object file does not satisfy any references to any symbols it defines coming from other files already being used in the link, then that object file will not be pulled into the link.
The solution then is to either
list foo.o explicitly on the link line, or
use -Wl,--whole-archive -lfoo -Wl,--no-whole-archive (or equivalent flags for your linker, if it has them), or
add -u foo to force foo.o to be pulled into the link.

First create an object file of that c file which contains the function.
gcc <Yourfile_Name>.c -o functions.o
And use ld to create the executable. I don't know how to do this with Microsoft Visual Studio Compiler.

Related

binding .a file with the .so shared library file in linux

I have one .a file ( ar command ) which I want to bind it with my .so file during GCC compilation.
How can I do this.
If I run this command :
gcc /usr/local/apr/lib/libapr-1.a ../../ndagentlibc/obj/*.o tideways_xhprof.o tracing.o -shared -o libhello.so
nm libhello.so | grep apr_term
output: U apr_terminate
apr_terminate is not getting its defination
If your .so file needs the .a file, link your .so with the .a file and all of the needed code from the .a archive will be available in the .so file.
Reorder your command and put the .a library at the end...
gcc ../../ndagentlibc/obj/*.o tideways_xhprof.o tracing.o -shared -o libhello.so /usr/local/apr/lib/libapr-1.a
as the ld(1) linker only selects the object modules (*.o) included in a library archive that it knows have unsolved references for at the moment of reading it (as you put it first in your command line, no unsolved references appear by that time, so no library .o component is selected and included at the time of library processing)
In the case of an archive of object modules, the linker tries to do its best, selecting only the ones that appear to be necessary, and putting an archive at first makes the linker to select no files from it to be linked.
note
BTW, the -shared option is used to create a shared object (a .so module) which probably is not what you want. If you want to create a final executable program, don't use -shared. I point at this, because the first time I had to fight with this, I assumed the kind of linking (shared or static) was specified with some option (common mistake, I think) but the kind of linking is actually given, object by object, by the kind of file you feed to the linker, and not with a command line option. Apart of other things, it makes the linker not to comply when some references are missing in the program (it assumes those will be resolved in a later linking)

(Cygwin) C program linked to custom header file having memory problems when trying to execute

I am using Cygwin. I have two files in the same directory, test.c and iah202_graphics.h. test.c uses functions from the header file, where I have used #include "iah202_graphics.h". I have added the Cygwin directory to my Environment Variables (PATH) already.
However I receive these errors for every function call:
$ gcc -o test test.c
/cygdrive/c/Users/Matthew/AppData/Local/Temp/cclm2bNk.o:test.c:(.text+0x27): undefined reference to `draw_line'.
/cygdrive/c/Users/Matthew/AppData/Local/Temp/cclm2bNk.o:test.c:(.text+0x27): relocation truncated to fit:
R_X86_64_PC32 against undefined symbol `draw_line'.
/cygdrive/c/Users/Matthew/AppData/Local/Temp/cclm2bNk.o:test.c:(.text+0x4a): undefined reference to
`draw_line'.
collect2: error: ld returned 1 exit status.
It's having trouble linking to the header file even though I've simply stated which file to use in the local directory. I don't understand what I'm doing wrong?
Undefined reference to 'blah' is a linker error rather than a compiler error and is almost always caused by not including a needed library.
Including a header file in your source file does not usually link in the code required to provided the functions declared in that header.
For example, were you to prevent linking of the C runtime library, you could include stdio.h as many times as you wanted to, and still not be able to resolve printf.
Bottom line, you generally need two steps:
include the relevant header file in your source code so it knows about the declarations of things provided; and
link against the relevant library or object file so it has access to the definitions of the things provided.
That could be something as simple as:
gcc -o test -I/path/to/iah202includes test.c -L/path/to/iah202libs -liah202
where -I indicates where include files can be found, -L adjusts the search path for library files, and -l actually specifies the library file to use.
Even simpler is if you have the source file for the graphics stuff (which seems to be the case based on your comments). In that case no library is needed, you can simply use:
gcc -o test test.c iab202_graphics.c
and that will compile both those translation units then link them together.

Why the order of object files is important for static libraries?

I create some files:
file1.c
file2.c
file3.c
I compile them using gcc -c file1.c and i did the same for other files, and i get object files. Later i used ar tool to create static library.
Everythink works correctly, but ar has option
ar -m -a file.o lib.a filetomove.o
to move object files in library, why order of object files is important? Please, show me example where object files must be in correct order.
This is less and less of a problem as time goes on, but for a long time linkers were single pass. That means if a symbol was defined in a.o and referenced in b.o, the linker had to "see" b.o before a.o or it would never find a definition for the reference.
In other circumstances, sometimes a "default" function is provided in a library that is linked last. This is a popular technique in embedded systems development. You can provide an override function by linking it in a static library or object module, but if you don't, the last library will provide a symbol that satisfies the linker.

GCC: undefined reference to xxx

I know that have been already asked a lot of time but I can't really solve it...
so I have a src folder where my main.c source is, an srclib where my lib.c file is stored and an include directory where my lib.h file is stored. now the makefile compiles the lib correctly and put the lib.a file in lib folder. the main.cincludes the lib like this:
#include "lib.h"
and it's compiled with -I ../include option, but when i compile it I get the undefined reference to xxx error for every function in the library
so what am I missing?
Nope. -I is for including the header files. You also need to link with the library using -l option.
Note: You may need to provide the path-to-library using -L option.
To quote the online gcc manual
-llibrary
Search the library named library when linking...... The linker searches a standard list of directories for the library, which is actually a file named liblibrary.a. The linker then uses this file as if it had been specified precisely by name.
EDIT:
To quote the remaining part of the same manual
It makes a difference where in the command you write this option; the linker searches and processes libraries and object files in the order they are specified. Thus, foo.o -lz bar.o searches library z after file foo.o but before bar.o. If bar.o refers to functions in z, those functions may not be loaded.
So, you need to put the -l<libanme> at the last of your compilation statement, as s_echo.c uses functions defined in that particular library.

object file from .a not included in .so

I have created a .c file which is being converted to a .o file along with around 300 other .c files and included in a .a static library. This library, along with many others is being used to create a .so dynamic library. On analyzing both the .a and the .so file with nm, I found that for some reason the symbols defined in the .c file are present in the .a file but not in the .so file. I can think of no reason this should happen. Can somebody please help me out here? The steps used to create the two binaries are:
gcc -fvisibility=hidden -c foo.c -o foo.c.o
ar cr libbar.a foo.c.o ...
gcc -fvisibility=hidden -fPIC -o libfinal.so libbar.a x.o y.a ...
The reason I have specified visibility hidden here is that I want to expose only a few selected symbols. To expose the symbols from foo.c I have specified the visibility attribute so that the functions signatures in the header foo.h look like:
extern int _____attribute_____ ((visibility ("default"))) func();
EDIT: The command nm libbar.a | grep Ctx gives:
000023c5 T CtxAcquireBitmap
000026e9 T CtxAcquireArray
00001e77 T CtxCallMethod
However, nm libfinal.so | grep Ctx does not show anything.
UPDATE: Found another post which discusses the uses of the --whole-archive option. Also, stumbled across the --export-dynamicoption which apparently tells the linker to retain unreferenced symbols. Investigating further.
Try using --whole-archive linker option to include all objects into your shared library when linking
gcc -o libfinal.so -Wl,--whole-archive libbar.a x.o y.a -Wl,--no-whole-archive
From man ld:
--whole-archive
For each archive mentioned on the command line after the --whole-archive option, include every object file in the archive in the
link, rather than searching the archive for the required object files. This is normally used to turn an archive file into a shared
library, forcing every object to be included in the resulting shared library. This option may be used more than once.
Two notes when using this option from gcc: First, gcc doesn't know about this option, so you have to use -Wl,-whole-archive.
Second, don't forget to use -Wl,-no-whole-archive after your list of archives, because gcc will add its own list of archives to your
link and you may not want this flag to affect those as well.
As far as I know, when compiling against a .a, gcc will only pull out the objects that are referenced by the other modules. If your intent is to include the whole content of the .a in the .so, a plain "compile/link x.c into libfinal.so using content in libbar.a" is not what you want.
Creating a dummy reference for the required symbols in my main file did not solve the problem. The referenced symbols appeared in the binary dump (obtained using nm) with a U (= undefined) marker. I managed to solve the problem by linking the object file directly when creating the .so file instead of including it in the .a library first. As these functions were marked extern they were included in the .so even though they were not being referenced within the library. Had they not been marked extern, they would not have been included just like sylvainulg said.
Thanks to Dmitry for pointing out the --whole-archive option. I did not know that such an option exists.

Resources