Skip to content
Draft
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
7 changes: 6 additions & 1 deletion compiler/src/dmd/frontend.h
Original file line number Diff line number Diff line change
Expand Up @@ -7331,6 +7331,7 @@ struct Target final

OS os;
uint8_t osMajor;
uint32_t osVersionLong;
uint8_t ptrsize;
uint8_t realsize;
uint8_t realpad;
Expand Down Expand Up @@ -7396,6 +7397,8 @@ struct Target final
floatAbi = 2,
objectFormat = 3,
CET = 4,
OSXVersion = 5,
FreeBSDVersion = 6,
};

public:
Expand All @@ -7405,6 +7408,7 @@ struct Target final
bool supportsLinkerDirective() const;
Target() :
osMajor(),
osVersionLong(),
ptrsize(),
realsize(),
realpad(),
Expand All @@ -7430,9 +7434,10 @@ struct Target final
params()
{
}
Target(OS os, uint8_t osMajor = 0u, uint8_t ptrsize = 0u, uint8_t realsize = 0u, uint8_t realpad = 0u, uint8_t realalignsize = 0u, uint8_t classinfosize = 0u, uint64_t maxStaticDataSize = 0LLU, TargetC c = TargetC(), TargetCPP cpp = TargetCPP(), TargetObjC objc = TargetObjC(), _d_dynamicArray< const char > architectureName = {}, CPU cpu = (CPU)0u, bool isAArch64 = false, bool isX86_64 = false, bool isX86 = false, bool isLP64 = false, _d_dynamicArray< const char > obj_ext = {}, _d_dynamicArray< const char > lib_ext = {}, _d_dynamicArray< const char > dll_ext = {}, bool run_noext = false, FPTypeProperties<float > FloatProperties = FPTypeProperties<float >(), FPTypeProperties<double > DoubleProperties = FPTypeProperties<double >(), FPTypeProperties<_d_real > RealProperties = FPTypeProperties<_d_real >(), Type* tvalist = nullptr, const Param* params = nullptr) :
Target(OS os, uint8_t osMajor = 0u, uint32_t osVersionLong = 0u, uint8_t ptrsize = 0u, uint8_t realsize = 0u, uint8_t realpad = 0u, uint8_t realalignsize = 0u, uint8_t classinfosize = 0u, uint64_t maxStaticDataSize = 0LLU, TargetC c = TargetC(), TargetCPP cpp = TargetCPP(), TargetObjC objc = TargetObjC(), _d_dynamicArray< const char > architectureName = {}, CPU cpu = (CPU)0u, bool isAArch64 = false, bool isX86_64 = false, bool isX86 = false, bool isLP64 = false, _d_dynamicArray< const char > obj_ext = {}, _d_dynamicArray< const char > lib_ext = {}, _d_dynamicArray< const char > dll_ext = {}, bool run_noext = false, FPTypeProperties<float > FloatProperties = FPTypeProperties<float >(), FPTypeProperties<double > DoubleProperties = FPTypeProperties<double >(), FPTypeProperties<_d_real > RealProperties = FPTypeProperties<_d_real >(), Type* tvalist = nullptr, const Param* params = nullptr) :
os(os),
osMajor(osMajor),
osVersionLong(osVersionLong),
ptrsize(ptrsize),
realsize(realsize),
realpad(realpad),
Expand Down
115 changes: 113 additions & 2 deletions compiler/src/dmd/target.d
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
module dmd.target;

import core.stdc.stdio;
import core.stdc.stdlib;

import dmd.astenums : CHECKENABLE;
import dmd.globals : Param;
Expand Down Expand Up @@ -350,6 +351,7 @@ extern (C++) struct Target

OS os;
ubyte osMajor;
uint osVersionLong; /// major, minor, patch version for getTargetInfo.

// D ABI
ubyte ptrsize; /// size of a pointer in bytes
Expand Down Expand Up @@ -1275,14 +1277,17 @@ extern (C++) struct Target
}
}

// this guarantees `getTargetInfo` and `allTargetInfos` remain in sync
// NOTE: If `allTargetInfos` gets implemented, the platform-specific keys
// should be moved to a separate enum.
private enum TargetInfoKeys
{
cppRuntimeLibrary,
cppStd,
floatAbi,
objectFormat,
CET
CET,
OSXVersion,
FreeBSDVersion,
}

