17 nov 2008

Makefiles(II) Dejando que gcc nos de las dependencias

Si no queremos comernos la cabeza para determinar cuales son las dependencias de un proyecto, podemos hacer que el compilador GNU nos las de.
Para ellos, si tenemos por ejemplo los archivos main.c funcinoes1.c y funcinoes2.c e includes.h y queremos ver cuáles son las dependencias, bastará con ejecutar:

gcc -MM main.c funciones1.c funciones2.c

y obtendremos las reglas para el Makefile.

Makefiles (I)

Los Makefiles son archivos de script para el programa Make, y sirven para realizar acciones sobre archivos cuando se cumplan unas dependencias. Pueden usarse para muchas tareas, aunque la mas comúnmente usada es la actualización de programas ejecutables de un proyecto e incluso de su documentación asociada cuando se producen cambios en el código.

El funcionamiento de Make se basa en un archivo llamado Makefile (si deseamos usar otro nombre tendremos que invocar a make después con "make -f nombre_makefile") en el que se disponen las reglas de dependencia entre los archivos y los objetivos(targets) del proyecto.

Supongamos que tenemos un proyecto en C que se compone de un archivo main.c en el que tenemos la función principal del programa, y luego tenemos un archivo funciones.c en el que tenemos las funciones que se llaman desde main. Supongamos también que queremos q nuestro programa se llame prueba (si estuvieramos en windows deberia ser prueba.exe, pero en UNIX no es necesario la extensión).

El formato del archivo es:

objetivo: dependencia1 dependencia2 .... dependenciaN
órdenes a ejecutar para la generación de "objetivo"

Para nuestro caso, el objetivo es prueba y sus dependencias son main.c y funciones.c, por lo tanto crearemos un archivo Makefile que contenga:

prueba: main.o funciones.o
gcc main.o funciones.o -o prueba

Lo guardamos y ejecutamos make. Como resultado, se creará el archivo prueba y además veremos que se ha llamado al compilador de c para generar main.o y funciones.o a partir de sus homólogos .c. Esto es debido a que el programa Make tiene cierta inteligencia y ya sabe como generar código objeto a partir de código fuente en C (también es capaz de hacer cosas parecidas para otros lenguajes). Podemos indicar nosotros todos los pasos a costa de que el Makefile sea mas complicado, pero eso si mas claro. El Makefile con todos los pasos sería:

prueba: main.o funciones.o
gcc main.o funciones.o -o prueba
main.o: main.c
gcc -c main.c
funciones.o: funciones.c
gcc -c funciones.c

En los makefiles podemos usar variables, por ejemplo para almacenar todas las dependencias, se suelen poner en mayúsculas para distinguirlas bien:

OBJS:= main.o funciones.o

prueba: $(OBJS)
gcc $(OBJS) -o prueba

El funcionamiento es el siguiente:
Make comprueba la lista de dependencias para prueba, comprueba si estas dependencias tienen a su vez dependencias (por ejemplo cuando hemos creado el Makefile poniendo que prueba dependía de main.o y funciones.o y estos a su vez dependían de main.c y funciones.c). Si alguna de las dependencias se incumple (entendiendo incumplir como que los archivos de los que depende un objetivo no existen, o su fecha de modificación es posterior a la del objetivo) se ejecutan las órdenes para dicho target.

Para ilustrarlo con nuestro ejemplo, supongamos que tenemos nuestros archivos fuente y nuestro Makefile, y que aún no hemos generado el ejecutable prueba, entonces, al ejecutar make, en primer lugar se determina si las dependencias de prueba existen y están actualizadas (comprueba que main.o y funciones.o existen y su fecha de modificación es anterior o igual que la de prueba) , en este caso los archivos no existen. A continuación se comprueban las dependencias de main.o (que es main.c) como main.o no existe, se ejecutan las ordenes para crearlo, esto es gcc -c main.c y se obtiene main.o, y lo mismo con funciones.o. Una vez cumplidas las dependencias de "2º nivel" se vuelve sobre las de "1er nivel" y dado que prueba no existe, se ejcuta la orden para crearlo a partir de main.o y funciones.o.

Imaginemos ahora que modificamos funciones.c porque había un error en el funcionamiento de una de las funciones. Naturalmente, queremos actualizar el ejecutable prueba para que incluya el cambio, pues bien aqui viene la potencia de los makefiles.
ejecutamos make y lo que ocurre es lo siguiente:

  1. Se intentan comprobar las dependencias de 1er nivel(prueba), pero como hay dependencias de 2º nivel se comprueban en primer lugar éstas últimas.
  2. Se comprueba las dependencias de 2º nivel y se determina que funciones.o es anterior a funciones.c, por lo que es necesario actualizar.
  3. Se ejecuta la orden para la dependencia de funciones.o
  4. Si no hay mas dependencias de 2º nivel, se pasa a las de 1er nivel.
  5. Se determina que prueba es anterior a una de sus dependencias (funcinoes.o) por lo que es necesario actualizar.
  6. Se ejecuta la orden para las dependencias de prueba, generándose de nuevo el ejecutable.
Ya tendríamos actualizado el programa. Podemos comprobar como únicamente se ha compilado la parte que ha cambiado respecto a la versión anterior. Si esto lo extrapolamos a un proyecto con muchos archivos, y con dependencias de varios niveles, la complejidad aumenta pero el funcionamiento es el mismo.

Continuaremos con cuestiones mas avanzadas sobre los makefiles en próximas entradas.

15 nov 2008

