Merge pull request #1399 from millenomi/pr/search-paths-for-preferences

diff --git a/CoreFoundation/Base.subproj/CFFileUtilities.c b/CoreFoundation/Base.subproj/CFFileUtilities.c
index 4511d7a..984cf1f 100644
--- a/CoreFoundation/Base.subproj/CFFileUtilities.c
+++ b/CoreFoundation/Base.subproj/CFFileUtilities.c
@@ -1179,7 +1179,7 @@
 }
 
 
-#if DEPLOYMENT_RUNTIME_SWIFT
+#if !DEPLOYMENT_RUNTIME_OBJC
 
 // https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
 // Version 0.8
@@ -1356,5 +1356,5 @@
     return CFArrayCreate(kCFAllocatorSystemDefault, NULL, 0, &kCFTypeArrayCallBacks);
 }
 
-#endif
+#endif // !DEPLOYMENT_RUNTIME_OBJC
 
diff --git a/CoreFoundation/Base.subproj/CFKnownLocations.c b/CoreFoundation/Base.subproj/CFKnownLocations.c
new file mode 100644
index 0000000..2da610b
--- /dev/null
+++ b/CoreFoundation/Base.subproj/CFKnownLocations.c
@@ -0,0 +1,82 @@
+/*	CFKnownLocations.c
+	Copyright (c) 1999-2017, Apple Inc. and the Swift project authors
+ 
+	Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors
+	Licensed under Apache License v2.0 with Runtime Library Exception
+	See http://swift.org/LICENSE.txt for license information
+	See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+*/
+
+#include "CFKnownLocations.h"
+
+#include <CoreFoundation/CFString.h>
+#include "CFPriv.h"
+#include "CFInternal.h"
+
+#include <assert.h>
+
+CFURLRef _Nullable _CFKnownLocationCreatePreferencesURLForUser(CFKnownLocationUser user, CFStringRef _Nullable username) {
+    CFURLRef location = NULL;
+    
+#if (DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI)
+    
+/*
+ Building for a Darwin OS. (We use these paths on Swift builds as well, so that we can interoperate a little with Darwin's defaults(1) command and the other system facilities; but you want to use the system version of CF if possible on those platforms, which will talk to cfprefsd(8) and has stronger interprocess consistency guarantees.)
+ 
+ User:
+ - Any: /Library/Preferences
+ - Current: $HOME/Library/Preferences
+ */
+    
+    switch (user) {
+        case _kCFKnownLocationUserAny:
+            location = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, CFSTR("/Library/Preferences"), kCFURLPOSIXPathStyle, true);
+            break;
+            
+        case _kCFKnownLocationUserCurrent:
+            username = NULL;
+            // passthrough to:
+        case _kCFKnownLocationUserByName: {
+            CFURLRef home = CFCopyHomeDirectoryURLForUser(username);
+            location = CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorSystemDefault, CFSTR("/Library/Preferences"), kCFURLPOSIXPathStyle, true, home);
+            CFRelease(home);
+            
+            break;
+        }
+            
+    }
+#elif !DEPLOYMENT_RUNTIME_OBJC && !DEPLOYMENT_TARGET_WINDOWS
+    
+/*
+ Building for an OS that uses the FHS, BSD's hier(7), and/or the XDG specification for paths:
+ 
+ User:
+ - Any: /usr/local/etc/
+ - Current: $XDG_CONFIG_PATH (usually: $HOME/.config/).
+ */
+    
+    switch (user) {
+        case _kCFKnownLocationUserAny:
+            location = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, CFSTR("/usr/local/etc"), kCFURLPOSIXPathStyle, true);
+            break;
+            
+        case _kCFKnownLocationUserByName:
+            assert(username == NULL);
+            // passthrough to:
+        case _kCFKnownLocationUserCurrent: {
+            CFStringRef path = _CFXDGCreateConfigHomePath();
+            location = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, path, kCFURLPOSIXPathStyle, true);
+            CFRelease(path);
+            
+            break;
+        }
+    }
+    
+#else
+    
+    #error For this platform, you need to define a preferences path for both 'any user' (i.e. installation-wide preferences) or the current user.
+    
+#endif
+    
+    return location;
+}
diff --git a/CoreFoundation/Base.subproj/CFKnownLocations.h b/CoreFoundation/Base.subproj/CFKnownLocations.h
new file mode 100644
index 0000000..629468c
--- /dev/null
+++ b/CoreFoundation/Base.subproj/CFKnownLocations.h
@@ -0,0 +1,42 @@
+/*	CFKnownLocations.h
+	Copyright (c) 1999-2017, Apple Inc. and the Swift project authors
+ 
+	Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors
+	Licensed under Apache License v2.0 with Runtime Library Exception
+	See http://swift.org/LICENSE.txt for license information
+	See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+*/
+
+#if !defined(__COREFOUNDATION_CFKNOWNLOCATIONS__)
+#define __COREFOUNDATION_CFKNOWNLOCATIONS__ 1
+
+#include <CoreFoundation/CFBase.h>
+#include <CoreFoundation/CFURL.h>
+
+CF_ASSUME_NONNULL_BEGIN
+
+typedef CF_ENUM(CFIndex, CFKnownLocationUser) {
+    _kCFKnownLocationUserAny,
+    _kCFKnownLocationUserCurrent,
+    _kCFKnownLocationUserByName,
+};
+
+/* A note on support:
+ 
+ - We document that CFPreferences… can only take AnyUser or CurrentUser as users.
+ - The code we shipped so far accepted the name of any one user on the current system as an alternative, but:
+ - For platforms that use the XDG spec to identify a configuration path in a user's home, we cannot determine that path for any user other than the one we're currently running as.
+ 
+ So:
+  - We're keeping that behavior when building Core Foundation for Darwin/ObjC for compatibility, hence the _EXTENSIBLE above; on those platforms, the …ByName enum will continue working to get locations for arbitrary usernames. But:
+  - For Swift and any new platform, we are enforcing the documented constraint. Using a user value other than …Any or …Current above will assert (or return NULL if asserts are off).
+ 
+ See CFKnownLocations.c for a summary of what paths are returned.
+ */
+
+// The username parameter is ignored for any user constant other than …ByName. …ByName with a NULL username is the same as …Current.
+extern CFURLRef _Nullable _CFKnownLocationCreatePreferencesURLForUser(CFKnownLocationUser user, CFStringRef _Nullable username);
+
+CF_ASSUME_NONNULL_END
+
+#endif /* __COREFOUNDATION_CFKNOWNLOCATIONS__ */
diff --git a/CoreFoundation/Base.subproj/CFPriv.h b/CoreFoundation/Base.subproj/CFPriv.h
index aa8dbe9..60c02a9 100644
--- a/CoreFoundation/Base.subproj/CFPriv.h
+++ b/CoreFoundation/Base.subproj/CFPriv.h
@@ -42,6 +42,7 @@
 #include <CoreFoundation/CFRunLoop.h>
 #include <CoreFoundation/CFSocket.h>
 #include <CoreFoundation/CFBundlePriv.h>
