Closed springmeyer closed 7 years ago
Good that you're raising this issue! Over the last weekend I compiled a freshly releases LLVM 3.8 (and then all of osrm-backend's dependencies with Clang/libc++ for ABI compatibility), and only after reading this issue checked for lto in the compilation log --- and indeed the CMake buildsystem did not activate it! Let's fix this once and for all! Here's a quick brain dump for Clang/lto:
I played around with ld.gold
three month ago (but back then in combination with GCC). Updating ld
so that it points to ld.gold
seems like the best bet as in:
https://gist.github.com/daniel-j-h/ed3bf9e5cb458b012b5a
For Clang/lto I think we also need to use the lto-aware binutils as in: http://llvm.org/docs/GoldPlugin.html#quickstart-for-using-lto-with-autotooled-projects
Setting env CXXFLAGS='-flto' LDFLAGS='-flto'
is fine when the user knows what to do.
The WebKit CMakeLists has some hints on how to do this programmatically:
https://github.com/WebKit/webkit/blob/master/Source/cmake/OptionsCommon.cmake
The Gentoo Wiki has some notes on solving exactly that problem: https://wiki.gentoo.org/wiki/Clang
(I remember trying to rebuild my Gentoo system a few years ago when lto in GCC was still new --- didn't work out that well :P)
Thanks for the further thoughts @daniel-j-h. So far, via testing osrm-backend build via node-osrm, I've got LTO working with osrm-backend using the llvm-ar
, llvm-nm
, and llvm-ranlib
. But now I'm hitting:
/home/travis/build/Project-OSRM/node-osrm/mason_packages/linux-x86_64/binutils/2.26/bin/ld: skipping incompatible /home/travis/build/Project-OSRM/node-osrm/mason_packages/.link/lib/libosrm.a when searching for -losrm
When trying to link node-osrm against libosrm.a
, as it appears that the static library is not valid. My next move is to try using the ar
provided by binutils-gold rather than llvm-ar
as per http://llvm.org/docs/GoldPlugin.html#quickstart-for-using-lto-with-autotooled-projects. The clang-ar
wrapper described at https://wiki.gentoo.org/wiki/Clang might also be onto something.
What's the last update on this? We're building binaries with Clang now by default (?); at least it's the default CXX
in node-osrm. And we probably will do so in the future, due to us not being able to upgrade to gcc 5.3 on Travis. Which means, this ticket is the main blocker for getting LTO working, I assume?
@daniel-j-h I'm using GCC5.3 in https://github.com/mapbox/route-annotator/
The approach there is to create a Docker container as part of the build. Travis supports this, and it unlocks using basically any build environment you want (route-annotator
is using ubuntu-16.04
). It does make the build a little slower, but given that you can locally reproduce what Travis is doing, I've found I don't get any failed builds if it works on my local machine.
See: https://github.com/mapbox/route-annotator/blob/master/.travis.yml https://github.com/mapbox/route-annotator/blob/master/Dockerfile
I'm only building one combination here at the moment, but it should be trivial to create multiple Dockerfiles for different environments and use them in the Travis build matrix.
Unfortunately, there's no Docker-for-Darwin, so this only works for Linux-based builds.
Just a quick update here LTO is still not enabled in node-osrm, so this issue remains valid:
https://travis-ci.org/Project-OSRM/node-osrm/jobs/153318356#L849
Confirmed this issue is still present. Using -flto
gets disabled by the CmakeLists.txt logic (on linux when building with clang++_ due to the fact that -flto
is not put in the LINKER_FLAGS for the check for whether the compiler recognizes -flto
. So, even though clang++
does know about the -flto
option, our CMakeLists.txt logic fails to detect this because linking fails (as you would expect when an .o is lto enabled but not thing linking).
I'm working on fixing the above problem in https://github.com/Project-OSRM/osrm-backend/pull/3377.
This problem has now been fixed in this proposed PR: https://github.com/Project-OSRM/osrm-backend/pull/3377. Will close this one since the underlying problems are discussed and detailed at https://github.com/Project-OSRM/osrm-backend/pull/3377.
Currently the
-flto
configure check is failing for clang++ linux builds on travis: https://travis-ci.org/Project-OSRM/osrm-backend/jobs/116873025#L1200The way LTO works with clang on linux is:
-flto
needs to be passed to CXXFLAGS-flto
needs to be passed to LDFLAGS/usr/bin/ld
or you need to pass-B/path/to/custom/bin
if the gold linker lives at/path/to/custom/bin/ld
apt-get install llvm-3.7-dev
The reason that the configure check is failing in our builds right now is that
-flto
is not being passed to the linking flags for the check_cxx_compiler_flag check here. And therefore the linker is not put in LTO mode for that configure check and the.o
file with LTO support cannot be read. The error in the cmake logs is:CMakeFiles/cmTryCompileExec3478428907.dir/src.cxx.o: file not recognized: File format not recognized
One workaround I've found is to do
export LDFLAGS="-flto"
which then triggers thecheck_cxx_compiler_flag
to use-flto
in the linker flags and then the binary produced is valid and can be run. But ideally some better workaround could be found, however my knowledge of cmake is too limited to begin to know what to do./cc @daniel-j-h for help.