Using llvm-ar & llvm-ranlib vs ar & ranlib for creating static libraries when thinLTO is enabled.

Hi :slight_smile:

I am trying to compile simple project consisting of an executable “app” and static library “bar”.
Note that I’m enabling thinLTO for both “app” and “bar”.

////////////////////////////////////////
// bar.h //

////////////////////////////////////////

#ifndef BAR

#define BAR

void bar ();

#endif

////////////////////////////////////////

////////////////////////////////////////

// bar.cpp //

////////////////////////////////////////

#include “bar.h”

#include

void bar ()

{

std::cout << “Bar” << std::endl;

}

////////////////////////////////////////

////////////////////////////////////////
// app.cpp //
////////////////////////////////////////

#include “bar.h”

#include

int main()

{

std::cout << “App” << std::endl;

bar();

}

////////////////////////////////////////

When I’m using llvm-ar and llvm-ranlib to create static library everything works fine:

$ clang++ -flto=thin -c bar.cpp -o bar.o

$ llvm-ar cr bar.a bar.o

$ llvm-ranlib bar.a

$ clang++ -flto=thin -c app.cpp -o app.o

$ clang++ -flto=thin -o app app.o bar.a

However using default ar and ranlib provided by my GNU/Linux distribution results in linking failure:

$ clang++ -flto=thin -c bar.cpp -o bar.o

$ ar cr bar.a bar.o

$ ranlib bar.a

$ clang++ -flto=thin -c app.cpp -o app.o

$ clang++ -flto=thin -o app app.o bar.a

bar.a: error adding symbols: Archive has no index; run ranlib to add one
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Note that for GCC using default ar and ranlib works fine:

$ g++ -flto -c bar.cpp -o bar.o

$ ar cr bar.a bar.o

$ ranlib bar.a

$ g++ -flto -c app.cpp -o app.o

$ g++ -flto -o app app.o bar.a

Obviously using gcc-ar and gcc-ranlib also works fine:

$ g++ -flto -c bar.cpp -o bar.o

$ gcc-ar cr bar.a bar.o

$ gcc-ranlib bar.a

$ g++ -flto -c app.cpp -o app.o

$ g++ -flto -o app app.o bar.a

My question is: Can I use ar and ranlib provided by GNU/Linux with clang++?

If not, then to properly setup clang as a default compiler on GNU/Linux machine,
I should not only run update-alternatives for cc and c++ commands,
but also somehow do that for ar and ranlib commands?

$ sudo update-alternatives --config cc
$ sudo update-alternatives --config c++

That’s very problematic since update-alternatives doesn’t work with ar and ranlib:

$ sudo update-alternatives --config ar
update-alternatives: error: no alternatives for ar

$ sudo update-alternatives --config ranlib
update-alternatives: error: no alternatives for ranlib

If default ar and ranlib is expected to not work with clang++,
then how should I setup Clang as a default compiler on GNU/Linux?

Thanks, Mateusz Zych

(Teresa, perhaps you can correct me if I’m wrong here)

Hi :slight_smile:

I am trying to compile simple project consisting of an executable “app” and static library “bar”.
Note that I’m enabling thinLTO for both “app” and “bar”.

////////////////////////////////////////
// bar.h //

////////////////////////////////////////

#ifndef BAR

#define BAR

void bar ();

#endif

////////////////////////////////////////

////////////////////////////////////////

// bar.cpp //

////////////////////////////////////////

#include “bar.h”

#include

void bar ()

{

std::cout << “Bar” << std::endl;

}

////////////////////////////////////////

////////////////////////////////////////
// app.cpp //
////////////////////////////////////////

#include “bar.h”

#include

int main()

{

std::cout << “App” << std::endl;

bar();

}

////////////////////////////////////////

When I’m using llvm-ar and llvm-ranlib to create static library everything works fine:

$ clang++ -flto=thin -c bar.cpp -o bar.o

$ llvm-ar cr bar.a bar.o

$ llvm-ranlib bar.a

$ clang++ -flto=thin -c app.cpp -o app.o

$ clang++ -flto=thin -o app app.o bar.a

However using default ar and ranlib provided by my GNU/Linux distribution results in linking failure:

$ clang++ -flto=thin -c bar.cpp -o bar.o

$ ar cr bar.a bar.o

$ ranlib bar.a

$ clang++ -flto=thin -c app.cpp -o app.o

$ clang++ -flto=thin -o app app.o bar.a

bar.a: error adding symbols: Archive has no index; run ranlib to add one
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Note that for GCC using default ar and ranlib works fine:

$ g++ -flto -c bar.cpp -o bar.o

$ ar cr bar.a bar.o

$ ranlib bar.a

$ g++ -flto -c app.cpp -o app.o

$ g++ -flto -o app app.o bar.a

Obviously using gcc-ar and gcc-ranlib also works fine:

$ g++ -flto -c bar.cpp -o bar.o

$ gcc-ar cr bar.a bar.o

$ gcc-ranlib bar.a

$ g++ -flto -c app.cpp -o app.o

$ g++ -flto -o app app.o bar.a

My question is: Can I use ar and ranlib provided by GNU/Linux with clang++?

Not when using LTO, so far as I know. Otherwise, yes. (no idea if llvm-ar/llvm-ranlib are totally general purpose replacements for those tools, but I guess they are roughly/generally so)

If not, then to properly setup clang as a default compiler on GNU/Linux machine,
I should not only run update-alternatives for cc and c++ commands,
but also somehow do that for ar and ranlib commands?

$ sudo update-alternatives --config cc
$ sudo update-alternatives --config c++

That’s very problematic since update-alternatives doesn’t work with ar and ranlib:

$ sudo update-alternatives --config ar
update-alternatives: error: no alternatives for ar

$ sudo update-alternatives --config ranlib
update-alternatives: error: no alternatives for ranlib

Looks like you can teach update-alternatives to support new commands with the --install option?

That’s correct, we recommend use of the llvm tools for working with bitcode. Note, however, that the GNU ar and ranlib do accept a plugin via --plugin, so you could try using those with the LLVM gold plugin to work with bitcode. I personally use the llvm-ar/llvm-ranlib however.
Teresa

I believe if you install LLVMgold.so into /usr/lib/bfd-plugins, the default ar and ranlib should pick it up without --plugin. See the info under Usage at https://llvm.org/docs/GoldPlugin.html.
Teresa

Hi Teresa, David, thanks for your reply!

Right, installing llvm-dev package (https://packages.ubuntu.com/bionic/llvm-dev)

  • $ sudo apt install llvm-dev
    and adding LLVMgold.so symbolic link to /usr/lib/bfd-plugins worked great. :grinning:

  • $ sudo ln -s /usr/lib/LLVMgold.so /usr/lib/bfd-plugins/LLVMgold.so
    I’m wondering if adding this symbolic link and LLVMgold.so
    should be part of installation of Clang on GNU/Linux (Ubuntu in my case)?
    I mean I was expecting Clang to work no problem after installing just clang package.

Best regards, Mateusz Zych