From c45f01866bdfe7c62a83b51dfb974acb7fa5cab6 Mon Sep 17 00:00:00 2001 From: Roman Lebedev Date: Wed, 29 Nov 2017 23:48:43 +0300 Subject: [PATCH] CMake: implement LTO for clang. Fixes #478 (#487) * CMake: implement LTO for clang. Fixes #478 * LTO: add basic docs about required executables. --- CMakeLists.txt | 3 +++ README.md | 3 +++ cmake/Modules/FindLLVMAr.cmake | 16 ++++++++++++++++ cmake/Modules/FindLLVMNm.cmake | 16 ++++++++++++++++ cmake/Modules/FindLLVMRanLib.cmake | 15 +++++++++++++++ cmake/llvm-toolchain.cmake | 8 ++++++++ 6 files changed, 61 insertions(+) create mode 100644 cmake/Modules/FindLLVMAr.cmake create mode 100644 cmake/Modules/FindLLVMNm.cmake create mode 100644 cmake/Modules/FindLLVMRanLib.cmake create mode 100644 cmake/llvm-toolchain.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index fb8acb65..44acc288 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,7 @@ option(BENCHMARK_BUILD_32_BITS "Build a 32 bit version of the library." OFF) option(BENCHMARK_ENABLE_INSTALL "Enable installation of benchmark. (Projects embedding benchmark may want to turn this OFF.)" ON) # Make sure we can import out CMake functions +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") # Read the git tags to determine the project version @@ -132,6 +133,8 @@ else() if (GCC_RANLIB) set(CMAKE_RANLIB ${GCC_RANLIB}) endif() + elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") + include(llvm-toolchain) endif() endif() diff --git a/README.md b/README.md index c6a9caf2..68796305 100644 --- a/README.md +++ b/README.md @@ -848,6 +848,9 @@ To enable link-time optimisation, use cmake -DCMAKE_BUILD_TYPE=Release -DBENCHMARK_ENABLE_LTO=true ``` +If you are using gcc, you might need to set `GCC_AR` and `GCC_RANLIB` cmake cache variables, if autodetection fails. +If you are using clang, you may need to set `LLVMAR_EXECUTABLE`, `LLVMNM_EXECUTABLE` and `LLVMRANLIB_EXECUTABLE` cmake cache variables. + ## Linking against the library When using gcc, it is necessary to link against pthread to avoid runtime exceptions. This is due to how gcc implements std::thread. diff --git a/cmake/Modules/FindLLVMAr.cmake b/cmake/Modules/FindLLVMAr.cmake new file mode 100644 index 00000000..23469813 --- /dev/null +++ b/cmake/Modules/FindLLVMAr.cmake @@ -0,0 +1,16 @@ +include(FeatureSummary) + +find_program(LLVMAR_EXECUTABLE + NAMES llvm-ar + DOC "The llvm-ar executable" + ) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(LLVMAr + DEFAULT_MSG + LLVMAR_EXECUTABLE) + +SET_PACKAGE_PROPERTIES(LLVMAr PROPERTIES + URL https://llvm.org/docs/CommandGuide/llvm-ar.html + DESCRIPTION "create, modify, and extract from archives" +) diff --git a/cmake/Modules/FindLLVMNm.cmake b/cmake/Modules/FindLLVMNm.cmake new file mode 100644 index 00000000..e56430a0 --- /dev/null +++ b/cmake/Modules/FindLLVMNm.cmake @@ -0,0 +1,16 @@ +include(FeatureSummary) + +find_program(LLVMNM_EXECUTABLE + NAMES llvm-nm + DOC "The llvm-nm executable" + ) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(LLVMNm + DEFAULT_MSG + LLVMNM_EXECUTABLE) + +SET_PACKAGE_PROPERTIES(LLVMNm PROPERTIES + URL https://llvm.org/docs/CommandGuide/llvm-nm.html + DESCRIPTION "list LLVM bitcode and object file’s symbol table" +) diff --git a/cmake/Modules/FindLLVMRanLib.cmake b/cmake/Modules/FindLLVMRanLib.cmake new file mode 100644 index 00000000..7b53e1a7 --- /dev/null +++ b/cmake/Modules/FindLLVMRanLib.cmake @@ -0,0 +1,15 @@ +include(FeatureSummary) + +find_program(LLVMRANLIB_EXECUTABLE + NAMES llvm-ranlib + DOC "The llvm-ranlib executable" + ) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(LLVMRanLib + DEFAULT_MSG + LLVMRANLIB_EXECUTABLE) + +SET_PACKAGE_PROPERTIES(LLVMRanLib PROPERTIES + DESCRIPTION "generate index for LLVM archive" +) diff --git a/cmake/llvm-toolchain.cmake b/cmake/llvm-toolchain.cmake new file mode 100644 index 00000000..fc119e52 --- /dev/null +++ b/cmake/llvm-toolchain.cmake @@ -0,0 +1,8 @@ +find_package(LLVMAr REQUIRED) +set(CMAKE_AR "${LLVMAR_EXECUTABLE}" CACHE FILEPATH "" FORCE) + +find_package(LLVMNm REQUIRED) +set(CMAKE_NM "${LLVMNM_EXECUTABLE}" CACHE FILEPATH "" FORCE) + +find_package(LLVMRanLib REQUIRED) +set(CMAKE_RANLIB "${LLVMRANLIB_EXECUTABLE}" CACHE FILEPATH "" FORCE)