diff mkoctfile.cc.in @ 8091:4e7527a7b3f9

mkoctfile.cc.in, octave-config.cc.in, octave-bug.cc.in: new files
author Michael Goffioul
date Mon, 08 Sep 2008 15:34:05 -0400
parents
children 6a292b0fa88c
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mkoctfile.cc.in	Mon Sep 08 15:34:05 2008 -0400
@@ -0,0 +1,702 @@
+#if defined (HAVE_CONFIG_H)
+#include <config.h>
+#endif
+
+#include <string>
+#include <map>
+#include <list>
+#include <algorithm>
+#include <iostream>
+#include <fstream>
+#include <vector>
+#include <cstdlib>
+
+#if defined (__WIN32__) && ! defined (_POSIX_VERSION)
+#include <windows.h>
+#ifdef _MSC_VER
+#define popen _popen
+#define pclose _pclose
+#endif
+#endif
+
+using namespace std;
+
+static bool initialized = false;
+static map<string,string> vars;
+
+static string OCTAVE_VERSION = %OCTAVE_CONF_VERSION%;
+
+static std::string substitute_prefix(const std::string& s, const std::string& prefix, const std::string& new_prefix)
+{
+	std::string retval = s;
+
+	if (!prefix.empty() && new_prefix != prefix)
+	{
+		int len = prefix.length();
+		if (retval.find(prefix) == 0)
+			retval.replace(0, len, new_prefix);
+	}
+
+#if defined (__WIN32__) && ! defined (_POSIX_VERSION)
+	std::replace(retval.begin(), retval.end(), '/', '\\');
+#endif
+
+	return retval;
+}
+
+static string get_line(FILE *fp)
+{
+	static vector<char> buf(100);
+	int idx = 0;
+	char c;
+
+	while (1)
+	{
+		c = (char)fgetc(fp);
+		if (c == '\n' || c == EOF)
+			break;
+		if (buf.size() <= idx)
+			buf.resize(buf.size() + 100);
+		buf[idx++] = c;
+	}
+	if (idx == 0)
+		return string("");
+	else
+		return string(&buf[0], idx);
+}
+
+
+static string get_variable(const char *name, const string& defval)
+{
+	const char *val = getenv(name);
+	if (val == NULL || val[0] == '\0')
+		return defval;
+	else
+		return string(val);
+}
+
+static string quote_path(const string& s)
+{
+	if (s.find(' ') != string::npos && s[0] != '"')
+		return "\"" + s + "\"";
+	return s;
+}
+
+static void initialize(void)
+{
+	if (initialized)
+		return;
+
+	initialized = true;
+
+	vars["OCTAVE_HOME"] = get_variable("OCTAVE_HOME", "");
+
+#if defined (__WIN32__) && ! defined (_POSIX_VERSION)
+	int n = 1024;
+
+	std::string bin_dir (n, '\0');
+
+	while (true)
+	{
+		int status = GetModuleFileName (0, &bin_dir[0], n);
+
+		if (status < n)
+		{
+			bin_dir.resize (status);
+			break;
+		}
+		else
+		{
+			n *= 2;
+			bin_dir.resize (n);
+		}
+	}
+
+	if (! bin_dir.empty ())
+	{
+		size_t pos = bin_dir.rfind ("\\bin\\");
+
+		if (pos != string::npos)
+			vars["OCTAVE_HOME"] = bin_dir.substr (0, pos);
+	}
+#endif
+	
+	vars["SED"] = get_variable("SED", %OCTAVE_CONF_SED%);
+
+	vars["OCTAVE_PREFIX"] = %OCTAVE_CONF_PREFIX%;
+
+	std::string DEFAULT_OCTINCLUDEDIR = %OCTAVE_CONF_OCTINCLUDEDIR%;
+	std::string DEFAULT_INCLUDEDIR = %OCTAVE_CONF_INCLUDEDIR%;
+	std::string DEFAULT_LIBDIR = %OCTAVE_CONF_LIBDIR%;
+	std::string DEFAULT_OCTLIBDIR = %OCTAVE_CONF_OCTLIBDIR%;
+
+	if (! vars["OCTAVE_HOME"].empty())
+	{
+		DEFAULT_OCTINCLUDEDIR = substitute_prefix(DEFAULT_OCTINCLUDEDIR, vars["OCTAVE_PREFIX"], vars["OCTAVE_HOME"]);
+		DEFAULT_INCLUDEDIR = substitute_prefix(DEFAULT_INCLUDEDIR, vars["OCTAVE_PREFIX"], vars["OCTAVE_HOME"]);
+		DEFAULT_LIBDIR = substitute_prefix(DEFAULT_LIBDIR, vars["OCTAVE_PREFIX"], vars["OCTAVE_HOME"]);
+		DEFAULT_OCTLIBDIR = substitute_prefix(DEFAULT_OCTLIBDIR, vars["OCTAVE_PREFIX"], vars["OCTAVE_HOME"]);
+	}
+
+	vars["OCTINCLUDEDIR"] = get_variable("OCTINCLUDEDIR", DEFAULT_OCTINCLUDEDIR);
+	vars["INCLUDEDIR"] = get_variable("INCLUDEDIR", DEFAULT_INCLUDEDIR);
+	vars["LIBDIR"] = get_variable("LIBDIR", DEFAULT_LIBDIR);
+	vars["OCTLIBDIR"] = get_variable("OCTLIBDIR", DEFAULT_OCTLIBDIR);
+
+#if defined (__WIN32__) && ! defined (_POSIX_VERSION)
+	std::string DEFAULT_INCFLAGS = "-I" + quote_path(vars["OCTINCLUDEDIR"]) + " -I" + quote_path(vars["OCTINCLUDEDIR"] + "\\octave");
+#else
+	std::string DEFAULT_INCFLAGS = "-I" + quote_path(vars["OCTINCLUDEDIR"]) + " -I" + quote_path(vars["OCTINCLUDEDIR"] + "/octave");
+#endif
+	if (vars["INCLUDEDIR"] != "/usr/include")
+		DEFAULT_INCFLAGS += " -I" + quote_path(vars["INCLUDEDIR"]);
+
+	std::string DEFAULT_LFLAGS = "-L" + quote_path(vars["OCTLIBDIR"]);
+	if (vars["LIBDIR"] != "/usr/lib")
+		DEFAULT_LFLAGS += " -L" + quote_path(vars["LIBDIR"]);
+
+	vars["CPPFLAGS"] = get_variable("CPPFLAGS", %OCTAVE_CONF_CPPFLAGS%);
+	vars["INCFLAGS"] = get_variable("INCFLAGS", DEFAULT_INCFLAGS);
+	vars["F2C"] = get_variable("F2C", %OCTAVE_CONF_F2C%);
+	vars["F2CFLAGS"] = get_variable("F2CFLAGS", %OCTAVE_CONF_F2CFLAGS%);
+	vars["F77"] = get_variable("F77", %OCTAVE_CONF_F77%);
+	vars["FFLAGS"] = get_variable("FFLAGS", %OCTAVE_CONF_FFLAGS%);
+	vars["FPICFLAG"] = get_variable("FPICFLAG", %OCTAVE_CONF_FPICFLAG%);
+	vars["CC"] = get_variable("CC", %OCTAVE_CONF_CC%);
+	vars["CFLAGS"] = get_variable("CFLAGS", %OCTAVE_CONF_CFLAGS%);
+	vars["CPICFLAG"] = get_variable("CPICFLAG", %OCTAVE_CONF_CPICFLAG%);
+	vars["CXX"] = get_variable("CXX", %OCTAVE_CONF_CXX%);
+	vars["CXXFLAGS"] = get_variable("CXXFLAGS", %OCTAVE_CONF_CXXFLAGS%);
+	vars["CXXPICFLAG"] = get_variable("CXXPICFLAG", %OCTAVE_CONF_CXXPICFLAG%);
+	vars["XTRA_CFLAGS"] = get_variable("XTRA_CFLAGS", %OCTAVE_CONF_XTRA_CFLAGS%);
+	vars["XTRA_CXXFLAGS"] = get_variable("XTRA_CXXFLAGS", %OCTAVE_CONF_XTRA_CXXFLAGS%);
+
+	vars["DEPEND_FLAGS"] = get_variable("DEPEND_FLAGS", %OCTAVE_CONF_DEPEND_FLAGS%);
+	vars["DEPEND_EXTRA_SED_PATTERN"] = get_variable("DEPEND_EXTRA_SED_PATTERN", %OCTAVE_CONF_DEPEND_EXTRA_SED_PATTERN%);
+
+	vars["DL_LD"] = get_variable("DL_LD", %OCTAVE_CONF_DL_LD%);
+	vars["DL_LDFLAGS"] = get_variable("DL_LDFLAGS", %OCTAVE_CONF_MKOCTFILE_DL_LDFLAGS%);
+
+	vars["RLD_FLAG"] = get_variable("RLD_FLAG", %OCTAVE_CONF_RLD_FLAG%);
+	vars["RDYNAMIC_FLAG"] = get_variable("RDYNAMIC_FLAG", %OCTAVE_CONF_RDYNAMIC_FLAG%);
+	vars["LIBOCTAVE"] = "-loctave";
+	vars["LIBOCTINTERP"] = "-loctinterp";
+	vars["LIBREADLINE"] = "-lreadline";
+	vars["LIBCRUFT"] = "-lcruft";
+	vars["BLAS_LIBS"] = get_variable("BLAS_LIBS", %OCTAVE_CONF_BLAS_LIBS%);
+	vars["FFTW_LIBS"] = get_variable("FFTW_LIBS", %OCTAVE_CONF_FFTW_LIBS%);
+	vars["LIBS"] = get_variable("LIBS", %OCTAVE_CONF_LIBS%);
+	vars["FLIBS"] = get_variable("FLIBS", %OCTAVE_CONF_FLIBS%);
+	vars["LD_CXX"] = get_variable("LD_CXX", %OCTAVE_CONF_LD_CXX%);
+	vars["LDFLAGS"] = get_variable("LDFLAGS", %OCTAVE_CONF_LDFLAGS%);
+	vars["LD_STATIC_FLAG"] = get_variable("LD_STATIC_FLAG", %OCTAVE_CONF_LD_STATIC_FLAG%);
+	vars["LFLAGS"] = get_variable("LFLAGS", DEFAULT_LFLAGS);
+
+	vars["ALL_FFLAGS"] = vars["FFLAGS"];
+
+	vars["ALL_CFLAGS"] = vars["INCFLAGS"] + " " + vars["XTRA_CFLAGS"] + " " + vars["CFLAGS"];
+
+	vars["ALL_CXXFLAGS"] = vars["INCFLAGS"] + " " + vars["XTRA_CXXFLAGS"] + " " + vars["CXXFLAGS"];
+
+	vars["ALL_LDFLAGS"] = vars["LD_STATIC_FLAG"] + " " + vars["CPICFLAG"] + " " + vars["LDFLAGS"];
+
+	vars["OCTAVE_LIBS"] = vars["LIBOCTINTERP"] + " " + vars["LIBOCTAVE"] + " " + vars["SPECIAL_MATH_LIB"] + " " + vars["LIBCRUFT"];
+}
+
+static string usage_msg = "usage: mkoctfile [options] file ...";
+static string version_msg = "mkoctfile, version " + OCTAVE_VERSION;
+static bool debug = false;
+static string help_msg =
+"\n"
+"Options:\n"
+"\n"
+"  -h, -?, --help          Print this message.\n"
+"\n"
+"  -IDIR                   Add -IDIR to compile commands.\n"
+"\n"
+"  -idirafter DIR          Add -idirafter DIR to compile commands.\n"
+"\n"
+"  -DDEF                   Add -DDEF to compile commands.\n"
+"\n"
+"  -lLIB                   Add library LIB to link command.\n"
+"\n"
+"  -LDIR                   Add -LDIR to link command.\n"
+"\n"
+"  -M, --depend            Generate dependency files (.d) for C and C++\n"
+"                          source files.\n"
+"\n"
+"  -RDIR                   Add -RDIR to link command.\n"
+"\n"
+"  -Wl,...                 Pass flags though the linker like -Wl,-rpath=...\n"
+"\n"
+"  -W...                   Pass flags though the compiler like -Wa,OPTION.\n"
+"\n"
+"  -c, --compile           Compile, but do not link.\n"
+"\n"
+"  -o FILE, --output FILE  Output file name.  Default extension is .oct\n"
+"                          (or .mex if --mex is specified) unless linking\n"
+"                          a stand-alone executable.\n"
+"\n"
+"  -g                      Enable debugging options for compilers.\n"
+"\n"
+"  -p VAR, --print VAR     Print configuration variable VAR.  Recognized\n"
+"                          variables are:\n"
+"\n"
+"			    ALL_CFLAGS                FFTW_LIBS     \n"
+"			    ALL_CXXFLAGS              FLIBS       \n"
+"			    ALL_FFLAGS                FPICFLAG      \n"
+"			    ALL_LDFLAGS               INCFLAGS      \n"
+"			    BLAS_LIBS                 LDFLAGS             \n"
+"			    CC                        LD_CXX              \n"
+"			    CFLAGS                    LD_STATIC_FLAG\n"
+"			    CPICFLAG                  LFLAGS              \n"
+"			    CPPFLAGS                  LIBCRUFT      \n"
+"			    CXX                       LIBOCTAVE     \n"
+"			    CXXFLAGS                  LIBOCTINTERP  \n"
+"			    CXXPICFLAG                LIBREADLINE   \n"
+"			    DEPEND_EXTRA_SED_PATTERN  LIBS        \n"
+"			    DEPEND_FLAGS              OCTAVE_LIBS   \n"
+"			    DL_LD                     RDYNAMIC_FLAG \n"
+"			    DL_LDFLAGS                RLD_FLAG      \n"
+"			    F2C                       SED         \n"
+"			    F2CFLAGS                  XTRA_CFLAGS   \n"
+"			    F77                       XTRA_CXXFLAGS \n"
+"			    FFLAGS\n"
+"\n"
+"  --link-stand-alone      Link a stand-alone executable file.\n"
+"\n"
+"  --mex                   Assume we are creating a MEX file.  Set the\n"
+"                          default output extension to \".mex\".\n"
+"\n"
+"  -s, --strip             Strip output file.\n"
+"\n"
+"  -v, --verbose           Echo commands as they are executed.\n"
+"\n"
+"  FILE                    Compile or link FILE.  Recognized file types are:\n"
+"\n"
+"                            .c    C source\n"
+"                            .cc   C++ source\n"
+"                            .C    C++ source\n"
+"                            .cpp  C++ source\n"
+"                            .f    Fortran source (fixed form)\n"
+"                            .F    Fortran source (fixed form)\n"
+"                            .f90  Fortran source (free form)\n"
+"                            .F90  Fortran source (free form)\n"
+"                            .o    object file\n"
+"                            .a    library file\n"
+#ifdef _MSC_VER
+"                            .lib  library file\n"
+#endif
+"\n";
+
+static string basename(const string& s, bool strip_path = false)
+{
+	size_t pos = s.rfind('.');
+	string retval;
+
+	if (pos == string::npos)
+		retval = s;
+	else
+		retval = s.substr(0, pos);
+	if (strip_path)
+	{
+		size_t p1 = retval.rfind('/'), p2 = retval.rfind('\\');
+		pos = (p1 != string::npos && p2 != string::npos ? max(p1, p2) : (p2 != string::npos ? p2 : p1));
+		if (pos != string::npos)
+			retval = retval.substr(0, pos);
+	}
+	return retval;
+}
+
+inline bool starts_with(const string& s, const string& prefix)
+{
+	return (s.length() >= prefix.length() && s.find(prefix) == 0);
+}
+
+inline bool ends_with(const string& s, const string& suffix)
+{
+	return (s.length() >= suffix.length() && s.rfind(suffix) == s.length()-suffix.length());
+}
+
+static int run_command(const string& cmd)
+{
+	if (debug)
+		cout << cmd << endl;
+	return system(cmd.c_str());
+}
+
+int main(int argc, char **argv)
+{
+	initialize();
+
+	string objfiles, libfiles, octfile, outputfile, incflags, defs, ldflags, pass_on_options, output_ext, file, output_option, cmd;
+	bool strip, no_oct_file_strip_on_this_platform, link, link_stand_alone, depend, compile;
+	list<string> cfiles, ccfiles, f77files;
+	int result = 0;
+
+	//cfiles = "";
+	//ccfiles = "";
+	//f77files = "";
+	objfiles = "";
+	libfiles = "";
+	octfile = "";
+	outputfile = "";
+	incflags = "";
+	defs = "";
+	ldflags = "";
+	pass_on_options = "";
+	strip = false;
+	no_oct_file_strip_on_this_platform = %NO_OCT_FILE_STRIP%;
+	link = true;
+	link_stand_alone = false;
+	output_ext = ".oct";
+	depend = false;
+	compile = true;
+
+	if (argc == 1)
+	{
+		cout << usage_msg << endl;
+		return 1;
+	}
+
+	if (argc == 2 && (!strcmp(argv[1], "-v") || !strcmp(argv[1], "--version")))
+	{
+		cout << version_msg << endl;
+		return 0;
+	}
+
+	for (int i=1; i<argc; i++)
+	{
+		string arg = argv[i];
+		size_t len = arg.length();
+
+		if (ends_with(arg, ".c"))
+		{
+			file = arg;
+			cfiles.push_back(file);
+		}
+		else if (ends_with(arg, ".cc") || ends_with(arg, ".C") || ends_with(arg, ".cpp"))
+		{
+			file = arg;
+			ccfiles.push_back(file);
+		}
+		else if (ends_with(arg, ".f") || ends_with(arg, ".F") ||
+			 ends_with(arg, "f90") || ends_with(arg, ".F90"))
+		{
+			file = arg;
+			f77files.push_back(file);
+		}
+		else if (ends_with(arg, ".o") || ends_with(arg, ".obj"))
+		{
+			file = arg;
+			objfiles += (" " + quote_path(arg));
+		}
+		else if (ends_with(arg, ".lib") || ends_with(arg, ".a"))
+		{
+			file = arg;
+			libfiles += (" " + quote_path(arg));
+		}
+		else if (arg == "-d" || arg == "--debug" || arg == "-v" || arg == "--verbose")
+		{
+			debug = true;
+			if (vars["CC"] == "cc-msvc")
+				vars["CC"] += " -d";
+			if (vars["CXX"] == "cc-msvc")
+				vars["CXX"] += " -d";
+			if (vars["DL_LD"] == "cc-msvc")
+				vars["DL_LD"] += " -d";
+		}
+		else if (arg == "-h" || arg == "-?" || arg == "--help")
+		{
+			cout << usage_msg << endl;
+			cout << help_msg << endl;
+			return 0;
+		}
+		else if (starts_with(arg, "-I"))
+		{
+			incflags += (" " + quote_path(arg));
+		}
+		else if (arg == "-idirafter")
+		{
+			if (i < argc-1)
+			{
+				arg = argv[++i];
+				incflags += (" -idirafter " + arg);
+			}
+			else
+				cerr << "mkoctfile: include directory name missing" << endl;
+		}
+		else if (starts_with(arg, "-D"))
+		{
+			defs += (" " + arg);
+		}
+		else if (starts_with(arg, "-Wl,") || starts_with(arg, "-l") || starts_with(arg, "-L") || starts_with(arg, "-R"))
+		{
+			ldflags += (" " + arg);
+		}
+		else if (arg == "-M" || arg == "--depend")
+		{
+			depend = true;
+			compile = false;
+		}
+		else if (arg == "-o" || arg == "--output")
+		{
+			if (i < argc-1)
+			{
+				arg = argv[++i];
+				outputfile = arg;
+			}
+			else
+				cerr << "mkoctfile: output file name missing" << endl;
+		}
+		else if (arg == "-p" || arg == "--print")
+		{
+			if (i < argc-1)
+			{
+				arg = argv[++i];
+				cout << vars[arg] << endl;
+				return 0;
+			}
+			else
+				cerr << "mkoctfile: --print requires argument" << endl;
+		}
+		else if (arg == "-s" || arg == "--strip")
+		{
+			if (no_oct_file_strip_on_this_platform)
+				cerr << "mkoctfile: stripping disabled on this platform" << endl;
+			else
+				strip = true;
+		}
+		else if (arg == "-c" || arg == "--compile")
+		{
+			link = false;
+		}
+		else if (arg == "-g")
+		{
+			vars["ALL_CFLAGS"] += " -g";
+			vars["ALL_CXXFLAGS"] += " -g";
+			vars["ALL_FFLAGS"] += " -g";
+		}
+		else if (arg == "--link-stand-alone")
+		{
+			link_stand_alone = true;
+		}
+		else if (arg == "--mex")
+		{
+			incflags += " -I.";
+			ldflags += " -Wl,-export:mexFunction";
+			output_ext = ".mex";
+		}
+		else if (starts_with(arg, "-W"))
+		{
+			pass_on_options += (" " + arg);
+		}
+		else
+		{
+			cerr << "mkoctfile: unrecognized argument " << arg;
+			return 1;
+		}
+
+		if (!file.empty() && octfile.empty())
+			octfile = file;
+	}
+
+	if (link_stand_alone)
+	{
+		if (!outputfile.empty())
+			output_option = "-o " + outputfile;
+	}
+	else
+	{
+		if (!outputfile.empty())
+			octfile = outputfile;
+		else
+			octfile = basename(octfile, true) + output_ext;
+	}
+
+	list<string>::const_iterator it;
+
+	if (depend)
+	{
+		for (it=cfiles.begin(); it!=cfiles.end(); ++it)
+		{
+			string f = *it, dfile = basename(f) + ".d", line;
+
+			unlink(dfile.c_str());
+			cmd = vars["CC"] + " " + vars["DEPEND_FLAGS"] + " " + vars["CPPFLAGS"] + " " +
+			      vars["ALL_CFLAGS"] + " " + incflags  + " " + defs + " " + quote_path(f);
+
+			FILE *fd = popen(cmd.c_str(), "r");
+			ofstream fo(dfile.c_str());
+			int pos;
+			while (!feof(fd))
+			{
+				line = get_line(fd);
+				if ((pos=line.rfind(".o:")) != string::npos)
+				{
+					int spos = line.rfind('/', pos);
+					string ofile = (spos == string::npos ? line.substr(0, pos+2) : line.substr(spos+1, pos-spos+1));
+					fo << "pic/" << ofile << " " << ofile << " " << dfile << line.substr(pos) << endl;
+				}
+				else
+					fo << line << endl;
+			}
+			pclose(fd);
+			fo.close();
+		}
+
+		for (it=ccfiles.begin(); it!=ccfiles.end(); ++it)
+		{
+			string f = *it, dfile = basename(f) + ".d", line;
+
+			unlink(dfile.c_str());
+			cmd = vars["CC"] + " " + vars["DEPEND_FLAGS"] + " " + vars["CPPFLAGS"] + " " +
+			      vars["ALL_CXXFLAGS"] + " " + incflags  + " " + defs + " " + quote_path(f);
+
+			FILE *fd = popen(cmd.c_str(), "r");
+			ofstream fo(dfile.c_str());
+			int pos;
+			while (!feof(fd))
+			{
+				line = get_line(fd);
+				if ((pos=line.rfind(".o:")) != string::npos)
+				{
+					int spos = line.rfind('/', pos);
+					string ofile = (spos == string::npos ? line.substr(0, pos+2) : line.substr(spos+1, pos-spos+1));
+					fo << "pic/" << ofile << " " << ofile << " " << dfile << line.substr(pos+2) << endl;
+				}
+				else
+					fo << line << endl;
+			}
+			pclose(fd);
+			fo.close();
+		}
+
+		return 0;
+	}
+
+	for (it=f77files.begin(); it!=f77files.end(); ++it)
+	{
+		string f = *it, b = basename(f);
+		if (!vars["F2C"].empty() && vars["F2C"] != "@F2C@")
+		{
+			string c = b + ".c";
+			cfiles.push_back(c);
+			cmd = vars["F2C"] + " " + vars["F2CFLAGS"] + " < " + f + " > " + c;
+			result = run_command(cmd);
+		}
+		else if (!vars["F77"].empty())
+		{
+			string o;
+			if (!outputfile.empty())
+			{
+				if (link)
+					o = b + ".o";
+				else
+					o = outputfile;
+			}
+			else
+				o = b + ".o";
+			objfiles += (" " + o);
+			cmd = vars["F77"] + " -c " + vars["FPICFLAG"] + " " + vars["ALL_FFLAGS"] + " " + incflags + " " + defs + " " +
+			      pass_on_options + " " + f + " -o " + o;
+			result = run_command(cmd);
+		}
+		else
+		{
+			cerr << "mkoctfile: no way to compile Fortran file " << f << endl;
+			return 1;
+		}
+	}
+
+	for (it=cfiles.begin(); it!=cfiles.end(); ++it)
+	{
+		string f = *it;
+		if (!vars["CC"].empty())
+		{
+			string b = basename(f), o;
+			if (!outputfile.empty())
+			{
+				if (link)
+					o = b + ".o";
+				else
+					o = outputfile;
+			}
+			else
+				o = b + ".o";
+			objfiles += (" " + o);
+			cmd = vars["CC"] + " -c " + vars["CPPFLAGS"] + " " + vars["CPICFLAG"] + " " + vars["ALL_CFLAGS"] + " " +
+			      pass_on_options + " " + incflags + " " + defs + " " + quote_path(f) + " -o " + quote_path(o);
+			result = run_command(cmd);
+		}
+		else
+		{
+			cerr << "mkoctfile: no way to compile C file " << f << endl;
+			return 1;
+		}
+	}
+	
+	for (it=ccfiles.begin(); it!=ccfiles.end(); ++it)
+	{
+		string f = *it;
+		if (!vars["CXX"].empty())
+		{
+			string b = basename(f), o;
+			if (!outputfile.empty())
+			{
+				if (link)
+					o = b + ".o";
+				else
+					o = outputfile;
+			}
+			else
+				o = b + ".o";
+			objfiles += (" " + o);
+			cmd = vars["CXX"] + " -c " + vars["CPPFLAGS"] + " " + vars["CXXPICFLAG"] + " " + vars["ALL_CXXFLAGS"] + " " +
+			      pass_on_options + " " + incflags + " " + defs + " " + quote_path(f) + " -o " + quote_path(o);
+			result = run_command(cmd);
+		}
+		else
+		{
+			cerr << "mkoctfile: no way to compile C++ file " << f << endl;
+			return 1;
+		}
+	}
+
+	if (link && !objfiles.empty())
+	{
+		if (link_stand_alone)
+		{
+			if (!vars["LD_CXX"].empty())
+			{
+				cmd= vars["LD_CXX"] + " " + vars["CPPFLAGS"] + " " + vars["ALL_CXXFLAGS"] + " " + vars["RDYNAMIC_FLAG"] + " " +
+				     vars["ALL_LDFLAGS"] + " " +  pass_on_options + " " +  output_option + " " + objfiles + " " + libfiles + " " +
+				     ldflags + " " + vars["LFLAGS"] + " " + vars["RLD_FLAG"] + " " + vars["OCTAVE_LIBS"] + " " + 
+				     vars["BLAS_LIBS"] + " " + vars["FFTW_LIBS"] + " " + vars["LIBREADLINE"] + " " + vars["LIBS"] + " " +
+				     vars["FLIBS"];
+				result = run_command(cmd);
+			}
+			else
+			{
+				cerr << "mkoctfile: no way to link stand-alone executable file" << endl;
+				return 1;
+			}
+		}
+		else
+		{
+			string LINK_DEPS = vars["LFLAGS"] + " " + vars["OCTAVE_LIBS"] + " " + vars["LDFLAGS"] + " " + vars["BLAS_LIBS"] + " " +
+					   vars["FFTW_LIBS"] + " " + vars["LIBS"] + " " + vars["FLIBS"];
+			cmd = vars["DL_LD"] + " " + vars["DL_LDFLAGS"] + " " + pass_on_options + " -o " + octfile + " " + objfiles + " " +
+			      libfiles + " " + ldflags + " " + LINK_DEPS;
+			result = run_command(cmd);
+		}
+
+		if (strip)
+		{
+			cmd = "strip " + octfile;
+			result = run_command(cmd);
+		}
+	}
+
+	return result;
+}