@@ -104,15 +104,19 @@ - (BOOL)extractBuildSettingsFromProject:(NSURL *)projectWrapperURL toDestination
104104 });
105105 return success;
106106 }
107+
108+ // Get project targets
109+ NSArray *targets = [self objectArrayForDictionary: rootObject key: @" targets" ];
110+
111+ // Validate project config name to guard against name conflicts with target names
112+ NSArray *targetNames = [targets valueForKeyPath: @" name" ];
113+ NSString *validatedProjectConfigName = [self validatedProjectConfigNameWithTargetNames: targetNames];
107114
108115 // Get project settings
109116 NSString *buildConfigurationListID = rootObject[@" buildConfigurationList" ];
110117 NSDictionary *projectSettings = [self buildSettingStringsByConfigurationForBuildConfigurationListID: buildConfigurationListID];
111118
112- self.buildSettingsByTarget [self .projectConfigName] = projectSettings;
113-
114- // Get project targets
115- NSArray *targets = [self objectArrayForDictionary: rootObject key: @" targets" ];
119+ self.buildSettingsByTarget [validatedProjectConfigName] = projectSettings;
116120
117121 // Add project targets
118122 for (NSDictionary *target in targets) {
@@ -130,6 +134,31 @@ - (BOOL)extractBuildSettingsFromProject:(NSURL *)projectWrapperURL toDestination
130134 return success;
131135}
132136
137+ // This will return a validated project config name to guard against naming conflicts with targets
138+ // If a conflict is found, the project config files will have "-Project-Settings" appended to the
139+ // provided project config name, using the user-specified name separator between words.
140+ - (NSString *)validatedProjectConfigNameWithTargetNames : (NSArray *)targetNames {
141+ NSString *validatedProjectConfigName = self.projectConfigName ;
142+ if ([targetNames containsObject: self .projectConfigName]) {
143+ validatedProjectConfigName = [validatedProjectConfigName stringByAppendingFormat: @" %@ Project%@ Settings" , self .nameSeparator, self .nameSeparator];
144+ [self presentErrorForNameConflictWithName: self .projectConfigName validatedName: validatedProjectConfigName];
145+ }
146+ return validatedProjectConfigName;
147+ }
148+
149+ // Notify the user we are not using the exact name for the project settings provided in Preferences
150+ - (void )presentErrorForNameConflictWithName : (NSString *)conflictedName validatedName : (NSString *)validatedName {
151+ NSString *errorDescription = [NSString stringWithFormat: @" Project settings filename conflict." ];
152+ NSString *errorRecoverySuggestion = [NSString stringWithFormat: @" The target \' %@ \' has the same name as the project name set in Preferences.\n\n The generated project settings files will use the name \' %@ \' to avoid a conflict." , conflictedName, validatedName];
153+ NSDictionary *errorUserInfo = @{NSLocalizedDescriptionKey :errorDescription, NSLocalizedRecoverySuggestionErrorKey : errorRecoverySuggestion};
154+
155+ NSError *error = [NSError errorWithDomain: [[NSBundle mainBundle ] bundleIdentifier ] code: ProjectSettingsNamingConflict userInfo: errorUserInfo];
156+
157+ dispatch_async (dispatch_get_main_queue (), ^{
158+ [NSApp presentError: error];
159+ });
160+
161+ }
133162
134163/* Writes an xcconfig file for each target / configuration combination to the specified directory.
135164 */
0 commit comments