diff options
author | Mark Donszelmann <Mark.Donszelmann@gmail.com> | 2009-11-06 15:30:37 +0100 |
---|---|---|
committer | Mark Donszelmann <Mark.Donszelmann@gmail.com> | 2009-11-06 15:30:37 +0100 |
commit | fa6eb468613603bfa2571f2e456468878bfe0b95 (patch) | |
tree | aab6fbeae127acd5b49b88cb0be70bce1d433fa9 /src/main/java/net/sf/antcontrib/cpptasks/apple/XcodeProjectWriter.java | |
parent | 7ea719da26b29976e7227b4846953d24ced709d8 (diff) | |
parent | 683d490074d93baa8a47db7ec43b7bd31145a12a (diff) | |
download | cpptasks-parallel-fa6eb468613603bfa2571f2e456468878bfe0b95.tar.gz cpptasks-parallel-fa6eb468613603bfa2571f2e456468878bfe0b95.tar.bz2 cpptasks-parallel-fa6eb468613603bfa2571f2e456468878bfe0b95.tar.xz cpptasks-parallel-fa6eb468613603bfa2571f2e456468878bfe0b95.zip |
Merged with cpptasks-1.0b5
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.java | 1430 |
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; } - } + } |