mirror of
https://github.com/reactos/CMake.git
synced 2024-11-24 12:09:48 +00:00
Clang IPO (LTO) support
This commit is contained in:
parent
d828d0eb08
commit
7d057b2738
25
Modules/Compiler/Clang-FindBinUtils.cmake
Normal file
25
Modules/Compiler/Clang-FindBinUtils.cmake
Normal file
@ -0,0 +1,25 @@
|
||||
if(NOT DEFINED _CMAKE_PROCESSING_LANGUAGE OR _CMAKE_PROCESSING_LANGUAGE STREQUAL "")
|
||||
message(FATAL_ERROR "Internal error: _CMAKE_PROCESSING_LANGUAGE is not set")
|
||||
endif()
|
||||
|
||||
# Try to find tools in the same directory as Clang itself
|
||||
get_filename_component(__clang_hint_1 "${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER}" REALPATH)
|
||||
get_filename_component(__clang_hint_1 "${__clang_hint_1}" DIRECTORY)
|
||||
|
||||
get_filename_component(__clang_hint_2 "${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER}" DIRECTORY)
|
||||
|
||||
set(__clang_hints ${__clang_hint_1} ${__clang_hint_2})
|
||||
|
||||
# http://manpages.ubuntu.com/manpages/precise/en/man1/llvm-ar.1.html
|
||||
find_program(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_AR NAMES
|
||||
"${_CMAKE_TOOLCHAIN_PREFIX}llvm-ar"
|
||||
HINTS ${__clang_hints}
|
||||
DOC "LLVM archiver"
|
||||
)
|
||||
|
||||
# http://manpages.ubuntu.com/manpages/precise/en/man1/llvm-ranlib.1.html
|
||||
find_program(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_RANLIB NAMES
|
||||
"${_CMAKE_TOOLCHAIN_PREFIX}llvm-ranlib"
|
||||
HINTS ${__clang_hints}
|
||||
DOC "Generate index for LLVM archive"
|
||||
)
|
@ -28,12 +28,54 @@ else()
|
||||
set(CMAKE_${lang}_COMPILE_OPTIONS_EXTERNAL_TOOLCHAIN "--gcc-toolchain=")
|
||||
endif()
|
||||
|
||||
set(_CMAKE_IPO_SUPPORTED_BY_CMAKE NO)
|
||||
set(_CMAKE_IPO_MAY_BE_SUPPORTED_BY_COMPILER NO)
|
||||
set(_CMAKE_IPO_SUPPORTED_BY_CMAKE YES)
|
||||
set(_CMAKE_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES)
|
||||
|
||||
unset(CMAKE_${lang}_COMPILE_OPTIONS_IPO)
|
||||
unset(CMAKE_${lang}_ARCHIVE_CREATE_IPO)
|
||||
unset(CMAKE_${lang}_ARCHIVE_APPEND_IPO)
|
||||
unset(CMAKE_${lang}_ARCHIVE_FINISH_IPO)
|
||||
string(COMPARE EQUAL "${CMAKE_${lang}_COMPILER_ID}" "AppleClang" __is_apple_clang)
|
||||
|
||||
# '-flto=thin' available since Clang 3.9 and Xcode 8
|
||||
# * http://clang.llvm.org/docs/ThinLTO.html#clang-llvm
|
||||
# * https://trac.macports.org/wiki/XcodeVersionInfo
|
||||
set(_CMAKE_LTO_THIN TRUE)
|
||||
if(__is_apple_clang)
|
||||
if(CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 8.0)
|
||||
set(_CMAKE_LTO_THIN FALSE)
|
||||
endif()
|
||||
else()
|
||||
if(CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 3.9)
|
||||
set(_CMAKE_LTO_THIN FALSE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(_CMAKE_LTO_THIN)
|
||||
set(CMAKE_${lang}_COMPILE_OPTIONS_IPO "-flto=thin")
|
||||
else()
|
||||
set(CMAKE_${lang}_COMPILE_OPTIONS_IPO "-flto")
|
||||
endif()
|
||||
|
||||
if(ANDROID)
|
||||
# https://github.com/android-ndk/ndk/issues/242
|
||||
set(CMAKE_${lang}_LINK_OPTIONS_IPO "-fuse-ld=gold")
|
||||
endif()
|
||||
|
||||
if(ANDROID OR __is_apple_clang)
|
||||
set(__ar "${CMAKE_AR}")
|
||||
set(__ranlib "${CMAKE_RANLIB}")
|
||||
else()
|
||||
set(__ar "${CMAKE_${lang}_COMPILER_AR}")
|
||||
set(__ranlib "${CMAKE_${lang}_COMPILER_RANLIB}")
|
||||
endif()
|
||||
|
||||
set(CMAKE_${lang}_ARCHIVE_CREATE_IPO
|
||||
"${__ar} cr <TARGET> <LINK_FLAGS> <OBJECTS>"
|
||||
)
|
||||
|
||||
set(CMAKE_${lang}_ARCHIVE_APPEND_IPO
|
||||
"${__ar} r <TARGET> <LINK_FLAGS> <OBJECTS>"
|
||||
)
|
||||
|
||||
set(CMAKE_${lang}_ARCHIVE_FINISH_IPO
|
||||
"${__ranlib} <TARGET>"
|
||||
)
|
||||
endmacro()
|
||||
endif()
|
||||
|
@ -915,6 +915,9 @@ void cmLocalGenerator::GetTargetFlags(
|
||||
const char* libraryLinkVariable =
|
||||
"CMAKE_SHARED_LINKER_FLAGS"; // default to shared library
|
||||
|
||||
const std::string linkLanguage =
|
||||
linkLineComputer->GetLinkerLanguage(target, buildType);
|
||||
|
||||
switch (target->GetType()) {
|
||||
case cmStateEnums::STATIC_LIBRARY:
|
||||
this->GetStaticLibraryFlags(linkFlags, buildType, target);
|
||||
@ -976,9 +979,6 @@ void cmLocalGenerator::GetTargetFlags(
|
||||
linkFlags += this->Makefile->GetSafeDefinition(build);
|
||||
linkFlags += " ";
|
||||
}
|
||||
|
||||
const std::string linkLanguage =
|
||||
linkLineComputer->GetLinkerLanguage(target, buildType);
|
||||
if (linkLanguage.empty()) {
|
||||
cmSystemTools::Error(
|
||||
"CMake can not determine linker language for target: ",
|
||||
@ -1040,6 +1040,8 @@ void cmLocalGenerator::GetTargetFlags(
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
this->AppendIPOLinkerFlags(linkFlags, target, config, linkLanguage);
|
||||
}
|
||||
|
||||
void cmLocalGenerator::GetTargetCompileFlags(cmGeneratorTarget* target,
|
||||
@ -1769,6 +1771,38 @@ void cmLocalGenerator::AppendFlagEscape(std::string& flags,
|
||||
this->AppendFlags(flags, this->EscapeForShell(rawFlag));
|
||||
}
|
||||
|
||||
void cmLocalGenerator::AppendIPOLinkerFlags(std::string& flags,
|
||||
cmGeneratorTarget* target,
|
||||
const std::string& config,
|
||||
const std::string& lang)
|
||||
{
|
||||
if (!target->IsIPOEnabled(config)) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (target->GetType()) {
|
||||
case cmStateEnums::EXECUTABLE:
|
||||
case cmStateEnums::SHARED_LIBRARY:
|
||||
case cmStateEnums::MODULE_LIBRARY:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string name = "CMAKE_" + lang + "_LINK_OPTIONS_IPO";
|
||||
const char* rawFlagsList = this->Makefile->GetDefinition(name);
|
||||
if (rawFlagsList == CM_NULLPTR) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<std::string> flagsList;
|
||||
cmSystemTools::ExpandListArgument(rawFlagsList, flagsList);
|
||||
for (std::vector<std::string>::const_iterator oi = flagsList.begin();
|
||||
oi != flagsList.end(); ++oi) {
|
||||
this->AppendFlagEscape(flags, *oi);
|
||||
}
|
||||
}
|
||||
|
||||
void cmLocalGenerator::AppendDefines(std::set<std::string>& defines,
|
||||
const char* defines_list) const
|
||||
{
|
||||
|
@ -115,6 +115,9 @@ public:
|
||||
virtual void AppendFlags(std::string& flags, const char* newFlags);
|
||||
virtual void AppendFlagEscape(std::string& flags,
|
||||
const std::string& rawFlag);
|
||||
void AppendIPOLinkerFlags(std::string& flags, cmGeneratorTarget* target,
|
||||
const std::string& config,
|
||||
const std::string& lang);
|
||||
///! Get the include flags for the current makefile and language
|
||||
std::string GetIncludeFlags(const std::vector<std::string>& includes,
|
||||
cmGeneratorTarget* target,
|
||||
|
@ -457,6 +457,9 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
|
||||
this->AddModuleDefinitionFlag(linkLineComputer.get(), linkFlags);
|
||||
}
|
||||
|
||||
this->LocalGenerator->AppendIPOLinkerFlags(linkFlags, this->GeneratorTarget,
|
||||
this->ConfigName, linkLanguage);
|
||||
|
||||
// Construct a list of files associated with this executable that
|
||||
// may need to be cleaned.
|
||||
std::vector<std::string> exeCleanFiles;
|
||||
|
@ -494,6 +494,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
|
||||
// Create set of linking flags.
|
||||
std::string linkFlags;
|
||||
this->LocalGenerator->AppendFlags(linkFlags, extraFlags);
|
||||
this->LocalGenerator->AppendIPOLinkerFlags(linkFlags, this->GeneratorTarget,
|
||||
this->ConfigName, linkLanguage);
|
||||
|
||||
// Add OSX version flags, if any.
|
||||
if (this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY ||
|
||||
|
Loading…
Reference in New Issue
Block a user