Skip to content

Commit 70cf62e

Browse files
committed
Add more Clang compatibility workarounds
1 parent e8833bf commit 70cf62e

2 files changed

Lines changed: 126 additions & 20 deletions

File tree

tools/gcc-wrapper/clang_option.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
struct ClangOption {
2+
const char* name;
3+
int value;
4+
};
5+
6+
typedef struct ClangOption clang_option_t;

tools/gcc-wrapper/main.c

Lines changed: 120 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "fs/exists.h"
1616
#include "fs/basename.h"
1717
#include "biggestint.h"
18+
#include "clang_option.h"
1819

1920
#if !(defined(OBGGCC) || defined(PINO))
2021
#error "Please define the cross-compiler flavor for which we will be a wrapper"
@@ -68,6 +69,7 @@ static const char GCC_OPT_STATIC_LIBLSAN[] = "-static-liblsan";
6869
static const char GCC_OPT_STATIC_LIBUBSAN[] = "-static-libubsan";
6970
static const char GCC_OPT_STATIC_LIBHWASAN[] = "-static-libhwasan";
7071

72+
static const char GCC_OPT_VERSION[] = "--version";
7173
static const char GCC_OPT_L[] = "-l";
7274
static const char GCC_OPT_V[] = "-v";
7375
static const char GCC_OPT_D[] = "-D";
@@ -110,13 +112,17 @@ static const char GCC_OPT_D_CLANG_PATCHLEVEL[] = "-D__clang_patchlevel__=0";
110112
static const char GCC_OPT_F_STACK_PROTECTOR[] = "-fstack-protector";
111113

112114
static const char CLANG_OPT_OZ[] = "-Oz";
113-
static const char CLANG_OPT_ICF[] = "--icf=";
115+
static const char CLANG_OPT_ICF[] = "--icf";
114116
static const char CLANG_OPT_TARGET[] = "--target";
115117
static const char CLANG_OPT_Q_UNUSED_ARGUMENTS[] = "-Qunused-arguments";
116118
static const char CLANG_OPT_W_NO_UNUSED_COMMAND_LINE_ARGUMENT[] = "-Wno-unused-command-line-argument";
117119
static const char CLANG_OPT_W_NO_INVALID_COMMAND_LINE_ARGUMENT[] = "-Wno-invalid-command-line-argument";
120+
static const char CLANG_OPT_W_NEWLINE_EOF[] = "-Wnewline-eof";
118121
static const char CLANG_OPT_PRINT_RESOURCE_DIR[] = "-print-resource-dir";
119122
static const char CLANG_OPT_F_NO_LIMIT_DEBUG_INFO[] = "-fno-limit-debug-info";
123+
static const char CLANG_OPT_GCC_TOOLCHAIN[] = "--gcc-toolchain";
124+
static const char CLANG_OPT_F_COLOR_DIAGNOSTICS[] = "-fcolor-diagnostics";
125+
static const char CLANG_OPT_F_NO_INTEGRATED_AS[] = "-fno-integrated-as";
120126

121127
static const char LD_OPT_DYNAMIC_LINKER[] = "-dynamic-linker";
122128
static const char LD_OPT_RPATH_LINK[] = "-rpath-link";
@@ -188,7 +194,9 @@ static const char VENDOR_UNKNOWN[] = "-unknown-";
188194

189195
static const char LD_PREFIX[] = "ld.";
190196

197+
static const char DASH = '-';
191198
static const char EQUAL = '=';
199+
static const char ZERO = '\0';
192200
static const char EQUAL_S[] = "=";
193201

