diff --git a/lib/libc/include/any-macos-any/libkern/OSAtomic.h b/lib/libc/include/aarch64-macos-gnu/libkern/OSAtomic.h similarity index 100% rename from lib/libc/include/any-macos-any/libkern/OSAtomic.h rename to lib/libc/include/aarch64-macos-gnu/libkern/OSAtomic.h diff --git a/lib/libc/include/any-macos-any/libkern/OSSpinLockDeprecated.h b/lib/libc/include/aarch64-macos-gnu/libkern/OSSpinLockDeprecated.h similarity index 100% rename from lib/libc/include/any-macos-any/libkern/OSSpinLockDeprecated.h rename to lib/libc/include/aarch64-macos-gnu/libkern/OSSpinLockDeprecated.h diff --git a/lib/libc/include/x86_64-macos-gnu/libkern/OSAtomic.h b/lib/libc/include/x86_64-macos-gnu/libkern/OSAtomic.h new file mode 100644 index 0000000000..37ef16ce44 --- /dev/null +++ b/lib/libc/include/x86_64-macos-gnu/libkern/OSAtomic.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2004-2016 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef _OSATOMIC_H_ +#define _OSATOMIC_H_ + +/*! @header + * These are deprecated legacy interfaces for atomic and synchronization + * operations. + * + * Define OSATOMIC_USE_INLINED=1 to get inline implementations of the + * OSAtomic interfaces in terms of the primitives. + * + * Define OSSPINLOCK_USE_INLINED=1 to get inline implementations of the + * OSSpinLock interfaces in terms of the primitives. + * + * These are intended as a transition convenience, direct use of those + * primitives should be preferred. + */ + +#include + +#include "OSAtomicDeprecated.h" +#include "OSSpinLockDeprecated.h" +#include "OSAtomicQueue.h" + +#endif /* _OSATOMIC_H_ */ \ No newline at end of file diff --git a/lib/libc/include/x86_64-macos-gnu/libkern/OSSpinLockDeprecated.h b/lib/libc/include/x86_64-macos-gnu/libkern/OSSpinLockDeprecated.h new file mode 100644 index 0000000000..a654a7bbc2 --- /dev/null +++ b/lib/libc/include/x86_64-macos-gnu/libkern/OSSpinLockDeprecated.h @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2004-2016 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef _OSSPINLOCK_DEPRECATED_H_ +#define _OSSPINLOCK_DEPRECATED_H_ + +/*! @header + * These are deprecated legacy interfaces for userspace spinlocks. + * + * These interfaces should no longer be used, particularily in situations where + * threads of differing priorities may contend on the same spinlock. + * + * The interfaces in should be used instead in cases where a very + * low-level lock primitive is required. In general however, using higher level + * synchronization primitives such as those provided by the pthread or dispatch + * subsystems should be preferred. + * + * Define OSSPINLOCK_USE_INLINED=1 to get inline implementations of these + * interfaces in terms of the primitives. This is intended as a + * transition convenience, direct use of those primitives is preferred. + */ + +#ifndef OSSPINLOCK_DEPRECATED +#define OSSPINLOCK_DEPRECATED 1 +#define OSSPINLOCK_DEPRECATED_MSG(_r) "Use " #_r "() from instead" +#define OSSPINLOCK_DEPRECATED_REPLACE_WITH(_r) \ + __OS_AVAILABILITY_MSG(macosx, deprecated=10.12, OSSPINLOCK_DEPRECATED_MSG(_r)) \ + __OS_AVAILABILITY_MSG(ios, deprecated=10.0, OSSPINLOCK_DEPRECATED_MSG(_r)) \ + __OS_AVAILABILITY_MSG(tvos, deprecated=10.0, OSSPINLOCK_DEPRECATED_MSG(_r)) \ + __OS_AVAILABILITY_MSG(watchos, deprecated=3.0, OSSPINLOCK_DEPRECATED_MSG(_r)) +#else +#undef OSSPINLOCK_DEPRECATED +#define OSSPINLOCK_DEPRECATED 0 +#define OSSPINLOCK_DEPRECATED_REPLACE_WITH(_r) +#endif + +#if !(defined(OSSPINLOCK_USE_INLINED) && OSSPINLOCK_USE_INLINED) + +#include +#include +#include +#include +#include + +__BEGIN_DECLS + +/*! @abstract The default value for an OSSpinLock. + @discussion + The convention is that unlocked is zero, locked is nonzero. + */ +#define OS_SPINLOCK_INIT 0 + + +/*! @abstract Data type for a spinlock. + @discussion + You should always initialize a spinlock to {@link OS_SPINLOCK_INIT} before + using it. + */ +typedef int32_t OSSpinLock OSSPINLOCK_DEPRECATED_REPLACE_WITH(os_unfair_lock); + + +/*! @abstract Locks a spinlock if it would not block + @result + Returns false if the lock was already held by another thread, + true if it took the lock successfully. + */ +OSSPINLOCK_DEPRECATED_REPLACE_WITH(os_unfair_lock_trylock) +__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) +bool OSSpinLockTry( volatile OSSpinLock *__lock ); + + +/*! @abstract Locks a spinlock + @discussion + Although the lock operation spins, it employs various strategies to back + off if the lock is held. + */ +OSSPINLOCK_DEPRECATED_REPLACE_WITH(os_unfair_lock_lock) +__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) +void OSSpinLockLock( volatile OSSpinLock *__lock ); + + +/*! @abstract Unlocks a spinlock */ +OSSPINLOCK_DEPRECATED_REPLACE_WITH(os_unfair_lock_unlock) +__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) +void OSSpinLockUnlock( volatile OSSpinLock *__lock ); + +__END_DECLS + +#else /* OSSPINLOCK_USE_INLINED */ + +/* + * Inline implementations of the legacy OSSpinLock interfaces in terms of the + * of the primitives. Direct use of those primitives is preferred. + * + * NOTE: the locked value of os_unfair_lock is implementation defined and + * subject to change, code that relies on the specific locked value used by the + * legacy OSSpinLock interface WILL break when using these inline + * implementations in terms of os_unfair_lock. + */ + +#if !OSSPINLOCK_USE_INLINED_TRANSPARENT + +#include + +__BEGIN_DECLS + +#if __has_attribute(always_inline) +#define OSSPINLOCK_INLINE static __inline +#else +#define OSSPINLOCK_INLINE static __inline __attribute__((__always_inline__)) +#endif + +#define OS_SPINLOCK_INIT 0 +typedef int32_t OSSpinLock; + +#if __has_extension(c_static_assert) +_Static_assert(sizeof(OSSpinLock) == sizeof(os_unfair_lock), + "Incompatible os_unfair_lock type"); +#endif + +OSSPINLOCK_INLINE +void +OSSpinLockLock(volatile OSSpinLock *__lock) +{ + os_unfair_lock_t lock = (os_unfair_lock_t)__lock; + return os_unfair_lock_lock(lock); +} + +OSSPINLOCK_INLINE +bool +OSSpinLockTry(volatile OSSpinLock *__lock) +{ + os_unfair_lock_t lock = (os_unfair_lock_t)__lock; + return os_unfair_lock_trylock(lock); +} + +OSSPINLOCK_INLINE +void +OSSpinLockUnlock(volatile OSSpinLock *__lock) +{ + os_unfair_lock_t lock = (os_unfair_lock_t)__lock; + return os_unfair_lock_unlock(lock); +} + +#undef OSSPINLOCK_INLINE + +__END_DECLS + +#else /* OSSPINLOCK_USE_INLINED_TRANSPARENT */ + +#include +#include +#include +#include +#include + +#define OS_NOSPIN_LOCK_AVAILABILITY \ + __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) \ + __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) + +__BEGIN_DECLS + +#define OS_SPINLOCK_INIT 0 +typedef int32_t OSSpinLock OSSPINLOCK_DEPRECATED_REPLACE_WITH(os_unfair_lock); +typedef volatile OSSpinLock *_os_nospin_lock_t + OSSPINLOCK_DEPRECATED_REPLACE_WITH(os_unfair_lock_t); + +OSSPINLOCK_DEPRECATED_REPLACE_WITH(os_unfair_lock_lock) +OS_NOSPIN_LOCK_AVAILABILITY +void _os_nospin_lock_lock(_os_nospin_lock_t lock); +#undef OSSpinLockLock +#define OSSpinLockLock(lock) _os_nospin_lock_lock(lock) + +OSSPINLOCK_DEPRECATED_REPLACE_WITH(os_unfair_lock_trylock) +OS_NOSPIN_LOCK_AVAILABILITY +bool _os_nospin_lock_trylock(_os_nospin_lock_t lock); +#undef OSSpinLockTry +#define OSSpinLockTry(lock) _os_nospin_lock_trylock(lock) + +OSSPINLOCK_DEPRECATED_REPLACE_WITH(os_unfair_lock_unlock) +OS_NOSPIN_LOCK_AVAILABILITY +void _os_nospin_lock_unlock(_os_nospin_lock_t lock); +#undef OSSpinLockUnlock +#define OSSpinLockUnlock(lock) _os_nospin_lock_unlock(lock) + +__END_DECLS + +#endif /* OSSPINLOCK_USE_INLINED_TRANSPARENT */ + +#endif /* OSSPINLOCK_USE_INLINED */ + +#endif /* _OSSPINLOCK_DEPRECATED_H_ */ \ No newline at end of file diff --git a/lib/std/zig/system.zig b/lib/std/zig/system.zig index 574ccfb32d..09fc15c8ba 100644 --- a/lib/std/zig/system.zig +++ b/lib/std/zig/system.zig @@ -22,6 +22,7 @@ pub const getSDKPath = macos.getSDKPath; pub const NativePaths = struct { include_dirs: ArrayList([:0]u8), lib_dirs: ArrayList([:0]u8), + framework_dirs: ArrayList([:0]u8), rpaths: ArrayList([:0]u8), warnings: ArrayList([:0]u8), @@ -29,6 +30,7 @@ pub const NativePaths = struct { var self: NativePaths = .{ .include_dirs = ArrayList([:0]u8).init(allocator), .lib_dirs = ArrayList([:0]u8).init(allocator), + .framework_dirs = ArrayList([:0]u8).init(allocator), .rpaths = ArrayList([:0]u8).init(allocator), .warnings = ArrayList([:0]u8).init(allocator), }; @@ -88,6 +90,19 @@ pub const NativePaths = struct { return self; } + if (comptime Target.current.isDarwin()) { + try self.addIncludeDir("/usr/include"); + try self.addIncludeDir("/usr/local/include"); + + try self.addLibDir("/usr/lib"); + try self.addLibDir("/usr/local/lib"); + + try self.addFrameworkDir("/Library/Frameworks"); + try self.addFrameworkDir("/System/Library/Frameworks"); + + return self; + } + if (!is_windows) { const triple = try Target.current.linuxTriple(allocator); const qual = Target.current.cpu.arch.ptrBitWidth(); @@ -122,6 +137,7 @@ pub const NativePaths = struct { pub fn deinit(self: *NativePaths) void { deinitArray(&self.include_dirs); deinitArray(&self.lib_dirs); + deinitArray(&self.framework_dirs); deinitArray(&self.rpaths); deinitArray(&self.warnings); self.* = undefined; @@ -158,6 +174,16 @@ pub const NativePaths = struct { return self.appendArray(&self.warnings, s); } + pub fn addFrameworkDir(self: *NativePaths, s: []const u8) !void { + return self.appendArray(&self.framework_dirs, s); + } + + pub fn addFrameworkDirFmt(self: *NativePaths, comptime fmt: []const u8, args: anytype) !void { + const item = try std.fmt.allocPrint0(self.framework_dirs.allocator, fmt, args); + errdefer self.framework_dirs.allocator.free(item); + try self.framework_dirs.append(item); + } + pub fn addWarningFmt(self: *NativePaths, comptime fmt: []const u8, args: anytype) !void { const item = try std.fmt.allocPrint0(self.warnings.allocator, fmt, args); errdefer self.warnings.allocator.free(item); @@ -237,8 +263,7 @@ pub const NativeTargetInfo = struct { // `---` `` ``--> Sub-version (Starting from Windows 10 onwards) // \ `--> Service pack (Always zero in the constants defined) // `--> OS version (Major & minor) - const os_ver: u16 = - @intCast(u16, version_info.dwMajorVersion & 0xff) << 8 | + const os_ver: u16 = @intCast(u16, version_info.dwMajorVersion & 0xff) << 8 | @intCast(u16, version_info.dwMinorVersion & 0xff); const sp_ver: u8 = 0; const sub_ver: u8 = if (os_ver >= 0x0A00) subver: { diff --git a/src/Compilation.zig b/src/Compilation.zig index cd3db84ec2..33376d46d2 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -2079,12 +2079,6 @@ pub fn addCCArgs( try argv.append("-ffunction-sections"); } - try argv.ensureCapacity(argv.items.len + comp.bin_file.options.framework_dirs.len * 2); - for (comp.bin_file.options.framework_dirs) |framework_dir| { - argv.appendAssumeCapacity("-iframework"); - argv.appendAssumeCapacity(framework_dir); - } - if (comp.bin_file.options.link_libcpp) { const libcxx_include_path = try std.fs.path.join(arena, &[_][]const u8{ comp.zig_lib_directory.path.?, "libcxx", "include", diff --git a/src/main.zig b/src/main.zig index 247f8327f0..096fa86c75 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1436,11 +1436,35 @@ fn buildOutputType( for (paths.warnings.items) |warning| { warn("{}", .{warning}); } + + const has_sysroot = if (comptime std.Target.current.isDarwin()) outer: { + const at_least_big_sur = target_info.target.os.getVersionRange().semver.min.major >= 11; + if (at_least_big_sur) { + const sdk_path = try std.zig.system.getSDKPath(arena); + try clang_argv.ensureCapacity(clang_argv.items.len + 2); + clang_argv.appendAssumeCapacity("-isysroot"); + clang_argv.appendAssumeCapacity(sdk_path); + break :outer true; + } + break :outer false; + } else false; + try clang_argv.ensureCapacity(clang_argv.items.len + paths.include_dirs.items.len * 2); + const isystem_flag = if (has_sysroot) "-iwithsysroot" else "-isystem"; for (paths.include_dirs.items) |include_dir| { - clang_argv.appendAssumeCapacity("-isystem"); + clang_argv.appendAssumeCapacity(isystem_flag); clang_argv.appendAssumeCapacity(include_dir); } + + try clang_argv.ensureCapacity(clang_argv.items.len + paths.framework_dirs.items.len * 2); + try framework_dirs.ensureCapacity(framework_dirs.items.len + paths.framework_dirs.items.len); + const iframework_flag = if (has_sysroot) "-iframeworkwithsysroot" else "-iframework"; + for (paths.framework_dirs.items) |framework_dir| { + clang_argv.appendAssumeCapacity(iframework_flag); + clang_argv.appendAssumeCapacity(framework_dir); + framework_dirs.appendAssumeCapacity(framework_dir); + } + for (paths.lib_dirs.items) |lib_dir| { try lib_dirs.append(lib_dir); }