
Un código, dos sistemas
Go: escribe una vez, compila en todas partes
Introducción
Construí un IDE en Go sobre Windows 11, copié el mismo código a Ubuntu, lo recompilé y funcionó exactamente igual. Sin reescribir nada, sin capas de compatibilidad, sin instalar un runtime aparte.
Eso que en otros lenguajes suele ser un proyecto en sí mismo, en Go es un comando. En este artículo cuento por qué pasa, cómo lo hice y qué detalles conviene cuidar para que te pase lo mismo.
Por qué Go lo hace fácil
Go compila a código nativo y empaqueta todo en un solo ejecutable. No hay máquina virtual que instalar como en Java, ni intérprete como en Python o Node.
Binario autocontenido: el runtime de Go (recolector de basura, planificador de goroutines) va dentro del ejecutable. Copias el archivo y corre.
Librería estándar portable:
os,path/filepath,net,ioy compañía abstraen las diferencias entre sistemas. El mismoos.ReadFilefunciona en Windows, Linux y macOS.Compilación cruzada nativa: el compilador ya trae soporte para decenas de combinaciones de sistema operativo y arquitectura. No necesitas toolchains extra mientras tu código sea Go puro.
Compilación rápida: recompilar un proyecto mediano toma segundos, así que probar en otra plataforma no da pereza.
Mi experiencia: del IDE en Windows 11 a Ubuntu
El IDE lo desarrollé y probé completo en Windows 11: editor, manejo de archivos, ejecución de procesos y la interfaz. Cuando lo tuve estable, quise ver qué pasaba en Linux.
Cloné el repositorio en Ubuntu.
Instalé Go con la misma versión que usaba en Windows.
Ejecuté
go build.
El resultado fue un ejecutable que hacía exactamente lo mismo que en Windows. Mismas funciones, mismo comportamiento, cero cambios en el código.
La clave fue haber escrito el código "pensando en Go" y no en Windows: usar la librería estándar para rutas y archivos, y no depender de comandos propios del sistema.
Cómo compilar para cada plataforma
En la máquina de destino basta con go build. Pero Go también permite generar el ejecutable de otro sistema sin salir del tuyo, usando dos variables de entorno: GOOS (sistema operativo) y GOARCH (arquitectura).
Desde Linux o macOS:
# Linux 64 bits
GOOS=linux GOARCH=amd64 go build -o miide-linux
# Windows 64 bits
GOOS=windows GOARCH=amd64 go build -o miide.exe
# macOS con Apple Silicon
GOOS=darwin GOARCH=arm64 go build -o miide-mac
Desde Windows con PowerShell:
$env:GOOS="linux"; $env:GOARCH="amd64"; go build -o miide-linux
Para ver todas las combinaciones soportadas:
go tool dist list
| Destino | GOOS | GOARCH |
|---|---|---|
| Windows 64 bits | windows | amd64 |
| Linux 64 bits | linux | amd64 |
| Linux ARM (Raspberry Pi 4/5) | linux | arm64 |
| macOS Intel | darwin | amd64 |
| macOS Apple Silicon | darwin | arm64 |
Detalles a cuidar
La portabilidad de Go es real, pero se puede romper con malos hábitos. Esto es lo que más conviene vigilar:
Rutas: nunca concatenes con
\o/a mano. Usafilepath.Joinyos.UserHomeDir().
// Mal: solo funciona en Windows
ruta := "C:\\Users\\" + usuario + "\\proyectos"
// Bien: funciona en cualquier sistema
home, _ := os.UserHomeDir()
ruta := filepath.Join(home, "proyectos")
Comandos externos: si lanzas procesos con
os/exec, recuerda quecmd.exeno existe en Linux nibashen un Windows limpio. Detecta el sistema conruntime.GOOS.CGO: si una dependencia usa C (muchas librerías de interfaz gráfica, SQLite clásico), la compilación cruzada deja de ser trivial. Lo más simple es compilar en la máquina destino, como hice con el IDE, o elegir alternativas en Go puro.
Interfaz gráfica: frameworks como Fyne o Wails son multiplataforma, pero en Linux pueden pedir paquetes del sistema (por ejemplo, librerías de desarrollo de OpenGL o GTK) antes del primer
go build.Build tags: cuando sí necesitas código distinto por sistema, sepáralo en archivos con sufijo (
terminal_windows.go,terminal_linux.go). Go elige el correcto al compilar, sinifrepartidos por todo el proyecto.Saltos de línea: Windows usa
\r\ny Linux\n. En un editor esto importa al leer y guardar archivos; normalízalo en un solo lugar.
Conclusión
Go cumple lo que otros lenguajes prometen: escribes una vez y compilas donde lo necesites. Mi IDE pasó de Windows 11 a Ubuntu sin tocar una línea.
Si estás eligiendo lenguaje para una herramienta de escritorio, una CLI o un servicio que debe correr en varios sistemas, Go merece estar en la lista. Usa la librería estándar, evita supuestos del sistema operativo y deja que el compilador haga el resto.

