## Libraries

Compiling converts your source code into object or machine code, which the processor can understand. So the compiler produces an object file (.o) from your source code. The linker then pieces the object files together and herefrom produces an executable. If you wish to “compile only” i.e. to obtain merely the object file, you can add the “-c” flag at compilation:

michael@michael-laptop:~$gcc -c test.c This produces the object file “test.o”. You can inspect this object file with the nm command. It basically lists all the symbols defined in the object file. ## Static Libraries A static library is an archive of object files. All we do is include this archive in the compile line just like we would do for the .o files. Any executable created by linking with a static library contains its own copy of all the binary object files found inside, so only the executable need be distributed. This archive is created with the ar command e.g. michael@michael-laptop:~$ ar r library.a file1.o file2.o file3.o

” r Insert the files member into archive (with replacement).”
You can then display what files are in an archive with the t option.

michael@michael-laptop:~$ar t library.a ## Shared Libraries It is a better idea to use shared libraries over static libraries. This is because modules that a program requires are loaded into the memory from shared objects at run time or load time, whereas static libraries are all put together at compile time. This has the advantage that I can change the object files in the libraries and not need to recompile my executable. If the library was static and I made a change, then I would need to recompile all the executables which depend on that library. Shared libraries have 3 names: ### soname has the prefix “lib” and the suffix .so followed by a full stop and then the major version number i.e. libtest.so.1 We would only increment the major version number if we make a change which breaks backward compatibility e.g. changing the number of arguments that a function has ### realname is the actual filename which contains the actual library code. It gains a minor version number plus a realase number in addition to the soname i.e. libtest.so.1.0.1 ### linker name is the name of the library which the linker refers to at compilation. It is the same as the soname, just without the version number i.e. libtest.so The linker name is basically a symbolic link to the soname, which is itself a symbolic link to the real name. To create a shared library, we need to compile our source code as follows: michael@michael-laptop:~$ gcc -fPIC -c test.c

The “-fPIC” option tells the compiler to produce Position Independent Code, which means the code can function regardless of where in the memory it is loaded. We can then proceed by using the “-shared” option at gcc and passing the soname as an option to the linker with the -Wl command.

michael@michael-laptop:~$gcc -shared -Wl,-soname,libtest.so.1 -o libtest.1.0.1 test.o The -shared option tells the compiler that the output file should be a shared library. -Wl,option Pass option as an option to the linker. If option contains commas, it is split into multiple options at the commas. You must not include whitespaces. The -soname option specifies the soname, duh. The -o option specifies the real name. Now that the shared library has been created, we need to install it, namely with ldconfig. The ldconfig program generates a symbolic link, named as the soname, to the realname. The -n option specifies the directory where the shared library is found. Finally, we need to create a new symbolic link with a filename as the linker name, to the soname. michael@michael-laptop:~$ ln -s libtest.so.1 libtest.so

where -s option stands for symbolic.

## at command

Scheduling a process to run automatically at a certain date and time can be quite useful. This is achieved with the at command. The at command reads a series of commands from the standard input and lumps them together into one single at-job to be executed at some point in the future.

Syntax: at [-V] [-q queue] [-f file] [-mkdv] [-t time]

You can man at to find out about all the options.

Here is an example:

michael@michael-laptop:~$at -mv 4:44 sep 21 Wed Sep 21 04:44:00 2011 warning: commands will be executed using /bin/sh at> g++ main.cpp -o test at> nohup ./test & at> job 13 at Wed Sep 21 04:44:00 2011 michael@michael-laptop:~$


-m option mails the user when the at-job has been executed. The -v option simply produces the first line i.e. displays when the job will be executed. One does not write , instead, this is achieved by entering CTRL+D here on a new line.

