macOS: Do not pass Apple-specific flags to llvm-strip

Since commit cf82300a63 (BinUtils: Clarify search logic and make it more
consistent, 2021-05-27, v3.21.0-rc1~119^2~2) we prefer `llvm-strip` over
`strip` when using Clang.  However, since commit 20291e8e72 (install:
Fix stripping on macOS, 2019-01-30, v3.14.0-rc1~31^2) on macOS we add
flags `-u -r`, needed by Apple's `strip` for executables, but that
`llvm-strip` does not need or support.  Improve the condition to add
Apple-specific flags only when the selected `strip` tool is Apple's.

Note that Apple dylibs must be stripped with `-x` with either Apple's
`strip` or `llvm-strip`.

Fixes: #24601
stage/master/nightly/2023/03/30
Brad King 2023-03-28 17:28:44 -04:00
parent f4b8176447
commit 689616785f
4 changed files with 51 additions and 9 deletions

View File

@ -3542,3 +3542,32 @@ cmInstallRuntimeDependencySet* cmGlobalGenerator::GetNamedRuntimeDependencySet(
}
return it->second;
}
cmGlobalGenerator::StripCommandStyle cmGlobalGenerator::GetStripCommandStyle(
std::string const& strip)
{
#ifdef __APPLE__
auto i = this->StripCommandStyleMap.find(strip);
if (i == this->StripCommandStyleMap.end()) {
StripCommandStyle style = StripCommandStyle::Default;
// Try running strip tool with Apple-specific options.
std::vector<std::string> cmd{ strip, "-u", "-r" };
std::string out;
std::string err;
int ret;
if (cmSystemTools::RunSingleCommand(cmd, &out, &err, &ret, nullptr,
cmSystemTools::OUTPUT_NONE) &&
// Check for Apple-specific output.
ret != 0 && cmHasLiteralPrefix(err, "fatal error: /") &&
err.find("/usr/bin/strip: no files specified") != std::string::npos) {
style = StripCommandStyle::Apple;
}
i = this->StripCommandStyleMap.emplace(strip, style).first;
}
return i->second;
#else
static_cast<void>(strip);
return StripCommandStyle::Default;
#endif
}

View File

@ -607,6 +607,13 @@ public:
cmInstallRuntimeDependencySet* GetNamedRuntimeDependencySet(
const std::string& name);
enum class StripCommandStyle
{
Default,
Apple,
};
StripCommandStyle GetStripCommandStyle(std::string const& strip);
protected:
// for a project collect all its targets by following depend
// information, and also collect all the targets
@ -737,6 +744,10 @@ private:
std::map<std::string, int> LanguageToLinkerPreference;
std::map<std::string, std::string> LanguageToOriginalSharedLibFlags;
#ifdef __APPLE__
std::map<std::string, StripCommandStyle> StripCommandStyleMap;
#endif
mutable bool DiagnosedCxxModuleSupport = false;
// Deferral id generation.

View File

@ -256,8 +256,7 @@ void cmInstallRuntimeDependencySetGenerator::GenerateStripFixup(
if (!strip.empty()) {
os << indent << "if(CMAKE_INSTALL_DO_STRIP)\n"
<< indent.Next() << "execute_process(COMMAND \"" << strip << "\" ";
if (this->LocalGenerator->GetMakefile()->GetSafeDefinition(
"CMAKE_HOST_SYSTEM_NAME") == "Darwin") {
if (this->LocalGenerator->GetMakefile()->IsOn("APPLE")) {
os << "-x ";
}
os << "\""

View File

@ -826,26 +826,29 @@ void cmInstallTargetGenerator::AddStripRule(std::ostream& os, Indent indent,
return;
}
if (!this->Target->Target->GetMakefile()->IsSet("CMAKE_STRIP")) {
std::string const& strip =
this->Target->Target->GetMakefile()->GetSafeDefinition("CMAKE_STRIP");
if (strip.empty()) {
return;
}
std::string stripArgs;
// macOS 'strip' is picky, executables need '-u -r' and dylibs need '-x'.
if (this->Target->IsApple()) {
if (this->Target->GetType() == cmStateEnums::SHARED_LIBRARY ||
this->Target->GetType() == cmStateEnums::MODULE_LIBRARY) {
// Strip tools need '-x' to strip Apple dylibs correctly.
stripArgs = "-x ";
} else if (this->Target->GetType() == cmStateEnums::EXECUTABLE) {
} else if (this->Target->GetType() == cmStateEnums::EXECUTABLE &&
this->Target->GetGlobalGenerator()->GetStripCommandStyle(
strip) == cmGlobalGenerator::StripCommandStyle::Apple) {
// Apple's strip tool needs '-u -r' to strip executables correctly.
stripArgs = "-u -r ";
}
}
os << indent << "if(CMAKE_INSTALL_DO_STRIP)\n";
os << indent << " execute_process(COMMAND \""
<< this->Target->Target->GetMakefile()->GetSafeDefinition("CMAKE_STRIP")
<< "\" " << stripArgs << "\"" << toDestDirPath << "\")\n";
os << indent << " execute_process(COMMAND \"" << strip << "\" " << stripArgs
<< "\"" << toDestDirPath << "\")\n";
os << indent << "endif()\n";
}