10 enero 2017

Generar un RPM en windows usando Maven

Quería compartir aquí el resultado de un poco de trabajo de investigación que tuve que hacer hace poco.

Objetivo: Crear un paquete RPM en una máquina Windows, utilizando Maven.

Conceptos:
  • RPM: es un tipo de empaquetamiento, que sirve para distribuir e instalar software en plataformas Linux. Dentro de este paquete se encuentra tanto el software como su configuración y las tareas que se tienen que realizar durante la instalación, desinstalación o actualización del software.
  • Maven: es una herramienta de software (desarrollada por Apache) para la gestión y construcción de proyectos Java. Se puede considerar como una evolución del Ant. Maven utiliza unos ficheros llamados POM (Project Object Model) para describir el software a construir.
Ya se que es un poco absurdo preparar software para Linux desde una maquina Windows, pero es algo que nos toca hacer, demasiadas veces.

rpm-maven-plugin

Una vez aclarado el objetivo, lo primero fue buscar un plugin para Maven que me permitiera crear un RPM, fue bastante fácil la búsqueda, y encontré el rpm-maven-plugin, que nos permite generar los paquetes RPM configurándolos en el POM. Pero habia una pega, utiliza comandos de Linux para generar el POM. (echar un vistazo a la documentación del rpm-maven-plugin para saber como preparar el POM).

Cygwin

Asi que decidí instalar el Cygwin (un software que nos permite ejecutar comandos de Linux en nuestro Windows), ya que este software tiene los comandos para rpm.
Nota: en la instalación del cygwin hay que seleccionar los paquetes para la generación de Rpm, como se ve en la siguiente imagen:


Pero, ojo, no hay que añadir el Cygwin al PATH, por que descubrí que los comandos "rpm" y "rpmbuild" de Cygwin no funcionan bien, fallaba algo. Así que tuve que crearme unos "rpm" y "rpmbuild" falsos que me ayudaran a hacer la compilación. Por desgracia los trucos que aparecen en muchos sitios de internet no me funcionaron, y tuve que investigar un poco más.

Comandos rpm y rpmbuild "trampeados"

Me preparé los siguientes programas C++ para trampear los comandos rpm y rpmbuild:

Para el rpm.exe
#include
#include
#include
#include

#define ENV_VAR_CYGWIN_PATH "CYGWIN_HOME"

int main(int argc, char* argv[])
{
    std::string command;

    char* cygwinPath = getenv(ENV_VAR_CYGWIN_PATH);
    if (NULL == cygwinPath) cygwinPath = "C:\\cygwin";

    command.append("set PATH=").append(cygwinPath).append("\\bin;%PATH% & ");
    command.append("bash -c \"rpm");

    for (int i = 1; i < argc; i ++) {
        command.append(" ").append(argv[i]);
    }
    command.append("\"");
    int retValue = system(command.c_str());
    return retValue;
}

Y el rpmbuild.exe
#include
#include
#include
#include

#define ENV_VAR_CYGWIN_PATH "CYGWIN_HOME"

int main(int argc, char* argv[])
{
    std::string command;
    char* cygwinPath = getenv(ENV_VAR_CYGWIN_PATH);
    if (NULL == cygwinPath) cygwinPath = "C:\\cygwin";

    command.append("set PATH=").append(cygwinPath).append("\\bin;%PATH% & ");
    command.append("bash -c \"rpmbuild");

    boolean isDefine = false;
    for (int i = 1; i < argc; i ++) {
        if (isDefine) command.append("=\'");
        else command.append(" ");
        command.append(argv[i]);
        if (isDefine) command.append("\'");
        isDefine = (0 == strcmp(argv[i],"--define"));
    }
    command.append("\"");
    int retValue = system(command.c_str());
    return retValue;
}

Con esto ya lo tengo todo preparado para hacer el RPM


Desde linea de comando:

Si el Maven lo lanzamos desde línea de comando tendremos que crear as siguientes variable de entorno:

  • CYGWIN_HOME --> contendrá el directorio de instalación de Cygwin (por ejemplo c:\cygwin)

Y en la variable de entorno PATH tendremos que poner el directorio donde se encuentran los comandos rpm.exe y rpmbuild.exe que hemos preparado. Por ejemplo si los hemos copiado en C:\bla\bin, nos bastará con definir PATH=C:\bla\bin;%PATH%


Desde el intellij

Si utilizamos un IDE de desarrollo, como el IntelliJ, tendremos que preparar las variables de entorno CYGWIN_HOME y PATH para que se utilicen de forma correcta al procesar el POM, como se puede ver en la siguiente imagen:



Con todo esto a mi me funcionó, y espero que le pueda ser de utilidad a alguien.

No hay comentarios: