Skip to content

Commit ccbe862

Browse files
committed
Implement getTargetInfo OSXVersion and FreeBSDVersion
1 parent a328c7c commit ccbe862

13 files changed

Lines changed: 150 additions & 45 deletions

File tree

compiler/src/dmd/frontend.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7328,6 +7328,7 @@ struct Target final
73287328

73297329
OS os;
73307330
uint8_t osMajor;
7331+
uint32_t osVersionLong;
73317332
uint8_t ptrsize;
73327333
uint8_t realsize;
73337334
uint8_t realpad;
@@ -7393,6 +7394,8 @@ struct Target final
73937394
floatAbi = 2,
73947395
objectFormat = 3,
73957396
CET = 4,
7397+
OSXVersion = 5,
7398+
FreeBSDVersion = 6,
73967399
};
73977400

73987401
public:
@@ -7402,6 +7405,7 @@ struct Target final
74027405
bool supportsLinkerDirective() const;
74037406
Target() :
74047407
osMajor(),
7408+
osVersionLong(),
74057409
ptrsize(),
74067410
realsize(),
74077411
realpad(),
@@ -7427,9 +7431,10 @@ struct Target final
74277431
params()
74287432
{
74297433
}
7430-
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) :
7434+
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) :
74317435
os(os),
74327436
osMajor(osMajor),
7437+
osVersionLong(osVersionLong),
74337438
ptrsize(ptrsize),
74347439
realsize(realsize),
74357440
realpad(realpad),

compiler/src/dmd/target.d

Lines changed: 113 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
module dmd.target;
2727

2828
import core.stdc.stdio;
29+
import core.stdc.stdlib;
2930

3031
import dmd.astenums : CHECKENABLE;
3132
import dmd.globals : Param;
@@ -350,6 +351,7 @@ extern (C++) struct Target
350351

351352
OS os;
352353
ubyte osMajor;
354+
uint osVersionLong; /// major, minor, patch version for getTargetInfo.
353355

354356
// D ABI
355357
ubyte ptrsize; /// size of a pointer in bytes
@@ -1275,14 +1277,17 @@ extern (C++) struct Target
12751277
}
12761278
}
12771279

1278-
// this guarantees `getTargetInfo` and `allTargetInfos` remain in sync
1280+
// NOTE: If `allTargetInfos` gets implemented, the platform-specific keys
1281+
// should be moved to a separate enum.
12791282
private enum TargetInfoKeys
12801283
{
12811284
cppRuntimeLibrary,
12821285
cppStd,
12831286
floatAbi,
12841287
objectFormat,
1285-
CET
1288+
CET,
1289+
OSXVersion,
1290+
FreeBSDVersion,
12861291
}
12871292

