Skip to content

Commit 416136a

Browse files
committed
[GR-45300] Prefer gcc and clang when using system toolchain.
PullRequest: graalpython/2728
2 parents fdce870 + 4d4c637 commit 416136a

File tree

2 files changed

+64
-12
lines changed

2 files changed

+64
-12
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/GraalPythonModuleBuiltins.java

Lines changed: 63 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -60,15 +60,18 @@
6060
import static com.oracle.graal.python.util.PythonUtils.toTruffleStringUncached;
6161
import static com.oracle.graal.python.util.PythonUtils.tsLiteral;
6262

63+
import java.io.File;
6364
import java.io.IOException;
6465
import java.io.InputStreamReader;
6566
import java.io.PrintWriter;
6667
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;
6772
import java.util.List;
6873
import java.util.logging.Level;
6974

70-
import com.oracle.truffle.api.dsl.Bind;
71-
import com.oracle.truffle.api.nodes.Node;
7275
import org.graalvm.nativeimage.ImageInfo;
7376

7477
import com.oracle.graal.python.PythonLanguage;
@@ -105,7 +108,6 @@
105108
import com.oracle.graal.python.builtins.objects.type.TypeNodes.CreateTypeNode;
106109
import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs;
107110
import com.oracle.graal.python.lib.PyObjectGetItem;
108-
import com.oracle.graal.python.lib.PyObjectTypeCheck;
109111
import com.oracle.graal.python.nodes.ErrorMessages;
110112
import com.oracle.graal.python.nodes.builtins.FunctionNodes.GetCallTargetNode;
111113
import com.oracle.graal.python.nodes.bytecode.PBytecodeRootNode;
@@ -131,11 +133,13 @@
131133
import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage;
132134
import com.oracle.graal.python.util.PythonUtils;
133135
import com.oracle.truffle.api.CallTarget;
136+
import com.oracle.truffle.api.CompilerAsserts;
134137
import com.oracle.truffle.api.CompilerDirectives;
135138
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
136139
import com.oracle.truffle.api.TruffleFile;
137140
import com.oracle.truffle.api.TruffleLanguage.Env;
138141
import com.oracle.truffle.api.TruffleLogger;
142+
import com.oracle.truffle.api.dsl.Bind;
139143
import com.oracle.truffle.api.dsl.Cached;
140144
import com.oracle.truffle.api.dsl.Cached.Shared;
141145
import com.oracle.truffle.api.dsl.Fallback;
@@ -150,6 +154,7 @@
150154
import com.oracle.truffle.api.interop.UnsupportedMessageException;
151155
import com.oracle.truffle.api.library.CachedLibrary;
152156
import com.oracle.truffle.api.nodes.LanguageInfo;
157+
import com.oracle.truffle.api.nodes.Node;
153158
import com.oracle.truffle.api.nodes.NodeUtil;
154159
import com.oracle.truffle.api.nodes.RootNode;
155160
import com.oracle.truffle.api.source.Source;
@@ -631,14 +636,62 @@ protected Object getToolPath(TruffleString tool) {
631636
}
632637
}
633638

634-
// Equivalent of PyObject_TypeCheck
635-
@Builtin(name = "type_check", minNumOfPositionalArgs = 2)
639+
@Builtin(name = "determine_system_toolchain", maxNumOfPositionalArgs = 1)
636640
@GenerateNodeFactory
637-
public abstract static class TypeCheckNode extends PythonBinaryBuiltinNode {
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+
638657
@Specialization
639-
boolean typeCheck(Object instance, Object cls,
640-
@Cached PyObjectTypeCheck typeCheckNode) {
641-
return typeCheckNode.execute(instance, cls);
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;
642695
}
643696
}
644697

@@ -662,7 +715,7 @@ static long doIt(@SuppressWarnings("unused") Object dummy) {
662715
}
663716
}
664717

665-
// 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
666719
@Builtin(name = "set_storage_strategy", minNumOfPositionalArgs = 2)
667720
@GenerateNodeFactory
668721
public abstract static class SetStorageStrategyNode extends PythonBinaryBuiltinNode {

graalpython/lib-graalpython/_sysconfig.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,7 @@ def _get_posix_vars():
5656

5757
use_system_toolchain = __graalpython__.use_system_toolchain
5858
if use_system_toolchain:
59-
def get_toolchain(name):
60-
return dict(CC='cc',CXX='c++',AR='ar',RANLIB='ranlib',LD='ld',NM='nm')[name]
59+
get_toolchain = __graalpython__.determine_system_toolchain().get
6160
else:
6261
get_toolchain = __graalpython__.get_toolchain_tool_path
6362

0 commit comments

Comments
 (0)