Couldnot execute the dynamically linked program - c

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.

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.

Unable to link dynamic library in macOS

I'm trying to use a C library called quirc in my C project. So far, I have generated a libquirc.dylib.1.0 by modifying the Makefile which was using Linux .so files.
quirc/helloquirc.c
#include <quirc.h>
#include <stdio.h>
int main() {
struct quirc *qr;
qr = quirc_new();
if (!qr) {
printf("Failed to allocate memory");
}
quirc_destroy(qr);
return 0;
}
I've created the above source file at the root of the repository. I'm using the following command to compile it:
gcc helloquirc.c -lquirc -L. -Ilib -o helloquirc
To my understanding the -l flag specifies the name of the dynamic library, the -L flag specifies the location of the dynamic library, the -I flag specifies the location of the header files, and -o specifies the name of the executable.
When I run this command I get the following error:
ld: library not found for -lquirc
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I changed the Makefile by using this line
.PHONY: libquirc.dylib
libquirc.dylib: libquirc.$(LIB_VERSION).dylib
libquirc.$(LIB_VERSION).dylib: $(LIB_OBJ)
$(CC) -shared -dynamiclib -o $# $(LIB_OBJ) $(LDFLAGS) -lm
and changing other instances of .so.$(LIB_VERSION) to .$(LIB_VERSION).dylib
Something is wrong with the way quirc was built. The correct library name would be something like libquirc.1.0.dylib with a symlink named libquirc.dylib.
It looks like quirc has a handwritten makefile instead of using something sensible like gyp or cmake. Handwritten makefiles are just fine as long as you're not trying to build shared libraries on multiple platforms.
However, if you are just compiling it yourself, you may find things simpler if you just use a static library instead. There is no point in having a shared library if you are not sharing it with anybody (if no other programs are using the same exact copy of libquirc).

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.

C pluginsystem: symbol lookup error

I am writing a plugin system which is separated other 3 modules:
plugin_system.c - the core of the system
list.c - contains a linked list implementation for plugins' storage
plugin_interface.h - contains the declaration needed by plugins, has no source file associated with
plugin_interface.h only contains only of types and the function:
extern int plugin_register(PluginManager *plug_manager, const char *name, Plugin *plug);
which is defined in plugin_system.c
When loading a plugin, the plugin system look for a funcion init_plugname() and call it, that function must call plugin_register to register the plugin.
The program is compiled with complex recursive Makefiles (not the best idea), but what I try to achieve is:
I compile the plugin system object in the main program folder, it is then linked with the main program. From make execution:
gcc -Wall -O2 -std=gnu99 -D DEBUG -g -fPIC -c -o /home/kowa/code/reseaux/projet/ringo/c/bin/list.o list.c
gcc -Wall -O2 -std=gnu99 -D DEBUG -g -fPIC -c -o /home/kowa/code/reseaux/projet/ringo/c/bin/plugin_system.o plugin_system.c
A plugin is compiled with gcc -fPIC -c -o plugname.o plugname.c plug_system.o followed by gcc -o plugname.so plugname.o plug_system.o -shared
I try to load the plugin in my main program and get this error:
symbol lookup error: ./plugins/zyva.so: undefined symbol: exists
exists is a function in the list module used by the plugin_system module to store plugins, the plugin_register function mentionned aboved calls it.
I've never done that kind of system before and I'm not an expert in shared library, I guess the problem is from how I compile the whole project, I may miss some linkage...
I just forgot to link the plugin with list.o which is used by the plugin_system.o...

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