Skip to content

Commit 1b2e40a

Browse files
committed
Compiler: improve target architecture handling
* simplify target triplet parsing and unparsing * add --target command line option for testing
1 parent fbbd94c commit 1b2e40a

File tree

3 files changed

+31
-41
lines changed

3 files changed

+31
-41
lines changed

common/target_info.c2

Lines changed: 13 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ module target_info;
1818
import console;
1919

2020
import c_errno local;
21-
import stdio;
21+
import stdio local;
2222
import stdlib local;
2323
import string local;
2424
import sys_utsname;
@@ -142,45 +142,27 @@ fn void Info.init(Info* info) {
142142
break;
143143
}
144144

145-
stdio.sprintf(info.triple, "%s-%s-%s-%s",
146-
arch_names[info.arch],
147-
vendor_names[info.vendor],
148-
system_names[info.sys],
149-
abi_names[info.abi]);
145+
snprintf(info.triple, elemsof(info.triple), "%s-%s-%s-%s",
146+
arch_names[info.arch],
147+
vendor_names[info.vendor],
148+
system_names[info.sys],
149+
abi_names[info.abi]);
150150
}
151151

152152
public fn bool Info.fromString(Info* info, const char* triple) {
153153
// expect format: <arch><sub>-<vendor>-<sys>-<abi>
154154
// TODO support sub for ARM
155-
// Note: very ugly way to split string
156155
char[32] arch_str;
157156
char[32] vendor_str;
158157
char[32] sys_str;
159158
char[32] abi_str;
160-
char*[4] matches = { arch_str, vendor_str, sys_str, abi_str };
161-
162-
i32 match = 0;
163-
const char* start = triple;
164-
const char* cp = start;
165-
while (*cp) {
166-
if (*cp == '-') {
167-
u32 len = cast<u32>(cp - start);
168-
strncpy(matches[match], start, len);
169-
matches[match][len] = 0;
170-
start = cp + 1;
171-
match++;
172-
if (match == 5) return false;
173-
}
174-
cp++;
175-
}
176-
if (cp != start) {
177-
u32 len = cast<u32>(cp - start);
178-
// TODO check len
179-
strncpy(matches[match], start, len);
180-
matches[match][len] = 0;
181-
match++;
182-
}
183-
if (match != 4) return false;
159+
u32 pos = 0;
160+
161+
// split the triple string into 4 components
162+
if (sscanf(triple, "%31[^-]-%31[^-]-%31[^-]-%31[^-]%n",
163+
arch_str, vendor_str, sys_str, abi_str, &pos) != 4
164+
|| triple[pos] != '\0')
165+
return false;
184166

185167
info.arch = str2arch(arch_str);
186168
if (info.arch == Arch.Unknown) {
@@ -203,7 +185,6 @@ public fn bool Info.fromString(Info* info, const char* triple) {
203185

204186
public fn const char* Info.str(const Info* info) {
205187
return info.triple;
206-
207188
}
208189

209190
public fn const char* Info.getSystemName(const Info* info) {

compiler/compiler.c2

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ public type Options struct {
8181
bool msan;
8282
bool ubsan;
8383
u32 libdir; // from environment varible C2_LIBDIR, into auxPool
84+
char *target_triple;
8485
}
8586

8687
public fn void build(string_pool.Pool* auxPool,
@@ -244,6 +245,8 @@ fn void Compiler.build(Compiler* c,
244245
c.is_image = target.getKind() == build_target.Kind.Image;
245246
c.libdirs.init(c.auxPool);
246247

248+
const char* target_str = opts.target_triple;
249+
247250
const char* output_base = constants.output_dir;
248251
if (c.build_info) {
249252
const char* output_dir2 = c.build_info.getOutputDir();
@@ -261,15 +264,7 @@ fn void Compiler.build(Compiler* c,
261264
for (u32 i=0; i<dirs.length(); i++) {
262265
c.libdirs.add(dirs.get_idx(i));
263266
}
264-
const char* target_str = c.build_info.getTarget();
265-
if (target_str) {
266-
if (!c.targetInfo.fromString(target_str)) {
267-
console.error("invalid target triple: %s", target_str);
268-
stdlib.exit(-1);
269-
}
270-
} else {
271-
c.targetInfo.getNative();
272-
}
267+
target_str = c.build_info.getTarget();
273268
} else {
274269
if (c.is_image) {
275270
// TODO src loc
@@ -279,6 +274,14 @@ fn void Compiler.build(Compiler* c,
279274
if (c.opts.libdir) c.libdirs.add(c.opts.libdir);
280275
c.targetInfo.getNative();
281276
}
277+
if (target_str) {
278+
if (!c.targetInfo.fromString(target_str)) {
279+
console.error("invalid target triple: %s", target_str);
280+
stdlib.exit(-1);
281+
}
282+
} else {
283+
c.targetInfo.getNative();
284+
}
282285
console.debug("triple: %s", c.targetInfo.str());
283286

284287
c.addGlobalDefine("SYSTEM", c.targetInfo.getSystemName());

compiler/main.c2

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ const char[] Usage_help =
198198
" --noplugins do not use plugins\n"
199199
" --showlibs print available libraries\n"
200200
" --showplugins print available plugins\n"
201+
" --target triple cross compile for a specified architecture\n"
201202
" --targets show available targets in recipe\n"
202203
" --test test mode (do not check for main() function)\n"
203204
" --trace-calls generate code that traces function calls\n"
@@ -242,6 +243,11 @@ fn i32 parse_long_opt(i32 i, i32 argc, char** argv, compiler.Options* comp_opts,
242243
case "showplugins":
243244
opts.show_plugins = true;
244245
break;
246+
case "target":
247+
if (i==argc-1) missing_arg(arg);
248+
i++;
249+
comp_opts.target_triple = argv[i];
250+
break;
245251
case "targets":
246252
opts.show_targets = true;
247253
break;

0 commit comments

Comments
 (0)