Live data from Hacker News

Show HN: A 166 KB file for cross compiling glibc for any version, any target

github.com

21–30 of 34 posts

Re: Show HN: A 166 KB file for cross compiling glibc for any version, any target

#21

Earlier quoted context omitted.

Can I use this incredible feature with other toolchains, or existing artifacts that have a glibc dependency? Say if I am using a language/toolchain which pulls in a C/C++ compiler, are you able to substitute "zig cc" there and explicitly cross-compile to a different GLIBC version?

Yep! Example: https://dev.to/kristoff/zig-makes-go-cross-compilation-just-...

Incredible, thanks a ton for doing this work!

Re: Show HN: A 166 KB file for cross compiling glibc for any version, any target

#22
post #6

What does "targeting any glibc version" mean? Is it the solution to the problem where you have to compile on an ancient Debian version to produce a binary that works on all Linux distributions because it otherwise links to too-new symbol versions in glibc? Can I use that outside of Zig, for compiling C++ code?

The correct solution for that is to just cross compile to whatever older CPU you want and target a sysroot that has a base image of whatever older glibc you wanted: you don't need to actually compile on the older device...

Example: https://github.com/ClickHouse-Extras/sysroot

Re: Show HN: A 166 KB file for cross compiling glibc for any version, any target

#24

How does one go about testing against arbitrary versions of glibc?

I'd say that the probable scenario here is that you're targeting some specific LTS Linux distros, and you want to be able to run on the specific version of glibc on those distros. Normally, binary compatibility goes forwards but not backwards. What this tool lets you to is target an old glibc without needing to install that specific glibc.

Re: Show HN: A 166 KB file for cross compiling glibc for any version, any target

#25

Something is very wrong with the state of C/C++ compiler development that it takes a different language to come in and make these obviously useful convenience features. Why are GCC and Clang not doing this?

This is not an issue with GCC or Clang as far as I'm aware, but with glibc and the way it handles backwards compatibility.

Versioned symbols get added when a function or object breaks binary compatibility. You keep around the old version, and compile against the new version. This might be something simple like a struct layout change, or a change in the size of an array. Both versions have the same name. When you compile, you'll get an unversioned symbol reference. When you link, that will get resolved to whatever the latest version is.

Windows handles this by giving a new name to new symbols. For example, MoveFile(), MoveFileA(), MoveFileW(), MoveFileExA(), MoveFileExW(). You get the correct symbol when you compile, either by calling the correct function directly, or by referring to it by macro (MoveFileEx is a macro for MoveFileExA or MoveFileExW). Newer versions of Windows also make you embed the GUID of the versions of Windows you support in your application manifest, and Windows will run your application in a compatibility environment (at runtime) matching the latest available version you specify.

On macOS, similarly, it uses the preprocessor, but it's a bit different and macOS also supports something called "weak linking" (not the same thing as weak linking in GNU Binutils / ELF). Weak linking allows you to link against an old version of a library, but use a symbol from a newer version... if the symbol is not available, it is NULL. This is done with the preprocessor and the linker in tandem... there's a preprocessor macro which specifies which minimum&maximum version of macOS (or iOS, etc) you target, and that affects which symbols are declared as being weakly linked.

The long and the short of it... you can use the latest macOS SDK to make binaries compatible with old versions of macOS, and same for Windows, but glibc maintainers have not made this possible for glibc.

Re: Show HN: A 166 KB file for cross compiling glibc for any version, any target

#26

What's the point in this? Surely you'll have more dependencies than glibc?

glibc is notoriously difficult to link against; most other typical libraries have simpler ABI.

This RH blog post is good intro on the topic: https://developers.redhat.com/blog/2019/08/01/how-the-gnu-c-...

Re: Show HN: A 166 KB file for cross compiling glibc for any version, any target

#27

How does one go about testing against arbitrary versions of glibc?

