Skip to content

Commit 1fe73dc

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

13 files changed

Lines changed: 142 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: 104 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,7 @@ extern (C++) struct Target
350350

351351
OS os;
352352
ubyte osMajor;
353+
uint osVersionLong; /// major, minor, patch version for getTargetInfo.
353354

354355
// D ABI
355356
ubyte ptrsize; /// size of a pointer in bytes
@@ -1275,14 +1276,17 @@ extern (C++) struct Target
12751276
}
12761277
}
12771278

1278-
// this guarantees `getTargetInfo` and `allTargetInfos` remain in sync
1279+
// NOTE: If `allTargetInfos` gets implemented, the platform-specific keys
1280+
// should be moved to a separate enum.
12791281
private enum TargetInfoKeys
12801282
{
12811283
cppRuntimeLibrary,
12821284
cppStd,
12831285
floatAbi,
12841286
objectFormat,
1285-
CET
1287+
CET,
1288+
OSXVersion,
1289+
FreeBSDVersion,
12861290
}
12871291

12881292
/**
@@ -1303,6 +1307,11 @@ extern (C++) struct Target
13031307
{
13041308
return new StringExp(loc, sval);
13051309
}
1310+
IntegerExp osVersion(uint v)
1311+
{
1312+
osVersionLong = v;
1313+
return new IntegerExp(v);
1314+
}
13061315

13071316
switch (name.toDString) with (TargetInfoKeys)
13081317
{
@@ -1323,6 +1332,83 @@ extern (C++) struct Target
13231332
case CET.stringof:
13241333
return new IntegerExp(driverParams.ibt);
13251334

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

17191805
////////////////////////////////////////////////////////////////////////////////
17201806
extern (C++) __gshared Target target;
1807+
1808+
private
1809+
{
1810+
// Define our own version of C prototypes, as older compilers didn't have
1811+
// the core.sys.*.sysctl module.
1812+
version (OSX)
1813+
{
1814+
extern (C) int sysctlbyname(const char* name, void* oldp, size_t* oldlenp,
1815+
const void* newp, size_t newlen) nothrow @nogc;
1816+
}
1817+
version (FreeBSD)
1818+
{
1819+
extern (C) int sysctlbyname(const char* name, void* oldp, size_t* oldlenp,
1820+
const void* newp, size_t newlen) nothrow @nogc;
1821+
}
1822+
}

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)