Rev 10 | Rev 12 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 10 | Rev 11 | ||
---|---|---|---|
Line 12... | Line 12... | ||
12 | // environment variables: |
12 | // environment variables: |
13 | // DEBUG_LINKER_DRIVER - when defined to any value (incl. empty string), print the constructed command line to stderr before calling the linker. |
13 | // DEBUG_LINKER_DRIVER - when defined to any value (incl. empty string), print the constructed command line to stderr before calling the linker. |
14 | 14 | ||
15 | #include <stdio.h> |
15 | #include <stdio.h> |
16 | #include <stdlib.h> |
16 | #include <stdlib.h> |
- | 17 | #include <stdint.h> |
|
17 | #include <stdarg.h> |
18 | #include <stdarg.h> |
18 | #include <stdbool.h> |
19 | #include <stdbool.h> |
19 | #include <string.h> |
20 | #include <string.h> |
20 | #include <fcntl.h> |
21 | #include <fcntl.h> |
21 | #ifndef _WIN32 |
22 | #ifndef _WIN32 |
Line 59... | Line 60... | ||
59 | 60 | ||
60 | 61 | ||
61 | #define ARGMODE_SINGLE 0 |
62 | #define ARGMODE_SINGLE 0 |
62 | #define ARGMODE_HASVAL 1 |
63 | #define ARGMODE_HASVAL 1 |
63 | #define ARGMODE_EQUALVAL 2 |
64 | #define ARGMODE_EQUALVAL 2 |
- | 65 | ||
- | 66 | ||
- | 67 | // handy macros that generate a version number in the format "YYYYMMDD" corresponding to the build date. Usage: printf ("version " VERSION_FMT_YYYYMMDD "\n", VERSION_ARG_YYYYMMDD); |
|
- | 68 | #ifndef VERSION_ARG_YYYYMMDD |
|
- | 69 | #define BUILDDATE_YEAR (&__DATE__[7]) // compiler will optimize this into a const string, e.g. "2021" |
|
- | 70 | #define BUILDDATE_MONTH ( \ |
|
- | 71 | *((uint32_t *) __DATE__) == *((uint32_t *) "Jan ") ? "01" : \ |
|
- | 72 | *((uint32_t *) __DATE__) == *((uint32_t *) "Feb ") ? "02" : \ |
|
- | 73 | *((uint32_t *) __DATE__) == *((uint32_t *) "Mar ") ? "03" : \ |
|
- | 74 | *((uint32_t *) __DATE__) == *((uint32_t *) "Apr ") ? "04" : \ |
|
- | 75 | *((uint32_t *) __DATE__) == *((uint32_t *) "May ") ? "05" : \ |
|
- | 76 | *((uint32_t *) __DATE__) == *((uint32_t *) "Jun ") ? "06" : \ |
|
- | 77 | *((uint32_t *) __DATE__) == *((uint32_t *) "Jul ") ? "07" : \ |
|
- | 78 | *((uint32_t *) __DATE__) == *((uint32_t *) "Aug ") ? "08" : \ |
|
- | 79 | *((uint32_t *) __DATE__) == *((uint32_t *) "Sep ") ? "09" : \ |
|
- | 80 | *((uint32_t *) __DATE__) == *((uint32_t *) "Oct ") ? "10" : \ |
|
- | 81 | *((uint32_t *) __DATE__) == *((uint32_t *) "Nov ") ? "11" : \ |
|
- | 82 | *((uint32_t *) __DATE__) == *((uint32_t *) "Dec ") ? "12" : \ |
|
- | 83 | "XX" \ |
|
- | 84 | ) // compiler will optimize this into a const string, e.g. "11" |
|
- | 85 | #define BUILDDATE_DAY ( \ |
|
- | 86 | *((uint32_t *) &__DATE__[3]) == *((uint32_t *) " 1 ") ? "01" : \ |
|
- | 87 | *((uint32_t *) &__DATE__[3]) == *((uint32_t *) " 2 ") ? "02" : \ |
|
- | 88 | *((uint32_t *) &__DATE__[3]) == *((uint32_t *) " 3 ") ? "03" : \ |
|
- | 89 | *((uint32_t *) &__DATE__[3]) == *((uint32_t *) " 4 ") ? "04" : \ |
|
- | 90 | *((uint32_t *) &__DATE__[3]) == *((uint32_t *) " 5 ") ? "05" : \ |
|
- | 91 | *((uint32_t *) &__DATE__[3]) == *((uint32_t *) " 6 ") ? "06" : \ |
|
- | 92 | *((uint32_t *) &__DATE__[3]) == *((uint32_t *) " 7 ") ? "07" : \ |
|
- | 93 | *((uint32_t *) &__DATE__[3]) == *((uint32_t *) " 8 ") ? "08" : \ |
|
- | 94 | *((uint32_t *) &__DATE__[3]) == *((uint32_t *) " 9 ") ? "09" : \ |
|
- | 95 | *((uint32_t *) &__DATE__[3]) == *((uint32_t *) " 10 ") ? "10" : \ |
|
- | 96 | *((uint32_t *) &__DATE__[3]) == *((uint32_t *) " 11 ") ? "11" : \ |
|
- | 97 | *((uint32_t *) &__DATE__[3]) == *((uint32_t *) " 12 ") ? "12" : \ |
|
- | 98 | *((uint32_t *) &__DATE__[3]) == *((uint32_t *) " 13 ") ? "13" : \ |
|
- | 99 | *((uint32_t *) &__DATE__[3]) == *((uint32_t *) " 14 ") ? "14" : \ |
|
- | 100 | *((uint32_t *) &__DATE__[3]) == *((uint32_t *) " 15 ") ? "15" : \ |
|
- | 101 | *((uint32_t *) &__DATE__[3]) == *((uint32_t *) " 16 ") ? "16" : \ |
|
- | 102 | *((uint32_t *) &__DATE__[3]) == *((uint32_t *) " 17 ") ? "17" : \ |
|
- | 103 | *((uint32_t *) &__DATE__[3]) == *((uint32_t *) " 18 ") ? "18" : \ |
|
- | 104 | *((uint32_t *) &__DATE__[3]) == *((uint32_t *) " 19 ") ? "19" : \ |
|
- | 105 | *((uint32_t *) &__DATE__[3]) == *((uint32_t *) " 20 ") ? "20" : \ |
|
- | 106 | *((uint32_t *) &__DATE__[3]) == *((uint32_t *) " 21 ") ? "21" : \ |
|
- | 107 | *((uint32_t *) &__DATE__[3]) == *((uint32_t *) " 22 ") ? "22" : \ |
|
- | 108 | *((uint32_t *) &__DATE__[3]) == *((uint32_t *) " 23 ") ? "23" : \ |
|
- | 109 | *((uint32_t *) &__DATE__[3]) == *((uint32_t *) " 24 ") ? "24" : \ |
|
- | 110 | *((uint32_t *) &__DATE__[3]) == *((uint32_t *) " 25 ") ? "25" : \ |
|
- | 111 | *((uint32_t *) &__DATE__[3]) == *((uint32_t *) " 26 ") ? "26" : \ |
|
- | 112 | *((uint32_t *) &__DATE__[3]) == *((uint32_t *) " 27 ") ? "27" : \ |
|
- | 113 | *((uint32_t *) &__DATE__[3]) == *((uint32_t *) " 28 ") ? "28" : \ |
|
- | 114 | *((uint32_t *) &__DATE__[3]) == *((uint32_t *) " 29 ") ? "29" : \ |
|
- | 115 | *((uint32_t *) &__DATE__[3]) == *((uint32_t *) " 30 ") ? "30" : \ |
|
- | 116 | *((uint32_t *) &__DATE__[3]) == *((uint32_t *) " 31 ") ? "31" : \ |
|
- | 117 | "XX" \ |
|
- | 118 | ) // compiler will optimize this into a const string, e.g. "14" |
|
- | 119 | #define VERSION_FMT_YYYYMMDD "%s%s%s" |
|
- | 120 | #define VERSION_ARG_YYYYMMDD BUILDDATE_YEAR, BUILDDATE_MONTH, BUILDDATE_DAY |
|
- | 121 | #endif // !VERSION_ARG_YYYYMMDD |
|
64 | 122 | ||
65 | 123 | ||
66 | char *array_contains (int argc, char **argv, char *needle, int mode) |
124 | char *array_contains (int argc, char **argv, char *needle, int mode) |
67 | { |
125 | { |
68 | char *arg; |
126 | char *arg; |
Line 73... | Line 131... | ||
73 | arg = argv[arg_index]; |
131 | arg = argv[arg_index]; |
74 | if (mode == ARGMODE_SINGLE) |
132 | if (mode == ARGMODE_SINGLE) |
75 | { |
133 | { |
76 | if (strcmp (arg, needle) == 0) |
134 | if (strcmp (arg, needle) == 0) |
77 | return (""); |
135 | return (""); |
78 | } |
136 | } |
79 | else if (mode == ARGMODE_HASVAL) |
137 | else if (mode == ARGMODE_HASVAL) |
80 | { |
138 | { |
81 | if ((arg_index + 1 < argc) && (strcmp (arg, needle) == 0)) |
139 | if ((arg_index + 1 < argc) && (strcmp (arg, needle) == 0)) |
82 | return (argv[arg_index + 1]); |
140 | return (argv[arg_index + 1]); |
83 | else if ((strncmp (arg, needle, needle_len) == 0) && (arg[needle_len] != 0)) |
141 | else if ((strncmp (arg, needle, needle_len) == 0) && (arg[needle_len] != 0)) |
Line 107... | Line 165... | ||
107 | asprintf (&new_str, "%s%s%s", out_str, (varval != NULL ? varval : ""), varstop + 1); |
165 | asprintf (&new_str, "%s%s%s", out_str, (varval != NULL ? varval : ""), varstop + 1); |
108 | free (out_str); |
166 | free (out_str); |
109 | out_str = new_str; |
167 | out_str = new_str; |
110 | } |
168 | } |
111 | return (out_str); |
169 | return (out_str); |
112 | } |
170 | } |
113 | 171 | ||
114 | 172 | ||
115 | char *makefmtstr (const char *fmt, ...) |
173 | char *makefmtstr (const char *fmt, ...) |
116 | { |
174 | { |
117 | va_list ap; |
175 | va_list ap; |
118 | char *outstr = NULL; |
176 | char *outstr = NULL; |
119 | va_start (ap, fmt); |
177 | va_start (ap, fmt); |
Line 158... | Line 216... | ||
158 | bool was_cpluspluslib_included = false; |
216 | bool was_cpluspluslib_included = false; |
159 | bool requires_libcplusplus = false; |
217 | bool requires_libcplusplus = false; |
160 | int arg_index; |
218 | int arg_index; |
161 | char *arg; |
219 | char *arg; |
162 | FILE *fp; |
220 | FILE *fp; |
- | 221 | ||
- | 222 | // special case: print the driver version and exit |
|
- | 223 | if ((argc == 2) && (strcmp (argv[1], "--driver-version") == 0)) |
|
- | 224 | { |
|
- | 225 | printf ("clang 'gcc' linker driver for QNX 8.0 version " VERSION_FMT_YYYYMMDD " by Pierre-Marie Baty <pm@pmbaty.com>\n", VERSION_ARG_YYYYMMDD); |
|
- | 226 | return (0); |
|
- | 227 | } |
|
163 | 228 | ||
164 | // if *any* of these flags are present, it means we don't want to link anything, so direct everything to the compiler |
229 | // if *any* of these flags are present, it means we don't want to link anything, so direct everything to the compiler |
165 | if ( ARGV_CONTAINS_SINGLEARG ("-fsyntax-only") |
230 | if ( ARGV_CONTAINS_SINGLEARG ("-fsyntax-only") |
166 | || ARGV_CONTAINS_SINGLEARG ("-c") |
231 | || ARGV_CONTAINS_SINGLEARG ("-c") |
167 | || ARGV_CONTAINS_SINGLEARG ("-M") |
232 | || ARGV_CONTAINS_SINGLEARG ("-M") |