Linking troubles in C - 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.

Related

Calling functions from an external C file that has its own main()

I have two C files, program.c and tests.c, that each contain a main function.
program.c is a standalone program, that compiles and run normally on its own. But I would like to also be able to use some of its functions in tests.c (without using a common header file). Is there a way of doing this?
If I insert the prototype of the function I want from program.c into tests.c and compile with:
gcc -o program.o -c program.c
gcc -o tests.o -c tests.c
gcc -o tests tests.o program.o
I obtain an error duplicate symbol _main, which I understand since there are indeed two `main' functions.
I basically would like to be able to treat program.c both as a standalone program and as a library, similarly to what could be done in Python with if __name__ == '__main__'.
If you need to have two separate distinct executables for which some of the functionality between them is similar you can share the common functionality by placing relevant functions into a third file, and compiling as a portable executable, DLL in Windows. (or shared library in Linux.) Each of these file types contain sharable, executable code, ithout the main() function, designed to be linked during compile time, and dynamically loaded into your executable at runtime.
Here is a step by step set of instructions for shared library using GCC and Linux.
Here is a step by step example for creating DLL using GCC in windows.
So I managed to achieve what I wanted thanks to the comment from #pmg:
I compile program.c into a standalone binary (gcc -o program program.c), but I also compile it into an object file with "main" renamed (gcc -c -Dmain=mainp -o program.o program.c).
I can then use this object file (that does not contain a "main" symbol anymore) to compile tests.c: gcc -o tests tests.c program.o.
Thanks #pmg, I did not know this use of the -D option.

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.

Couldnot execute the dynamically linked program

Hi I tried doing static library and a shared library with the gnu compiler, here is following code
following is the code for the library
calc_mean.c
double mean(double a, double b){
return (a+b)/2;
}
following is my header file calc_mean.h
double mean(double,double);
Now i started creating static library using following commands
first , calc_mean.c is turned into an object file
gcc -c calc_mean.c -o calc_mean.o
second ,the archiver (ar) is invoked to produce a static
library (named libmean.a) out of the object file calc_mean.o
ar rcs libmean.a calc_mean.o
third, created shared library before that using -fPIC option
created an independant code which is necessary for shared library
gcc -c -fPIC calc_mean.c -o calc_mean.o
now the shared library is created using following command line
gcc -shared -Wl,-soname,libmean.so.1 -o libmean.so.1.0.1 calc_mean.o
finally my main.c file that uses the library is as follows
#include <stdio.h>
#include "calc_mean.h"
int main(int argc, char* argv[]){
double v1,v2,m;
v1 = 5.2;
v2 = 7.9;
m=mean(v1,v2);
printf("The mean of %3.2f and %3.2f is %3.2f\n",v1,v2,m);
return 0;
}
finally I linked the program against static library that generated a statically_linked.exe
gcc -static main.c -L. -lmean -o statically_linked
when dynamically linked, it generated a dynamically_linked.exe with the following command
gcc main.c -o dynamically_linked -L. -lmean
Now when i use the command to execute the dynamically linked program using the following command, Iam getting an error message saying LD_LIBRARY is not recognized as an internal or external command,operable program or batch file
LD_LIBRARY_PATH=.D:\c\project3./dynamically_linked
how can I execute the dynamically linked program?
Your last line suggests that you do all this on windows. But you seem to have followed a step by step guide for linux or another *nix platform.
On windows, a dynamically linked library is in .dll format (not .so) and there's no versioning convention, so the command to create the shared library should look a little different.
Instead of:
gcc -shared -Wl,-soname,libmean.so.1 -o libmean.so.1.0.1 calc_mean.o
do the following on windows:
gcc -shared -Wl,--out-implib,libmean.dll.a -o mean-1.dll calc_mean.o
This creates the library itself named mean-1.dll as well as an import library named libmean.dll.a. The import library (sometimes called .lib instead of .dll.a) on the windows platform is just a stub used during linking of your program, AFAIK MinGW doesn't need it, but other compilers could.
Linking your main program should then work with the same command:
gcc main.c -o dynamically_linked -L. -lmean
And for finding .dll libraries in windows, there is no LD_LIBRARY_PATH -- windows just looks for them in the standard search path, including the directory of the .exe requiring it. IOW, you should be able to just run your program.

How to compile a C program with a personal library that includes threads

I created a library for my C programs and this includes threads. I usually work with Code::Blocks and I never had problems, but now I need to compile programs directly from terminal. I saw that I need to write -lpthread but also my library name (its name is my_lib.h). I tried to compile first the library with gcc my_lib.c -c and this works; after, I tried this gcc main.c my_lib.h -o main -lpthread, but this doesn't work.
So what is the correctly sintax to compile this program that uses my_lib.h?
I assume my_lib.c is just a module (object file) rather than shared library.
The compiling consists of two parts - compiling into object files and then linking:
# compiling (note the -c)
gcc -c my_lib.c
gcc -c main.c
# linking (no -c, just specify target with -o)
gcc -o main main.o my_lib.o -lpthread
Header files are never compiled (explicitly), they are just included from the .c files and therefore never produce .o file.

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.

Resources