+#include <CoreFoundation/CFKnownLocations.h>
 
 CF_EXTERN_C_BEGIN
 
@@ -655,6 +656,34 @@
 CF_EXPORT Boolean _CFExtensionUniCharsIsValidToAppend(const UniChar *uchars, CFIndex ucharsLength) API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0));
 CF_EXPORT Boolean _CFExtensionIsValidToAppend(CFStringRef extension) API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0));
 
+
+#if !DEPLOYMENT_RUNTIME_OBJC
+
+// https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
+// Version 0.8
+
+// note: All paths set in these environment variables must be absolute.
+
+/// a single base directory relative to which user-specific data files should be written. This directory is defined by the environment variable $XDG_DATA_HOME.
+CF_EXPORT CFStringRef _CFXDGCreateDataHomePath(void) CF_RETURNS_RETAINED;
+
+/// a single base directory relative to which user-specific configuration files should be written. This directory is defined by the environment variable $XDG_CONFIG_HOME.
+CF_EXPORT CFStringRef _CFXDGCreateConfigHomePath(void) CF_RETURNS_RETAINED;
+
+/// a set of preference ordered base directories relative to which data files should be searched. This set of directories is defined by the environment variable $XDG_DATA_DIRS.
+CF_EXPORT CFArrayRef _CFXDGCreateDataDirectoriesPaths(void) CF_RETURNS_RETAINED;
+
+/// a set of preference ordered base directories relative to which configuration files should be searched. This set of directories is defined by the environment variable $XDG_CONFIG_DIRS.
+CF_EXPORT CFArrayRef _CFXDGCreateConfigDirectoriesPaths(void) CF_RETURNS_RETAINED;
+
+/// a single base directory relative to which user-specific non-essential (cached) data should be written. This directory is defined by the environment variable $XDG_CACHE_HOME.
+CF_EXPORT CFStringRef _CFXDGCreateCacheDirectoryPath(void) CF_RETURNS_RETAINED;
+
+/// a single base directory relative to which user-specific runtime files and other file objects should be placed. This directory is defined by the environment variable $XDG_RUNTIME_DIR.
+CF_EXPORT CFStringRef _CFXDGCreateRuntimeDirectoryPath(void) CF_RETURNS_RETAINED;
+
+#endif // !DEPLOYMENT_RUNTIME_OBJC
+
 CF_EXTERN_C_END
 
 #endif /* ! __COREFOUNDATION_CFPRIV__ */
