Skip to content

Windows Port #1779

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ option(FOUNDATION_PATH_TO_LIBDISPATCH_SOURCE "Path to libdispatch source" "")
option(FOUNDATION_PATH_TO_LIBDISPATCH_BUILD "Path to libdispatch build" "")
option(FOUNDATION_PATH_TO_XCTEST_BUILD "Path to XCTest build" "")

find_package(CURL REQUIRED)
find_package(ICU COMPONENTS uc i18n REQUIRED)
find_package(LibXml2 REQUIRED)
find_package(UUID REQUIRED)
# find_package(CURL REQUIRED)
# find_package(ICU COMPONENTS uc i18n REQUIRED)
# find_package(LibXml2 REQUIRED)
# find_package(UUID REQUIRED)

include(SwiftSupport)
include(GNUInstallDirs)
Expand All @@ -35,11 +35,14 @@ ExternalProject_Add(CoreFoundation
-DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM}
-DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>
-DCMAKE_INSTALL_LIBDIR=usr/lib
-DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME}
-DCMAKE_SYSTEM_PROCESSOR=${CMAKE_SYSTEM_PROCESSOR}
-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
-DCF_DEPLOYMENT_SWIFT=YES
-DCF_ENABLE_LIBDISPATCH=${FOUNDATION_ENABLE_LIBDISPATCH}
-DCF_PATH_TO_LIBDISPATCH_SOURCE=${FOUNDATION_PATH_TO_LIBDISPATCH_SOURCE}
-DCF_PATH_TO_LIBDISPATCH_BUILD=${FOUNDATION_PATH_TO_LIBDISPATCH_BUILD}
-DICU_INCLUDE_DIR=${ICU_INCLUDE_DIR}
-DICU_ROOT=${ICU_ROOT}
INSTALL_COMMAND
${CMAKE_COMMAND} -E env --unset=DESTDIR ${CMAKE_COMMAND} --build . --target install)
ExternalProject_Get_Property(CoreFoundation install_dir)
Expand Down Expand Up @@ -241,7 +244,7 @@ add_swift_library(Foundation
${LIBXML2_LIBRARIES}
${libdispatch_ldflags}
${uuid_LIBRARIES}
-Xlinker;-rpath;-Xlinker;"\\\$\$ORIGIN"
-Xlinker;-rpath;-Xlinker;"\\\$\$ORIGIN"
SWIFT_FLAGS
-DDEPLOYMENT_RUNTIME_SWIFT
${deployment_enable_libdispatch}
Expand Down
3 changes: 0 additions & 3 deletions CoreFoundation/Base.subproj/CFBase.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,6 @@ CF_INLINE CFAllocatorPreferredSizeCallBack __CFAllocatorGetPreferredSizeFunction
}

static const void * const __MallocDefaultZoneInfoPlaceholder = NULL;
#if !TARGET_OS_MAC
#define malloc_default_zone() (NULL)
#endif

#if TARGET_OS_MAC

