1 package org.codehaus.mojo.natives.c;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 import java.io.File;
28 import java.io.FileWriter;
29 import java.io.IOException;
30 import java.util.Iterator;
31 import java.util.List;
32
33 import org.codehaus.mojo.natives.NativeBuildException;
34 import org.codehaus.mojo.natives.linker.AbstractLinker;
35 import org.codehaus.mojo.natives.linker.Linker;
36 import org.codehaus.mojo.natives.linker.LinkerConfiguration;
37 import org.codehaus.mojo.natives.util.FileUtil;
38 import org.codehaus.plexus.component.annotations.Component;
39 import org.codehaus.plexus.util.FileUtils;
40 import org.codehaus.plexus.util.cli.Commandline;
41
42
43
44
45 @Component(role = Linker.class, hint = "generic", instantiationStrategy = "per-lookup")
46 public class CLinker
47 extends AbstractLinker
48 {
49
50
51
52
53 protected Commandline createLinkerCommandLine( List objectFiles, LinkerConfiguration config )
54 throws NativeBuildException
55 {
56 if ( config.getExecutable() == null )
57 {
58 config.setExecutable( "gcc" );
59 }
60
61 Commandline cl = new Commandline();
62
63 cl.setWorkingDirectory( config.getWorkingDirectory().getPath() );
64
65 cl.setExecutable( config.getExecutable() );
66
67 if ( config.getStartOptions() != null )
68 {
69 cl.addArguments( config.getStartOptions() );
70 }
71
72 String linkerOutputOption = this.getLinkerOutputOption();
73 if ( linkerOutputOption.endsWith( " " ) )
74 {
75 cl.createArg().setValue( linkerOutputOption.substring( 0, linkerOutputOption.length() - 1 ) );
76 cl.createArg().setFile( config.getOutputFile() );
77 }
78 else
79 {
80 cl.createArg().setValue( linkerOutputOption + config.getOutputFile() );
81 }
82
83
84 if ( config.isUsingLinkerResponseFile() )
85 {
86 try
87 {
88 File linkerFile = new File( config.getWorkingDirectory(), "objectsFile" );
89 FileWriter linkerFileWriter = new FileWriter( linkerFile, false );
90 for ( int i = 0; i < objectFiles.size(); ++i )
91 {
92 File objFile = (File) objectFiles.get( i );
93 linkerFileWriter.write( objFile.getPath() + "\n" );
94 }
95 linkerFileWriter.close();
96 }
97 catch ( IOException error )
98 {
99 throw new NativeBuildException( "Error creating linker response file", error );
100 }
101
102 cl.createArg().setValue( "@objectsFile" );
103 }
104 else
105 {
106
107 for ( int i = 0; i < objectFiles.size(); ++i )
108 {
109 File objFile = (File) objectFiles.get( i );
110
111
112 String objFilePath = FileUtil.truncatePath( objFile.getPath(), config.getWorkingDirectory().getPath() );
113
114 cl.createArg().setValue( objFilePath );
115 }
116 }
117
118 if ( config.getMiddleOptions() != null )
119 {
120 cl.addArguments( config.getMiddleOptions() );
121 }
122
123 setCommandLineForExternalLibraries( cl, config );
124
125 if ( config.getEndOptions() != null )
126 {
127 cl.addArguments( config.getEndOptions() );
128 }
129
130 return cl;
131
132 }
133
134
135
136
137 protected String getLinkerOutputOption()
138 {
139 return "-o ";
140 }
141
142
143
144
145
146
147
148
149 protected void setCommandLineForExternalLibraries( Commandline cl, LinkerConfiguration config )
150 throws NativeBuildException
151 {
152 if ( config.getExternalLibFileNames().size() == 0 )
153 {
154 return;
155 }
156
157 boolean hasUnixLinkage = false;
158
159 for ( Iterator iter = config.getExternalLibFileNames().iterator(); iter.hasNext(); )
160 {
161 String libFileName = (String) iter.next();
162
163 String ext = FileUtils.getExtension( libFileName );
164
165 if ( "o".equals( ext ) || "obj".equals( ext ) || "lib".equals( ext ) || "dylib".equals( ext ) )
166 {
167 File libFile = new File( config.getExternalLibDirectory(), libFileName );
168 String relativeLibFile =
169 FileUtil.truncatePath( libFile.getPath(), config.getWorkingDirectory().getPath() );
170 cl.createArg().setValue( relativeLibFile );
171 }
172 else if ( "a".equals( ext ) || "so".equals( ext ) || "sl".equals( ext ) )
173 {
174 hasUnixLinkage = true;
175 }
176 }
177
178 if ( hasUnixLinkage )
179 {
180 cl.createArg().setValue( "-L" + config.getExternalLibDirectory() );
181 }
182
183 for ( Iterator iter = config.getExternalLibFileNames().iterator(); iter.hasNext(); )
184 {
185 String libFileName = (String) iter.next();
186
187 String ext = FileUtils.getExtension( libFileName );
188
189 if ( "a".equals( ext ) || "so".equals( ext ) || "sl".equals( ext ) )
190 {
191 String libName = FileUtils.removeExtension( libFileName );
192
193 if ( libFileName.startsWith( "lib" ) )
194 {
195 libName = libName.substring( "lib".length() );
196 }
197
198 cl.createArg().setValue( "-l" + libName );
199 }
200 }
201 }
202
203 }