Skip to content

Commit 41bfd73

Browse files
committed
Add more Clang compatibility workarounds
1 parent e8833bf commit 41bfd73

2 files changed

Lines changed: 121 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: 115 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,16 @@ 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";
120125

121126
static const char LD_OPT_DYNAMIC_LINKER[] = "-dynamic-linker";
122127
static const char LD_OPT_RPATH_LINK[] = "-rpath-link";
@@ -188,7 +193,9 @@ static const char VENDOR_UNKNOWN[] = "-unknown-";
188193

189194
static const char LD_PREFIX[] = "ld.";
190195

196+
static const char DASH = '-';
191197
static const char EQUAL = '=';
198+
static const char ZERO = '\0';
192199
static const char EQUAL_S[] = "=";
193200

194201
static const char* const FASTER_LINKERS[] = {
@@ -197,6 +204,51 @@ static const char* const FASTER_LINKERS[] = {
197204
"gold"
198205
};
199206

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

361-
int status = 1;
413+
int status = CLANG_SPECIFIC_REMOVE_CUR;
414+
size_t index = 0;
415+
416+
size_t size = 0;
362417

363418
const char* previous = prev;
364419
const char* current = cur;
365420

366-
if (strncmp(current, GCC_OPT_WL, strlen(GCC_OPT_WL)) == 0) {
367-
current += strlen(GCC_OPT_WL);
368-
}
421+
const char* name = cur;
422+
int value = 0;
423+
const clang_option_t* option = NULL;
369424

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

374-
if (strcmp(current, CLANG_OPT_W_NO_UNUSED_COMMAND_LINE_ARGUMENT) == 0) {
375-
goto end;
427+
if (strncmp(current, GCC_OPT_WL, strlen(GCC_OPT_WL)) == 0) {
428+
current += strlen(GCC_OPT_WL);
376429
}
377430

378-
if (strcmp(current, CLANG_OPT_W_NO_INVALID_COMMAND_LINE_ARGUMENT) == 0) {
431+
if (*current != DASH || *current == ZERO) {
432+
status = CLANG_SPECIFIC_REMOVE_NON;
379433
goto end;
380434
}
381435

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

386-
if (strcmp(current, CLANG_OPT_F_NO_LIMIT_DEBUG_INFO) == 0) {
438+
for (index = 0; index < sizeof(CLANG_SPECIFIC_REMOVE) / sizeof(*CLANG_SPECIFIC_REMOVE); index++) {
439+
option = &CLANG_SPECIFIC_REMOVE[index];
440+
441+
name = option->name;
442+
value = option->value;
443+
444+
while (*(++name) == DASH) {};
445+
446+
size = strlen(name);
447+
448+
if (strncmp(current, name, size) != 0) {
449+
continue;
450+
}
451+
452+
ch = current[size];
453+
454+
if (!(ch == EQUAL || ch == ZERO)) {
455+
continue;
456+
}
457+
458+
if (value && ch == ZERO) {
459+
status = CLANG_SPECIFIC_REMOVE_NXT;
460+
}
461+
387462
goto end;
388463
}
389464

390-
status = 0;
465+
status = CLANG_SPECIFIC_REMOVE_NON;
391466

392467
end:;
393468

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

609684
int address_sanitizer = 0;
610685
int stack_protector = 0;
686+
int version = 0;
611687
int verbose = 0;
612688
int wants_libcxx = 0;
613689
int wants_static_libcxx = 0;
@@ -757,6 +833,8 @@ int main(int argc, char* argv[], char* envp[]) {
757833
override_linker = 1;
758834
} else if (strncmp(cur, GCC_OPT_F_STACK_PROTECTOR, strlen(GCC_OPT_F_STACK_PROTECTOR)) == 0) {
759835
stack_protector = 1;
836+
} else if (strcmp(cur, GCC_OPT_VERSION) == 0) {
837+
version = 1;
760838
} else if (strcmp(cur, GCC_OPT_V) == 0) {
761839
verbose = 1;
762840
} else if (strcmp(cur, GCC_OPT_L_STDCXX) == 0) {
@@ -811,16 +889,18 @@ int main(int argc, char* argv[], char* envp[]) {
811889
}
812890
}
813891
} 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);
892+
size = strlen(CLANG_OPT_TARGET);
815893

816894
/* Clang has two variants of this flag: one with double hyphens, and one with a single hyphen. */
817895
if (strncmp(cur, CLANG_OPT_TARGET + 1, strlen(CLANG_OPT_TARGET + 1)) == 0) {
818-
cur -= 1;
896+
size--;
819897
}
820898

899+
cur += size;
900+
821901
ch = *cur;
822902

823-
if (!(ch == EQUAL || ch == '\0')) {
903+
if (!(ch == EQUAL || ch == ZERO)) {
824904
goto next;
825905
}
826906

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

899979
next:;
900980

901-
if (clang_specific_remove(prev, cur)) {
981+
status = clang_specific_remove(prev, cur);
982+
983+
if (status != CLANG_SPECIFIC_REMOVE_NON) {
984+
if (status == CLANG_SPECIFIC_REMOVE_NXT) {
985+
index++;
986+
}
987+
902988
if (prev != NULL && strcmp(prev, GCC_OPT_XLINKER) == 0) {
903989
prev = NULL;
904990
kargv[--kargc] = (char*) prev;
991+
992+
if (status == CLANG_SPECIFIC_REMOVE_NXT) {
993+
index++;
994+
}
905995
}
906996

907997
continue;
@@ -1005,6 +1095,11 @@ int main(int argc, char* argv[], char* envp[]) {
10051095
}
10061096
}
10071097

1098+
if (version && known_clang(cc)) {
1099+
printf(CLANG_VERSION_TEMPLATE, DEFAULT_TARGET, parent_directory);
1100+
goto end;
1101+
}
1102+
10081103
wants_libcxx += (strcmp(cc, GPP) == 0 || strcmp(cc, CPP) == 0 || strcmp(cc, GM2) == 0 || strcmp(cc, CLANGPP) == 0);
10091104

10101105
if (wants_libcxx) {

0 commit comments

Comments
 (0)