Skip to content

Commit 325c7de

Browse files
committed
[GR-12550] Futher progress on running numpy setup
PullRequest: graalpython/299
2 parents d66c174 + 7637079 commit 325c7de

File tree

32 files changed

+1132
-335
lines changed

32 files changed

+1132
-335
lines changed
Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
/*
2+
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* The Universal Permissive License (UPL), Version 1.0
6+
*
7+
* Subject to the condition set forth below, permission is hereby granted to any
8+
* person obtaining a copy of this software, associated documentation and/or
9+
* data (collectively the "Software"), free of charge and under any and all
10+
* copyright rights in the Software, and any and all patent rights owned or
11+
* freely licensable by each licensor hereunder covering either (i) the
12+
* unmodified Software as contributed to or provided by such licensor, or (ii)
13+
* the Larger Works (as defined below), to deal in both
14+
*
15+
* (a) the Software, and
16+
*
17+
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
18+
* one is included with the Software each a "Larger Work" to which the Software
19+
* is contributed by such licensors),
20+
*
21+
* without restriction, including without limitation the rights to copy, create
22+
* derivative works of, display, perform, and distribute the Software and make,
23+
* use, sell, offer for sale, import, export, have made, and have sold the
24+
* Software and the Larger Work(s), and to sublicense the foregoing rights on
25+
* either these or other terms.
26+
*
27+
* This license is subject to the following condition:
28+
*
29+
* The above copyright notice and either this complete permission notice or at a
30+
* minimum a reference to the UPL must be included in all copies or substantial
31+
* portions of the Software.
32+
*
33+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39+
* SOFTWARE.
40+
*/
41+
package com.oracle.graal.python.shell;
42+
43+
import java.io.IOException;
44+
import java.nio.file.Files;
45+
import java.nio.file.Path;
46+
import java.nio.file.Paths;
47+
import java.nio.file.StandardCopyOption;
48+
import java.nio.file.attribute.PosixFilePermission;
49+
import java.util.ArrayList;
50+
import java.util.Arrays;
51+
import java.util.HashSet;
52+
import java.util.List;
53+
54+
public class GraalPythonCC extends GraalPythonCompiler {
55+
private String outputFilename;
56+
private boolean linkExecutable;
57+
private boolean link;
58+
private Boolean compile;
59+
private List<String> clangArgs;
60+
private List<String> fileInputs;
61+
62+
GraalPythonCC() {
63+
}
64+
65+
private static List<String> clangPrefix = Arrays.asList(new String[]{
66+
"clang",
67+
"-emit-llvm",
68+
"-fPIC",
69+
"-Wno-int-to-void-pointer-cast",
70+
"-Wno-int-conversion",
71+
"-Wno-incompatible-pointer-types-discards-qualifiers",
72+
"-ggdb",
73+
"-O1",
74+
});
75+
private static List<String> optPrefix = Arrays.asList(new String[]{
76+
"opt",
77+
"-mem2reg",
78+
"-globalopt",
79+
"-simplifycfg",
80+
"-constprop",
81+
"-always-inline",
82+
"-instcombine",
83+
"-dse",
84+
"-loop-simplify",
85+
"-reassociate",
86+
"-licm",
87+
"-gvn",
88+
"-o",
89+
});
90+
91+
static void main(String[] args) {
92+
new GraalPythonCC().run(args);
93+
}
94+
95+
private void run(String[] args) {
96+
parseOptions(args);
97+
launchCC();
98+
}
99+
100+
private void parseOptions(String[] args) {
101+
outputFilename = A_OUT;
102+
linkExecutable = true;
103+
link = true;
104+
verbose = false;
105+
compile = null;
106+
clangArgs = new ArrayList<>(clangPrefix);
107+
fileInputs = new ArrayList<>();
108+
for (int i = 0; i < args.length; i++) {
109+
String arg = args[i];
110+
switch (arg) {
111+
case "-o":
112+
clangArgs.add(arg);
113+
i++;
114+
if (i >= args.length) {
115+
throw new RuntimeException("-o needs an argument");
116+
}
117+
outputFilename = arg = args[i];
118+
break;
119+
case "-shared":
120+
linkExecutable = false;
121+
break;
122+
case "-c":
123+
link = false;
124+
linkExecutable = false;
125+
break;
126+
case "-v":
127+
if (!verbose) {
128+
verbose = true;
129+
continue; // the first verbose is not passed on to clang
130+
}
131+
break;
132+
default:
133+
if (arg.endsWith(".o") || arg.endsWith(".bc")) {
134+
if (compile == null) {
135+
compile = false;
136+
} else if (compile != false) {
137+
throw new RuntimeException("cannot mix source and compiled sources");
138+
}
139+
fileInputs.add(arg);
140+
} else if (arg.endsWith(".c") || arg.endsWith(".cpp") || arg.endsWith(".cxx")) {
141+
if (compile == null) {
142+
compile = true;
143+
} else if (compile != true) {
144+
throw new RuntimeException("cannot mix source and compiled sources");
145+
}
146+
fileInputs.add(arg);
147+
}
148+
}
149+
clangArgs.add(arg);
150+
}
151+
String targetFlags = System.getenv("LLVM_TARGET_FLAGS");
152+
if (targetFlags != null) {
153+
clangArgs.addAll(Arrays.asList(targetFlags.split(" ")));
154+
}
155+
}
156+
157+
private void launchCC() {
158+
// run the clang compiler to generate bc files
159+
try {
160+
Files.delete(Paths.get(outputFilename));
161+
} catch (IOException e) {
162+
// no matter;
163+
}
164+
165+
if (compile) {
166+
exec(clangArgs);
167+
logV("opt: ", fileInputs);
168+
if (!Files.exists(Paths.get(outputFilename))) {
169+
// if no explicit output filename was given or produced, we search the commandline
170+
// for files for which now have a bc file and optimize those. This happens when you
171+
// pass multiple .c files to clang and ask it to emit llvm bitcode
172+
for (String f : fileInputs) {
173+
String bcFile = bcFileFromFilename(f);
174+
assert Files.exists(Paths.get(bcFile));
175+
optFile(bcFile);
176+
}
177+
} else {
178+
optFile(outputFilename);
179+
}
180+
}
181+
182+
if (link) {
183+
linkShared(fileInputs);
184+
if (linkExecutable) {
185+
try {
186+
Path linkedBCfile = Files.move(Paths.get(outputFilename), Paths.get(bcFileFromFilename(outputFilename)), StandardCopyOption.REPLACE_EXISTING);
187+
linkExecutable(outputFilename, linkedBCfile.toString());
188+
} catch (IOException e) {
189+
throw new RuntimeException(e);
190+
}
191+
}
192+
}
193+
}
194+
195+
private static void linkExecutable(String executableScript, String linkedBcFile) throws IOException {
196+
List<String> cmdline = GraalPythonMain.getCmdline(Arrays.asList(), Arrays.asList());
197+
cmdline.add("-LLI");
198+
cmdline.add(linkedBcFile);
199+
Path executablePath = Paths.get(executableScript);
200+
Files.write(executablePath, String.join(" ", cmdline).getBytes());
201+
HashSet<PosixFilePermission> perms = new HashSet<>(Arrays.asList(new PosixFilePermission[]{PosixFilePermission.OWNER_EXECUTE, PosixFilePermission.GROUP_EXECUTE}));
202+
perms.addAll(Files.getPosixFilePermissions(executablePath));
203+
Files.setPosixFilePermissions(executablePath, perms);
204+
}
205+
206+
private void linkShared(List<String> bitcodeFiles) {
207+
if (fileInputs.size() > 0) {
208+
ArrayList<String> ldCmd = new ArrayList<>(bitcodeFiles);
209+
if (verbose) {
210+
ldCmd.add("-v");
211+
}
212+
ldCmd.add("-o");
213+
ldCmd.add(outputFilename);
214+
GraalPythonLD.main(ldCmd.toArray(new String[0]));
215+
}
216+
}
217+
218+
private void optFile(String bcFile) {
219+
List<String> opt = new ArrayList<>(optPrefix);
220+
opt.add(bcFile);
221+
opt.add(bcFile);
222+
exec(opt);
223+
}
224+
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* The Universal Permissive License (UPL), Version 1.0
6+
*
7+
* Subject to the condition set forth below, permission is hereby granted to any
8+
* person obtaining a copy of this software, associated documentation and/or
9+
* data (collectively the "Software"), free of charge and under any and all
10+
* copyright rights in the Software, and any and all patent rights owned or
11+
* freely licensable by each licensor hereunder covering either (i) the
12+
* unmodified Software as contributed to or provided by such licensor, or (ii)
13+
* the Larger Works (as defined below), to deal in both
14+
*
15+
* (a) the Software, and
16+
*
17+
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
18+
* one is included with the Software each a "Larger Work" to which the Software
19+
* is contributed by such licensors),
20+
*
21+
* without restriction, including without limitation the rights to copy, create
22+
* derivative works of, display, perform, and distribute the Software and make,
23+
* use, sell, offer for sale, import, export, have made, and have sold the
24+
* Software and the Larger Work(s), and to sublicense the foregoing rights on
25+
* either these or other terms.
26+
*
27+
* This license is subject to the following condition:
28+
*
29+
* The above copyright notice and either this complete permission notice or at a
30+
* minimum a reference to the UPL must be included in all copies or substantial
31+
* portions of the Software.
32+
*
33+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39+
* SOFTWARE.
40+
*/
41+
package com.oracle.graal.python.shell;
42+
43+
import java.io.IOException;
44+
import java.util.List;
45+
46+
public class GraalPythonCompiler {
47+
protected static final String A_OUT = "a.out";
48+
49+
protected static String bcFileFromFilename(String f) {
50+
int dotIdx = f.lastIndexOf('.');
51+
if (dotIdx > 1) {
52+
return f.substring(0, dotIdx + 1) + "bc";
53+
} else {
54+
return f + ".bc";
55+
}
56+
}
57+
58+
protected boolean verbose;
59+
60+
public GraalPythonCompiler() {
61+
super();
62+
}
63+
64+
protected void exec(List<String> args) {
65+
try {
66+
ProcessBuilder processBuilder = new ProcessBuilder();
67+
processBuilder.inheritIO();
68+
processBuilder.command(args);
69+
logV(args);
70+
int status = processBuilder.start().waitFor();
71+
if (status != 0) {
72+
System.exit(status);
73+
}
74+
} catch (IOException | InterruptedException e) {
75+
throw new RuntimeException(e);
76+
}
77+
}
78+
79+
protected void logV(String prefix, List<String> args) {
80+
if (verbose) {
81+
System.err.print("[python] ");
82+
System.err.print("[" + getClass().getSimpleName() + "] ");
83+
if (prefix != null) {
84+
System.err.print(prefix);
85+
}
86+
System.err.println(String.join(" ", args));
87+
}
88+
}
89+
90+
protected void logV(List<String> args) {
91+
logV(null, args);
92+
}
93+
94+
}

0 commit comments

Comments
 (0)