Blog de Abelardo Jara Berrocal: Ubuntu, electronica y software libre

Marzo 16, 2008

Crear CD de repositorios de tu Ubuntu con apt-on-CD

Archivado en: Linux Ubuntu Administracion — Abelardo Jara @ 4:45 pm
Tomado de:

http://armandodiaz.wordpress.com/2007/07/31/crear-cds-de-repositorios-en-ubuntu/

Bueno he investigado recientemente en una forma de instalar Ubuntu, actualizarlo e instalar los programas que utilizo sin tener una conexion de Internet, esto puede ser util cuando se lo quieres instalar a un amigo de una forma rapida y/o no tiene acceso a Internet, ademas de ser algo muy practico si decides reinstalar ubuntu aunque no veo la necesidad de reinstalar como en SO donde cada mes debes resintalarlo para que funcione bien, o.k mejor empezemos de una vez.

Instalmos AptonCD que es un nuevo programa para distribuciones Debian (Ubuntu incluída) que permite grabar en CD o DVD los programas que tenemos en nuestros repositorios.

Lo puedes instalar de varias formas, desde la consola, Synaptic o descargando el deb, bueno les explico como lo instale yo

descarge desde esta pagina aqui el deb luego lo instalamos (ya sabes la forma mas facil, dando doble click).

Luego lo ejecutamos desde Sistema->Administración->APTonCD. y ejecutamos Crear AptonCd

Crear ISO

luego automaticamente busca los paquetes para añadirlo diferenciando los que estan en su ultima version (los marca por defecto) y las versiones antiguas (no los marca), ademas si has descargado otros deb o quieres guardar otros tipos de archivos pudes añadirlos, luego de esto le das aceptar y te crea un ISO con los paquetes y la quemas con cualquier grabador de Imagenes ISO puede ser GnomeBaker o KB3 por decir algunos.

guardar iso

ya cuando lo quieras instalar solo debes de ir a Sistema->Administración->Gestor de paquetes Synaptic, en el menu de configuracion >repositorios en pestaña otros repositorios Añadir CD-ROM, aceptamos y refrescamos la lista de programas disponibles, muy facil claro que si y ademas muy practico.

Repositorio

Fecha y Hora en la consola (Bash) en GNU/Linux

Archivado en: Linux Ubuntu Administracion, Programacion del Bash — Abelardo Jara @ 2:58 pm

Tomado de:

http://braianet.blogspot.com/2008/03/fecha-y-hora-en-la-consola-bash-en.html

Excelente truco leído en http://www.busindre.com donde nos muestra como tener un reloj permanente en nuestra consola, además de explicar la instalación mediante las fuentes para BSD y Gnu/Linux. Les dejo un screenshot. Saludos!


Si queremos ver en nuestra terminal bash de GNU/Linux / FreeBSD la fecha y la hora en todo momento de una forma limpia, podemos seguir este truco basado en la utilidad GNU “screen”, la cual sino viniera instalada en nuestro sistema, la podremos encontrar en nuestro gestor de paquete avanzado (apt, yum, urpmi, yast, etc…) o en forma de sources en los repositorios GNU. La utilidad de esto recae sobre todo cuando salimos a las terminales (Ctrl + Alt + tecla F), ya que fuera del entorno gráfico no disfrutamos de un reloj al que poder consultar.

Hay otros métodos de poder ver la fecha en consola, como es configurarlo en el propio prompt o haciendo uso de algún script, pero realmente no son las mejores soluciones, vamos a ver como hacerlo de forma más óptima, cómoda y rápida mediante la aplicación screen.

Instalamos screen en ArchLinux o en la distro que tengan mediante su gestor de paquetes.

pacman -S screen

Una vez instalado la utilidad screen, tenemos que añadir al fichero de configuración screenrc, ya sea el global (/etc) o el perteneciente a cada usuario ($HOME/.screenrc) la siguiente linea:

caption always "%{+b wk}%-21=%D %d/%m/%Y %0c"

NOTA: La opción “startup_message on” podemos desear ponerla en “off” para que no muestre el mensaje de copyright cada vez que screen se ejecute.

Luego para que aparezca la fecha y la hora según nos acreditemos en una consola cuya shell sea bash, debemos añadir esta linea al fichero $HOME/.bash_profile (Sino tenemos el fichero debemos crearlo). También podríamos añadirla al fichero /etc/profile.

screen

Al ser añadido al fichero .bash_profile, cada vez que se nos pida login y password en una terminal, veremos que en la parte inferior derecha tenemos mostrada la fecha y la hora. Pero claro, esto es solo al loguearnos, de estar logueados en el entorno gráfico no se pide login y password por lo que en las consolas que arranquemos (xterm, konsole, ater, aterm, rxvt y demas) debemos ejecutar el comando screen cuando queramos disfrutar de la fecha y hora. Realmente su utilidad esta mas centrada en el uso de las tty ya que en los escritorios la hora suele estar casi siempre a la vista.

Usando la aplicación screen, para poder salir de una consola / terminal deberemos ejecutar dos veces el comando exit, una para salir del screen y otra para cerrar la sesión. Este mismo truco puede ser aplicable a otro tipo de shells, no solo a bash, pero ya cambiarían los ficheros de configuración dependiendo de si usamos bash, sh, zsh, etc…

Expresiones Regulares en la shell: Ejemplos de uso con grep, awk y sed.

Archivado en: Programacion del Bash — Abelardo Jara @ 2:51 pm

Tomado de:

http://braianet.blogspot.com/2008/03/expresiones-regulares-en-la-shell.html

Estaba intentando hacer un CGI muy sencillo usando bash (como lo que quería hacer era algo muy específico de bash, no he querido usar ni Perl, ni PHP). La única dificultad que he encontrado ha sido obtener las distintas variables que el método GET pasa al CGI a través de la variable $QUERY_STRING, que normalmente tiene este aspecto:

QUERY_STRING='parametro1=valor1&parametro2=valor2&parametro3=valor3'

Estaba yo ya comenzando a darle vueltas a una Expresión Regular para interpretar dicha salida cuando he decidido buscar en Google para ver si alguien tenía una solución más completa que la que yo ya tenía a medias. He llegado al artículo CGI Scripting Tips for Bash or SH que propone lo siguiente para extraer del QUERY_STRING la variable que nos interese:

PARAMETROX=`echo "$QUERY_STRING" | grep -oE "(^|[?&])parametrox=[^&]+" | sed "s/%20/ /g" | cut -f 2 -d "="`

Y es que con bash y sus compañeros sed, awk, cat, grep, etc. aún se puede hacer casi de todo, incluso un weblog o un servidor web. Como las Expresiones Regulares son tan excepcionalmente útiles como complicadas a la hora de usarlas, me he decidido a comentar algunos ejemplos, comenzando por el que me ha llevado a este artículo.

Y antes de seguir conviene comentar que la opción -o del grep del comando anterior indica que la salida del comando ha de contener únicamente la parte de texto que coincide con el patrón, no toda la línea. La opción -E indica que se va a usar una Expresión Regular Extendida (egrep es lo mismo que grep -E).

Pasemos a analizar la expresión regular… (^|[?&])parametrox=[^&]+ significa que buscamos algo que:

^|[?&] está a principio de línea ^ o | que comienza por un caracter ? o un &
parametrox= seguido por la secuencia de caracteres parametrox=
[^&]+ y que acaba con uno o más caracteres + que no sean &

Ejemplos de Expresiones Regulares

La página http://www.regular-expressions.info es un excelente sitio para aprender sobre expresiones regulares. Allí he encontrado algunos ejemplos que me han gustado Éstos son tres de ellos especialmente útiles:

Buscar una dirección de e-mail

