morganstanley/binlog

Do not use LTO if AR is incompatible with LD

Opened this issue · 7 comments

I followed the install steps but the following error is reporeted:
[ 21%] Linking CXX executable brecovery
/usr/bin/cmake -E cmake_link_script CMakeFiles/brecovery.dir/link.txt --verbose=1
/usr/bin/c++ -O2 -g -DNDEBUG CMakeFiles/brecovery.dir/bin/brecovery.cpp.o -o brecovery libbinlog.a
/usr/bin/ld: libbinlog.a: error adding symbols: file format not recognized
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [CMakeFiles/brecovery.dir/build.make:85: brecovery] Error 1
make[2]: Leaving directory '/home/user/project/public/binlog/Release'
make[1]: *** [CMakeFiles/Makefile2:571: CMakeFiles/brecovery.dir/all] Error 2
make[1]: Leaving directory '/home/user/project/public/binlog/Release'
make: *** [Makefile:141: all] Error 2

libbinlog.a has been generated

Please post the output of /usr/bin/c++ --version and /usr/bin/ld --version. Perhaps these two are for different architectures? Can you compile other projects with /usr/bin/c++ ?

It's a normal desktop machine with Ubuntu 20.04.3 LTS, the arch should be the same.
I can compile simple hello word with /usr/bin/c++ and run the output executable successfully. Please let me know if you would like me to try with any specific project.

/usr/bin/c++ --version
clang version 10.0.0-4ubuntu1
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin

/usr/bin/ld --version
GNU ld (GNU Binutils for Ubuntu) 2.34
Copyright (C) 2020 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or (at your option) a later version.
This program has absolutely no warranty.

From the make VERBOSE=1 output, please show how libbinlog.a was built.

Please find the full cmake and build log attached.
buildlog.txt

It appears to be an incompatibility between llvm-ar + -fthin-lto and the gnu linker.
To verify that LTO is at fault, in CMakeLists.txt, please remove this block:

# Interprocedural Optimization (LTO)
if(POLICY CMP0069)
  cmake_policy(SET CMP0069 NEW)
  include(CheckIPOSupported) # fails if policy 69 is not set
  check_ipo_supported(RESULT BINLOG_HAS_IPO)
  if(BINLOG_HAS_IPO)
    message(STATUS "Use interprocedural optimization")
  endif()
endif()

And instead add:

set(BINLOG_HAS_IPO OFF)

If this makes it build, then the proper solution is either:

  • force clang to use llvm linkers (-fuse-ld=lld, perhaps)
  • force clang to use gnu ar exclusively (don't know how)

Yes, removing that block does make it work. Thank you very much for the help.

Thanks for confirming. I renamed the ticket to reflect the uncovered issue. The LTO checker should detect this degenerate case, and disable LTO automatically.