How to link my C program to a static/dynamic library? - c

I'm trying to link my C program to both a static and dynamic library to see the difference. How do I do that?
I've made my own Makefile:
# ------ executable rule -----------
app : app.o
-gcc -g app.o -o app
# ------ intermeditate object files rule (.o) -------
app.o : main.c
-gcc -g -c main.c -o app.o
I've only shown you some of my Makefile as I think the rest is unnecessary.
I've tried to write -L. lstatic after -gcc -g app.o -o app but it didn't work.

Read about invoking GCC. Order of arguments to gcc matters a lot!
You could use -static or -Bstatic
You can also explicitly link with static libraries, by giving some /usr/lib/libfoo.a (or some appropriate file path) argument at link time.
You'll better improve your Makefile to use existing builtin rules (try make -p) and conventional variables, e.g. like here. Read the documentation of GNU make.

Related

C Link External Library in Makefile

I am having issues linking a library (termbox) when compiling. I get the error:
make: *** No rule to make target `termbox.h', needed by `test.o'. Stop.
Makefile:
edit: test.o
gcc -Wall -o edit test.o
test.o: test.c termbox/src/termbox.h
gcc -Wall -c test.c -ltermbox/src
Include:
#include "termbox/src/termbox.h"
I have also tried using the compiled library but ran into similar issues. Do I have to use some sort of combination of specifying the header file and the location of the compiled library?
The directory of my termbox folder is in the same directory as test.c.
Thanks!
You have managed to compile and include the header file for the library, but you did not yet tell the compiler where the code (definitions) are - i.e. you did not tell it to link in the library yet.
You will need to do that next, this is done in a similar way to telling the linker what files to link, but with some extra syntax. It appears to be a static library (.a suffix) so you can link like this:
test.o: test.c termbox/src/termbox.h
gcc -Wall -c test.c -Itermbox/src -Lsrc -ltermbox
Where -L... specifies where libraries can be found and -l... specifies the library name to link to minus the lib prefix and the .a or .so suffix. Also note that order is important, so leave the library linkage at the end.
More on library linking order here
UPDATE
Sorry I added the linking to the wrong line! - here is the updated answer:
# The linker stage
edit: test.o
gcc -Wall -o edit test.o -Lsrc -ltermbox
# Compile stage
test.o: test.c termbox/src/termbox.h
gcc -Wall -c test.c -ltermbox/src

Using a static library in C

I found a useful library on github for my project, after building this later I tried to use some predefined function on it. I couldn't compile my project because there is some header file missing like this one :
In file included from main.c:2:0:
ptask.h:11:19: fatal error: ptime.h: No such file or directory
I compiled my project using this command :
gcc main.c -L. -lptask
This is all the files in project folder :
libptask.a main.c ptask.h
This is the library content:
$ ar -t libptask.a
pbarrier.c.o
pmutex.c.o
ptask.c.o
ptime.c.o
rtmode.c.o
tstat.c.o
libdl.c.o
dle_timer.c.o
calibrate.c.o
Do I need to add all the headers of this files or just link the lib when compiling ?
Your main.c #include-s ptask.h which in turn #include-s ptime.h. Having compiled static libs alone is not enough (that's the linker's job), you still need to have all used header files (which is the compiler's job), both the ones you use and their dependencies, recursively applicable.
Normally you need to be sure that the header files are in your "include path", something that a lot of compilers define with -I as a command-line option. You'll need to include the source directory of that library, or if it has a make install option, then the place where they got installed.
regarding:
gcc main.c -L. -lptask
this is performing the compile step and the link step in one command.
It is also not enabling the warnings, which should always be enabled during the compile step.
Suggest something similar to the following to compile
gcc -Wall -Wextra -Wconversion -pedantic -std=gnu11 -g -c main.c -o main.o -I.
and when you have fixed all the warnings, then use something similar to the following to link
gcc main.o -o main -L. -lptask

make - specify library to link from the command line (without Makefile)

