@@ -208,7 +208,8 @@ class BackendX86_64 : CompilerBackend {
208208 break ;
209209 }
210210 case " osx" : {
211- ret ~= [" OSX" , " IO" , " File" , " Args" , " Exit" ];
211+ ret ~= [" OSX" , " IO" , " Exit" , " Time" , " File" , " Args" ];
212+ if (useLibc) ret ~= " Heap" ;
212213 break ;
213214 }
214215 default : break ;
@@ -255,29 +256,35 @@ class BackendX86_64 : CompilerBackend {
255256 linkCommand ~= format(" -l%s" , lib);
256257 }
257258
258- if (! link.empty()) {
259+ if (! link.empty() && os == " linux " ) {
259260 // idk if this is correct on all linux systems but whatever
260261 linkCommand ~= " -dynamic-linker /lib64/ld-linux-x86-64.so.2" ;
261262 }
262263
263264 if (useLibc) {
264- string [] possiblePaths = [
265- " /usr/lib/crt1.o" ,
266- " /usr/lib/x86_64-linux-gnu/crt1.o"
267- ];
268- bool crt1;
269-
270- foreach (ref path ; possiblePaths) {
271- if (exists(path)) {
272- crt1 = true ;
273- linkCommand ~= format(" %s" , path);
274- linkCommand ~= format(" %s/crti.o" , path.dirName());
275- linkCommand ~= format(" %s/crtn.o" , path.dirName());
265+ if (os == " linux" ) {
266+ string [] possiblePaths = [
267+ " /usr/lib/crt1.o" ,
268+ " /usr/lib/x86_64-linux-gnu/crt1.o"
269+ ];
270+ bool crt1;
271+
272+ foreach (ref path ; possiblePaths) {
273+ if (exists(path)) {
274+ crt1 = true ;
275+ linkCommand ~= format(" %s" , path);
276+ linkCommand ~= format(" %s/crti.o" , path.dirName());
277+ linkCommand ~= format(" %s/crtn.o" , path.dirName());
278+ }
276279 }
277- }
278280
279- if (! crt1) {
280- stderr.writeln(" WARNING: Failed to find crt1.o, program may behave incorrectly" );
281+ if (! crt1) {
282+ stderr.writeln(" WARNING: Failed to find crt1.o, program may behave incorrectly" );
283+ }
284+ } else if (os == " osx" ) {
285+ linkCommand ~= " -syslibroot `xcrun --sdk macosx --show-sdk-path`" ;
286+ } else {
287+ WarnNoInfo(" Cannot use libc on operating system '%s'" , os);
281288 }
282289 }
283290
@@ -331,7 +338,7 @@ class BackendX86_64 : CompilerBackend {
331338 }
332339 }
333340 else if (word.type == WordType.Raw) {
334- output ~= format(" call %s\n " , name);
341+ output ~= format(" call %s\n " , ExternSymbol( name) );
335342 }
336343 else if (word.type == WordType.C) {
337344 assert (0 ); // TODO: error
@@ -347,15 +354,19 @@ class BackendX86_64 : CompilerBackend {
347354 ErrorNoInfo(" Backend doesn't support operating system '%s'" , os);
348355 }
349356
350- if (useLibc) output ~= " global main\n " ;
351- else if (os == " osx" ) output ~= " default rel\n global _main\n " ;
352- else output ~= " global _start\n " ;
353-
354357 output ~= " section .text\n " ;
355-
356- if (useLibc) output ~= " main:\n " ;
357- else if (os == " osx" ) output ~= " _main:\n " ;
358- else output ~= " _start:\n " ;
358+
359+ if (os == " osx" ) {
360+ output ~= " default rel\n " ;
361+ output ~= " global _main\n " ;
362+ output ~= " _main:\n " ;
363+ } else if (useLibc) {
364+ output ~= " global main\n " ;
365+ output ~= " main:\n " ;
366+ } else {
367+ output ~= " global _start\n " ;
368+ output ~= " _start:\n " ;
369+ }
359370
360371 output ~= " call __init\n " ;
361372
@@ -486,7 +497,7 @@ class BackendX86_64 : CompilerBackend {
486497 }
487498 else {
488499 if (word.type == WordType.Raw) {
489- output ~= format(" call %s\n " , node.name);
500+ output ~= format(" call %s\n " , ExternSymbol( node.name) );
490501 }
491502 else if (word.type == WordType.C) {
492503 if (word.params.length >= 1 ) {
@@ -523,7 +534,7 @@ class BackendX86_64 : CompilerBackend {
523534
524535 // TODO: support more than 6 parameters
525536
526- output ~= format(" call %s\n " , word.symbolName);
537+ output ~= format(" call %s\n " , ExternSymbol( word.symbolName) );
527538
528539 if (! word.isVoid) {
529540 output ~= " mov [r15], rax\n " ;
@@ -1157,7 +1168,7 @@ class BackendX86_64 : CompilerBackend {
11571168 }
11581169
11591170 if (word.type != WordType.Callisto) {
1160- output ~= format(" extern %s\n " , node.func);
1171+ output ~= format(" extern %s\n " , ExternSymbol( node.func) );
11611172 }
11621173
11631174 words[funcName] = word;
@@ -1173,7 +1184,7 @@ class BackendX86_64 : CompilerBackend {
11731184 if (node.func in words) {
11741185 auto word = words[node.func];
11751186 string symbol = word.type == WordType.Callisto?
1176- format(" __func__%s" , node.func.Sanitise()) : node.func;
1187+ format(" __func__%s" , node.func.Sanitise()) : ExternSymbol( node.func) ;
11771188
11781189 output ~= format(" mov rax, %s\n " , symbol);
11791190 output ~= " mov [r15], rax\n " ;
@@ -1312,4 +1323,12 @@ class BackendX86_64 : CompilerBackend {
13121323 Error(node.error, " Variable '%s' doesn't exist" , node.var);
13131324 }
13141325 }
1326+
1327+ private string ExternSymbol (string name) {
1328+ if (os == " osx" ) {
1329+ return " _" ~ name;
1330+ } else {
1331+ return name;
1332+ }
1333+ }
13151334}
0 commit comments