diff --git a/CoreFoundation/Preferences.subproj/CFPreferences.c b/CoreFoundation/Preferences.subproj/CFPreferences.c
index 56e24f4..19cd77b 100644
--- a/CoreFoundation/Preferences.subproj/CFPreferences.c
+++ b/CoreFoundation/Preferences.subproj/CFPreferences.c
@@ -26,6 +26,8 @@
 #include <CoreFoundation/CFUUID.h>
 #endif
 
+#include <assert.h>
+
 #if DEBUG_PREFERENCES_MEMORY
 #include "../Tests/CFCountingAllocator.c"
 #endif
@@ -182,37 +184,29 @@
 	return url;
  
 #else
-    CFURLRef  home = NULL;
-    CFURLRef  url;
-    int levels = 0;
-    //    if (hostName != kCFPreferencesCurrentHost && hostName != kCFPreferencesAnyHost) return NULL; // Arbitrary host access not permitted
+    CFURLRef location = NULL;
+    
+    CFKnownLocationUser user;
+    
     if (userName == kCFPreferencesAnyUser) {
-        if (!home) home = CFURLCreateWithFileSystemPath(alloc, CFSTR("/Library/Preferences/"), kCFURLPOSIXPathStyle, true);
-        levels = 1;
-        if (hostName == kCFPreferencesCurrentHost) url = home;
-        else {
-            url = CFURLCreateWithFileSystemPathRelativeToBase(alloc, CFSTR("Network/"), kCFURLPOSIXPathStyle, true, home);
-            levels ++;
-            CFRelease(home);
-        }
+        user = _kCFKnownLocationUserAny;
+    } else if (userName == kCFPreferencesCurrentUser) {
+        user = _kCFKnownLocationUserCurrent;
     } else {
-        home = CFCopyHomeDirectoryURLForUser((userName == kCFPreferencesCurrentUser) ? NULL : userName);
-        if (home) {
-            url = (safeLevel > 0) ? CFURLCreateWithFileSystemPathRelativeToBase(alloc, CFSTR("Library/Safe Preferences/"), kCFURLPOSIXPathStyle, true, home) :
-            CFURLCreateWithFileSystemPathRelativeToBase(alloc, CFSTR("Library/Preferences/"), kCFURLPOSIXPathStyle, true, home);
-            levels = 2;
-            CFRelease(home);
-            if (hostName != kCFPreferencesAnyHost) {
-                home = url;
-                url = CFURLCreateWithFileSystemPathRelativeToBase(alloc, CFSTR("ByHost/"), kCFURLPOSIXPathStyle, true, home);
-                levels ++;
-                CFRelease(home);
-            }
-        } else {
-            url = NULL;
-        }
+        user = _kCFKnownLocationUserByName;
     }
