60
60
import static com .oracle .graal .python .util .PythonUtils .toTruffleStringUncached ;
61
61
import static com .oracle .graal .python .util .PythonUtils .tsLiteral ;
62
62
63
+ import java .io .File ;
63
64
import java .io .IOException ;
64
65
import java .io .InputStreamReader ;
65
66
import java .io .PrintWriter ;
66
67
import java .nio .charset .StandardCharsets ;
68
+ import java .nio .file .Files ;
69
+ import java .nio .file .Path ;
70
+ import java .nio .file .Paths ;
71
+ import java .util .Arrays ;
67
72
import java .util .List ;
68
73
import java .util .logging .Level ;
69
74
128
133
import com .oracle .graal .python .runtime .sequence .storage .SequenceStorage ;
129
134
import com .oracle .graal .python .util .PythonUtils ;
130
135
import com .oracle .truffle .api .CallTarget ;
136
+ import com .oracle .truffle .api .CompilerAsserts ;
131
137
import com .oracle .truffle .api .CompilerDirectives ;
132
138
import com .oracle .truffle .api .CompilerDirectives .TruffleBoundary ;
133
139
import com .oracle .truffle .api .TruffleFile ;
@@ -630,6 +636,65 @@ protected Object getToolPath(TruffleString tool) {
630
636
}
631
637
}
632
638
639
+ @ Builtin (name = "determine_system_toolchain" , maxNumOfPositionalArgs = 1 )
640
+ @ GenerateNodeFactory
641
+ public abstract static class DetermineSystemToolchain extends PythonUnaryBuiltinNode {
642
+ /**
643
+ * This is derived from {@code distutils.unixccompiler._is_gcc}
644
+ */
645
+ private static final String [] C_COMPILER_PRECEDENCE = {"gcc" , "clang" };
646
+ private static final String [] CXX_COMPILER_PRECEDENCE = {"g++" , "clang++" };
647
+
648
+ private static final PKeyword [] GENERIC_TOOLCHAIN = {
649
+ new PKeyword (tsLiteral ("CC" ), tsLiteral ("cc" )),
650
+ new PKeyword (tsLiteral ("CXX" ), tsLiteral ("c++" )),
651
+ new PKeyword (tsLiteral ("AR" ), tsLiteral ("ar" )),
652
+ new PKeyword (tsLiteral ("RANLIB" ), tsLiteral ("ranlib" )),
653
+ new PKeyword (tsLiteral ("LD" ), tsLiteral ("ld" )),
654
+ new PKeyword (tsLiteral ("NM" ), tsLiteral ("nm" ))
655
+ };
656
+
657
+ @ Specialization
658
+ PDict doGeneric (@ SuppressWarnings ("unused" ) Object unused ) {
659
+ return factory ().createDict (fromToolchain ());
660
+ }
661
+
662
+ @ TruffleBoundary
663
+ private static PKeyword [] fromToolchain () {
664
+ PKeyword [] result = GENERIC_TOOLCHAIN ;
665
+ int id = which ();
666
+ if (id >= 0 ) {
667
+ assert id < C_COMPILER_PRECEDENCE .length ;
668
+ result = Arrays .copyOf (GENERIC_TOOLCHAIN , GENERIC_TOOLCHAIN .length );
669
+ result [0 ] = new PKeyword (tsLiteral ("CC" ), tsLiteral (C_COMPILER_PRECEDENCE [id ]));
670
+ result [1 ] = new PKeyword (tsLiteral ("CXX" ), tsLiteral (CXX_COMPILER_PRECEDENCE [id ]));
671
+ }
672
+ return result ;
673
+ }
674
+
675
+ private static int which () {
676
+ CompilerAsserts .neverPartOfCompilation ();
677
+ String path = System .getenv ("PATH" );
678
+ if (path != null ) {
679
+ for (int i = 0 ; i < C_COMPILER_PRECEDENCE .length ; i ++) {
680
+ int last = 0 ;
681
+ for (int j = path .indexOf (File .pathSeparatorChar ); j != -1 ; j = path .indexOf (File .pathSeparatorChar , last )) {
682
+ Path resolvedProgramName = Paths .get (path .substring (last , j )).resolve (C_COMPILER_PRECEDENCE [i ]);
683
+ if (Files .isExecutable (resolvedProgramName )) {
684
+ return i ;
685
+ }
686
+ /*
687
+ * next start is the char after the separator because we have "path0:path1"
688
+ * and 'i' points to ':'
689
+ */
690
+ last = j + 1 ;
691
+ }
692
+ }
693
+ }
694
+ return -1 ;
695
+ }
696
+ }
697
+
633
698
@ Builtin (name = "posix_module_backend" , minNumOfPositionalArgs = 0 )
634
699
@ GenerateNodeFactory
635
700
public abstract static class PosixModuleBackendNode extends PythonBuiltinNode {
@@ -650,7 +715,7 @@ static long doIt(@SuppressWarnings("unused") Object dummy) {
650
715
}
651
716
}
652
717
653
- // Internal builtin used for testing: changes strategy of newly allocated set or map
718
+ // Internal builtin used for testing: changes strategy of newly allocated set or map
654
719
@ Builtin (name = "set_storage_strategy" , minNumOfPositionalArgs = 2 )
655
720
@ GenerateNodeFactory
656
721
public abstract static class SetStorageStrategyNode extends PythonBinaryBuiltinNode {
0 commit comments