12881293
/**
@@ -1303,6 +1308,11 @@ extern (C++) struct Target
13031308
{
13041309
return new StringExp(loc, sval);
13051310
}
1311+
IntegerExp osVersion(uint v)
1312+
{
1313+
osVersionLong = v;
1314+
return new IntegerExp(v);
1315+
}
13061316

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

1336+
case OSXVersion.stringof:
1337+
if (os == Target.OS.OSX)
1338+
{
1339+
// Format of the version: XX_YY_ZZ
1340+
if (osVersionLong)
1341+
return new IntegerExp(osVersionLong);
1342+
1343+
static uint macOSVersion(uint darwin)
1344+
{
1345+
// Darwin25 maps to macOS 26
1346+
if (darwin >= 25)
1347+
return (darwin + 1) * 1_00_00;
1348+
// Darwin20 to 24 maps to macOS 11 to 15
1349+
else if (darwin >= 20)
1350+
return (darwin - 9) * 1_00_00;
1351+
// Darwin4 to 19 map to macOS 10.0 to 10.15
1352+
else if (darwin >= 4)
1353+
return 10_00_00 + ((darwin - 4) * 1_00);
1354+
return 0;
1355+
}
1356+
// Infer from the requested deployment target.
1357+
if (const env = getenv("MACOSX_DEPLOYMENT_TARGET"))
1358+
{
1359+
uint major, minor, tiny;
1360+
if (sscanf ("%u.%u.%u", &major, &minor, &tiny) >= 0)
1361+
return osVersion((major * 1_00_00) + (minor * 1_00) + tiny);
1362+
}
1363+
// Infer from -target= os version (i.e: darwin20)
1364+
if (auto macVersion = macOSVersion(osMajor))
1365+
return osVersion(macVersion);
1366+
// Infer from the running system.
1367+
version (OSX)
1368+
{
1369+
char[32] buf = 0;
1370+
size_t length = buf.length;
1371+
uint major, minor, tiny;
1372+
if (sysctlbyname("kern.osproductversion", buf.ptr, &length, null, 0) == 0)
1373+
{
1374+
// Returns the macOS version string, e.g: 12.6.0
1375+
if (sscanf(buf.ptr, "%u.%u.%u", &major, &minor, &tiny) >= 0)
1376+
return osVersion((major * 1_00_00) + (minor * 1_00) + tiny);
1377+
}
1378+
if (sysctlbyname("kern.osrelease", buf.ptr, &length, null, 0) == 0)
1379+
{
1380+
// Returns the darwin version string, map to macOS.
1381+
if (sscanf(buf.ptr, "%u.%u.%u", &major, &minor, &tiny) >= 0)
1382+
{
1383+
if (auto macVersion = macOSVersion(major))
1384+
return osVersion(macVersion);
1385+
}
1386+
}
1387+
}
1388+
// Fallback on guessing appropriate minimum version.
1389+
if (isAArch64)
1390+
return osVersion(11_00_00);
1391+
else if (isX86_64)
1392+
return osVersion(10_06_00);
1393+
else
1394+
return osVersion(10_05_00);
1395+
}
1396+
goto default;
1397+
1398+
case FreeBSDVersion.stringof:
1399+
if (os == Target.OS.FreeBSD)
1400+
{
1401+
// Format of the version: XX_YY_ZZZ
1402+
if (osVersionLong)
1403+
return new IntegerExp(osVersionLong);
1404+
1405+
// Infer from -target= os version (i.e: freebsd13)
1406+
if (osMajor)
1407+
return osVersion(osMajor * 1_00_000);
1408+
// Infer from the running system.
1409+
version (FreeBSD)
1410+
{
1411+
int osreldate;
1412+
size_t length = int.sizeof;
1413+
if (sysctlbyname("kern.osreldate", &osreldate, &length, null, 0) == 0)
1414+
return osVersion(osreldate);
1415+
}
1416+
// Fallback to minimum supported version.
1417+
return osVersion(10_00_000);
1418+
}
1419+
goto default;
1420+
13261421
default:
13271422
return null;
13281423
}
@@ -1718,3 +1813,19 @@ struct TargetObjC
17181813

17191814
////////////////////////////////////////////////////////////////////////////////
17201815
extern (C++) __gshared Target target;
1816+
1817+
private
1818+
{
1819+
// Define our own version of C prototypes, as older compilers didn't have
1820+
// the core.sys.*.sysctl module.
1821+
version (OSX)
1822+
{
1823+
extern (C) int sysctlbyname(const char* name, void* oldp, size_t* oldlenp,
1824+
const void* newp, size_t newlen) nothrow @nogc;
1825+
}
1826+
version (FreeBSD)
1827+
{
1828+
extern (C) int sysctlbyname(const char* name, void* oldp, size_t* oldlenp,
1829+
const void* newp, size_t newlen) nothrow @nogc;
1830+
}
1831+
}

compiler/src/dmd/target.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ struct Target
137137

138138
OS os;
139139
uint8_t osMajor;
140+
uint32_t osVersionLong;
140141
// D ABI
141142
uint8_t ptrsize;
142143
uint8_t realsize; // size a real consumes in memory

druntime/src/core/internal/qsort.d

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,7 @@ static if (Glibc_Qsort_R)
5656
}
5757
else version (FreeBSD)
5858
{
59-
import core.sys.freebsd.config : __FreeBSD_version;
60-
61-
static if (__FreeBSD_version >= 1400000)
59+
static if (__traits(getTargetInfo, "FreeBSDVersion") >= 1400000)
6260
{
6361
// FreeBSD changed qsort_r function signature to POSIX in FreeBSD 14.0
6462
alias Cmp = extern (C) int function(scope const void*, scope const void*, scope void*);

druntime/src/core/sys/freebsd/config.d

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,7 @@ public import core.sys.posix.config;
1414
// NOTE: When adding newer versions of FreeBSD, verify all current versioned
1515
// bindings are still compatible with the release.
1616

17-
version (CoreDdoc) enum __FreeBSD_version = 1600011; // keep at latest
18-
else version (FreeBSD_16) enum __FreeBSD_version = 1600011;
19-
else version (FreeBSD_15) enum __FreeBSD_version = 1500063;
20-
else version (FreeBSD_14) enum __FreeBSD_version = 1400097;
21-
else version (FreeBSD_13) enum __FreeBSD_version = 1301000;
22-
else version (FreeBSD_12) enum __FreeBSD_version = 1203000;
23-
else version (FreeBSD_11) enum __FreeBSD_version = 1104000;
24-
else version (FreeBSD_10) enum __FreeBSD_version = 1004000;
25-
else version (FreeBSD_9) enum __FreeBSD_version = 903000;
26-
else version (FreeBSD_8) enum __FreeBSD_version = 804000;
27-
else static assert(false, "Unsupported version of FreeBSD");
17+
enum __FreeBSD_version = __traits(getTargetInfo, "FreeBSDVersion");
2818

2919
// First version of FreeBSD to support 64-bit stat buffer.
30-
enum INO64_FIRST = 1200031;
20+
enum INO64_FIRST = 1200000;

druntime/src/core/sys/freebsd/sys/event.d

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ enum
3939
EVFILT_SYSCOUNT = 11,
4040
}
4141

42-
static if (__FreeBSD_version >= 1200000)
42+
static if (__traits(getTargetInfo, "FreeBSDVersion") >= 1200000)
4343
{
4444
struct kevent_t
4545
{
@@ -170,7 +170,7 @@ version (GNU)
170170
}
171171
else
172172
{
173-
static if (__FreeBSD_version >= 1200000)
173+
static if (__traits(getTargetInfo, "FreeBSDVersion") >= 1200000)
174174
pragma(mangle, "kevent@@FBSD_1.5")
175175
int kevent(int kq, const kevent_t *changelist, int nchanges,
176176
kevent_t *eventlist, int nevents,

druntime/src/core/sys/freebsd/sys/mount.d

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ struct fid
3434

3535
enum MFSNAMELEN = 16;
3636

37-
static if (__FreeBSD_version >= 1200000)
37+
static if (__traits(getTargetInfo, "FreeBSDVersion") >= 1200000)
3838
{
3939
enum MNAMELEN = 1024;
4040
enum STATFS_VERSION = 0x20140518;
@@ -316,7 +316,7 @@ version (GNU)
316316
}
317317
else
318318
{
319-
static if (__FreeBSD_version >= 1200000)
319+
static if (__traits(getTargetInfo, "FreeBSDVersion") >= 1200000)
320320
{
321321
pragma(mangle, "fhstat@FBSD_1.5") int fhstat(const fhandle_t*, stat_t*);
322322
pragma(mangle, "fhstatfs@FBSD_1.5") int fhstatfs(const fhandle_t*, statfs_t*);

druntime/src/core/sys/posix/dirent.d

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,7 @@ else version (Darwin)
8282
}
8383
else version (FreeBSD)
8484
{
85-
import core.sys.freebsd.config;
86-
87-
static if (__FreeBSD_version >= 1200000)
85+
static if (__traits(getTargetInfo, "FreeBSDVersion") >= 1200000)
8886
{
8987
struct dirent
9088
{
@@ -240,8 +238,6 @@ else version (Darwin)
240238
}
241239
else version (FreeBSD)
242240
{
243-
import core.sys.freebsd.config;
244-
245241
// https://github.com/freebsd/freebsd/blob/master/sys/sys/dirent.h
246242
enum
247243
{
@@ -264,7 +260,7 @@ else version (FreeBSD)
264260
}
265261
else
266262
{
267-
static if (__FreeBSD_version >= 1200000)
263+
static if (__traits(getTargetInfo, "FreeBSDVersion") >= 1200000)
268264
pragma(mangle, "readdir@FBSD_1.5") dirent* readdir(DIR*);
269265
else
270266
pragma(mangle, "readdir@FBSD_1.0") dirent* readdir(DIR*);
@@ -536,7 +532,7 @@ else version (FreeBSD)
536532
}
537533
else
538534
{
539-
static if (__FreeBSD_version >= 1200000)
535+
static if (__traits(getTargetInfo, "FreeBSDVersion") >= 1200000)
540536
pragma(mangle, "readdir_r@FBSD_1.5") int readdir_r(DIR*, dirent*, dirent**);
541537
else
542538
pragma(mangle, "readdir_r@FBSD_1.0") int readdir_r(DIR*, dirent*, dirent**);

druntime/src/core/sys/posix/stdio.d

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -364,14 +364,12 @@ else version (Darwin)
364364
}
365365
else version (FreeBSD)
366366
{
367-
import core.sys.freebsd.config;
368-
369367
enum L_ctermid = 1024;
370368

371369
int fseeko(FILE*, off_t, int);
372370
off_t ftello(FILE*);
373371

374-
static if (__FreeBSD_version >= 800000)
372+
static if (__traits(getTargetInfo, "FreeBSDVersion") >= 800000)
375373
{
376374
ssize_t getdelim(char**, size_t*, int, FILE*);
377375
ssize_t getline(char**, size_t*, FILE*);

druntime/src/core/sys/posix/sys/stat.d

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1227,7 +1227,7 @@ else version (FreeBSD)
12271227
import core.sys.freebsd.config;
12281228

12291229
// https://github.com/freebsd/freebsd/blob/master/sys/sys/stat.h
1230-
static if (__FreeBSD_version >= INO64_FIRST)
1230+
static if (__traits(getTargetInfo, "FreeBSDVersion") >= INO64_FIRST)
12311231
{
12321232
struct stat_t
12331233
{
@@ -2045,7 +2045,7 @@ else version (FreeBSD)
20452045
}
20462046
else
20472047
{
2048-
static if (__FreeBSD_version >= INO64_FIRST)
2048+
static if (__traits(getTargetInfo, "FreeBSDVersion") >= INO64_FIRST)
20492049
{
20502050
pragma(mangle, "fstat@FBSD_1.5") int fstat(int, stat_t*);
20512051
pragma(mangle, "lstat@FBSD_1.5") int lstat(const scope char*, stat_t*);
@@ -2058,14 +2058,14 @@ else version (FreeBSD)
20582058
pragma(mangle, "stat@FBSD_1.0") int stat(const scope char*, stat_t*);
20592059
}
20602060
}
2061-
static if (__FreeBSD_version >= 800000)
2061+
static if (__traits(getTargetInfo, "FreeBSDVersion") >= 800000)
20622062
{
20632063
int fchmodat(int, const scope char*, mode_t, int);
20642064
int fstatat(int, const scope char*, stat_t*, int);
20652065
int mkdirat(int, const scope char*, mode_t);
20662066
int mkfifoat(int, const scope char*, mode_t);
20672067
}
2068-
static if (__FreeBSD_version >= 1003000)
2068+
static if (__traits(getTargetInfo, "FreeBSDVersion") >= 1000000)
20692069
{
20702070
int futimens(int, ref const(timespec)[2]);
20712071
int utimensat(int, const scope char*, ref const(timespec)[2], int);
@@ -2345,7 +2345,7 @@ else version (FreeBSD)
23452345
}
23462346
else
23472347
{
2348-
static if (__FreeBSD_version >= INO64_FIRST)
2348+
static if (__traits(getTargetInfo, "FreeBSDVersion") >= INO64_FIRST)
23492349
pragma(mangle, "mknod@FBSD_1.5") int mknod(const scope char*, mode_t, dev_t);
23502350
else
23512351
pragma(mangle, "mknod@FBSD_1.0") int mknod(const scope char*, mode_t, dev_t);

0 commit comments

Comments
 (0)