Define per-target OSX_ARCHITECTURES property

The CMAKE_OSX_ARCHITECTURES variable works only as a global setting.
This commit defines target properties

  OSX_ARCHITECTURES
  OSX_ARCHITECTURES_<CONFIG>

to specify OS X architectures on a per-target and per-configuration
basis.  See issue #8725.
This commit is contained in:
Brad King 2009-10-21 13:00:49 -04:00
parent 2f94a2c919
commit 2dc39b8c32
8 changed files with 112 additions and 25 deletions

View File

@ -1515,6 +1515,34 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
extraLinkOptions += targetLinkFlags; extraLinkOptions += targetLinkFlags;
} }
// Set target-specific architectures.
std::vector<std::string> archs;
target.GetAppleArchs(configName, archs);
if(!archs.empty())
{
// Enable ARCHS attribute.
buildSettings->AddAttribute("ONLY_ACTIVE_ARCH",
this->CreateString("NO"));
// Store ARCHS value.
if(archs.size() == 1)
{
buildSettings->AddAttribute("ARCHS",
this->CreateString(archs[0].c_str()));
}
else
{
cmXCodeObject* archObjects =
this->CreateObject(cmXCodeObject::OBJECT_LIST);
for(std::vector<std::string>::iterator i = archs.begin();
i != archs.end(); i++)
{
archObjects->AddObject(this->CreateString((*i).c_str()));
}
buildSettings->AddAttribute("ARCHS", archObjects);
}
}
// Get the product name components. // Get the product name components.
std::string pnprefix; std::string pnprefix;
std::string pnbase; std::string pnbase;

View File

