Packages that build-depend on clang cannot be cross built because bin:clang from src:llvm-defaults depends on bin:clang-$MAJORVER which in turn depends on binutils. I used the attached patch to build llvm-toolchain-21 on arm64/s390x. Then I used the produced binary packages and successfully cross built (on amd64 for arm64/s390x) a bunch of packages that build-depend on clang, including the package I'm interested in, libobjc2 (not yet in Debian). We at the GNUstep team plan to package the GNUstep Objective-C runtime which was specifically written for Clang, and to provide dual runtime support on architectures where it will be available. We've spent considerable efforts to make the GNUstep stack cross-buildable during the trixie release cycle and it would be a pity to lose that feature. In case you consider applying the patch, the same should be done for other (relevant) llvm-toolchain-* packages. Thanks. P.S.: I see that some packages (e.g., filament) build-depend on clang:native, have a cross-specific make conditional in debian/rules and pass --target accordingly. This won't work in our case because bin:gnustep-make must depend on clang and the :native annotation can be used only for build-dependencies, IIRC.
Hi Yavor, Thanks for addressing the wider audience for review. I agree that there is a problem here, but the problem I see is a bit bigger than what you describe. Awesome. It's been a while that I ran into a GNUstep-related cross build failure. Now I understand why. It seems like your development packages declare a (runtime) dependency on a clang package. This is unusual at best. Normally, libraries do not depend on a toolchain. Can you give some background on why you think this is needed? You rightly indicate that your dependencies cannot use :native. Given your patch, I expect that what you end up with is a host architecture clang. This is not something you can actually run during a cross build. While your dependencies may become satisfiable, your build fails upon the first attempt to run the compiler. If it succeeds, you like installed qemu-user-binfmt on the machine, but you cannot rely on that. When clang links something, it runs /usr/bin/ld. This is not something that binutils-for-host provides. Your patch breaks the very simple use case of natively building and linking a hello world C source file using clang. I would hope that clang's autopkgtests readily fail once your patch is applied. Did you run them? I am not sure where we want to go from here. clang is a multi-target compiler, but it uses single-target binutils underneath. If you pass -target, it calls out to prefixed binutils, so technically speaking we'd need clang to depend on binutils-for-host for all architectures at the same time (or use binutils-multiarch). Having clang depend on binutils-multiarch may not be the worst of options. If we don't want that, we likely need a clang-for-host package that can forward the architecture constraint to the underlying binutils-for-host package. If you look at cross build systems involving gcc, many of them have learned that you can do a cross build by varying the compiler executable. This approach would technically also work for clang as it can parse its argv[0] and derive a target triplet from that. I'm not sure that this is how many projects use clang. The other way is passing a -target. How many projects reliably pass that? Which of these approaches do we want to label the preferred approach? I fear I'm adding more questions than answers. Helmut
Helmut Grohne wrote: I knew it was not that simple... There's still #1094879; simpleagenda.app has exactly the same problem. I recently fixed gnustep-sqlclient and edenmath.app (regression). The most important reason is that occasionally we have to enforce a non-default compiler for all GNUstep packages and it's easier to control it from one package instead of doing sourceful uploads for ~60 packages. TBH, the last time we did this was 15 years ago with GCC 4.7 and its libobjc transition. But it's likely to occur much more often with clang: libobjc2 supports only a subset of architectures where clang is available, because one function is implemented in assembly. Adding support for more architectures is "simply" adding an implementation in assembly for a new architecture. So suppose all GNUstep packages have this in their Build-Depends field: clang:native [amd64 arm64 armhf hurd-any i386 riscv64], libobjc2-dev [amd64 arm64 armhf hurd-any i386 riscv64], If an implementation for loong64 is added, it would require correction in debian/control for all packages and sourceful uploads in the right order. That's rather inconvenient. Another reason is that a lot of users requested to make it easy to get a capable development environment by installing just one package (gnustep-devel or gnustep-core-devel). That's indeed the case -- I had qemu-user-binfmt installed and that's what confused me. Removing it immediately shows the problem. And I can't explain why, but now I can reliably reproduce #1094879 which would allow me to work on a fix that can be included upstream. Of course you are right, that's so blatantly obvious. Sadly, no; mea culpa. Perhaps I'm misunderstanding something, but binutils-multiarch depends on binutils, which would lead to the same problem we have now. I guess all of these are questions for the LLVM maintainers.