Mercurial > octave-nkf
view mkoctfile.cc.in @ 8968:91d53dc37f79
Add perm * sparse, perm \ sparse, sparse * perm, and sparse / perm operations.
Nothing terribly fancy in any of this. There probably is some
mechanism for using the permutation vectors and some assign or index
method in the sparse classes, but I've never understood all the
intricacies. I'm opting for a simple implementation at the cost of
possibly duplicating some functionality.
author | Jason Riedy <jason@acm.org> |
---|---|
date | Tue, 10 Mar 2009 21:54:44 -0400 |
parents | eb63fbe60fab |
children | a3237ae32c0d |
line wrap: on
line source
/* Copyright (C) 2008 Michael Goffioul This file is part of Octave. Octave is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. Octave is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Octave; see the file COPYING. If not, see <http://www.gnu.org/licenses/>. */ #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 (true) { c = static_cast<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 + "\""; else 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 file, output_option; list<string> cfiles, ccfiles, f77files; int result = 0; string objfiles = ""; string libfiles = ""; string octfile = ""; string outputfile = ""; string incflags = ""; string defs = ""; string ldflags = ""; string pass_on_options = ""; bool strip = false; bool no_oct_file_strip_on_this_platform = %NO_OCT_FILE_STRIP%; bool link = true; bool link_stand_alone = false; string output_ext = ".oct"; bool depend = false; bool 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 ()); string 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 ()); string 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); string 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); string 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); string 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); string 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 ()) { string 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"]; string cmd = vars["DL_LD"] + " " + vars["DL_LDFLAGS"] + " " + pass_on_options + " -o " + octfile + " " + objfiles + " " + libfiles + " " + ldflags + " " + LINK_DEPS; result = run_command (cmd); } if (strip) { string cmd = "strip " + octfile; result = run_command (cmd); } } return result; }