简体   繁体   中英

Compiling an external library on Linux

Good Day Everyone,

NB - This problem has been solved - I have provided my own solution in the answer section however the solution provided by Jonathan is much shorter. Nevertheless, this was the following question I originally posted:

I am basically trying to compile a serial library (for UART communication) on Linux however I am not really sure how to correctly compile (I have mentioned what I have done so far below), any suggestions would be highly valuable. I am using the serialib library - which is composed of 2 main files ( serialib.h and serialib.cpp ) , you may directly view the source code of these files here (scroll all the way to the bottom and view the files in new tabs): http://serialib.free.fr/html/classserialib.html

I transferred these files (serialib.h and serialib.cpp) to my BeagleBone Black micro-controller which is running Debian (Wheezy) , g++/gcc (Debian 4.6.3-14) 4.6.3. I wrote my own program ( uart.cpp is my file name) to access the functions provided by this library, this is what I wrote:

#include <iostream>
#include "serialib.h"
#ifdef __linux__
#define DEVICE_PORT "/dev/ttyO1"
#endif
int main()
{
    serialib LS;
    return 0;
}

So as you can see I am trying to access the 'seriallib' class. serialib.h, serialib.cpp and uart.cpp are all in the home directory. I also manually added the iostream library in serialib.cpp as I did not see it being declared in the original source code.

Now I am really unsure of how to compile such external libraries but so far I tried the following steps:

  1. g++ -c -Wall -Werror -fPIC serialib.c to convert to PIC which gives the following error:

distcc[3142] (dcc_parse_hosts) Warning: /home/debian/.distcc/zeroconf/hosts contained no hosts; can't distribute work distcc[3142] (dcc_zeroconf_add_hosts) CRITICAL! failed to parse host file. distcc[3142] (dcc_build_somewhere) Warning: failed to distribute, running locally instead

  1. g++ serialib.cpp -L /home/debian/serialib.h which gives the following error:

/usr/lib/gcc/arm-linux-gnueabihf/4.6/../../../arm-linux-gnueabihf/crt1.o: In function _start': (.text+0x30): undefined reference to main' collect2: ld returned 1 exit status distcc[3210] ERROR: compile serialib.cpp on localhost failed

As of now I am still finding out how to compile this and if I manage to work this out then I'll post my solution here too. Once again any suggestion will be highly valuable. Thank you all :) .

  1. g++ -c -Wall -Werror -fPIC serialib.c to convert to PIC which gives the following error:

The "error" is not an error, it's a warning, telling you that your distcc setup is broken, but that it compiled locally.

That command doesn't "convert to PIC", it compiles the file serialib.c and produces a compiled object file, serialib.o

  1. g++ serialib.cpp -L /home/debian/serialib.h

This is just nonsense. It tries to build a program from serialib.cpp and use the directory /home/debian/serialib.h (which isn't a directory!) to find libraries.

You don't need to "compile a library" you can just compile both the source files and link them together into a program. Either:

g++ -c serialib.cpp 
g++ -c uart.cpp
g++ serialib.o uart.o -o uart

Or all in one command:

g++ serialib.cpp uart.cpp -o uart

You should read An Introduction to GCC to understand the commands, not just enter bogus commands without understanding them.

I have found a solution to this problem, hope this helps for all the future readers with similar problems. I have my own source code uart.cpp (Given in the question) which I want to compile, the external library is serialib that contains two main files (serialib.h and serialib.cpp), you will want to replace the following commands with respect to the files you have

Step 1: Compiling with position independent code

g++ -c -Wall -Werror -fpic serialib.cpp

Step 2: Creating a shared library

g++ -shared -o libserialib.so serialib.o , here the library is libserialib.so .

Step 3: Linking your source code with library

g++ -L /home/debian -lserialib uart.cpp -o uart

g++ -L /home/debian -Wall -o test uart.cpp -lserialib

You may save the library at a different path and you may have a different name of course. Suppose you have a library called libabc.so at the directory /home/user/myDir then the commands will be like:

g++ -L /home/user/myDir -labc your_code.cpp -o your_code

g++ -L /home/user/myDir -Wall -o test your_code.cpp -labc

test is out own program, lserialib is actually looking for libserialib.so and not serialib.o as gcc/g++ assumes all libraries start with lib and end with .so or .a and you can see the same goes for labc as it will look for libabc.so thus it is important to make sure your library name begins with lib and ends with .so or .a

Step 4: Making library available at run time

Here we provide the path where the library is actually stored, I saved it in the directory /home/debian which is why my command looks like:

export LD_LIBRARY_PATH=/home/debian:$LD_LIBRARY_PATH

if your library is saved at /path/to/file then the command will look like:

export LD_LIBRARY_PATH=/path/to/file:$LD_LIBRARY_PATH

This is to help the loader find the shared library and to view this path: echo $LD_LIBRARY_PATH and to unset this: unset LD_LIBRARY_PATH

To execute the program type either ./test or ./uart and in case of any modification to the main source code (uart.cpp in this case) , simply repeat step 3. I found the following link very useful: http://www.cprogramming.com/tutorial/shared-libraries-linux-gcc.html . Thank you to all of you who took time to read this question and especially those who gave me suggestions. If anyone has more or better solutions, feel free to post them here to assist future readers :).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM