InicioLinuxalgo para programar en linux lenguaje C

algo para programar en linux lenguaje C

Linux•6/25/2011
El GNU cc (gcc) es el conjunto de programas que comprenden el compilador del proyecto GNU. Compila programas escritos en C, C++, o C dirigido a Objetos. El gcc también compila Fortran (con apoyo de g77). Este capítulo se concentra en el compilador de C porque C es la lengua nativa de Linux. El capitulo también cubre las diferencias entre gcc y egcs version 1.1.2, el conjunto experimental de programas del compilador GNU. Este capitulo abarca los siguientes temas: -Invocacion del gcc -Opciones y argumentos para controlar la conducta del gcc -Compilación de multiples archivos Todos los programas de este capitulo pueden sr encontrados en el sitio web https:www.mcp.cominfo bajo el numero de ISBN 0789722151. Utilizacion del compilador de código de GNU (gcc) El gcc le da al programador un amplio control sobre el proceso de compilación. Este ultimo comprende cuatro etapas: preprocesador,compilación, ensamblaje y vinclación. Uno puede detener el proceso después de cualquier de dichas etapas para examinar el rendimiento del compilador en la misma. El gcc también puede administrar los diversos dilalectos de C, tales como el ANSI C o C tradicional (el de sus desarrolladores, Kernighan y Ritchie). Se puede controlar la cantidad y el tipo de información de depuración, si se le deseara emplear, que se incristará en el archivo binario resultante y, como la mayoria de los compiladores, gcc puede llevar a cabo también optimización de codigo. El gcc incluye más de treinta advertencias individuales y tres niveles de advertencia tipo "captura todo". El gcc es tambipen un compilador cruzado de modo que se puede desarrollar el código en una arquitectura de procesador y correrlo en otra. La compilación cruzada es importante porque linuz corre en muchos tipos diferentes de sistemas tales como el x86 de Intel, las PowerPC, las Amiga y las SCN Sparcs. Cada chip de procesador tiene una arquitectura física diferente, de modo que la manera en que se debe construir un binario varia para cada sistema. Cuando se utiliza como un compilador cruzado, el gcc permite que se compile un programa diseñado para correr en una PowePC en, digamos, un sistema Intek x86. Finalmenge el gcc acepta una lista larga de extensiones a C. La mayoria de estas extensiones mejora el desempeño, contribuye a la tarea del compilador tendiente a la optimizacion del codigo, o hace más sencillo el trabajo del programador. El precio a pagar a cambio es la disminucion de la portabilidad. Mencionaremos algunas de las extensiones más comunes, porque las mismas se pueden encontrar en los archivos de encabezamiento del kernel, pero lo ideal es que el lector evite su uso en los programas que redacte. Invocacion de gcc Para utilizar gcc, suministre un nombre de archivo fuente de C y utilice la opcion -c para especificar el nombre del archivo de salida. gcc preprocesara, compilará, ensamblará y vinculará (link), el programa, generando un archivo ejecutable, a menudo denominado binario. La sintaxis más simple se ilustra aquí: gcc archivo_entrada.c [-o archivo_salida] archivo_entrada.c es un archivo de código fuente en C y -o establece que el nombre del archivo de salida será archivo_salida. Los corchetes ([]) indican a lo largo de este libro argumentos opcionales. Si el nombre del archivo de salida no se especifica, gcc lo denominara a.out como opcion predeterminada. Ejemplo Este ejemplo utiliza gcc para crear el programa hola a partir del código fuente hola.c. Primero, el código fuente: /*Nombre del programa en Internet: hallo.c*/ /* *Listado 1.1 *hola.c -Programa canónico "¡Hola, mundo!" * */ #include int main(void) { puts("!Hola, mundo de programadores de Linux!" ) ; return 0; } para correr compilar este programa escriba $gcc hola.c -o hola Si todo anduvo bien, gcc realiza su trabajo en silencio y luego regresa a la señal de petición de comandos del sistema operativo, gcc compila y linkea el archivo fuente hols.c, creando el archivo binario que fue especificado mediante el argumento -o, o sea hola. El comando ls (que vendria a ser algo así como la contraparte UNIX del comando DIR de DOS) muestra que existe un nuevo programa, hola. El ultimo comando ejecuta el programa, y produce la siguiente salida: $ ls hola.c hola $ ./hola ¡Hola, mundo de programadores de Linux! Precaucion El comando que ejecuta el programa hola incluia especificamente al directorio corriente,representandolo con un punto (.), porque incluir al directorio corriente en la ruta representa un riesgo para la seguridad. Es decir, si el directorio corriente fuese un subdirectorio del ultimo directorio incluido en la ruta, en lugar de utilizar una sentencia SPATH semejante a /bin: /usr/bin: usr/local/bin/: .(con el punto final), la sentencia deberia ser /bin: /usr/bin: /usr/local/bin, de modo que ningun hacker pudiera colocar en el directorio corriente, un comando dañino del mismo nombre del comando normal que uno verdaderamente desea ejecutar. ¿Como sabe gcc cómo procesar los archivos? Se basa en las extensiones de los mismos para determinar cómo procesar correctamente cada archivo. Las extensiones más comunes y sus interpretaciones se listan en la tabla 1.1 Tabla 1.1 Cómo interpreta gcc las extensiones de archivo Extensiones Tipo de Archivo .c Codigo de lenguaje C .C, .cc Codigo de lenguaje C++ .i Codigo de C procesado .ii Codigo fuente de C++ procesado .S, .s Codigo fuente en lenguaje ensamblador .o Codigo objeto compilado .a, .so Codigo de biblioteca compilado Invocacion de gcc paso a paso En el primer ejemplo hubo muchas cosas que tuvieron lugar de manera en cubierta y el lector no las vio, gcc primero corio hola.c por el preprocesador, cpp, para expadir cualquier macro que pudiese haber e insertar los contenidos de los archivos incluidos mediante #include. Luego compilo el codigo fuente preprocesado,convirtiendolo en código obj. Finalmente el linker, ld,creo el archivo binario hola. El proceso completo de vinculacion se ilustra en la fig 1-1. Codigo Fuente |<-Preprocesador v Preoprocesado de Codigo fuente | v Compilar | v Codigo Objetos | v / Librerias de codigo Enlazador <- | puesta en marcha del codigo. v Ejecutar Archivo Figura 1.1 La compilacion de un programa consiste de varias etapas. Uno puede recrear estas etapas manualmente, avanzando por el proceso de compilacion un paso por vez. Para indicar a gcc que detenga la compilacion luego del procesado, utilice la opción -E de gcc, como se indica a continuacion: $ gcc -E archivo_entrada.c -o archivo de salida.cpp El paso siguiente consiste en compilar el archivo preprocesado para convertirlo en código objeto, utilizando la opcion .c de gcc. La opción -x se utiliza para indicarle a gcc que comience la compilacion a partir de scierta etapa La sintaxis correcta para esta esta etapa es: $ gcc -x cpp-output -c archivo_entrada.cpp -o archivo de salida.o Linkeando el archivo objeto, finalmente, se obtiene su imagen binaria. El comando que llevaría a cabo la etapa de vinculación sería añgo así como la siguiente: $ gcc archivo_entrada.c -o archivo_salida Ejemplo Volviendo al programa hola del ejemplo anterior, avance paso a paso a través del proceso de compilacion tal como lo ilustra el ejemplo siguiente. Primero, preprocese hola.c $gcc -E hola.c -o hola.cpp Si el lector examina hola.cpp con un editor de texto, verá que el contenido del archivo de ncabezamiento stdio.h ha sido efectivamente insertado en el codigo fuente junto a otros simbolos de preprocesado. El listado siguiente es un extracto del hola.cpp //realizar el eperimento El paso siguiente es compilar hola.cpp para convertirlo en código objeto: $gcc -x cpp-output -o hola.cpp -o hola.o Se debe utilizar la opcion -x para indicarle a gcc que comience la compilacion a cierta altura, en este caso, a partir del código fuente preprocesado. Cuando se efectúa el linkeo del codigo objeto, finalmente se crea un archivo binario: $ gcc hola.o -o hola Espero que con esto el lector pueda advertir que es mucho mas sencillo utilizar la sintaxis abreviada, gcc hola.c -o hola. El ejemplo paso a paso demostro que uno puede detener y comenzar la compilacion en cualquier etapa, si surgiese la necesidad. Una situacion en la cual uno puede realizar la compilacion paso a paso es cuando se está creando bibliotecas. En este caso, uno olo desea crear archivos objeto, de modo que la etapa final del linkeo resulta innecesaria. Otra circunstancia de realizar el proceso de compilacion paso a paso es cuando un archivo incluido mediante #include produce conflictos con el código que el lector ha redactado, o tal vez con otro archivo insertado con #include. Reacorrer el proceso paso a paso permitira con mayor claridad cual es el archivo que genera el conflicto. Utilizacion de multiples archivos de codigo fuente La mayoria de los programas de C consiste de múltiples archivos de código fuente, de modo que cada archivo fuente debe ser compilado a código objeto antes del paso final de línkeo. Este requirimiento se satisface con facilidad. Sólo se requiere proveer a gcc del nombre de cada archivo de código fuente que se deba compilar. gcc se hace cargo del resto del proceso. La invocación de gcc seriasimilar a la siguiente: $ gcc archivo1.c file2.c file3.c -o name_program gcc primero crea archivo1.o, archivo2.o y archivo3.o antes de linkearlos entre sí para crear nombre_programa. Ejemplo Supongamowss que se desea compilar nuevo-hola, que utiliza código proveniente de dos módulos, mostrar.c y mensaje.c, y un archivo de encabezado, msg.h: /**Nombre de programa en Internet*/ /*nuevo_hola.c*/ /*-------------------mostrar.c---------*/ /* *mostrar.c _ Controlador de pantalla */ #include #include "mensaje.h" int main(void) { char mensaje_bienvebida[]={"!Hola, programador¡"}; char mensaje_despedida[]={"!Adios, programador¡"}; printf("%sn",mensaje_bienvenida); imprimir_mensaje("mensaje_despedida" ) ; return 0; } /*-------------------mensaje.h-----------------------*/ /* * mensaje.h : Encabezado de mensaje.c */ #ifndef MENSAJE_H_ #define MENSAJE_H_ void imprimir_mensaje(char *mensaje); #endif /*MENSAJE_H_*/ /*---------mensaje.c-------------*/ /* *mensaje.c funcion definida en mensaje.h */ #include #include "mensaje.h" void imprimir_mensaje(char *mensaje) { printf("%sn",mensaje ) ; } El comando para compilar estos progrmas, y por lo tanto para crear nuevo_hola, es: $ gcc mensaje.c mostrar.c -o nuevo_hola Al correr este programa, su salida será la siguiente: $ ./nuevo_hola !Hola,programador¡ !Adios, programador¡ gcc recorre las mismas etapas de preprocesador- compilacion-linkeo que antes , esta vez creando archivos objetos para cada archico fuente antes de proceder a crear el archivo final binario, nuevo_hola. Tipear comandos largos como éste puede volverse tedioso, sin embargo. En el capitulo 2 "Control de proceso de compilacion: el make de GNU", se vera como resolver este problema. La proxima seccion prsentara lás muchas opciones de línea de comando de gcc. opcion y argumentos La lista de opciones de línea de comando que acepta gcc ocuparia varias paginas, de modo que la tabla 1.2 presenta sólo las más comunes. Tabla 1.2 Opciones de linea de comando gcc Opcion Proposito -o nombre_archivo Designar el archivo de salida nombre_archivo (no necesariamente cuando se compila código objeto). Si no se especifica el nombre de este archivo, la opcion predeterminada es a.out. -c Compilar sin linkear -Dfoo=bar Define un macro de procesador foo con un valor bar en la linea de comandos -Iruta_dir Sitúa la ruta de acceso al directorio especificado en ruta_dir al comienzo de la lista de direcciones en que gcc busca a incluir por la presencia de la directiva #Include -Lruta_dir Situa la ruta de acceso al directorio especificado en ruta_dir al comienzo de la lista de directorios en que gcc busca archivos de biblioteca. Como opcion predeterminada, gcc linkea bibliotecas compartidas. -static Linkea biblliotecas estáticas. -lfoo Linkea la biblioteca foo. -g Incluye en el archivo binario informacion estándar de depuración. -ggdb Incluye en el archivo binario muchisima información de depuracipon que solo puede interpretar el depurador del GNU,gdb -O Optimiza el codigo de compilacion, Esto es equivalente a especificar -O1 -On Especifica un nivel de optimización n, 0<=n<=3 -ansi Coloca el compilador en modo ANSI/ISO C, no permite extensiones GNU que genera conflictos con dichos estandares. -pedantic Muestra todas las advertencias que requiere que el ANSI/ISO C estandar -pendatic-errors Muestra todos los errores que requiere el ANSI/ISO C estandar -traditional Habilita el apoyo para la sintaxis del C de Kernighan y Ritchie (si el lector no comprende lo que significa eso, no se preocupe po r ello; basta con saber que Kernighan y Ritchie fueron los diseñadores del C original ). -W Suprime todos los mensajes de advertencia -Wall Exhibe todas las advertencias generalmente aplicables que puede proveer gcc. Para ver advertencias especificas, utilice -Wwarning. -werror En lugar de generar advertencisas, gcc convertira las advertencias en errores, deteniendo la compilacipon -MM Emitirá una lista de dependencia compatibñe con make, útil para crear una makefile en un proyecto complicado. -v Muestra los comandos utilizados en cada etapa de la compilacion. El lector ya ha visto cómo operan -C y -O. Si no se especifica -o, sin embargo, para un archivo de entrada denominado nom_archivo.ext (donde ext representa cualquier extension de hasta tres caracteres)., la accion predeterminada de gcc será denominar al archivo ejecutable a.out, al archivo objeto nombre_archivo.o, y al archivo en lenguaje ensamblador nombre_archivo.s. La salida del preprocesador va al dispositivo que se encuentre establecido como stdout (dispositivi estándar de salida) Archivos de biblioteca y de inclusión Si se dispone de archivos de biblioteca o de inclusion situados en ubicaciones no eestandár, las opciones -Lruta_dir y -Iruta_dir permiten especificar dichas ubicaciones y asegurar que se busque los repectivos archivos en esas ubicaciones antes de hacerlo en las estandár (las asignadas por compilador como predeterminadas). Por ejemplo , si se almacenan los archivos de inclusión habituales en /usuario/local/mis_inclusiones, para que gcc los encuentre la invoacion a gcc deberia ser algo parecido a: $ gcc infile.c -I/usuario/local/mis_inclusiones De manera similar , supongamos que el lector esté comprobando una nueva biblioteca de programacion, libnueva.a, que esta corrientemente almacenada en /ususario/local/mis bibliotecas, antes de instalarla como biblioteca estándar de sistema. Supongamos también que los archivos de encabezado están almacenadas en /usuario/local/mis_inclusiones. Consecuente,emte, para linkear libnueva.a y ayudar a gcc a encontrar los archivos de encabezado, el comando gcc de linéa de comandos deberia ser similar añ siguiente: $ gccmi_aplicacion.c -I/usuario/local/mis_inclusiones -L/usuario/local/mis_bibliotecas -lnueva La opcion -l le indica al linker que tome códig objeto desde la biblioteca especificada. El ejemplo anterior vincularia libnueva.a Consejo Una convencion Unix requiere que las bibliotecas de denominaran lib{algun nombre}, y gcc, al igual que la mayoria de los compiladores de UNIX y de Linux, se basa en dica convencion. Si el lector no utiliza la opcion -l cuando vincula bibliotecas o no proveee una ruta de acceso a la biblioteca a ser vinculada, la etapa de linkeo no tendra éxito y gcc emitira un mensaje de error aduciendo referencias sin definir a "nombre de funcion". Como opción predeterminada gccc utiliza bibliotecas compartidas, de modo qie si el lector necesita vincular bibliotecas estáticas,deberá utilizar la opción -static. Esto significa que se solo se utilizarán bibliotecas estáticas . El siguiente ejemplo crea un archivo ejecutable vinculado contra la biblioteca estática ncurses: $gcc aplic_curses.c -lncurses -static -Para aprender a progrmar con ncurses, ver "Una interfaz API de usuario en modo texto" Cuando uno vincula bibliotexas estáticas, el archivo ejecutable que se obtiene resulta mucho más grande que cuando se utilizan bibliotecas compartidas. ¿Para que utilizar una biblioteca estática, entonces? Una razon habitual es para garantizar que los usuarios puedan utilizar el programa: en el caso de las bibliotecas compartidas, el código que necesita un progra,a para poder corrrer se linkea al mismo dinámicamente durante su ejecución, en lugar de serlo estaticamente durante su compilación. Si la biblioteca compartida que requiere el programa para poder ser corrido no se encuentra instalada en el sistema del usuario, el mismo obtendra errores y no podrá correr el programa. EL navegador Netscape constituye un ejemplo perfecto de este problema. Netscape se basa fuertemente en Motif, un costoso toolkit de programacion en X. La mayoria de los usuarios linux no puede afrontarse el costo de instalar Motif en sus sistemas por que el mismo cuesta demasiado dinero, de modo que Netscape en la practica instala dos veriones de su navegador, en sus sistema; una que linkea bibliotecas compartida , netscape -dynMontif, y una que vincula bibliotecas estáticas, netscape -statMotif. El propio archivo ejecutable de Netscape es en realidad un script de interfaz que determina si el usuario posee instalada la biblioteca compartida de Motif y activa uno u otro de los archivos binaros según sea requerido. Ejemplo 1. Este ejemplo crea una bibloteca estática, libmensajes.a. Los comandos requeridos para hacer esto son $ gcc -c mensajes.c -o libmensajes.o $ ar rcs libmensajes.a libmensajes.o Recuerdese en un parrafo anterior de este capitulo que -c le indica a gcc crear un archivo objeto denominando en este caso, libmensajea.o la segunda linea utiliza el comando ar ppara crear la biblioteca estática denominada libmensajes.a a partir del módulo objeto, libmsg.o. El ejemplo siguiente utiliza esta biblioteca. 2.Ahora el lector dispone de una biblioteca para poder ser linkeada. Le deberá informar a gcc dónde encontrar el archivo de inclusión, utilizando -I dónde encontrar la biblioteca empleando -L, y el nombre de la biblioteca , utilizando -l como se ilustra aqui $ gcc mostrar.c -o nuevo_hola_lib -I. -L. -lmensajes Un ejemplo anerior creaba nuevo_hola compilando juntos mostrar.c y mensajes.c. Esta vez, creamos nuevo_hola_lib linkeando la biblioteca estática libmensajes.a. Este ejemplo creo un archivo ejecutable denominado nuevo_hola_lib (el nombre fue elegido aqui para distinguirlo del que se empleaba en el otro ejemplo ) vinculando a libmensaje.a,(-lmensajes) ubicado en el directorio del trabajo (actual) corriente (-L.). El punto (.) situado al lado de la letra L representa el directorio corriente. La salida de este programa se listar a continuación. $ ./nuevo_hola_lib ¡Hola,programador! ¡Adios programador!
Datos archivados del Taringa! original
30puntos
3,290visitas
0comentarios
Actividad nueva en Posteamelo
0puntos
8visitas
0comentarios
Dar puntos:

Dejá tu comentario

0/2000

Autor del Post

l
lexlawliet🇦🇷
Usuario
Puntos0
Posts3
Ver perfil →
PosteameloArchivo Histórico de Taringa! (2004-2017). Preservando la inteligencia colectiva de la internet hispanohablante.

CONTACTO

18 de Septiembre 455, Casilla 52

Chillán, Región de Ñuble, Chile

Solo correo postal

© 2026 Posteamelo.com. No afiliado con Taringa! ni sus sucesores.

Contenido preservado con fines históricos y culturales.