To see whats at-jobs have been scheduled, enter atq (alternatively at -l

michael@michael-laptop:~$atq 13 Wed Sep 21 04:44:00 2011 a michael michael@michael-laptop:~$ at -l
13	Wed Sep 21 04:44:00 2011 a michael
michael@michael-laptop:~$ To remove this job, enter atrm and the ID: michael@michael-laptop:~$ atrm 13
michael@michael-laptop:~$atq michael@michael-laptop:~$


The at-job inherits the environment of the terminal that schedules it and hence contains the same working directory and environment variables. If at some point in the future you forget what commands an at-job contains, you can view them with at -c job. This lists the environment variables of the at-job and contains the commands at the bottom.

## Kill – Killing Processes and the top Command

Sooner or later you will want to kill a process, whether it be some code executed in the background that is taking too long or simply a program that is misbehaving.

If the code has been executed by the user in the background, then one can use the jobs command with the kill command:

michael@michael-laptop:~$jobs [1]+ Running ./test & michael@michael-laptop:~$ kill -9 %1
michael@michael-laptop:~$[1]+ Killed ./test  The second term specifies which signal to send, as specified in . As an exemplary aside, CTRL + C sends the SIGINT interrupt signal to the program and CTRL + Z sends the SIGSTOP pause signal. The -9 sends the SIGKILL signal, which is slightly more forceful than the default SIGTERM which is obtained by -15 or omitting this field. SIGKILL forces the program to end immediately whereas SIGTERM can be intercepted or ignored by the program. The latter is the gentler approach as it can allow the program to clean itself up before finishing. ?using the latter would have produced this line of code [1]+ Terminated ./test as opposed to Killed ## top command Alternatively, you can use the top command to display processes in order of CPU demand. N.B. It is called “top” because only the top most demanding processes are shown. top - 12:26:34 up 23 days, 12:39, 2 users, load average: 8.00, 8.01, 8.05 Tasks: 152 total, 10 running, 142 sleeping, 0 stopped, 0 zombie Cpu(s): 64.4%us, 0.2%sy, 0.0%ni, 35.4%id, 0.0%wa, 0.0%hi, 0.1%si, 0.0%st Mem: 24732896k total, 24581112k used, 151784k free, 531980k buffers Swap: 3999676k total, 9080k used, 3990596k free, 21636732k cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 2447 laemmel 20 0 122m 111m 972 R 100 0.5 9880:20 BD-concn-semifl 2486 lindon 20 0 58676 40m 1492 R 100 0.2 9875:24 hing 4053 laemmel 20 0 122m 111m 972 R 100 0.5 9672:33 BD-concn-semifl 7782 sturm 20 0 19496 7100 1220 R 100 0.0 1520:41 tfpulling 20031 sturm 20 0 23384 10m 1220 R 100 0.0 5330:51 tfpulling 26339 sturm 20 0 22616 10m 1220 R 100 0.0 4374:08 tfpulling 30841 glaser 20 0 44.5g 473m 344m R 100 2.0 10974:30 hoomd 1093 sturm 20 0 58764 45m 1184 R 100 0.2 10176:04 tfpulling  Within top, you can press k (for kill) and then enter the PID (process ID) of the process you would like to kill. To exit top, press q. If you know the PID, which you can get from top, you can use the kill command in a regular terminal by entering  kill -9 PID ## Background Processes and the jobs Command If your code takes a long time to run after execution, you may consider running it in the background. Consider the executable “test”, I run it as follows 1. Running Processes in the Background michael@michael-laptop:~$ ./test

while it is running, you do much with the terminal. You can abort it with  CTRL + C or you can pause it with CTRL + Z

michael@michael-laptop:~$./test ^Z [1]+ Stopped ./test  The last line is exactly what you would get if you typed the job command. You can now send this process to run in the background by typing bg michael@michael-laptop:~$ bg
[1]+ ./test &
michael@michael-laptop:~$ Typing jobs again will now show you that the process is running in the background michael@michael-laptop:~$ jobs
[1]+  Running                 ./test &
michael@michael-laptop:~$ When the process finished, a confirmation will be displayed in the terminal like this [1]+ Done ./test michael@michael-laptop:~$


In addition, you can bring processes back to the foreground by entering fg job_id, where the job id is found from the jobs command (it is the number before the process e.g. 1 in this example).

You may now also wish to know how to kill background processes