# FYI: Cosmopolitan for e.g. Julia portability (potentially)

**URL:** <https://discourse.julialang.org/t/fyi-cosmopolitan-for-e-g-julia-portability-potentially/61488>\
**Category:** Offtopic\
**Created:** [May 20, 2021, 1:13am UTC](https://discourse.julialang.org/t/fyi-cosmopolitan-for-e-g-julia-portability-potentially/61488 "2021-05-20T01:13:22Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)\
**Post date:** [May 20, 2021, 1:13am UTC](https://discourse.julialang.org/t/fyi-cosmopolitan-for-e-g-julia-portability-potentially/61488/1 "2021-05-20T01:13:22Z")

</div>

> **[GitHub - jart/cosmopolitan: build-once run-anywhere c library](https://github.com/jart/cosmopolitan)**
>
> build-once run-anywhere c library. Contribute to jart/cosmopolitan development by creating an account on GitHub.

> reconfigures stock GCC and Clang to output a POSIX-approved polyglot format that runs natively on Linux + Mac + Windows + FreeBSD + OpenBSD + NetBSD + BIOS with the best possible performance and the tiniest footprint imaginable.

See at: [Cosmopolitan Libc: build-anywhere run-anywhere C library](https://justine.lol/cosmopolitan/index.html)

> Cosmopolitan makes C a build-once run-anywhere language, similar to Java, except it doesn’t require interpreters or virtual machines be installed beforehand.  
> […]  
> For details on how this works, please read the [αcτµαlly pδrταblε εxεcµταblε](https://justine.lol/ape.html) blog post.

I proposed the rather cool [αcτµαlly pδrταblε εxεcµταblε](https://justine.lol/ape.html) way back for PackageCompiler.jl, but then the issue was closed (I do not recall if Cosmopolitan existed then and what I see now claimed), and possibly Cosmopolitan, building on it, makes portable Julia now more viable if anyone feels like trying a hack to make it work.

> ### Platform Agnostic C / C++ / FORTRAN Tooling
> 
> Who could have predicted that cross-platform native builds would be this easy? As it turns out, they’re surprisingly cheap too.

Julia could be the first portable language/binary that includes fast JIT of native code.

I’m thinking of the showstoppers, Julia is implemented by several languages, C, C++ (not STL for itself? while “_LLVM_ makes heavy use of the C++ Standard Template Library ( _STL_ )” and others?), FemtoLisp (should probably work) and Fortran.

This wouldn’t make Julia fully portable, to e.g. ARM and POWER, but I can live with that. 🙂 And it might even be possible ARM according to the docs; or MacOS ARM emulation could work, but Julia itself could generate ARM code…?

Also Linux, means traditional ELF binaries, doesn’t imply would work on Android. That would be cool, if you first install Ubuntu on Android, which already can run Julia, potentially such (ARM) Julia build could work?

At some point there was unofficial Julia-lite, without OpenBLAS if it would help (there are also some interesting (partial) Julia replacements or also system OpenBLAS could be used), similar could be done for problematic dependencies, e.g. using Fortran, and still be useful.

It’s a bit unclear (since issue open), but it seems Python 2.7 already works this way (and other languages close, e.g. PHP):

> <https://github.com/jart/cosmopolitan/issues/141>
>
> ~~https://github.com/ahgamut/python27~~  
> https://github.com/ahgamut/cpython/tr…ee/cosmo\_py27
> 
> The \`assert\` macro needs to be changed in \`cosmopolitan.h\` to enable compilation (see #138). 
> Afterwards, just clone the repo and run \`superconfigure\`.  
> 
> Python 2.7.18 compiled seamlessly once I figured out how \`autoconf\` worked, and what flags were being fed to the source files when running \`make\`. I'm pretty sure we can compile any C-based extensions into \`python.exe\` -- they just need to compiled/linked with Cosmopolitan, with necessary glue code added to the Python source. For example, I was able to compile \[SQLite\](https://github.com/sqlite/sqlite) into \`python.exe\` to enable the internal \`\_sqlite\` module.
> 
> The compiled APE is about 4.1MB with \`MODE=tiny\` (without any of the standard modules, the interpreter alone is around 1.6MB). Most of the modules in the stdlib compile without error. The \`\_socket\`module (required for Python's simple HTTP server) doesn't compile, as it requires the structs from \`netdb.h\`.
> 
> On Windows, the APE exits immediately because the intertpreter is unable to find the platform-specific files.
> \`Module/getpath.c\` and \`Lib/site.py\` in the Python source try to use absolute paths from the prefixes provided during compilation; Editing those files to search the right locations (possibly with some \`zipos\` magic) ought to fix this.

and:

> **[GitHub - jart/sectorlisp: Bootstrapping LISP in a Boot Sector](https://github.com/jart/sectorlisp)**
>
> Bootstrapping LISP in a Boot Sector. Contribute to jart/sectorlisp development by creating an account on GitHub.

> <https://github.com/jart/cosmopolitan/issues/27#issuecomment-755730818>
>
> First of all, great work hacking your way to platform independence!
> 
> Been just… wondering if anyone made any attempts to use it in conjunction with the c++ standard library and if so, what does work and what doesn't ? - I'd expect that the standard library depends on some platform specific code, however it would be great if I could get started somewhere so I can start refactoring those bits. 
> 
> I would love to package cosmopolitan for https://github.com/loopperfect/buckaroo or even built a beginner friendly SDK around this library.
> 
> My naive attempt to use cosmopolitan.h in a c++ project failed with a couple errors:
> 
> \`\`\`
> clang++ -std=c++20 \\
> -I/usr/include/c++/10 \\
> -I/usr/include/x86\_64-linux-gnu/c++/10/ \\
> -I/usr/include/x86\_64-linux-gnu/ \\
> -I/usr/include \\
> -Io\\
> -g -O -static -fno-pie -mno-red-zone -nostdlib -nostdinc -U\_\_cplusplus -o hello.com main.cpp \\
> -Wl,--oformat=binary -Wl,--gc-sections -Wl,-z,max-page-size=0x1000 -fuse-ld=bfd \\
> -Wl,-T,o/ape.lds -include o/cosmopolitan.h o/libc/crt/crt.o o/ape/ape.o o/cosmopolitan.a
> \`\`\`
> 
> \`\`\`
> // hello.cpp
> \#include\<cosmopolitan.h\>
> \#include\<vector\>
> 
> int main() {
> return 0;
> }
> \`\`\`
> 
> errors:
> \`\`\`bash
> In file included from \<built-in\>:1:
> ./o/cosmopolitan.h:284:24: error: cannot combine with previous 'int' declaration specifier
> typedef \_\_WCHAR\_TYPE\_\_ wchar\_t;
> ^
> ./o/cosmopolitan.h:284:1: warning: typedef requires a name \[-Wmissing-declarations\]
> typedef \_\_WCHAR\_TYPE\_\_ wchar\_t;
> ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> ./o/cosmopolitan.h:285:9: error: 'char16\_t' cannot be signed or unsigned
> typedef \_\_CHAR16\_TYPE\_\_ char16\_t;
> ^
> \<built-in\>:157:25: note: expanded from here
> \#define \_\_CHAR16\_TYPE\_\_ unsigned short
> ^
> In file included from \<built-in\>:1:
> ./o/cosmopolitan.h:285:9: error: 'short char16\_t' is invalid
> \<built-in\>:157:34: note: expanded from here
> \#define \_\_CHAR16\_TYPE\_\_ unsigned short
> ^
> In file included from \<built-in\>:1:
> ./o/cosmopolitan.h:285:1: warning: typedef requires a name \[-Wmissing-declarations\]
> typedef \_\_CHAR16\_TYPE\_\_ char16\_t;
> ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> ./o/cosmopolitan.h:286:25: error: cannot combine with previous 'int' declaration specifier
> typedef \_\_CHAR32\_TYPE\_\_ char32\_t;
> ^
> ./o/cosmopolitan.h:286:1: warning: typedef requires a name \[-Wmissing-declarations\]
> typedef \_\_CHAR32\_TYPE\_\_ char32\_t;
> ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> ./o/cosmopolitan.h:7712:35: error: unknown type name 'int128\_t'
> int sleb128(const void \*, size\_t, int128\_t);
> ^
> ./o/cosmopolitan.h:7713:37: error: unknown type name 'int128\_t'
> int unsleb128(const void \*, size\_t, int128\_t \*);
> ^
> ./o/cosmopolitan.h:21493:16: error: unknown type name 'jmp\_buf'
> void gclongjmp(jmp\_buf, int) nothrow wontreturn paramsnonnull();
> ^
> ./o/cosmopolitan.h:21525:3: error: unknown type name 'jmp\_buf'
> jmp\_buf jb;
> ^
> In file included from main.cpp:2:
> In file included from /usr/include/c++/10/vector:60:
> In file included from /usr/include/c++/10/bits/stl\_algobase.h:60:
> /usr/include/c++/10/bits/functexcept.h:44:1: error: unknown type name '\_GLIBCXX\_BEGIN\_NAMESPACE\_VERSION'
> \_GLIBCXX\_BEGIN\_NAMESPACE\_VERSION
> ^
> /usr/include/c++/10/bits/functexcept.h:112:1: error: unknown type name '\_GLIBCXX\_END\_NAMESPACE\_VERSION'
> \_GLIBCXX\_END\_NAMESPACE\_VERSION
> ^
> /usr/include/c++/10/bits/functexcept.h:113:1: error: expected unqualified-id
> } // namespace
> ^
> In file included from main.cpp:2:
> In file included from /usr/include/c++/10/vector:60:
> In file included from /usr/include/c++/10/bits/stl\_algobase.h:61:
> /usr/include/c++/10/bits/cpp\_type\_traits.h:71:1: error: unknown type name '\_GLIBCXX\_BEGIN\_NAMESPACE\_VERSION'
> \_GLIBCXX\_BEGIN\_NAMESPACE\_VERSION
> ^
> /usr/include/c++/10/bits/cpp\_type\_traits.h:214:12: error: redefinition of '\_\_is\_integer\<int\>'
> struct \_\_is\_integer\<int\>
> ^ ~~~~~~~~~~~~~~~~
> /usr/include/c++/10/bits/cpp\_type\_traits.h:138:12: note: previous definition is here
> struct \_\_is\_integer\<bool\>
> ^
> /usr/include/c++/10/bits/cpp\_type\_traits.h:542:5: error: unknown type name '\_GLIBCXX20\_CONSTEXPR'
> \_GLIBCXX20\_CONSTEXPR
> ^
> /usr/include/c++/10/bits/cpp\_type\_traits.h:543:21: error: expected ';' at end of declaration
> inline \_Iterator
> ^
> /usr/include/c++/10/bits/cpp\_type\_traits.h:544:18: error: unknown type name '\_Iterator'
> \_\_miter\_base(\_Iterator \_\_it)
> ^
> /usr/include/c++/10/bits/cpp\_type\_traits.h:544:5: error: C++ requires a type specifier for all declarations
> \_\_miter\_base(\_Iterator \_\_it)
> ^
> /usr/include/c++/10/bits/cpp\_type\_traits.h:547:1: error: unknown type name '\_GLIBCXX\_END\_NAMESPACE\_VERSION'
> \_GLIBCXX\_END\_NAMESPACE\_VERSION
> ^
> /usr/include/c++/10/bits/cpp\_type\_traits.h:548:1: error: expected unqualified-id
> } // namespace
> ^
> fatal error: too many errors emitted, stopping now \[-ferror-limit=\]
> 4 warnings and 20 errors generated.
> 
> \`\`

> Cosmopolitan works great with C++ but very little effort has been made to integrate it with an existing STL.

STL will likely be a showstopper, unless we could use system LLVM and it’s the only STL using code? At one point there was Cfront “C with classes” (later renamed C++) to C transpiler, I guess nothing similar exists anymore…

---

<div class="post-metadata">

**Author:** ![ImreSamu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/imresamu/32/20677_2.png) [@ImreSamu](https://discourse.julialang.org/u/ImreSamu)\
**Post date:** [May 20, 2021, 10:08pm UTC](https://discourse.julialang.org/t/fyi-cosmopolitan-for-e-g-julia-portability-potentially/61488/2 "2021-05-20T22:08:11Z")

</div>

imho: only for the simple code …

For a complex codebase: it is not so easy to implement.  
Now we have a

- “Linux (Glibc)” and a “Linux (Musl)” based Julia \* ( 32bit / 64 bit )
- Windows (7+ / 10+ ) \* ( 32bit / 64bit )
- …

> [@Palli](#):
>
> with the best possible performance and the tiniest footprint imaginable.

imho: the X86 - there is a new 4 **micro-architecture feature level** …  
( IMHO: not the tiniest footprint including all )

```julia
> x86-64: CMOV, CMPXCHG8B, FPU, FXSR, MMX, FXSR, SCE, SSE, SSE2
> x86-64-v2: (close to Nehalem) CMPXCHG16B, LAHF-SAHF, POPCNT, SSE3, SSE4.1, SSE4.2, SSSE3
> x86-64-v3: (close to Haswell) AVX, AVX2, BMI1, BMI2, F16C, FMA, LZCNT, MOVBE, XSAVE
> x86-64-v4: AVX512F, AVX512BW, AVX512CD, AVX512DQ, AVX512VL

```

- [GCC 11's x86-64 Microarchitecture Feature Levels Are Ready To Roll - Phoronix](https://www.phoronix.com/scan.php?page=news_item&px=GCC-11-x86-64-Feature-Levels)

---

<div class="post-metadata">

**Author:** ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)\
**Post date:** [May 20, 2021, 10:43pm UTC](https://discourse.julialang.org/t/fyi-cosmopolitan-for-e-g-julia-portability-potentially/61488/3 "2021-05-20T22:43:21Z")

</div>

Thanks for the link, I’m aware of feature levels, but wasn’t familiar with these exact terms: “x86-64-v2, x86-64-v3, and x86-64-v4”.

That doesn’t seem to be any problem. There’s not a different Julia binary (per OS) for those anyway. With a portable Julia binary across OSes, nothing changes. It (the core, not dependencies) can just target the most conservative x86-64 (and just ignore 32-bit, not a huge concern for me). At runtime when you invoke the backend, LLVM, it will generate appropriate code, for e.g. latest, even if LLVM itself is compiled for oldest. And if you want you can override just as you currently can.

You are quoting me, quoting the project “the tiniest footprint”. Yes, Julia will not be small, or smaller. That refers to the Cosmopolitan. Getting something like this working with Julia would be interesting and a first step, then making smaller might be a later step.

---

<div class="post-metadata">

**Author:** ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)\
**Post date:** [May 20, 2021, 10:48pm UTC](https://discourse.julialang.org/t/fyi-cosmopolitan-for-e-g-julia-portability-potentially/61488/4 "2021-05-20T22:48:04Z")

</div>

> [@ImreSamu](#):
>
> “Linux (Musl)” based

Yes, seems not supported. You can still just use specific Julia target that or some platform Cosmopolitan doesn’t support. Musl, is not needed for Linux except for some very obscure distros like Alpine. Getting Windows, Mac and Linux most use would be awesome, and I wouldn’t rule out Musl could be supported later.

---

<div class="post-metadata">

**Author:** ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)\
**Post date:** [May 20, 2021, 11:10pm UTC](https://discourse.julialang.org/t/fyi-cosmopolitan-for-e-g-julia-portability-potentially/61488/5 "2021-05-20T23:10:17Z")

</div>

The julia binary is actually only 12320 bytes. What’s taking the most space are dependencies:

-rwxr-xr-x 1 pharaldsson\_sym pharaldsson\_sym 184609760 mar 25 02:40 sys.so  
-rwxr-xr-x 1 pharaldsson\_sym pharaldsson\_sym 71850032 mar 25 02:30 libLLVM-11jl.so  
-rwxr-xr-x 1 pharaldsson\_sym pharaldsson\_sym 39025344 mar 25 02:41 libjulia-internal.so.1.6  
-rwxr-xr-x 1 pharaldsson\_sym pharaldsson\_sym 30415776 mar 25 02:30 libopenblas64\_.0.3.10.so  
-rwxr-xr-x 1 pharaldsson\_sym pharaldsson\_sym 22521088 mar 25 02:30 libstdc++.so.6.0.26  
-rwxr-xr-x 1 pharaldsson\_sym pharaldsson\_sym 7382888 mar 25 02:30 libgfortran.so.4.0.0  
[…]

sys.so is the sysimage, and while it’s e.g. sys.dll on Windows, it’s not clear to me Cosmopolitan can’t work for such (e.g. could it be statically linked?). Worst case (for proof-of-concept), you could duplicate all dependencies, have .so and .dll, doubling in size… or tripling for MacOS too. Doesn’t sound nice, but you could also have one preferred platform, say Windows (as it’s very popular) with its DLLs, and dynamically download .so etc. on first use if you happen to run on Linux (or discover preinstalled Julia’s .so files). This likely solved potential STL issues, as they only cover libLLVM-11jl.so (or maybe more), but not the main julia or julia.exe?

---

<div class="post-metadata">

**Author:** ![ImreSamu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/imresamu/32/20677_2.png) [@ImreSamu](https://discourse.julialang.org/u/ImreSamu)\
**Post date:** [May 20, 2021, 11:12pm UTC](https://discourse.julialang.org/t/fyi-cosmopolitan-for-e-g-julia-portability-potentially/61488/6 "2021-05-20T23:12:53Z")

</div>

> [@Palli](#):
>
> very obscure distros like Alpine.

imho: this is a default minimal Docker linux for testing .  
and the docker official minimal images - based this linux.

for example postgres … has a debian(glicbc) + alpine(musl) version

> <https://github.com/docker-library/postgres/tree/master/13>
>
> //github.com/docker-library/postgres/tree/master/13

for julia - it has a minimal disk savings

```julia
julia 1.6 22b56ebea464 8 days ago 486MB
julia 1.6-alpine 89e8f10e3115 3 weeks ago 408MB

```

---

<div class="post-metadata">

**Author:** ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)\
**Post date:** [May 20, 2021, 11:29pm UTC](https://discourse.julialang.org/t/fyi-cosmopolitan-for-e-g-julia-portability-potentially/61488/7 "2021-05-20T23:29:35Z")

</div>

I’m mainly thinking of portable Julia for non-server use, to eventually support apps for end-users, and wouldn’t you then not be unlikely to use Docker?

I’ve never used it, nor had the need, I at least think it’s mainly for servers, and then you likely want to support only one infrastructure (or you can at least choose).

Linux is most used anyway for servers (even most used on Microsoft’s Azure), and I’m not too concerned about server use (current Julia binary options wouldn’t or needn’t go away). Even for Windows servers, Docker “runs on WSL 2”, so you would still use the same Julia Linux binary.