-    return url;
+    
+    CFURLRef base = _CFKnownLocationCreatePreferencesURLForUser(user, userName);
+    
+    if (hostName == kCFPreferencesCurrentHost) {
+        location = CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorSystemDefault, CFSTR("ByHost"), kCFURLPOSIXPathStyle, true, base);
+    } else {
+        assert(hostName == kCFPreferencesAnyHost);
+        location = CFRetain(base);
+    }
+    
+    CFRelease(base);
+    return location;
 #endif
 }
 
diff --git a/CoreFoundation/build.py b/CoreFoundation/build.py
index cfdf606..046babb 100755
--- a/CoreFoundation/build.py
+++ b/CoreFoundation/build.py
@@ -198,6 +198,7 @@
 	'Locale.subproj/CFDateFormatter_Private.h',
 	'Locale.subproj/CFLocale_Private.h',
 	'Parsing.subproj/CFPropertyList_Private.h',
+	'Base.subproj/CFKnownLocations.h',
 ],
 project = [
 ])
@@ -292,6 +293,7 @@
 	'String.subproj/CFRegularExpression.c',
 	'String.subproj/CFAttributedString.c',
 	'String.subproj/CFRunArray.c',
+	'Base.subproj/CFKnownLocations.h',
 ]
 
 sources = CompileSources(sources_list)
diff --git a/Foundation.xcodeproj/project.pbxproj b/Foundation.xcodeproj/project.pbxproj
index c2c885c..0eeae88 100644
--- a/Foundation.xcodeproj/project.pbxproj
+++ b/Foundation.xcodeproj/project.pbxproj
@@ -10,6 +10,8 @@
 		0383A1751D2E558A0052E5D1 /* TestStream.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0383A1741D2E558A0052E5D1 /* TestStream.swift */; };
 		03B6F5841F15F339004F25AF /* TestURLProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03B6F5831F15F339004F25AF /* TestURLProtocol.swift */; };
 		1520469B1D8AEABE00D02E36 /* HTTPServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1520469A1D8AEABE00D02E36 /* HTTPServer.swift */; };
+		153E951120111DC500F250BE /* CFKnownLocations.h in Headers */ = {isa = PBXBuildFile; fileRef = 153E950F20111DC500F250BE /* CFKnownLocations.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		153E951220111DC500F250BE /* CFKnownLocations.c in Sources */ = {isa = PBXBuildFile; fileRef = 153E951020111DC500F250BE /* CFKnownLocations.c */; };
 		159884921DCC877700E3314C /* TestHTTPCookieStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 159884911DCC877700E3314C /* TestHTTPCookieStorage.swift */; };
 		231503DB1D8AEE5D0061694D /* TestDecimal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 231503DA1D8AEE5D0061694D /* TestDecimal.swift */; };
 		294E3C1D1CC5E19300E4F44C /* TestNSAttributedString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 294E3C1C1CC5E19300E4F44C /* TestNSAttributedString.swift */; };
