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