diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/plugin.xml b/build/org.eclipse.cdt.managedbuilder.core.tests/plugin.xml
index 561f09a12cd..251a90103f3 100644
--- a/build/org.eclipse.cdt.managedbuilder.core.tests/plugin.xml
+++ b/build/org.eclipse.cdt.managedbuilder.core.tests/plugin.xml
@@ -3956,4 +3956,262 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/resources/test30Projects/CDTFortranTest1/CDTFortranTest1.zip b/build/org.eclipse.cdt.managedbuilder.core.tests/resources/test30Projects/CDTFortranTest1/CDTFortranTest1.zip
new file mode 100644
index 00000000000..e863ae7b986
Binary files /dev/null and b/build/org.eclipse.cdt.managedbuilder.core.tests/resources/test30Projects/CDTFortranTest1/CDTFortranTest1.zip differ
diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/DefaultFortranDependencyCalculator.java b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/DefaultFortranDependencyCalculator.java
new file mode 100644
index 00000000000..6132894cf86
--- /dev/null
+++ b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/DefaultFortranDependencyCalculator.java
@@ -0,0 +1,260 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.managedbuilder.core.tests;
+
+import java.io.*;
+import java.lang.String;
+import java.util.ArrayList;
+
+import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
+import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo;
+import org.eclipse.cdt.managedbuilder.core.IManagedOutputNameProvider;
+import org.eclipse.cdt.managedbuilder.core.IConfiguration;
+import org.eclipse.cdt.managedbuilder.core.ITool;
+import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+
+/**
+ * This class implements the Dependency Manager and Output Name Provider interfaces
+ * for a very "quick & dirty" ifort tool-chain on Win32
+ */
+public class DefaultFortranDependencyCalculator implements IManagedDependencyGenerator,
+ IManagedOutputNameProvider
+{
+ public static final String MODULE_EXTENSION = "mod"; //$NON-NLS-1$
+
+ /*
+ * Return a list of the names of all modules used by a file
+ */
+ private String[] findUsedModuleNames(File file) {
+ ArrayList names = new ArrayList();
+ try {
+ InputStream in = new BufferedInputStream(new FileInputStream(file));
+ Reader r = new BufferedReader(new InputStreamReader(in));
+ StreamTokenizer st = new StreamTokenizer(r);
+ st.commentChar('!');
+ st.eolIsSignificant(false);
+ st.slashSlashComments(false);
+ st.slashStarComments(false);
+ st.wordChars('_', '_');
+
+ while (st.nextToken() != StreamTokenizer.TT_EOF) {
+ if (st.ttype == StreamTokenizer.TT_WORD) {
+ if (st.sval.equalsIgnoreCase("use")) {
+ st.nextToken();
+ if (st.ttype == StreamTokenizer.TT_WORD) {
+ names.add(st.sval);
+ } else {
+ st.pushBack();
+ }
+ }
+ }
+ }
+ }
+ catch (Exception e) {
+ return new String[0];
+ }
+ return (String[]) names.toArray(new String[names.size()]);
+ }
+
+ /*
+ * Return a list of the names of all modules defined in a file
+ */
+ private String[] findModuleNames(File file) {
+ ArrayList names = new ArrayList();
+ try {
+ InputStream in = new BufferedInputStream(new FileInputStream(file));
+ Reader r = new BufferedReader(new InputStreamReader(in));
+ StreamTokenizer st = new StreamTokenizer(r);
+ st.commentChar('!');
+ st.eolIsSignificant(false);
+ st.slashSlashComments(false);
+ st.slashStarComments(false);
+ st.wordChars('_', '_');
+
+ while (st.nextToken() != StreamTokenizer.TT_EOF) {
+ if (st.ttype == StreamTokenizer.TT_WORD) {
+ if (st.sval.equalsIgnoreCase("module")) {
+ st.nextToken();
+ if (st.ttype == StreamTokenizer.TT_WORD) {
+ names.add(st.sval);
+ } else {
+ st.pushBack();
+ }
+ }
+ }
+ }
+ }
+ catch (Exception e) {
+ return new String[0];
+ }
+ return (String[]) names.toArray(new String[names.size()]);
+ }
+
+ /*
+ * Returns true if the resource is a Fortran source file
+ */
+ private boolean isFortranFile(ITool tool, IResource resource) {
+ // TODO: Get the file extensions from the tool's primary input type
+ String ext = resource.getFileExtension();
+ if (ext != null) {
+ if (ext.equalsIgnoreCase("f")) return true;
+ if (ext.equalsIgnoreCase("for")) return true;
+ if (ext.equalsIgnoreCase("f90")) return true;
+ }
+ return false;
+ }
+
+ /*
+ * Given a set of the module names used by a source file, and a set of resources to search, determine
+ * if any of the source files implements the module names.
+ */
+ private IResource[] FindModulesInResources(IProject project, ITool tool, IResource resource, IResource[] resourcesToSearch,
+ String topBuildDir, String[] usedNames) {
+ ArrayList modRes = new ArrayList();
+ for (int ir = 0; ir < resourcesToSearch.length; ir++) {
+ if (resourcesToSearch[ir].equals(resource)) continue;
+ if (resourcesToSearch[ir].getType() == IResource.FILE) {
+ File projectFile = resourcesToSearch[ir].getLocation().toFile();
+ if (!isFortranFile(tool, resourcesToSearch[ir])) continue;
+ String[] modules = findModuleNames(projectFile);
+ if (modules != null) {
+ for (int iu = 0; iu < usedNames.length; iu++) {
+ boolean foundDependency = false;
+ for (int im = 0; im < modules.length; im++) {
+ if (usedNames[iu].equalsIgnoreCase(modules[im])) {
+ // Get the path to the module file that will be created by the build. By default, ifort appears
+ // to generate .mod files in the directory from which the compiler is run. For MBS, this
+ // is the top-level build directory.
+ // TODO: Support the /module:path option and use that in determining the path of the module file
+ IPath modName = Path.fromOSString(topBuildDir + Path.SEPARATOR + modules[im] + "." + MODULE_EXTENSION);
+ modRes.add(project.getFile(modName));
+ modRes.add(resourcesToSearch[ir]);
+ foundDependency = true;
+ break;
+ }
+ }
+ if (foundDependency) break;
+ }
+ }
+ } else if (resourcesToSearch[ir].getType() == IResource.FOLDER) {
+ try {
+ IResource[] modFound = FindModulesInResources(project, tool, resource, ((IFolder)resourcesToSearch[ir]).members(),
+ topBuildDir, usedNames);
+ if (modFound != null) {
+ for (int i=0; i 0) {
+ // Get the names of modules created by this source file
+ String[] modules = findModuleNames(primaryInputNames[0].toFile());
+ // Add any generated modules
+ if (modules != null) {
+ for (int i = 0; i < modules.length; i++) {
+ // Return the path to the module file that will be created by the build. By default, ifort appears
+ // to generate .mod files in the directory from which the compiler is run. For MBS, this
+ // is the top-level build directory.
+ // TODO: Support the /module:path option and use that in determining the path of the module file
+ // TODO: The nameProvider documentation should note that the returned path is relative to the top-level
+ // build directory. HOWEVER, if only a file name is returned, MBS will automatically add on the
+ // directory path relative to the top-level build directory. The relative path comes from the source
+ // file location. In order to specify that this output file is always in the top-level build
+ // directory, regardless of the source file directory structure, return "./path".
+ IPath modName = Path.fromOSString("." + Path.SEPARATOR + modules[i] + "." + MODULE_EXTENSION);
+ outs.add(modName);
+ }
+ }
+ }
+ return (IPath[]) outs.toArray(new IPath[outs.size()]);
+ }
+
+}
diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ManagedProject30MakefileTests.java b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ManagedProject30MakefileTests.java
index c0b65d7972f..4e3c1a51aab 100644
--- a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ManagedProject30MakefileTests.java
+++ b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ManagedProject30MakefileTests.java
@@ -77,6 +77,7 @@ public class ManagedProject30MakefileTests extends TestCase {
suite.addTest(new ManagedProject30MakefileTests("test30_1"));
suite.addTest(new ManagedProject30MakefileTests("test30_2"));
suite.addTest(new ManagedProject30MakefileTests("testTopTC"));
+ suite.addTest(new ManagedProject30MakefileTests("CDTFortranTest1"));
return suite;
}
@@ -542,4 +543,17 @@ public class ManagedProject30MakefileTests extends TestCase {
}
buildDegenerativeProjects(projects, null);
}
+
+ /* (non-Javadoc)
+ * tests external dependency calculation using Fortran modules
+ */
+ public void CDTFortranTest1(){
+ IPath[] makefiles = {
+ Path.fromOSString("makefile"),
+ Path.fromOSString("objects.mk"),
+ Path.fromOSString("sources.mk"),
+ Path.fromOSString("subdir.mk")};
+ IProject[] projects = createProjects("CDTFortranTest1", null, null, true);
+ buildProjects(projects, makefiles);
+ }
}