@@ -498,6 +500,8 @@
 		0383A1741D2E558A0052E5D1 /* TestStream.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestStream.swift; sourceTree = "<group>"; };
 		03B6F5831F15F339004F25AF /* TestURLProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestURLProtocol.swift; sourceTree = "<group>"; };
 		1520469A1D8AEABE00D02E36 /* HTTPServer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HTTPServer.swift; sourceTree = "<group>"; };
+		153E950F20111DC500F250BE /* CFKnownLocations.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CFKnownLocations.h; sourceTree = "<group>"; };
+		153E951020111DC500F250BE /* CFKnownLocations.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = CFKnownLocations.c; sourceTree = "<group>"; };
 		159884911DCC877700E3314C /* TestHTTPCookieStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestHTTPCookieStorage.swift; sourceTree = "<group>"; };
 		22B9C1E01C165D7A00DECFF9 /* TestDate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestDate.swift; sourceTree = "<group>"; };
 		231503DA1D8AEE5D0061694D /* TestDecimal.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestDecimal.swift; sourceTree = "<group>"; };
@@ -1091,6 +1095,8 @@
 				5B5D895F1BBDABF400234F36 /* CFUtilities.h */,
 				5B5D89541BBDAA0100234F36 /* CFUUID.c */,
 				5B5D89531BBDAA0100234F36 /* CFUUID.h */,
+				153E950F20111DC500F250BE /* CFKnownLocations.h */,
+				153E951020111DC500F250BE /* CFKnownLocations.c */,
 				5B5D88B51BBC978900234F36 /* CoreFoundation_Prefix.h */,
 				5B5D895B1BBDAB7E00234F36 /* CoreFoundation.h */,
 				5B5D88C61BBC983600234F36 /* ForFoundationOnly.h */,
@@ -1912,6 +1918,7 @@
 				5B7C8AD61BEA80FC00C5B690 /* CFPlugIn.h in Headers */,
 				5B7C8AD81BEA80FC00C5B690 /* CFPreferences.h in Headers */,
 				5B7C8AF11BEA81AC00C5B690 /* CFStreamAbstract.h in Headers */,
+				153E951120111DC500F250BE /* CFKnownLocations.h in Headers */,
 				5B7C8AFE1BEA81AC00C5B690 /* CFURLComponents.h in Headers */,
 				5B7C8ABC1BEA805C00C5B690 /* CFAvailability.h in Headers */,
 				5B6E11A91DA45EB5009B48A3 /* CFDateFormatter_Private.h in Headers */,
@@ -2363,6 +2370,7 @@
 				5B7C8A961BEA7FF900C5B690 /* CFBundle_Binary.c in Sources */,
 				5B7C8AAC1BEA800D00C5B690 /* CFString.c in Sources */,
 				5B7C8A821BEA7FCE00C5B690 /* CFStorage.c in Sources */,
+				153E951220111DC500F250BE /* CFKnownLocations.c in Sources */,
 				5B7C8AAF1BEA800D00C5B690 /* CFStringUtilities.c in Sources */,
 				5B7C8A891BEA7FDB00C5B690 /* CFNumberFormatter.c in Sources */,
 				5B7C8A8C1BEA7FE200C5B690 /* CFDate.c in Sources */,
@@ -2660,7 +2668,11 @@
 				INFOPLIST_FILE = Foundation/Info.plist;
 				INIT_ROUTINE = "___CFInitialize";
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
+				LD_RUNPATH_SEARCH_PATHS = (
+					"$(inherited)",
+					"@executable_path/../Frameworks",
+					"@loader_path/Frameworks",
+				);
 				OTHER_CFLAGS = (
 					"-DCF_BUILDING_CF",
 					"-DDEPLOYMENT_TARGET_MACOSX",
@@ -2732,7 +2744,11 @@
 				INFOPLIST_FILE = Foundation/Info.plist;
 				INIT_ROUTINE = "___CFInitialize";
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
+				LD_RUNPATH_SEARCH_PATHS = (
+					"$(inherited)",
+					"@executable_path/../Frameworks",
+					"@loader_path/Frameworks",
+				);
 				OTHER_CFLAGS = (
 					"-DCF_BUILDING_CF",
 					"-DDEPLOYMENT_TARGET_MACOSX",
@@ -2880,7 +2896,11 @@
 					/usr/include/libxml2,
 				);
 				INFOPLIST_FILE = TestFoundation/Resources/Info.plist;
-				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
+				LD_RUNPATH_SEARCH_PATHS = (
+					"$(inherited)",
+					"@executable_path/../Frameworks",
+					"@loader_path/../Frameworks",
+				);
 				LIBRARY_SEARCH_PATHS = "$(inherited)";
 				MACH_O_TYPE = mh_execute;
 				OTHER_SWIFT_FLAGS = "-DDEPLOYMENT_ENABLE_LIBDISPATCH -swift-version 4";
@@ -2906,7 +2926,11 @@
 					/usr/include/libxml2,
 				);
 				INFOPLIST_FILE = TestFoundation/Resources/Info.plist;
