2016-03-10 2 views
11

Я пытаюсь применить Оптимизацию времени связи с LLVM в проекте CMake, который создает общую библиотеку. Мой вопрос почти такой же, как этот:LTO с LLVM и CMake

Switching between GCC and Clang/LLVM using CMake.

Однако ответы больше не применимы, так как llvm-ld нет в новых версиях. В командной строке, я бегу следующие команды, чтобы получить LTO (Предполагая, что есть только 2 .cpp файлы):

компилировать байт-код:

clang++ -c FirstClass.cpp -O3 -flto -o FirstClass.bc 
clang++ -c SecondClass.cpp -O3 -flto -o SecondClass.bc 

Ссылка байт-код:

llvm-link FirstClass.bc SecondClass.bc -o unoptimized.bc 

Оптимизировать байт код:

opt -O3 unoptimized.bc -o optimized.bc 

Преобразование байт кода в общий объект:

clang++ -shared optimized.bc -o libTest.so 

Может кто-нибудь, пожалуйста, скажите мне, как запустить CMake дополнительные шаги?

+2

Это может быть работа для [ 'add_custom_command'] (https://cmake.org/cmake/help/v3 .0/command/add_custom_command.html) cmake ... Что-то вроде 'add_custom_command (OUTPUT libTest.so COMMAND clang ++ -shared optimized.bc -o libTest.so MAIN_DEPENDENCY optimized.bc)' См. Http://stackoverflow.com/ вопросы/13470499/CMake-надстройка на заказ команда-с зависимостями-с-а-другого-каталога – francis

ответ

6

Правильный способ использования Clang и включить LTO использует -flto флаг в clang командной строки как при компиляции и время связи.

Кроме того, вам необходимо будет работать на платформе с компоновщиком, который либо поддерживает LTO (обычно платформы Apple), либо имеет плагин LLVM-компоновщика (Linux с использованием компоновщика Gold, но я думаю, что некоторые из них получили BFD для поддержки плагина-компоновщика). Если вы используете плагин-компоновщик, вам нужно убедиться, что ваша установка LLVM построена и установлена ​​плагином. Если это так, Clang автоматически добавит необходимые параметры командной строки компоновщика, чтобы использовать плагин при связывании с -flto, даже для общих объектов.

Кроме того, проект LLVM работает над новым компоновщиком (LLD), который будет поддерживать LTO из коробки на всех поддерживаемых платформах, но все еще довольно рано. В настоящее время я знаю, что люди тестируют свою поддержку LTO в Windows и Linux, и, похоже, она работает хорошо, но по-прежнему не хватает многих функций.

1

Включение (тонкий) LTO на CMake 3.9 и выше должен быть просто:

include(CheckIPOSupported) 
check_ipo_supported() 
set_target_properties(myProject PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE) 

set_target_properties Вместо каждый проект, единая глобальная настройка set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) может быть сделан.

Для того, чтобы ускорить компиляции, кэш для LTO может быть установлен:

function(append value) 
    foreach(variable ${ARGN}) 
     set(${variable} "${${variable}} ${value}" PARENT_SCOPE) 
    endforeach(variable) 
endfunction() 

append("-fuse-ld=gold -Wl,--no-threads,--plugin-opt,cache-dir=${PROJECT_BINARY_DIR}/lto.cache" CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS) 

Это заставляет gold как линкер для того, чтобы использовать правильные параметры командной строки. Для этого может потребоваться символическая ссылка: /usr/lib/LLVMgold.so - /usr/lib/llvm-4.0/lib/LLVMgold.so.

2

check_ipo_supported() результат для меня в "Policy CMP0069 не установлен" ошибка на CMake 3.9.1.

С его помощью CMake до 3,8 поддерживает только LTO компилятора Intel. Для меня это тоже не работало на XCode 9.

То, что сработало, в конце концов:

cmake_policy(SET CMP0069 NEW) 
include(CheckIPOSupported) 
check_ipo_supported() 

add_executable(Foobar SOURCES) 
set_target_properties(Foobar PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE) 

Похоже add_executable() потребности быть после cmake_policy(SET CMP0069 NEW).

кэш LTO

target_link_libraries(Foobar "-Wl,-cache_path_lto,${PROJECT_BINARY_DIR}/lto.cache") не сделал никакого вреда.

Выберите вариант командной строки depending on your linker.

Более брутальный вариант

Согласно @ ChandlerCarruth отвечают:

if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") 
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto") 
    target_link_libraries(Foobar -flto) 
endif() 
Смежные вопросы