@ -712,6 +712,9 @@ void cmLocalGenerator::AddBuildTargetRule(const char* llang, cmTarget& target)
std::string langFlags; std::string langFlags;
this->AddLanguageFlags(langFlags, llang, 0); this->AddLanguageFlags(langFlags, llang, 0);
#ifdef __APPLE__
this->AddArchitectureFlags(langFlags, &target, llang, 0);
#endif /* __APPLE__ */
vars.LanguageCompileFlags = langFlags.c_str(); vars.LanguageCompileFlags = langFlags.c_str();
cmCustomCommandLines commandLines; cmCustomCommandLines commandLines;
@ -1751,21 +1754,18 @@ void cmLocalGenerator::OutputLinkLibraries(std::ostream& fout,
} }
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void cmLocalGenerator::AddLanguageFlags(std::string& flags,
const char* lang,
const char* config)
{
// Add language-specific flags.
std::string flagsVar = "CMAKE_";
flagsVar += lang;
flagsVar += "_FLAGS";
// Add special OSX flags
#ifdef __APPLE__ #ifdef __APPLE__
void cmLocalGenerator::AddArchitectureFlags(std::string& flags,
cmTarget* target,
const char *lang,
const char* config)
{
if(this->EmitUniversalBinaryFlags) if(this->EmitUniversalBinaryFlags)
{ {
const char* osxArch = std::vector<std::string> archs;
this->Makefile->GetDefinition("CMAKE_OSX_ARCHITECTURES"); target->GetAppleArchs(config, archs);
const char* sysroot = const char* sysroot =
this->Makefile->GetDefinition("CMAKE_OSX_SYSROOT"); this->Makefile->GetDefinition("CMAKE_OSX_SYSROOT");
const char* sysrootDefault = const char* sysrootDefault =
@ -1775,24 +1775,13 @@ void cmLocalGenerator::AddLanguageFlags(std::string& flags,
std::string isysrootVar = std::string("CMAKE_") + lang + "_HAS_ISYSROOT"; std::string isysrootVar = std::string("CMAKE_") + lang + "_HAS_ISYSROOT";
bool hasIsysroot = this->Makefile->IsOn(isysrootVar.c_str()); bool hasIsysroot = this->Makefile->IsOn(isysrootVar.c_str());
bool flagsUsed = false; bool flagsUsed = false;
if(osxArch && sysroot && lang && (lang[0] =='C' || lang[0] == 'F')) if(!archs.empty() && sysroot && lang && (lang[0] =='C' || lang[0] == 'F'))
{ {
std::vector<std::string> archs;
cmSystemTools::ExpandListArgument(std::string(osxArch),
archs);
bool addArchFlag = false;
if(archs.size() >= 1)
{
if(archs[0] != "")
{
addArchFlag = true;
}
}
// if there is more than one arch add the -arch and // if there is more than one arch add the -arch and
// -isysroot flags, or if there is one arch flag, but // -isysroot flags, or if there is one arch flag, but
// it is not the default -arch flag for the system, then // it is not the default -arch flag for the system, then
// add it. Otherwize do not add -arch and -isysroot // add it. Otherwize do not add -arch and -isysroot
if(addArchFlag) if(archs[0] != "")
{ {
for( std::vector<std::string>::iterator i = archs.begin(); for( std::vector<std::string>::iterator i = archs.begin();
i != archs.end(); ++i) i != archs.end(); ++i)
@ -1823,7 +1812,19 @@ void cmLocalGenerator::AddLanguageFlags(std::string& flags,
flags += deploymentTarget; flags += deploymentTarget;
} }
} }
#endif }
#endif /* __APPLE__ */
//----------------------------------------------------------------------------
void cmLocalGenerator::AddLanguageFlags(std::string& flags,
const char* lang,
const char* config)
{
// Add language-specific flags.
std::string flagsVar = "CMAKE_";
flagsVar += lang;
flagsVar += "_FLAGS";
this->AddConfigVariableFlags(flags, flagsVar.c_str(), config); this->AddConfigVariableFlags(flags, flagsVar.c_str(), config);
} }

View File

@ -133,6 +133,10 @@ public:
std::vector<cmLocalGenerator*>& GetChildren() { return this->Children; }; std::vector<cmLocalGenerator*>& GetChildren() { return this->Children; };
#ifdef __APPLE__
void AddArchitectureFlags(std::string& flags, cmTarget* target, const char *lang, const char* config);
#endif /* __APPLE__ */
void AddLanguageFlags(std::string& flags, const char* lang, void AddLanguageFlags(std::string& flags, const char* lang,
const char* config); const char* config);
void AddSharedFlags(std::string& flags, const char* lang, bool shared); void AddSharedFlags(std::string& flags, const char* lang, bool shared);

View File

@ -229,6 +229,10 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
// Add language feature flags. // Add language feature flags.
this->AddFeatureFlags(flags, linkLanguage); this->AddFeatureFlags(flags, linkLanguage);
#ifdef __APPLE__
this->LocalGenerator->AddArchitectureFlags(flags, this->Target, linkLanguage, this->ConfigName);
#endif /* __APPLE__ */
// Add target-specific linker flags. // Add target-specific linker flags.
this->LocalGenerator->AppendFlags this->LocalGenerator->AppendFlags
(linkFlags, this->Target->GetProperty("LINK_FLAGS")); (linkFlags, this->Target->GetProperty("LINK_FLAGS"));

View File

@ -682,6 +682,10 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
std::string langFlags; std::string langFlags;
this->AddFeatureFlags(langFlags, linkLanguage); this->AddFeatureFlags(langFlags, linkLanguage);
#ifdef __APPLE__
this->LocalGenerator->AddArchitectureFlags(langFlags, this->Target, linkLanguage, this->ConfigName);
#endif /* __APPLE__ */
// remove any language flags that might not work with the // remove any language flags that might not work with the
// particular os // particular os
if(forbiddenFlagVar) if(forbiddenFlagVar)

View File

@ -294,6 +294,10 @@ void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
// Add language feature flags. // Add language feature flags.
this->AddFeatureFlags(flags, lang); this->AddFeatureFlags(flags, lang);
#ifdef __APPLE__
this->LocalGenerator->AddArchitectureFlags(flags, this->Target, lang, this->ConfigName);
#endif /* __APPLE__ */
// Fortran-specific flags computed for this target. // Fortran-specific flags computed for this target.
if(*l == "Fortran") if(*l == "Fortran")
{ {

View File

@ -572,6 +572,23 @@ void cmTarget::DefineProperties(cmake *cm)
"This property is ignored for non-imported targets.", "This property is ignored for non-imported targets.",
false /* TODO: make this chained */ ); false /* TODO: make this chained */ );
cm->DefineProperty
("OSX_ARCHITECTURES", cmProperty::TARGET,
"Target specific architectures for OS X.",
"The OSX_ARCHITECTURES property sets the target binary architecture "
"for targets on OS X. "
"This property is initialized by the value of the variable "
"CMAKE_OSX_ARCHITECTURES if it is set when a target is created. "
"Use OSX_ARCHITECTURES_<CONFIG> to set the binary architectures on a "
"per-configuration basis. "
"<CONFIG> is an upper-case name (ex: \"OSX_ARCHITECTURES_DEBUG\").");
cm->DefineProperty
("OSX_ARCHITECTURES_<CONFIG>", cmProperty::TARGET,
"Per-configuration OS X binary architectures for a target.",
"This property is the configuration-specific version of "
"OSX_ARCHITECTURES.");
cm->DefineProperty cm->DefineProperty
("OUTPUT_NAME", cmProperty::TARGET, ("OUTPUT_NAME", cmProperty::TARGET,
"Output name for target files.", "Output name for target files.",
@ -988,6 +1005,7 @@ void cmTarget::SetMakefile(cmMakefile* mf)
this->SetPropertyDefault("LIBRARY_OUTPUT_DIRECTORY", 0); this->SetPropertyDefault("LIBRARY_OUTPUT_DIRECTORY", 0);
this->SetPropertyDefault("RUNTIME_OUTPUT_DIRECTORY", 0); this->SetPropertyDefault("RUNTIME_OUTPUT_DIRECTORY", 0);
this->SetPropertyDefault("Fortran_MODULE_DIRECTORY", 0); this->SetPropertyDefault("Fortran_MODULE_DIRECTORY", 0);
this->SetPropertyDefault("OSX_ARCHITECTURES", 0);
// Collect the set of configuration types. // Collect the set of configuration types.
std::vector<std::string> configNames; std::vector<std::string> configNames;
@ -3652,6 +3670,27 @@ void cmTarget::GetLanguages(std::set<cmStdString>& languages) const
} }
} }
//----------------------------------------------------------------------------
void cmTarget::GetAppleArchs(const char* config,
std::vector<std::string>& archVec)
{
const char* archs = 0;
if(config && *config)
{
std::string defVarName = "OSX_ARCHITECTURES_";
defVarName += cmSystemTools::UpperCase(config);
archs = this->GetProperty(defVarName.c_str());
}
if(!archs)
{
archs = this->GetProperty("OSX_ARCHITECTURES");
}
if(archs)
{
cmSystemTools::ExpandListArgument(std::string(archs), archVec);
}
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool cmTarget::IsChrpathUsed(const char* config) bool cmTarget::IsChrpathUsed(const char* config)
{ {

View File

@ -410,6 +410,9 @@ public:
// until we have per-target object file properties. // until we have per-target object file properties.
void GetLanguages(std::set<cmStdString>& languages) const; void GetLanguages(std::set<cmStdString>& languages) const;
/** Get the list of OS X target architectures to be built. */
void GetAppleArchs(const char* config, std::vector<std::string>& archVec);
/** Return whether this target is an executable with symbol exports /** Return whether this target is an executable with symbol exports
enabled. */ enabled. */
bool IsExecutableWithExports(); bool IsExecutableWithExports();