¿Qué es SoLo y por qué resuelve un problema histórico de Linux?
Un binario completamente estático no necesita dependencias externas: un solo archivo, sin libc compartida, sin sorpresas al migrar entre distribuciones. La realidad se complica cuando ese programa requiere acceso a hardware gráfico. Los controladores Vulkan y OpenGL vienen del sistema como objetos compartidos compilados contra glibc, y un ejecutable vinculado con musl no puede cargarlos con un dlopen() convencional.
El proyecto SoLo —creado por pg83 y publicado bajo licencia MIT— elimina esa barrera. Su cargador permite que una aplicación estática cargue en tiempo de ejecución bibliotecas compartidas del sistema sin introducir una segunda libc en el proceso. Hasta ahora, las alternativas obligaban a empaquetar contenedores, AppImages o distribuciones completas dentro del software. SoLo hace lo opuesto: mantiene todo estático excepto el componente que genuinamente pertenece al host, su driver de hardware.
La prueba de concepto es concreta: un ejecutable estático carga el controlador Vulkan instalado en el equipo, ejecuta un shader de cómputo y escribe el resultado en un PNG. Funciona en GPUs AMD (radv, radeonsi), Intel, NVIDIA y Apple M1 bajo Asahi Linux.
👥 ¿Quieres ir más allá de la noticia?
En nuestra comunidad discutimos las tendencias, compartimos oportunidades y nos ayudamos entre emprendedores. Sin humo, solo acción.
👥 Unirme a la comunidadCómo funciona la arquitectura híbrida
SoLo implementa tres capas principales:
Cargador ELF propio. Un mapeador de segmentos ELF que camina DT_NEEDED, resuelve símbolos versionados, aplica reubicaciones x86-64 y aarch64, soporta ELF TLS, TLSDESC, IFUNCs, RELRO e inicializadores. Las dependencias que son DSOs se cargan recursivamente.
Puente de ABI glibc sobre musl. Las importaciones como malloc@GLIBC_2.2.5 se resuelven mediante adaptadores (glibc_shim.cpp) que apuntan al runtime musl existente. Si una función glibc no implementada se invoca, el sistema falla explícitamente indicando el símbolo exacto y su versión, en lugar de corromper silenciosamente el proceso.
API dlfcn. Una interfaz fuente compatible con dlopen()/dlsym() redirigida internamente a SoLo. El código existente no necesita modificaciones mayores.
Las características más relevantes para desarrolladores:
- Excepciones C++ cruzan ambos mundos. Un
throwen el mundo estático se desenrolla a través de frames compilados en glibc hacia uncatchde glibc, y viceversa. Hay una sola maquinaria de excepciones en el proceso. - Los cuatro modelos TLS sin wrappers. General-dynamic, local-dynamic, TLSDESC e initial-exec funcionan sin parcheo de código. Las variables initial-exec residen en un arena de 16 KiB dentro del TLS estático del ejecutable.
- Semánticas de enlace de
ld.so. Interposición global,RTLD_DEEPBIND,DT_SYMBOLIC, hash GNU y SysV, lazy PLT binding con registros de argumento preservados, ifuncs con hwcaps y/etc/ld.so.cache. - Introspección cruzada.
backtrace()recorre frames estáticos y glibc;dl_iterate_phdr,dladdr1y el facadelink_mappermiten que profilers y debuggers vean todas las imágenes.
Benchmark real: 2.100 objetos compartidos cargados en CI
El proyecto no se limita a demos. En cada commit, la integración continua carga los objetos compartidos de los 1.000 paquetes más instalados de Debian —aproximadamente 2.100 objetos— a través de SoLo, tanto en x86-64 como en aarch64.
Esto cubre las closures de dependencia reales de Mesa/Vulkan ICD. La carga es el piso, no la afirmación: las llamadas a símbolos aún no implementados abortan con un mensaje explícito, y el archivo dev/abi-demand.txt documenta el trabajo pendiente ordenado por demanda de instalación.
Comparativa con soluciones existentes
| Solución | Modelo | Limitación principal |
|---|---|---|
| gcompat | Preload de libgcompat.so |
Requiere paquete de compatibilidad del sistema; no funciona desde un proceso estático puro |
| Detour | Arranca ld-linux del sistema |
Introduce una segunda libc y estado TLS separado |
| Cosmopolitan Libc | Bootstrap del intérprete host | Mismo problema de doble libc |
| ClickHouse userspace loader | Mapea ELF pero no carga glibc | Propone bootstrapear ld.so del sistema (modelo Detour-like) |
| Flatpak / AppImage / containers | Empaqueta distribución completa | Archivos enormes, namespaces, extracción, debugging complejo |
| SoLo | ELF loader + puente ABI musl/glibc | Autocontenido; cero segundas libc; todo en un ejecutable |
Qué significa esto para tu startup
Si tu equipo despliega software en Linux —especialmente herramientas que requieren aceleración GPU, inferencia de IA o procesamiento gráfico— SoLo cambia las reglas de la distribución.
Acción 1: Evalúa si puedes eliminar contenedores de producción
Empaquetar una mini-distribución dentro de tu app (AppImage, Flatpak, Docker) aumenta el tamaño del artefacto entre 50x y 200x respecto a un binario estático. Para equipos que despliegan cientos de instancias, esos megabytes acumulados representan gigabytes innecesarios en registries, bandwidth de pull y superficie de ataque.
Si tu aplicación usa Vulkan, OpenGL o bibliotecas del sistema compatibles con SoLo, podrías reducir tu binary de ~500 MB a ~10-50 MB manteniendo funcionalidad gráfica completa.
Acción 2: Adopta musl para builds reproducibles
Alpine Linux usa musl por defecto y produce imágenes de contenedor de 5-10 MB frente a los 150-200 MB de Ubuntu/Debian. El obstáculo siempre fue la incompatibilidad con bibliotecas glibc. Con SoLo, ese obstáculo desaparece.
Para implementar:
- Compila tu aplicación con
-staticcontra musl (musl-gcco toolchain Alpine) - Vincula
libdlfcn.ade SoLo en tu build system - Los
dlopen()/dlsym()existentes se redirigen automáticamente - Verifica con
readelf -dW ./tu_binarioque no haya sección dinámica
Riesgos actuales a considerar
SoLo es funcional pero仍处于 fase experimental:
dlcloseno descarga imágenes del sistema. Es carga única.- Threads creados antes de un
dlopenven TLS zero-initialized para módulos cargados después. Debes cargar bibliotecas initial-exec antes de crear threads que las usen. - No hay soporte Windows/macOS. Solo Linux x86-64 y aarch64.
- ABI incompleto. Algunas funciones glibc aún fallan explícitamente. Revisa
dev/abi-demand.txtpara ver cobertura.
Fuentes
👥 ¿Quieres ir más allá de la noticia?
En nuestra comunidad discutimos las tendencias, compartimos oportunidades y nos ayudamos entre emprendedores. Sin humo, solo acción.
👥 Unirme a la comunidad













