GNU Octave  3.8.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
mkoctfile.in.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 2008-2013 Michael Goffioul
4 
5 This file is part of Octave.
6 
7 Octave is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with Octave; see the file COPYING. If not, see
19 <http://www.gnu.org/licenses/>.
20 
21 */
22 
23 #if defined (HAVE_CONFIG_H)
24 #include <config.h>
25 #endif
26 
27 #include <string>
28 #include <cstring>
29 #include <map>
30 #include <list>
31 #include <algorithm>
32 #include <iostream>
33 #include <fstream>
34 #include <vector>
35 #include <cstdlib>
36 
37 #if defined (__WIN32__) && ! defined (_POSIX_VERSION)
38 #include <windows.h>
39 #ifdef _MSC_VER
40 #define popen _popen
41 #define pclose _pclose
42 #endif
43 #endif
44 
45 using namespace std;
46 
47 static bool initialized = false;
48 static map<string,string> vars;
49 
50 static string OCTAVE_VERSION = %OCTAVE_CONF_VERSION%;
51 
52 static string
53 substitute_prefix (const string& s, const string& prefix,
54  const string& new_prefix)
55 {
56  string retval = s;
57 
58  if (!prefix.empty () && new_prefix != prefix)
59  {
60  int len = prefix.length ();
61  if (retval.find (prefix) == 0)
62  retval.replace (0, len, new_prefix);
63  }
64 
65 #if defined (__WIN32__) && ! defined (_POSIX_VERSION)
66  replace (retval.begin (), retval.end (), '/', '\\');
67 #endif
68 
69  return retval;
70 }
71 
72 static string
73 get_line (FILE *fp)
74 {
75  static vector<char> buf (100);
76  unsigned int idx = 0;
77  char c;
78 
79  while (true)
80  {
81  c = static_cast<char> (fgetc (fp));
82  if (c == '\n' || c == EOF)
83  break;
84  if (buf.size () <= idx)
85  buf.resize (buf.size () + 100);
86  buf[idx++] = c;
87  }
88  if (idx == 0)
89  return string ("");
90  else
91  return string (&buf[0], idx);
92 }
93 
94 
95 static string
96 get_variable (const char *name, const string& defval)
97 {
98  const char *val = getenv (name);
99  if (val && *val)
100  return string (val);
101  else
102  return defval;
103 }
104 
105 static string
106 quote_path (const string& s)
107 {
108  if (s.find (' ') != string::npos && s[0] != '"')
109  return "\"" + s + "\"";
110  else
111  return s;
112 }
113 
114 static void
116 {
117  if (initialized)
118  return;
119 
120  initialized = true;
121 
122  vars["OCTAVE_HOME"] = get_variable ("OCTAVE_HOME", "");
123 
124 #if defined (__WIN32__) && ! defined (_POSIX_VERSION)
125  int n = 1024;
126 
127  string bin_dir (n, '\0');
128 
129  while (true)
130  {
131  int status = GetModuleFileName (0, &bin_dir[0], n);
132 
133  if (status < n)
134  {
135  bin_dir.resize (status);
136  break;
137  }
138  else
139  {
140  n *= 2;
141  bin_dir.resize (n);
142  }
143  }
144 
145  if (! bin_dir.empty ())
146  {
147  size_t pos = bin_dir.rfind ("\\bin\\");
148 
149  if (pos != string::npos)
150  vars["OCTAVE_HOME"] = bin_dir.substr (0, pos);
151  }
152 #endif
153 
154  vars["SED"] = get_variable ("SED", %OCTAVE_CONF_SED%);
155 
156  vars["OCTAVE_PREFIX"] = %OCTAVE_CONF_PREFIX%;
157 
158  string DEFAULT_OCTINCLUDEDIR = %OCTAVE_CONF_OCTINCLUDEDIR%;
159  string DEFAULT_INCLUDEDIR = %OCTAVE_CONF_INCLUDEDIR%;
160  string DEFAULT_LIBDIR = %OCTAVE_CONF_LIBDIR%;
161  string DEFAULT_OCTLIBDIR = %OCTAVE_CONF_OCTLIBDIR%;
162 
163  if (! vars["OCTAVE_HOME"].empty ())
164  {
165  DEFAULT_OCTINCLUDEDIR
166  = substitute_prefix (DEFAULT_OCTINCLUDEDIR, vars["OCTAVE_PREFIX"],
167  vars["OCTAVE_HOME"]);
168 
169  DEFAULT_INCLUDEDIR
170  = substitute_prefix (DEFAULT_INCLUDEDIR, vars["OCTAVE_PREFIX"],
171  vars["OCTAVE_HOME"]);
172 
173  DEFAULT_LIBDIR
174  = substitute_prefix (DEFAULT_LIBDIR, vars["OCTAVE_PREFIX"],
175  vars["OCTAVE_HOME"]);
176 
177  DEFAULT_OCTLIBDIR
178  = substitute_prefix (DEFAULT_OCTLIBDIR, vars["OCTAVE_PREFIX"],
179  vars["OCTAVE_HOME"]);
180  }
181 
182  vars["OCTINCLUDEDIR"] = get_variable ("OCTINCLUDEDIR", DEFAULT_OCTINCLUDEDIR);
183  vars["INCLUDEDIR"] = get_variable ("INCLUDEDIR", DEFAULT_INCLUDEDIR);
184  vars["LIBDIR"] = get_variable ("LIBDIR", DEFAULT_LIBDIR);
185  vars["OCTLIBDIR"] = get_variable ("OCTLIBDIR", DEFAULT_OCTLIBDIR);
186 
187 #if defined (__WIN32__) && ! defined (_POSIX_VERSION)
188  string DEFAULT_INCFLAGS
189  = "-I" + quote_path (vars["OCTINCLUDEDIR"] + "\\..")
190  + " -I" + quote_path (vars["OCTINCLUDEDIR"]);
191 #else
192  string DEFAULT_INCFLAGS
193  = "-I" + quote_path (vars["OCTINCLUDEDIR"] + "/..")
194  + " -I" + quote_path (vars["OCTINCLUDEDIR"]);
195 #endif
196  if (vars["INCLUDEDIR"] != "/usr/include")
197  DEFAULT_INCFLAGS += " -I" + quote_path (vars["INCLUDEDIR"]);
198 
199  string DEFAULT_LFLAGS = "-L" + quote_path (vars["OCTLIBDIR"]);
200  if (vars["LIBDIR"] != "/usr/lib")
201  DEFAULT_LFLAGS += " -L" + quote_path (vars["LIBDIR"]);
202 
203  vars["CPPFLAGS"] = get_variable ("CPPFLAGS", %OCTAVE_CONF_CPPFLAGS%);
204  vars["INCFLAGS"] = get_variable ("INCFLAGS", DEFAULT_INCFLAGS);
205  vars["F77"] = get_variable ("F77", %OCTAVE_CONF_MKOCTFILE_F77%);
206  vars["FFLAGS"] = get_variable ("FFLAGS", %OCTAVE_CONF_FFLAGS%);
207  vars["FPICFLAG"] = get_variable ("FPICFLAG", %OCTAVE_CONF_FPICFLAG%);
208  vars["CC"] = get_variable ("CC", %OCTAVE_CONF_MKOCTFILE_CC%);
209  vars["CFLAGS"] = get_variable ("CFLAGS", %OCTAVE_CONF_CFLAGS%);
210  vars["CPICFLAG"] = get_variable ("CPICFLAG", %OCTAVE_CONF_CPICFLAG%);
211  vars["CXX"] = get_variable ("CXX", %OCTAVE_CONF_MKOCTFILE_CXX%);
212  vars["CXXFLAGS"] = get_variable ("CXXFLAGS", %OCTAVE_CONF_CXXFLAGS%);
213  vars["CXXPICFLAG"] = get_variable ("CXXPICFLAG", %OCTAVE_CONF_CXXPICFLAG%);
214  vars["XTRA_CFLAGS"] = get_variable ("XTRA_CFLAGS", %OCTAVE_CONF_XTRA_CFLAGS%);
215  vars["XTRA_CXXFLAGS"] = get_variable ("XTRA_CXXFLAGS",
217 
218  vars["AR"] = get_variable ("AR", %OCTAVE_CONF_MKOCTFILE_AR%);
219  vars["RANLIB"] = get_variable ("RANLIB", %OCTAVE_CONF_MKOCTFILE_RANLIB%);
220 
221  vars["DEPEND_FLAGS"] = get_variable ("DEPEND_FLAGS",
222  %OCTAVE_CONF_DEPEND_FLAGS%);
223  vars["DEPEND_EXTRA_SED_PATTERN"] = get_variable ("DEPEND_EXTRA_SED_PATTERN",
224  %OCTAVE_CONF_DEPEND_EXTRA_SED_PATTERN%);
225 
226  vars["DL_LD"] = get_variable ("DL_LD", %OCTAVE_CONF_MKOCTFILE_DL_LD%);
227  vars["DL_LDFLAGS"] = get_variable ("DL_LDFLAGS",
229 
230  vars["RDYNAMIC_FLAG"] = get_variable ("RDYNAMIC_FLAG",
232  vars["LIBOCTAVE"] = "-loctave";
233  vars["LIBOCTINTERP"] = "-loctinterp";
234  vars["READLINE_LIBS"] = "-lreadline";
235  vars["LAPACK_LIBS"] = get_variable ("LAPACK_LIBS", %OCTAVE_CONF_LAPACK_LIBS%);
236  vars["BLAS_LIBS"] = get_variable ("BLAS_LIBS", %OCTAVE_CONF_BLAS_LIBS%);
237  vars["FFTW3_LDFLAGS"] = get_variable ("FFTW3_LDFLAGS",
239  vars["FFTW3_LIBS"] = get_variable ("FFTW3_LIBS", %OCTAVE_CONF_FFTW3_LIBS%);
240  vars["FFTW3F_LDFLAGS"] = get_variable ("FFTW3F_LDFLAGS",
242  vars["FFTW3F_LIBS"] = get_variable ("FFTW3F_LIBS", %OCTAVE_CONF_FFTW3F_LIBS%);
243  vars["LIBS"] = get_variable ("LIBS", %OCTAVE_CONF_LIBS%);
244  vars["FLIBS"] = get_variable ("FLIBS", %OCTAVE_CONF_FLIBS%);
245  vars["OCTAVE_LINK_DEPS"] = get_variable ("FLIBS",
247  vars["OCT_LINK_DEPS"] = get_variable ("FLIBS", %OCTAVE_CONF_OCT_LINK_DEPS%);
248  vars["FLIBS"] = get_variable ("FLIBS", %OCTAVE_CONF_FLIBS%);
249 
250  vars["LD_CXX"] = get_variable ("LD_CXX", %OCTAVE_CONF_MKOCTFILE_LD_CXX%);
251  vars["LDFLAGS"] = get_variable ("LDFLAGS", %OCTAVE_CONF_LDFLAGS%);
252  vars["LD_STATIC_FLAG"] = get_variable ("LD_STATIC_FLAG",
254  vars["LFLAGS"] = get_variable ("LFLAGS", DEFAULT_LFLAGS);
255  vars["F77_INTEGER8_FLAG"] = get_variable ("F77_INTEGER8_FLAG",
257 
258  vars["ALL_FFLAGS"] = vars["FFLAGS"] + " " + vars["F77_INTEGER8_FLAG"];
259 
260  vars["ALL_CFLAGS"] = vars["INCFLAGS"] + " " + vars["XTRA_CFLAGS"] + " "
261  + vars["CFLAGS"];
262 
263  vars["ALL_CXXFLAGS"] = vars["INCFLAGS"] + " " + vars["XTRA_CXXFLAGS"] + " "
264  + vars["CXXFLAGS"];
265 
266  vars["ALL_LDFLAGS"] = vars["LD_STATIC_FLAG"] + " " + vars["CPICFLAG"] + " "
267  + vars["LDFLAGS"];
268 
269  vars["OCTAVE_LIBS"] = vars["LIBOCTINTERP"] + " " + vars["LIBOCTAVE"] + " "
270  + vars["SPECIAL_MATH_LIB"];
271 
272  vars["FFTW_LIBS"] = vars["FFTW3_LDFLAGS"] + " " + vars["FFTW3_LIBS"] + " "
273  + vars["FFTW3F_LDFLAGS"] + " " + vars["FFTW3F_LIBS"];
274 }
275 
276 static string usage_msg = "usage: mkoctfile [options] file ...";
277 static string version_msg = "mkoctfile, version " + OCTAVE_VERSION;
278 static bool debug = false;
279 static string help_msg =
280 "\n"
281 "Options:\n"
282 "\n"
283 " -h, -?, --help Print this message.\n"
284 "\n"
285 " -IDIR Add -IDIR to compile commands.\n"
286 "\n"
287 " -idirafter DIR Add -idirafter DIR to compile commands.\n"
288 "\n"
289 " -DDEF Add -DDEF to compile commands.\n"
290 "\n"
291 " -lLIB Add library LIB to link command.\n"
292 "\n"
293 " -LDIR Add -LDIR to link command.\n"
294 "\n"
295 " -M, --depend Generate dependency files (.d) for C and C++\n"
296 " source files.\n"
297 "\n"
298 " -RDIR Add -RDIR to link command.\n"
299 "\n"
300 " -Wl,... Pass flags though the linker like -Wl,-rpath=...\n"
301 "\n"
302 " -W... Pass flags though the compiler like -Wa,OPTION.\n"
303 "\n"
304 " -c, --compile Compile, but do not link.\n"
305 "\n"
306 " -o FILE, --output FILE Output file name. Default extension is .oct\n"
307 " (or .mex if --mex is specified) unless linking\n"
308 " a stand-alone executable.\n"
309 "\n"
310 " -g Enable debugging options for compilers.\n"
311 "\n"
312 " -p VAR, --print VAR Print configuration variable VAR. Recognized\n"
313 " variables are:\n"
314 "\n"
315 " ALL_CFLAGS FFTW3F_LDFLAGS\n"
316 " ALL_CXXFLAGS FFTW3F_LIBS\n"
317 " ALL_FFLAGS FLIBS\n"
318 " ALL_LDFLAGS FPICFLAG\n"
319 " AR INCFLAGS\n"
320 " BLAS_LIBS LAPACK_LIBS\n"
321 " CC LDFLAGS\n"
322 " CFLAGS LD_CXX\n"
323 " CPICFLAG LD_STATIC_FLAG\n"
324 " CPPFLAGS LFLAGS\n"
325 " CXX LIBOCTAVE\n"
326 " CXXFLAGS LIBOCTINTERP\n"
327 " CXXPICFLAG LIBS\n"
328 " DEPEND_EXTRA_SED_PATTERN OCTAVE_LIBS\n"
329 " DEPEND_FLAGS OCTAVE_LINK_DEPS\n"
330 " DL_LD OCT_LINK_DEPS\n"
331 " DL_LDFLAGS RANLIB\n"
332 " EXEEXT RDYNAMIC_FLAG\n"
333 " F77 READLINE_LIBS\n"
334 " F77_INTEGER_8_FLAG SED\n"
335 " FFLAGS XTRA_CFLAGS\n"
336 " FFTW3_LDFLAGS XTRA_CXXFLAGS\n"
337 " FFTW3_LIBS\n"
338 "\n"
339 " --link-stand-alone Link a stand-alone executable file.\n"
340 "\n"
341 " --mex Assume we are creating a MEX file. Set the\n"
342 " default output extension to \".mex\".\n"
343 "\n"
344 " -s, --strip Strip output file.\n"
345 "\n"
346 " -v, --verbose Echo commands as they are executed.\n"
347 "\n"
348 " FILE Compile or link FILE. Recognized file types are:\n"
349 "\n"
350 " .c C source\n"
351 " .cc C++ source\n"
352 " .C C++ source\n"
353 " .cpp C++ source\n"
354 " .f Fortran source (fixed form)\n"
355 " .F Fortran source (fixed form)\n"
356 " .f90 Fortran source (free form)\n"
357 " .F90 Fortran source (free form)\n"
358 " .o object file\n"
359 " .a library file\n"
360 #ifdef _MSC_VER
361 " .lib library file\n"
362 #endif
363 "\n";
364 
365 static string
366 basename (const string& s, bool strip_path = false)
367 {
368  string retval;
369  size_t pos = s.rfind ('.');
370 
371  if (pos == string::npos)
372  retval = s;
373  else
374  retval = s.substr (0, pos);
375 
376  if (strip_path)
377  {
378  size_t p1 = retval.rfind ('/'), p2 = retval.rfind ('\\');
379  pos = (p1 != string::npos && p2 != string::npos
380  ? max (p1, p2) : (p2 != string::npos ? p2 : p1));
381  if (pos != string::npos)
382  retval = retval.substr (++pos, string::npos);
383  }
384 
385  return retval;
386 }
387 
388 inline bool
389 starts_with (const string& s, const string& prefix)
390 {
391  return (s.length () >= prefix.length () && s.find (prefix) == 0);
392 }
393 
394 inline bool
395 ends_with (const string& s, const string& suffix)
396 {
397  return (s.length () >= suffix.length ()
398  && s.rfind (suffix) == s.length () - suffix.length ());
399 }
400 
401 static int
402 run_command (const string& cmd)
403 {
404  if (debug)
405  cout << cmd << endl;
406  return system (cmd.c_str ());
407 }
408 
409 bool
410 is_true (const std::string& s)
411 {
412  return (s == "yes"
413  || s == "true");
414 }
415 
416 int
417 main (int argc, char **argv)
418 {
419  initialize ();
420 
421  string file, output_option;
422  list<string> cfiles, ccfiles, f77files;
423  int result = 0;
424 
425  string objfiles = "";
426  string libfiles = "";
427  string octfile = "";
428  string outputfile = "";
429  string incflags = "";
430  string defs = "";
431  string ldflags = "";
432  string pass_on_options = "";
433  bool strip = false;
434  bool no_oct_file_strip_on_this_platform = is_true ("%NO_OCT_FILE_STRIP%");
435  bool link = true;
436  bool link_stand_alone = false;
437  string output_ext = ".oct";
438  bool depend = false;
439  bool compile = true;
440 
441  if (argc == 1)
442  {
443  cout << usage_msg << endl;
444  return 1;
445  }
446 
447  if (argc == 2 && (!strcmp (argv[1], "-v")
448  || !strcmp (argv[1], "-version")
449  || !strcmp (argv[1], "--version")))
450  {
451  cout << version_msg << endl;
452  return 0;
453  }
454 
455  for (int i = 1; i < argc; i++)
456  {
457  string arg = argv[i];
458 
459  if (ends_with (arg, ".c"))
460  {
461  file = arg;
462  cfiles.push_back (file);
463  }
464  else if (ends_with (arg, ".cc") || ends_with (arg, ".C")
465  || ends_with (arg, ".cpp"))
466  {
467  file = arg;
468  ccfiles.push_back (file);
469  }
470  else if (ends_with (arg, ".f") || ends_with (arg, ".F")
471  || ends_with (arg, "f90") || ends_with (arg, ".F90"))
472  {
473  file = arg;
474  f77files.push_back (file);
475  }
476  else if (ends_with (arg, ".o") || ends_with (arg, ".obj"))
477  {
478  file = arg;
479  objfiles += (" " + quote_path (arg));
480  }
481  else if (ends_with (arg, ".lib") || ends_with (arg, ".a"))
482  {
483  file = arg;
484  libfiles += (" " + quote_path (arg));
485  }
486  else if (arg == "-d" || arg == "-debug" || arg == "--debug"
487  || arg == "-v" || arg == "-verbose" || arg == "--verbose")
488  {
489  debug = true;
490  if (vars["CC"] == "cc-msvc")
491  vars["CC"] += " -d";
492  if (vars["CXX"] == "cc-msvc")
493  vars["CXX"] += " -d";
494  if (vars["DL_LD"] == "cc-msvc")
495  vars["DL_LD"] += " -d";
496  }
497  else if (arg == "-h" || arg == "-?" || arg == "-help" || arg == "--help")
498  {
499  cout << usage_msg << endl;
500  cout << help_msg << endl;
501  return 0;
502  }
503  else if (starts_with (arg, "-I"))
504  {
505  incflags += (" " + quote_path (arg));
506  }
507  else if (arg == "-idirafter")
508  {
509  if (i < argc-1)
510  {
511  arg = argv[++i];
512  incflags += (" -idirafter " + arg);
513  }
514  else
515  cerr << "mkoctfile: include directory name missing" << endl;
516  }
517  else if (starts_with (arg, "-D"))
518  {
519  defs += (" " + arg);
520  }
521  else if (starts_with (arg, "-Wl,") || starts_with (arg, "-l")
522  || starts_with (arg, "-L") || starts_with (arg, "-R"))
523  {
524  ldflags += (" " + arg);
525  }
526  else if (arg == "-M" || arg == "-depend" || arg == "--depend")
527  {
528  depend = true;
529  compile = false;
530  }
531  else if (arg == "-o" || arg == "-output" || arg == "--output")
532  {
533  if (i < argc-1)
534  {
535  arg = argv[++i];
536  outputfile = arg;
537  }
538  else
539  cerr << "mkoctfile: output file name missing" << endl;
540  }
541  else if (arg == "-p" || arg == "-print" || arg == "--print")
542  {
543  if (i < argc-1)
544  {
545  arg = argv[++i];
546  cout << vars[arg] << endl;
547  return 0;
548  }
549  else
550  cerr << "mkoctfile: --print requires argument" << endl;
551  }
552  else if (arg == "-s" || arg == "-strip" || arg == "--strip")
553  {
554  if (no_oct_file_strip_on_this_platform)
555  cerr << "mkoctfile: stripping disabled on this platform" << endl;
556  else
557  strip = true;
558  }
559  else if (arg == "-c" || arg == "-compile" || arg == "--compile")
560  {
561  link = false;
562  }
563  else if (arg == "-g")
564  {
565  vars["ALL_CFLAGS"] += " -g";
566  vars["ALL_CXXFLAGS"] += " -g";
567  vars["ALL_FFLAGS"] += " -g";
568  }
569  else if (arg == "-link-stand-alone" || arg == "--link-stand-alone")
570  {
571  link_stand_alone = true;
572  }
573  else if (arg == "-mex" || arg == "--mex")
574  {
575  incflags += " -I.";
576 #ifdef _MSC_VER
577  ldflags += " -Wl,-export:mexFunction";
578 #endif
579  output_ext = ".mex";
580  }
581  else if (starts_with (arg, "-W"))
582  {
583  pass_on_options += (" " + arg);
584  }
585  else
586  {
587  cerr << "mkoctfile: unrecognized argument " << arg;
588  return 1;
589  }
590 
591  if (!file.empty () && octfile.empty ())
592  octfile = file;
593  }
594 
595  if (link_stand_alone)
596  {
597  if (!outputfile.empty ())
598  output_option = "-o " + outputfile;
599  }
600  else
601  {
602  if (!outputfile.empty ())
603  {
604  octfile = outputfile;
605  size_t len = octfile.length ();
606  size_t len_ext = output_ext.length ();
607  if (octfile.substr (len-len_ext) != output_ext)
608  octfile += output_ext;
609  }
610  else
611  octfile = basename (octfile, true) + output_ext;
612  }
613 
614  list<string>::const_iterator it;
615 
616  if (depend)
617  {
618  for (it = cfiles.begin (); it != cfiles.end (); ++it)
619  {
620  string f = *it, dfile = basename (f, true) + ".d", line;
621 
622  unlink (dfile.c_str ());
623  string cmd = vars["CC"] + " " + vars["DEPEND_FLAGS"] + " "
624  + vars["CPPFLAGS"] + " " + vars["ALL_CFLAGS"] + " "
625  + incflags + " " + defs + " " + quote_path (f);
626 
627  FILE *fd = popen (cmd.c_str (), "r");
628  ofstream fo (dfile.c_str ());
629  size_t pos;
630  while (!feof (fd))
631  {
632  line = get_line (fd);
633  if ((pos = line.rfind (".o:")) != string::npos)
634  {
635  size_t spos = line.rfind ('/', pos);
636  string ofile =
637  (spos == string::npos ? line.substr (0, pos+2)
638  : line.substr (spos+1, pos-spos+1));
639  fo << "pic/" << ofile << " " << ofile << " "
640  << dfile << line.substr (pos) << endl;
641  }
642  else
643  fo << line << endl;
644  }
645  pclose (fd);
646  fo.close ();
647  }
648 
649  for (it = ccfiles.begin (); it != ccfiles.end (); ++it)
650  {
651  string f = *it, dfile = basename (f, true) + ".d", line;
652 
653  unlink (dfile.c_str ());
654  string cmd = vars["CC"] + " " + vars["DEPEND_FLAGS"] + " "
655  + vars["CPPFLAGS"] + " " + vars["ALL_CXXFLAGS"] + " "
656  + incflags + " " + defs + " " + quote_path (f);
657 
658  FILE *fd = popen (cmd.c_str (), "r");
659  ofstream fo (dfile.c_str ());
660  size_t pos;
661  while (!feof (fd))
662  {
663  line = get_line (fd);
664  if ((pos = line.rfind (".o:")) != string::npos)
665  {
666  size_t spos = line.rfind ('/', pos);
667  string ofile =
668  (spos == string::npos ? line.substr (0, pos+2)
669  : line.substr (spos+1, pos-spos+1));
670  fo << "pic/" << ofile << " " << ofile << " "
671  << dfile << line.substr (pos+2) << endl;
672  }
673  else
674  fo << line << endl;
675  }
676  pclose (fd);
677  fo.close ();
678  }
679 
680  return 0;
681  }
682 
683  for (it = f77files.begin (); it != f77files.end (); ++it)
684  {
685  string f = *it, b = basename (f, true);
686  if (!vars["F77"].empty ())
687  {
688  string o;
689  if (!outputfile.empty ())
690  {
691  if (link)
692  o = b + ".o";
693  else
694  o = outputfile;
695  }
696  else
697  o = b + ".o";
698  objfiles += (" " + o);
699  string cmd = vars["F77"] + " -c " + vars["FPICFLAG"] + " "
700  + vars["ALL_FFLAGS"] + " " + incflags + " " + defs + " "
701  + pass_on_options + " " + f + " -o " + o;
702  result = run_command (cmd);
703  }
704  else
705  {
706  cerr << "mkoctfile: no way to compile Fortran file " << f << endl;
707  return 1;
708  }
709  }
710 
711  for (it = cfiles.begin (); it != cfiles.end (); ++it)
712  {
713  string f = *it;
714  if (!vars["CC"].empty ())
715  {
716  string b = basename (f, true), o;
717  if (!outputfile.empty ())
718  {
719  if (link)
720  o = b + ".o";
721  else
722  o = outputfile;
723  }
724  else
725  o = b + ".o";
726  objfiles += (" " + o);
727  string cmd = vars["CC"] + " -c " + vars["CPPFLAGS"] + " "
728  + vars["CPICFLAG"] + " " + vars["ALL_CFLAGS"] + " "
729  + pass_on_options + " " + incflags + " " + defs + " "
730  + quote_path (f) + " -o " + quote_path (o);
731  result = run_command (cmd);
732  }
733  else
734  {
735  cerr << "mkoctfile: no way to compile C file " << f << endl;
736  return 1;
737  }
738  }
739 
740  for (it = ccfiles.begin (); it != ccfiles.end (); ++it)
741  {
742  string f = *it;
743  if (!vars["CXX"].empty ())
744  {
745  string b = basename (f, true), o;
746  if (!outputfile.empty ())
747  {
748  if (link)
749  o = b + ".o";
750  else
751  o = outputfile;
752  }
753  else
754  o = b + ".o";
755  objfiles += (" " + o);
756  string cmd = vars["CXX"] + " -c " + vars["CPPFLAGS"] + " "
757  + vars["CXXPICFLAG"] + " " + vars["ALL_CXXFLAGS"] + " "
758  + pass_on_options + " " + incflags + " " + defs + " "
759  + quote_path (f) + " -o " + quote_path (o);
760  result = run_command (cmd);
761  }
762  else
763  {
764  cerr << "mkoctfile: no way to compile C++ file " << f << endl;
765  return 1;
766  }
767  }
768 
769  if (link && !objfiles.empty ())
770  {
771  if (link_stand_alone)
772  {
773  if (!vars["LD_CXX"].empty ())
774  {
775  string cmd = vars["LD_CXX"] + " " + vars["CPPFLAGS"] + " "
776  + vars["ALL_CXXFLAGS"] + " " + vars["RDYNAMIC_FLAG"]
777  + " " + vars["ALL_LDFLAGS"] + " "
778  + pass_on_options + " " + output_option + " "
779  + objfiles + " " + libfiles + " "
780  + ldflags + " " + vars["LFLAGS"]
781  + " -loctinterp -loctave "
782  + " " + vars["OCT_LINK_OPTS"]
783  + " " + vars["OCTAVE_LINK_DEPS"];
784  result = run_command (cmd);
785  }
786  else
787  {
788  cerr << "mkoctfile: no way to link stand-alone executable file"
789  << endl;
790  return 1;
791  }
792  }
793  else
794  {
795  string cmd = vars["DL_LD"] + " " + vars["DL_LDFLAGS"] + " "
796  + pass_on_options + " -o " + octfile + " "
797  + objfiles + " " + libfiles + " "
798  + ldflags + " " + vars["LFLAGS"]
799  + " -loctinterp -loctave "
800  + vars["OCT_LINK_OPTS"] + " " + vars["OCT_LINK_DEPS"];
801  result = run_command (cmd);
802  }
803 
804  if (strip)
805  {
806  string cmd = "strip " + octfile;
807  result = run_command (cmd);
808  }
809  }
810 
811  return result;
812 }