summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/CCTask.java54
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineLinker.java12
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/compiler/LinkType.java45
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/gcc/GccProcessor.java83
4 files changed, 131 insertions, 63 deletions
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/CCTask.java b/src/main/java/net/sf/antcontrib/cpptasks/CCTask.java
index 3197080..0701ba1 100644
--- a/src/main/java/net/sf/antcontrib/cpptasks/CCTask.java
+++ b/src/main/java/net/sf/antcontrib/cpptasks/CCTask.java
@@ -21,6 +21,7 @@ import java.util.Enumeration;
import java.util.Hashtable;
import java.util.*;
+import net.sf.antcontrib.cpptasks.compiler.AbstractLinker;
import net.sf.antcontrib.cpptasks.compiler.CompilerConfiguration;
import net.sf.antcontrib.cpptasks.compiler.LinkType;
import net.sf.antcontrib.cpptasks.compiler.Linker;
@@ -622,7 +623,7 @@ public class CCTask extends Task {
// Assemble hashtable of all files
// that we know how to compile (keyed by output file name)
//
- final Hashtable targets = getTargets(linkerConfig, objectFiles, versionInfo, _outfile);
+ final Hashtable targets = getTargets(linkerConfig, objectFiles, versionInfo, _outfile); // getTargets(..) -> createConfiguration(..) -> addImpliedArgs(..)
TargetInfo linkTarget = null;
//
// if output file is not specified,
@@ -804,7 +805,7 @@ public class CCTask extends Task {
final LinkerConfiguration linkConfig = (LinkerConfiguration) linkTarget
.getConfiguration();
if (failOnError) {
- linkConfig.link(this, linkTarget);
+ linkConfig.link(this, linkTarget); // link(..) -> prepareArguments(..) -> decorateLinkerOption(..) + getOutputFileSwitch(..)
} else {
try {
linkConfig.link(this, linkTarget);
@@ -1297,11 +1298,7 @@ public class CCTask extends Task {
}
/**
- * User preference whether to use a high-level-tool for
- * linker operations, e.g. gcc instead of ar to build static libraries.
- * <p>
- * Default is false.
- * </p>
+ * See {@link #getUseHighlevelTool()}.
* @param useHighlevelTool user preference, default is false
*/
public void setUseHighlevelTool(final boolean useHighlevelTool) {
@@ -1309,7 +1306,11 @@ public class CCTask extends Task {
}
/**
- * Gets the usehighleveltool flag.
+ * User preference whether to use a high-level-tool for
+ * linker operations, e.g. gcc instead of ar to build static libraries.
+ * <p>
+ * Default is false.
+ * </p>
* @return the usehighleveltool flag
* @see #setUseHighlevelTool(boolean)
*/
@@ -1318,6 +1319,43 @@ public class CCTask extends Task {
}
/**
+ * See {@link #getWriteSONAME()}
+ * @param v user preference, default is false
+ */
+ public void setWriteSONAME(final boolean v) {
+ linkType.setWriteSONAME(v);
+ }
+
+ /**
+ * User preference whether to write the {@code DT_SONAME} in a {@link #isSharedLibrary() shared library}
+ * using the {@link AbstractLinker#getOutputFileName(String, net.sf.antcontrib.cpptasks.VersionInfo)}.
+ * <p>
+ * This will set the linker options {@code -h name}, which is compatible with GNU ld and clang's ld,
+ * decorated as {@code -Wl,-h,name}.
+ * </p>
+ * <p>
+ * Feature is currently enabled for the GnuLinker (GccLinker 'gcc' + GppLinker 'gpp') as well as for clang (clang).
+ * </p>
+ * <p>
+ * Default is false.
+ * </p>
+ *
+ * @return the setSONAME flag
+ */
+ public boolean getWriteSONAME() {
+ return linkType.getWriteSONAME();
+ }
+
+ /**
+ * Gets whether the link should produce a shared library.
+ *
+ * @return boolean
+ */
+ public boolean isSharedLibrary() {
+ return linkType.isSharedLibrary();
+ }
+
+ /**
* Sets the project.
*/
@Override
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineLinker.java
index d7b30cd..8ed0b2f 100644
--- a/src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineLinker.java
+++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/CommandLineLinker.java
@@ -31,6 +31,7 @@ import net.sf.antcontrib.cpptasks.types.CommandLineArgument;
import net.sf.antcontrib.cpptasks.types.LibrarySet;
import net.sf.antcontrib.cpptasks.TargetDef;
import net.sf.antcontrib.cpptasks.VersionInfo;
+import net.sf.antcontrib.cpptasks.gcc.GccProcessor;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.types.Environment;
@@ -328,13 +329,17 @@ public abstract class CommandLineLinker extends AbstractLinker
final String outputDir,
final String outputFile,
final String[] sourceFiles,
- final CommandLineLinkerConfiguration config) {
+ final CommandLineLinkerConfiguration config)
+ {
final String[] preargs = config.getPreArguments();
final String[] endargs = config.getEndArguments();
final String outputSwitch[] = getOutputFileSwitch(task, outputFile);
+ final boolean writeSONAME = task.getWriteSONAME() && task.isSharedLibrary() && ( isGCC || isCLANG );
int allArgsCount = preargs.length + 1 + outputSwitch.length +
- sourceFiles.length + endargs.length;
+ sourceFiles.length + endargs.length +
+ ( writeSONAME ? 1 : 0 );
+
if (isLibtool) {
allArgsCount++;
}
@@ -354,6 +359,9 @@ public abstract class CommandLineLinker extends AbstractLinker
for (int i = 0; i < preargs.length; i++) {
allArgs[index++] = decorateLinkerOption(buf, preargs[i]);
}
+ if( writeSONAME ) {
+ allArgs[index++] = "-Wl,-h,"+GccProcessor.getEscapedOutputFile(outputFile);
+ }
for (int i = 0; i < outputSwitch.length; i++) {
allArgs[index++] = outputSwitch[i];
}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/compiler/LinkType.java b/src/main/java/net/sf/antcontrib/cpptasks/compiler/LinkType.java
index c74f314..d650de7 100644
--- a/src/main/java/net/sf/antcontrib/cpptasks/compiler/LinkType.java
+++ b/src/main/java/net/sf/antcontrib/cpptasks/compiler/LinkType.java
@@ -27,14 +27,8 @@ public class LinkType {
private OutputTypeEnum outputType = new OutputTypeEnum();
private boolean staticRuntime = false;
private SubsystemEnum subsystem = new SubsystemEnum();
- /**
- * User preference whether to use a high-level-tool for
- * linker operations, e.g. gcc instead of ar to build static libraries.
- * <p>
- * Default is false.
- * </p>
- */
private boolean useHighlevelTool = false;
+ private boolean writeSONAME = false;
/**
* Constructor
@@ -158,11 +152,7 @@ public class LinkType {
}
/**
- * User preference whether to use a high-level-tool for
- * linker operations, e.g. gcc instead of ar to build static libraries.
- * <p>
- * Default is false.
- * </p>
+ * See {@link #getUseHighlevelTool()}.
* @param useHighlevelTool user preference, default is false
*/
public void setUseHighlevelTool(final boolean useHighlevelTool) {
@@ -170,11 +160,40 @@ public class LinkType {
}
/**
- * Gets the usehighleveltool flag.
+ * User preference whether to use a high-level-tool for
+ * linker operations, e.g. gcc instead of ar to build static libraries.
+ * <p>
+ * Default is false.
+ * </p>
* @return the usehighleveltool flag
* @see #setUseHighlevelTool(boolean)
*/
public boolean getUseHighlevelTool() {
return useHighlevelTool;
}
+
+ /**
+ * See {@link #getWriteSONAME()}
+ * @param v user preference, default is false
+ */
+ public void setWriteSONAME(final boolean v) {
+ writeSONAME=v;
+ }
+
+ /**
+ * User preference whether to write the {@code DT_SONAME} in a {@link #isSharedLibrary() shared library}
+ * using the {@link AbstractLinker#getOutputFileName(String, net.sf.antcontrib.cpptasks.VersionInfo)}.
+ * <p>
+ * This will set the linker options {@code -h name}, which is compatible with GNU ld and clang's ld,
+ * decorated as {@code -Wl,-h,name}.
+ * </p>
+ * <p>
+ * Default is false.
+ * </p>
+ *
+ * @return the setSONAME flag
+ */
+ public boolean getWriteSONAME() {
+ return writeSONAME;
+ }
}
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/gcc/GccProcessor.java b/src/main/java/net/sf/antcontrib/cpptasks/gcc/GccProcessor.java
index 988848d..e02054d 100644
--- a/src/main/java/net/sf/antcontrib/cpptasks/gcc/GccProcessor.java
+++ b/src/main/java/net/sf/antcontrib/cpptasks/gcc/GccProcessor.java
@@ -1,5 +1,5 @@
/*
- *
+ *
* Copyright 2002-2004 The Ant-Contrib project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -25,8 +25,8 @@ import net.sf.antcontrib.cpptasks.CUtil;
import net.sf.antcontrib.cpptasks.compiler.CaptureStreamHandler;
/**
* A add-in class for Gcc processors
- *
- *
+ *
+ *
*/
public class GccProcessor {
// the results from gcc -dumpmachine
@@ -34,8 +34,8 @@ public class GccProcessor {
private static String[] specs;
// the results from gcc -dumpversion
private static String version;
- private static int addLibraryPatterns(String[] libnames, StringBuffer buf,
- String prefix, String extension, String[] patterns, int offset) {
+ private static int addLibraryPatterns(final String[] libnames, final StringBuffer buf,
+ final String prefix, final String extension, final String[] patterns, final int offset) {
for (int i = 0; i < libnames.length; i++) {
buf.setLength(0);
buf.append(prefix);
@@ -48,21 +48,21 @@ public class GccProcessor {
/**
* Converts absolute Cygwin file or directory names to the corresponding
* Win32 name.
- *
+ *
* @param names
* array of names, some elements may be null, will be changed in
* place.
*/
- public static void convertCygwinFilenames(String[] names) {
+ public static void convertCygwinFilenames(final String[] names) {
if (names == null) {
throw new NullPointerException("names");
}
- File gccDir = CUtil.getExecutableLocation("gcc.exe");
+ final File gccDir = CUtil.getExecutableLocation("gcc.exe");
if (gccDir != null) {
- String prefix = gccDir.getAbsolutePath() + "/..";
- StringBuffer buf = new StringBuffer();
+ final String prefix = gccDir.getAbsolutePath() + "/..";
+ final StringBuffer buf = new StringBuffer();
for (int i = 0; i < names.length; i++) {
- String name = names[i];
+ final String name = names[i];
if (name != null && name.length() > 1 && name.charAt(0) == '/') {
buf.setLength(0);
buf.append(prefix);
@@ -72,9 +72,9 @@ public class GccProcessor {
}
}
}
- public static String[] getLibraryPatterns(String[] libnames) {
- StringBuffer buf = new StringBuffer();
- String[] patterns = new String[libnames.length * 2];
+ public static String[] getLibraryPatterns(final String[] libnames) {
+ final StringBuffer buf = new StringBuffer();
+ final String[] patterns = new String[libnames.length * 2];
int offset = addLibraryPatterns(libnames, buf, "lib", ".a", patterns, 0);
if (isHPUX()) {
offset = addLibraryPatterns(libnames, buf, "lib", ".sl", patterns,
@@ -87,8 +87,8 @@ public class GccProcessor {
}
public static String getMachine() {
if (machine == null) {
- String[] args = new String[]{"gcc", "-dumpmachine"};
- String[] cmdout = CaptureStreamHandler.run(args);
+ final String[] args = new String[]{"gcc", "-dumpmachine"};
+ final String[] cmdout = CaptureStreamHandler.run(args);
if (cmdout.length == 0) {
machine = "nomachine";
} else {
@@ -97,8 +97,8 @@ public class GccProcessor {
}
return machine;
}
- public static String[] getOutputFileSwitch(String letter, String outputFile) {
- StringBuffer buf = new StringBuffer();
+ public static String getEscapedOutputFile(final String outputFile) {
+ final StringBuffer buf = new StringBuffer();
if (outputFile.indexOf(' ') >= 0) {
buf.append('"');
buf.append(outputFile.replace('\\', '/'));
@@ -106,28 +106,31 @@ public class GccProcessor {
} else {
buf.append(outputFile.replace('\\', '/'));
}
- String[] retval = new String[]{letter, buf.toString()};
+ return buf.toString();
+ }
+ public static String[] getOutputFileSwitch(final String letter, final String outputFile) {
+ final String[] retval = new String[]{letter, getEscapedOutputFile(outputFile)};
return retval;
}
/**
* Returns the contents of the gcc specs file.
- *
+ *
* The implementation locates gcc.exe in the executable path and then
* builds a relative path name from the results of -dumpmachine and
* -dumpversion. Attempts to use gcc -dumpspecs to provide this information
* resulted in stalling on the Execute.run
- *
+ *
* @return contents of the specs file
*/
public static String[] getSpecs() {
if (specs == null) {
- File gccParent = CUtil.getExecutableLocation("gcc.exe");
+ final File gccParent = CUtil.getExecutableLocation("gcc.exe");
if (gccParent != null) {
//
// build a relative path like
// ../lib/gcc-lib/i686-pc-cygwin/2.95.3-5/specs
//
- StringBuffer buf = new StringBuffer("../lib/gcc-lib/");
+ final StringBuffer buf = new StringBuffer("../lib/gcc-lib/");
buf.append(getMachine());
buf.append('/');
buf.append(getVersion());
@@ -135,8 +138,8 @@ public class GccProcessor {
//
// resolve it relative to the location of gcc.exe
//
- String relativePath = buf.toString();
- File specsFile = new File(gccParent, relativePath);
+ final String relativePath = buf.toString();
+ final File specsFile = new File(gccParent, relativePath);
//
// found the specs file
//
@@ -144,9 +147,9 @@ public class GccProcessor {
//
// read the lines in the file
//
- BufferedReader reader = new BufferedReader(new FileReader(
+ final BufferedReader reader = new BufferedReader(new FileReader(
specsFile));
- Vector lines = new Vector(100);
+ final Vector lines = new Vector(100);
String line = reader.readLine();
while (line != null) {
lines.addElement(line);
@@ -154,7 +157,7 @@ public class GccProcessor {
}
specs = new String[lines.size()];
lines.copyInto(specs);
- } catch (IOException ex) {
+ } catch (final IOException ex) {
}
}
}
@@ -165,8 +168,8 @@ public class GccProcessor {
}
public static String getVersion() {
if (version == null) {
- String[] args = new String[]{"gcc", "-dumpversion"};
- String[] cmdout = CaptureStreamHandler.run(args);
+ final String[] args = new String[]{"gcc", "-dumpversion"};
+ final String[] cmdout = CaptureStreamHandler.run(args);
if (cmdout.length == 0) {
version = "noversion";
} else {
@@ -180,24 +183,24 @@ public class GccProcessor {
}
/**
* Determines if task is running with cygwin
- *
+ *
* @return true if cygwin was detected
*/
public static boolean isCygwin() {
return getMachine().indexOf("cygwin") > 0;
}
private static boolean isHPUX() {
- String osname = System.getProperty("os.name").toLowerCase();
+ final String osname = System.getProperty("os.name").toLowerCase();
if (osname.indexOf("hp") >= 0 && osname.indexOf("ux") >= 0) {
return true;
}
return false;
}
/**
- *
+ *
* Parses the results of the specs file for a specific processor and
* options
- *
+ *
* @param specsContent
* Contents of specs file as returned from getSpecs
* @param specSectionStart
@@ -205,8 +208,8 @@ public class GccProcessor {
* @param options
* command line switches such as "-istart"
*/
- public static String[][] parseSpecs(String[] specsContent,
- String specSectionStart, String[] options) {
+ public static String[][] parseSpecs(final String[] specsContent,
+ final String specSectionStart, final String[] options) {
if (specsContent == null) {
throw new NullPointerException("specsContent");
}
@@ -216,15 +219,15 @@ public class GccProcessor {
if (options == null) {
throw new NullPointerException("option");
}
- String[][] optionValues = new String[options.length][];
- StringBuffer optionValue = new StringBuffer(40);
+ final String[][] optionValues = new String[options.length][];
+ final StringBuffer optionValue = new StringBuffer(40);
for (int i = 0; i < specsContent.length; i++) {
String specLine = specsContent[i];
//
// if start of section then start paying attention
//
if (specLine.startsWith(specSectionStart)) {
- Vector[] optionVectors = new Vector[options.length];
+ final Vector[] optionVectors = new Vector[options.length];
for (int j = 0; j < options.length; j++) {
optionVectors[j] = new Vector(10);
}
@@ -287,7 +290,7 @@ public class GccProcessor {
// fill in any missing option values with
// a zero-length string array
for (int i = 0; i < optionValues.length; i++) {
- String[] zeroLenArray = new String[0];
+ final String[] zeroLenArray = new String[0];
if (optionValues[i] == null) {
optionValues[i] = zeroLenArray;
}