Xcode: Add source file property to control file type (#14854)

Add source file properties to control Xcode file type attributes:

  XCODE_EXPLICIT_FILE_TYPE   => explicitFileType
  XCODE_LAST_KNOWN_FILE_TYPE => lastKnownFileType

Add a RunCMake.XcodeProject test to verify generated project content.
This commit is contained in:
Brad King 2014-05-15 13:50:53 -04:00
parent ae80cb9f28
commit a339ea6529
15 changed files with 75 additions and 8 deletions

View File

@ -289,6 +289,8 @@ Properties on Source Files
/prop_sf/OBJECT_OUTPUTS /prop_sf/OBJECT_OUTPUTS
/prop_sf/SYMBOLIC /prop_sf/SYMBOLIC
/prop_sf/WRAP_EXCLUDE /prop_sf/WRAP_EXCLUDE
/prop_sf/XCODE_EXPLICIT_FILE_TYPE
/prop_sf/XCODE_LAST_KNOWN_FILE_TYPE
Properties on Cache Entries Properties on Cache Entries
=========================== ===========================

View File

@ -0,0 +1,8 @@
XCODE_EXPLICIT_FILE_TYPE
------------------------
Set the Xcode ``explicitFileType`` attribute on its reference to a
source file. CMake computes a default based on file extension but
can be told explicitly with this property.
See also :prop_sf:`XCODE_LAST_KNOWN_FILE_TYPE`.

View File

@ -0,0 +1,9 @@
XCODE_LAST_KNOWN_FILE_TYPE
--------------------------
Set the Xcode ``lastKnownFileType`` attribute on its reference to a
source file. CMake computes a default based on file extension but
can be told explicitly with this property.
See also :prop_sf:`XCODE_EXPLICIT_FILE_TYPE`, which is preferred
over this property if set.

View File

@ -0,0 +1,7 @@
xcode-file-type
---------------
* The :generator:`Xcode` generator learned to check source
file properties :prop_sf:`XCODE_EXPLICIT_FILE_TYPE` and
:prop_sf:`XCODE_LAST_KNOWN_FILE_TYPE` for a custom Xcode
file reference type.

View File

@ -647,13 +647,14 @@ cmXCodeObject*
cmGlobalXCodeGenerator::CreateXCodeSourceFileFromPath( cmGlobalXCodeGenerator::CreateXCodeSourceFileFromPath(
const std::string &fullpath, const std::string &fullpath,
cmTarget& cmtarget, cmTarget& cmtarget,
const std::string &lang) const std::string &lang,
cmSourceFile* sf)
{ {
// Using a map and the full path guarantees that we will always get the same // Using a map and the full path guarantees that we will always get the same
// fileRef object for any given full path. // fileRef object for any given full path.
// //
cmXCodeObject* fileRef = cmXCodeObject* fileRef =
this->CreateXCodeFileReferenceFromPath(fullpath, cmtarget, lang); this->CreateXCodeFileReferenceFromPath(fullpath, cmtarget, lang, sf);
cmXCodeObject* buildFile = this->CreateObject(cmXCodeObject::PBXBuildFile); cmXCodeObject* buildFile = this->CreateObject(cmXCodeObject::PBXBuildFile);
buildFile->SetComment(fileRef->GetComment()); buildFile->SetComment(fileRef->GetComment());
@ -696,7 +697,7 @@ cmGlobalXCodeGenerator::CreateXCodeSourceFile(cmLocalGenerator* lg,
this->CurrentLocalGenerator->GetSourceFileLanguage(*sf); this->CurrentLocalGenerator->GetSourceFileLanguage(*sf);
cmXCodeObject* buildFile = cmXCodeObject* buildFile =
this->CreateXCodeSourceFileFromPath(sf->GetFullPath(), cmtarget, lang); this->CreateXCodeSourceFileFromPath(sf->GetFullPath(), cmtarget, lang, sf);
cmXCodeObject* fileRef = buildFile->GetObject("fileRef")->GetObject(); cmXCodeObject* fileRef = buildFile->GetObject("fileRef")->GetObject();
cmXCodeObject* settings = cmXCodeObject* settings =
@ -828,7 +829,8 @@ cmXCodeObject*
cmGlobalXCodeGenerator::CreateXCodeFileReferenceFromPath( cmGlobalXCodeGenerator::CreateXCodeFileReferenceFromPath(
const std::string &fullpath, const std::string &fullpath,
cmTarget& cmtarget, cmTarget& cmtarget,
const std::string &lang) const std::string &lang,
cmSourceFile* sf)
{ {
std::string fname = fullpath; std::string fname = fullpath;
cmXCodeObject* fileRef = this->FileRefs[fname]; cmXCodeObject* fileRef = this->FileRefs[fname];
@ -850,6 +852,19 @@ cmGlobalXCodeGenerator::CreateXCodeFileReferenceFromPath(
bool useLastKnownFileType = false; bool useLastKnownFileType = false;
std::string fileType; std::string fileType;
if(sf)
{
if(const char* e = sf->GetProperty("XCODE_EXPLICIT_FILE_TYPE"))
{
fileType = e;
}
else if(const char* l = sf->GetProperty("XCODE_LAST_KNOWN_FILE_TYPE"))
{
useLastKnownFileType = true;
fileType = l;
}
}
if(fileType.empty())
{ {
// If fullpath references a directory, then we need to specify // If fullpath references a directory, then we need to specify
// lastKnownFileType as folder in order for Xcode to be able to // lastKnownFileType as folder in order for Xcode to be able to
@ -902,7 +917,7 @@ cmGlobalXCodeGenerator::CreateXCodeFileReference(cmSourceFile* sf,
this->CurrentLocalGenerator->GetSourceFileLanguage(*sf); this->CurrentLocalGenerator->GetSourceFileLanguage(*sf);
return this->CreateXCodeFileReferenceFromPath( return this->CreateXCodeFileReferenceFromPath(
sf->GetFullPath(), cmtarget, lang); sf->GetFullPath(), cmtarget, lang, sf);
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -1052,7 +1067,7 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
{ {
std::string obj = *oi; std::string obj = *oi;
cmXCodeObject* xsf = cmXCodeObject* xsf =
this->CreateXCodeSourceFileFromPath(obj, cmtarget, ""); this->CreateXCodeSourceFileFromPath(obj, cmtarget, "", 0);
externalObjFiles.push_back(xsf); externalObjFiles.push_back(xsf);
} }
} }

View File

@ -163,10 +163,12 @@ private:
std::vector<cmLocalGenerator*>& generators); std::vector<cmLocalGenerator*>& generators);
cmXCodeObject* CreateXCodeFileReferenceFromPath(const std::string &fullpath, cmXCodeObject* CreateXCodeFileReferenceFromPath(const std::string &fullpath,
cmTarget& cmtarget, cmTarget& cmtarget,
const std::string &lang); const std::string &lang,
cmSourceFile* sf);
cmXCodeObject* CreateXCodeSourceFileFromPath(const std::string &fullpath, cmXCodeObject* CreateXCodeSourceFileFromPath(const std::string &fullpath,
cmTarget& cmtarget, cmTarget& cmtarget,
const std::string &lang); const std::string &lang,
cmSourceFile* sf);
cmXCodeObject* CreateXCodeFileReference(cmSourceFile* sf, cmXCodeObject* CreateXCodeFileReference(cmSourceFile* sf,
cmTarget& cmtarget); cmTarget& cmtarget);
cmXCodeObject* CreateXCodeSourceFile(cmLocalGenerator* gen, cmXCodeObject* CreateXCodeSourceFile(cmLocalGenerator* gen,

View File

@ -123,6 +123,10 @@ if("${CMAKE_GENERATOR}" MATCHES "Visual Studio [^6]")
add_RunCMake_test(SolutionGlobalSections) add_RunCMake_test(SolutionGlobalSections)
endif() endif()
if(XCODE_VERSION AND NOT "${XCODE_VERSION}" VERSION_LESS 3)
add_RunCMake_test(XcodeProject)
endif()
add_RunCMake_test(File_Generate) add_RunCMake_test(File_Generate)
add_RunCMake_test(ExportWithoutLanguage) add_RunCMake_test(ExportWithoutLanguage)
add_RunCMake_test(target_link_libraries) add_RunCMake_test(target_link_libraries)

View File

@ -0,0 +1,3 @@
cmake_minimum_required(VERSION 2.8.4)
project(${RunCMake_TEST} NONE)
include(${RunCMake_TEST}.cmake)

View File

@ -0,0 +1,3 @@
include(RunCMake)
run_cmake(XcodeFileType)

View File

@ -0,0 +1,10 @@
set(expect-default "explicitFileType = sourcecode")
set(expect-explicit "explicitFileType = \"sourcecode.c.h\"")
set(expect-lastKnown "lastKnownFileType = \"sourcecode.c.h\"")
foreach(src default explicit lastKnown)
file(STRINGS ${RunCMake_TEST_BINARY_DIR}/XcodeFileType.xcodeproj/project.pbxproj actual-${src}
REGEX "PBXFileReference.*src-${src}")
if(NOT actual-${src} MATCHES "${expect-${src}}")
message(SEND_ERROR "src-${src} does not match '${expect-${src}}':\n ${actual-${src}}")
endif()
endforeach()

View File

@ -0,0 +1,4 @@
enable_language(C)
add_executable(main main.c src-default src-explicit src-lastKnown)
set_property(SOURCE src-explicit PROPERTY XCODE_EXPLICIT_FILE_TYPE sourcecode.c.h)
set_property(SOURCE src-lastKnown PROPERTY XCODE_LAST_KNOWN_FILE_TYPE sourcecode.c.h)

View File

View File

View File