Expand Down
5 changes: 3 additions & 2 deletions CoreFoundation/Base.subproj/CFFileUtilities.c
Original file line number Diff line number Diff line change
Expand Up @@ -1015,6 +1015,7 @@ CF_PRIVATE CFIndex _CFLengthAfterDeletingPathExtension(UniChar *unichars, CFInde
#define DT_DIR 4
#define DT_REG 8
#define DT_LNK 10
#define DT_UNKNOWN 0
#endif

// NOTE: on Windows the filename is UTF16-encoded, the fileNameLen is result of wcslen. This function automatically skips '.' and '..', and '._' files
Expand All @@ -1023,7 +1024,7 @@ CF_PRIVATE void _CFIterateDirectory(CFStringRef directoryPath, Boolean appendSla
if (!CFStringGetFileSystemRepresentation(directoryPath, directoryPathBuf, CFMaxPathSize)) return;

#if DEPLOYMENT_TARGET_WINDOWS
#error this path does not support calculateFullResultPath but it must do so someday
#warning this path does not support calculateFullResultPath but it must do so someday
CFIndex cpathLen = strlen(directoryPathBuf);
// Make sure there is room for the additional space we need in the win32 api
if (cpathLen + 2 < CFMaxPathSize) {
Expand Down Expand Up @@ -1059,7 +1060,7 @@ CF_PRIVATE void _CFIterateDirectory(CFStringRef directoryPath, Boolean appendSla
}

Boolean isDirectory = file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Boolean result = fileHandler(fileName, isDirectory ? DT_DIR : DT_REG);
Boolean result = fileHandler(fileName, NULL, isDirectory ? DT_DIR : DT_REG);
CFRelease(fileName);
if (!result) break;
} while (FindNextFileW(handle, &file));
Expand Down
61 changes: 30 additions & 31 deletions CoreFoundation/Base.subproj/CFInternal.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,9 @@ CF_EXTERN_C_BEGIN
#include <stdio.h>
#endif // TARGET_OS_MAC || TARGET_OS_LINUX || TARGET_OS_BSD

#if !TARGET_OS_WIN32
#include <pthread.h>
#endif

#if !DEPLOYMENT_RUNTIME_SWIFT && __has_include(<os/log.h>)
#include <os/log.h>
Expand Down Expand Up @@ -264,7 +266,7 @@ static inline void __CFRuntimeSetValue(CFTypeRef cf, uint8_t n1, uint8_t n2, uin
do {
// maybe don't need to do the negation part because the right side promises that we are not going to touch the rest of the word
newInfo = (info & ~mask) | ((x << n2) & mask);
} while (!atomic_compare_exchange_weak(&(((CFRuntimeBase *)cf)->_cfinfoa), &info, newInfo));
} while (!atomic_compare_exchange_weak(&(((CFRuntimeBase *)cf)->_cfinfoa), (uint64_t *)&info, newInfo));
}

/// Set a flag in a CFTypeRef info bitfield.
Expand Down Expand Up @@ -406,6 +408,9 @@ CF_PRIVATE Boolean __CFProcessIsRestricted(void);
#if DEPLOYMENT_TARGET_WINDOWS
#define SAFE_STACK_BUFFER_DECL(Type, Name, Count, Max) Type *Name; BOOL __ ## Name ## WasMallocd = NO; if (sizeof(Type) * Count > Max) { Name = (Type *)malloc((Count) * sizeof(Type)); __ ## Name ## WasMallocd = YES; } else Name = (Count > 0) ? _alloca((Count) * sizeof(Type)) : NULL
#define SAFE_STACK_BUFFER_USE(Type, Name, Count, Max) if (sizeof(Type) * Count > Max) { Name = (Type *)malloc((Count) * sizeof(Type)); __ ## Name ## WasMallocd = YES; } else Name = (Count > 0) ? _alloca((Count) * sizeof(Type)) : NULL

// Be sure to call this before your SAFE_STACK_BUFFER exits scope.
#define SAFE_STACK_BUFFER_CLEANUP(Name) if (__ ## Name ## WasMallocd) free(Name)
#else
// Declare and allocate a stack buffer. Max is the max size (in bytes) before falling over to malloc.
#define SAFE_STACK_BUFFER_DECL(Type, Name, Count, Max) Type *Name; BOOL __ ## Name ## WasMallocd = NO; if (sizeof(Type) * Count > Max) { Name = (Type *)malloc((Count) * sizeof(Type)); __ ## Name ## WasMallocd = YES; } else Name = (Count > 0) ? alloca((Count) * sizeof(Type)) : NULL
Expand Down Expand Up @@ -449,7 +454,7 @@ static const CFStringRef S = (CFStringRef)&__##S;
static _CF_CONSTANT_OBJECT_BACKING struct __CFConstStr __##S CONST_STRING_SECTION = _CF_CONST_STR_CONTENTS(V); \
CF_PRIVATE const CFStringRef S = (CFStringRef)&__##S;

#elif defined(__CONSTANT_CFSTRINGS__)
#elif defined(__CONSTANT_CFSTRINGS__) || DEPLOYMENT_TARGET_WINDOWS

#define CONST_STRING_DECL(S, V) const CFStringRef S = (const CFStringRef)__builtin___CFStringMakeConstantString(V);
#define STATIC_CONST_STRING_DECL(S, V) static const CFStringRef S = (const CFStringRef)__builtin___CFStringMakeConstantString(V);
Expand Down Expand Up @@ -540,29 +545,24 @@ CF_INLINE Boolean __CFLockTry(volatile CFLock_t *lock) {

#elif DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD

typedef int32_t CFLock_t;
#define CFLockInit 0
typedef pthread_mutex_t CFLock_t;
#if DEPLOYMENT_TARGET_FREEBSD
#define CFLockInit ((pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER)
#else
#define CFLockInit ((pthread_mutex_t)PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP)
#endif
#define CF_LOCK_INIT_FOR_STRUCTS(X) (X = CFLockInit)

CF_INLINE void __CFLock(volatile CFLock_t *lock) {
while (__sync_val_compare_and_swap(lock, 0, ~0) != 0) {
sleep(0);
}
}

CF_INLINE void __CFUnlock(volatile CFLock_t *lock) {
__sync_synchronize();
*lock = 0;
}

CF_INLINE Boolean __CFLockTry(volatile CFLock_t *lock) {
return (__sync_val_compare_and_swap(lock, 0, ~0) == 0);
}
#define __CFLock(LP) ({ (void)pthread_mutex_lock(LP); })
#define __CFUnlock(LP) ({ (void)pthread_mutex_unlock(LP); })
#define __CFLockTry(LP) ({ (void)pthread_mutex_trylock(LP) == 0; })

typedef CFLock_t OSSpinLock;
#define OS_SPINLOCK_INIT CFLockInit
#define OSSpinLockLock(lock) __CFLock(lock)
#define OSSpinLockUnlock(lock) __CFUnlock(lock)
// NOTE: we cannot use pthread_spinlock_t here as there is no static initializer
// defined for them in the POSIX specification.
typedef int32_t OSSpinLock;
#define OS_SPINLOCK_INIT 0
#define OSSpinLockLock(lock) ({ while (__sync_val_compare_and_swap(lock, 0, ~0)) sleep(0); })
#define OSSpinLockUnlock(lock) ({ __sync_synchronize(); *lock = 0; })

#else

Expand All @@ -574,6 +574,7 @@ typedef CFLock_t OSSpinLock;

#if __has_include(<os/lock.h>)
#include <os/lock.h>
#elif DEPLOYMENT_TARGET_WINDOWS
#else
#define OS_UNFAIR_LOCK_INIT PTHREAD_MUTEX_INITIALIZER
typedef pthread_mutex_t os_unfair_lock;
Expand Down Expand Up @@ -682,6 +683,7 @@ CF_PRIVATE CFArrayRef _CFCreateCFArrayByTokenizingString(const char *values, cha
#define DT_DIR 4
#define DT_REG 8
#define DT_LNK 10
#define DT_UNKNOWN 0
#endif

/*
Expand Down Expand Up @@ -863,8 +865,9 @@ CF_PRIVATE bool __CFBinaryPlistIsArray(const uint8_t *databytes, uint64_t datale

// These are replacements for pthread calls on Windows
CF_EXPORT int _NS_pthread_main_np();
CF_EXPORT int _NS_pthread_setspecific(pthread_key_t key, const void *val);
CF_EXPORT void* _NS_pthread_getspecific(pthread_key_t key);
CF_EXPORT _CFThreadRef _NS_pthread_self(void);
CF_EXPORT int _NS_pthread_setspecific(_CFThreadSpecificKey key, const void *val);
CF_EXPORT void* _NS_pthread_getspecific(_CFThreadSpecificKey key);
CF_EXPORT int _NS_pthread_key_init_np(int key, void (*destructor)(void *));
CF_EXPORT void _NS_pthread_setname_np(const char *name);

Expand All @@ -874,18 +877,13 @@ CF_EXPORT void _NS_pthread_setname_np(const char *name);
#define pthread_key_init_np _NS_pthread_key_init_np
#define pthread_main_np _NS_pthread_main_np
#define pthread_setname_np _NS_pthread_setname_np
#define pthread_self _NS_pthread_self
#endif

#if DEPLOYMENT_TARGET_LINUX
#define pthread_main_np _CFIsMainThread
#endif

#if DEPLOYMENT_TARGET_WINDOWS
// replacement for DISPATCH_QUEUE_OVERCOMMIT until we get a bug fix in dispatch on Windows
// <rdar://problem/7923891> dispatch on Windows: Need queue_private.h
#define DISPATCH_QUEUE_OVERCOMMIT 2
#endif

#if DEPLOYMENT_TARGET_WINDOWS
CF_PRIVATE const wchar_t *_CFDLLPath(void);
#endif
Expand Down Expand Up @@ -937,7 +935,8 @@ enum {
};
#endif

#if DEPLOYMENT_TARGET_LINUX
#if DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_WINDOWS

#define QOS_CLASS_USER_INITIATED DISPATCH_QUEUE_PRIORITY_HIGH
#define QOS_CLASS_DEFAULT DISPATCH_QUEUE_PRIORITY_DEFAULT
#define QOS_CLASS_UTILITY DISPATCH_QUEUE_PRIORITY_LOW
Expand Down
19 changes: 19 additions & 0 deletions CoreFoundation/Base.subproj/CFKnownLocations.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,25 @@ CFURLRef _Nullable _CFKnownLocationCreatePreferencesURLForUser(CFKnownLocationUs
}
}

#elif DEPLOYMENT_TARGET_WINDOWS

switch (user) {
case _kCFKnownLocationUserAny:
location = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, CFSTR("\\Users\\All Users\\AppData\\Local"), kCFURLWindowsPathStyle, true);
break;
case _kCFKnownLocationUserCurrent:
username = CFGetUserName();
// fallthrough
case _kCFKnownLocationUserByName:
const char *buffer = CFStringGetCStringPtr(username, kCFStringEncodingUTF8);
CFURLRef directory = CFURLCreateFromFileSystemRepresentation(kCFAllocatorSystemDefault, (const unsigned char *)buffer, strlen(buffer), true);
CFURLRef home = CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorSystemDefault, CFSTR("\\Users"), kCFURLWindowsPathStyle, true, directory);
location = CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorSystemDefault, CFSTR("\\AppData\\Local"), kCFURLWindowsPathStyle, true, home);
CFRelease(home);
CFRelease(directory);
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.
Expand Down
Loading