For simple program eg, proc.c which has only one source file, it's convenient to compile and link using just make proc, which by default search for proc.c and create proc as output file. There is no need to create a Makefile for that.
If proc.c requires to link with some library such as the math library (defined by <math.h>). Using gcc directly, we can use gcc -c proc.c -o proc -lm. Is there an equivalent make command line option to specify -lm so we can use make command directly without writing a Makefile?
Similar task suggested by Basile Starynkevitch:
Makefile with Multiple Executables
Link library with make without makefile
If your source file is prova.c then you can do the following:
$> export LDFLAGS=-lm; make prova
or:
$> export LDLIBS=-lm; make prova # LDLIBS works on Linux (but LDFLAGS doesn't)
or:
$ make prova LDLIBS=-lm
as Make uses this implicit rule:
%: %.o # Link object file
$(CC) $(LDFLAGS) n.o $(LOADLIBES) $(LDLIBS)
Make has several implicit rules, you can see all of them with make -p.
For further information see this post.

How to include static library in makefile

I have the following makefile
CXXFILES = pthreads.cpp
CXXFLAGS = -O3 -o prog -rdynamic -D_GNU_SOURCE -L./libmine
LIBS = -lpthread -ldl
all:
$(CXX) $(CXXFILES) $(LIBS) $(CXXFLAGS)
clean:
rm -f prog *.o
I am trying to include the ./libmine library within CXXFLAGS, but it seems like it is not the right way to include a static library, because when I compile the program, I get many undefined references error. So what is actually the right way to include a static library in the makefile?
use
LDFLAGS= -L<Directory where the library resides> -l<library name>
Like :
LDFLAGS = -L. -lmine
for ensuring static compilation you can also add
LDFLAGS = -static
Or you can just get rid of the whole library searching, and link with with it directly.
Say you have main.c, fun.c and a static library libmine.a.
Then you can just do in your final link line of the Makefile
$(CC) $(CFLAGS) main.o fun.o libmine.a
CXXFLAGS = -O3 -o prog -rdynamic -D_GNU_SOURCE -L./libmine
LIBS = libmine.a -lpthread
Make sure that the -L option appears ahead of the -l option; the order of options in linker command lines does matter, especially with static libraries. The -L option specifies a directory to be searched for libraries (static or shared). The -lname option specifies a library which is with libmine.a (static) or libmine.so (shared on most variants of Unix, but Mac OS X uses .dylib and HP-UX used to use .sl). Conventionally, a static library will be in a file libmine.a. This is convention, not mandatory, but if the name is not in the libmine.a format, you cannot use the -lmine notation to find it; you must list it explicitly on the compiler (linker) command line.
The -L./libmine option says "there is a sub-directory called libmine which can be searched to find libraries". I can see three possibilities:
You have such a sub-directory containing libmine.a, in which case you also need to add -lmine to the linker line (after the object files that reference the library).
You have a file libmine that is a static archive, in which case you simply list it as a file ./libmine with no -L in front.
You have a file libmine.a in the current directory that you want to pick up. You can either write ./libmine.a or -L . -lmine and both should find the library.
The -L merely gives the path where to find the .a or .so file. What you're looking for is to add -lmine to the LIBS variable.
Make that -static -lmine to force it to pick the static library (in case both static and dynamic library exist).
Addition: Suppose the path to the file has been conveyed to the linker (or compiler driver) via -L you can also specifically tell it to link libfoo.a by giving -l:libfoo.a. Note that in this case the name includes the conventional lib-prefix. You can also give a full path this way. Sometimes this is the better method to "guide" the linker to the right location.

Linking troubles in C

I have a test.c that is using code from two libraries. One is statically linked (say libstatic.a, the other - dynamically (e.g. libdynamic.so).
I compiled my c file as follows:
gcc -I../inc -c test_subframeip_omap.c -o test_subframeip_omap.o
How do I link now the static and dynamic libraries in order to produce the final executable?
Thanks!
You generally need something like:
gcc -I../inc -c test_subframeip_omap.c -o test_subframeip_omap.o
gcc -L/path/to/libs -l static -ldynamic -o test_subframeip_omap test_subframeip_omap.o
The -L adds directories to the library search path and -l specifies a library to link with. It's also done as part of the link, not the compile.

Resources