40
40
*/
41
41
package com .oracle .graal .python .shell ;
42
42
43
+ import java .io .BufferedReader ;
44
+ import java .io .File ;
45
+ import java .io .IOException ;
46
+ import java .lang .ProcessBuilder .Redirect ;
47
+ import java .nio .file .Files ;
48
+ import java .nio .file .Path ;
49
+ import java .nio .file .Paths ;
43
50
import java .util .ArrayList ;
44
51
import java .util .Arrays ;
52
+ import java .util .Collection ;
45
53
import java .util .List ;
46
54
55
+ import jline .internal .InputStreamReader ;
56
+
47
57
public class GraalPythonLD extends GraalPythonCompiler {
48
58
private static List <String > linkPrefix = Arrays .asList (new String []{
49
59
"llvm-link" ,
@@ -68,6 +78,7 @@ private void parseOptions(String[] args) {
68
78
ldArgs = new ArrayList <>(linkPrefix );
69
79
fileInputs = new ArrayList <>();
70
80
List <String > droppedArgs = new ArrayList <>();
81
+ List <String > libraryDirs = new ArrayList <>();
71
82
for (int i = 0 ; i < args .length ; i ++) {
72
83
String arg = args [i ];
73
84
switch (arg ) {
@@ -84,6 +95,22 @@ private void parseOptions(String[] args) {
84
95
default :
85
96
if (arg .endsWith (".o" ) || arg .endsWith (".bc" )) {
86
97
fileInputs .add (arg );
98
+ } else if (arg .startsWith ("-L" )) {
99
+ libraryDirs .add (arg .substring (2 ));
100
+ } else if (arg .startsWith ("-l" )) {
101
+ List <String > bcFiles = searchLib (libraryDirs , arg .substring (2 ));
102
+ for (String bcFile : bcFiles ) {
103
+ try {
104
+ if (Files .probeContentType (Paths .get (bcFile )).contains ("llvm-ir-bitcode" )) {
105
+ logV ("library input:" , bcFile );
106
+ fileInputs .add (bcFile );
107
+ } else {
108
+ droppedArgs .add (bcFile + "(dropped as library input)" );
109
+ }
110
+ } catch (IOException e ) {
111
+ throw new RuntimeException (e );
112
+ }
113
+ }
87
114
} else {
88
115
droppedArgs .add (arg );
89
116
}
@@ -95,6 +122,66 @@ private void parseOptions(String[] args) {
95
122
logV ("Dropped args: " , droppedArgs );
96
123
}
97
124
125
+ private List <String > searchLib (List <String > libraryDirs , String lib ) {
126
+ List <String > bcFiles = new ArrayList <>();
127
+ String [] suffixes = new String []{".bc" , ".o" , ".a" , ".so" };
128
+ String [] prefixes = new String []{"lib" , "" };
129
+ for (String libdir : libraryDirs ) {
130
+ for (String prefix : prefixes ) {
131
+ for (String suffix : suffixes ) {
132
+ Path path = Paths .get (libdir , prefix + lib + suffix );
133
+ String pathString = path .toAbsolutePath ().toString ();
134
+ logV ("Checking for library:" , pathString );
135
+ if (Files .exists (path )) {
136
+ if (suffix .equals (".a" )) {
137
+ // extract members
138
+ try {
139
+ bcFiles .addAll (arMembers (pathString ));
140
+ } catch (IOException | InterruptedException e ) {
141
+ throw new RuntimeException (e );
142
+ }
143
+ } else {
144
+ bcFiles .add (pathString );
145
+ break ;
146
+ }
147
+ }
148
+ }
149
+ }
150
+ }
151
+ logV ("Found bitcode files for library:" , bcFiles );
152
+ return bcFiles ;
153
+ }
154
+
155
+ private Collection <? extends String > arMembers (String path ) throws IOException , InterruptedException {
156
+ List <String > members = new ArrayList <>();
157
+ File temp = File .createTempFile (path , Long .toString (System .nanoTime ()));
158
+ temp .delete ();
159
+ temp .mkdir ();
160
+ temp .deleteOnExit ();
161
+
162
+ ProcessBuilder extractAr = new ProcessBuilder ();
163
+ extractAr .redirectInput (Redirect .INHERIT );
164
+ extractAr .redirectError (Redirect .INHERIT );
165
+ extractAr .redirectOutput (Redirect .PIPE );
166
+ extractAr .directory (temp );
167
+ logV ("ar" , path );
168
+ // "ar t" lists the members one per line
169
+ extractAr .command ("ar" , "t" , path );
170
+ Process start = extractAr .start ();
171
+ try (BufferedReader buffer = new BufferedReader (new InputStreamReader (start .getInputStream ()))) {
172
+ String line = null ;
173
+ while ((line = buffer .readLine ()) != null ) {
174
+ members .add (temp .getAbsolutePath () + File .separator + line );
175
+ }
176
+ }
177
+ start .waitFor ();
178
+ // actually extract them now
179
+ extractAr .redirectOutput (Redirect .INHERIT );
180
+ extractAr .command ("ar" , "xv" , path );
181
+ extractAr .start ().waitFor ();
182
+ return members ;
183
+ }
184
+
98
185
private void launchLD () {
99
186
ldArgs .add (outputFilename );
100
187
ldArgs .addAll (fileInputs );
0 commit comments