Merge topic 'xcode-object-ids'
b8b6573db8
Xcode: Use deterministic object ids for script build phases2892228dc9
cmGlobalXCodeGenerator: Add infrastructure for deterministic object idsd250b67722
cmGlobalXCodeGenerator: Adopt pbxproj object id generation Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !5671
This commit is contained in:
commit
38335f275f
@ -18,6 +18,7 @@
|
||||
#include "cmsys/RegularExpression.hxx"
|
||||
|
||||
#include "cmComputeLinkInformation.h"
|
||||
#include "cmCryptoHash.h"
|
||||
#include "cmCustomCommand.h"
|
||||
#include "cmCustomCommandGenerator.h"
|
||||
#include "cmCustomCommandLines.h"
|
||||
@ -798,9 +799,10 @@ void cmGlobalXCodeGenerator::addObject(std::unique_ptr<cmXCodeObject> obj)
|
||||
}
|
||||
|
||||
cmXCodeObject* cmGlobalXCodeGenerator::CreateObject(
|
||||
cmXCodeObject::PBXType ptype)
|
||||
cmXCodeObject::PBXType ptype, cm::string_view key)
|
||||
{
|
||||
auto obj = cm::make_unique<cmXCode21Object>(ptype, cmXCodeObject::OBJECT);
|
||||
auto obj = cm::make_unique<cmXCode21Object>(ptype, cmXCodeObject::OBJECT,
|
||||
this->GetObjectId(ptype, key));
|
||||
auto ptr = obj.get();
|
||||
this->addObject(std::move(obj));
|
||||
return ptr;
|
||||
@ -808,7 +810,9 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateObject(
|
||||
|
||||
cmXCodeObject* cmGlobalXCodeGenerator::CreateObject(cmXCodeObject::Type type)
|
||||
{
|
||||
auto obj = cm::make_unique<cmXCodeObject>(cmXCodeObject::None, type);
|
||||
auto obj = cm::make_unique<cmXCodeObject>(
|
||||
cmXCodeObject::None, type,
|
||||
"Temporary cmake object, should not be referred to in Xcode file");
|
||||
auto ptr = obj.get();
|
||||
this->addObject(std::move(obj));
|
||||
return ptr;
|
||||
@ -1739,13 +1743,13 @@ void cmGlobalXCodeGenerator::CreateCustomCommands(
|
||||
if (this->XcodeBuildSystem >= BuildSystem::Twelve) {
|
||||
// create prebuild phase
|
||||
preBuildPhase =
|
||||
this->CreateRunScriptBuildPhase("CMake PreBuild Rules", prebuild);
|
||||
this->CreateRunScriptBuildPhase("CMake PreBuild Rules", gtgt, prebuild);
|
||||
// create prelink phase
|
||||
preLinkPhase =
|
||||
this->CreateRunScriptBuildPhase("CMake PreLink Rules", prelink);
|
||||
this->CreateRunScriptBuildPhase("CMake PreLink Rules", gtgt, prelink);
|
||||
// create postbuild phase
|
||||
postBuildPhase =
|
||||
this->CreateRunScriptBuildPhase("CMake PostBuild Rules", postbuild);
|
||||
postBuildPhase = this->CreateRunScriptBuildPhase("CMake PostBuild Rules",
|
||||
gtgt, postbuild);
|
||||
} else {
|
||||
std::vector<cmSourceFile*> classes;
|
||||
if (!gtgt->GetConfigCommonSourceFilesForXcode(classes)) {
|
||||
@ -1877,7 +1881,8 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateRunScriptBuildPhase(
|
||||
}
|
||||
|
||||
cmXCodeObject* buildPhase =
|
||||
this->CreateObject(cmXCodeObject::PBXShellScriptBuildPhase);
|
||||
this->CreateObject(cmXCodeObject::PBXShellScriptBuildPhase,
|
||||
cmStrCat(gt->GetName(), ':', sf->GetFullPath()));
|
||||
buildPhase->AddAttribute("buildActionMask",
|
||||
this->CreateString("2147483647"));
|
||||
cmXCodeObject* buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
|
||||
@ -1936,7 +1941,8 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateRunScriptBuildPhase(
|
||||
}
|
||||
|
||||
cmXCodeObject* cmGlobalXCodeGenerator::CreateRunScriptBuildPhase(
|
||||
std::string const& name, std::vector<cmCustomCommand> const& commands)
|
||||
std::string const& name, cmGeneratorTarget const* gt,
|
||||
std::vector<cmCustomCommand> const& commands)
|
||||
{
|
||||
if (commands.empty()) {
|
||||
return nullptr;
|
||||
@ -1959,7 +1965,8 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateRunScriptBuildPhase(
|
||||
}
|
||||
|
||||
cmXCodeObject* buildPhase =
|
||||
this->CreateObject(cmXCodeObject::PBXShellScriptBuildPhase);
|
||||
this->CreateObject(cmXCodeObject::PBXShellScriptBuildPhase,
|
||||
cmStrCat(gt->GetName(), ':', name));
|
||||
buildPhase->AddAttribute("buildActionMask",
|
||||
this->CreateString("2147483647"));
|
||||
cmXCodeObject* buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
|
||||
@ -2927,8 +2934,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
|
||||
cmXCodeObject* cmGlobalXCodeGenerator::CreateUtilityTarget(
|
||||
cmGeneratorTarget* gtgt)
|
||||
{
|
||||
cmXCodeObject* shellBuildPhase =
|
||||
this->CreateObject(cmXCodeObject::PBXShellScriptBuildPhase);
|
||||
cmXCodeObject* shellBuildPhase = this->CreateObject(
|
||||
cmXCodeObject::PBXShellScriptBuildPhase, gtgt->GetName());
|
||||
shellBuildPhase->AddAttribute("buildActionMask",
|
||||
this->CreateString("2147483647"));
|
||||
cmXCodeObject* buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
|
||||
@ -3156,6 +3163,32 @@ cmXCodeObject* cmGlobalXCodeGenerator::FindXCodeTarget(
|
||||
return i->second;
|
||||
}
|
||||
|
||||
std::string cmGlobalXCodeGenerator::GetObjectId(cmXCodeObject::PBXType ptype,
|
||||
cm::string_view key)
|
||||
{
|
||||
std::string objectId;
|
||||
if (!key.empty()) {
|
||||
cmCryptoHash hash(cmCryptoHash::AlgoSHA256);
|
||||
hash.Initialize();
|
||||
hash.Append(&ptype, sizeof(ptype));
|
||||
hash.Append(key);
|
||||
objectId = cmSystemTools::UpperCase(hash.FinalizeHex().substr(0, 24));
|
||||
} else {
|
||||
char cUuid[40] = { 0 };
|
||||
CFUUIDRef uuid = CFUUIDCreate(kCFAllocatorDefault);
|
||||
CFStringRef s = CFUUIDCreateString(kCFAllocatorDefault, uuid);
|
||||
CFStringGetCString(s, cUuid, sizeof(cUuid), kCFStringEncodingUTF8);
|
||||
objectId = cUuid;
|
||||
CFRelease(s);
|
||||
CFRelease(uuid);
|
||||
cmSystemTools::ReplaceString(objectId, "-", "");
|
||||
if (objectId.size() > 24) {
|
||||
objectId = objectId.substr(0, 24);
|
||||
}
|
||||
}
|
||||
return objectId;
|
||||
}
|
||||
|
||||
std::string cmGlobalXCodeGenerator::GetOrCreateId(const std::string& name,
|
||||
const std::string& id)
|
||||
{
|
||||
|
@ -11,6 +11,8 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <cm/string_view>
|
||||
|
||||
#include "cmGlobalGenerator.h"
|
||||
#include "cmXCodeObject.h"
|
||||
|
||||
@ -162,11 +164,13 @@ private:
|
||||
const std::string& configName);
|
||||
|
||||
cmXCodeObject* FindXCodeTarget(const cmGeneratorTarget*);
|
||||
std::string GetObjectId(cmXCodeObject::PBXType ptype, cm::string_view key);
|
||||
std::string GetOrCreateId(const std::string& name, const std::string& id);
|
||||
|
||||
// create cmXCodeObject from these functions so that memory can be managed
|
||||
// correctly. All objects created are stored in this->XCodeObjects.
|
||||
cmXCodeObject* CreateObject(cmXCodeObject::PBXType ptype);
|
||||
cmXCodeObject* CreateObject(cmXCodeObject::PBXType ptype,
|
||||
cm::string_view key = {});
|
||||
cmXCodeObject* CreateObject(cmXCodeObject::Type type);
|
||||
cmXCodeObject* CreateString(const std::string& s);
|
||||
cmXCodeObject* CreateObjectReference(cmXCodeObject*);
|
||||
@ -256,7 +260,8 @@ private:
|
||||
cmGeneratorTarget const* gt,
|
||||
cmCustomCommand const& cc);
|
||||
cmXCodeObject* CreateRunScriptBuildPhase(
|
||||
std::string const& name, std::vector<cmCustomCommand> const& commands);
|
||||
std::string const& name, cmGeneratorTarget const* gt,
|
||||
std::vector<cmCustomCommand> const& commands);
|
||||
std::string ConstructScript(cmCustomCommandGenerator const& ccg);
|
||||
void CreateReRunCMakeFile(cmLocalGenerator* root,
|
||||
std::vector<cmLocalGenerator*> const& gens);
|
||||
|
@ -4,11 +4,12 @@
|
||||
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "cmSystemTools.h"
|
||||
|
||||
cmXCode21Object::cmXCode21Object(PBXType ptype, Type type)
|
||||
: cmXCodeObject(ptype, type)
|
||||
cmXCode21Object::cmXCode21Object(PBXType ptype, Type type, std::string id)
|
||||
: cmXCodeObject(ptype, type, std::move(id))
|
||||
{
|
||||
this->Version = 21;
|
||||
}
|
||||
|
@ -13,7 +13,7 @@
|
||||
class cmXCode21Object : public cmXCodeObject
|
||||
{
|
||||
public:
|
||||
cmXCode21Object(PBXType ptype, Type type);
|
||||
cmXCode21Object(PBXType ptype, Type type, std::string id);
|
||||
void PrintComment(std::ostream&) override;
|
||||
static void PrintList(std::vector<std::unique_ptr<cmXCodeObject>> const&,
|
||||
std::ostream& out, PBXType t);
|
||||
|
@ -40,7 +40,7 @@ cmXCodeObject::~cmXCodeObject()
|
||||
this->Version = 15;
|
||||
}
|
||||
|
||||
cmXCodeObject::cmXCodeObject(PBXType ptype, Type type)
|
||||
cmXCodeObject::cmXCodeObject(PBXType ptype, Type type, std::string id)
|
||||
{
|
||||
this->Version = 15;
|
||||
this->Target = nullptr;
|
||||
@ -48,27 +48,7 @@ cmXCodeObject::cmXCodeObject(PBXType ptype, Type type)
|
||||
|
||||
this->IsA = ptype;
|
||||
|
||||
if (type == OBJECT) {
|
||||
// Set the Id of an Xcode object to a unique string for each instance.
|
||||
// However the Xcode user file references certain Ids: for those cases,
|
||||
// override the generated Id using SetId().
|
||||
//
|
||||
char cUuid[40] = { 0 };
|
||||
CFUUIDRef uuid = CFUUIDCreate(kCFAllocatorDefault);
|
||||
CFStringRef s = CFUUIDCreateString(kCFAllocatorDefault, uuid);
|
||||
CFStringGetCString(s, cUuid, sizeof(cUuid), kCFStringEncodingUTF8);
|
||||
this->Id = cUuid;
|
||||
CFRelease(s);
|
||||
CFRelease(uuid);
|
||||
} else {
|
||||
this->Id =
|
||||
"Temporary cmake object, should not be referred to in Xcode file";
|
||||
}
|
||||
|
||||
cmSystemTools::ReplaceString(this->Id, "-", "");
|
||||
if (this->Id.size() > 24) {
|
||||
this->Id = this->Id.substr(0, 24);
|
||||
}
|
||||
this->Id = std::move(id);
|
||||
|
||||
this->TypeValue = type;
|
||||
if (this->TypeValue == OBJECT) {
|
||||
|
@ -57,7 +57,7 @@ public:
|
||||
};
|
||||
static const char* PBXTypeNames[];
|
||||
virtual ~cmXCodeObject();
|
||||
cmXCodeObject(PBXType ptype, Type type);
|
||||
cmXCodeObject(PBXType ptype, Type type, std::string id);
|
||||
Type GetType() const { return this->TypeValue; }
|
||||
PBXType GetIsA() const { return this->IsA; }
|
||||
|
||||
|
@ -0,0 +1,4 @@
|
||||
if(EXISTS "${CMAKE_CURRENT_BINARY_DIR}/exists-for-build2")
|
||||
message(FATAL_ERROR "Custom command incorrectly re-ran after CMake re-ran!")
|
||||
endif()
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/out.txt")
|
5
Tests/RunCMake/BuildDepends/RepeatCMake-Custom.cmake
Normal file
5
Tests/RunCMake/BuildDepends/RepeatCMake-Custom.cmake
Normal file
@ -0,0 +1,5 @@
|
||||
add_custom_command(OUTPUT out.txt
|
||||
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_LIST_DIR}/RepeatCMake-Custom-Script.cmake
|
||||
DEPENDS ${CMAKE_CURRENT_LIST_DIR}/RepeatCMake-Custom-Script.cmake
|
||||
)
|
||||
add_custom_target(drive ALL DEPENDS out.txt)
|
@ -79,6 +79,23 @@ if(RunCMake_GENERATOR MATCHES "Make")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
function(run_RepeatCMake CASE)
|
||||
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${CASE}-build)
|
||||
if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
|
||||
set(RunCMake_TEST_OPTIONS -DCMAKE_CONFIGURATION_TYPES=Debug)
|
||||
else()
|
||||
set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
|
||||
endif()
|
||||
run_cmake(${CASE})
|
||||
set(RunCMake_TEST_NO_CLEAN 1)
|
||||
run_cmake_command(${CASE}-build1 ${CMAKE_COMMAND} --build . --config Debug)
|
||||
run_cmake_command(${CASE}-rerun1 ${CMAKE_COMMAND} .)
|
||||
file(WRITE ${RunCMake_TEST_BINARY_DIR}/exists-for-build2 "")
|
||||
run_cmake_command(${CASE}-build2 ${CMAKE_COMMAND} --build . --config Debug)
|
||||
endfunction()
|
||||
|
||||
run_RepeatCMake(RepeatCMake-Custom)
|
||||
|
||||
function(run_ReGeneration)
|
||||
# test re-generation of project even if CMakeLists.txt files disappeared
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user