summaryrefslogtreecommitdiff
path: root/src/main/java/net/sf/antcontrib/cpptasks/apple/XcodeProjectWriter.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/net/sf/antcontrib/cpptasks/apple/XcodeProjectWriter.java')
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/apple/XcodeProjectWriter.java1430
1 files changed, 936 insertions, 494 deletions
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/apple/XcodeProjectWriter.java b/src/main/java/net/sf/antcontrib/cpptasks/apple/XcodeProjectWriter.java
index 7f21bec..f901b4d 100644
--- a/src/main/java/net/sf/antcontrib/cpptasks/apple/XcodeProjectWriter.java
+++ b/src/main/java/net/sf/antcontrib/cpptasks/apple/XcodeProjectWriter.java
@@ -16,20 +16,6 @@
*/
package net.sf.antcontrib.cpptasks.apple;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.Writer;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.Vector;
-import java.util.List;
-
-import org.apache.tools.ant.BuildException;
-
import net.sf.antcontrib.cpptasks.CCTask;
import net.sf.antcontrib.cpptasks.CUtil;
import net.sf.antcontrib.cpptasks.TargetInfo;
@@ -37,538 +23,994 @@ import net.sf.antcontrib.cpptasks.compiler.CommandLineCompilerConfiguration;
import net.sf.antcontrib.cpptasks.compiler.CommandLineLinkerConfiguration;
import net.sf.antcontrib.cpptasks.compiler.ProcessorConfiguration;
import net.sf.antcontrib.cpptasks.gcc.GccCCompiler;
+import net.sf.antcontrib.cpptasks.ide.DependencyDef;
import net.sf.antcontrib.cpptasks.ide.ProjectDef;
import net.sf.antcontrib.cpptasks.ide.ProjectWriter;
+import org.apache.tools.ant.BuildException;
+import org.xml.sax.SAXException;
+
+import javax.xml.transform.TransformerConfigurationException;
+import java.io.File;
+import java.io.IOException;
+import java.text.NumberFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
/**
- * Writes a Apple Xcode project directory.
- *
- * Status: Collects file list but does not pick up libraries and settings from
- * project.
- *
- * @author curta
+ * Writes a Apple Xcode 2.1+ project directory. XCode stores project
+ * configuration as a PropertyList. Though it will always write the project
+ * as a Cocoa Old-Style ASCII property list, it will read projects
+ * stored using Cocoa's XML Property List format.
*/
public final class XcodeProjectWriter
- implements ProjectWriter {
-
- /**
- * Next object identifier for project file.
- */
- private int nextID = 0x08FB7796;
-
- /**
- * Constructor.
- *
- */
- public XcodeProjectWriter() {
- }
-
- /**
- * Get next unique ID.
- * @return unique ID
- */
- private String getUniqueID() {
- return Integer.toString(nextID++, 16) + "FE84155DC02AAC07";
- }
-
- /**
- * Writes a project definition file.
- *
- * @param fileName
- * File name base, writer may append appropriate extension
- * @param task
- * cc task for which to write project
- * @param projectDef
- * project element
- * @param targets
- * compilation targets
- * @param linkTarget
- * link target
- * @throws IOException
- * if error writing project file
- */
- public void writeProject(final File fileName,
- final CCTask task,
- final ProjectDef projectDef,
- final List sources,
- final Hashtable targets,
- final TargetInfo linkTarget) throws IOException {
-
- File xcodeDir = new File(fileName + ".xcode");
- if (!projectDef.getOverwrite() && xcodeDir.exists()) {
- throw new BuildException("Not allowed to overwrite project file "
- + xcodeDir.toString());
+ implements ProjectWriter {
+
+ /**
+ * Constructor.
+ */
+ public XcodeProjectWriter() {
}
- CommandLineCompilerConfiguration compilerConfig =
- getBaseCompilerConfiguration(targets);
- if (compilerConfig == null) {
- throw new BuildException(
- "Unable to find compilation target using GNU C++ compiler");
+ /**
+ * Writes a project definition file.
+ *
+ * @param fileName File name base, writer may append appropriate extension
+ * @param task cc task for which to write project
+ * @param projectDef project element
+ * @param targets compilation targets
+ * @param linkTarget link target
+ * @throws IOException if error writing project file
+ */
+ public void writeProject(final File fileName,
+ final CCTask task,
+ final ProjectDef projectDef,
+ final List sources,
+ final Hashtable targets,
+ final TargetInfo linkTarget) throws IOException {
+
+ File xcodeDir = new File(fileName + ".xcodeproj");
+ if (!projectDef.getOverwrite() && xcodeDir.exists()) {
+ throw new BuildException("Not allowed to overwrite project file "
+ + xcodeDir.toString());
+ }
+
+ CommandLineCompilerConfiguration compilerConfig =
+ getBaseCompilerConfiguration(targets);
+ if (compilerConfig == null) {
+ throw new BuildException(
+ "Unable to find compilation target using GNU C++ compiler");
+ }
+
+
+ CommandLineLinkerConfiguration linkerConfig = null;
+ if (linkTarget.getConfiguration() instanceof CommandLineLinkerConfiguration) {
+ linkerConfig = (CommandLineLinkerConfiguration) linkTarget.getConfiguration();
+ }
+
+ String projectName = projectDef.getName();
+ if (projectName == null) {
+ projectName = fileName.getName();
+ }
+ final String basePath = fileName.getAbsoluteFile().getParent();
+
+ xcodeDir.mkdir();
+
+ File xcodeProj = new File(xcodeDir, "project.pbxproj");
+
+ //
+ // create property list
+ //
+ Map propertyList = new HashMap();
+ propertyList.put("archiveVersion", "1");
+ propertyList.put("classes", new HashMap());
+ propertyList.put("objectVersion", "42");
+ Map objects = new HashMap();
+
+ final String sourceTree = "<source>";
+
+ //
+ // add source files and source group to property list
+ //
+ List sourceGroupChildren =
+ addSources(objects, "SOURCE_ROOT", basePath, targets);
+ PBXObjectRef sourceGroup =
+ createPBXGroup("Source", sourceTree, sourceGroupChildren);
+ objects.put(sourceGroup.getID(), sourceGroup.getProperties());
+
+
+
+
+ //
+ // add product to property list
+ //
+ PBXObjectRef product = addProduct(objects, linkTarget);
+ List productsList = new ArrayList();
+ productsList.add(product);
+ PBXObjectRef productsGroup =
+ createPBXGroup("Products", sourceTree, productsList);
+ objects.put(productsGroup.getID(), productsGroup.getProperties());
+
+ //
+ // add documentation group to property list
+ //
+ PBXObjectRef documentationGroup = addDocumentationGroup(objects, sourceTree);
+
+ //
+ // add main group containing source, products and documentation group
+ //
+ ArrayList groups = new ArrayList(3);
+ groups.add(sourceGroup);
+ groups.add(documentationGroup);
+ groups.add(productsGroup);
+ PBXObjectRef mainGroup = createPBXGroup(projectName, sourceTree, groups);
+ StringBuffer comments = new StringBuffer();
+ for(Iterator iter = projectDef.getComments().iterator(); iter.hasNext();) {
+ comments.append(iter.next());
+ }
+ if (comments.length() > 0) {
+ mainGroup.getProperties().put("comments", comments.toString());
+ }
+ objects.put(mainGroup.getID(), mainGroup.getProperties());
+
+ //
+ // add project configurations
+ //
+ PBXObjectRef compilerConfigurations =
+ addProjectConfigurationList(objects,
+ basePath,
+ projectDef.getDependencies(),
+ compilerConfig,
+ linkerConfig);
+
+ String projectDirPath = "";
+ List projectTargets = new ArrayList();
+
+ //
+ // add project to property list
+ //
+ //
+ // Calculate path (typically several ../..) of the root directory
+ // (where build.xml lives) relative to the XCode project directory.
+ // XCode 3.0 will now prompt user to supply the value if not specified.
+ String projectRoot = CUtil.toUnixPath(
+ CUtil.getRelativePath(basePath, projectDef.getProject().getBaseDir()));
+ PBXObjectRef project = createPBXProject(compilerConfigurations, mainGroup,
+ projectDirPath, projectRoot, projectTargets);
+ objects.put(project.getID(), project.getProperties());
+
+ List frameworkBuildFiles = new ArrayList();
+ for (Iterator iter = projectDef.getDependencies().iterator(); iter.hasNext();) {
+ DependencyDef dependency = (DependencyDef) iter.next();
+ PBXObjectRef buildFile = addDependency(objects, project, groups, basePath, dependency);
+ if (buildFile != null) {
+ frameworkBuildFiles.add(buildFile);
+ }
+ }
+ //
+ // add description of native target (that is the executable or
+ // shared library)
+ //
+ PBXObjectRef nativeTarget =
+ addNativeTarget(objects, linkTarget, product,
+ projectName, sourceGroupChildren, frameworkBuildFiles);
+ projectTargets.add(nativeTarget);
+
+
+
+
+
+ //
+ // finish up overall property list
+ //
+ propertyList.put("objects", objects);
+ propertyList.put("rootObject", project.getID());
+
+
+ //
+ // write property list out to XML file
+ //
+ try {
+ PropertyListSerialization.serialize(propertyList,
+ projectDef.getComments(), xcodeProj);
+ } catch (TransformerConfigurationException ex) {
+ throw new IOException(ex.toString());
+ } catch (SAXException ex) {
+ if (ex.getException() instanceof IOException) {
+ throw (IOException) ex.getException();
+ }
+ throw new IOException(ex.toString());
+ }
}
- String projectName = projectDef.getName();
- if (projectName == null) {
- projectName = fileName.getName();
+
+ /**
+ * Adds a dependency to the object graph.
+ * @param objects
+ * @param project
+ * @param mainGroupChildren
+ * @param baseDir
+ * @param dependency
+ * @return PBXBuildFile to add to PBXFrameworksBuildPhase.
+ */
+ private PBXObjectRef addDependency(final Map objects,
+ final PBXObjectRef project,
+ final List mainGroupChildren,
+ final String baseDir,
+ final DependencyDef dependency) {
+ if (dependency.getFile() != null) {
+ File xcodeDir = new File(dependency.getFile().getAbsolutePath() + ".xcodeproj");
+ if (xcodeDir.exists()) {
+ PBXObjectRef xcodePrj = createPBXFileReference("SOURCE_ROOT", baseDir, xcodeDir);
+ mainGroupChildren.add(xcodePrj);
+ objects.put(xcodePrj.getID(), xcodePrj.getProperties());
+
+ int proxyType = 2;
+ PBXObjectRef proxy = createPBXContainerItemProxy(
+ xcodePrj, proxyType, dependency.getName());
+ objects.put(proxy.getID(), proxy.getProperties());
+
+ PBXObjectRef referenceProxy = createPBXReferenceProxy(proxy, dependency);
+ objects.put(referenceProxy.getID(), referenceProxy.getProperties());
+
+ PBXObjectRef buildFile = createPBXBuildFile(referenceProxy, Collections.EMPTY_MAP);
+ objects.put(buildFile.getID(), buildFile.getProperties());
+
+ List productsChildren = new ArrayList();
+ productsChildren.add(referenceProxy);
+ PBXObjectRef products = createPBXGroup("Products", "<group>", productsChildren);
+ objects.put(products.getID(), products.getProperties());
+
+ Map projectReference = new HashMap();
+ projectReference.put("ProductGroup", products);
+ projectReference.put("ProjectRef", xcodePrj);
+
+ List projectReferences = (List) project.getProperties().get("ProjectReferences");
+ if (projectReferences == null) {
+ projectReferences = new ArrayList();
+ project.getProperties().put("ProjectReferences", projectReferences);
+ }
+ projectReferences.add(projectReference);
+ return buildFile;
+ }
+ }
+ return null;
}
- final String basePath = fileName.getAbsoluteFile().getParent();
-
- xcodeDir.mkdir();
-
- File xcodeProj = new File(xcodeDir, "project.pbxproj");
-
- //
- // assume that all C++ compiles can use the
- // same settings
- //
- CommandLineCompilerConfiguration gccConfig = null;
-
- Vector sourceList = new Vector(targets.size());
- Iterator targetIter = targets.values().iterator();
- while (targetIter.hasNext()) {
- TargetInfo info = (TargetInfo) targetIter.next();
- File[] targetsources = info.getSources();
- for (int i = 0; i < targetsources.length; i++) {
- sourceList.addElement(new SourceEntry(targetsources[i],
- getUniqueID(), getUniqueID()));
- }
- ProcessorConfiguration procConfig = info.getConfiguration();
- if (procConfig instanceof CommandLineCompilerConfiguration
- && gccConfig == null) {
- gccConfig = (CommandLineCompilerConfiguration) procConfig;
- }
+
+ /**
+ * Add documentation group to map of objects.
+ * @param objects object map.
+ * @param sourceTree source tree description.
+ * @return documentation group.
+ */
+ private PBXObjectRef addDocumentationGroup(final Map objects,
+ final String sourceTree) {
+ List productsList = new ArrayList();
+ PBXObjectRef products =
+ createPBXGroup("Documentation", sourceTree, productsList);
+ objects.put(products.getID(), products.getProperties());
+ return products;
}
- SourceEntry[] sortedSources = new SourceEntry[sourceList.size()];
- sourceList.copyInto(sortedSources);
- Arrays.sort(sortedSources, new Comparator() {
- public int compare(final Object o1, final Object o2) {
- return ( (SourceEntry) o1).getFile().getName().compareTo( ( (
- SourceEntry) o2).getFile().getName());
- }
- });
- File outFile = task.getOutfile();
-
- Writer writer = new BufferedWriter(new FileWriter(xcodeProj));
-
- writer.write("// !$*UTF8*$!\n");
- writer.write(" {\n");
- writer.write(" archiveVersion = 1;\n");
- writer.write(" classes = {\n");
- writer.write(" };\n");
- writer.write(" objectVersion = 39;\n");
- writer.write(" objects = {\n");
- writer.write(" 014CEA520018CE5811CA2923 = {\n");
- writer.write(" buildRules = (\n");
- writer.write(" );\n");
- writer.write(" buildSettings = {\n");
- writer.write(" COPY_PHASE_STRIP = NO;\n");
- writer.write(" DEBUGGING_SYMBOLS = YES;\n");
- writer.write(" GCC_DYNAMIC_NO_PIC = NO;\n");
- writer.write(" GCC_ENABLE_FIX_AND_CONTINUE = YES;\n");
- writer.write(" GCC_GENERATE_DEBUGGING_SYMBOLS = YES;\n");
- writer.write(" GCC_OPTIMIZATION_LEVEL = 0;\n");
- writer.write(" OPTIMIZATION_CFLAGS = \"-O0\";\n");
- writer.write(" ZERO_LINK = YES;\n");
- writer.write(" };\n");
- writer.write(" isa = PBXBuildStyle;\n");
- writer.write(" name = Development;\n");
- writer.write(" };\n");
- writer.write(" 014CEA530018CE5811CA2923 = {\n");
- writer.write(" buildRules = (\n");
- writer.write(" );\n");
- writer.write(" buildSettings = {\n");
- writer.write(" COPY_PHASE_STRIP = YES;\n");
- writer.write(" GCC_ENABLE_FIX_AND_CONTINUE = NO;\n");
- writer.write(" ZERO_LINK = NO;\n");
- writer.write(" };\n");
- writer.write(" isa = PBXBuildStyle;\n");
- writer.write(" name = Deployment;\n");
- writer.write(" };\n");
- writer.write("// 010\n");
- writer.write("// 011\n");
- writer.write("// 012\n");
- writer.write("// 013\n");
- writer.write("// 014\n");
- writer.write("// 080\n");
- writer.write("// 081\n");
- writer.write("// 082\n");
- writer.write("// 083\n");
- writer.write("// 084\n");
- writer.write(" 08FB7793FE84155DC02AAC07 = {\n");
- writer.write(" buildSettings = {\n");
- writer.write(" };\n");
- writer.write(" buildStyles = (\n");
- writer.write(" 014CEA520018CE5811CA2923,\n");
- writer.write(" 014CEA530018CE5811CA2923,\n");
- writer.write(" );\n");
- writer.write(" hasScannedForEncodings = 1;\n");
- writer.write(" isa = PBXProject;\n");
- writer.write(" mainGroup = 08FB7794FE84155DC02AAC07;\n");
- writer.write(" projectDirPath = \"\";\n");
- writer.write(" targets = (\n");
- writer.write(" D2AAC0620554660B00DB518D,\n");
- writer.write(" );\n");
- writer.write(" };\n");
- writer.write(" 08FB7794FE84155DC02AAC07 = {\n");
- writer.write(" children = (\n");
- writer.write(" 08FB7795FE84155DC02AAC07,\n");
- writer.write(" 1AB674ADFE9D54B511CA2CBB,\n");
- writer.write(" );\n");
- writer.write(" isa = PBXGroup;\n");
- writer.write(" name = ");
- writer.write(outFile.getName());
- writer.write(";\n");
- writer.write(" refType = 4;\n");
- writer.write(" sourceTree = \"<group>\";\n");
- writer.write(" };\n");
- writer.write(" 08FB7795FE84155DC02AAC07 = {\n");
- writer.write(" children = (\n");
-
- //
- // source ID's go here
- //
- for (int i = 0; i < sortedSources.length; i++) {
- writer.write(" ");
- writer.write(sortedSources[i].getSourceID());
- writer.write(",\n");
+
+ /**
+ * Add file reference of product to map of objects.
+ * @param objects object map.
+ * @param linkTarget build description for executable or shared library.
+ * @return file reference to generated executable or shared library.
+ */
+ private PBXObjectRef addProduct(final Map objects,
+ final TargetInfo linkTarget) {
+
+ //
+ // create file reference for executable file
+ // forget Ant's location, just place in XCode's default location
+ PBXObjectRef executable = createPBXFileReference("BUILD_PRODUCTS_DIR",
+ linkTarget.getOutput().getParent(),
+ linkTarget.getOutput());
+ Map executableProperties = executable.getProperties();
+
+ String fileType = getFileType(linkTarget);
+ executableProperties.put("explicitFileType", fileType);
+ executableProperties.put("includeInIndex", "0");
+ objects.put(executable.getID(), executableProperties);
+
+ return executable;
}
- writer.write(" );\n");
- writer.write(" isa = PBXGroup;\n");
- writer.write(" name = Source;\n");
- writer.write(" refType = 4;\n");
- writer.write(" sourceTree = \"<group>\";\n");
- writer.write(" };\n");
-
- for (int i = 0; i < sortedSources.length; i++) {
- //
- // source definition
- //
- SourceEntry entry = sortedSources[i];
- writer.write(" ");
- writer.write(entry.getSourceID());
- writer.write(" = {\n");
- writer.write(" fileEncoding = 4;\n");
- writer.write(" isa = PBXFileReference;\n");
- String sourceName = entry.getFile().getName();
- if (sourceName.endsWith(".c")) {
- writer.write(" lastKnownFileType = sourcecode.c.c;\n");
- } else {
- writer.write(" lastKnownFileType = sourcecode.cpp.cpp;\n");
- }
-
- String relativePath = CUtil.getRelativePath(basePath, entry.getFile());
- if (!relativePath.equals(sourceName)) {
- writer.write(" name = ");
- writer.write(sourceName);
- writer.write(";\n");
- }
- writer.write(" path = ");
- writer.write(relativePath);
- writer.write(";\n");
- writer.write(" refType = 4;\n");
- writer.write(" sourceTree = \"<group>\";\n");
- writer.write(" };\n");
-
- //
- // build definition
- //
- writer.write(" ");
- writer.write(entry.getBuildID());
- writer.write(" = {\n");
- writer.write(" fileRef = ");
- writer.write(entry.getSourceID());
- writer.write(";\n");
- writer.write(" isa = PBXBuildFile;\n");
- writer.write(" settings = {\n");
- writer.write(" };\n");
- writer.write(" };\n");
+ /**
+ * Add file references for all source files to map of objects.
+ * @param objects map of objects.
+ * @param sourceTree source tree.
+ * @param basePath parent of XCode project dir
+ * @param targets build targets.
+ * @return list containing file references of source files.
+ */
+ private List addSources(final Map objects,
+ final String sourceTree,
+ final String basePath,
+ final Hashtable targets) {
+ List sourceGroupChildren = new ArrayList();
+
+ ArrayList sourceList = new ArrayList(targets.size());
+ Iterator targetIter = targets.values().iterator();
+ while (targetIter.hasNext()) {
+ TargetInfo info = (TargetInfo) targetIter.next();
+ File[] targetsources = info.getSources();
+ for (int i = 0; i < targetsources.length; i++) {
+ sourceList.add(targetsources[i]);
+ }
+ }
+ Object[] sortedSources = sourceList.toArray();
+ Arrays.sort(sortedSources, new Comparator() {
+ public int compare(final Object o1, final Object o2) {
+ return (((File) o1).getName().compareTo(
+ ((File) o2).getName()));
+ }
+ });
+ for (int i = 0; i < sortedSources.length; i++) {
+ PBXObjectRef fileRef = createPBXFileReference(sourceTree,
+ basePath, (File) sortedSources[i]);
+ sourceGroupChildren.add(fileRef);
+ objects.put(fileRef.getID(), fileRef.getProperties());
+ }
+
+ return sourceGroupChildren;
}
- writer.write("// 080\n");
- writer.write("// 081\n");
- writer.write("// 082\n");
- writer.write("// 083\n");
- writer.write("// 084\n");
- writer.write("// 1A0\n");
- writer.write("// 1A1\n");
- writer.write("// 1A2\n");
- writer.write("// 1A3\n");
- writer.write("// 1A4\n");
- writer.write(" 1AB674ADFE9D54B511CA2CBB = {\n");
- writer.write(" children = (\n");
- writer.write(" D2AAC0630554660B00DB518D,\n");
- writer.write(" );\n");
- writer.write(" isa = PBXGroup;\n");
- writer.write(" name = Products;\n");
- writer.write(" refType = 4;\n");
- writer.write(" sourceTree = \"<group>\";\n");
- writer.write(" };\n");
- writer.write("// 1A0\n");
- writer.write("// 1A1\n");
- writer.write("// 1A2\n");
- writer.write("// 1A3\n");
- writer.write("// 1A4\n");
- writer.write("// D20\n");
- writer.write("// D21\n");
- writer.write("// D22\n");
- writer.write("// D23\n");
- writer.write("// D24\n");
- writer.write(" D2AAC0600554660B00DB518D = {\n");
- writer.write(" buildActionMask = 2147483647;\n");
- writer.write(" files = (\n");
- writer.write(" );\n");
- writer.write(" isa = PBXHeadersBuildPhase;\n");
- writer.write(" runOnlyForDeploymentPostprocessing = 0;\n");
- writer.write(" };\n");
- writer.write(" D2AAC0610554660B00DB518D = {\n");
- writer.write(" buildActionMask = 2147483647;\n");
- writer.write(" files = (\n");
-
- //
- // build ID's
- //
- for (int i = 0; i < sortedSources.length; i++) {
- writer.write(" ");
- writer.write(sortedSources[i].getBuildID());
- writer.write(",\n");
+
+ /**
+ * Add native target configuration list.
+ * @param objects map of objects.
+ * @param projectName project name.
+ * @return build configurations for native target.
+ */
+ private PBXObjectRef addNativeTargetConfigurationList(final Map objects,
+ final String projectName) {
+
+ //
+ // Create a configuration list with
+ // two stock configurations: Debug and Release
+ //
+ List configurations = new ArrayList();
+ Map debugSettings = new HashMap();
+ debugSettings.put("COPY_PHASE_STRIP", "NO");
+ debugSettings.put("GCC_DYNAMIC_NO_PIC", "NO");
+ debugSettings.put("GCC_ENABLE_FIX_AND_CONTINUE", "YES");
+ debugSettings.put("GCC_MODEL_TUNING", "G5");
+ debugSettings.put("GCC_OPTIMIZATION_LEVEL", "0");
+ debugSettings.put("INSTALL_PATH", "$(HOME)/bin");
+ debugSettings.put("PRODUCT_NAME", projectName);
+ debugSettings.put("ZERO_LINK", "YES");
+ PBXObjectRef debugConfig = createXCBuildConfiguration("Debug",
+ debugSettings);
+ objects.put(debugConfig.getID(), debugConfig.getProperties());
+ configurations.add(debugConfig);
+
+ Map releaseSettings = new HashMap();
+ List archs = new ArrayList();
+ archs.add("ppc");
+ archs.add("i386");
+ releaseSettings.put("ARCHS", archs);
+ releaseSettings.put("GCC_GENERATE_DEBUGGING_SYMBOLS", "NO");
+ releaseSettings.put("GCC_MODEL_TUNING", "G5");
+ releaseSettings.put("INSTALL_PATH", "$(HOME)/bin");
+ releaseSettings.put("PRODUCT_NAME", projectName);
+ PBXObjectRef releaseConfig = createXCBuildConfiguration("Release",
+ releaseSettings);
+ objects.put(releaseConfig.getID(), releaseConfig.getProperties());
+ configurations.add(releaseConfig);
+
+ PBXObjectRef configurationList = createXCConfigurationList(configurations);
+ objects.put(configurationList.getID(), configurationList.getProperties());
+ return configurationList;
}
- writer.write(" );\n");
- writer.write(" isa = PBXSourcesBuildPhase;\n");
- writer.write(" runOnlyForDeploymentPostprocessing = 0;\n");
- writer.write(" };\n");
- writer.write(" D2AAC0620554660B00DB518D = {\n");
- writer.write(" buildPhases = (\n");
- writer.write(" D2AAC0600554660B00DB518D,\n");
- writer.write(" D2AAC0610554660B00DB518D,\n");
- writer.write(" );\n");
- writer.write(" buildRules = (\n");
- writer.write(" );\n");
- writer.write(" buildSettings = {\n");
- writer.write(" DYLIB_COMPATIBILITY_VERSION = 1;\n");
- writer.write(" DYLIB_CURRENT_VERSION = 1;\n");
- //
- // write preprocessor macros
- //
- if (gccConfig != null) {
- String[] options = gccConfig.getPreArguments();
- boolean hasD = false;
- for (int i = 0; i < options.length; i++) {
- if (options[i].startsWith("-D")) {
- if (!hasD) {
- writer.write(" GCC_PREPROCESSOR_DEFINITIONS = \"");
- hasD = true;
- } else {
- writer.write(" ");
- }
- writer.write(options[i].substring(2));
+
+
+
+ /**
+ * Add project configuration list.
+ * @param objects map of objects.
+ * @param baseDir base directory.
+ * @param compilerConfig compiler configuration.
+ * @return project configuration object.
+ */
+ private PBXObjectRef addProjectConfigurationList(final Map objects,
+ final String baseDir,
+ final List dependencies,
+ final CommandLineCompilerConfiguration compilerConfig,
+ final CommandLineLinkerConfiguration linkerConfig) {
+ //
+ // Create a configuration list with
+ // two stock configurations: Debug and Release
+ //
+ List configurations = new ArrayList();
+ Map debugSettings = new HashMap();
+ debugSettings.put("GCC_WARN_ABOUT_RETURN_TYPE", "YES");
+ debugSettings.put("GCC_WARN_UNUSED_VARIABLE", "YES");
+ debugSettings.put("PREBINDING", "NO");
+ debugSettings.put("SDKROOT", "/Developer/SDKs/MacOSX10.4u.sdk");
+
+
+ PBXObjectRef debugConfig = createXCBuildConfiguration("Debug", debugSettings);
+ objects.put(debugConfig.getID(), debugConfig.getProperties());
+ configurations.add(debugConfig);
+
+ Map releaseSettings = new HashMap();
+ releaseSettings.put("GCC_WARN_ABOUT_RETURN_TYPE", "YES");
+ releaseSettings.put("GCC_WARN_UNUSED_VARIABLE", "YES");
+ releaseSettings.put("PREBINDING", "NO");
+ releaseSettings.put("SDKROOT", "/Developer/SDKs/MacOSX10.4u.sdk");
+ PBXObjectRef releaseConfig =
+ createXCBuildConfiguration("Release", releaseSettings);
+ objects.put(releaseConfig.getID(), releaseConfig.getProperties());
+ configurations.add(releaseConfig);
+ PBXObjectRef configurationList = createXCConfigurationList(configurations);
+ Map projectConfigurationListProperties = configurationList.getProperties();
+ projectConfigurationListProperties.put("defaultConfigurationIsVisible", "0");
+ projectConfigurationListProperties.put("defaultConfigurationName", "Debug");
+ objects.put(configurationList.getID(), configurationList.getProperties());
+
+ //
+ // add include paths to both configurations
+ //
+ File[] includeDirs = compilerConfig.getIncludePath();
+ if (includeDirs.length > 0) {
+ ArrayList includePaths = new ArrayList();
+ Map includePathMap = new HashMap();
+ for (int i = 0; i < includeDirs.length; i++) {
+ if(!CUtil.isSystemPath(includeDirs[i])) {
+ String absPath = includeDirs[i].getAbsolutePath();
+ if (!includePathMap.containsKey(absPath)) {
+ if(absPath.startsWith("/usr/")) {
+ includePaths.add(CUtil.toUnixPath(absPath));
+ } else {
+ String relPath = CUtil.toUnixPath(
+ CUtil.getRelativePath(baseDir, includeDirs[i]));
+ includePaths.add(relPath);
+ }
+ includePathMap.put(absPath, absPath);
+ }
+ }
+ }
+ includePaths.add("${inherited)");
+ debugSettings.put("HEADER_SEARCH_PATHS", includePaths);
+ releaseSettings.put("HEADER_SEARCH_PATHS", includePaths);
+ }
+
+ //
+ // add preprocessor definitions to both configurations
+ //
+ //
+ String[] preArgs = compilerConfig.getPreArguments();
+ List defines = new ArrayList();
+ for (int i = 0; i < preArgs.length; i++) {
+ if (preArgs[i].startsWith("-D")) {
+ defines.add(preArgs[i].substring(2));
+ }
}
- }
- if (hasD) {
- writer.write("\";\n");
- }
+ if (defines.size() > 0) {
+ defines.add("$(inherited)");
+ debugSettings.put("GCC_PREPROCESSOR_DEFINITIONS", defines);
+ releaseSettings.put("GCC_PREPROCESSOR_DEFINITIONS", defines);
+ }
+
+
+ if (linkerConfig != null) {
+ Map librarySearchMap = new HashMap();
+ List librarySearchPaths = new ArrayList();
+ List otherLdFlags = new ArrayList();
+ String[] linkerArgs = linkerConfig.getEndArguments();
+ for (int i = 0; i < linkerArgs.length; i++) {
+ if (linkerArgs[i].startsWith("-L")) {
+ String libDir = linkerArgs[i].substring(2);
+ if (!librarySearchMap.containsKey(libDir)) {
+ if (!libDir.equals("/usr/lib")) {
+ librarySearchPaths.add(
+ CUtil.toUnixPath(CUtil.getRelativePath(baseDir,
+ new File(libDir))));
+ }
+ librarySearchMap.put(libDir, libDir);
+
+ }
+ } else if (linkerArgs[i].startsWith("-l")) {
+ //
+ // check if library is in dependencies list
+ //
+ String libName = linkerArgs[i].substring(2);
+ boolean found = false;
+ for(Iterator iter = dependencies.iterator();iter.hasNext();) {
+ DependencyDef dependency = (DependencyDef) iter.next();
+ if (libName.startsWith(dependency.getName())) {
+ File dependencyFile = dependency.getFile();
+ if (dependencyFile != null &&
+ new File(dependencyFile.getAbsolutePath() + ".xcodeproj").exists()) {
+ found = true;
+ break;
+ }
+ }
+ }
+ if (!found) {
+ otherLdFlags.add(linkerArgs[i]);
+ }
+ }
+ }
+
+
+ debugSettings.put("LIBRARY_SEARCH_PATHS", librarySearchPaths);
+ debugSettings.put("OTHER_LDFLAGS", otherLdFlags);
+ releaseSettings.put("LIBRARY_SEARCH_PATHS", librarySearchPaths);
+ releaseSettings.put("OTHER_LDFLAGS", otherLdFlags);
+ }
+ return configurationList;
}
- writer.write(" GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO;\n");
- writer.write(" GCC_WARN_UNKNOWN_PRAGMAS = NO;\n");
- if (gccConfig != null) {
- File[] includes = gccConfig.getIncludePath();
- if (includes.length > 0) {
- writer.write(" HEADER_SEARCH_PATHS = \"");
- for (int i = 0; i < includes.length; i++) {
- if (i > 0) {
- writer.write(" ");
- }
- writer.write(CUtil.getRelativePath(basePath, includes[i]));
+
+ /**
+ * Add native target to map of objects.
+ * @param objects map of objects.
+ * @param linkTarget description of executable or shared library.
+ * @param product product.
+ * @param projectName project name.
+ * @param sourceGroupChildren source files needed to build product.
+ * @return native target.
+ */
+ private PBXObjectRef addNativeTarget(final Map objects,
+ final TargetInfo linkTarget,
+ final PBXObjectRef product,
+ final String projectName,
+ final List sourceGroupChildren,
+ final List frameworkBuildFiles) {
+
+ PBXObjectRef buildConfigurations =
+ addNativeTargetConfigurationList(objects, projectName);
+
+ int buildActionMask = 2147483647;
+ List buildPhases = new ArrayList();
+
+ Map settings = new HashMap();
+ settings.put("ATTRIBUTES", new ArrayList());
+ List buildFiles = new ArrayList();
+ for (Iterator iter = sourceGroupChildren.iterator();
+ iter.hasNext();) {
+ PBXObjectRef sourceFile = (PBXObjectRef) iter.next();
+ PBXObjectRef buildFile = createPBXBuildFile(sourceFile, settings);
+ buildFiles.add(buildFile);
+ objects.put(buildFile.getID(), buildFile.getProperties());
}
- writer.write("\";\n");
- }
+
+
+ PBXObjectRef sourcesBuildPhase = createPBXSourcesBuildPhase(buildActionMask,
+ buildFiles, false);
+ objects.put(sourcesBuildPhase.getID(), sourcesBuildPhase.getProperties());
+ buildPhases.add(sourcesBuildPhase);
+
+
+ buildActionMask = 8;
+ PBXObjectRef frameworksBuildPhase =
+ createPBXFrameworksBuildPhase(buildActionMask,
+ frameworkBuildFiles, false);
+ objects.put(frameworksBuildPhase.getID(), frameworksBuildPhase.getProperties());
+ buildPhases.add(frameworksBuildPhase);
+
+ PBXObjectRef copyFilesBuildPhase = createPBXCopyFilesBuildPhase(8,
+ "/usr/share/man/man1", "0", new ArrayList(), true);
+ objects.put(copyFilesBuildPhase.getID(), copyFilesBuildPhase.getProperties());
+ buildPhases.add(copyFilesBuildPhase);
+
+ List buildRules = new ArrayList();
+
+ List dependencies = new ArrayList();
+
+ String productInstallPath = "$(HOME)/bin";
+
+ String productType = getProductType(linkTarget);
+
+ PBXObjectRef nativeTarget = createPBXNativeTarget(projectName,
+ buildConfigurations, buildPhases, buildRules, dependencies,
+ productInstallPath, projectName, product, productType);
+ objects.put(nativeTarget.getID(), nativeTarget.getProperties());
+
+ return nativeTarget;
}
-
-
- String[] linkerArgs = null;
- ProcessorConfiguration linkConfig = linkTarget.getConfiguration();
- if (linkConfig instanceof CommandLineLinkerConfiguration) {
- linkerArgs = ((CommandLineLinkerConfiguration) linkConfig).getPreArguments();
+
+ private int getProductTypeIndex(final TargetInfo linkTarget) {
+ String outPath = linkTarget.getOutput().getPath();
+ String outExtension = null;
+ int lastDot = outPath.lastIndexOf('.');
+ if (lastDot != -1) {
+ outExtension = outPath.substring(lastDot);
+ }
+ if (".a".equalsIgnoreCase(outExtension) || ".lib".equalsIgnoreCase(outExtension)) {
+ return 1;
+ } else if (".dylib".equalsIgnoreCase(outExtension) ||
+ ".so".equalsIgnoreCase(outExtension) ||
+ ".dll".equalsIgnoreCase(outExtension)) {
+ return 2;
+ }
+ return 0;
}
-
- writer.write(" INSTALL_PATH = /usr/local/lib;\n");
- if (linkerArgs != null) {
- boolean hasLibPath = false;
- for (int i = 0; i < linkerArgs.length; i++) {
- if (linkerArgs[i].startsWith("-L")) {
- if (!hasLibPath) {
- writer.write(" LIBRARY_SEARCH_PATHS = \"");
- hasLibPath = true;
- } else {
- writer.write(" ");
- }
- writer.write(linkerArgs[i].substring(2));
- }
+ private String getProductType(final TargetInfo linkTarget) {
+ switch(getProductTypeIndex(linkTarget)) {
+ case 1:
+ return "com.apple.product-type.library.static";
+ case 2:
+ return "com.apple.product-type.library.dynamic";
+ default:
+ return "com.apple.product-type.tool";
}
- if (hasLibPath) {
- writer.write("\";\n");
+ }
+
+ private String getFileType(final TargetInfo linkTarget) {
+ switch(getProductTypeIndex(linkTarget)) {
+ case 1:
+ return "archive.ar";
+ case 2:
+ return "compiled.mach-o.dylib";
+ default:
+ return "compiled.mach-o.executable";
}
- }
- writer.write(" LIBRARY_STYLE = DYNAMIC;\n");
- writer.write(" OTHER_CFLAGS = \"\";\n");
- writer.write(" OTHER_LDFLAGS = \"");
- if (linkerArgs != null) {
- String prepend = "";
- for (int i = 0; i < linkerArgs.length; i++) {
- if (!linkerArgs[i].startsWith("-L")) {
- writer.write(prepend);
- writer.write(linkerArgs[i]);
- prepend = " ";
- }
- }
}
- writer.write("\";\n");
- writer.write(" OTHER_REZFLAGS = \"\";\n");
- writer.write(" PRODUCT_NAME = testbsd;\n");
- writer.write(" SECTORDER_FLAGS = \"\";\n");
- writer.write(" WARNING_CFLAGS = \"-Wmost\";\n");
- writer.write(" };\n");
- writer.write(" dependencies = (\n");
- writer.write(" );\n");
- writer.write(" isa = PBXNativeTarget;\n");
-
- writer.write(" name = ");
- writer.write(outFile.getName());
- writer.write(";\n");
- writer.write(" productName = ");
- writer.write(outFile.getName());
- writer.write(";\n");
- writer.write(" productReference = D2AAC0630554660B00DB518D;\n");
-
- String productType = "com.apple.product-type.library.dynamic";
- String prefix = "lib";
- String suffix = ".dylib";
- String explicitFileType = "compiled.mach-o.dylib";
- String outType = task.getOuttype();
- if ("executable".equals(outType)) {
- productType = "com.apple.product-type.tool";
- prefix = "";
- suffix = "";
- explicitFileType = "compiled.mach-o.executable";
- } else if ("static".equals(outType)) {
- productType = "com.apple.product-type.library.static";
- suffix = ".a";
- explicitFileType = "archive.ar";
+
+
+ /**
+ * Create PBXFileReference.
+ * @param sourceTree source tree.
+ * @param baseDir base directory.
+ * @param file file.
+ * @return PBXFileReference object.
+ */
+ private static PBXObjectRef createPBXFileReference(final String sourceTree,
+ final String baseDir,
+ final File file) {
+ Map map = new HashMap();
+ map.put("isa", "PBXFileReference");
+
+ String relPath = CUtil.toUnixPath(CUtil.getRelativePath(baseDir, file));
+ map.put("path", relPath);
+ map.put("name", file.getName());
+ map.put("sourceTree", sourceTree);
+ return new PBXObjectRef(map);
+ }
+
+ /**
+ * Create PBXGroup.
+ * @param name group name.
+ * @param sourceTree source tree.
+ * @param children list of PBXFileReferences.
+ * @return group.
+ */
+ private static PBXObjectRef createPBXGroup(final String name,
+ final String sourceTree,
+ final List children) {
+ Map map = new HashMap();
+ map.put("isa", "PBXGroup");
+ map.put("name", name);
+ map.put("sourceTree", sourceTree);
+ map.put("children", children);
+ return new PBXObjectRef(map);
}
- writer.write(" productType = \"");
- writer.write(productType);
- writer.write("\";\n");
- writer.write(" };\n");
- writer.write(" D2AAC0630554660B00DB518D = {\n");
-
- writer.write(" explicitFileType = \"");
- writer.write(explicitFileType);
- writer.write("\";\n");
- writer.write(" includeInIndex = 0;\n");
- writer.write(" isa = PBXFileReference;\n");
- writer.write(" path = ");
- writer.write(outFile.getName());
- writer.write(suffix);
- writer.write(";\n");
- writer.write(" refType = 3;\n");
- writer.write(" sourceTree = BUILT_PRODUCTS_DIR;\n");
- writer.write(" };\n");
- writer.write(" };\n");
- writer.write(" rootObject = 08FB7793FE84155DC02AAC07;\n");
- writer.write(" }\n");
-
- writer.close();
- }
-
- /**
- * Gets the first recognized compiler from the
- * compilation targets.
- * @param targets compilation targets
- * @return representative (hopefully) compiler configuration
- */
- private CommandLineCompilerConfiguration
- getBaseCompilerConfiguration(Hashtable targets) {
- //
- // find first target with an GNU C++ compilation
- //
- CommandLineCompilerConfiguration compilerConfig = null;
- //
- // get the first target and assume that it is representative
- //
- Iterator targetIter = targets.values().iterator();
- while (targetIter.hasNext()) {
- TargetInfo targetInfo = (TargetInfo) targetIter.next();
- ProcessorConfiguration config = targetInfo.getConfiguration();
- String identifier = config.getIdentifier();
- //
- // for the first cl compiler
- //
- if (config instanceof CommandLineCompilerConfiguration) {
- compilerConfig = (CommandLineCompilerConfiguration) config;
- if (compilerConfig.getCompiler() instanceof GccCCompiler) {
- return compilerConfig;
+
+ /**
+ * Create PBXProject.
+ * @param buildConfigurationList build configuration list.
+ * @param mainGroup main group.
+ * @param projectDirPath project directory path.
+ * @param targets targets.
+ * @param projectRoot projectRoot directory relative to
+ * @return project.
+ */
+ private static PBXObjectRef createPBXProject(final PBXObjectRef buildConfigurationList,
+ final PBXObjectRef mainGroup,
+ final String projectDirPath,
+ final String projectRoot,
+ final List targets) {
+ Map map = new HashMap();
+ map.put("isa", "PBXProject");
+ map.put("buildConfigurationList", buildConfigurationList.getID());
+ map.put("hasScannedForEncodings", "0");
+ map.put("mainGroup", mainGroup.getID());
+ map.put("projectDirPath", projectDirPath);
+ map.put("targets", targets);
+ map.put("projectRoot", projectRoot);
+ return new PBXObjectRef(map);
+ }
+
+ /**
+ * Create XCConfigurationList.
+ * @param buildConfigurations build configurations.
+ * @return configuration list.
+ */
+ private static PBXObjectRef createXCConfigurationList(final List buildConfigurations) {
+ Map map = new HashMap();
+ map.put("isa", "XCConfigurationList");
+ map.put("buildConfigurations", buildConfigurations);
+ return new PBXObjectRef(map);
+ }
+
+
+ /**
+ * Create XCBuildConfiguration.
+ * @param name name.
+ * @param buildSettings build settings.
+ * @return build configuration.
+ */
+ private static PBXObjectRef createXCBuildConfiguration(final String name,
+ final Map buildSettings) {
+ Map map = new HashMap();
+ map.put("isa", "XCBuildConfiguration");
+ map.put("buildSettings", buildSettings);
+ map.put("name", name);
+ return new PBXObjectRef(map);
+ }
+
+ /**
+ * Create PBXNativeTarget.
+ * @param name name.
+ * @param buildConfigurationList build configuration list.
+ * @param buildPhases build phases.
+ * @param buildRules build rules.
+ * @param dependencies dependencies.
+ * @param productInstallPath product install path.
+ * @param productName product name.
+ * @param productReference file reference for product.
+ * @param productType product type.
+ * @return native target.
+ */
+ private static PBXObjectRef createPBXNativeTarget(final String name,
+ final PBXObjectRef buildConfigurationList,
+ final List buildPhases,
+ final List buildRules,
+ final List dependencies,
+ final String productInstallPath,
+ final String productName,
+ final PBXObjectRef productReference,
+ final String productType) {
+ Map map = new HashMap();
+ map.put("isa", "PBXNativeTarget");
+ map.put("buildConfigurationList", buildConfigurationList);
+ map.put("buildPhases", buildPhases);
+ map.put("buildRules", buildRules);
+ map.put("dependencies", dependencies);
+ map.put("name", name);
+ map.put("productInstallPath", productInstallPath);
+ map.put("productName", productName);
+ map.put("productReference", productReference);
+ map.put("productType", productType);
+ return new PBXObjectRef(map);
+ }
+
+ /**
+ * Create PBXSourcesBuildPhase.
+ * @param buildActionMask build action mask.
+ * @param files source files.
+ * @param runOnly if true, phase should only be run on deployment.
+ * @return PBXSourcesBuildPhase.
+ */
+ private static PBXObjectRef createPBXSourcesBuildPhase(int buildActionMask,
+ List files,
+ boolean runOnly) {
+ Map map = new HashMap();
+ map.put("buildActionMask",
+ String.valueOf(buildActionMask));
+ map.put("files", files);
+ map.put("isa", "PBXSourcesBuildPhase");
+ map.put("runOnlyForDeploymentPostprocessing", toString(runOnly));
+ return new PBXObjectRef(map);
+ }
+
+ /**
+ * Create PBXBuildFile.
+ * @param fileRef source file.
+ * @param settings build settings.
+ * @return PBXBuildFile.
+ */
+ private static PBXObjectRef createPBXBuildFile(PBXObjectRef fileRef,
+ Map settings) {
+ Map map = new HashMap();
+ map.put("fileRef", fileRef);
+ map.put("isa", "PBXBuildFile");
+ if (settings != null) {
+ map.put("settings", settings);
}
- }
+ return new PBXObjectRef(map);
}
- return null;
- }
- /**
- * Source file with 96-bit source and build ID's.
- */
- private static final class SourceEntry {
/**
- * Source file.
+ * Create PBXFrameworksBuildPhase.
+ * @param buildActionMask build action mask.
+ * @param files files.
+ * @param runOnly if true, phase should only be run on deployment.
+ * @return PBXFrameworkBuildPhase.
*/
- private final File file;
+ private static PBXObjectRef createPBXFrameworksBuildPhase(
+ final int buildActionMask,
+ final List files,
+ final boolean runOnly) {
+ Map map = new HashMap();
+ map.put("isa", "PBXFrameworksBuildPhase");
+ map.put("buildActionMask", NumberFormat.getIntegerInstance(Locale.US).format(buildActionMask));
+ map.put("files", files);
+ map.put("runOnlyForDeploymentPostprocessing", toString(runOnly));
+ return new PBXObjectRef(map);
+ }
/**
- * Source ID.
+ * Create a build phase that copies files to a destination.
+ * @param buildActionMask build action mask.
+ * @param dstPath destination path.
+ * @param dstSubfolderSpec subfolder spec.
+ * @param files files.
+ * @param runOnly if true, phase should only be run on deployment.
+ * @return PBXCopyFileBuildPhase.
*/
- private final String sourceID;
+ private static PBXObjectRef createPBXCopyFilesBuildPhase(
+ final int buildActionMask,
+ final String dstPath,
+ final String dstSubfolderSpec,
+ final List files,
+ final boolean runOnly) {
+ Map map = new HashMap();
+ map.put("isa", "PBXCopyFilesBuildPhase");
+ map.put("buildActionMask", NumberFormat.getIntegerInstance(Locale.US).format(buildActionMask));
+ map.put("dstPath", dstPath);
+ map.put("dstSubfolderSpec", dstSubfolderSpec);
+ map.put("files", files);
+ map.put("runOnlyForDeploymentPostprocessing", toString(runOnly));
+ return new PBXObjectRef(map);
+ }
+
/**
- * Build step ID.
+ * Create a proxy for a file in a different project.
+ * @param containerPortal XcodeProject containing file.
+ * @param proxyType proxy type.
+ * @return PBXContainerItemProxy.
*/
- private final String buildID;
+ private static PBXObjectRef createPBXContainerItemProxy(
+ final PBXObjectRef containerPortal,
+ final int proxyType,
+ final String remoteInfo) {
+ Map map = new HashMap();
+ map.put("isa", "PBXContainerItemProxy");
+ map.put("containerPortal", containerPortal);
+ map.put("proxyType", NumberFormat.getIntegerInstance(Locale.US).format(proxyType));
+ map.put("remoteInfo", remoteInfo);
+ return new PBXObjectRef(map);
+ }
+
/**
- * Constructor.
- * @param fileArg source file
- * @param sourceIDArg source ID
- * @param buildIDArg build step ID
+ * Create a proxy for a file in a different project.
+ * @param remoteRef PBXContainerItemProxy for reference.
+ * @param dependency dependency.
+ * @return PBXContainerItemProxy.
*/
- public SourceEntry(final File fileArg,
- final String sourceIDArg,
- final String buildIDArg) {
- file = fileArg;
- sourceID = sourceIDArg;
- buildID = buildIDArg;
+ private static PBXObjectRef createPBXReferenceProxy(
+ final PBXObjectRef remoteRef,
+ final DependencyDef dependency) {
+ Map map = new HashMap();
+ map.put("isa", "PBXReferenceProxy");
+ String fileType = "compiled.mach-o.dylib";
+ map.put("fileType", fileType);
+ map.put("remoteRef", remoteRef);
+ map.put("path", dependency.getFile().getName() + ".dylib");
+ map.put("sourceTree", "BUILT_PRODUCTS_DIR");
+ return new PBXObjectRef(map);
}
/**
- * Get source file.
- * @return source file
+ * Method returns "1" for true, "0" for false.
+ * @param b boolean value.
+ * @return "1" for true, "0" for false.
*/
- public File getFile() {
- return file;
+ private static String toString(boolean b) {
+ if (b) {
+ return "1";
+ } else {
+ return "0";
+ }
}
/**
- * Get source ID.
- * @return source ID
+ * Represents a property map with an 96 bit identity.
+ * When placed in a property list, this object will
+ * output the string representation of the identity
+ * which XCode uses to find the corresponding property
+ * bag in the "objects" property of the top-level property list.
*/
- public String getSourceID() {
- return sourceID;
+ private static final class PBXObjectRef {
+ /**
+ * Identifier.
+ */
+ private final String id;
+ /**
+ * Properties.
+ */
+ private final Map properties;
+ /**
+ * Next available identifier.
+ */
+ private static int nextID = 0;
+
+ /**
+ * Create reference.
+ * @param props properties.
+ */
+ public PBXObjectRef(final Map props) {
+ if (props == null) {
+ throw new NullPointerException("props");
+ }
+ StringBuffer buf = new StringBuffer("000000000000000000000000");
+ String idStr = Integer.toHexString(nextID++);
+ buf.replace(buf.length() - idStr.length(), buf.length(), idStr);
+ id = buf.toString();
+ properties = props;
+ }
+
+ /**
+ * Get object identifier.
+ * @return identifier.
+ */
+ public String toString() {
+ return id;
+ }
+
+ /**
+ * Get object identifier.
+ * @return object identifier.
+ */
+ public String getID() {
+ return id;
+ }
+
+ /**
+ * Get properties.
+ * @return properties.
+ */
+ public Map getProperties() {
+ return properties;
+ }
}
/**
- * Get build step ID.
- * @return build step ID
+ * Gets the first recognized compiler from the
+ * compilation targets.
+ *
+ * @param targets compilation targets
+ * @return representative (hopefully) compiler configuration
*/
- public String getBuildID() {
- return buildID;
+ private CommandLineCompilerConfiguration
+ getBaseCompilerConfiguration(Hashtable targets) {
+ //
+ // find first target with an GNU C++ compilation
+ //
+ CommandLineCompilerConfiguration compilerConfig;
+ //
+ // get the first target and assume that it is representative
+ //
+ Iterator targetIter = targets.values().iterator();
+ while (targetIter.hasNext()) {
+ TargetInfo targetInfo = (TargetInfo) targetIter.next();
+ ProcessorConfiguration config = targetInfo.getConfiguration();
+ //
+ // for the first cl compiler
+ //
+ if (config instanceof CommandLineCompilerConfiguration) {
+ compilerConfig = (CommandLineCompilerConfiguration) config;
+ if (compilerConfig.getCompiler() instanceof GccCCompiler) {
+ return compilerConfig;
+ }
+ }
+ }
+ return null;
}
- }
+
}