mirror of
https://github.com/Kitware/CMake.git
synced 2026-02-21 14:40:26 -06:00
Merge topic '16680-ios-bundle-resources'
b5189fdaApple: Add test for bundle resource layoutc51c2cfaApple: Fix Resources location for all generators060be58cXcode: Properly handle Bundle Resources with more than one hierarchy level484ccb0cXcode: Properly handle non-resource Bundle files on iOS Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !613
This commit is contained in:
@@ -21,3 +21,10 @@ extension is changed). See the :prop_tgt:`PUBLIC_HEADER`,
|
||||
:prop_tgt:`PRIVATE_HEADER`, and :prop_tgt:`RESOURCE` target properties for
|
||||
specifying files meant for ``Headers``, ``PrivateHeaders``, or
|
||||
``Resources`` directories.
|
||||
|
||||
If the specified location is equal to ``Resources``, the resulting location
|
||||
will be the same as if the :prop_tgt:`RESOURCE` property had been used. If
|
||||
the specified location is a sub-folder of ``Resources``, it will be placed
|
||||
into the respective sub-folder. Note: For iOS Apple uses a flat bundle layout
|
||||
where no ``Resources`` folder exist. Therefore CMake strips the ``Resources``
|
||||
folder name from the specified location.
|
||||
|
||||
@@ -3315,8 +3315,18 @@ cmGeneratorTarget::GetTargetSourceFileFlags(const cmSourceFile* sf) const
|
||||
// were not listed in one of the other lists.
|
||||
if (const char* location = sf->GetProperty("MACOSX_PACKAGE_LOCATION")) {
|
||||
flags.MacFolder = location;
|
||||
const bool stripResources =
|
||||
this->GlobalGenerator->ShouldStripResourcePath(this->Makefile);
|
||||
if (strcmp(location, "Resources") == 0) {
|
||||
flags.Type = cmGeneratorTarget::SourceFileTypeResource;
|
||||
if (stripResources) {
|
||||
flags.MacFolder = "";
|
||||
}
|
||||
} else if (cmSystemTools::StringStartsWith(location, "Resources/")) {
|
||||
flags.Type = cmGeneratorTarget::SourceFileTypeDeepResource;
|
||||
if (stripResources) {
|
||||
flags.MacFolder += strlen("Resources/");
|
||||
}
|
||||
} else {
|
||||
flags.Type = cmGeneratorTarget::SourceFileTypeMacContent;
|
||||
}
|
||||
@@ -3370,7 +3380,7 @@ void cmGeneratorTarget::ConstructSourceFileFlags() const
|
||||
if (cmSourceFile* sf = this->Makefile->GetSource(*it)) {
|
||||
SourceFileFlags& flags = this->SourceFlagsMap[sf];
|
||||
flags.MacFolder = "";
|
||||
if (!this->Makefile->PlatformIsAppleIos()) {
|
||||
if (!this->GlobalGenerator->ShouldStripResourcePath(this->Makefile)) {
|
||||
flags.MacFolder = "Resources";
|
||||
}
|
||||
flags.Type = cmGeneratorTarget::SourceFileTypeResource;
|
||||
|
||||
@@ -422,7 +422,9 @@ public:
|
||||
SourceFileTypePublicHeader, // is in "PUBLIC_HEADER" target property
|
||||
SourceFileTypeResource, // is in "RESOURCE" target property *or*
|
||||
// has MACOSX_PACKAGE_LOCATION=="Resources"
|
||||
SourceFileTypeMacContent // has MACOSX_PACKAGE_LOCATION!="Resources"
|
||||
SourceFileTypeDeepResource, // MACOSX_PACKAGE_LOCATION starts with
|
||||
// "Resources/"
|
||||
SourceFileTypeMacContent // has MACOSX_PACKAGE_LOCATION!="Resources[/]"
|
||||
};
|
||||
struct SourceFileFlags
|
||||
{
|
||||
|
||||
@@ -2487,6 +2487,11 @@ std::string cmGlobalGenerator::GenerateRuleFile(
|
||||
return ruleFile;
|
||||
}
|
||||
|
||||
bool cmGlobalGenerator::ShouldStripResourcePath(cmMakefile* mf) const
|
||||
{
|
||||
return mf->PlatformIsAppleIos();
|
||||
}
|
||||
|
||||
std::string cmGlobalGenerator::GetSharedLibFlagsForLanguage(
|
||||
std::string const& l) const
|
||||
{
|
||||
|
||||
@@ -337,6 +337,10 @@ public:
|
||||
relevant for mixed macOS and iOS builds. */
|
||||
virtual bool UseEffectivePlatformName(cmMakefile*) const { return false; }
|
||||
|
||||
/** Return whether the "Resources" folder prefix should be stripped from
|
||||
MacFolder. */
|
||||
virtual bool ShouldStripResourcePath(cmMakefile*) const;
|
||||
|
||||
std::string GetSharedLibFlagsForLanguage(std::string const& lang) const;
|
||||
|
||||
/** Generate an <output>.rule file path for a given command output. */
|
||||
|
||||
@@ -1154,8 +1154,12 @@ bool cmGlobalXCodeGenerator::CreateXCodeTargets(
|
||||
// dstPath in frameworks is relative to Versions/<version>
|
||||
ostr << mit->first;
|
||||
} else if (mit->first != "MacOS") {
|
||||
// dstPath in bundles is relative to Contents/MacOS
|
||||
ostr << "../" << mit->first.c_str();
|
||||
if (gtgt->Target->GetMakefile()->PlatformIsAppleIos()) {
|
||||
ostr << mit->first;
|
||||
} else {
|
||||
// dstPath in bundles is relative to Contents/MacOS
|
||||
ostr << "../" << mit->first;
|
||||
}
|
||||
}
|
||||
copyFilesBuildPhase->AddAttribute("dstPath",
|
||||
this->CreateString(ostr.str()));
|
||||
@@ -1173,6 +1177,45 @@ bool cmGlobalXCodeGenerator::CreateXCodeTargets(
|
||||
}
|
||||
}
|
||||
|
||||
// create vector of "resource content file" build phases - only for
|
||||
// framework or bundle targets
|
||||
if (isFrameworkTarget || isBundleTarget || isCFBundleTarget) {
|
||||
typedef std::map<std::string, std::vector<cmSourceFile*> >
|
||||
mapOfVectorOfSourceFiles;
|
||||
mapOfVectorOfSourceFiles bundleFiles;
|
||||
for (std::vector<cmSourceFile*>::const_iterator i = classes.begin();
|
||||
i != classes.end(); ++i) {
|
||||
cmGeneratorTarget::SourceFileFlags tsFlags =
|
||||
gtgt->GetTargetSourceFileFlags(*i);
|
||||
if (tsFlags.Type == cmGeneratorTarget::SourceFileTypeDeepResource) {
|
||||
bundleFiles[tsFlags.MacFolder].push_back(*i);
|
||||
}
|
||||
}
|
||||
mapOfVectorOfSourceFiles::iterator mit;
|
||||
for (mit = bundleFiles.begin(); mit != bundleFiles.end(); ++mit) {
|
||||
cmXCodeObject* copyFilesBuildPhase =
|
||||
this->CreateObject(cmXCodeObject::PBXCopyFilesBuildPhase);
|
||||
copyFilesBuildPhase->SetComment("Copy files");
|
||||
copyFilesBuildPhase->AddAttribute("buildActionMask",
|
||||
this->CreateString("2147483647"));
|
||||
copyFilesBuildPhase->AddAttribute("dstSubfolderSpec",
|
||||
this->CreateString("7"));
|
||||
copyFilesBuildPhase->AddAttribute("dstPath",
|
||||
this->CreateString(mit->first));
|
||||
copyFilesBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing",
|
||||
this->CreateString("0"));
|
||||
buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
|
||||
copyFilesBuildPhase->AddAttribute("files", buildFiles);
|
||||
std::vector<cmSourceFile*>::iterator sfIt;
|
||||
for (sfIt = mit->second.begin(); sfIt != mit->second.end(); ++sfIt) {
|
||||
cmXCodeObject* xsf = this->CreateXCodeSourceFile(
|
||||
this->CurrentLocalGenerator, *sfIt, gtgt);
|
||||
buildFiles->AddObject(xsf);
|
||||
}
|
||||
contentBuildPhases.push_back(copyFilesBuildPhase);
|
||||
}
|
||||
}
|
||||
|
||||
// create framework build phase
|
||||
cmXCodeObject* frameworkBuildPhase = 0;
|
||||
if (!externalObjFiles.empty()) {
|
||||
@@ -3657,6 +3700,12 @@ bool cmGlobalXCodeGenerator::UseEffectivePlatformName(cmMakefile* mf) const
|
||||
return cmSystemTools::IsOn(epnValue);
|
||||
}
|
||||
|
||||
bool cmGlobalXCodeGenerator::ShouldStripResourcePath(cmMakefile*) const
|
||||
{
|
||||
// Xcode determines Resource location itself
|
||||
return true;
|
||||
}
|
||||
|
||||
void cmGlobalXCodeGenerator::ComputeTargetObjectDirectory(
|
||||
cmGeneratorTarget* gt) const
|
||||
{
|
||||
|
||||
@@ -88,6 +88,8 @@ public:
|
||||
|
||||
bool UseEffectivePlatformName(cmMakefile* mf) const CM_OVERRIDE;
|
||||
|
||||
bool ShouldStripResourcePath(cmMakefile*) const CM_OVERRIDE;
|
||||
|
||||
bool SetGeneratorToolset(std::string const& ts, cmMakefile* mf) CM_OVERRIDE;
|
||||
void AppendFlag(std::string& flags, std::string const& flag);
|
||||
|
||||
|
||||
@@ -4,11 +4,17 @@ enable_language(C)
|
||||
add_library(Framework ${FRAMEWORK_TYPE}
|
||||
foo.c
|
||||
foo.h
|
||||
res.txt)
|
||||
res.txt
|
||||
flatresource.txt
|
||||
deepresource.txt
|
||||
some.txt)
|
||||
set_target_properties(Framework PROPERTIES
|
||||
FRAMEWORK TRUE
|
||||
PUBLIC_HEADER foo.h
|
||||
RESOURCE "res.txt")
|
||||
set_source_files_properties(flatresource.txt PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
|
||||
set_source_files_properties(deepresource.txt PROPERTIES MACOSX_PACKAGE_LOCATION Resources/deep)
|
||||
set_source_files_properties(some.txt PROPERTIES MACOSX_PACKAGE_LOCATION somedir)
|
||||
|
||||
add_custom_command(TARGET Framework POST_BUILD
|
||||
COMMAND /usr/bin/file $<TARGET_FILE:Framework>)
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
set(framework-dir "${RunCMake_TEST_BINARY_DIR}/Framework.framework")
|
||||
set(framework-resources "${framework-dir}/Resources")
|
||||
set(framework-resource-file "${framework-resources}/res.txt")
|
||||
set(framework-flat-resource-file "${framework-resources}/flatresource.txt")
|
||||
set(framework-deep-resource-file "${framework-resources}/deep/deepresource.txt")
|
||||
set(framework-library "${framework-dir}/Framework")
|
||||
set(framework-versions "${framework-dir}/Versions")
|
||||
set(framework-some-file "${framework-versions}/Current/somedir/some.txt")
|
||||
set(plist-file "${framework-resources}/Info.plist")
|
||||
set(framework-header "${framework-dir}/Headers/foo.h")
|
||||
|
||||
@@ -22,6 +25,18 @@ if(NOT EXISTS ${framework-resource-file})
|
||||
message(SEND_ERROR "Framework resource file not found at ${framework-resource-file}")
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS ${framework-flat-resource-file})
|
||||
message(SEND_ERROR "Framework flat resource file not found at ${framework-flat-resource-file}")
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS ${framework-deep-resource-file})
|
||||
message(SEND_ERROR "Framework deep resource file not found at ${framework-deep-resource-file}")
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS ${framework-some-file})
|
||||
message(SEND_ERROR "Framework some file not found at ${framework-some-file}")
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS ${framework-versions})
|
||||
message(SEND_ERROR "Framework versions not found at ${framework-versions}")
|
||||
endif()
|
||||
|
||||
0
Tests/RunCMake/Framework/deepresource.txt
Normal file
0
Tests/RunCMake/Framework/deepresource.txt
Normal file
0
Tests/RunCMake/Framework/flatresource.txt
Normal file
0
Tests/RunCMake/Framework/flatresource.txt
Normal file
@@ -1,6 +1,9 @@
|
||||
set(framework-dir "${RunCMake_TEST_BINARY_DIR}/Framework.framework")
|
||||
set(framework-resources "${framework-dir}/Resources")
|
||||
set(framework-resource-file "${framework-dir}/res.txt")
|
||||
set(framework-flat-resource-file "${framework-dir}/flatresource.txt")
|
||||
set(framework-deep-resource-file "${framework-dir}/deep/deepresource.txt")
|
||||
set(framework-some-file "${framework-dir}/somedir/some.txt")
|
||||
set(framework-library "${framework-dir}/Framework")
|
||||
set(framework-versions "${framework-dir}/Versions")
|
||||
set(plist-file "${framework-dir}/Info.plist")
|
||||
@@ -22,6 +25,18 @@ if(NOT EXISTS ${framework-resource-file})
|
||||
message(SEND_ERROR "Framework resource file not found at ${framework-resource-file}")
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS ${framework-flat-resource-file})
|
||||
message(SEND_ERROR "Framework flat resource file not found at ${framework-flat-resource-file}")
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS ${framework-deep-resource-file})
|
||||
message(SEND_ERROR "Framework deep resource file not found at ${framework-deep-resource-file}")
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS ${framework-some-file})
|
||||
message(SEND_ERROR "Framework some file not found at ${framework-some-file}")
|
||||
endif()
|
||||
|
||||
if(EXISTS ${framework-versions})
|
||||
message(SEND_ERROR "Framework versions found at ${framework-versions}")
|
||||
endif()
|
||||
|
||||
0
Tests/RunCMake/Framework/some.txt
Normal file
0
Tests/RunCMake/Framework/some.txt
Normal file
Reference in New Issue
Block a user