Como seguramente muchos sabreis, los compiladores XC de Microchip están basados en GCC, un compilador libre y gratuito con licencia GPL. Sea como sea, Microchip parte de GCC, le mete sus apaños y lo comercializa, además a precios abusivos, por ejemplo la versión PRO Workstation para PIC32 cuesta unos 1200 euros, de vergüenza.
Lo bueno de la licencia GPL, es que si coges esos fuentes y los modificas, tienes la obligación de facilitar los fuentes modificados, y eso Microchip lo cumple por supuesto. TODOS los fuentes de los compiladores XC (
XC8, XC16 y XC32), se pueden descargar de la web de Microchip, y ahí, editando el fuente correspondiente podemos ver como limitan la optimización en función del tipo de licencia, FREE, STANDARD o PRO.
Ante todo, dejar claro que TODO lo que voy a contar es LEGAL, partimos de un compilador gratuito como es GCC, aunque modificado por Microchip, y simplemente vamos a deshacer lo que Microchip ha hecho, y todo ello a partir de los fuentes que la propia Microchip proporciona. El paquete GCC se compone de varios productos, que hay que compilar por separado (
gmp, ppl, cloog, libelf, zlib, binutils y GCC ) para finalmente enlazarlos todos creando el ejecutable GCC, y ahi, SI, hay unas librerías de Microchip, librerías que se instalan automáticamente al instalar MPLABX y XC32. Lo que quiero decir es que el compilado final modificado no lo puedo facilitar, pero si las instrucciones para compilar todo el paquete y obtener el compilador libre, sin limitaciones. Los precompilados de cada paquete, hasta la compilación final que lo enlaza todo, si que los podré facilitar porque son parte de GCC, no son propiedad de Microchip.
Todos los pasos que voy a seguir y documentar están basados en la información que dan en la web de Jubatian, solo que a mi me gusta documentar las cosas de manera más detallada, con capturas de pantalla, todo bien mascado sin presuponer nada:
http://www.jubatian.com/articles/turning-on-optimizations-in-microchips-xc32/1.- Útiles necesarios.1.-
Cygwin: entorno de desarrollo y compilador emulando un entorno Linux bajo Windows.
https://www.cygwin.com/ Para Windows 32 bits -->
https://www.cygwin.com/setup-x86.exe Para Windows 64 bits -->
https://www.cygwin.com/setup-x86_64.exe2.-
Fuentes compilador XC de Microchip:
http://www.microchip.com/pagehandler/en-us/devtools/dev-tools-parts.html XC32 v1.40 --->
http://ww1.microchip.com/downloads/en/DeviceDoc/xc32-v1.40-src.zip XC16 v1.25 --->
http://ww1.microchip.com/downloads/en/DeviceDoc/v1.25.src.zip3.-
MPLABX de Microchip http://www.microchip.com/pagehandler/en-us/devtools/dev-tools-parts.html V3.15 para Windows 32/64 bits:
http://ww1.microchip.com/downloads/en/DeviceDoc/MPLABX-v3.15-windows-installer.exe4.-
Compilador XC32 gratuito de Microchip:
http://www.microchip.com/pagehandler/en-us/devtools/dev-tools-parts.html v1.40 para Windows
http://www.microchip.com/mplabxc32windows5.-
Librerias pic32mx de Microchip, se instalan automáticamente al instalar el compilador XC32, en el subdirectorio pic32mx de la instalación.
2.- Instalación.2.1- Ejecutamos la instalación de Cygwin Seleccionamos instalar desde Internet > Siguiente.
Dejamos el directorio de instalación por omisión que muestra C:\cygwin64
Seleccionamos el directorio donde queremos que se descarguen los ficheros de instalación, yo he elegido C:\cygwin64\instalacion
Aqui lo dejamos por omisión, Direct Connection.
Seleccionar el sitio de descarga, en principio cualquiera vale.
Paquetes a instalar: hacen falta
gcc, make, binutils, automake, autoconf, bison, flex, e iconv. Escribimos uno a uno esos paquetes en la ventana
Search y pinchamos sobre cada uno en
Default para que cambie a
Install. La instalación ocupará aproximadamente
1 Gb.
Si faltase algo más tarde se puede añadir, no hay problema. No recomiendo que seleccioneis que se instale todo (All), porque creo que son tropecientos mil Gigas. Le damos a
Siguiente.
Y ahí estará un rato descargando e instalando paquetes.
2.2- Descargamos e instalamos MPLABX y XC32. Voy a documentar la compilación de XC32, pero sirve igual para hacerlo con
XC8 y XC16.
2.3- Descargamos y descomprimimos los fuentes de XC32 de la web de Microchip, en el directorio
C:\Cygwin64\fuentes. Este es el directorio de mi instalación de Cygwin, si lo habeis llamado de otra forma, colgar el subdirectorio fuentes en el raiz de vuestra instalación y descomprimir ahí los fuentes de XC32.
2.4- Copiamos las librerías de Microchip, que encontraremos en el subdirectorio
pic32mx de la instalación de XC32. De estas librerías solo necesitamos los contenidos de los subdirectorios
lib e
include.
Copiaremos los contenidos siguientes (ocupa unos 850 Mb):
pic32mx\lib\ ---> C:\Cigwin64\usr\lib\
pic32mx\include\ ---> C:\Cigwin64\usr\include\3.- Configuración de Cygwin.Una vez instalado Cygwin, ejecutamos el terminal Cygwin
Vereis que se abre una ventana DOS, con un entorno Linux, que responde a todos los comandos Linux, me bajo al directorio raiz con
cd/ o subdirectorio a subdirectorio con
cd.., y visualizo el contenido con
ls -l.
Ahí está todo el entorno de desarrollo, incluido el compilador de C GCC, para poder recompilar XC32 que es a su vez una modificación del propio GCC. Quien ya conozca Linux esa ventaja que tiene, aunque con cuatro comandos básicos, para este caso, es más que suficiente, el CD para cambiar de directorio, el LS para visualizar el contenido y poco más. La estructura de directorios como se ve es la típica de Linux, etc, var, usr, tmp, lib, dev, home.... todo muy familiar para cualquier linuxero.
Los subdirectorios
fuentes e
instalacion los cree yo, para almacenar los fuentes de XC32 y los paquetes de instalación de Cygwin. También habrá que crear un directorio para los compilados, definiendo unas vías con variables de entorno para que la compilación localice librerías y cabeceras (archivos .h).
Ahora toca añadir las variables de entorno para que el proceso de compilación localice librerías y cabeceras (archivos .h) al compilar.
Así que abrimos de nuevo el terminal de Cygwin y tecleamos cada una de estas dos lineas, podeis hacer un copiar-pegar para ir más rápido.
export CPPFLAGS="-I c:/cygwin64/usr/include"
export LDFLAGS="-L c:/cygwin64/usr/lib"Para comprobar que se han añadido basta con teclear
export, y veremos nuestras variables de entorno en la lista, junto a muchas más propias de Windows.
Lamentablemente, parece que al cerrar el terminal y volverlo a abrir esas variables de entorno se pierden y nos toca volver a teclearlas. Se podrían añadir a la lista de variables de entorno de Windows, pero teniendo en cuenta que probablemente todo el proceso de compilación lo haremos del tirón en un solo día, mejor dejarlo así. Como digo, si cerrais y abris de nuevo el terminal al teclear de nuevo
export, vereis que las variables de entorno ya no están.
En cuanto a la configuración de Cygwin, esto es todo lo que hay que hacer, pasemos a otro tema.
4.- Modificación de los fuentes de XC32 para eliminar las restricciones por licencia.En este paso modificaremos los fuentes de GCC, en los que Microchip añadió sus apaños para restringir las opciones de optimización según el tipo de licencia.
El fuente concreto en el que se comprueba la licencia es
mchp.c, desde este programa Microchip llama a un programa propio llamado
xclm en el que usando un algoritmo SHA-256 calcula el tipo de licencia según el código almacenado en un fichero de licencias que se supone lo proporciona Microchip cuando compramos el producto, no así cuando usamos la versión FREE.
Los tipos de licencia posibles son
FREE, Standard y PRO para XC32, y además para
XC32++ tenemos FREE y FULL. XC32++ es para trabajar con C++. Aquí podeis ver el tipo de optimizaciones disponibles según licencia, además con la PRO y la XC32++ FULL tenemos
mips16 y
lto.
Mips16 permite compilar en 16 bits, lo que reduce el objeto aún más, hasta un 26%, sobre lto de momento desconozco su utilidad.
Editando el fuente
mchp.c, nos encontramos en las lineas
1238 a 1271 la rutina que comprueba la licencia y en base a ella permite los diversos niveles de optimización que he indicado en la imagen anterior.
Las variables
nullify_O2, nullify_O3 y nullify_Os se corresponden con los niveles de optimización
2, 3 y s, y, las variables
nullify_mips16 y nullify_lto se corresponden con
mips16 y lto. Poniendo la variable correspondiente a cero, se autoriza ese nivel de optimización, por eso en la rutina inicialmente todas están a 1, osea pendientes de autorizar según licencia. Cuando la licencia es PRO, como podemos ver en el fuente, todas esas variables se ponen a cero, pero si la licencia es la Standard solo se pone a cero la variable nullify_O2 para autorizar hasta el nivel dos de optimización.
#ifndef SKIP_LICENSE_MANAGER
nullify_O2 = 1;
nullify_O3 = 1;
nullify_Os = 1;
nullify_mips16 = 1;
nullify_lto = 1;
#endif /* SKIP_LICENSE_MANAGER */
if (mchp_profile_option) {
flag_inline_small_functions = 0;
flag_inline_functions = 0;
flag_no_inline = 1;
flag_optimize_sibling_calls = 0;
}
require_cpp = (strstr (save_decoded_options[0].arg, "cc1plus")!=NULL);
mchp_pic32_license_valid = pic32_get_license (require_cpp);
if (require_cpp && !((mchp_pic32_license_valid == PIC32_VALID_CPP_FREE) ||
(mchp_pic32_license_valid == PIC32_VALID_CPP_FULL)))
{
error ("MPLAB XC32 C++ license not activated");
inform (input_location, "Visit http://www.microchip.com/MPLABXCcompilers to acquire a "
"free C++ license");
}
if ((mchp_pic32_license_valid == PIC32_VALID_PRO_LICENSE) ||
(mchp_pic32_license_valid == PIC32_VALID_CPP_FULL))
{
nullify_lto = nullify_mips16 = nullify_O2 = nullify_O3 = nullify_Os = 0;
}
else if (mchp_pic32_license_valid == PIC32_VALID_STANDARD_LICENSE)
{
nullify_O2 = 0;
}
En esta linea que marco a continuación, es exactamente donde se llama al programa
XCLM de Microchip para calcular el tipo de licencia, usando un algoritmo SHA-256, y devuelve en la variable
mchp_pic32_license_valid un dígito que indica el tipo de licencia autorizado.
require_cpp = (strstr (save_decoded_options[0].arg, "cc1plus")!=NULL);
mchp_pic32_license_valid = pic32_get_license (require_cpp);
if (require_cpp && !((mchp_pic32_license_valid == PIC32_VALID_CPP_FREE) ||
(mchp_pic32_license_valid == PIC32_VALID_CPP_FULL)))
{
error ("MPLAB XC32 C++ license not activated");
inform (input_location, "Visit http://www.microchip.com/MPLABXCcompilers to acquire a "
"free C++ license");
}
if ((mchp_pic32_license_valid == PIC32_VALID_PRO_LICENSE) ||
(mchp_pic32_license_valid == PIC32_VALID_CPP_FULL))
{
nullify_lto = nullify_mips16 = nullify_O2 = nullify_O3 = nullify_Os = 0;
}
else if (mchp_pic32_license_valid == PIC32_VALID_STANDARD_LICENSE)
{
nullify_O2 = 0;
}
Ese dígito en
mchp_pic32_license_valid será el siguiente según tipo de licencia.
0 = licencia FREE
1 = licencia Standard
2 = licencia PRO
4 = licencia no C++
5 = licencia C++ FREE
6 = licencia C++ FULL
La modificación a realizar es bastante obvia, forzamos en la variable
mchp_pic32_license_valid el dígito que queramos según la licencia que nos interese y arreglado. Personalmente no me gusta borrar nada de los fuentes originales, ni modificar lineas, prefiero siempre AÑADIR poniendo un comentario que indique que ese añadido es mío, así que para activar la licencia PRO o la C++ FULL, solo tenemos que añadir una linea tras la llamada a la rutina que calcula la licencia.
Para activar una licencia PRO, añadiriamos esta linea de código en la linea 1255.
mchp_pic32_license_valid = pic32_get_license (require_cpp);
mchp_pic32_license_valid = 2; // añadido por planeta9999Y si queremos activar la licencia de C++ completa:
mchp_pic32_license_valid = pic32_get_license (require_cpp);
mchp_pic32_license_valid = 6; // añadido por planeta9999Y eso es todo, salvamos el fuente y ya lo tenemos casi todo listo para empezar a compilar todos los paquetes de GCC, previo a la compilación y enlazado final que nos dará un nuevo XC32 completo sin limitaciones, GRATUITO y LEGAL.
Nos vamos a ahorrar un pico, porque
la versión PRO cuesta 1200 euros y la versión
XC32++ FULL se va a los 1500 euros.
5.- Creando estructura de subdirectorios para la compilación.En este paso simplemente vamos a crear unos subdirectorios donde se irán creando los objetos de las compilaciones que vayamos haciendo de los diversos paquetes que componen GCC.
En concreto hay que compilar
gmp, ppl, cloog, libelf, zlib, binutils y finalmente
GCC, asi que para tenerlo todo un poco ordenado vamos a crear un subdirectorio para cada paquete, utilizaremos por ejemplo la nomenclatura
[componente]_build. He decidido crear el subdirectorio
compilados colgando del raiz de Cygwin, y dentro de ese subdirectorio uno para cada paquete, lo veis en esta imagen. Zlib no se puede compilar fuera del directorio de los fuentes, así que no he creado el subdirectorio
zlib_build en
compilados porque no serviría.
Con esto hemos llegado al final de la configuración del entorno. Lo siguiente ya será empezar a compilar cada paquete por separado y el paso final con el enlazado de todos ellos y la compilación de GCC.
6.- Cumpliendo con GPL.Según los requerimientos de la licencia GPL en la que está basado GCC, aquí facilito la
descarga del fuente modificado, que es como ya comenté el programa
mchp.c. La modificación es un añadido en la linea 1255, para habilitar en cualquier caso todos los niveles de optimización que permite GCC. He puesto el código 2 que activa la licencia PRO, pero se puede modificar poniendo un 6 para activar XC32++.
Si editais el fuente, os encontrareis este añadido en la linea 1255.
mchp_pic32_license_valid = 2; // añadido por planeta9999, 2 = XC32 PRO, 6 = XC32++ FULLEnlace descarga
fuente mchp.c modificado, reemplazarlo en los fuentes de Microchip XC32 v1.40 antes de compilar.
https://mega.nz/#!hIVkHIrC!Ey4mXwZsHirHA7Pw18kx_zkXr7mTvCMWAspl_c9XuhM7.- Compilando paquetes gmp, ppl, cloog, libelf, zlib y binutils. (contenidos en preparación)8.- Enlazado y compilación final de GCC. (contenidos en preparación)9.- Pruebas del nuevo XC32 sin limitaciones sobre MPLABX. (contenidos en preparación)Y por hoy hasta aquí. Seguiremos, si alguien quiere ir haciendo camino y probando no es complicado ....