RFC: Select a "better" linker by default or warn about using bfd

After spending quite a bit of time helping new people to the project in both Discourse and Discord one thing becomes very obvious:

Building LLVM with default options (Debug) and GCC + BFD linker (still the default on many Linux distributions) almost always fails because it’s running out of memory. Which leads to a lot of confusion and questions.

I think we can solve this issue and make it better for people starting to build LLVM for the first time. There are two approaches I can think of:

  • Detect bfd linker and make a soft warning when building release configuration and a hard warning when building debug, with a cmake option to override. Possibly using the same mechanism suggested here: :gear: D123777 [CMake] Check for problematic MSVC + /arch:AVX configuration (llvm.org)
  • Automatically try to use a “better” linker by default. This means probing if your compiler can do -fuse-ld=lld/gold before falling back to bfd and then either warn softly or do the same thing as the point above.

I think doing this (fairly simple) detection in CMake would lead to a lot of benefit for new people to the LLVM project. In my own opinion I think we should go for the automatic probing - using supported / sane defaults is always better than warning users and have them manually opt in to the thing we want to use instead.

I can make a patch for this if we agree on what the best way forward is.

5 Likes

Agreed on this being a common problem.

But I’m not sure how many users will have lld or gold installed on their systems.

Maybe instead (or in addition) we should push people to do Release builds instead (maybe with asserts enabled). Perhaps that should even be the default? This is usually the solution I point people towards.

3 Likes

I think this makes a lot of sense as well.

I think maybe we should do both change the default build_type and prefer lld and gold over bfd.

I thought Gold was no longer actively worked on upstream, and LLD requires LLVM to already be installed so may not be good to suggest to users trying to build LLVM.

Debug builds with BUILD_SHARED_LIBS=ON work fine with all linkers including BFD, do they not? Could we instead switch to that by default for debug builds?

Yes gold is deprecated - but it would still work better in bfd in this specific case. Most distributions comes with gold installed already (at least what I have seen).

I have no experience with building LLVM with BUILD_SHARED_LIBS=ON so I can’t really comment on that. But setting the default build type to release feels like a smaller change than to set shared_libs to true. But I really don’t have a very definitive opinion on this one.

I had built the LLVM/Clang successfully with the options BUILD_SHARED_LIBS=ON using the bfd linker.
But I wonder the BUILD_SHARED_LIBS options are available for the Windows Platform also. And applying the option LLVM_BUILD_LLVM_DYLIB instead would be more better as the LLVM/Clang CMAKE tutorial recommends.

I’d be in great support of making Release the default option in the cmake build. I think the default of it being Debug is quite user hostile as users tend to not think about setting CMAKE_BUILD_TYPE. This has then often lead to two scenarios:

  1. People wondering why their LLVM/Clang installation is occupying more than 100GB of disk space
  2. Builds failing due to the executable being too large or the linker taking too much RAM and being killed by the OS.

For those reasons telling people to set CMAKE_BUILD_TYPE to Release has always been my number 1 suggestion to anyone asking me how to compile Clang/LLVM.

I think as developers on LLVM and Clang we are generally aware of the difference, and even if we were to get the option wrong, don’t mind recompiling with the correct build type set, given how often we already get to recompile the whole project.

Users on the other hand generally only compile the project once to eg. get the newest version of Clang, and not having to tell them that they have wasted the previous hour by compiling a debug version and must now waste another by recompiling in Release would greatly increase user experience.

2 Likes

Yeah I think this is the best way forward. Developers know about -DCMAKE_BUILD_TYPE and this is mostly just harming new users that mostly just wants to build a release build.

+1 for a default to Release!
Previous discussion on this topic: [llvm-dev] wasteful cmake defaults (in which defaulting to lld was also mentioned). A link from this discussion also: https://www.kitware.com/cmake-and-the-default-build-type/

An alternative: I would propose to error out and ask the user to explicitly select a build type instead of letting it default to Debug.

Given how easy it is to ‘apt get install lld’ on common architectures, It shouldn’t be hard to make it the default with the option to opt back into the system linker.

Sounds to me like we have several different things in parallel:

  • Probe for lld over bfd if LLVM_USE_LINKER is not supplied. Low risk, high benefit if we find lld. I will submit a patch for this.
  • Warn if you do bfd + debug build. This seems easy and low risk as well. Can anyone think of a good reason not to add this warning? I will post a patch for this unless someone thinks it’s a really bad idea.
  • Change default BUILD_TYPE to Release. This might be a better default - but it’s a “breaking” change and switches the default from targeting “developers” to “users”. I am fine with this change personally - but it seemed some people didn’t like this in the thread Mehdi linked.
  • Change default of building libraries as dynamic instead of static when building debug. Not sure about this one myself - but I don’t have anything against it per se.
  • warn about parameters that could lead to a bad user experience
  • change the default to improve user experience

I am a bit afraid about the second one. This could be surprising for users, ie. developers.

I suggest starting new threads as necessary (or at least editing the topic title for this one).

I also think we should switch from Debug to Release as the default build type. This is easy to do, very safe, and I think will have a bigger impact on user experience than the other proposed changes.

In my opinion, we shouldn’t try to detect the linker or default to some other linker than the chosen compiler’s default, especially if we are compiling with gcc. I think it will be too complicated to implement in CMake and we will run into some compatibility problems e.g. gcc + LTO won’t work with lld. If we do this, I think we may just be trading one set of confusing errors for another.

+1 to changing the default to Release. I think this is the right default for both users and developers. The distinction between users and developers is in whether -DLLVM_ENABLE_ASSERTIONS=true needs to be set as well.

Split the Debug->Release change out into it’s own thread and posted a diff.

I agree and I’d prefer we don’t change the default.

Users who need an alternative linker can specify LLVM_ENABLE_LLD=on or LLVM_USE_LINKER=.