command to compile c files with .a files - c

I have several .c files and one .a object file. What command with gcc should I use to compile them to one exe file? If we use a makefile, how will it look like?

For simple cases you can probably do this:
gcc -o maybe.exe useful.a something.c
Makefiles for non-trivial projects usually first invoke gcc to compile each .c file to a .o object.
gcc -c something.c
Then they invoke the linker (these days often using gcc as a wrapper for it) with a list of .o and .a files to link into an output executable.
gcc -o maybe.exe useful.a something.o
Note also that for most installed libraries, it's typical not to explicitly specify the .a file but instead to say -lhandy which would be short for "try to find something called libhandy.a in the configured (or specified with -L) search directories"

*.a is a static library and not dynamic (*.dll in windows and *.so in linux)
gcc -L<here comes the library path> -l<library name>
for example for the file you have libname.a in the current path you should use:
gcc *.c -L. -lname -o myprogram.o
from the man (put man gcc in the shell command prompt)
You can mix options and other arguments. For the most part, the order
you use doesn't matter. Order does matter when you use several options
of the same kind; for example, if you specify -L more than once, the
directories are searched in the order specified. Also, the placement
of the -l option is significant.

The .a file is a library, already compiled. You compile your .c file to a .o, then you use the linker to link your .o with the .a to produce an executable.

Related

Is the GCC link option truly necessary when linking to a static library?

I've been playing around with GCC lately and have been experimenting with the linking options. I'm somewhat confused why the link option -l is necessary when statically linking to an archive file. It seems like you can just toss the .a file as if it were an ordinary object file.
For example, take the following make file:
test1 : main.c libfunc.a
gcc main.c -L. -lfunc -o main.out
test2 : main.c libfunc.a
gcc main.c libfunc.a -o main.out
libfunc.a : func1.c func2.c
gcc func1.c -c
gcc func2.c -c
ar cr libfunc.a func1.o func2.o
Make target test1 uses GCC's linking options to link to the archive file. Target test2 instead just includes the archive file direct. Building and running each output seem to result in the same executable.
There are several ways you can tell gcc what file(s) to use. An argument of the form -lname (or the two arguments -l name) says “Search for a library named name”. Per the GCC documentation, this argument is passed to the linker (typically the ld command). The linker looks for a file with a name like libname.extension, where extension is one of the known library files extensions such as .a or .so, and it looks for files with those names in a list of library directories it has. You can add directories to search with the -L switch.
When the linker finds the library, it uses it just as if you had specified the path, so the end result is the same whether you specify the library with -l or with its path.
By using the path, you can specify libraries that are not in the known library directories or that have unusual names.
Note that the linker does not process libraries the same way as object files. When the linker processes an object file, it incorporates everything in the object file into the output file being constructed. When the linker processes a library file, it incorporates only those modules within the library that provide a symbol definition for a symbol referenced by a prior module and not yet resolved. For example, if you write a program that uses sqrt but does not use sin, then, when the linker processes libm.a after reading your object module, it will take the sqrt module from the library but not the sin module.

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)

How to let gcc compiler know where a certain file is

I'm trying to compile my C code but I need to tell the GCC compiler where two file are.
The two files are located here
/usr/local/ssl/include/
/usr/local/ssl/lib/
I want to add this to my gcc -o file file.c so that my program can work.
In gcc, the -I option is used for adding a directory to the set of directories to search for header files, and the -L option is used for adding a directory to the set of directories to search for libraries. Since you're not explicitly linking in any libraries, you shouldn't need the -L option in this case.
gcc -I/usr/local/ssl/include -o file file.c
If you were linking in libraries, something like the following format should work, assuming that file.c calls a function in libmyLib.a:
gcc -I/usr/local/ssl/include -o file file.c -L/path/to/my/library -lmyLib
See this question for more details regarding library linking order.

Link .a library to .o object so only .o needs to be included when building

I'm using a pre-built library called 'libdscud-6.02.a', which includes a lot of low level I/O calls for some specific hardware. From this, I created some wrapper functions which I compiled into an object file called 'io.o'.
Now, I have a few programs which I'm compiling with these I/O functions and instead of having to do this:
gcc libdscud-6.02a io.o -o test test.c
I would like to just have this:
gcc io.o -o test test.c
Is there any way to link the .a file into the .o file so I only need to include the .o file when compiling binaries?
You could do the opposite and add the io.o file to the .a file using ar:
ar q libdscud-6.02.a io.o
One solution would be simply to use a make variable:
IO_STUFF = libdscud-6.02a io.o
...
$(CC) $(IO_STUFF) ...
AFAIK it is not possible to link .a library and .o file to create another intermediate file i.e. file which is not linked like .o file.
The solution provided by Burton Samograd look like a very good option; but in case you are not allowed to modify .a library file then you can follow suggestion provided by DarkDust in case you are building using make.
However you can create a shared library .so file, from a .a library file and .o file (I think that is what Michael Burr is trying to convey). You can use only the shared library instead of both .a & .o file to generate your executable as follows:
Generate shared library gcc io.o libdscud-6.02.a -shared -o io.so (Please note that the order of files passed for linking is important)
Build your source with gcc io.so -o test test.c . To execute your executable path of io.so should be in the look up path of loader (ld) i.e. LD_LIBRARY_PATH.
The right way to work with shared object would be to create a libio.so which is the naming convention and not io.so and build code as gcc test.c -o test -L<path_to_libio.so> -lio and path to libio.so should be in ld's look up path for executing the output executable.
I know creating shared library just to avoid addition of another file for compilation does not seem to be what you want to do ...but it is just for your info in case you didn't already know :)

How does gcc recognize that -lfl corresponds to flex library?

when i compile lex.yy.c with lfl gcc recognizes that some .a file of the flex library might be needed to be linked with my code. similarly for yacc we specify the -ly compiler option.
in other words if i create a library, abc.a i want gcc to recognize that whenever a program is compiled with -labc it should link with the library abc.a. what configuration changes need to be done?
The yacc library is named liby.so, and lives in something like /usr/lib, which is a directory that ld knows about.
Your abc library should be named libabc.so (or ".a" for a static lib), and should be placed in a directory that is searched by ld.
To add /home/foo/libs to the list of directories searched, add -L/home/foo/libs to the ld command.
You don't need to configure anything. Call your library libabc.a, then use the command line:
gcc ... -L<path-to-libabc.a> -labc
Alternatively, if you want GCC to recognise the library abc and link it via -labc, assuming abc is a static library, make sure your library file/archive abc is named libabc.a, and it is either located in one of the directories GCC searches for .a files, or you add a -L flag where the parameter is the directory where libabc.a is located in.

Resources