Práctica de compilación en Linux

Los tres artículos anteriores reproducen los principios de la compilación de Linux: preprocesamiento> compilación> ensamblaje> enlace

cadenas: vea los caracteres imprimibles en el archivo de impresión
nm: lista de símbolos en algunos archivos
===========================================
El siguiente es el principio de compilación de Linux de la práctica operativa real

Hay tres archivos test1.c test2.c main.c en el directorio del sistema ubutun / home / spx / compilation
spx@spx-linux:~/编译$ cat test1.c 
#include<stdio.h>

void test1(){
	printf("test1...\n"); 
}
void no_use_fun()
{
	printf("no use fun...\n");
}
spx@spx-linux:~/编译$ cat test2.c 
#include<stdio.h>

void test2()
{
	printf("test2\n");
}
spx@spx-linux:~/编译$ cat main.c 
#include<stdio.h>

main()
{
	test1();
}
spx@spx-linux:~/编译$ 

Compile test1.c en la biblioteca dinámica libtest1.so y la biblioteca estática libtest1.a y vea la lista de símbolos en nm 

n m podemos ver que la biblioteca dinámica libtest1.so y la biblioteca estática libtest1.a contienen todas las funciones test1 y no_use_fun
spx@spx-linux:~/编译$ gcc -fPIC -c test1.c 
spx@spx-linux:~/编译$ gcc -shared -fPIC -o libtest1.so test1.o 
spx@spx-linux:~/编译$ ar rc libtest1.a test1.o 
spx@spx-linux:~/编译$ nm libtest1.a 

test1.o:
                 U _GLOBAL_OFFSET_TABLE_
0000000000000012 T no_use_fun
                 U puts
0000000000000000 T test1
spx@spx-linux:~/编译$ nm libtest1.so 
0000000000200e50 a _DYNAMIC
0000000000200fe8 a _GLOBAL_OFFSET_TABLE_
                 w _Jv_RegisterClasses
0000000000200e30 d __CTOR_END__
0000000000200e28 d __CTOR_LIST__
0000000000200e40 d __DTOR_END__
0000000000200e38 d __DTOR_LIST__
00000000000006f8 r __FRAME_END__
0000000000200e48 d __JCR_END__
0000000000200e48 d __JCR_LIST__
0000000000201018 A __bss_start
                 w __cxa_finalize@@GLIBC_2.2.5
00000000000005f0 t __do_global_ctors_aux
0000000000000520 t __do_global_dtors_aux
0000000000201010 d __dso_handle
                 w __gmon_start__
0000000000201018 A _edata
0000000000201028 A _end
0000000000000628 T _fini
00000000000004b8 T _init
0000000000000500 t call_gmon_start
0000000000201018 b completed.6531
0000000000201020 b dtor_idx.6533
00000000000005a0 t frame_dummy
00000000000005de T no_use_fun
                 U puts@@GLIBC_2.2.5
00000000000005cc T test1
spx@spx-linux:~/编译$ 

Biblioteca respectivamente dinámica libtest1.so biblioteca estática libtest1.a enlace al archivo ejecutable main1, main2 y ejecutado. La ejecución del error main1, la biblioteca compartida libtest1.so no se pudo encontrar . Este es un error común en la ejecución de la biblioteca dinámica. Debe configurar la ruta del archivo de la biblioteca dinámica para las variables de entorno. Puede ver la biblioteca de enlaces de archivos ejecutables con ldd
spx@spx-linux:~/编译$ gcc -o main1 main.c libtest1.so 
spx@spx-linux:~/编译$ gcc -o main2 main.c libtest1.a
spx@spx-linux:~/编译$ ./main1 
./main1: error while loading shared libraries: libtest1.so: cannot open shared object file: No such file or directory
spx@spx-linux:~/编译$ ./main2 
test1...
spx@spx-linux:~/编译$ 


spx@spx-linux:~/编译$ ldd main1 
	linux-vdso.so.1 =>  (0x00007fff019ff000)
	libtest1.so => not found
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f148e2a9000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f148e678000)
spx@spx-linux:~/编译$
Agregue la variable de entorno LD_LIBRARY_PATH, ldd encuentra la biblioteca dinámica y ejecuta main1 correctamente
spx@spx-linux:~/编译$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/spx/编译
spx@spx-linux:~/编译$ echo $LD_LIBRARY_PATH
:/home/spx/编译
spx@spx-linux:~/编译$ ldd main1 
	linux-vdso.so.1 =>  (0x00007fff7b9ff000)
	libtest1.so (0x00007f86876ff000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f8687332000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f8687903000)
spx@spx-linux:~/编译$ ./main1 
test1...
spx@spx-linux:~/编译$ 
如果我们修改test1.c的内容,重新生成libtest1.so libtest1.a,再执行
spx@spx-linux:~/编译$ cat test1.c 
#include<stdio.h>

void test1(){
	printf("test1 update...\n"); 
}
void no_use_fun()
{
	printf("no use fun...\n");
}
spx@spx-linux:~/编译$ gcc -fPIC -c test1.c 
spx@spx-linux:~/编译$ gcc -shared -fPIC -o libtest1.so test1.o 
spx@spx-linux:~/编译$ ar rc libtest1.a test1.o 
spx@spx-linux:~/编译$ ./main1 
test1 update...
spx@spx-linux:~/编译$ ./main2 
test1...

main1 ejecuta el contenido modificado, mientras que main2 no se modifica. Debido a que la vinculación estática agrega el archivo .o real al archivo ejecutable, no se actualizará a sí mismo. Cuando se actualiza el archivo de la biblioteca, es necesario volver a compilarlo. Para la vinculación dinámica, se agrega un puntero a la biblioteca dinámica al archivo ejecutable y no es necesario volver a compilar cuando se actualiza el archivo de la biblioteca.
spx@spx-linux:~/编译$ gcc -o main2 main.c libtest1.a 
spx@spx-linux:~/编译$ ./main2 
test1 update...
spx@spx-linux:~/编译$

Supongo que te gusta

Origin blog.csdn.net/weixin_40017062/article/details/80574871
Recomendado
Clasificación