Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Flang] Driver hardcodes lib/libflang_rt.a path that is incorrect on lib64 systems, and does not permit multilib #127538

Open
mgorny opened this issue Feb 17, 2025 · 17 comments

Comments

@mgorny
Copy link
Member

mgorny commented Feb 17, 2025

I'm almost ready to package Flang on Gentoo. The remaining problem is that the driver hardcodes the lib directory for libflang_rt.a:

void tools::addFortranRuntimeLibraryPath(const ToolChain &TC,
const llvm::opt::ArgList &Args,
ArgStringList &CmdArgs) {
// Default to the <driver-path>/../lib directory. This works fine on the
// platforms that we have tested so far. We will probably have to re-fine
// this in the future. In particular, on some platforms, we may need to use
// lib64 instead of lib.
SmallString<256> DefaultLibPath =
llvm::sys::path::parent_path(TC.getDriver().Dir);
llvm::sys::path::append(DefaultLibPath, "lib");

This is problematic for two reasons:

  1. Gentoo is using lib64 for 64-bit libraries on platforms such on amd64, and lib for 32-bit libraries, and installing a 64-bit library into lib is generally an error.
  2. The forced use of a single library directory makes cross-compilation / multilib builds impossible. I haven't tested how well Flang works with that yet, but at least a dumb flang --target=i686-pc-linux-gnu hello.f90 seems to work, modulo trying to link a 64-bit runtime.

I've tried fiddling a fair bit, and unfortunately I don't see any good way of getting the correct lib* directory in that code. Perhaps the correct approach would be to include the architecture in the filename the way compiler-rt does — and perhaps move it to clang's resource directory while at it?

@llvmbot llvmbot added the flang Flang issues not falling into any other category label Feb 17, 2025
@mgorny
Copy link
Member Author

mgorny commented Feb 17, 2025

Oh, and for completeness: we are installing the whole LLVM into per-version prefixes, so that different versions can be used simultaneously. So we can't just rely on the linker picking up the library from /usr/lib64 but need Flang to explicitly point it to the right directory.

@EugeneZelenko EugeneZelenko added flang:driver and removed flang Flang issues not falling into any other category labels Feb 17, 2025
@llvmbot
Copy link
Member

llvmbot commented Feb 17, 2025

@llvm/issue-subscribers-flang-driver

Author: Michał Górny (mgorny)

I'm almost ready to package Flang on Gentoo. The remaining problem is that the driver hardcodes the `lib` directory for `libflang_rt.a`:

void tools::addFortranRuntimeLibraryPath(const ToolChain &TC,
const llvm::opt::ArgList &Args,
ArgStringList &CmdArgs) {
// Default to the <driver-path>/../lib directory. This works fine on the
// platforms that we have tested so far. We will probably have to re-fine
// this in the future. In particular, on some platforms, we may need to use
// lib64 instead of lib.
SmallString<256> DefaultLibPath =
llvm::sys::path::parent_path(TC.getDriver().Dir);
llvm::sys::path::append(DefaultLibPath, "lib");

This is problematic for two reasons:

  1. Gentoo is using lib64 for 64-bit libraries on platforms such on amd64, and lib for 32-bit libraries, and installing a 64-bit library into lib is generally an error.
  2. The forced use of a single library directory makes cross-compilation / multilib builds impossible. I haven't tested how well Flang works with that yet, but at least a dumb flang --target=i686-pc-linux-gnu hello.f90 seems to work, modulo trying to link a 64-bit runtime.

I've tried fiddling a fair bit, and unfortunately I don't see any good way of getting the correct lib* directory in that code. Perhaps the correct approach would be to include the architecture in the filename the way compiler-rt does — and perhaps move it to clang's resource directory while at it?

@tarunprabhu
Copy link
Contributor

It looks like gcc installs libgfortran and libstdc++ to its equivalent of a resource directory. It seems like a reasonable place to put it. But we should try to be consistent with libc++, which is the closest equivalent in the LLVM project.

@mgorny
Copy link
Member Author

mgorny commented Feb 18, 2025

Is flang_rt compatible across different Flang versions? I.e. is it fine to, say, use libflang_rt.a from Flang main with older version of Flang compiler?

@tarunprabhu
Copy link
Contributor

Is flang_rt compatible across different Flang versions? I.e. is it fine to, say, use libflang_rt.a from Flang main with older version of Flang compiler?

I am not sure. Perhaps someone more knowledgeable about the runtime can give you a more definitive answer, @klausler @kiranchandramohan @jeanPerier @clementval

@jeanPerier
Copy link
Contributor

Is flang_rt compatible across different Flang versions? I.e. is it fine to, say, use libflang_rt.a from Flang main with older version of Flang compiler?

There is no such guarantee. The runtime API do evolve from time to time and some may be removed/modified. The Fortran runtime is not a "standard library", it is tightly connected to the compiler, so it is more similar to compiler-rt in terms of compiler/runtime interaction, even though its features are comparable to libc++.

@mgorny
Copy link
Member Author

mgorny commented Feb 24, 2025

Yeah, so I think clang resource dir would work best. FWICS the standalone runtimes build already attempts installing it somewhere like that, except that I don't think the driver actually checks that location.

@Meinersbur
Copy link
Member

Meinersbur commented Feb 26, 2025

At the moment flang does not support cross-compilation. Even if flang accepts --target, it should not be used, there are many places where Flang assumes that the target system is the same as the host. Making flang-rt use of the LLVM_ENABLE_RUNTIMES system in #110217 was just the first step. Also, Flang currently only supports 64-bit, so multilib is somewhat pointless.

#110217 (LLVM_ENABLE_RUNTIMES=flang-rt) also changed the location of flang_rt.runtime.lib, compared to the old way FLANG_INCLUDE_RUNTIME=ON. I originally used CMAKE_INSTALL_LIBDIR which seemed the platform-correct way to do. Unfortunately, it did now work, see the discussion at #110217 (comment).

I see you also opened #127345, the library where libflang_rt.runtime.a and the driver searches for them must be in-sync, ideally also with clang/compiler-rt. Unfortantely, it's total chaos (together with LLVM_ENABLE_PER_TARGET_RUNTIME_DIR). There are two lib in the path, there is CMAKE_INSTALL_LIBDIR, CLANG_INSTALL_LIBDIR_BASENAME, CLANG_LIBDIR_SUFFIX, LLVM_LIBDIR_SUFFIX, ... and I have no idea what is the correct way to do it.

@Meinersbur
Copy link
Member

Is flang_rt compatible across different Flang versions? I.e. is it fine to, say, use libflang_rt.a from Flang main with older version of Flang compiler?

There is no such guarantee. The runtime API do evolve from time to time and some may be removed/modified. The Fortran runtime is not a "standard library", it is tightly connected to the compiler, so it is more similar to compiler-rt in terms of compiler/runtime interaction, even though its features are comparable to libc++.

To elaborate, this is the reason why libflang_rt.runtime.a is put into Clang's resource dir (<clang-executable>/../lib/clang/<version>/lib/<target-triple>)

@DavidTruby
Copy link
Member

DavidTruby commented Feb 27, 2025

Just to add a bit of context; flang does support cross compilation in practice between "similar" targets, ie 64 bit targets where the sizes of the types are the same. I've used it myself to cross compile from x86_64-linux to aarch64-linux, as well as from aarch64-linux to aarch64-win32, and it has worked well in those cases. It's certainly under tested though, and you have to hope that the platforms you're using have the same eg integer widths.
This could certainly be better tested, and we should look at fixing the code that assumes the build platform has the same type widths as the target platform.

I'm also not aware of anyone having tested flang on any kind of 32 bit architecture. It's almost certainly impossible to do a build of flang itself in 32 bit because of memory requirements; I suppose you could cross compile it (it's just a C++ programme after all) but I'm not aware of that having been tested by anyone.

I don't think any of this should be a mark against a distributor's desire to have lib only contain 32 bit libraries and lib64 contain only 64 bit binaries though. It does sound to me like taking the same approach as clang takes for compiler-rt would be the best path forward. Would we be able to invent a flang resource dir using the same logic as clang uses for its equivalent, and use that as the location for libflang-rt?

@Meinersbur
Copy link
Member

Just to add a bit of context; flang does support cross compilation in practice between "similar" targets, ie 64 bit targets where the sizes of the types are the same. I've used it myself to cross compile from x86_64-linux to aarch64-linux, as well as from aarch64-linux to aarch64-win32, and it has worked well in those cases. It's certainly under tested though, and you have to hope that the platforms you're using have the same eg integer widths. This could certainly be better tested, and we should look at fixing the code that assumes the build platform has the same type widths as the target platform.

Not just type widths, but also alignment rules, which causes structs to have different sizes etc.

x86_64 and aarch64 might mostly work, since both are LP64 (sizeof(long)==8) and probably the same alignments, but win32 uses LLP64 (sizeof(long)==4) and WILL cause problems:
https://github.com/llvm/llvm-project/blob/main/flang/include/flang/Optimizer/CodeGen/DescriptorModel.h#L91-L94

I don't think we should claim any level of "supported" as long as there are such known miscompilation issues. Otherwise users/clients will use it, their program crashes unexpectedly, nobody can reproduce it until we're told that they were cross-compiling, and rightfully blame us for it. At least I want to tell them they were not supposed to do cross-compilation.

@clementval
Copy link
Contributor

For 32 bits the doc is pretty clear.

Note that flang is not supported on 32 bit CPUs.

For cross compilation to other 64bits target nobody ever claimed that is was implemented and/or tested so I would not use it in production until somebody spend the time to make the adjustment to make it work 100%.

@DavidTruby
Copy link
Member

Yeah, I wasn't trying to suggest that anyone should use it in production as of yet, only that it does work in some cases, and that we should try not to put any more blockers in place for when we do want to make it work in more/all cases.

@mgorny
Copy link
Member Author

mgorny commented Feb 27, 2025

It's almost certainly impossible to do a build of flang itself in 32 bit because of memory requirements; I suppose you could cross compile it (it's just a C++ programme after all) but I'm not aware of that having been tested by anyone.

Well, that's pretty much what multilib is about, but I didn't plan on doing that. At this point, I'd like to see 32-bit platform support fixed in MLIR first (but can't really find time to look into it), as it's going to be required for ClangIR.

That said, the memory requirements are a problem on 64-bit platforms as well. With 32G RAM here, I have to build Flang with -j4 instead of -j12 — and I literally haven't seen any other package build using so much memory, browsers et al. It's also easily OOMs our devbox that has 64G but defaults to -j16.

@luporl
Copy link
Contributor

luporl commented Mar 6, 2025

I'm seeing an error on macOS that seems related to this issue:

$ ~/flang/install/bin/flang -fopenmp -o ftest ftest.o
ld: library 'flang_rt.runtime' not found
flang-21: error: linker command failed with exit code 1 (use -v to see invocation)

Adding -v:

$ ~/flang/install/bin/flang -v -fopenmp -o ftest ftest.o
flang version 21.0.0git ([email protected]:luporl/llvm-project.git 6c9a9d9fe2371e586be8ecba8b9a2d129d1c0226)
Target: arm64-apple-darwin24.3.0
Thread model: posix
InstalledDir: /Users/leandro.lupori/home/git/flang/install/bin
Build config: +assertions
 "/usr/bin/ld" -demangle -lto_library /Users/leandro.lupori/home/git/flang/install/lib/libLTO.dylib -dynamic -arch arm64 -platform_version macos 14.7.0 14.7.0 -syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -mllvm -enable-linkonceodr-outlining -o ftest ftest.o -L/Users/leandro.lupori/home/git/flang/install/lib -lflang_rt.runtime -lomp -L/Users/leandro.lupori/home/git/flang/install/lib -lSystem /Users/leandro.lupori/home/git/flang/install/lib/clang/21/lib/darwin/libclang_rt.osx.a
ld: library 'flang_rt.runtime' not found

I can work around it by explicitly passing the directory where flang_rt is installed:

$ ~/flang/install/bin/flang -v -fopenmp -L/Users/leandro.lupori/home/git/flang/install/lib/clang/21/lib/arm64-apple-darwin24.3.0 -o ftest ftest.o

It's interesting that clang_rt is installed in lib/clang/21/lib/darwin instead, and its absolute path is used when linking.

@h-vetinari
Copy link
Contributor

That said, the memory requirements are a problem on 64-bit platforms as well. With 32G RAM here, I have to build Flang with -j4 instead of -j12 — and I literally haven't seen any other package build using so much memory, browsers et al. It's also easily OOMs our devbox that has 64G but defaults to -j16.

See #127364

@DanielCChen
Copy link
Contributor

I didn't go through all the comment, but PR #134362 may fix this. The driver will search for the full path to libflang_rt.runtime.a(so).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests