Después del pequeño tostón del otro día donde se comentaba la ruta de las librerías en Linux, hoy toca comentar el gran tostón de cómo se desarrollan librerías que usen otras librerías y varios efectos durante el enlazado. Si no estáis muy interesados en el desarrollo de librerías en Linux no sigáis leyendo porque quizás me odiéis. Y si sí desarrolláis librerías… bueno, quizás tampoco deberíais seguir… quedáis avisados.
Lo primero, una descripción rápida de como programar una libraría en Linux:
Creas el archivo de código fuente, por ejemplo mylib.cpp, para luego compilarlo con la opción del compilador de generar código independiente de la posición (PIC):
$ g++ -Wall -fPIC -c mylib.cpp
Luego enlazas todos los archivos objeto resultantes (*.o) en el binario de la librería indicándole al linker, además, el nombre de la librería (soname):
$ g++ -shared -Wl,soname,libmylib.so.0 -o libmylib.so.0.1 *.o
Una vez hecho esto se puede instalar la librería en algún directorio como /usr/local/lib u /opt/lib, aunque no es necesario para hacer estas pruebas.
Para usar la librería, basta con crear un programa, por ejemplo myprog.cpp, y enlazar esta librería en él. Eso sí, no os olvidéis de indicarle al compilador dónde están los archivos de cabecera (con la opción -I) y de exportar la variable LD_LIBRARY_PATH indicando el directorio de vuestra librería (como vimos el otro día):
$ g++ -I/path/to/mylib/include -o myprog -lmylib myprog.cpp
Una vez tenemos la librería y nuestro programa que la usa vamos con los curiosos efectos:
En el caso de que nuestra librería use otra librería de forma interna, a la hora de compilar es necesario indicarle donde están los archivos de cabecera de la librería a usar (opción -I) pero no es necesario indicarle, a la hora de enlazar, la librería con la que enlazar:
$ g++ -Wall -fPIC -I/path/to/otherlib/include -c mylib.cpp
$ g++ -shared -Wl,soname,libmylib.so.0 -lotherlib -o libmylib.so.0.1 *.o
A la hora de compilar nuestro programa con nuestra librería enlazada de la forma anterior, es necesario que sí enlacemos nuestro programa a la otra librería, sino ni siquiera enlazará porque no se pueden resolver los símbolos de otherlib que usa mylib. Por ello nuestro programa se compilaría:
$ g++ -o myprog -lmylib -lotherlib myprog.cpp
En caso de enlazar mylib con otherlib (usando la opción -lotherlib antes comentada), no sería necesario enlazar myprog con otherlib. Resumiendo este tostón incomprensible: hay que enlazar nuestro programa con todas las librerías que use y todas las que usen éstas y no lo estén ya en las mismas, aunque siempre es mejor enlazar cada cosa con lo que utiliza.
Un ejemplo:
- Compilo
mylibsin enlazar conotherlib:- Compilo
myprogenlazando amylib: error porque no enlaza conotherlib. - Compilo
myprogenlazando amylibyotherlib: todo correcto.
- Compilo
- Compilo
mylibenlazando conotherlib:- Compilo
myprogenlazando amylib: todo correcto porque, aunque hace uso deotherlib, esta ya está enlazada enmylib. - Compilo
myprogenlazando amylibyotherlib: todo correcto aunque innecesario porqueotherlibya está enlazada conmylib.
- Compilo
Buf… bueno, yo lo entiendo porque me ha pasado y he investigado un rato para resolverlo, pero visto aquí, así, sin anestesia… pues cuesta. Pero bueno, aquí queda por si en un futuro se me olvida. Y para quién le sea útil, por supuesto.





