Problem with the way BUILD_SHARED_LIBS=ON handled in llvm 3.8

Hi,

For lllvm 3.7 and before BUILD_SHARED_LIBS=ON would produce versioned
shared libs like

libLLVMLTO.so (symlink)
libLLVMLTO.so.3.7 (symlink)
libLLVMLTO.so.3.7.0 (real file)

now it just builds an unversioned libLLVMLTO.so file which I believe
is a problem because when a program links to llvm it generates a
runtime dependency on libLLVMLTO.so instead of libLLVMLTO.so.3.7.0
which will break versioned dependencies.

Can we please get this behaviour back?

Thanks,
ismail

The LLVM libraries are not API stable (especially not the ones you generate with BUILD_SHARED_LIBS). Those libraries are really not intended to ship. What are you trying to accomplish? Have you tried using libLTO or libLLVM? The later is generated with the option LLVM_BUILD_LLVM_DYLIB=On.

-Chris

Hi,

The LLVM libraries are not API stable (especially not the ones you generate with BUILD_SHARED_LIBS). Those libraries are really not intended to ship.

I know that's why I need them versioned. Currently we (openSUSE) ship
libLLVM package which will install libLLVMFooBar.so.3.7 files and
llvm-devel package will ship unversioned libLLVMFooBar.so.

So, any application linking against LLVM generates a dependency
against the versioned libLLVMFooBar.so.3.7 and not against the
unversioned library. This way when we ship the new libLLVM 3.8 old
application will have to be recompiled to correctly link against the
new LLVM

LLVM 3.7 and before did this correctly and 3.8 should not break this.
As I said in another mail I tried -DLLVM_BUILD_LLVM_DYLIB=ON
-DLLVM_LINK_LLVM_DYLIB=ON but it's not currently usable as it is.

Thanks,
ismail

I think the right solution here is to fix LLVM_BUILD_LLVM_DYLIB and LLVM_LINK_LLVM_DYLIB (which should work) rather than fixing BUILD_SHARED_LIBS which was never intended to work for this use case.

Either way, patches welcome.

-Chris

Hi,

Yes, I'm aware of the change that caused this. It was when I stopped setting SOVERSION as a target property on all shared libraries. That change was deliberate in order to match functionality between CMake and the autoconf build.

In the autoconf build we didn't actually set the SOVERSION on libraries. Instead we include the version in the name of libLLVM, and we didn't version libLTO (except on Darwin).

I believe we are coming back to the point that BUILD_SHARED_LIBS=On should never be used when building a distribution, so the libraries shouldn't be versioned. The only reason to use libLTO is if your system linker is slow and you want to improve iteration times.

A clang built with BUILD_SHARED_LIBS=On will be significantly slower than one built against a single LLVM dynamic library, and in turn that is significantly slower than a clang built against static libraries. On Darwin process launch for a clang built against an LLVM dynamic library takes 2ms longer to launch than clang built against static libraries.

The fix here is not to make BUILD_SHARED_LIBS work the way it used to. The fix is to make LLVM_LINK_LLVM_DYLIB work with out-of-tree builds.

Also, as a note, I believe that reverting the change that caused this is a non-starter (others can feel free to disagree). That change fixed a blocking issue that prevented clients of the autoconf builds from moving to CMake.

-Chris

Hi,

Hi,

Yes, I'm aware of the change that caused this. It was when I stopped setting SOVERSION as a target property on all shared libraries. That change was deliberate in order to match functionality between CMake and the autoconf build.

In the autoconf build we didn't actually set the SOVERSION on libraries. Instead we include the version in the name of libLLVM, and we didn't version libLTO (except on Darwin).

I believe we are coming back to the point that BUILD_SHARED_LIBS=On should never be used when building a distribution, so the libraries shouldn't be versioned. The only reason to use libLTO is if your system linker is slow and you want to improve iteration times.

A clang built with BUILD_SHARED_LIBS=On will be significantly slower than one built against a single LLVM dynamic library, and in turn that is significantly slower than a clang built against static libraries. On Darwin process launch for a clang built against an LLVM dynamic library takes 2ms longer to launch than clang built against static libraries.

The fix here is not to make BUILD_SHARED_LIBS work the way it used to. The fix is to make LLVM_LINK_LLVM_DYLIB work with out-of-tree builds.

Since I am the only one complained about this so far, I'll revert this
change locally for 3.8 packaging and work on getting
LLVM_LINK_LLVM_DYLIB work as expected so we can use it for packaging
3.9.

Other than the darwin-specific name choice, shouldn't
LLVM_LINK_LLVM_DYLIB also be usable on linux to link against a
libLLVM.so? Or is there a speed difference, on the faster dynamic
library loading on linux, between loading many shared libraries, of
smaller aggregate size, rather than loading one larger sized shared
library.
                    Jack

There was a really big debate about the naming of that option when it went in. The problem is that we support three platforms and they all refer to libraries using different terminology. Linux calls them shared objects referring to the distribution method, but Darwin and Windows both refer to them as dynamic referring to how they are loaded. Sadly there is no good name.

All platforms see performance implications of dynamically linking libraries as opposed to statically linking them. I don’t know whether that hits Darwin or Linux worse, but I believe Darwin’s two-level name spacing actually makes Darwin better than Linux. If I understand correctly it hits windows worst of all because of how Windows handles weak symbol resolution.

On all platforms I would expect the many shared libraries to be way worse relative to one shared library. I expect that would be the case because one of the complications of C++ is a lot of weak exports. Those come from functions implemented in headers which are then compiled into each generated object file. At static link time the linker resolves the duplicates down to a single implementation. If you are linking one dynamic library you will have way less symbols than if you are linking multiple libraries because each library will have its own copy of the duplicated symbols.

-Chris