@@ -3,7 +3,7 @@ public import redub.libs.semver;
33import hipjson;
44
55
6- enum AcceptedCompiler
6+ enum AcceptedCompiler : ubyte
77{
88 invalid,
99 dmd,
@@ -12,21 +12,44 @@ enum AcceptedCompiler
1212 gxx
1313}
1414
15- enum AcceptedLinker
15+ enum AcceptedLinker : ubyte
1616{
1717 unknown,
1818 gnuld,
1919 ld64,
2020 // /I know there a plenty more, but still..
2121}
2222
23+ enum AcceptedArchiver : ubyte
24+ {
25+ ar,
26+ llvmAr,
27+ libtool,
28+ /**
29+ * D compiler will be used for creating the library
30+ */
31+ none
32+ }
33+
2334enum UsesGnuLinker
2435{
2536 unknown,
2637 yes,
2738 no
2839}
2940
41+
42+ struct Archiver
43+ {
44+ AcceptedArchiver type;
45+ string bin;
46+ }
47+ struct Linker
48+ {
49+ AcceptedLinker type;
50+ string bin;
51+ }
52+
3053AcceptedCompiler acceptedCompilerfromString (string str)
3154{
3255 switch (str)
@@ -54,6 +77,35 @@ AcceptedLinker acceptedLinkerfromString(string str)
5477 }
5578}
5679
80+ AcceptedArchiver acceptedArchiverFromString (string str)
81+ {
82+ switch (str)
83+ {
84+ static foreach (mem; __traits (allMembers, AcceptedArchiver))
85+ {
86+ case mem:
87+ return __traits (getMember, AcceptedArchiver, mem);
88+ }
89+ default :
90+ return AcceptedArchiver.none;
91+ }
92+ }
93+
94+ private Linker acceptedLinker (JSONValue v)
95+ {
96+ JSONValue* acc = " defaultLinker" in v;
97+ if (! acc)
98+ return Linker (AcceptedLinker.unknown);
99+ return Linker (acceptedLinkerfromString(acc.object[" type" ].str), acc.object[" bin" ].str);
100+ }
101+
102+ private Archiver acceptedArchiver (JSONValue v)
103+ {
104+ JSONValue* acc = " defaultArchiver" in v;
105+ if (! acc)
106+ return Archiver (AcceptedArchiver.none);
107+ return Archiver (acceptedArchiverFromString(acc.object[" type" ].str), acc.object[" bin" ].str);
108+ }
57109
58110
59111/**
@@ -75,14 +127,21 @@ struct Compiler
75127 // /Accepts both a complete path to an executable or a global environment search path name
76128 string binOrPath;
77129
78- // /Librarian tool
79- string archiver = " llvm-ar" ;
130+ /**
131+ * For generating libraries, redub might use dmd/ldc2 by default since that simplifies the logic.
132+ * Although it is slightly slower, this is also a compromise one takes by using integration with C
133+ */
134+ Archiver archiver = Archiver(AcceptedArchiver.none);
80135
136+ /**
137+ * Currently a flag that only affects Windows. Usually it is turned off since depending on the case, it might
138+ * make compilation slower
139+ */
81140 bool usesIncremental = false ;
82141
83142 // /Currently unused. Was used before for checking whether --start-group should be emitted or not. Since it is emitted
84143 // /by default, only on webAssembly which is not, it lost its usage for now.
85- AcceptedLinker linker = AcceptedLinker.unknown;
144+ Linker linker = Linker( AcceptedLinker.unknown) ;
86145
87146
88147 string getCompilerString () const
@@ -239,7 +298,8 @@ Compiler getCompiler(string compilerOrPath = "dmd", string compilerAssumption =
239298 if (ret == Compiler.init)
240299 ret = inferCompiler(compilerOrPath, compilerAssumption, compilersInfo, isDefault, isGlobal);
241300
242- ret.linker = acceptedLinkerfromString(compilersInfo[" defaultLinker" ].str);
301+ ret.linker = acceptedLinker(compilersInfo);
302+ ret.archiver = acceptedArchiver(compilersInfo);
243303
244304 // Checks for ldc.conf switches to see if it is using gnu linker by default
245305 // /TODO: Might be reactivated if that issue shows again.
@@ -376,7 +436,7 @@ private Compiler getCompilerFromCache(JSONValue allCompilersInfo, string compile
376436 SemVer(arr[VERSION_ ].str),
377437 SemVer(arr[FRONTEND_VERSION ].str),
378438 arr[VERSION_STRING ].str,
379- key, null , false , acceptedLinkerfromString (allCompilersInfo[ " defaultLinker " ].str )
439+ key, acceptedArchiver (allCompilersInfo) , false , acceptedLinker (allCompilersInfo)
380440 );
381441 }
382442 }
@@ -417,11 +477,24 @@ private void saveCompilerInfo(JSONValue allCompilersInfo, ref Compiler compiler,
417477 }
418478 if (! (" version" in allCompilersInfo))
419479 allCompilersInfo[" version" ] = JSONValue(RedubVersionOnly);
480+ if (! (" defaultArchiver" in allCompilersInfo))
481+ {
482+ JSONValue defaultArchiver = JSONValue.emptyObject;
483+ auto def = getDefaultArchiver();
484+ defaultArchiver[" type" ] = def.type.to! string ;
485+ defaultArchiver[" bin" ] = def.bin;
486+ allCompilersInfo[" defaultArchiver" ] = defaultArchiver;
487+ }
420488
421489 if (! (" defaultLinker" in allCompilersInfo))
422- allCompilersInfo[" defaultLinker" ] = JSONValue(getDefaultLinker().to! string );
423-
424- compiler.linker = acceptedLinkerfromString(allCompilersInfo[" defaultLinker" ].str);
490+ {
491+ JSONValue defaultLinker = JSONValue.emptyObject;
492+ auto def = getDefaultLinker();
493+ defaultLinker[" type" ] = def.type.to! string ;
494+ defaultLinker[" bin" ] = def.bin;
495+ allCompilersInfo[" defaultLinker" ] = defaultLinker;
496+ }
497+ compiler.linker = acceptedLinker(allCompilersInfo);
425498
426499 if (! (" compilers" in allCompilersInfo))
427500 allCompilersInfo[" compilers" ] = JSONValue.emptyObject;
@@ -475,23 +548,42 @@ private Compiler assumeCompiler(string compilerOrPath, string compilerAssumption
475548}
476549
477550
478- AcceptedLinker getDefaultLinker ()
551+ Linker getDefaultLinker ()
479552{
480- version ( Posix )
553+ with (AcceptedLinker )
481554 {
482- import std.process ;
483- import std.string ;
484- auto res = executeShell(" ld -v" );
485- if (res.status != 0 )
486- return AcceptedLinker.unknown;
487-
488- if (res.output.startsWith(" GNU ld" ))
489- return AcceptedLinker.gnuld;
490- else if (res.output.startsWith(" @(#)PROGRAM:ld" ))
491- return AcceptedLinker.ld64;
555+ version (Posix )
556+ {
557+ import std.process ;
558+ import std.string ;
559+ auto res = executeShell(" ld -v" );
560+ if (res.status == 0 )
561+ {
562+ if (res.output.startsWith(" GNU ld" ))
563+ return Linker (gnuld, " ld" );
564+ else if (res.output.startsWith(" @(#)PROGRAM:ld" ))
565+ return Linker (ld64, " ld" );
566+ }
567+ }
568+ return Linker (unknown);
492569 }
570+ }
493571
494- return AcceptedLinker.unknown;
572+
573+ Archiver getDefaultArchiver ()
574+ {
575+ import std.array :staticArray;
576+ import std.process ;
577+ with (AcceptedArchiver)
578+ {
579+ foreach (Archiver v; [Archiver(ar, " ar" ), Archiver(llvmAr, " llvm-ar" ), Archiver(libtool, " libtool" )].staticArray)
580+ {
581+ auto res = executeShell(v.bin~ " --help" );
582+ if (res.status == 0 )
583+ return v;
584+ }
585+ return Archiver (none);
586+ }
495587}
496588
497589private bool tryInferLdc (string compilerOrPath, string vString, out Compiler comp)
0 commit comments