Skip to content

Commit

Permalink
Merge pull request ziglang#7506 from kubkon/fix-6923
Browse files Browse the repository at this point in the history
zig cc: detect framework include paths when native
  • Loading branch information
kubkon authored Jan 2, 2021
2 parents a9c75a2 + 763d807 commit 5a65796
Show file tree
Hide file tree
Showing 7 changed files with 311 additions and 9 deletions.
47 changes: 47 additions & 0 deletions lib/libc/include/x86_64-macos-gnu/libkern/OSAtomic.h
Original file line number Diff line number Diff line change
@@ -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 <stdatomic.h> primitives.
*
* Define OSSPINLOCK_USE_INLINED=1 to get inline implementations of the
* OSSpinLock interfaces in terms of the <os/lock.h> primitives.
*
* These are intended as a transition convenience, direct use of those
* primitives should be preferred.
*/

#include <sys/cdefs.h>

#include "OSAtomicDeprecated.h"
#include "OSSpinLockDeprecated.h"
#include "OSAtomicQueue.h"

#endif /* _OSATOMIC_H_ */
212 changes: 212 additions & 0 deletions lib/libc/include/x86_64-macos-gnu/libkern/OSSpinLockDeprecated.h
Original file line number Diff line number Diff line change
@@ -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 <os/lock.h> 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 <os/lock.h> 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 <os/lock.h> 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 <sys/cdefs.h>
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <Availability.h>

__BEGIN_DECLS

/*! @abstract The default value for an <code>OSSpinLock</code>.
@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 <code>false</code> if the lock was already held by another thread,
<code>true</code> 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 <os/lock.h> 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 <os/lock.h>

__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 <sys/cdefs.h>
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <Availability.h>

#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_ */
29 changes: 27 additions & 2 deletions lib/std/zig/system.zig
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,15 @@ 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),

pub fn detect(allocator: *Allocator) !NativePaths {
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),
};
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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: {
Expand Down
6 changes: 0 additions & 6 deletions src/Compilation.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
26 changes: 25 additions & 1 deletion src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down

0 comments on commit 5a65796

Please sign in to comment.