\b[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b

\b[A-Z0-9._%-]+ Buscamos un comienzo de palabra \b que contenga uno o más caracteres + dentro del conjunto A a Z, 0 a 9,., _, % y -, que son los caracteres admitidos para un nombre de usuario
@ seguido del símbolo @
[A-Z0-9.-]+ seguido por uno o más + caracteres A a Z, 0 a 9,. y -, que son los caracteres admitidos para un dominio
\. seguido por un punto escapado con \, ya que el punto solo significa cualquier caracter
[A-Z]{2,4}\b seguido por entre 2 y 4 caracteres {2,4} entre el conjunto A-Z y además éste tiene que ser el final de una palabra \b

Por tanto, si usáramos esa expresión regular con egrep sobre un texto como este:

En un lugar de la Mancha, de cuyo nombre no quiero acordarme, pero a cuyo ayuntamiento podíamos enviar e-mails a la dirección ayuntamiento@lugardelamancha.es, no ha mucho tiempo que vivía un hidalgo de los de lanza en astillero, adarga antigua, rocín flaco y galgo corredor cuyo e-mail era don.quijote@del.toboso.edu.

obtendríamos:

$ egrep -oi '\b[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4}' donqui.txt
ayuntamiento@lugardelamancha.es
don.quijote@del.toboso.edu

Buscar dos palabras cercanas en un párrafo

Si consideramos que dos palabras cercanas son aquellas que están separadas entre 1 y 8 palabras, esta expresión regular es perfecta:

\bpalabra1\W+(w+\W+){1,8}palabra2\b

\bpalabra1 Buscamos un comienzo de palabra con la sucesión de caracteres palabra1
\W+ seguido por uno o varios caracteres no alfanuméricos \W
(\w+\W+){1,8} seguido de entre 1 y 8 grupos {1,8} de uno o más caracteres alfanuméricos \w y uno o más caracteres no alfanuméricos \W
palabra2\b acabado un la sucesión de caracteres palabra2

Y podemos probar la expresión sobre el texto anterior:

$ egrep -o '\bhidalgo\W+(\w+\W+){1,8}lanza\b' donqui.txt
hidalgo de los de lanza

Por supuesto, puede ser que no sepamos si palabra1 va antes que palabra2, así que podemos especificar que una cosa o | la otra:

\b(palabra1\W+(\w+\W+){1,8}palabra2|palabra2\W+(\w+\W+){1,8}palabra1)\b

Buscar una dirección IP

\b[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\b

Creo que este ejemplo ya no necesita explicación, aunque tiene un defecto: la expresión encajaría también con 999.999.999.999. Para corregirlo, podríamos sustituir cada bloque [0-9]{1,3} por (25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?) que significa que cada número puede ser del 250 al 255 25[0-5] o del 200 al 249 2[0-4][0-9] o del 0 al 199, contemplando la posibilidad de que por ejemplo un 7 se escriba 7, 07 o 007 [01]?[0-9][0-9]?. El símbolo ? indica uno o ninguno.

Podemos obtener fácilmente una lista de IPs que han visitado nuestro servidor web con el siguiente comando:

$ egrep -o '\b[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\b' access.log | sort -u

Ejemplos de uso de las Expresiones Regulares en la shell

En el uso diario de la shell, las expresiones regulares son nuestra navaja suiza. Ya hemos visto algunos ejemplos con grep, pero sigamos con algunos más de cosecha propia que usan grep, awk y sed.

Lista de usuarios con password a partir del /etc/shadow

Resulta que queremos saber los usuarios del fichero /etc/shadow que pueden logearse al sistema (que no tienen un caracter ! o * en el campo del password). La expresión regular a usar sería:

# egrep '^[^:]+:[^*!]+:' /etc/shadow
fulano:$1$PFC1F2pj$0KEflTjNmDQg9.rtFT/DK0:12793:0:99999:7:::
mengano:$1$aAUa4js/$c2LEh.HeT0JvCG3B.34O.:12793:0:99999:7:::

^[^:]+ Buscamos uno o más caracteres + que no sean : [^:] a principio de línea ^
: seguido de un caracter :
[^*!]+ seguido por una secuencia de uno o más caracteres que no sean ! o *
: seguido de otro caracter :

Podemos hacerlo un poco mejor, porque sólo nos interesa ver el nombre del usuario. Para ello podríamos hacer un cut -f 1 -d : sobre la salida anterior, pero usando el awk somos capaces de hacer lo anterior en un sólo comando:

# awk -F":" '$2~/[^!*]+/ { print $1 }' /etc/shadow
fulano
mengano

En el comando anterior le decimos a awk que, usando como separador de campos el caracter : (-F”:”) queremos que nos saque el primer campo { print $1 } siempre que el segundo campo cumpla la regla de que contenga uno o más caracteres que no sean ! o * $2~/[^!*]+/.

Extraer los referer del access.log

Si tenemos líneas como la siguiente (LogFormat combined) en el access.log de nuestro apache:

192.168.1.3 - - [12/Apr/2007:22:15:14 +0200] "GET /blog/ HTTP/1.1" 200 46503 "http://www.google.es/search?hl=es&q=vicente+navarro" "Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.8.1.3) Gecko/20070310 Iceweasel/2.0.0.3 (Debian-2.0.0.3-1)"
192.168.1.3 - - [12/Apr/2007:22:24:07 +0200] "GET /blog/ HTTP/1.1" 200 46503 "http://www.google.es/search?q=super+coco&hl=es&start=10&sa=N" "Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.8.1.3) Gecko/20070310 Iceweasel/2.0.0.3 (Debian-2.0.0.3-1)"

podemos obtener un listado de los referers que han traído a los visitantes a la página con el siguiente comando:

$ egrep -o '^[0-9.]+ - - \[.+\] \"[^"]+\" [0-9-]+ [0-9-]+ \"[^"]+\"' access.log | egrep -o '\"[^"-]+\"$' | egrep -o '[^"]+' | sort -u
...
http://www.google.es/search?hl=es&q=vicente+navarro
http://www.google.es/search?q=super+coco&hl=es&start=10&sa=N
...

Hay dos grep’s, porque estamos identificando y extrayendo todo el texto hasta llegar al referer para dejarlo al final y después extraerlo con el segundo grep. Pero aunque sirva para ilustrar la entrada, resulta que nos hemos complicado muchísimo la vida, porque el trozo del referer es el único que comienza con http://. Teniendo en cuenta esto, el comando, con una Expresión Regular mucho más simple, queda:

$ egrep -o 'http://[^"]+' access.log | sort -u

Y usando sólo awk:

awk '$0~/http/ { print $11 }' access.log | awk -F'"' '{ print $2 }' | sort -u

Pero ahora queremos saber a partir de los referers que hemos obtenido anteriormente, con qué parámetros de búsqueda y en qué posición aparece nuestra página en Google. Para ello, podríamos usar la Expresión Regular del principio para obtener los parámetros q= y start= de la URL de Google, pero hagámoslo con awk:

$ egrep -o 'http://[^"]+' big | sort -u | awk -F "[?&=]" '$1~/google.+search/ { TERMINOBUSQUEDA=""; POSICION="0"; for (i=2; i<=NF; i++) { if ($(i-1)~"(^|^as_)q$") { TERMINOBUSQUEDA=$i; } if ($(i-1)~"^start$") { POSICION=$i; } } print TERMINOBUSQUEDA " " POSICION; }' super+coco 10 vicente+navarro 0

Es decir, si la línea es una búsqueda de Google, el awk ha de hacer:

TERMINOBUSQUEDA="";
POSICION="0";
for (i=2; i<=NF; i++) { if ($(i-1)~"(^|^as_)q$") { TERMINOBUSQUEDA=$i;} if ($(i-1)~"^start$") { POSICION=$i; } } print TERMINOBUSQUEDA " " POSICION;

Expresiones Regulares de Perl (PCRE)

Las Expresiones Regulares de Perl (PCRE) son más potentes que las Expresiones Regulares POSIX. En algunas distribuciones, el grep -P nos permite usarlas, pero en Debian no es posible usar la opción -P de grep. En cambio, tenemos el pcregrep que sí que nos lo permite. Y una de las cosas más interesantes que se puede hacer con estas reglas es Lookahead y Lookbehind. Supongamos que queremos sacar de las URL de Google el valor del parámetro q= con un sólo comando, a diferencia de la expresión del principio que requería un cut adicional:

$ echo "http://www.google.es/search?q=super+coco&hl=es&start=10&sa=N" | pcregrep -o '(?<=[&?]q=)[^&?]+' super+coco

Usando PCRE, algo como (?<=delante)detras significa que para coincidir, la cadena tiene que ser delantedetras, pero delante no aparecerá en la cadena coincidente. ¡Muy útil! La pena es que este tipo de expresiones no se puede usar con cadenas de longitud variable:

$ pcregrep -o '(?<=\w+)prueba' fichero.txt pcregrep: Error in command-line regex at offset 7: lookbehind assertion is not fixed length

Ejemplos con sed y el /etc/passwd

sed es otra utilidad muy versátil. Su función más típica es la de sustitución, aunque también puede hacer cosas sencillas pero útiles como mostrar sólo un conjunto de líneas de un fichero o eliminarlas, insertar texto al final de una línea determinada o reemplazar el texto de esa línea..

La sintaxis típica de sed para reemplazos es:

sed -r 's/reemplazada/reemplazo/g'

El -r es paraque el sed use Expresiones Regulares Extendidas o POSIX y el g significa que la sustitución se hará todas las veces que se encuentre la Expresión Regular en la línea, no sólo la primera vez. Si nos viene mal usar el carácter / para no tener que escapar, por ejemplo, muchas barras de path, podríamos usar cualquier otro carácter: s_reemplazada_reemplazo_g.

Por ejemplo, si quisiéramos cambiar la shell por defecto a todos los usuarios que aparecen en /etc/passwd, podríamos hacer:

$ sed -r 's/[^:]+$/:\/bin\/bash/g' /etc/passwd
...
mail:x:8:8:mail:/var/mail::/bin/bash
news:x:9:9:news:/var/spool/news::/bin/bash
uucp:x:10:10:uucp:/var/spool/uucp::/bin/bash
...

Y si queremos añadir una cabecera de “usuario_” a todos los nombres de usuario del sistema, podemos usar el carácter & para usar la parte coincidente en la cadena de reemplazo:

$ sed -r 's/^[^:]+/usuario_&/g' /etc/passwd
...
usuario_mail:x:8:8:mail:/var/mail:/bin/sh
usuario_news:x:9:9:news:/var/spool/news:/bin/sh
usuario_uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh
...

Y como lo que pongamos entre paréntesis () en la cadena reemplazada, el sed nos lo guarda para usar en la cadena de reemplazo en \1, \2,… \9, supongamos que queremos mover todo a un nuevo sistema de ficheros y queremos cambiar tanto el home del usuario como su shell:

$ sed -r 's/([^:]+):([^:]+)$/:\/newfs\1:\/newfs\2/g' /etc/passwd
...
mail:x:8:8:mail::/newfs/var/mail:/newfs/bin/sh
news:x:9:9:news::/newfs/var/spool/news:/newfs/bin/sh
uucp:x:10:10:uucp::/newfs/var/spool/uucp:/newfs/bin/sh
...

Enlaces relacionados

Actualización 14/4/07: Un pobrecito hablador (¡muchas gracias!) comenta en la bitácora de Super Coco en Barrapunto otra interesante forma de obtener un parámetro de la QUERY_STRING:

PARAMETROX=`echo "$QUERY_STRING" | sed -r 's/.*\bparametroX=([^&]+).*/\1/'`

Actualización 9/11/07:

Supongamos que encontramos una página que ofrece muchos enlaces a ficheros para descargar de la red P2P eDonkey y nosotros queremos usar el aMule para hacerlo sin tener que copiar o pegar todos los enlaces o hacer click sobre todos ellos. Los enlaces ed2k aparecen en el código HTML de la página así:

fichero de la red eDonkey

Pues bien, tras guardar el HTML de la página en cuestión a disco, queremos extraer dichos enlaces para usarlos en el comando ed2k de aMule. Si supiéramos que no hay más de un enlace por línea podríamos hacerlo simplemente con un grep:

ed2k $(grep -E -o 'ed2k://[^/]+/' pagina.html)

Pero como es muy posible que no sea así, casi mejor lo hacemos con un awk:

ed2k $(awk -F '"' '/ed2k/ { for (i=1; i<=NF; i++) if ($i~"^ed2k") { print $i } }' pagina.html)

Actualización 26/11/07:

Extraer el texto existente entre etiquetas de un fichero HTML:

# pcregrep -o '(?<=)(.*?)(?=)' index.html
prueba

Si la probamos con el pcregrep, sólo sacará como máximo una coincidencia por línea y no funcionará si las etiquetas de principio y final están en líneas diferentes.

Cuando la etiqueta de principio tenga algún parámetro como por ejemplo: , la expresión no funcionará. Sin embargo, con algo como:

# pcregrep -o ']*>(.*?)' index.html
prueba

podríamos extraer el texto con las etiquetas, pero hemos tenido que quitar los lookahead y lookbehind porque si no:

# pcregrep -o '(?<=]*>)(.*?)(?=)' index.html
pcregrep: Error in command-line regex at offset 19: lookbehind assertion is not fixed length

Como crear servidor de repositorios Ubuntu/Debian para nuestra red local

Archivado en: Linux Ubuntu Administracion — Abelardo Jara @ 2:39 pm

Tomado de:

http://blog.iones.org/?p=18

El proceso es realmente sencillo y útil si tienes más de una máquina. La finalidad es evitar descargar los paquetes de nuevo si ya lo hiciste una vez, por eso habrá un equipo que haga servidor y desde el cual se actualizará el repositorio que creemos. El primer proceso es instalar la herramienta apt-move, para ello simplemente realizar un :

# apt-get install apt-move

ya sea desde el usuario root o través de sudo. El funcionamiento es fácil de entender, esta herramienta va a crear un mirror a partir de los paquetes ( en nuestro caso ) que tome de /var/cache/apt/archives y los introduce en una estructura con la misma jerarquía que un mirror de debian. En este mirror tendremos los paquetes que se vayan actualizando desde la equipo que actua como repositorio y junto con los que instalemos nuevos. Una vez instalado apt-move, procedemos a configurar el archivo que se encuentra en /etc/apt-move.conf, es muy sencillo y bastante intuitivo.

Configuración de apt-move.conf

APTSITES=”ftp.rediris.es ” (Es muy importante dejar el espacio despues del nombre o dará fallos, se pueden añadir más nombres de servidores.
LOCALDIR=/mnt/repositorio (Donde creamos el repositorio, es buena idea tener una particion distinta).
FILECACHE=/var/cache/apt/archives ( Lógico, es de donde obtenemos los paquetes)
DELETE=yes ( Elimina la versiones más antiguas de los paquetes del repositorio )

Ahora es necesario tener un servidor, ya sea http o ftp, o de cualquier otro tipo que nos dé acceso al mirror que acabamos de crear. En mi caso tengo instalado Apache, con lo cual tendré que crear un enlace simbólico al repositorio dentro del directorio accesible por Apache, que por defecto es /var/www/.
Con lo cual, ahora mirror ( el enlace ) ya es accesible via http. Ya quedan pocos pasos para tener listo nuestro mirror local, el siguiente paso es actualizar nuestro sistema.

# apt-get update; apt-get dist-upgrade; apt-move update

Si todo ha ido bien, nuestro repositorio se habrá creado de forma correcta, podeis entrar para comprobar la jerarquía de un mirror de Debian, es igual que el de cualquier ftp de Debian que podais haber entrado.

Configurando el source.list

Ahora solo hay que configurar el source.list de los equipos necesarios, simplemente añadir la siguiente linea al archivo:

deb http://10.10.10.10/mirror/ testing main contrib non-fre

Evidentemente la IP depende de cada uno, yo por llevar la contraria monté una red de clase A , pero ese es otro tema, mirror es el nombre del enlace simbólico que creamos en el directorio /var/www/, lo siguiente depende de la rama con la que esteis trabajando, y de las secciones que tengais. LLegado esto, simplemente queda hacer un apt-get update en el equipo recien configurado para que añada la lista de paquetes de nuestro mirror local, el funcionamiento es simple, si un paquete no está en nuestro repositorio busca en los siguientes que tengamos, por eso colocar el nuestro el primero del source.list. Enlaces que me han ayudado (no puedo evitar hablar como si hubiesen más lectores. Links: WikiDebian y BulmaLug . En fin, si se me olvida se que lo tengo aquí, pero por si acaso tengo que investigar como hacer un backup de mi blog. Recuerdos a BaTuz el único nunca mejor dicho, que me lee, a ver si tu también te pones a escribir algo.

Combinaciones básicas para EMACS

Archivado en: EMACS y edicion de documentos con Latex — Abelardo Jara @ 2:30 pm

A petición de un amigo voy a poner los keystrokes de Emacs que más suelo utilizar cuando programo, paro los que no conozcan Emacs ( Editor MACROS, de ahí su contracción), decir que es muy potente, y que cada día me sorprende más, estava escribiendo la serie de combinaciones que más utilizo y las que conozco y me he dado cuenta que se bastantes, con lo cual, en vez de soltar de golpe todas las que conozco, voy ha relizarlo en varias partes, las que considere oporturnas para que no se haga pesado leer todas de golpe, en esta primera remesa voy a poner las que más se usan a nivel básico, es decir movimiento, ficheros , trabajo con buffers, búsqueda….

Simbología

ESC-x o Meta-x : Lo veo en muchos sitios, y es lo mismo, pero és más comodo usar Alt-Izq ( Meta ), o por lo menos a mi me lo parece.

Ctrl-x ( Esto significa que sin soltar control, pulsar x)

Evidentemente esta recopilación será de utilidad para alguien que haya manejado Emacs minimamente, aunque no por ello no quiere decir que no sirva para la iniciación.

  • Moviendose por EmacsCtrl-n ( Avanza a la línea siguiente)
    Ctrl-p ( Retrocede a línea anterior)
    Ctrl-f ( Avanza un caracter )
    Ctrl-b ( Retrocede un caracter )
    Ctrl-a ( Ir al principio de la línea )
    Ctrl-e ( Ir al final de la línea )
    Ctrl-v ( Avanzar una página )
    Ctrl-j ( Retorno )
    Ctrl-m ( Retorno , hay diferencia con la anterior, si se pulsa estando en el shell se ejecuta la orden que esté escrita, en el otro caso pasa de línea)
    Meta-f ( Avanzar de palabra en palabra )
    Meta-b ( Retrocede una palabra )
    Meta-a ( Ir al incio de un parrafo )
    Meta-e ( Ir al final de un parrafo )
    Meta-v ( Retroceder una página )
    Meta- ( Ir al final del buffer )
    Ctrl-x Ctrl-c ( Salir de Emacs )
    Ctrl-z ( Suspender Emacs, en consola se pone en background, para volver basta con escribir en la consola fg, mientras que en las X simplemente se minimiza )
  • Buffers y Frames Ctrl-o ( Cambias de buffer )
    Ctrl-x Ctrl-b ( Listado de los buffers abiertos )
    Ctrl-b ( Cambias al buffer siguiente)
    Ctrl-x 2 ( Split de la pantalla en dos, horizontalmente )
    Ctrl-x 3 ( Lo uso muchísimo, hace split vertical )
    Ctrl-x 5 2 ( Abre en un ventana nueva el buffer en el que estas, ojo!! si sales de esa venta es como si cierras el original )
    Ctrl-x 5 0 ( Cerrar ventana )
    Ctrl-x { ( Mueves el scroll hacia la izquierda )
    Ctrl-x } ( Mueves el scroll hacia la derecha )
  • Marking y eliminación
    Ctrl-space o Ctrl-@ ( Establece marco de selección )
    Ctrl-w ( Cortar )
    Meta-w ( Copiar)
    Ctrl-y ( Pegar )
    Ctrl-d ( Elimina un caracter)
    Ctrl-k ( Elimina la línea actual )
  • Ficheros
    Ctrl-f ( Arbrir un archivo )
    Ctrl-x Ctrl-s ( Guardar cambios un archivo )
    Ctrl-x Ctrl-w ( Guardar como )
    Ctrl-d ( Introducir directorio )
    Ctrl-x i (Insertar archivo )
  • Búqueda y reemplazo
    Ctrl-s ( Buscar hacia delante )
    Ctrl-r ( Buscar hacia atrás )
    Ctrl-g (Abortar lo que se está haciendo, en este caso la búsqueda, sirve para todo )
    Meta-% ( Reemplazo, te pide la palabra a buscar y la que quieres sustituir, luego si no dices nada, pide confirmación una por una, salvo que introduzcas el carácter ‘!’ )
    Meta Ctrl-s RETURN ( Buscar mediante una expresión regular hacia delante )
    Meta Ctrl-r RETURN ( Buscar mediante una expresión regular hacia atrás )
  • Bueno, con esta primera parte creo que vamos bien, son combinaciones básicas, y se que al principio cuesta acostumbrase, sobre todo a dejar de usar las flechas para moverse por el texto, pero con el tiempo aprecias la fluidez y rapidez de Emacs.

    Configurando EMACS con las teclas abreviadas de Microsoft Word

    Archivado en: EMACS y edicion de documentos con Latex — Abelardo Jara @ 12:55 pm

    Emacs es mi editor de texto preferido (realmente soy fanatico de EMACS), lo uso continuamente en el trabajo y en casa. Es un editor muy potente, totalmente personalizable, pero dificil de aprender, eso si: una vez superada la curva es toda una herramienta de edición.

    Aun así tiene sus cosillas, por ejemplo: la funcionalidad de autoguardado tiene un pequeño (d)efecto lateral realmente feo. Por cada fichero que hayas editado te crea un fichero con el mismo nombre añadiendole un ~ al final del nombre del fichero. Al final acabas con miles de ficheros acabados en ~ por el disco duro, además puedes cometer errores si usas algún sistema de versiones de ficheros al añadir directorios con estos ficheros si olvidas que emacs lo genera.

    Además muchos de nosotros ni siquiera necesitamos esta funcionalidad. Yo llevo el autoguardado de serie, como si fuera un cron que se ejecutase cada minuto, de mis tiempos de estudiante de instituto en los que hacias trabajos con word. Si se iba la luz podías perder una tarde de trabajo. Creo recordar que en mi ordenador el autoguardado no venia activado por defecto.

    Adjunto a continuación mi archivo .emacs (hay varias cositas adicionales que he configurado, para poder compilar mis programas más rapidamente).

    Entre algunas cosas, es que he puesto teclas parecidas a las de Word para manejar EMACS.

    ;; -*- mode: emacs-lisp -*-
    (add-to-list ‘load-path “~/.emacs.d”)

    ;; Set paper size
    (if (or (string-match “XEmacs” emacs-version)
    (string-match “20.” emacs-version))
    (setq ps-paper-type ‘a4)
    (setq ps-paper-type ‘ps-a4))

    ;; Make ?, ? and such work
    (set-language-environment ’spanish)
    (set-terminal-coding-system ‘iso-latin-1)

    ;; Save space
    ;(menu-bar-mode nil)

    ;; Activate highlight in search and replace
    (setq search-highlight t)
    (setq query-replace-highlight t)

    ;; we want fontification in all modes
    (global-font-lock-mode t t)
    ;; maximum possible fontification
    (setq font-lock-maximum-decoration t)

    ;; Provide templates for new files
    (auto-insert-mode t)

    ;; Abbrevs
    ; Use C-xaig to correct common typos
    ; (setq abbrev-file-name “~/emacs/abbrev_defs”)
    (if (file-exists-p abbrev-file-name)
    (quietly-read-abbrev-file))

    ;; Activate template autocompletion
    (set-default ‘abbrev-mode t)

    ;; Bell instead of annoying beep
    (setq visible-bell t)

    ;;;turn off the bell http://www.emacswiki.org/cgi-bin/wiki?AlarmBell
    (setq ring-bell-function ‘ignore)

    ;; Do not add empty lines at the end of our file if we press down key
    (setq next-line-add-newlines nil)

    ;; When in text (or related mode) break the lines at 80 chars
    (setq fill-column 77)

    ;; Highlight matching parentheses. Very useful for coding.
    (show-paren-mode 1)

    ;; Automatically reload files after they’ve been modified
    ;; (typically in Visual C++)
    (global-auto-revert-mode 1)

    ;; Highlight regions for cutting or copying
    (setq transient-mark-mode t)

    ;; Enter changes lines and auto-indents the new line
    (add-hook ‘c-mode-hook
    ‘(lambda ()
    (define-key c-mode-map “\C-m” ‘newline-and-indent)))

    (add-hook ‘c++-mode-hook
    ‘(lambda ()
    (define-key c++-mode-map “\C-m” ‘newline-and-indent)))

    (add-hook ‘vhdl-mode-hook
    ‘(lambda ()
    (define-key vhdl-mode-map “\C-m” ‘newline-and-indent)))

    ;; Use abbreviations of previously entered phrases, press control enter to choose
    (define-key global-map [(control return)] ‘dabbrev-expand)

    ;; Helper for compilation. Close the compilation window if
    ;; there was no error at all.
    (defun compilation-exit-autoclose (status code msg)
    ;; If M-x compile exists with a 0
    (when (and (eq status ‘exit) (zerop code))
    ;; then bury the *compilation* buffer, so that C-x b doesn’t go there
    (bury-buffer)
    ;; and delete the *compilation* window
    (delete-window (get-buffer-window (get-buffer “*compilation*”))))
    ;; Always return the anticipated result of compilation-exit-message-function
    (cons msg code))
    ;; Specify my function (maybe I should have done a lambda function)
    (setq compilation-exit-message-function ‘compilation-exit-autoclose)

    ;; =============== Split window and start a shell in second window =============
    ;; follow-mode allows easier editing of long files
    ;;(follow-mode t)
    ;; want two windows at startup
    ;; (split-window-vertically)
    ;; move to other window
    ;; (other-window 1)
    ;; start a shell
    ;;(shell)
    ;; move back to first window
    ;; (other-window 1)

    ;; ===== Set the highlight current line minor mode =====

    ;; In every buffer, the line which contains the cursor will be fully
    ;; highlighted

    ;(global-hl-line-mode 1)

    ;; ===== Set standard indent to 2 rather that 4 =======

    (setq standard-indent 2)
    ; No sangra si estamos en literales
    (setq c-tab-always-indent “other”)
    ; Espacios en vez de tabuladores
    (setq-default indent-tabs-mode nil)

    ;; ========== Line by line scrolling ==================

    ;; This makes the buffer scroll by only a single line when the up or
    ;; down cursor keys push the cursor (tool-bar-mode) outside the
    ;; buffer. The standard emacs behaviour is to reposition the cursor in
    ;; the center of the screen, but this can make the scrolling confusing

    (setq scroll-step 1)

    ;; ========== Support Wheel Mouse Scrolling ==========

    (mouse-wheel-mode t)

    ;; ========== Prevent Emacs from making backup files ==========

    (setq make-backup-files nil)
    ;disable backup
    (setq backup-inhibited t)
    ;change prefix of auto-save files
    (setq auto-save-list-file-prefix “~/.emacs-saves/.saves-”)
    ;disable auto save
    (setq auto-save-default nil)

    ;; ========== Enable Line and Column Numbering ==========

    ;; Show line-number in the mode line
    (line-number-mode 1)

    ;; Show column-number in the mode line
    (column-number-mode 1)

    ;; ===== Function to delete a line =====

    ;; First define a variable which will store the previous column position
    (defvar previous-column nil “Save the column position”)

    ;; Define the nuke-line function. The line is killed, then the newline
    ;; character is deleted. The column which the cursor was positioned at is then
    ;; restored. Because the kill-line function is used, the contents deleted can
    ;; be later restored by usibackward-delete-char-untabifyng the yank commands.
    (defun nuke-line()
    “Kill an entire line, including the trailing newline character”
    (interactive)

    ;; Store the current column position, so it can later be restored for a more
    ;; natural feel to the deletion
    (setq previous-column (current-column))

    ;; Now move to the end of the current line
    (end-of-line)

    ;; Test the length of the line. If it is 0, there is no need for a
    ;; kill-line. All that happens in this case is that the new-line character
    ;; is deleted.
    (if (= (current-column) 0)
    (delete-char 1)

    ;; This is the ‘else’ clause. The current line being deleted is not zero
    ;; in length. First remove the line by moving to its start and then
    ;; killing, followed by deletion of the newline character, and then
    ;; finally restoration of the column position.
    (progn
    (beginning-of-line)
    (kill-line)
    (delete-char 1)
    (move-to-column previous-column))))

    ;;=============================================================================
    ;; * Set Variables & Rebind keys
    ;;=============================================================================
    ;; Commands to make my programming environment nice
    (global-set-key [f1] ‘help-command)
    (global-set-key [f2] ‘undo)
    (global-set-key [f3] ‘isearch-repeat-forward)
    (global-set-key [f4] ‘replace-string)
    (global-set-key [f5] ‘compile)
    (global-set-key [f6] ‘next-error)
    (global-set-key [f7] ‘other-window)
    (global-set-key [f8] ‘enlarge-window)
    (global-set-key [f9] ’speedbar-get-focus)
    (global-set-key [f11] ‘delete-other-windows)
    (global-set-key [f12] ‘nuke-line)

    (global-set-key [kp-prior] ’scroll-down)      ; [PgUp]
    (global-set-key [prior]    ’scroll-down)      ; [PgUp]
    (global-set-key [kp-next]  ’scroll-up)        ; [PgDn]
    (global-set-key [next]     ’scroll-up)        ; [PgDn]
    (global-set-key “\M-g” ‘goto-line)

    ;; home and end – needed for emacs
    (global-set-key [home] ‘beginning-of-line)
    (global-set-key [end] ‘end-of-line)

    (global-set-key “\C-cd” ‘delete-region)
    (global-set-key “\C-ca” ‘copy-region-as-kill)
    (global-set-key “\C-cv” ‘yank)
    (global-set-key “\C-cx” ‘kill-region)

    (global-set-key [delete] ‘delete-char)
    (global-set-key [(meta delete)] ‘(lambda () (interactive) (backward-or-forward-kill-word -1)))
    (global-set-key [(alt delete)] ‘(lambda () (interactive) (backward-or-forward-kill-word -1)))

    ;; to get the scroll wheel work

    (global-set-key [(button5)] ‘(lambda () (interactive) (scroll-up 3)))
    (global-set-key [(button4)] ‘(lambda () (interactive) (scroll-down 3)))
    (global-set-key [(shift button5)] ‘(lambda () (interactive) (scroll-up-command)))
    (global-set-key [(shift button4)] ‘(lambda () (interactive) (scroll-down-command)))
    (global-set-key [(control button5)] ‘(lambda () (interactive) (scroll-up-command)))
    (global-set-key [(control button4)] ‘(lambda () (interactive) (scroll-down-command)))

    (global-set-key [(mouse-5)] ‘(lambda () (interactive) (scroll-up 3)))
    (global-set-key [(mouse-4)] ‘(lambda () (interactive) (scroll-down 3)))
    (global-set-key [(shift mouse-5)] ‘(lambda () (interactive) (scroll-up)))
    (global-set-key [(shift mouse-4)] ‘(lambda () (interactive) (scroll-down)))
    (global-set-key [(control mouse-5)] ‘(lambda () (interactive) (scroll-up)))
    (global-set-key [(control mouse-4)] ‘(lambda () (interactive) (scroll-down)))

    ;==========Now we add color themes support===============
    (when window-system
    (require ‘color-theme)
    ;;(load-file “~/.emacs.d/color-theme-blue.el”)
    (color-theme-dark-blue2)
    )

    ;; ======================Modes for EMACs=========================

    ;; make text-mode default
    (setq default-major-mode ‘text-mode)

    (add-hook ‘c++-mode-hook ‘turn-on-auto-fill)
    (add-hook ‘c-mode-hook ‘turn-on-auto-fill)
    (add-hook ‘vhdl-mode ‘turn-on-auto-fill)

    ;;;
    ;;; VHDL mode
    ;;;

    (autoload ‘vhdl-mode “vhdl-mode” “VHDL Editing Mode” t);
    (setq auto-mode-alist (append ‘((“\\.vhd$”  . vhdl-mode)) auto-mode-alist))
    (setq auto-mode-alist (append ‘((“\\.vhdl$” . vhdl-mode)) auto-mode-alist))
    (add-hook ‘vhdl-mode-hook
    ‘(lambda ()
    ;;vhdl-electric enables templates
    (setq vhdl-electric-mode nil)
    (setq vhdl-stutter t)
    (setq vhdl-compiler ‘v-system)
    (setq vhdl-upper-case-keywords nil)
    (setq vhdl-basic-offset 4)
    (setq vhdl-comment-level 2)
    (setq comment-column 40)
    (setq end-comment-column 79)
    (setq vhdl-keywords-colorize t)
    (setq vhdl-signals-colorize nil)
    (setq vhdl-default-colors nil)
    (setq vhdl-print-two-column t)
    (setq vhdl-print-with-fonts t)
    (setq vhdl-print-with-colors nil)
    (setq font-lock-keywords-case-fold-search t)
    (setq vhdl-index-menu t)
    (setq vhdl-sourcefile-menu t)
    (setq vhdl-list-indent t)
    (setq vhdl-empty-lines t)
    (setq indent-tabs-mode nil)
    (setq vhdl-zero “‘0′”)
    (setq vhdl-one “‘1′”)
    (setq vhdl-date-scientific-format nil)
    ))

    ;;turn off vhdl templates
    (add-hook ‘vhdl-mode-hook (function (lambda () (abbrev-mode nil))))

    ;; ===============Adding C/C++ templates hooked into C/C++ mode=================

    ;; This is a way to hook tempo into cc-mode
    (defvar c-tempo-tags nil
    “Tempo tags for C mode”)
    (defvar c++-tempo-tags nil
    “Tempo tags for C++ mode”)

    ;;; C-Mode Templates and C++-Mode Templates (uses C-Mode Templates also)
    (require ‘tempo)
    (setq tempo-interactive t)

    (add-hook ‘c-mode-hook ‘(lambda ()
    (local-set-key [f11] ‘tempo-complete-tag)))
    (add-hook ‘c-mode-hook ‘(lambda ()
    (tempo-use-tag-list ‘c-tempo-tags)
    ))
    (add-hook ‘c++-mode-hook ‘(lambda ()
    (tempo-use-tag-list ‘c-tempo-tags)
    (tempo-use-tag-list ‘c++-tempo-tags)
    ))

    ;;; Preprocessor Templates (appended to c-tempo-tags)

    (tempo-define-template “c-include”
    ‘(“include <” r “.h>” > n
    )
    “include”
    “Insert a #include <> statement”
    ‘c-tempo-tags)

    (tempo-define-template “c-ifdef”
    ‘(“ifdef ” (p “ifdef-clause: ” clause) > n> p n
    “#else /* !(” (s clause) “) */” n> p n
    “#endif /* ” (s clause)” */” n>
    )
    “ifdef”
    “Insert a #ifdef #else #endif statement”
    ‘c-tempo-tags)

    (tempo-define-template “c-ifndef”
    ‘(“ifndef ” (p “ifndef-clause: ” clause) > n
    “#define ” (s clause) n> p n
    “#endif /* ” (s clause)” */” n>
    )
    “ifndef”
    “Insert a #ifndef #define #endif statement”
    ‘c-tempo-tags)

    ;;; C-Mode Templates

    (tempo-define-template “c-if”
    ‘(> “if (” (p “if-clause: ” clause) “)” n>
    “{” > n>
    > r n
    “}” > n>
    )
    “if”
    “Insert a C if statement”
    ‘c-tempo-tags)

    (tempo-define-template “c-else”
    ‘(> “else” n>
    “{” > n>
    > r n
    “}” > n>
    )
    “else”
    “Insert a C else statement”
    ‘c-tempo-tags)

    (tempo-define-template “c-if-else”
    ‘(> “if (” (p “if-clause: ” clause) “)”  n>
    “{” > n
    > r n
    “}” > n
    “else” > n
    “{” > n>
    > r n
    “}” > n>
    )
    “ifelse”
    “Insert a C if else statement”
    ‘c-tempo-tags)

    (tempo-define-template “c-while”
    ‘(> “while (” (p “while-clause: ” clause) “)” >  n>
    “{” > n
    > r n
    “}” > n>
    )
    “while”
    “Insert a C while statement”
    ‘c-tempo-tags)

    (tempo-define-template “c-for”
    ‘(> “for (” (p “for-clause: ” clause) “)” >  n>
    “{” > n
    > r n
    “}” > n>
    )
    “for”
    “Insert a C for statement”
    ‘c-tempo-tags)

    (tempo-define-template “c-for-i”
    ‘(> “for (” (p “variable: ” var) ” = 0; ” (s var)
    ” < “(p “upper bound: ” ub)”; ” (s var) “++)” >  n>
    “{” > n
    > r n
    “}” > n>
    )
    “fori”
    “Insert a C for loop: for(x = 0; x < ..; x++)”
    ‘c-tempo-tags)

    (tempo-define-template “c-main”
    ‘(> “int main(int argc, char *argv[])” >  n>
    “{” > n>
    > r n
    > “return 0 ;” n>
    > “}” > n>
    )
    “main”
    “Insert a C main statement”
    ‘c-tempo-tags)

    (tempo-define-template “c-if-malloc”
    ‘(> (p “variable: ” var) ” = (“
    (p “type: ” type) ” *) malloc (sizeof(” (s type)
    “) * ” (p “nitems: ” nitems) “) ;” n>
    > “if (” (s var) ” == NULL)” n>
    > “error_exit (\”" (buffer-name) “: ” r “: Failed to malloc() ” (s var) ” \”) ;” n>
    )
    “ifmalloc”
    “Insert a C if (malloc…) statement”
    ‘c-tempo-tags)

    (tempo-define-template “c-if-calloc”
    ‘(> (p “variable: ” var) ” = (“
    (p “type: ” type) ” *) calloc (sizeof(” (s type)
    “), ” (p “nitems: ” nitems) “) ;” n>
    > “if (” (s var) ” == NULL)” n>
    > “error_exit (\”" (buffer-name) “: ” r “: Failed to calloc() ” (s var) ” \”) ;” n>
    )
    “ifcalloc”
    “Insert a C if (calloc…) statement”
    ‘c-tempo-tags)

    (tempo-define-template “c-switch”
    ‘(> “switch (” (p “switch-condition: ” clause) “)” n>
    “{” >  n>
    “case ” (p “first value: “) “:” > n> p n
    “break;” > n> p n
    “default:” > n> p n
    “break;” > n
    “}” > n>
    )
    “switch”
    “Insert a C switch statement”
    ‘c-tempo-tags)

    (tempo-define-template “c-case”
    ‘(n “case ” (p “value: “) “:” > n> p n
    “break;” > n> p
    )
    “case”
    “Insert a C case statement”
    ‘c-tempo-tags)

    ;;;C++-Mode Templates

    (tempo-define-template “c++-class”
    ‘(“class ” (p “classname: ” class) p n “{” n “public:” n>

    (s class) “();”
    (indent-for-comment) “the default constructor” n>

    (s class)
    “(const ” (s class) “&rhs);”
    (indent-for-comment) “the copy constructor” n>

    (s class)
    “& operator=(const ” (s class) “&rhs);”
    (indent-for-comment) “the assignment operator” n>

    n> “// the default address-of operators” n>
    “// “(s class)
    “* operator&()             { return this; };” n>
    “// const “(s class)
    “* operator&() const { return this; };” n

    n > “~” (s class) “();”
    (indent-for-comment) “the destructor” n n>
    p n
    “protected:” n> p n
    “private:” n> p n
    “};\t// end of class ” (s class) n>
    )
    “class”
    “Insert a class skeleton”
    ‘c++-tempo-tags)

    ;; ================= Templates when creating new files ========================
    ;; auto-insert for .pl and .cgi
    (load-library “autoinsert”)

    (define-auto-insert “\\.pl$” ‘perl-auto-insert)
    (defun perl-auto-insert ()
    (progn
    (insert “#! /usr/bin/perl\nuse warnings;\nuse strict;\n”)
    (insert “use Carp;\n\n”)
    (insert “use FindBin ();\n”)
    (insert “use Data::Dumper;\n$Data::Dumper::Indent   = 1;\n”)
    (insert “$Data::Dumper::Sortkeys = 1;\n\n”)
    (insert “use lib $FindBin::Bin;\n\n”)
    )
    )

    (define-auto-insert “\\.cgi$” ‘cgi-auto-insert)
    (defun cgi-auto-insert ()
    (progn
    (insert “#! /usr/bin/perl\nuse warnings;\nuse strict;\n\n”)
    (insert “use CGI ();\n”)
    (insert “use CGI::Carp qw(fatalsToBrowser);\n”)
    (insert “use HTML::Template::Compiled;\n”)
    (insert “use FindBin ();\n”)
    (insert “use lib $FindBin::Bin;\n\n”)
    (insert “my $filename = ‘template.tmpl’;\n”)
    (insert “my $cssUrl   = ’style.css’;\n\n”);
    (insert “my $cgi    = CGI->new();\nmy %params = $cgi->Vars();\n\n”)
    (insert “print $cgi->header( -type => ‘text/html’, -expires => ‘+3s’ );\n”)
    (insert “my $constructorParams = { filename => $filename,\n”)
    (insert “                          path     => \”$FindBin::Bin/templates\”,\n”)
    (insert “                          # die_on_bad_params => 0,\n”)
    (insert “                         };\n\n”)
    (insert “my $template = &Template\n”)
    (insert “    ( $cgi, $constructorParams,\n”)
    (insert “      {\n       SELF_URL => $ENV{SCRIPT_NAME},\n”)
    (insert “       CSS_URL => $cssUrl,\n   } );\n\n”)
    (insert “print $template->output();\n\n”)
    (insert “# print $cgi->start_html(‘title’);\n\n\n”)
    (insert “# print $cgi->end_html();\n\n”)
    (insert “# ————————————————————\n”)
    (insert “sub Template {\n”)
    (insert “    my( $cgi, $constructorParams, $htmlParams ) = @_;\n\n”)
    (insert “    my $template = HTML::Template::Compiled->new( %$constructorParams );\n”)
    (insert “    $template->param( %$htmlParams ) if ref $htmlParams;\n\n”)
    (insert “    return $template;\n”)
    (insert “} # Template\n”)
    (insert “# ————————————————————\n”)
    )
    )

    (add-hook ‘find-file-hooks ‘auto-insert)
    (desktop-load-default)
    (desktop-read)

    ;;===================== Functions defined by user =============================
    ;;Convert DOS cr-lf to UNIX newline
    (defun dos2unix () (interactive) (goto-char (point-min))
    (while (search-forward “\r” nil t) (replace-match “”)))
    ;;Convert UNIX newline to DOS cr-lf
    (defun unix2dos () (interactive) (goto-char (point-min))
    (while (search-forward “\n” nil t) (replace-match “\r\n”)))

    ImageMagick: Capturador de pantallas y conversor de imágenes ligero para Fluxbuntu

    Archivado en: Linux Ubuntu Administracion — Abelardo Jara @ 12:20 pm

    Fuente: http://www.forat.info/2007/07/16/como-capturar-pantalla-en-linux-con-imagemagick/

    Sobre una Debian recién instalada he necesitado un capturador de pantalla para mi nuevo Linux así que he estado un rato buscando algún tipo de capturador de pantalla que fuera lijero y sencillo a la hora de utilizar.

    Truco : En Linux Ubuntu se puede capturar la pantalla completa simplemente pulsando la tecla ImpPnt y listo. ( Ubuntu es una de las distribuciones que trae un capturador de serie )

    Si funcionáis sobre un Linux que no trae un capturador de pantalla de serie aquí os dejo la solución que a mi me ha parecido la mejor después de probar varios capturadores.

    Imagemagick
    nos ofrece una de sus utilidades ( Import ) la que nos permite hacer capturas de pantalla a base de comandos. ( A mi me gusta )

    Podemos hacer una captura de pantalla de el siguiente modo ….

    import h /home/forat/captura.jpg

    Se entiende que (/home/forat tienes que substituirlo por tu home)

    Ejecutando este comando aparecerá automáticamente un puntero en el centro de la pantalla y podrás apuntar hacia la ventana que quieras capturar y en el caso que quisieras capturar la pantalla completa solo tienes que pinchar en el fondo de escritorio.

    Es fácil, rápido y lijero.

    ¿ No tienes instalado Imagemagick ?

    En Debian… (o mejor aun Ubuntu)

    Logeate como root con el comando su.

    $ aptitude install imagemagick

    y listo, ya lo tienes instalado.

    Ahora ya tengo un capturador guapo para seguir haciendo manuales. ;)

    ¿ Y tu tienes el tuyo ?

    AJUSTES FINALES (TOMADO DE BULMA.NET)

    Utilizando la herramienta convert de ImageMagick (apt-get install ImageMagick) podemos pasar el gráfico por ejemplo .ps a cualquier otro formato. En mi caso yo he utilizado:

    $ convert bulmaring.ps bulmaring.jpg
    Para generar el gráfico grande completo
    $ convert -geometry 240x240 bulmaring.ps bulmaring.mini.jpg
    Para generar la miniatura.

    Compilación cruzada: usando Ubuntu para compilar programas .exe para Windows

    Archivado en: Programacion C++ en Linux, Programacion C++ en Windows — Abelardo Jara @ 10:39 am

    Créditos

    • Autor: Hugo Ruscitti
    • Fecha: 31 de Agosto del 2006

    Introducción

    Este trabajo presenta una serie de consejos e indicaciones sobre como generar programas multimedia para Windows desde un sistema operativo como GNU/Linux.

    Dado que la temática que trataremos es de cierta complejidad, he decidido no crear una referencia completa sobre las herramientas que utilizaremos, en su lugar intentaré abordar el asunto de manera práctica, creando ejemplos de aplicaciones funcionales. De esta forma podrá conocer los componentes mas elementales del proceso y ver sus resultados inmediatos.

    El por qué de la cuestión

    GNU/Linux cuenta con una extensa galería de recursos para quienes disfrutamos de la programación. Entre aplicaciones y bibliotecas, GNU/Linux ofrece un entorno confortable y flexible, incluso, para desarrolladores de aplicaciones multimedia.

    Una herramienta para programadores muy interesante es Mingw (“Minimalistic GNU for Windows”), que nació con la intensión de adaptar varias herramientas de desarrollo del sistema GNU a entornos Windows.

    Si bien encontrará varios usos para Mingw, aquí lo utilizaremos para lograr que nuestro sistema GNU pueda generar archivos ejecutables para sistemas Windows. En general, a este proceso de “exportar” aplicaciones a otros sistemas o arquitecturas se lo denomina “cross-building”, “cross-compile”, o como decidimos llamarlo en este artículo: “compilación cruzada”.

    Este recurso de soporte a otros sistemas nos permite ampliar nuestras posibilidades de crear programas Multiplataforma, sin cambiar de sistema y utilizando siempre Software Libre.

    Requisitos

    Para seguir este tutorial le recomiendo contar con algunas herramientas que veremos mas adelante: gcc, mingw y wine. Muchas distribuciones de GNU/Linux cuentan con sistemas administradores de paquetes que le permiten instalar y desinstalar programas con facilidad, por ese motivo no debería tener problemas en comenzar a probar los ejemplos de este artículo.

    El proceso de instalación en mi sistema Debian GNU/Linux llevó unos pocos segundos. Si utiliza este mismo sistema, u otro basado en él como Ubuntu o Knoppix, ejecute como usuario administrador (root) 1:

    apt-get install mingw32

    El sistema de paquetes `apt` le informará que necesita instalar, como mínimo, otros 2 paquetes llamados `mingw32-runtime` y `mingw32-binutils`. Indique y continúe.

    Si todo sale bien obtendrá un mensaje como:

    Configurando mingw32-binutils (2.15.94-20050118.1-1) …
    Configurando mingw32-runtime (3.7-1) …
    Configurando mingw32 (3.4.2.20040916.1-2) …

    En cambio, si se le presenta algún tipo de problema puede recurrir a las versiones en código fuente disponibles en el sitio oficial de Mingw, o bien, obtener un entorno de compilación completo en el sitio de la biblioteca SDL.

    Nuestro programa ejecutable para GNU/Linux

    Seguramente alguna vez ha escrito el clásico programa que imprime en pantalla la leyenda “hola mundo !”. Este sencillo programa nos resultará de mucha utilidad como primer ejemplo.

    Código fuente: hola_mundo.c
    #include <stdio.h>

    int main (void)
    {
    printf (“Hola mundo!\n);
    printf (\n);
    printf (“pulse ENTER para continuar\n);

    getchar ();

    return 0;
    }

    Para crear un programa ejecutable compatible con GNU/Linux podemos invocar al compilador gcc de la siguiente manera:

    gcc hola_mundo.c

    Mediante dicho comando, se generará un archivo ejecutable llamado `a.out`. Ahora estamos en condiciones de ejecutar el programa escribiendo:

    ./a.out

    Tenga en cuenta que también podría alterar el nombre del programa generado (a.out) especificando el comando `-o` como se muestra a continuación:

    gcc hola_mundo.c -o hola

    de forma que el archivo generado reciba el nombre `hola` en lugar de `a.out`.

    Compilando para sistemas Windows con MinGW

    El programa anterior funcionaría solamente en GNU/Linux. Si nuestra intensión es generar una versión funcional para sistemas Windows podemos recurrir a MinGW. La forma de utilizar esta herramienta en GNU es muy similar al resto de los programas como gcc y make, en Mingw encontrará una serie de programas que cumplen las tareas de `procesar`, `compilar` y `enlazar` aplicaciones pero generando archivos ejecutables para sistemas Windows.

    En nuestro caso, el programa que reemplaza la tarea de generar el programa ejecutable será i586-mingw32-gcc, por lo tanto si ejecutamos:

    i586-mingw32msvc-gcc hola_mundo.c -o hola.exe

    Obtendremos el archivo ejecutable hola.exe para sistemas Windows. Note que he utilizado la opción `-o` como en el ejemplo de comando anterior para definir el nombre del programa.

    gcc no es único programa incluido en Mingw, existen muchos otros bajo la misma nomenclatura, donde se utiliza el prefijo i586-mingw32msvc. Por ejemplo, para generar programas en lenguaje C++ puede utilizar el programa i586-mingw32msvc-g++.

    Analizando el resultado de la compilación

    El programa que generamos con MinGW ya está en condiciones de funcionar en un sistema operativo como Windows, solo debería trasladar el programa ejecutable a ese sistema junto con su biblioteca mingwm10.dll. Aunque también existe la posibilidad de analizar el funcionamiento del programa desde nuestro propio sistema GNU/Linux, simulando un entorno de funcionamiento Windows.

    Existe un programa muy popular en GNU que nos permite interpretar aplicaciones para Windows, este programa se llama Wine, y se incluye en numerosos repertorios de programas. En el caso de las distribuciones basadas en Debian GNU/Linux es probable que necesite instalarlo mediante el sistema `apt`. Para ello ejecute como administrador del sistema (root) el siguiente comando:

    apt-get install wine winesetuptk

    El segundo programa (winesetuptk) se utiliza para definir los parámetros de configuración de wine de manera sencilla.

    Cuando termine de instalar el programa podrá correr aplicaciones diseñadas para sistemas Windows desde su sistema GNU invocando a los comandos:

    • wine: para cargar y ejecutar programas gráficos.
    • wineconsole: para cargar y ejecutar programas de consola.

    Para verificar que nuestro programa `hola.exe` funciona mediante wine podemos ejecutar:

    wineconsole hola.exe

    Note que los programas para Windows suelen clasificarse en dos grupos: los programas de `consola` y las aplicaciones `gráficas`. Aquí comencé con un programa sencillo para mostrar que puede compilarlo tanto para GNU como Windows, este primer ejemplo es un programa de `consola`.

    Analicemos otro ejemplo; en la documentación del programa MinGW existe un programa que utiliza rutinas propias de los sistemas Windows. Lo utilizaremos para mostrar como funciona Wine con un programa gráfico.

    Código fuente: hello.c
    #include <windows.h>

    int main(int argc, char *argv[])
    {
    MessageBox(NULL, “Hello, world!”, “Hello, world!”, MB_OK);
    return 0;
    }

    Si genera un archivo ejecutable en base a este programa gráfico mediante Mingw32, luego podrá invocar al programa wine como se muestra a continuación:

    wine hello.exe

    Obteniendo en pantalla:

    Si bien este no es un programa de `consola` debería tener en cuenta que en los sistemas Windows aparecerá, de todas maneras, una pantalla de `consola`. Para evitar que esto ocurra debe indicarle a MinGW que el programa será completamente `gráfico` mediante la opción `-mwindows`:

    -mwindows

    Utilizando bibliotecas

    MinGW también puede establecer vínculos entre nuestros programas y diversas bibliotecas dinámicas, simplemente debe obtener las bibliotecas de desarrollo que necesite, colocarlas en el directorio adecuado e indicarle a MinGW que las utilizará.

    Para mostrar esta posibilidad tomaremos como ejemplo un programa multimedia que utiliza la biblioteca SDL llamado Mouse. Primero instalaremos el entorno de desarrollo, luego generamos el programa y por último analizaremos su funcionamiento mediante `wine`.

    Instalando la biblioteca SDL

    En el sitio web www.libsdl.org encontrará una versión de la biblioteca indicada como `mingw32`, al momento de escribir este artículo la versión mas reciente es 1.2.11 y el archivo para descargar recibe el nombre de sdl-devel-1.2.11-mingw32.tar.gz. De todas formas es recomendable que visite la web de SDL y busque si existe una versión mas reciente.

    Para instalar esta biblioteca he tenido que ejecutar:

    tar xzvf sdl-devel-1.2.10-mingw32.tar.gz
    cd SDL-1.2.10
    su
    mkdir /usr/local/cross-tools/
    mkdir /usr/local/cross-tools/i386-mingw32msvc/
    make cross
    make install
    exit






    Si por algún motivo quiere alterar el directorio de instalación de la biblioteca deberá editar el archivo Makefile incluido en el directorio SDL-1.2.10 y reemplazar la linea:

    CROSS_PATH := /usr/local/cross-tools/i386-mingw32msvc/

    Compilar un programa que utiliza SDL para GNU

    Antes de continuar recordemos como utilizar la utilidad `sdl-config` para crear aplicaciones nativas en GNU/Linux:

    El proceso de compilación de un programa que utiliza bibliotecas requiere de varias especificaciones (que bibliotecas enlazar, donde residen las cabeceras .h, etc). En GNU/Linux estas especificaciones se suelen indicar mediante programas (o scripts) que obtienen todos los parámetros necesarios para realizar la compilación, en el caso de las bibliotecas SDL existe el comando sdl-config, que nos facilita la tarea de realizar especificaciones. Por ejemplo:

    sdl-config –cflags

    nos informa todos los parámetros necesarios para iniciar el proceso de compilación (generar los ficheros objeto). Además:

    sdl-config –libs

    nos indica las opciones que debemos especificar para enlazar el programa a las bibliotecas. Así, nuestro programa se puede compilar en GNU/Linux mediante el comando:

    gcc mouse `sdl-config –cflags –libs`

    Las comillas invertidas (“) le permiten a gcc obtener el retorno de sdl-config y utilizarlo como argumento. En este caso sería equivalente invocar a sdl-config –cflags –libs, copiar su resultado en pantalla y colocarlo como argumento al generar el programa con gcc.

    Una vez invocada la compilación, nuestro programa de ejemplo se podrá ejecutar mediante el comando:

    ./mouse

    Nuestro programa funcionando en GNU/Linux

    Compilar un programa con SDL para Windows desde GNU

    El proceso de compilación mediante MinGW es muy similar, solo que debemos reemplazar la llamada a sdl-config por un script situado en:

    /usr/local/cross-tools/i386-mingw32msvc/bin/sdl-config

    Este script funciona de manera similar a la herramienta sdl-config nativa de GNU/Linux. Por ejemplo si queremos obtener todas las opciones de compilación y enlace para nuestros programas con gcc invocamos a:

    /usr/local/cross-tools/i386-mingw32msvc/bin/sdl-config –cflags –libs

    Para probar nuestro ejemplo completo, ejecutemos las siguientes sentencias en un intérprete de órdenes:

    alias gcc_cross=i586-mingw32msvc-gcc
    alias sdl-config_cross=/usr/local/cross-tools/i386-mingw32msvc/bin/sdl-config

    gcc_cross mouse.c -o mouse.exe `sdl-config_cross –cflags –libs`


    Note que las llamadas a `alias` nos facilitan escribir los comandos completos. Para analizar otra alternativa de compilación puede descargar el ejemplo completo e invocar al programa Make.

    En caso de errores …

    Si el proceso de compilación falla indicando que no se encuentran las cabeceras SDL.h, posiblemente se deba a un error del script `sdl-config`. Note que las bibliotecas SDL se suelen instalar dentro de un directorio llamado “include” o “include/SDL”, el script `sdl-config` debe indicar con precisión el lugar exacto en donde residen estos archivos.

    Lamentablemente he notado que la versión actual de sdl-config no indica correctamente la ruta de estos archivos .h en mi sistema. Si en su equipo ocurre lo mismo intente editar el archivo /usr/local/cross-tools/i386-mingw32msvc/bin/sdl-config como administrador de sistema (root) y cambie la linea:

    echo -I${prefix}/include/SDL -D_GNU_SOURCE=1 -Dmain=SDL_main

    por:

    echo -I${prefix}/include -D_GNU_SOURCE=1 -Dmain=SDL_main

    Si el problema persiste no dude en consultarlo en nuestro foro de mensajes.

    Otro problema muy frecuente en la utilización de esta biblioteca se encuentra en la inclusión del archivo “SDL.h” al código de nuestro programa. La forma mas adecuada de incluir este archivo es mediante:

    #include “SDL.h”

    Es cierto que existen muchas formas de indicar la ruta a un archivo como este (“SDL/SDL.h”, “sdl.H” etc.), aunque sería deseable que adopte solo aquella forma que le brinda mayores posibilidades de generar el programa en diferentes sistemas sin cambiar una sola linea del programa.

    Verificando el funcionamiento del programa:

    A diferencia de nuestro primer ejemplo, este programa se encuentra vinculado a la biblioteca dinámica SDL y por ese motivo necesitará del archivo SDL.dll para que todo funcione correctamente. Tanto en sistemas Windows como mediante Wine podrá resolver esta dependencia situando el archivo SDL.dll dentro del directorio donde reside el archivo ejecutable:

    cp /usr/local/cross-tools/i386-mingw32msvc/bin/SDL.dll ./

    Ahora observemos como funciona nuestro programa con Wine:

    wine mouse.exe

    Programa mouse sobre Wine en Debian GNU/Linux

    si ejecutamos este mismo programa en un sistema Windows notaremos que su funcionalidad es idéntica:


    Funcionando sobre Windows XP con el tema de escritorio clásico

    Si utiliza programas SDL con frecuencia, tal vez le resulte mas útil situar el archivo SDL.dll dentro de la carpeta “Windows\system” (en el sistema Windows) o en “$HOME/.wine/fake_windows/Windows/System” (si utiliza Wine). Esto evitará que necesite copiar el archivo .dll en cada proyecto que realice.

    Bibliotecas Adicionales

    SDL cuenta con una serie de bibliotecas adicionales para brindar soporte a otras tareas como utilizar ficheros SVG (formato de imágenes vectoriales), MP3 (música), GUI (interfases visuales), etc. Añadir estas bibliotecas a su proyecto es muy sencillo, solo debe obtener las bibliotecas de desarrollo que necesite para sistemas Windows (o aquellas indicadas para mingw32) y ubicar los archivos .h dentro del directorio:

    /usr/local/cross-tools/i386-mingw32msvc/include/

    Luego necesitará copiar los archivos de biblioteca (.a/.la) en:

    /usr/local/cross-tools/i386-mingw32msvc/lib/

    Por último, no olvide que los usuarios de sus aplicaciones necesitarán tener los archivos .dll en su sistema a la hora de ejecutar los programas.

    Conclusión

    GNU/Linux incluye una extensa colección de programas interesantes para todo tipo de usuarios. A mi entender, Mingw es una herramienta indispensable para aquellos programadores que estudiamos el desarrollo de programas libres y Multiplataforma. Aquí solo hemos visto el principio de la historia …

    Licencia

    Se permite la copia, modificación y distribución de este artículo sólo bajo los términos de la Licencia Creative Commons. Los programas de ejemplo se distribuyen bajo la licencia GPL.

    Notas

    1 – En distribuciones como Ubuntu puede ejecutar `sudo apt-get …` como usuario normal.

    Usando Fluxbuntu para herramientas Xilinx ISE 9.2 desde línea de comandos

    Archivado en: FPGAs, VHDL y Computacion Reconfigurable — Abelardo Jara @ 10:10 am

    Bueno, en esta ocasion voy a hacer un recuento de mi instalación de Fluxbuntu en una Pentium 4 de 1GB de RAM, no es que sea una máquina tan antigua, pero es la misma configuración que he usado en una viejita Armada V300, y en ambas va a la maravilla. De paso de instalar el ISE y el EDK instalé otros programas para desarollo en C++ y Java pero que también se requieren para usar las herramientas de Xilinx.

    Primero instalé Fluxbuntu en ambas máquinas. A continuación listaré un registro de mis principales pasos:
    I. AÑADIENDO REPOSITORIOS DE MULTIMEDIA PARA APT-GET

    Luego de loguearme edité el archivo /etc/apt/sources.list
    y añadí las siguientes líneas:

    # Medibuntu – Ubuntu 7.10 “gutsy gibbon”
    deb http://packages.medibuntu.org/ gutsy free non-free
    deb-src http://packages.medibuntu.org/ gutsy free non-free

    Luego de esto lo guardo y agrego su clave:

    wget -q http://packages.medibuntu.org/medibuntu-key.gpg -O- | sudo apt-key add - && sudo apt-get update

    Luego realizo un:

    apt-get update

    y un apt-get upgrade

    NOTA: Algo importante de Fluxbuntu es que no monta automáticamente las unidades de CD/DVD, esto es debido a que he usado la versión RC (release candidate), para corregir esto, debes loguearte con tu usuario y crear una carpeta .ivman

    >>mkdir .ivman

    El otro bug es que el menú de Fluxbox no se actualiza automáticamente después de instalar programas, así que debemos hacerlo con un comando:

    >>sudo update-menus

    Listo, esto son los 2 bugs más importantes.

    II. INSTALANDO PAQUETES BÁSICOS

    a. Instalando herramientas para Internet y Correo

    sudo apt-get install firefox language-pack-es mozilla-firefox-locale-es-es flashplugin-nonfree evolution acroread acroread-plugins evince

    b. Instalando editor de textos básico, terminal y EMACS

    sudo apt-get install leafpad gedit gnome-terminal emacs

    c. Instalar servidor de impresión CUPS (incluyendo impresora virtual CUPS PDF)

    sudo apt-get install cupsys cupsys-bsd cupsys-common cupsys-client cupsys-driver-gutenprint gnome-cups-manager cups-pdf

    d. Instalar GNU Classpat, Java 6 y Subversion

    sudo apt-get install build-essential mingw32 mingw32-binutils mingw32-runtime sun-java6-jdk subversion

    e. Instalar herramientas para desarrollar un compilador, JLex y Java CUP

    sudo apt-get install jlex jflex cup

    f. Instalar librerías y cabeceras para desarrollar programas con gtkmm y libglademm

    sudo apt-get install libgtkmm-2.4-1c2a libgtkmm-2.4-dev libglademm-2.4-1c2a libglademm-2.4-dev

    g. Instalar herramientas complementarias y codecs

    sudo apt-get install w32codecs ffmpeg skype acroread openssh-server imagemagick gqview

    h. Instalar LaTeX y editor de TeXMaker

    sudo apt-get install tetex-base tetex-extra tetex-bin tex-common psutils latex-ucs ispell ispanish aspell aspell-es texmaker

    i. Requerimientos para herramientas de Xilinx

    sudo apt-get install libmotif3 portmap libusb-dev fxload

    Bueno hasta aquí fue lo básico.

    III. DEFINIENDO MI CLASSPATH PARA JAVA Y PARA USAR JLEX Y JAVA CUP

    CLASSPATH=.:/home/abelardo/Java
    export CLASSPATH=$CLASSPATH:/usr/share/java/cup.jar:/usr/share/java/JLex.jar:/usr/share/java/JFlex.jar

    IV. INSTALANDO EL XILINX ISE 9.2 Y EL XILINX EDK 9.2

    El siguiente paso es simple, iniciamos sesión en Fluxbuntu y ponemos el DVD del Xilinx ISE 9.2. Montamos el DVD y ejecutamos en el directorio padre de este el archivo “setup” (sin .exe) desde consola. Ambos programas deben ser instalados como usuario root.

    Los pasos siguientes son iguales a instalar este programa en Windows ya que disponemos de un instalador gráfico.

    El Xilinx EDK 9.2 se instala de la misma manera. En mi caso yo instalé ambos en /opt

    Luego modifique mi archivo de .bashrc para poder acceder a las herramientas de síntesis e implementación desde línea de comandos.

    export LANGUAGE=en_GB:en

    export XILINX=/opt/Xilinx92i
    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/Xilinx92i/bin/lin
    export PATH=$PATH:/opt/Xilinx92i/bin/lin:/opt/modeltech/bin:/opt/matlab7/bin:/opt/netbeans-6.0/bin

    En mi caso $PATH tiene otros directorios añadidos dado que también instalaré allí Modelsim SE 6.2 para Linux. Matlab 7 R14 para Linux y Netbeans 6 (con el CD que me llego gratis :)

    Ahora tenemos el problema de que no podemos usar el cable USB para programar dispositivos de Xilinx, para eso seguimos las instrucciones de

    http://rmdir.de/~michael/xilinx/

    Alli descargamos el código fuente para crearnos una librería libusb.so que nos permitirá emular el driver windrv6 que usa el Xilinx Impact para programar usando JTAG y USB las tarjetas de Xilinx. Siguiendo las instrucciones me creé un archivo libusb.so y lo puse en mi directorio /home/abelardo/flexlm/libusb.so

    Añadi la siguiente línea a mi .bashrc

    export LD_PRELOAD=/home/abelardo/flexlm/libusb.so

    Ahora el problema es que las tarjetas de Xilinx necesitan que se les descargue un firmware mediante USB antes de Impact las pueda reconocer. Entonces copiamos el archivo:

    [XILINX-PATH]/bin/lin/install_script/install_drivers/linux_drivers/pcusb/xusbdfwu.hex

    a /etc/hotplug/usb/xusbdfwu.fw/xusbdfwu.hex

    Luego cree un archivo en /etc/udev/rules.d/:

    llamado: 52-xilinxusb.rules (puede ser cualquier nombre) y le puse el siguiente contenido:

    ENV{UDEVD_EVENT}=="1", ACTION=="add", BUS=="usb", SYSFS{idVendor}=="03fd", SYSFS{idProduct}=="0007", MODE="0666", RUN+="/sbin/fxload -v -t fx2  -I /etc/hotplug/usb/xusbdfwu.fw/xusbdfwu.hex -D $env{DEVNAME}" ENV{UDEVD_EVENT}=="1", ACTION=="add", BUS=="usb", SYSFS{idVendor}=="03fd", SYSFS{idProduct}=="0009", MODE="0666", RUN+="/sbin/fxload -v -t fx2  -I /etc/hotplug/usb/xusbdfwu.fw/xusbdfwu.hex -D $env{DEVNAME}" ENV{UDEVD_EVENT}=="1", ACTION=="add", BUS=="usb", SYSFS{idVendor}=="03fd", SYSFS{idProduct}=="000b", MODE="0666", RUN+="/sbin/fxload -v -t fx2  -I /etc/hotplug/usb/xusbdfwu.fw/xusbdfwu.hex -D $env{DEVNAME}" ENV{UDEVD_EVENT}=="1", ACTION=="add", BUS=="usb", SYSFS{idVendor}=="03fd", SYSFS{idProduct}=="000d", MODE="0666", RUN+="/sbin/fxload -v -t fx2  -I /etc/hotplug/usb/xusbdfwu.fw/xusbdfwu.hex -D $env{DEVNAME}"
    
    ENV{UDEVD_EVENT}=="1", ACTION=="add", BUS=="usb", SYSFS{idVendor}=="03fd", SYSFS{idProduct}=="000f", MODE="0666", RUN+="/sbin/fxload -v -t fx2  -I /etc/hotplug/usb/xusbdfwu.fw/xusbdfwu.hex -D $env{DEVNAME}"
    
    ACTION=="add",BUS=="usb",SYSFS{idVendor}=="03fd",SYSFS{idProduct}=="0008",MODE="666"

    Las primeras 5 líneas se encargan de cargar el firmware a las tarjetas de Xilinx, Lo malo es que al descargar el firmware, las tarjetas de Xilinx cambian su SYSFS o ID, de modo que solo el usuario root podrá acceder a su programación usando Impact. Por ello añadi la ultima línea donde uso el SYSFS o ID de la tarjeta XUPV2PRO después de que se le descarga el firmware que es 0008 y le doy permisos 0666 para que cualquier usuario pueda escribir en ella. Quizás no es la opción mas segura, debería crear un grupo llamado “Xilinx” y que sólo usuarios de este grupo pudieran escribir en el dispositivo USB con ID 0008, pero aparte de esto, este método que les menciono trabaja bien.

    Falta solamente reiniciar udev:

    >>sudo /etc/init.d/udev restart

    Listo!

    Para probar que todo está bien, conecten su tarjeta XUPV2PRO y despues de prenderla hagan un:

    Haciendo lsusb para ver la tarjeta XUPV2PROPara ver que si podemos escribir en ella:

    >> ls -l /dev/bus/usb/002

    crw-rw-r– 1 root root 189, 128 Mar 16 03:47 001
    crw-rw-r– 1 root root 189, 129 Mar 16 08:47 002
    crw-rw-r– 1 root root 189, 130 Mar 16 08:47 003
    crw-rw-rw- 1 root root 189, 148 Mar 16 09:55 021

    Observemos que el puerto 021 esta con permisos “w” o “write” para tanto usuario, grupo y los demás, que es lo que requerimos que todos puedan escribir en la tarjeta. El puerto usb21 será usado por Impact para programar la tarjeta.

    Ahora cualquier usuario puede invocar Impact y descargar su bitstream. En este momento si alguien llama al Impact, este podrá detectar y tener acceso de configuración sobre la tarjeta (en mi caso la XUPV2PRO):

    Llamando a la herramienta Impact

    Hay un problema adicional con las herramientas de Xilinx y se da si queremos llamar al fpga_editor o al floorplanner desde línea de comandos:

    >>fpga_editor

    Wind/U X-toolkit Error: wuDisplay: Can’t open display

    Para corregir esto debemos antes de llamarlos, cambiar nuestra variable DISPLAY

    export DISPLAY=:0.

    Esta práctica no es recomendable dado que las conexiones remotas SSH a nuestra máquina ya no podrán hacer X forwarding al host remoto, pero parece ser un error del Wind/X toolkit que usa Xilinx que usa expresiones no estándar para el DISPLAY.

    Otro error que es bien molesto es al actualizar proyectos de EDK de versiones anteriores dice que libdb-4.1.so no fue encontrada, en este caso debemos hacer lo siguiente:

    sudo ln -s /usr/lib/libdb-4.x.so /usr/lib/libdb-4.1.so

    donde “x” es un numero que puede cambiar, debes mirar en /usr/lib para saber que libdb tienes.

    V. CREANDO UN MAKEFILE Y SCRIPTS PARA REALIZAR EL FLUJO DE DISEÑO DE XILINX (INCLUIDA CONFIGURACIÓN DESDE LÍNEA DE COMANDOS)

    Finalmente ya que nuestro .bashrc esta configurado para usar las herramientas de sintesis desde línea de comandos, podemos hacer el flujo de diseño sin GUI en línea de comandos, lo que será mucho más rápido.

    Crearemos primero un directorio para nuestro proyecto, dentro de este directorio habrán 1 archivo Makefile y dos directorios: hdl y bitstreams (es arbritraria esta elección que hice)

    En el directorio hdl debe ir todos nuestros archivos de código fuente VHDL, junto a un archivo script para el XST, que lo llame top.script y un archivo de lista de dependecias de nuestro código VHDL llamado top.prj

    En el directorio bitstreams debe ir la bitstream que se enviará al FPGA (se genera después de hacer el “make” del proyecto), y un script de bash runimpact.sh para llamar a Impact y un archivo prog.cmd donde coloqué las opciones para llamar a Impact desde línea de comandos (modo batch).

    Les adjunto el Makefile para poder correr el flujo de diseño de Xilinx sin usar la interface gráfica: (correrá mássss rapido)

    # Simple makefile#
    
    SHELL=/bin/bash
    
    TOP=topSRCS=./hdl/top.vhd ./hdl/top.prj
    
    # List all of your required cores here.
    
    #CORES = tri_mode_eth_mac_v2_2.edn \
    
    #        rxfifo_8kx9_to_36.edn     \
    
    #        rxfifo_8kx9_to_72.edn
    
    # uncomment the following line to skip rebuilding IP cores
    
    CORES =
    
    #-------------------------------------------------------
    
    # Probably dont need to change anything below this line.
    
    #-------------------------------------------------------
    
    # name of the global report file.
    
    REPORT = synth.txt
    
    # Smartguide support to improve routing speeds
    
    ifneq ($(strip $(wildcard $(TOP)_par.ncd)),)
    
    SMARTGUIDE_CP = cp $(TOP)_par.ncd smartguide.ncd
    
    SMARTGUIDE = -smartguide smartguide.ncd
    
    NUM_ITER =
    
    else
    
    SMARTGUIDE_CP =
    
    SMARTGUIDE =
    
    NUM_ITER = -n 1
    
    endif
    
    # Need to be able to recreate the core IP
    
    .SUFFIXES : .edn .xco .ngc
    
    # Invoke coregen to create edn or ngc files etc needed for ngdbuild.
    
    # Alas coregen will recreate the xco file so we just copy the old
    
    # xco and then copy it back after we are done.
    
    # Also, copy the .vhd files to ../src
    
    #
    
    .xco.edn:
    
    @echo ==================================================
    
    @echo "=== Invoking coregen to rebuild $@"
    
    @echo ==================================================
    
    cp -p $< $<.BAK
    
    coregen -b $<
    
    mv $<.BAK $<
    
    @if [ -r $*.vhd ]; then \
    
    @echo "Copying $*.vhd to the src directory." ;\
    
    cp $*.vhd ./hdl/src ;\
    
    fi
    
    .xco.ngc:
    
    @echo ==================================================
    
    @echo "=== Invoking coregen to rebuild $@"
    
    @echo ==================================================
    
    cp -p $< $<.BAK
    
    coregen -b $<
    
    mv $<.BAK $<
    
    @if [ -r $*.v ]; then \
    
    @echo "Copying $*.vhd to the src directory." ;\
    
    cp $*.vhd ./hdl/src ;\
    
    fi
    
    all: $(TOP)_par.ncd $(TOP)_par.twr $(TOP)_par.bit
    
    @echo Making all...
    
    cores: $(CORES)
    
    @echo "Made cores."
    
    bitstream: $(TOP)_par.bit
    
    @echo "Bitstream created."
    
    # Generate Bit Stream
    
    $(TOP)_par.bit: $(TOP)_par.ncd
    
    @echo ==================================================
    
    @echo "=== Generate bit stream file from ncd"
    
    @echo ==================================================
    
    bitgen -intstyle ise -g Binary:Yes -m -w $(TOP)_par.ncd
    
    rm ./bitstreams/$(TOP)_par.bit
    
    cp $(TOP)_par.bit ./bitstreams/
    
    # Run timing analysis ( add -u for unconstrained paths)
    
    $(TOP)_par.twr: $(TOP)_par.ncd
    
    @echo ==================================================
    
    @echo "=== Run Post Place and Route Timing (trce)"
    
    @echo ==================================================
    
    trce -v $(TOP)_par.ncd $(TOP).pcf | tee -a $REPORT
    
    # Run PaR
    
    $(TOP)_par.ncd: $(TOP).ncd
    
    @echo ==================================================
    
    @echo "=== Run Place and Route (PAR)"
    
    @echo ==================================================
    
    if par -intstyle ise $(NUM_ITER) -ol high -pl high -rl high -t 1 $(SMARTGUIDE) -w $(TOP).ncd $(TOP)_par.ncd ;\
    
    then \
    
    @echo "Place and Route passed." ;\
    
    cat $(TOP)_par.par >> $REPORT ;\
    
    else \
    
    @echo "Place and Route failed - see $(TOP)_par.par for details." ;\
    
    exit 1 ;\
    
    fi
    
    # Run map
    
    $(TOP).ncd: $(TOP).ngd
    
    @echo ==================================================
    
    @echo "=== Run MAP"
    
    @echo ==================================================
    
    $(SMARTGUIDE_CP)
    
    if map -intstyle ise -detail -u -ol high -cm speed $(SMARTGUIDE) -ignore_keep_hierarchy -pr b -k 4 -c 100 -tx off -timing $(TOP) ; \
    
    then \
    
    @echo "map passed." ; \
    
    cat $(TOP).mrp >> $REPORT ;\
    
    else \
    
    @echo "map failed - see $(TOP).mrp for details." ;\
    
    exit 1 ;\
    
    fi
    
    # Run ngdbuild (would also pull in core .ngo files)
    
    $(TOP).ngd: $(TOP).ngc
    
    @echo ==================================================
    
    @echo "=== Run NGDBUILD"
    
    @echo ==================================================
    
    if ngdbuild -intstyle ise $(TOP) ; \
    
    then \
    
    @echo "ngdbuild passed." ; \
    
    cat $(TOP).bld >> $REPORT ;\
    
    else \
    
    @echo "ngdbuild failed - see $(TOP).bld for details." ;\
    
    exit 1 ;\
    
    fi
    
    # Run synthesis
    
    $(TOP).ngc: $(SRCS) ./hdl/$(TOP).script
    
    @echo ==================================================
    
    @echo "=== Run Synthesis (XST)"
    
    @echo ==================================================
    
    if xst -intstyle ise -ifn ./hdl/$(TOP).script ; \
    
    then \
    
    @echo "Synthesis passed." ; \
    
    cat $(TOP).srp >> $REPORT ;\
    
    else \
    
    @echo "Synthesis failed - see $(TOP).srp for details." ;\
    
    exit 1 ;\
    
    fi
    
    #Generate Post-synthesis VHDL and SDF:
    
    psv: $(TOP)_par.ncd
    
    @echo ==================================================
    
    @echo "=== Generate post-synthesis verilog and SDF"
    
    @echo ==================================================
    
    netgen -sim -ofmt vhdl nf2_top_par.ncd -pcf $(TOP).pcf
    
    clean:
    
    rm -rf *.bld *.lso *.mrp *.ncd *.ngm *.pad.* *.par *.twr *.bit *.drc *.bgn
    
    rm -rf *.pcf *.xpi *.srp *vhdl.prj *pad.txt *.pad *pad.csv netlist.lst xst
    
    rm -rf $(TOP).ngc *~ $(TOP)_par.v $(TOP)_par.sdf $(TOP)_par.bin
    
    rm -rf *.msk *.unroutes *.xml
    
    rm -rf $REPORT
    
    really_clean:
    
    @echo "Making really clean - will need to use coregen to rebuild the core ngc files."
    
    make clean
    
    rm -rf *.ngc *.ngo *.edn *.asy *flist.txt *readme.txt *.sym *.v *.veo *.log *.ngd *.nlf

    NOTA: Si tenemos netlists .NGC generados mediante Coregen estos deben ser copiados al directorio tope del proyecto donde se encuentra nuestro Makefile.

    El top.prj es un archivo que es una lista de los archivos VHDL que tiene nuestro proyecto pero tiene que ser en el orden de dependencia, de modo que en esta lista top.vhd que es el archivo tope y que depende de todos será el que se liste al final.

    El archivo top.script es mi script para usar el XST desde línea de comandos y en mi caso lo he hecho así:

    run
    -ifn ./hdl/top.prj
    -ifmt VHDL
    -ofn top.ngc
    -ent top
    -ofmt NGC
    -p xc2vp30-7-ff896
    -opt_mode SPEED
    -opt_level 1
    -max_fanout 32
    -keep_hierarchy no
    -register_duplication YES
    -equivalent_register_removal no
    -hierarchy_separator /
    -bus_delimiter <>
    -mux_extract YES
    -mux_style MUXF
    -ram_extract YES
    -ram_style Auto
    -rom_extract YES
    -rom_style Distributed
    -decoder_extract YES
    -priority_extract YES
    -shreg_extract YES
    -shift_extract YES
    -xor_collapse YES
    -resource_sharing YES
    -iobuf YES
    -register_balancing no
    -slice_packing Yes
    -glob_opt max_delay
    -fsm_encoding Compact

    Estas opciones definitivamente se pueden cambiar según nuestros requerimientos. Ejemplo: flujo de diseño modular o para reconfiguración dinámica parcial.

    Al final de la compilación mediante “make” se me copia la bitstream generada y lista para descargarse al FPGA en el directorio “bitstreams”.

    Ventana que reporta que make finalizó exitosamente

    El script runimpact.sh dentro del directorio “bitstreams” lo listo a continuación:

    #!/bin/bash
    impact -batch prog.cmd

    El archivo prog.cmd también está en este directorio y su contenido es:

    setmode -bscan
    setcable -p auto
    identify
    assignfile -p 3 -file top_par.bit
    program -p 3
    quit

    VI. TRABAJANDO CON EMACS Y MODELSIM PARA EDICIÓN DE NUESTRO CÓDIGO VHDL

    Si ejecutamos todo nuestro flujo de diseño veremos que la etapa de síntesis es la que consume más tiempo, asi que si la vamos a ejecutar sería mejor que estemos seguro que nuestro archivos VHDL hacen lo que esperamos, para eso usaremos el Modelsim para Linux.

    Después de estos pasos instalé Matlab 7 R14 para Linux, Modelsim 6.2 para Linux y el Intel C++ Compiler 10.1.008. Los pasos para instalar estos programas están en Internet, (en San Google) y no son complicados.

    Todos estos programas se encuentran en Emule, junto al Cadence para diseño de circuitos VLSI versión IC 5.033; lo malo de este último es que sólo es soportado hasta por el kernel del Ubuntu Dapper (de Edgy para arriba no funciona), así que si quieren usarlo necesitarán una máquina con Ubuntu Dapper y antes de ejecutarlo dar una variable de entorno:

    alias icfb=’LD_ASSUME_KERNEL=2.6.15 icfb’

    La razón de esto es un problema con las librerías de threads que usa el Cadence IC 5.033 que actualmente están obsoletas.

    Una vez instalado el Modelsim y que ha sido añadido a nuestro PATH en el .bashrc tendremos listos para usar en línea de comandos el compilador VCOM y el simulador VSIM del Modelsim.

    Para compilar nuestros archivos VHDL, nos vamos dentro del directorio “hdl” de nuestro proyecto y creamos primero una librerìa work donde compilaremos nuestro diseño:

    >>vlib work

    >>vmap work work

    Para ver si trabaja bien, llamamos al compilador del Modelsim VCOM

    >>vcom -93 -work work top.vhd

    Model Technology ModelSim SE vcom 6.2 Compiler 2004.08 Aug 19 2007
    – Loading package standard
    – Loading package std_logic_1164
    – Loading package std_logic_arith
    – Loading package std_logic_unsigned
    – Compiling entity top
    – Compiling architecture behavioral of top

    La directiva -93 es para especificar VHDL 93.

    Ahora ya que esta creada la librería podemos editar nuestro código VHDL usando EMACS. Sinceramente es el mejor editor VHDL que existe, ya que EMACS dispone integrado un modo especial para VHDL que nos permite hacer autocompletado de código, insertar un componente o instancia desde otro archivo VHDL, generador de testbench, manejador de proyectos mediante “Speedbar”.

    Es el mejor editor VHDL que existe y siendo GNU. Y como adicional, EMACS se integra con el Modelsim en forma automática, de modo que cuando en EMACS llamamos compilar, EMACS llamara al VCOM de Modelsim para compilar el código que estamos editando y saber si nos hemos equivocado (increíble no?).

    EMACS editando con VHDL-mode

    Para simular nuestro código VHDL desde lìnea de comandos, necesitamos usar VSIM, pero en modo consola:

    >>vsim -c work.[testbench_top] -do “run -all; exit;”

    testbench_top es el nombre de nuestro archivo testbench_top.vhd que debe también haber sido compilado previamente con VCOM y dentro de nuestra librerìa WORK.

    Blog de WordPress.com.