Astronomia espacial: Distancia a las estrellas (paralaje)

¿Como se determina la distancia a la que se encuentra una estrella?
Bueno, pues la primera respuesta es: "depende de lo lejos que este".
Esto es como la pescadilla que se muerde la cola, pero si consideramos una estrella cercana, podemos determinar la distancia a la que está mediante su paralaje.
Para explicar qué es el paralaje, vamos a hacer un pequeño experimento que consiste en mirar nuestro dedo con un ojo guiñado, observar su posición respecto al fondo (usar algún punto de referencia) y después hacer lo propio con el otro ojo, sin movernos del sitio, ni tampoco mover el dedo o la cabeza. Comprobaremos, que la posición del dedo, respecto del punto de referencia elegido en el fondo, cambia.
Lo que ocurre, es que la distancia entre nuestros ojos hace que los rayos de luz nos sigan el mismo camino a uno y otro ojo, por lo que la posición aparente respecto al fondo es distinta para cada ojo.
Mediante trigonometría podemos calcular la distancia a la que se encuentra el dedo de nosotros.
De la misma manera, si consideramos una estrella, y tomamos su posición respecto al fondo fijo en los extremos de la órbita terrestre (su separación será el diámetro de la órbita, esto es 2 U. A.) podemos calcular la distancia a la estrella en parsecs.
1 parsec es la distancia a la cual un punto se observa con un paralaje (medido en extremos de la órbita de la tierra) de un segundo de arco (1º son 60 minutos de arco y un minuto arco son 60 segundos de arco). Así pues, medimos el desplazamiento de la estrella en segundos de arco(d) y su distancia en parsecs sera 1/d.
Ésta es la forma de determinar la distancia a una estrella cercana (suponiendo el resto fijas por estar mas lejos).
Hay que decir que ésta medida no es exacta, puesto que en el cálculo trigonométrico se realiza una aproximación. Ésta consiste en considerar el arco medido como la tangente del ángulo y esta tangente aproximarla por el ángulo ya que éste es muy pequeño.
Además, reflexionando un poco, uno puede pensar: "vale, pero una estrella se puede estar moviendo", pues si, las estrellas se mueven solo que nosotros nos somos capaces de percibirlo debido a la distancia tan enorme a la que están, pero por ejemplo, existen estrellas cuya posición no coincide con las observadas por los griegos, lo que indica que se han movido.

Esto plantea un inconveniente para el cálculo del paralaje, puesto que un desplazamiento de la posición aparente de la estrella, incluye un desplazamiento "propio" de la estrella debido a su movimiento por el universo. Los paralajes de las estrellas son pequeños, pero los movimientos propios son aun mas pequeños, por lo que no suele resultar difícil distinguirlos.
El desplazamiento debido al paralaje se ve como una elipse si observamos y anotamos la posición de una estrella todos los días del año, mientras que si dibujamos la trayectoria durante muchos años, veríamos como dicha elipse se va desplazando en la dirección del movimiento propio de la estrella.
Hay que decir también que existe una componente radial del desplazamiento de las estrellas que no influye en éste análisis, y que se puede determinar a través del efecto Doppler de su emisión.
Esta entrada puede resultar un poco densa sin un dibujo y alguna formula, así que intentare completarlo en cuanto pueda.

Astronomia espacial: Estrellas(introducción)

Para los griegos, las estrellas eran motas luminosas de un misterioso 5º elemento y que se encontraban en la esfera mas alejada (ver teoría geocéntrica o de las esferas).
Hoy sabemos que están compuestas de los mismos elementos químicos que nuestro planeta, además de conocer sus temperaturas, distancias, etc...

Las estrellas son esferas de plasma auto-sustentadas por su propia gravedad y cuya masa es suficientemente grande como para que en su núcleo se produzcan fenómenos de fusión nuclear.
Las estrellas son de diferentes colores, y esto esta marcado por su temperatura superficial. La Ley de Wien nos da la longitud de onda a la que se produce su máximo de emisión.

Así pues, si una estrella aparece de color rojo significa que tiene una mayor cantidad de emisión en longitudes de onda cercanas a la del color rojo (longitudes de onda grandes dentro del rango visible), lo que significa que su temperatura superficial es pequeña.

Si el color es azulado, significa que estaremos en el extremo opuesto del rango visible (longitud de onda pequeña) por lo que su temperatura superficial será alta. En caso de que una estrella aparezca con color blanco-amarillo, significa que emite por igual longitudes de onda cercanas al rojo y al azul, estando el máximo por tanto en el centro del rango visible, siendo su temperatura media.

La energía que radian las estrellas(tanto en el rango visible como en el invisible) es producida por las reacciones termonucleares que se producen en su interior, básicamente consumen los elementos químicos de los que están compuestas hasta agotarlos.
Cuando el combustible se agota la estrella muere, pero la evolución estelar la trataremos en otro artículo.
La velocidad de consumo del combustible depende de la temperatura de la estrella, cuanto mas caliente sea, mas rápido consume el mismo.

Pero ¿Como conocemos la distancia a la que esta una estrella?¿y su tamaño?¿y su temperatura y color?
Como decían en Conan "Esa es otra historia...."

Bueno, he creado este blog para guardar la explicación de cualquier cosa que me resulte interesante hacer y que cuando vuelvo a necesitar nunca recuerdo.
De esta forma pondré artículos de diversos temas (Linux, OS X, Astronomía...) ya sean por "trasteos" personales o porque me hagan falta para mi actividad profesional o académica.
Vamos a ello