View Javadoc

1   /*
2    * #%L
3    * Native ARchive plugin for Maven
4    * %%
5    * Copyright (C) 2002 - 2014 NAR Maven Plugin developers.
6    * %%
7    * Licensed under the Apache License, Version 2.0 (the "License");
8    * you may not use this file except in compliance with the License.
9    * You may obtain a copy of the License at
10   * 
11   * http://www.apache.org/licenses/LICENSE-2.0
12   * 
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   * #L%
19   */
20  package com.github.maven_nar.cpptasks.msvc;
21  
22  import java.io.File;
23  import java.io.IOException;
24  import java.util.ArrayList;
25  import java.util.Arrays;
26  import java.util.Vector;
27  
28  import com.github.maven_nar.cpptasks.CCTask;
29  import com.github.maven_nar.cpptasks.CUtil;
30  import com.github.maven_nar.cpptasks.TargetMatcher;
31  import com.github.maven_nar.cpptasks.VersionInfo;
32  import com.github.maven_nar.cpptasks.compiler.CommandLineLinker;
33  import com.github.maven_nar.cpptasks.compiler.LinkType;
34  import com.github.maven_nar.cpptasks.platforms.WindowsPlatform;
35  import com.github.maven_nar.cpptasks.types.LibrarySet;
36  import com.github.maven_nar.cpptasks.types.LibraryTypeEnum;
37  
38  /**
39   * Abstract base class for linkers that try to mimic the command line arguments
40   * for the Microsoft (r) Incremental Linker
41   *
42   * @author Curt Arnold
43   */
44  public abstract class MsvcCompatibleLinker extends CommandLineLinker {
45    public MsvcCompatibleLinker(final String command, final String identifierArg, final String outputSuffix) {
46      super(command, identifierArg, new String[] {
47          ".obj", ".lib", ".res"
48      }, new String[] {
49          ".map", ".pdb", ".lnk", ".dll", ".tlb", ".rc", ".h"
50      }, outputSuffix, false, null);
51    }
52  
53    private ArrayList<File> libPaths = new ArrayList<>(Arrays.asList(CUtil.getPathFromEnvironment("LIB", ";")));
54    
55    @Override
56    protected void addBase(final CCTask task, final long base, final Vector<String> args) {
57      if (base >= 0) {
58        final String baseAddr = Long.toHexString(base);
59        args.addElement("/BASE:0x" + baseAddr);
60      }
61    }
62  
63    @Override
64    protected void addEntry(final CCTask task, final String entry, final Vector<String> args) {
65      if (entry != null) {
66        args.addElement("/ENTRY:" + entry);
67      }
68    }
69  
70    @Override
71    protected void addFixed(final CCTask task, final Boolean fixed, final Vector<String> args) {
72      if (fixed != null) {
73        if (fixed.booleanValue()) {
74          args.addElement("/FIXED");
75        } else {
76          args.addElement("/FIXED:NO");
77        }
78      }
79    }
80  
81    @Override
82    protected void addImpliedArgs(final CCTask task, final boolean debug, final LinkType linkType,
83        final Vector<String> args) {
84      args.addElement("/NOLOGO");
85      if (debug) {
86        args.addElement("/DEBUG");
87      }
88      if (linkType.isSharedLibrary()) {
89        args.addElement("/DLL");
90      }
91      //
92      // The following lines were commented out
93      // from v 1.5 to v 1.12 with no explanation
94      //
95      if (linkType.isSubsystemGUI()) {
96        args.addElement("/SUBSYSTEM:WINDOWS");
97      } else {
98        if (linkType.isSubsystemConsole()) {
99          args.addElement("/SUBSYSTEM:CONSOLE");
100       }
101     }
102   }
103 
104   @Override
105   protected void addIncremental(final CCTask task, final boolean incremental, final Vector<String> args) {
106     if (incremental) {
107       args.addElement("/INCREMENTAL:YES");
108     } else {
109       args.addElement("/INCREMENTAL:NO");
110     }
111   }
112 
113   @Override
114   protected void addLibraryPath(final Vector<String> preargs, final String path) {
115     preargs.addElement("/LIBPATH:" + path);
116     libPaths.add(0,new File(path));
117   }
118 
119   @Override
120   protected String[] addLibrarySets(final CCTask task, final LibrarySet[] libsets, final Vector<String> preargs,
121       final Vector<String> midargs, final Vector<String> endargs) {
122     for (final LibrarySet set : libsets) {
123       final File libdir = set.getDir(null);
124       addLibraryDirectory(libdir, preargs);
125     }
126     return null;
127   }
128 
129   @Override
130   protected void addMap(final CCTask task, final boolean map, final Vector<String> args) {
131     if (map) {
132       args.addElement("/MAP");
133     }
134   }
135 
136   @Override
137   protected void addStack(final CCTask task, final int stack, final Vector<String> args) {
138     if (stack >= 0) {
139       final String stackStr = Integer.toHexString(stack);
140       args.addElement("/STACK:0x" + stackStr);
141     }
142   }
143 
144   /**
145    * Adds source or object files to the bidded fileset to
146    * support version information.
147    * 
148    * @param versionInfo
149    *          version information
150    * @param linkType
151    *          link type
152    * @param isDebug
153    *          true if debug build
154    * @param outputFile
155    *          name of generated executable
156    * @param objDir
157    *          directory for generated files
158    * @param matcher
159    *          bidded fileset
160    */
161   @Override
162   public void addVersionFiles(final VersionInfo versionInfo, final LinkType linkType, final File outputFile,
163       final boolean isDebug, final File objDir, final TargetMatcher matcher) throws IOException {
164     WindowsPlatform.addVersionFiles(versionInfo, linkType, outputFile, isDebug, objDir, matcher);
165   }
166 
167   @Override
168   public String getCommandFileSwitch(final String commandFile) {
169     return "@" + commandFile;
170   }
171 
172   @Override
173   public File[] getLibraryPath() {
174     return libPaths.toArray(new File[libPaths.size()]);
175   }
176 
177   @Override
178   public String[] getLibraryPatterns(final String[] libnames, final LibraryTypeEnum libType) {
179     final StringBuffer buf = new StringBuffer();
180     final String[] patterns = new String[libnames.length];
181     for (int i = 0; i < libnames.length; i++) {
182       buf.setLength(0);
183       buf.append(libnames[i]);
184       buf.append(".lib");
185       patterns[i] = buf.toString();
186     }
187     return patterns;
188   }
189 
190   @Override
191   public int getMaximumCommandLength() {
192     // FREEHEP stay on the safe side
193     return 32000; // 32767;
194   }
195 
196   @Override
197   public String[] getOutputFileSwitch(final String outputFile) {
198     return new String[] {
199       "/OUT:" + outputFile
200     };
201   }
202 
203   @Override
204   public boolean isCaseSensitive() {
205     return false;
206   }
207 }