Cómo crear ejecutables Go para múltiples plataformas en Ubuntu 16.04

Introducción

Índice
  1. Introducción
  • Prerrequisitos
  • Paso 1: Instalación de programas Go desde el control de versiones
  • Paso 2: creación de un ejecutable
  • Paso 3: Instalación de un ejecutable
  • Paso 4: creación de ejecutables para diferentes arquitecturas
  • Paso 5: Creación de un script para automatizar la compilación cruzada
  • Conclusion
  • El lenguaje de programación Go viene con una rica cadena de herramientas que hace que obtener paquetes y crear ejecutables sea increíblemente fácil. Una de las características más poderosas de Go es la capacidad de crear ejecutables para cualquier plataforma externa compatible con Go. Esto hace que las pruebas y la distribución de paquetes sean mucho más fáciles, porque no es necesario tener acceso a una plataforma específica para distribuir el paquete en ella.

    En este tutorial, utilizará las herramientas de Go para obtener un paquete del control de versiones e instalar automáticamente su ejecutable. Luego, compilará e instalará manualmente el ejecutable para familiarizarse con el proceso. Luego, compilará un ejecutable para una arquitectura diferente y automatizará el proceso de compilación para crear ejecutables para múltiples plataformas. Cuando termine, sabrá cómo compilar ejecutables para Windows y macOS, así como para otras plataformas que desee admitir.

    Prerrequisitos

    Para seguir este tutorial, necesitarás:

    • Un servidor Ubuntu 16.04 configurado siguiendo la guía de configuración inicial del servidor Ubuntu 16.04 , incluido un usuario sudo no root y un firewall.
    • Go instalado, como se describe en Cómo instalar Go 1.6 en Ubuntu 16.04 .

    Paso 1: Instalación de programas Go desde el control de versiones

    Antes de poder crear ejecutables a partir de un paquete Go, tenemos que obtener su código fuente. La go getherramienta puede obtener paquetes de sistemas de control de versiones como GitHub. En segundo plano, go getclona paquetes en subdirectorios del $GOPATH/src/directorio. Luego, si corresponde, instala el paquete compilando su ejecutable y colocándolo en el $GOPATH/bindirectorio. Si configuraste Go como se describe en los tutoriales de requisitos previos, el $GOPATH/bindirectorio se incluye en tu $PATHvariable de entorno, lo que garantiza que puedas usar los paquetes instalados desde cualquier lugar de tu sistema.

    La sintaxis del go getcomando es . Es una cadena que identifica de forma única un paquete. Suele ser la ubicación del paquete en un repositorio remoto como Github o un directorio dentro del directorio de tu máquina.go get package-import-pathpackage-import-path$GOPATH/src/

    Es común usarlo go getcon la -ubandera, que indica go getque se debe obtener el paquete y sus dependencias, o actualizar esas dependencias si ya están presentes en la máquina.

    En este tutorial, instalaremos Caddy , un servidor web escrito en Go. Según las instrucciones de Caddy x, utilizaremos github.com/mholt/caddy/caddyla ruta de importación del paquete. Utilice go getpara obtener e instalar Caddy:

    1. go get -u github.com/mholt/caddy/caddy

    El comando tardará un tiempo en completarse, pero no verá ningún progreso mientras obtiene el paquete y lo instala. No hay ningún resultado que indique que el comando se ejecutó correctamente.

    Cuando se complete el comando, encontrará el código fuente de Caddy disponible en $GOPATH/src/github.com/mholt/caddy. Además, dado que Caddy tiene un ejecutable, se creó y almacenó automáticamente en el $GOPATH/bindirectorio. Verifique esto usando whichpara imprimir la ubicación del ejecutable:

    1. which caddy

    Verás el siguiente resultado:

    Output/home/sammy/work/bin/caddy

    Nota : El go getcomando instala paquetes desde la rama predeterminada de un repositorio Git, que en muchos casos es la masterrama , o la rama en desarrollo. Asegúrese de revisar las instrucciones, que normalmente se encuentran en el READMEarchivo del repositorio, antes de usar go get.

    Puedes usar comandos de Git como, por ejemplo, git checkoutpara seleccionar una rama diferente en las fuentes obtenidas mediante el go getcomando. Revisa el tutorial Cómo usar ramas de Git para obtener más información sobre cómo cambiar de rama.

    Veamos el proceso de instalación de paquetes Go con más detalle, comenzando con la creación de ejecutables a partir de los paquetes que ya hemos obtenido.

    Paso 2: creación de un ejecutable

    El go getcomando descargó el código fuente e instaló el ejecutable de Caddy en un solo comando. Pero es posible que desees reconstruir el ejecutable tú mismo o crear un ejecutable a partir de tu propio código. El go buildcomando crea ejecutables.

    Aunque ya instalamos Caddy, vamos a compilarlo de nuevo manualmente para familiarizarnos con el proceso. Ejecutamos go buildy especificamos la ruta de importación del paquete:

    1. go build github.com/mholt/caddy/caddy

    Como antes, si no hay salida, esto indica que la operación se ha realizado correctamente. El ejecutable se generará en el directorio actual, con el mismo nombre que el directorio que contiene el paquete. En este caso, el ejecutable se llamará caddy.

    Si se encuentra en el directorio del paquete, puede omitir la ruta al paquete y simplemente ejecutar go build.

    Para especificar un nombre o una ubicación diferentes para el ejecutable, utilice el -oindicador. Construyamos un ejecutable llamado caddy-servery colóquelo en un builddirectorio dentro del directorio de trabajo actual:

    1. go build -o build/caddy-server github.com/mholt/caddy/caddy

    Este comando crea el ejecutable y también crea el ./builddirectorio si no existe.

    Ahora veamos cómo instalar ejecutables.

    Paso 3: Instalación de un ejecutable

    La creación de un ejecutable crea el ejecutable en el directorio actual o en el directorio que elija. La instalación de un ejecutable es el proceso de crear un ejecutable y almacenarlo en $GOPATH/bin. El go installcomando funciona igual que go build, pero go installse encarga de colocar el archivo de salida en el lugar correcto para usted.

    Para instalar un ejecutable, utilice go install, seguido de la ruta de importación del paquete. Una vez más, utilice Caddy para probar esto:

    1. go install github.com/mholt/caddy/caddy

    Al igual que con go build, no verá ningún resultado si el comando se ejecutó correctamente. Y como antes, el ejecutable se crea con el mismo nombre que el directorio que contiene el paquete. Pero esta vez, el ejecutable se almacena en $GOPATH/bin. Si $GOPATH/bines parte de su $PATHvariable de entorno, el ejecutable estará disponible desde cualquier lugar de su sistema operativo. Puede verificar su ubicación mediante whichel comando:

    1. which caddy

    Verás el siguiente resultado:

    Output of which/home/sammy/work/bin/caddy

    Ahora que comprende cómo go getfuncionan , go buildy go install, y cómo se relacionan, exploremos una de las características más populares de Go: crear ejecutables para otras plataformas de destino.

    Paso 4: creación de ejecutables para diferentes arquitecturas

    El go buildcomando le permite crear un archivo ejecutable para cualquier plataforma de destino compatible con Go, en su plataforma . Esto significa que puede probar, publicar y distribuir su aplicación sin crear esos archivos ejecutables en las plataformas de destino que desea utilizar.

    La compilación cruzada funciona estableciendo las variables de entorno necesarias que especifican el sistema operativo y la arquitectura de destino. Usamos la variable GOOSpara el sistema operativo y GOARCHla arquitectura de destino. Para crear un ejecutable, el comando adoptaría esta forma:

    1. env GOOS=target-OS GOARCH=target-architecture go build package-import-path

    El envcomando ejecuta un programa en un entorno modificado. Esto le permite utilizar variables de entorno solo para la ejecución del comando actual. Las variables se anulan o se restablecen después de que se ejecuta el comando.

    La siguiente tabla muestra las posibles combinaciones de GOOSy GOARCHque puedes utilizar:

    GOOS– Sistema operativo de destino GOARCH– Plataforma de destino
    android arm
    darwin 386
    darwin amd64
    darwin arm
    darwin arm64
    dragonfly amd64
    freebsd 386
    freebsd amd64
    freebsd arm
    linux 386
    linux amd64
    linux arm
    linux arm64
    linux ppc64
    linux ppc64le
    linux mips
    linux mipsle
    linux mips64
    linux mips64le
    netbsd 386
    netbsd amd64
    netbsd arm
    openbsd 386
    openbsd amd64
    openbsd arm
    plan9 386
    plan9 amd64
    solaris amd64
    windows 386
    windows amd64

    Advertencia: la compilación cruzada de ejecutables para Android requiere el NDK de Android y alguna configuración adicional que está más allá del alcance de este tutorial.

    Usando los valores de la tabla, podemos construir Caddy para Windows de 64 bits de esta manera:

    1. env GOOS=windows GOARCH=amd64 go build github.com/mholt/caddy/caddy

    Una vez más, no hay salida que indique que la operación se ha realizado correctamente. El ejecutable se creará en el directorio actual, utilizando el nombre del paquete como nombre. Sin embargo, dado que creamos este ejecutable para Windows, el nombre termina con el sufijo .exe.

    Debes tener caddy.exeel archivo en tu directorio actual, lo cual puedes verificar con el lscomando.

    1. ls caddy.exe

    Verás el caddy.exearchivo listado en la salida:

    Outputcaddy.exe

    Nota : Puede utilizar la -obandera para cambiar el nombre del ejecutable o colocarlo en una ubicación diferente. Sin embargo, al crear un ejecutable para Windows y proporcionar un nombre diferente, asegúrese de especificar explícitamente el .exesufijo al configurar el nombre del ejecutable.

    Veamos cómo programar este proceso para facilitar el lanzamiento de software para múltiples entornos de destino.

    Paso 5: Creación de un script para automatizar la compilación cruzada

    El proceso de creación de ejecutables para muchas plataformas puede ser un poco tedioso, pero podemos crear un script para facilitar las cosas.

    El script tomará la ruta de importación del paquete como argumento, iterará a través de una lista predefinida de pares de sistemas operativos y plataformas, y generará un ejecutable para cada par, colocando la salida en el directorio actual. Cada ejecutable se nombrará con el nombre del paquete, seguido de la plataforma y la arquitectura de destino, en el formato package-OS-architecture. Este será un script universal que puede usar en cualquier proyecto.

    Cambie a su directorio de inicio y cree un nuevo archivo llamado go-executable-build.bashen su editor de texto:

    1. cd ~
    2. nano go-executable-build.bash

    Comenzaremos nuestro script con una línea shebang . Esta línea define qué intérprete analizará este script cuando se ejecute como ejecutable. Agregue la siguiente línea para especificar quién bashdebe ejecutar este script:

    go-ejecutable-build.bash

    #!/usr/bin/env bash

    Queremos tomar la ruta de importación del paquete como argumento de la línea de comandos. Para ello, utilizaremos variable, donde es un número no negativo. La variable contiene el nombre del script que ejecutaste, mientras que y mayor contendrán argumentos proporcionados por el usuario. Agrega esta línea al script, que tomará el primer argumento de la línea de comandos y lo almacenará en una variable llamada :$nn$0$1package

    go-ejecutable-build.bash

    ...package=$1

    A continuación, asegúrese de que el usuario haya proporcionado este valor. Si no se proporciona el valor, salga del script con un mensaje que explica cómo utilizar el script:

    go-ejecutable-build.bash

    ...if [[ -z "$package" ]]; then  echo "usage: $0 package-name"  exit 1fi

    Esta ifdeclaración verifica el valor de la $packagevariable. Si no está configurada, usamos echopara imprimir el uso correcto y luego terminamos el script usando exit. exittoma un valor de retorno como argumento, que debe ser 0para ejecuciones exitosas y cualquier valor distinto de cero para ejecuciones fallidas. Usamos 1aquí ya que el script no tuvo éxito.

    Nota : Si desea que este script funcione con un paquete predefinido, cambie la packagevariable para que apunte a esa ruta de importación:

    go-ejecutable-build.bash

    ...package="github.com/user/hello"

    A continuación, queremos extraer el nombre del paquete de la ruta. La ruta de importación del paquete está delimitada por /caracteres, y el nombre del paquete se encuentra al final de la ruta. Primero, dividiremos la ruta de importación del paquete en una matriz, utilizando el /como delimitador:

    go-ejecutable-build.bash

    package_split=(${package//// })

    El nombre del paquete debe ser el último elemento de esta nueva $package_splitmatriz. En Bash, puedes usar un índice de matriz negativo para acceder a una matriz desde el final en lugar de desde el principio. Agrega esta línea para obtener el nombre del paquete de la matriz y almacenarlo en una variable llamada package_name:

    go-ejecutable-build.bash

    ...package_name=${package_split[-1]}

    Now, you’ll need to decide what platforms and architectures you want build executables for. In this tutorial, we’ll build executables for Windows 64-bit, Windows 32-bit, and 64-bit macOS. We will put these targets in an array with the format OS/Platform, so we can split each pair into GOOS and GOARCH variables using the same method we used to extract the package name from the path. Add the platforms to the script:

    go-executable-build.bash

    ...platforms=("windows/amd64" "windows/386" "darwin/amd64")

    Next, we’ll iterate through the array of platforms, split each platform entry into values for the GOOS and GOARCH environment variables, and use those to build the executable. We can do that with the following for loop:

    go-executable-build.bash

    ...for platform in "${platforms[@]}"do...done

    The platform variable will contain an entry from the platforms array in each iteration. We need to split platform to two variables – GOOS and GOARCH. Add the following lines to the for loop:

    go-executable-build.bash

    for platform in "${platforms[@]}"doplatform_split=(${platform//// })GOOS=${platform_split[0]}GOARCH=${platform_split[1]}done

    Next, we will generate the executable’s name by combining the package name with the OS and architecture. When we’re building for Windows, we also need to add the .exe suffix to the filename. Add this code to the for loop:

    go-executable-build.bash

    for platform in "${platforms[@]}"doplatform_split=(${platform//// })GOOS=${platform_split[0]}GOARCH=${platform_split[1]}    output_name=$package_name'-'$GOOS'-'$GOARCHif [ $GOOS = "windows" ]; thenoutput_name+='.exe'fidone

    With the variables set, we use go build to create the executable. Add this line to the body of the for loop, right above the done keyword:

    go-executable-build.bash

    ...if [ $GOOS = "windows" ]; thenoutput_name+='.exe'fienv GOOS=$GOOS GOARCH=$GOARCH go build -o $output_name $packagedone

    Finally, we should check to see if there were errors building the executable. For example, we might run into an error if we try to build a package we don’t have sources for. We can check the go build command’s return code for a non-zero value. The variable $? contains the return code from a previous command’s execution. If go build returns anything other than 0, there was a problem, and we’ll want to exit the script. Add this code to the for loop, after the go build command and above the done keyword.

    go-executable-build.bash

    ...env GOOS=$GOOS GOARCH=$GOARCH go build -o $output_name $packageif [ $? -ne 0 ]; then   echo 'An error has occurred! Aborting the script execution...'exit 1fi

    With that, we now have a script that will build multiple executables from our Go package. Here’s the completed script:

    go-executable-build.bash

    #!/usr/bin/env bashpackage=$1if [[ -z "$package" ]]; then  echo "usage: $0 package-name"  exit 1fipackage_split=(${package//// })package_name=${package_split[-1]}platforms=("windows/amd64" "windows/386" "darwin/amd64")for platform in "${platforms[@]}"doplatform_split=(${platform//// })GOOS=${platform_split[0]}GOARCH=${platform_split[1]}output_name=$package_name'-'$GOOS'-'$GOARCHif [ $GOOS = "windows" ]; thenoutput_name+='.exe'fienv GOOS=$GOOS GOARCH=$GOARCH go build -o $output_name $packageif [ $? -ne 0 ]; then   echo 'An error has occurred! Aborting the script execution...'exit 1fidone

    Verify that your file matches the preceding code. Then save the file and exit the editor.

    Before we can use the script, we have to make it executable with the chmod command:

    1. chmod +x go-executable-build.bash

    Finally, test the script by building executables for Caddy:

    1. ./go-executable-build.bash github.com/mholt/caddy/caddy

    If everything goes well, you should have executables in your current directory. No output indicates successful script execution. You can verify are executables created using ls command:

    1. ls caddy*

    You should see all three versions:

    Example ls outputcaddy-darwin-amd64 caddy-windows-386.exe caddy-windows-amd64.exe

    To change the target platforms, just change the platforms variable in your script.

    Conclusion

    In this tutorial, you’ve learned how to use Go’s tooling to obtain packages from version control systems, as well as build and cross-compile executables for different platforms.

    You also created a script that you can use to cross-compile a single package for many platforms.

    To make sure your application works correctly, you can take a look at testing and continuous integration like Travis-CI and AppVeyor for testing on Windows.

    If you are interested in Caddy and how to use it, take a look at How to Host a Website with Caddy on Ubuntu 16.04.

    SUSCRÍBETE A NUESTRO BOLETÍN 
    No te pierdas de nuestro contenido ni de ninguna de nuestras guías para que puedas avanzar en los juegos que más te gustan.

    Deja una respuesta

    Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

    Subir

    Este sitio web utiliza cookies para mejorar tu experiencia mientras navegas por él. Este sitio web utiliza cookies para mejorar tu experiencia de usuario. Al continuar navegando, aceptas su uso. Mas informacion