I'd say that the probable scenario here is that you're targeting some specific LTS Linux distros, and you want to be able to run on the specific version of glibc on those distros. Normally, binary compatibility goes forwards but not backwards. What this tool lets you to is target an old glibc without needing to install that specific glibc.

In my case, older versions of glibc (< 2.24) have a bug which prevents using posix_spawn. I'm not sure exactly which version of glibc has the fix. I would like to test against all glibc releases in turn, to identify the first in which posix_spawn is usable, but AFAICT there's no easy way to do that.

Re: Show HN: A 166 KB file for cross compiling glibc for any version, any target

#28

Earlier quoted context omitted.

I wish Rust used prefix &[]i32 for a slice, and [5][2]i32 for a 5x2 array. Instead it uses &[i32] for a slice, and [[i32; 2]; 5] for a 5x2 array. Reading types backwards is alive and well.

I prefer the unambiguous nesting of Rust's style. I can never remember the array shape when array bounds are listed in either prefix or postfix style. It's a tiny bit of extra typing that ensures that my understanding of the code is always 100% correct.

I find Rust's array style more confusing than prefix, since prefix matches the order you index into the arrays (arr: [5][2]i32 can be validly indexed as arr[<5][<2]), and Rust's style is written backwards from how you index the array. Can you clarify how you find Rust unambiguous?

Re: Show HN: A 166 KB file for cross compiling glibc for any version, any target

#29

Earlier quoted context omitted.

I prefer the unambiguous nesting of Rust's style. I can never remember the array shape when array bounds are listed in either prefix or postfix style. It's a tiny bit of extra typing that ensures that my understanding of the code is always 100% correct.

I find Rust's array style more confusing than prefix, since prefix matches the order you index into the arrays (arr: [5][2]i32 can be validly indexed as arr[<5][<2]), and Rust's style is written backwards from how you index the array. Can you clarify how you find Rust unambiguous?

It's just obvious to me that it works the correct way by way of elimination of alternative parsing. The example below can be unwrapped mentally and unambiguously as "an array of 5 items of (an array of 2 items of i32)". Indexing into the array is not backwards: the outer array is deref'd first, giving you one of those five items which has length two.

  fn main() {
    let mut a: [[i32; 2]; 5] = [[0,0],[0,0],[0,0],[0,0],[0,0]];
    println!("{:?}", a[0]);
  }
Note that the Rust array declarations are also homologous to other types in the ecosystem, such as nested Option types or nested collections (eg: Option> or List>).

Contrast w/the C version, where it's obvious to a skilled C programmer but you need to remember to read the bounds from right to left to determine the memory layout (ie: an array of 5 arrays of two elements each):

  int main() {
    int i[5][2] = {{1,2},{3,4}, /*...*/};
    printf("%ld\n", sizeof(i[0])/sizeof(int));
    return 0;
  }
In this case you are required to mentally combine the type on the left of the variable with the bounds on the right of the variable to parse a type declaration in your head that eventually looks like the Rust version:

  (int[2])[5]
I've been doing a lot of professional C work lately so it's currently "swapped in", but I find that any time I pick C up after spending time away I find it ambiguous and I have to reason through the ordering of the declarations.

Obviously this is all IMHO and YMMV, but this developer does find it significantly easier to unambiguously parse Rust types.

Re: Show HN: A 166 KB file for cross compiling glibc for any version, any target

#30

Earlier quoted context omitted.

I find Rust's array style more confusing than prefix, since prefix matches the order you index into the arrays (arr: [5][2]i32 can be validly indexed as arr[<5][<2]), and Rust's style is written backwards from how you index the array. Can you clarify how you find Rust unambiguous?

It's just obvious to me that it works the correct way by way of elimination of alternative parsing. The example below can be unwrapped mentally and unambiguously as "an array of 5 items of (an array of 2 items of i32)". Indexing into the array is not backwards: the outer array is deref'd first, giving you one of those five items which has length two. fn main() { let mut a: [[i32; 2]; 5] = [[0,0],[0,0],[0,0],[0,0],[0,…

[deleted]
Post reply on HN