194202
static const char* const FASTER_LINKERS[] = {
@@ -197,6 +205,55 @@ static const char* const FASTER_LINKERS[] = {
197205
"gold"
198206
};
199207

208+
static const char CLANG_VERSION_TEMPLATE[] =
209+
"clang version 21.0.0\n"
210+
"Target: %s\n"
211+
"Thread model: posix\n"
212+
"InstalledDir: %s\n";
213+
214+
static clang_option_t CLANG_SPECIFIC_REMOVE[] = {
215+
{
216+
.name = CLANG_OPT_Q_UNUSED_ARGUMENTS,
217+
.value = 0
218+
},
219+
{
220+
.name = CLANG_OPT_W_NO_UNUSED_COMMAND_LINE_ARGUMENT,
221+
.value = 0
222+
},
223+
{
224+
.name = CLANG_OPT_W_NO_INVALID_COMMAND_LINE_ARGUMENT,
225+
.value = 0
226+
},
227+
{
228+
.name = CLANG_OPT_ICF,
229+
.value = 1
230+
},
231+
{
232+
.name = CLANG_OPT_F_NO_LIMIT_DEBUG_INFO,
233+
.value = 0
234+
},
235+
{
236+
.name = CLANG_OPT_GCC_TOOLCHAIN,
237+
.value = 1
238+
},
239+
{
240+
.name = CLANG_OPT_W_NEWLINE_EOF,
241+
.value = 0
242+
},
243+
{
244+
.name = CLANG_OPT_F_COLOR_DIAGNOSTICS,
245+
.value = 0
246+
},
247+
{
248+
.name = CLANG_OPT_F_NO_INTEGRATED_AS,
249+
.value = 0
250+
},
251+
};
252+
253+
#define CLANG_SPECIFIC_REMOVE_NON 0
254+
#define CLANG_SPECIFIC_REMOVE_CUR 1
255+
#define CLANG_SPECIFIC_REMOVE_NXT 2
256+
200257
#define ERR_SUCCESS 0
201258
#define ERR_MEM_ALLOC_FAILURE -1
202259
#define ERR_UNKNOWN_COMPILER -2
@@ -358,36 +415,59 @@ static int clang_specific_remove(const char* const prev, const char* const cur)
358415
Remove Clang-specific options that have no GCC equivalents.
359416
*/
360417

361-
int status = 1;
418+
int status = CLANG_SPECIFIC_REMOVE_CUR;
419+
size_t index = 0;
420+
421+
size_t size = 0;
362422

363423
const char* previous = prev;
364424
const char* current = cur;
365425

366-
if (strncmp(current, GCC_OPT_WL, strlen(GCC_OPT_WL)) == 0) {
367-
current += strlen(GCC_OPT_WL);
368-
}
426+
const char* name = cur;
427+
int value = 0;
428+
const clang_option_t* option = NULL;
369429

370-
if (strcmp(current, CLANG_OPT_Q_UNUSED_ARGUMENTS) == 0) {
371-
goto end;
372-
}
430+
unsigned char ch = 0;
373431

374-
if (strcmp(current, CLANG_OPT_W_NO_UNUSED_COMMAND_LINE_ARGUMENT) == 0) {
375-
goto end;
432+
if (strncmp(current, GCC_OPT_WL, strlen(GCC_OPT_WL)) == 0) {
433+
current += strlen(GCC_OPT_WL);
376434
}
377435

378-
if (strcmp(current, CLANG_OPT_W_NO_INVALID_COMMAND_LINE_ARGUMENT) == 0) {
436+
if (*current != DASH || *current == ZERO) {
437+
status = CLANG_SPECIFIC_REMOVE_NON;
379438
goto end;
380439
}
381440

382-
if (strncmp(current, CLANG_OPT_ICF, strlen(CLANG_OPT_ICF)) == 0) {
383-
goto end;
384-
}
441+
while (*(++current) == DASH) {};
385442

386-
if (strcmp(current, CLANG_OPT_F_NO_LIMIT_DEBUG_INFO) == 0) {
443+
for (index = 0; index < sizeof(CLANG_SPECIFIC_REMOVE) / sizeof(*CLANG_SPECIFIC_REMOVE); index++) {
444+
option = &CLANG_SPECIFIC_REMOVE[index];
445+
446+
name = option->name;
447+
value = option->value;
448+
449+
while (*(++name) == DASH) {};
450+
451+
size = strlen(name);
452+
453+
if (strncmp(current, name, size) != 0) {
454+
continue;
455+
}
456+
457+
ch = current[size];
458+
459+
if (!(ch == EQUAL || ch == ZERO)) {
460+
continue;
461+
}
462+
463+
if (value && ch == ZERO) {
464+
status = CLANG_SPECIFIC_REMOVE_NXT;
465+
}
466+
387467
goto end;
388468
}
389469

390-
status = 0;
470+
status = CLANG_SPECIFIC_REMOVE_NON;
391471

392472
end:;
393473

@@ -608,6 +688,7 @@ int main(int argc, char* argv[], char* envp[]) {
608688

609689
int address_sanitizer = 0;
610690
int stack_protector = 0;
691+
int version = 0;
611692
int verbose = 0;
612693
int wants_libcxx = 0;
613694
int wants_static_libcxx = 0;
@@ -757,6 +838,8 @@ int main(int argc, char* argv[], char* envp[]) {
757838
override_linker = 1;
758839
} else if (strncmp(cur, GCC_OPT_F_STACK_PROTECTOR, strlen(GCC_OPT_F_STACK_PROTECTOR)) == 0) {
759840
stack_protector = 1;
841+
} else if (strcmp(cur, GCC_OPT_VERSION) == 0) {
842+
version = 1;
760843
} else if (strcmp(cur, GCC_OPT_V) == 0) {
761844
verbose = 1;
762845
} else if (strcmp(cur, GCC_OPT_L_STDCXX) == 0) {
@@ -811,16 +894,18 @@ int main(int argc, char* argv[], char* envp[]) {
811894
}
812895
}
813896
} else if (strncmp(cur, CLANG_OPT_TARGET, strlen(CLANG_OPT_TARGET)) == 0 || strncmp(cur, CLANG_OPT_TARGET + 1, strlen(CLANG_OPT_TARGET + 1)) == 0) {
814-
cur += strlen(CLANG_OPT_TARGET);
897+
size = strlen(CLANG_OPT_TARGET);
815898

816899
/* Clang has two variants of this flag: one with double hyphens, and one with a single hyphen. */
817900
if (strncmp(cur, CLANG_OPT_TARGET + 1, strlen(CLANG_OPT_TARGET + 1)) == 0) {
818-
cur -= 1;
901+
size--;
819902
}
820903

904+
cur += size;
905+
821906
ch = *cur;
822907

823-
if (!(ch == EQUAL || ch == '\0')) {
908+
if (!(ch == EQUAL || ch == ZERO)) {
824909
goto next;
825910
}
826911

@@ -898,10 +983,20 @@ int main(int argc, char* argv[], char* envp[]) {
898983

899984
next:;
900985

901-
if (clang_specific_remove(prev, cur)) {
986+
status = clang_specific_remove(prev, cur);
987+
988+
if (status != CLANG_SPECIFIC_REMOVE_NON) {
989+
if (status == CLANG_SPECIFIC_REMOVE_NXT) {
990+
index++;
991+
}
992+
902993
if (prev != NULL && strcmp(prev, GCC_OPT_XLINKER) == 0) {
903994
prev = NULL;
904995
kargv[--kargc] = (char*) prev;
996+
997+
if (status == CLANG_SPECIFIC_REMOVE_NXT) {
998+
index++;
999+
}
9051000
}
9061001

9071002
continue;
@@ -1005,6 +1100,11 @@ int main(int argc, char* argv[], char* envp[]) {
10051100
}
10061101
}
10071102

1103+
if (version && known_clang(cc)) {
1104+
printf(CLANG_VERSION_TEMPLATE, DEFAULT_TARGET, parent_directory);
1105+
goto end;
1106+
}
1107+
10081108
wants_libcxx += (strcmp(cc, GPP) == 0 || strcmp(cc, CPP) == 0 || strcmp(cc, GM2) == 0 || strcmp(cc, CLANGPP) == 0);
10091109

10101110
if (wants_libcxx) {

0 commit comments

Comments
 (0)