CS-FreeStyle / 10000-How-To-Do-in-CS

1 stars 0 forks source link

makefiles gcc #82

Open liuty10 opened 4 years ago

liuty10 commented 4 years ago

writing makfile:

http://nuclear.mutantstargoat.com/articles/make/

https://randu.org/tutorials/c/make.php

how to use gcc: https://www3.ntu.edu.sg/home/ehchua/programming/cpp/gcc_make.html

Good Tutorial: https://www.cprogramming.com/tutorial/shared-libraries-linux-gcc.html

https://renenyffenegger.ch/notes/development/languages/C-C-plus-plus/GCC/create-libraries/index

liuty10 commented 4 years ago

Step 1: Compiling with Position Independent Code

We need to compile our library source code into position-independent code (PIC):1

$ gcc -c -Wall -Werror -fpic foo.c Step 2: Creating a shared library from an object file

Now we need to actually turn this object file into a shared library. We will call it libfoo.so:

gcc -shared -o libfoo.so foo.o Step 3: Linking with a shared library

As you can see, that was actually pretty easy. We have a shared library. Let us compile our main.c and link it with libfoo. We will call our final program test. Note that the -lfoo option is not looking for foo.o, but libfoo.so. GCC assumes that all libraries start with lib and end with .so or .a (.so is for shared object or shared libraries, and .a is for archive, or statically linked libraries).

$ gcc -Wall -o test main.c -lfoo /usr/bin/ld: cannot find -lfoo collect2: ld returned 1 exit status Telling GCC where to find the shared library

Uh-oh! The linker does not know where to find libfoo. GCC has a list of places it looks by default, but our directory is not in that list.2 We need to tell GCC where to find libfoo.so. We will do that with the -L option. In this example, we will use the current directory, /home/username/foo:

$ gcc -L/home/username/foo -Wall -o test main.c -lfoo Step 4: Making the library available at runtime

Good, no errors. Now let us run our program:

$ ./test ./test: error while loading shared libraries: libfoo.so: cannot open shared object file: No such file or directory Oh no! The loader cannot find the shared library.3 We did not install it in a standard location, so we need to give the loader a little help. We have a couple of options: we can use the environment variable LD_LIBRARY_PATH for this, or rpath. Let us take a look first at LD_LIBRARY_PATH:

Using LD_LIBRARY_PATH

$ echo $LD_LIBRARY_PATH There is nothing in there. Let us fix that by prepending our working directory to the existing LD_LIBRARY_PATH:

$ LD_LIBRARY_PATH=/home/username/foo:$LD_LIBRARY_PATH $ ./test ./test: error while loading shared libraries: libfoo.so: cannot open shared object file: No such file or directory What happened? Our directory is in LD_LIBRARY_PATH, but we did not export it. In Linux, if you do not export the changes to an environment variable, they will not be inherited by the child processes. The loader and our test program did not inherit the changes we made. Thankfully, the fix is easy:

$ export LD_LIBRARY_PATH=/home/username/foo:$LD_LIBRARY_PATH $ ./test This is a shared library test... Hello, I am a shared library