Where to change LD_LIBRARY_PATH - c

I want to compile these files into executable.
//main.c
#include <stdio.h>
#include <mylib.h>
int main(void){
call_hello_world();
return 0;
}
//mylib.h
void call_hello_world(void);
//mylib.c
#include <mylib.h>
#include <stdio.h>
void call_hello_world( void ) {
printf( ”Hello world!” );
}
I tried
gcc -c -I. -fPIC -o mylib.o mylib.c
gcc -shared -o libmylib.so mylib.o
gcc -c -o main.o main.c
gcc -o hello main.o -L. -lmylib
but at the third step, I got stucked because it couldn't find my 'mylib.h'. My professor said I needed to change 'LD_LIBRARY_PATH' so I tried to add this export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/dev/shm my .zshrc but it still didn't work for me. Any suggestions what I should do?

There are several issues with your approach.
First, there is a difference between including a header file like this #include <mylib.h> and including it like that #include "mylib.h".
The first option is usually used to include standard library header files, that should be located in the standard set of directories according to the FHS on Linux.
The latter is the option you might want to use as it is usually used to include user-defined headers and tells the preprocessor to search in the directory of the file containing the directive. (See #quest49 answer's https://stackoverflow.com/a/21594/3852949)
The LD_LIBRARY_PATH environment variable is used to indicate where libraries should be searched for first before looking into the standard set of directories.
So what you would want to do to make your main.c file compile, and after changing #include <mylib.h> directive to #include "mylib.h", is to either :
Add the include file into the directory where your main.c file is located
Indicate where the include file path is with -I option to gcc

These are the commands needed :
gcc -c -I. -fPIC -o mylib.o mylib.c
gcc -shared -o libmylib.so mylib.o
gcc -c -I. -o main.o main.c
gcc -o hello main.o libmylib.so
Then in your shell:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/full/path/of/directory/containing/libmylib-so

Related

How do you link two files in make, that both include a different library?

I want to test my code in test.c which includes main.h with all the function declarations from main.c. I want to compile my test.c file with criterion, which on its own works fine like this: cc -c test.c -o testing -I include -L lib -l criterion.3.1.0 and I compile my main.c in the same way and it works fine: cc main.c -o output -I include -L lib -l SDL2-2.0.0. But when I want to include a function from main.c in test.c it gives me a linking error.
The project architecture is like this:
main.c
#include "main.h"
int function1(){
[...]
}
test.c
#include "main.h"
#include <criterion/criterion.h>
Test(sample,test_function1){
cr_assert(function1() == 1);
}
main.h
#include <SDL2/SDL.h>
extern int function1();
How do I have to compile/link these files in order to have my test-file use get access to the functions from main.c?
What you are currently doing is compiling and linking the binary in a single command for each source file in your project. The linker, with how you are doing this, is not aware of your other sources. Instead, you should first build the object files for each source file, and then you can link those together to form your binary.
Building object files:
cc -c main.c -I include -o main.o
cc -c test.c -I include -o test.o
Linking:
cc -o testing main.o test.o -Llib -lcriterion.3.1.0 -lSDL2-2.0.0

How do I create Makefile for this

Here is my header file
#include <stdio.h>
#include <stdlib.h>
#include "gd.h"
#include "gdfontmb.h"
#include "gdfontl.h"
#include "gdfontg.h"
When I run this program I usually type 'gcc -o test test.o -lm -lpng -lgd'
It works fine for only one .c file, but this is just for testing. I want to link this with others c file in my project (Actually I'm really new to use gd.h)
Here is my Makefile (but It isn't work!!)
ifeq ($(OSTYPE),WINDOWS)
EXECEXT =.exe
COMP =__MINGCC__
PLATFORM =mingw
else
EXECEXT =
COMP =__GCC__
PLATFORM =linux
endif
EXECUTABLES= test$(EXECEXT)
all : $(EXECUTABLES)
test.o : test.c
gcc -c test.c
test$(EXECEXT) : test.o
gcc -o test$(EXECEXT) test.o -lm -lpng -gd
clean :
-rm *.o
-rm $(EXECUTABLES)
Using this Makefile, I got all error about undefined reference to whatever that are in the gd library.
What did I do wrong and How can I fix this?
Your own cc command already gives the answer. You need -lgd, not -gd.
E.g. set in the start:
LIBS=-lm -lpng -lgd
CC=gcc
(the latter can be the full OS-dependent path as well, and then the CC should be part of the OS specific part, and be specified as a full path).
and change the gcc line later to
$(CC) -o test$(EXECEXT) test.o $(LIBS)
And the rule for test.o is (usually) not really needed, as it is a default way to make a .o file from a .c file.

C - programming a makefile and how they work

So given three files:
main.h
#include <stdio.h>
void printFunc(*char);
main.c
#include "main.h"
int main(){
printFunc("Hello World\n");
return 0;
}
printFunc.c
#include "main.h"
void printFunc(char *string){
printf("%s", string);
return;
}
You can compile using gcc on a linux machine as follows:
gcc -g -Wall -c file1.c //compile but do not link file
gcc -g -Wall -c file2.c //same
gcc file1.o file2.o -o main //executable "main"
or
gcc -g -Wall file1.c file2.c -o main
But I am concerned with how the header file gets included. I came across this when I was working on creating a "makefile" when I noticed that some tutorials will do something like this:
main : main.o printFunc.o
gcc -o main main.o printFunc.o
main.o : main.c
gcc -g -Wall -c -o main.o main.c
printFunc.o : printFunc.c
gcc -g -Wall -c -o printFunc.o printFunc.c
and others will include the header file as a dependent with:
main : main.o printFunc.o //main.h EDIT
//commands
main.o : printFunc.o main.h
//commands
Finally:
So, is it necessary to include the header file as a dependent to the executable? When does the include file get placed within the sources?
And also one could use this command:
executableName : dependencies.o //and a header file?
gcc -g -Wall -o executableSource.c
Which could be done with the line:
gcc -g -Wall -o executableName executableSource.c
Will the second command be run but the first is shorthand notation?
And finally, I thought the "-o" command was "send output to", if you will. If that way, it seems intuitive to run the command like:
gcc compileThisFile andSendOutputTo thisExecutableFile
gcc someSource.c -o executableFile
But with the notation listed above its more like:
gcc sendOutputTo thisExecutableFile fromThisSource
Is that correct?
main : main.o printFun.o main.h is definitely wrong. That's saying that the header is a prerequisite for linking. A header is a prerequisite for compilation.
Assuming what you really meant was to specify the header as a compilation dependency (e.g. printFunc.o : printFunc.c printFunc.h), this means that if the header changes, the object file will be automatically regenerated. If you don't, then it won't.
A dependency in Makefile is saying that whenever any of the listed files change, run the command again. It does not mean that the listed file will be included into the compilation or linking. You still need the regular #include "main.h" in your sources.
Thus, this works too:
printFunc.o : printFunc.c someReadmeFile.txt
gcc -g -Wall -c -o printFunc.o printFunc.c
Whenever printFunc.c or someReadmeFile.txt is updated, gcc -g -Wall .... will be executed again.
I hope it's clearer now.

Build .so file from .c file using gcc command line

I'm trying to create a hello world project for Linux dynamic libraries (.so files). So I have a file hello.c:
#include <stdio.h>
void hello()
{
printf("Hello world!\n");
}
How do I create a .so file that exports hello(), using gcc from the command line?
To generate a shared library you need first to compile your C code with the -fPIC (position independent code) flag.
gcc -c -fPIC hello.c -o hello.o
This will generate an object file (.o), now you take it and create the .so file:
gcc hello.o -shared -o libhello.so
EDIT: Suggestions from the comments:
You can use
gcc -shared -o libhello.so -fPIC hello.c
to do it in one step. – Jonathan Leffler
I also suggest to add -Wall to get all warnings, and -g to get debugging information, to your gcc commands. – Basile Starynkevitch

Problems when linking shared library

Below are the steps of how I generate the executable file using shared library.
I have three files:
File libhello.c
/* hello.c - demonstrate library use. */
#include <stdio.h>
void hello(void)
{
printf("Hello, library world./n");
}
File libhello.h
/* hello.h - demonstrate library use. */
void hello(void);
File main.c
/* main.c -- demonstrate direct use of the "hello" routine */
#include "hello.h"
int main(void)
{
hello();
return 0;
}
I use the commands below to generate the shared library.
gcc -g -Wall -fPIC -c hello.c -o hello.o
gcc -shared -W,soname,-libhello.so.0 -o libhello.so.0.0.0 hello.o
Finally, I add the library path to the LD_LIBRARY_PATH variable and try to create the executable file using the shared library.
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
ln -s libhello.so.0.0.0 libhello.so.0
gcc -g -Wall -c main.c -o main.o -I.
gcc -o main main.o -lhello -L.
However, at the last step, there is one error: can't find -lhello. So, where am I wrong?
Thanks.
gcc looks for libhello.so when linking a new program. libhello.so.0 is used when the dynamic dependencies of an already linked program are searched.
In other terms: gcc -o main main.o -lhello -L. looks for libhello.so, and ./main looks for libhello.so.0. This allows to have multiple versions of a library available for legacy programs while precisely identifying the library that matches the installed headers.
A symlink libhello.so -> libhello.so.0.0.0 should do the trick.

Resources