-				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
+				LD_RUNPATH_SEARCH_PATHS = (
+					"$(inherited)",
+					"@executable_path/../Frameworks",
+					"@loader_path/../Frameworks",
+				);
 				LIBRARY_SEARCH_PATHS = "$(inherited)";
 				MACH_O_TYPE = mh_execute;
 				OTHER_SWIFT_FLAGS = "-DDEPLOYMENT_ENABLE_LIBDISPATCH -swift-version 4";
@@ -2930,7 +2954,12 @@
 				CODE_SIGN_IDENTITY = "";
 				COMBINE_HIDPI_IMAGES = YES;
 				INFOPLIST_FILE = TestFoundation/xdgTestHelper/Info.plist;
-				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../../.. @loader_path/../../.. @executable_path/../Frameworks";
+				LD_RUNPATH_SEARCH_PATHS = (
+					"$(inherited)",
+					"@executable_path/../../..",
+					"@loader_path/../../..",
+					"@executable_path/../Frameworks",
+				);
 				MACOSX_DEPLOYMENT_TARGET = 10.12;
 				PRODUCT_BUNDLE_IDENTIFIER = org.swift.xdgTestHelper;
 				PRODUCT_NAME = "$(TARGET_NAME)";
@@ -2952,7 +2981,12 @@
 				CODE_SIGN_IDENTITY = "";
 				COMBINE_HIDPI_IMAGES = YES;
 				INFOPLIST_FILE = TestFoundation/xdgTestHelper/Info.plist;
-				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../../.. @loader_path/../../.. @executable_path/../Frameworks";
+				LD_RUNPATH_SEARCH_PATHS = (
+					"$(inherited)",
+					"@executable_path/../../..",
+					"@loader_path/../../..",
+					"@executable_path/../Frameworks",
+				);
 				MACOSX_DEPLOYMENT_TARGET = 10.12;
 				PRODUCT_BUNDLE_IDENTIFIER = org.swift.xdgTestHelper;
 				PRODUCT_NAME = "$(TARGET_NAME)";
@@ -3044,4 +3078,3 @@
 	};
 	rootObject = 5B5D88541BBC938800234F36 /* Project object */;
 }
-
diff --git a/build.py b/build.py
index 97db80c..a222e3b 100755
--- a/build.py
+++ b/build.py
@@ -224,6 +224,7 @@
 	'CoreFoundation/Locale.subproj/CFDateFormatter_Private.h',
 	'CoreFoundation/Locale.subproj/CFLocale_Private.h',
 	'CoreFoundation/Parsing.subproj/CFPropertyList_Private.h',
+	'CoreFoundation/Base.subproj/CFKnownLocations.h',
 ],
 project = [
 ])
@@ -321,6 +322,7 @@
 	'CoreFoundation/String.subproj/CFAttributedString.c',
 	'CoreFoundation/String.subproj/CFRunArray.c',
 	'CoreFoundation/URL.subproj/CFURLSessionInterface.c',
+	'CoreFoundation/Base.subproj/CFKnownLocations.c',
 ])
 
 # This code is already in libdispatch so is only needed if libdispatch is