/**
Expand All @@ -1303,6 +1308,11 @@ extern (C++) struct Target
{
return new StringExp(loc, sval);
}
IntegerExp osVersion(uint v)
{
osVersionLong = v;
return new IntegerExp(v);
}

switch (name.toDString) with (TargetInfoKeys)
{
Expand All @@ -1323,6 +1333,91 @@ extern (C++) struct Target
case CET.stringof:
return new IntegerExp(driverParams.ibt);

case OSXVersion.stringof:
if (os == Target.OS.OSX)
{
// Format of the version: XX_YY_ZZ
if (osVersionLong)
return new IntegerExp(osVersionLong);

static uint macOSVersion(uint darwin)
{
// Darwin25 maps to macOS 26
if (darwin >= 25)
return (darwin + 1) * 1_00_00;
// Darwin20 to 24 maps to macOS 11 to 15
else if (darwin >= 20)
return (darwin - 9) * 1_00_00;
// Darwin4 to 19 map to macOS 10.0 to 10.15
else if (darwin >= 4)
return 10_00_00 + ((darwin - 4) * 1_00);
return 0;
}
// Infer from the requested deployment target.
if (const env = getenv("MACOSX_DEPLOYMENT_TARGET"))
{
uint major, minor, tiny;
if (sscanf (env, "%u.%u.%u", &major, &minor, &tiny) >= 0)
return osVersion((major * 1_00_00) + (minor * 1_00) + tiny);
}
// Infer from -target= os version (i.e: darwin20)
if (auto macVersion = macOSVersion(osMajor))
return osVersion(macVersion);
// Infer from the running system.
version (OSX)
{
char[32] buf = 0;
size_t length = buf.length;
uint major, minor, tiny;
if (sysctlbyname("kern.osproductversion", buf.ptr, &length, null, 0) == 0)
{
// Returns the macOS version string, e.g: 12.6.0
if (sscanf(buf.ptr, "%u.%u.%u", &major, &minor, &tiny) >= 0)
return osVersion((major * 1_00_00) + (minor * 1_00) + tiny);
}
if (sysctlbyname("kern.osrelease", buf.ptr, &length, null, 0) == 0)
{
// Returns the darwin version string, map to macOS.
if (sscanf(buf.ptr, "%u.%u.%u", &major, &minor, &tiny) >= 0)
{
if (auto macVersion = macOSVersion(major))
return osVersion(macVersion);
}
}
}
// Fallback on guessing appropriate minimum version.
if (isAArch64)
return osVersion(11_00_00);
else if (isX86_64)
return osVersion(10_06_00);
else
return osVersion(10_05_00);
}
goto default;

case FreeBSDVersion.stringof:
if (os == Target.OS.FreeBSD)
{
// Format of the version: XX_YY_ZZZ
if (osVersionLong)
return new IntegerExp(osVersionLong);

// Infer from -target= os version (i.e: freebsd13)
if (osMajor)
return osVersion(osMajor * 1_00_000);
Comment on lines +1405 to +1407
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

freebsd13.2 is also a valid triplet but the implementation in dmd to parse this ignores the minor version number.

Perhaps that should be fixed, as the same applies to darwin triplets too (though darwin19.1 and darwin20.1 might have two subtly different meanings between old and new macos versioning schemes)

// Infer from the running system.
version (FreeBSD)
{
int osreldate;
size_t length = int.sizeof;
if (sysctlbyname("kern.osreldate", &osreldate, &length, null, 0) == 0)
return osVersion(osreldate);
}
// Fallback to minimum supported version.
return osVersion(10_00_000);
}
goto default;

default:
return null;
}
Expand Down Expand Up @@ -1718,3 +1813,19 @@ struct TargetObjC

////////////////////////////////////////////////////////////////////////////////
extern (C++) __gshared Target target;

private
{
// Define our own version of C prototypes, as older compilers didn't have
// the core.sys.*.sysctl module.
version (OSX)
{
extern (C) int sysctlbyname(const char* name, void* oldp, size_t* oldlenp,
const void* newp, size_t newlen) nothrow @nogc;
}
version (FreeBSD)
{
extern (C) int sysctlbyname(const char* name, void* oldp, size_t* oldlenp,
const void* newp, size_t newlen) nothrow @nogc;
}
}
1 change: 1 addition & 0 deletions compiler/src/dmd/target.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ struct Target

OS os;
uint8_t osMajor;
uint32_t osVersionLong;
// D ABI
uint8_t ptrsize;
uint8_t realsize; // size a real consumes in memory
Expand Down
4 changes: 1 addition & 3 deletions druntime/src/core/internal/qsort.d
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,7 @@ static if (Glibc_Qsort_R)
}
else version (FreeBSD)
{
import core.sys.freebsd.config : __FreeBSD_version;

static if (__FreeBSD_version >= 1400000)
static if (__traits(getTargetInfo, "FreeBSDVersion") >= 1400000)
{
// FreeBSD changed qsort_r function signature to POSIX in FreeBSD 14.0
alias Cmp = extern (C) int function(scope const void*, scope const void*, scope void*);
Expand Down
14 changes: 2 additions & 12 deletions druntime/src/core/sys/freebsd/config.d
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,7 @@ public import core.sys.posix.config;
// NOTE: When adding newer versions of FreeBSD, verify all current versioned
// bindings are still compatible with the release.

version (CoreDdoc) enum __FreeBSD_version = 1600011; // keep at latest
else version (FreeBSD_16) enum __FreeBSD_version = 1600011;
else version (FreeBSD_15) enum __FreeBSD_version = 1500063;
else version (FreeBSD_14) enum __FreeBSD_version = 1400097;
else version (FreeBSD_13) enum __FreeBSD_version = 1301000;
else version (FreeBSD_12) enum __FreeBSD_version = 1203000;
else version (FreeBSD_11) enum __FreeBSD_version = 1104000;
else version (FreeBSD_10) enum __FreeBSD_version = 1004000;
else version (FreeBSD_9) enum __FreeBSD_version = 903000;
else version (FreeBSD_8) enum __FreeBSD_version = 804000;
else static assert(false, "Unsupported version of FreeBSD");
enum __FreeBSD_version = __traits(getTargetInfo, "FreeBSDVersion");

// First version of FreeBSD to support 64-bit stat buffer.
enum INO64_FIRST = 1200031;
enum INO64_FIRST = 1200000;
4 changes: 2 additions & 2 deletions druntime/src/core/sys/freebsd/sys/event.d
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ enum
EVFILT_SYSCOUNT = 11,
}

static if (__FreeBSD_version >= 1200000)
static if (__traits(getTargetInfo, "FreeBSDVersion") >= 1200000)
{
struct kevent_t
{
Expand Down Expand Up @@ -170,7 +170,7 @@ version (GNU)
}
else
{
static if (__FreeBSD_version >= 1200000)
static if (__traits(getTargetInfo, "FreeBSDVersion") >= 1200000)
pragma(mangle, "kevent@@FBSD_1.5")
int kevent(int kq, const kevent_t *changelist, int nchanges,
kevent_t *eventlist, int nevents,
Expand Down
4 changes: 2 additions & 2 deletions druntime/src/core/sys/freebsd/sys/mount.d
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ struct fid

enum MFSNAMELEN = 16;

static if (__FreeBSD_version >= 1200000)
static if (__traits(getTargetInfo, "FreeBSDVersion") >= 1200000)
{
enum MNAMELEN = 1024;
enum STATFS_VERSION = 0x20140518;
Expand Down Expand Up @@ -316,7 +316,7 @@ version (GNU)
}
else
{
static if (__FreeBSD_version >= 1200000)
static if (__traits(getTargetInfo, "FreeBSDVersion") >= 1200000)
{
pragma(mangle, "fhstat@FBSD_1.5") int fhstat(const fhandle_t*, stat_t*);
pragma(mangle, "fhstatfs@FBSD_1.5") int fhstatfs(const fhandle_t*, statfs_t*);
Expand Down
10 changes: 3 additions & 7 deletions druntime/src/core/sys/posix/dirent.d
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,7 @@ else version (Darwin)
}
else version (FreeBSD)
{
import core.sys.freebsd.config;

static if (__FreeBSD_version >= 1200000)
static if (__traits(getTargetInfo, "FreeBSDVersion") >= 1200000)
{
struct dirent
{
Expand Down Expand Up @@ -240,8 +238,6 @@ else version (Darwin)
}
else version (FreeBSD)
{
import core.sys.freebsd.config;

// https://github.com/freebsd/freebsd/blob/master/sys/sys/dirent.h
enum
{
Expand All @@ -264,7 +260,7 @@ else version (FreeBSD)
}
else
{
static if (__FreeBSD_version >= 1200000)
static if (__traits(getTargetInfo, "FreeBSDVersion") >= 1200000)
pragma(mangle, "readdir@FBSD_1.5") dirent* readdir(DIR*);
else
pragma(mangle, "readdir@FBSD_1.0") dirent* readdir(DIR*);
Expand Down Expand Up @@ -536,7 +532,7 @@ else version (FreeBSD)
}
else
{
static if (__FreeBSD_version >= 1200000)
static if (__traits(getTargetInfo, "FreeBSDVersion") >= 1200000)
pragma(mangle, "readdir_r@FBSD_1.5") int readdir_r(DIR*, dirent*, dirent**);
else
pragma(mangle, "readdir_r@FBSD_1.0") int readdir_r(DIR*, dirent*, dirent**);
Expand Down
4 changes: 1 addition & 3 deletions druntime/src/core/sys/posix/stdio.d
Original file line number Diff line number Diff line change
Expand Up @@ -364,14 +364,12 @@ else version (Darwin)
}
else version (FreeBSD)
{
import core.sys.freebsd.config;

enum L_ctermid = 1024;

int fseeko(FILE*, off_t, int);
off_t ftello(FILE*);

static if (__FreeBSD_version >= 800000)
static if (__traits(getTargetInfo, "FreeBSDVersion") >= 800000)
{
ssize_t getdelim(char**, size_t*, int, FILE*);
ssize_t getline(char**, size_t*, FILE*);
Expand Down
10 changes: 5 additions & 5 deletions druntime/src/core/sys/posix/sys/stat.d
Original file line number Diff line number Diff line change
Expand Up @@ -1227,7 +1227,7 @@ else version (FreeBSD)
import core.sys.freebsd.config;

// https://github.com/freebsd/freebsd/blob/master/sys/sys/stat.h
static if (__FreeBSD_version >= INO64_FIRST)
static if (__traits(getTargetInfo, "FreeBSDVersion") >= INO64_FIRST)
{
struct stat_t
{
Expand Down Expand Up @@ -2045,7 +2045,7 @@ else version (FreeBSD)
}
else
{
static if (__FreeBSD_version >= INO64_FIRST)
static if (__traits(getTargetInfo, "FreeBSDVersion") >= INO64_FIRST)
{
pragma(mangle, "fstat@FBSD_1.5") int fstat(int, stat_t*);
pragma(mangle, "lstat@FBSD_1.5") int lstat(const scope char*, stat_t*);
Expand All @@ -2058,14 +2058,14 @@ else version (FreeBSD)
pragma(mangle, "stat@FBSD_1.0") int stat(const scope char*, stat_t*);
}
}
static if (__FreeBSD_version >= 800000)
static if (__traits(getTargetInfo, "FreeBSDVersion") >= 800000)
{
int fchmodat(int, const scope char*, mode_t, int);
int fstatat(int, const scope char*, stat_t*, int);
int mkdirat(int, const scope char*, mode_t);
int mkfifoat(int, const scope char*, mode_t);
}
static if (__FreeBSD_version >= 1003000)
static if (__traits(getTargetInfo, "FreeBSDVersion") >= 1000000)
{
int futimens(int, ref const(timespec)[2]);
int utimensat(int, const scope char*, ref const(timespec)[2], int);
Expand Down Expand Up @@ -2345,7 +2345,7 @@ else version (FreeBSD)
}
else
{
static if (__FreeBSD_version >= INO64_FIRST)
static if (__traits(getTargetInfo, "FreeBSDVersion") >= INO64_FIRST)
pragma(mangle, "mknod@FBSD_1.5") int mknod(const scope char*, mode_t, dev_t);
else
pragma(mangle, "mknod@FBSD_1.0") int mknod(const scope char*, mode_t, dev_t);
Expand Down
4 changes: 1 addition & 3 deletions druntime/src/core/sys/posix/sys/types.d
Original file line number Diff line number Diff line change
Expand Up @@ -209,13 +209,11 @@ else version (Darwin)
}
else version (FreeBSD)
{
import core.sys.freebsd.config;

// https://github.com/freebsd/freebsd/blob/master/sys/sys/_types.h
alias blkcnt_t = long;
alias blksize_t = uint;

static if (__FreeBSD_version >= 1200000)
static if (__traits(getTargetInfo, "FreeBSDVersion") >= 1200000)
{
alias dev_t = ulong;
alias ino_t = ulong;
Expand Down
Loading
Loading