¿Por qué tenemos que decirle a gcc con qué biblioteca enlazar cuando esa información ya está en el archivo fuente en forma de #include ?
Por ejemplo, si tengo un código que usa hilos y tiene:
#include <pthread.h>Todavía tengo que compilarlo con la opción -pthread en gcc :
gcc -pthread test.cSi no doy la opción -pthread , dará errores al encontrar definiciones de funciones de subprocesos.
Estoy usando esta versión:
gcc --version gcc (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4Esta puede ser una de las cosas más comunes que hacen tropezar a los principiantes con C.
En C hay dos pasos diferentes para construir un programa, compilación y enlace. Para los fines de su pregunta, estos pasos conectan su código a dos tipos diferentes de archivos, encabezados y bibliotecas.
El compilador maneja la directiva #include <pthread.h> en su código C. El compilador (en realidad, el preprocesador) literalmente pega el contenido de pthread.h en su código antes de convertir su archivo C en un archivo de objeto.
pthread.h es un archivo de encabezado, no una biblioteca. Contiene una lista de las funciones que puede esperar encontrar en la biblioteca, qué argumentos toman y qué devuelven. Un encabezado puede existir sin una biblioteca y viceversa. El encabezado es un archivo de texto, que a menudo se encuentra en /usr/include en sistemas derivados de Unix. Puede abrirlo como cualquier archivo C para leer el contenido.
La línea de comando gcc -lpthread test.c compila y vincula. En los viejos tiempos, primero haría algo como cc test.c , luego ld -lpthread test.o . Como puede ver, -lpthread es en realidad una opción para el enlazador.
El enlazador no sabe nada sobre archivos de texto como código C o encabezados. Solo funciona con archivos de objetos compilados y bibliotecas existentes. El indicador -l le dice en qué bibliotecas buscar para encontrar las funciones que está utilizando.
El nombre del encabezado no tiene nada que ver con el nombre de la biblioteca. Aquí es realmente sólo por el accidente. La mayoría de las veces hay muchos encabezados proporcionados por la biblioteca.
Especialmente en C++, suele haber un encabezado por clase y la biblioteca suele proporcionar implementaciones de clases desde el mismo espacio de nombres. En C, los encabezados están organizados para que contengan un subconjunto común de funciones: math.h contiene operaciones matemáticas, stdio.h proporciona funciones IO, etc.
Son dos cosas separadas. Los archivos .h contienen las declaraciones, a veces también la función en línea. Como todos sabemos, todas las funciones deben tener una implementación/definición para funcionar. Estas implementaciones se mantienen por separado. -lpthread , por ejemplo, es la biblioteca que contiene la implementación de las functions declared in headers en forma binaria.
Separar la implementación es lo que la gente quiere cuando no quieres compartir tu código comercial con otros.
Asi que,
gcc -pthread test.c dígale a gcc que busque definiciones declaradas en pthread.h en libpthread . -pthread se expande a libpthread por el enlazador automáticamente