GNU Octave  4.4.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
mkoctfile.in.cc
Go to the documentation of this file.
1 // %NO_EDIT_WARNING%
2 /*
3 
4 Copyright (C) 2008-2018 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
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12 
13 Octave is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License 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 <https://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 <sstream>
36 #include <vector>
37 #include <cstdlib>
38 
39 #if defined (CROSS)
40 # include <sys/types.h>
41 # include <sys/wait.h>
42 # include <unistd.h>
43 
44 # ifndef OCTAVE_UNUSED
45 # define OCTAVE_UNUSED
46 # endif
47 #else
48 # include "unistd-wrappers.h"
49 # include "wait-wrappers.h"
50 #endif
51 
52 static std::map<std::string, std::string> vars;
53 
54 #if ! defined (OCTAVE_VERSION)
55 # define OCTAVE_VERSION %OCTAVE_CONF_VERSION%
56 #endif
57 
58 #if ! defined (OCTAVE_PREFIX)
59 # define OCTAVE_PREFIX %OCTAVE_CONF_PREFIX%
60 #endif
61 
62 #if ! defined (OCTAVE_EXEC_PREFIX)
63 # define OCTAVE_EXEC_PREFIX %OCTAVE_CONF_EXEC_PREFIX%
64 #endif
65 
66 #include "shared-fcns.h"
67 
68 #if defined (CROSS)
69 
70 static int
71 octave_unlink_wrapper (const char *nm)
72 {
73  return unlink (nm);
74 }
75 
76 static bool
77 octave_wifexited_wrapper (int status)
78 {
79  return WIFEXITED (status);
80 }
81 
82 static int
83 octave_wexitstatus_wrapper (int status)
84 {
85  return WEXITSTATUS (status);
86 }
87 
88 #endif
89 
90 static std::string
91 get_line (FILE *fp)
92 {
93  std::ostringstream buf;
94 
95  while (true)
96  {
97  int c = std::fgetc (fp);
98 
99  if (c == '\n' || c == EOF)
100  break;
101 
102  buf << static_cast<char> (c);
103  }
104 
105  return buf.str ();
106 }
107 
108 static std::string
109 get_variable (const char *name, const std::string& defval)
110 {
111  const char *val = getenv (name);
112 
113  if (val && *val)
114  return std::string (val);
115  else
116  return defval;
117 }
118 
119 static std::string
121 {
122  if (s.find (' ') != std::string::npos && s[0] != '"')
123  return '"' + s + '"';
124  else
125  return s;
126 }
127 
128 static void
130 {
131  set_octave_home ();
132 
133  vars["OCTAVE_HOME"] = Voctave_home;
134  vars["OCTAVE_EXEC_HOME"] = Voctave_exec_home;
135 
136  vars["SED"] = get_variable ("SED", %OCTAVE_CONF_SED%);
137 
138  vars["OCTINCLUDEDIR"]
139  = get_variable ("OCTINCLUDEDIR",
140  prepend_octave_home (%OCTAVE_CONF_OCTINCLUDEDIR%));
141 
142  vars["INCLUDEDIR"]
143  = get_variable ("INCLUDEDIR",
144  prepend_octave_home (%OCTAVE_CONF_INCLUDEDIR%));
145 
146  vars["LIBDIR"]
147  = get_variable ("LIBDIR", prepend_octave_exec_home (%OCTAVE_CONF_LIBDIR%));
148 
149  vars["OCTLIBDIR"]
150  = get_variable ("OCTLIBDIR", prepend_octave_exec_home (%OCTAVE_CONF_OCTLIBDIR%));
151 
152 #if defined (OCTAVE_USE_WINDOWS_API)
153  std::string DEFAULT_INCFLAGS
154  = "-I" + quote_path (vars["OCTINCLUDEDIR"] + R"(\..)")
155  + " -I" + quote_path (vars["OCTINCLUDEDIR"]);
156 #else
157  std::string DEFAULT_INCFLAGS
158  = "-I" + quote_path (vars["OCTINCLUDEDIR"] + "/..")
159  + " -I" + quote_path (vars["OCTINCLUDEDIR"]);
160 #endif
161 
162  if (vars["INCLUDEDIR"] != "/usr/include")
163  DEFAULT_INCFLAGS += " -I" + quote_path (vars["INCLUDEDIR"]);
164 
165  std::string DEFAULT_LFLAGS = "-L" + quote_path (vars["OCTLIBDIR"]);
166 
167  if (vars["LIBDIR"] != "/usr/lib")
168  DEFAULT_LFLAGS += " -L" + quote_path (vars["LIBDIR"]);
169 
170  vars["CPPFLAGS"] = get_variable ("CPPFLAGS", %OCTAVE_CONF_CPPFLAGS%);
171 
172  vars["INCFLAGS"] = get_variable ("INCFLAGS", DEFAULT_INCFLAGS);
173 
174  vars["F77"] = get_variable ("F77", %OCTAVE_CONF_MKOCTFILE_F77%);
175 
176  vars["FFLAGS"] = get_variable ("FFLAGS", %OCTAVE_CONF_FFLAGS%);
177 
178  vars["FPICFLAG"] = get_variable ("FPICFLAG", %OCTAVE_CONF_FPICFLAG%);
179 
180  vars["CC"] = get_variable ("CC", %OCTAVE_CONF_MKOCTFILE_CC%);
181 
182  vars["CFLAGS"] = get_variable ("CFLAGS", %OCTAVE_CONF_CFLAGS%);
183 
184  vars["CPICFLAG"] = get_variable ("CPICFLAG", %OCTAVE_CONF_CPICFLAG%);
185 
186  vars["CXX"] = get_variable ("CXX", %OCTAVE_CONF_MKOCTFILE_CXX%);
187 
188  vars["CXXFLAGS"] = get_variable ("CXXFLAGS", %OCTAVE_CONF_CXXFLAGS%);
189 
190  vars["CXXPICFLAG"] = get_variable ("CXXPICFLAG", %OCTAVE_CONF_CXXPICFLAG%);
191 
192  vars["XTRA_CFLAGS"] = get_variable ("XTRA_CFLAGS", %OCTAVE_CONF_XTRA_CFLAGS%);
193 
194  vars["XTRA_CXXFLAGS"] = get_variable ("XTRA_CXXFLAGS",
195  %OCTAVE_CONF_XTRA_CXXFLAGS%);
196 
197  vars["AR"] = get_variable ("AR", %OCTAVE_CONF_MKOCTFILE_AR%);
198 
199  vars["RANLIB"] = get_variable ("RANLIB", %OCTAVE_CONF_MKOCTFILE_RANLIB%);
200 
201  vars["DEPEND_FLAGS"] = get_variable ("DEPEND_FLAGS",
202  %OCTAVE_CONF_DEPEND_FLAGS%);
203 
204  vars["DEPEND_EXTRA_SED_PATTERN"]
205  = get_variable ("DEPEND_EXTRA_SED_PATTERN",
206  %OCTAVE_CONF_DEPEND_EXTRA_SED_PATTERN%);
207 
208  vars["DL_LD"] = get_variable ("DL_LD", %OCTAVE_CONF_MKOCTFILE_DL_LD%);
209 
210  vars["DL_LDFLAGS"] = get_variable ("DL_LDFLAGS",
211  %OCTAVE_CONF_MKOCTFILE_DL_LDFLAGS%);
212 
213  vars["RDYNAMIC_FLAG"] = get_variable ("RDYNAMIC_FLAG",
214  %OCTAVE_CONF_RDYNAMIC_FLAG%);
215 
216  vars["LIBOCTAVE"] = "-loctave";
217 
218  vars["LIBOCTINTERP"] = "-loctinterp";
219 
220  vars["READLINE_LIBS"] = "-lreadline";
221 
222  vars["LAPACK_LIBS"] = get_variable ("LAPACK_LIBS", %OCTAVE_CONF_LAPACK_LIBS%);
223 
224  vars["BLAS_LIBS"] = get_variable ("BLAS_LIBS", %OCTAVE_CONF_BLAS_LIBS%);
225 
226  vars["FFTW3_LDFLAGS"] = get_variable ("FFTW3_LDFLAGS",
227  %OCTAVE_CONF_FFTW3_LDFLAGS%);
228 
229  vars["FFTW3_LIBS"] = get_variable ("FFTW3_LIBS", %OCTAVE_CONF_FFTW3_LIBS%);
230 
231  vars["FFTW3F_LDFLAGS"] = get_variable ("FFTW3F_LDFLAGS",
232  %OCTAVE_CONF_FFTW3F_LDFLAGS%);
233 
234  vars["FFTW3F_LIBS"] = get_variable ("FFTW3F_LIBS", %OCTAVE_CONF_FFTW3F_LIBS%);
235 
236  vars["LIBS"] = get_variable ("LIBS", %OCTAVE_CONF_LIBS%);
237 
238  vars["FLIBS"] = get_variable ("FLIBS", %OCTAVE_CONF_FLIBS%);
239 
240  vars["OCTAVE_LINK_DEPS"] = get_variable ("OCTAVE_LINK_DEPS",
241  %OCTAVE_CONF_MKOCTFILE_OCTAVE_LINK_DEPS%);
242 
243  vars["OCTAVE_LINK_OPTS"] = get_variable ("OCTAVE_LINK_OPTS",
244  %OCTAVE_CONF_OCTAVE_LINK_OPTS%);
245 
246  vars["OCT_LINK_DEPS"] = get_variable ("OCT_LINK_DEPS",
247  %OCTAVE_CONF_MKOCTFILE_OCT_LINK_DEPS%);
248 
249  vars["OCT_LINK_OPTS"] = get_variable ("OCT_LINK_OPTS",
250  %OCTAVE_CONF_OCT_LINK_OPTS%);
251 
252  vars["LD_CXX"] = get_variable ("LD_CXX", %OCTAVE_CONF_MKOCTFILE_LD_CXX%);
253 
254  vars["LDFLAGS"] = get_variable ("LDFLAGS", %OCTAVE_CONF_LDFLAGS%);
255 
256  vars["LD_STATIC_FLAG"] = get_variable ("LD_STATIC_FLAG",
257  %OCTAVE_CONF_LD_STATIC_FLAG%);
258 
259  vars["LFLAGS"] = get_variable ("LFLAGS", DEFAULT_LFLAGS);
260 
261  vars["F77_INTEGER8_FLAG"] = get_variable ("F77_INTEGER8_FLAG",
262  %OCTAVE_CONF_F77_INTEGER_8_FLAG%);
263  vars["ALL_FFLAGS"] = vars["FFLAGS"] + ' ' + vars["F77_INTEGER8_FLAG"];
264 
265  vars["ALL_CFLAGS"]
266  = vars["INCFLAGS"] + ' ' + vars["XTRA_CFLAGS"] + ' ' + vars["CFLAGS"];
267 
268  vars["ALL_CXXFLAGS"]
269  = vars["INCFLAGS"] + ' ' + vars["XTRA_CXXFLAGS"] + ' ' + vars["CXXFLAGS"];
270 
271  vars["ALL_LDFLAGS"]
272  = vars["LD_STATIC_FLAG"] + ' ' + vars["CPICFLAG"] + ' ' + vars["LDFLAGS"];
273 
274  vars["OCTAVE_LIBS"]
275  = (vars["LIBOCTINTERP"] + ' ' + vars["LIBOCTAVE"] + ' '
276  + vars["SPECIAL_MATH_LIB"]);
277 
278  vars["FFTW_LIBS"] = vars["FFTW3_LDFLAGS"] + ' ' + vars["FFTW3_LIBS"] + ' '
279  + vars["FFTW3F_LDFLAGS"] + ' ' + vars["FFTW3F_LIBS"];
280 }
281 
282 static std::string usage_msg = "usage: mkoctfile [options] file ...";
283 
284 static std::string version_msg = "mkoctfile, version " OCTAVE_VERSION;
285 
286 static bool debug = false;
287 
289 "\n"
290 "Options:\n"
291 "\n"
292 " -h, -?, --help Print this message.\n"
293 "\n"
294 " -IDIR Add -IDIR to compile commands.\n"
295 "\n"
296 " -idirafter DIR Add -idirafter DIR to compile commands.\n"
297 "\n"
298 " -DDEF Add -DDEF to compile commands.\n"
299 "\n"
300 " -lLIB Add library LIB to link command.\n"
301 "\n"
302 " -LDIR Add -LDIR to link command.\n"
303 "\n"
304 " -M, --depend Generate dependency files (.d) for C and C++\n"
305 " source files.\n"
306 #if ! defined (OCTAVE_USE_WINDOWS_API)
307 "\n"
308 " -pthread Add -pthread to link command.\n"
309 #endif
310 "\n"
311 " -RDIR Add -RDIR to link command.\n"
312 "\n"
313 " -Wl,... Pass flags though the linker like -Wl,-rpath=...\n"
314 "\n"
315 " -W... Pass flags though the compiler like -Wa,OPTION.\n"
316 "\n"
317 " -c, --compile Compile, but do not link.\n"
318 "\n"
319 " -o FILE, --output FILE Output filename. Default extension is .oct\n"
320 " (or .mex if --mex is specified) unless linking\n"
321 " a stand-alone executable.\n"
322 "\n"
323 " -g Enable debugging options for compilers.\n"
324 "\n"
325 " -p VAR, --print VAR Print configuration variable VAR. Recognized\n"
326 " variables are:\n"
327 "\n"
328 " ALL_CFLAGS INCFLAGS\n"
329 " ALL_CXXFLAGS INCLUDEDIR\n"
330 " ALL_FFLAGS LAPACK_LIBS\n"
331 " ALL_LDFLAGS LD_CXX\n"
332 " AR LDFLAGS\n"
333 " BLAS_LIBS LD_STATIC_FLAG\n"
334 " CC LFLAGS\n"
335 " CFLAGS LIBDIR\n"
336 " CPICFLAG LIBOCTAVE\n"
337 " CPPFLAGS LIBOCTINTERP\n"
338 " CXX LIBS\n"
339 " CXXFLAGS OCTAVE_EXEC_HOME\n"
340 " CXXPICFLAG OCTAVE_HOME\n"
341 " DEPEND_EXTRA_SED_PATTERN OCTAVE_LIBS\n"
342 " DEPEND_FLAGS OCTAVE_LINK_DEPS\n"
343 " DL_LD OCTAVE_LINK_OPTS\n"
344 " DL_LDFLAGS OCTINCLUDEDIR\n"
345 " F77 OCTLIBDIR\n"
346 " F77_INTEGER8_FLAG OCT_LINK_DEPS\n"
347 " FFLAGS OCT_LINK_OPTS\n"
348 " FFTW3F_LDFLAGS RANLIB\n"
349 " FFTW3F_LIBS RDYNAMIC_FLAG\n"
350 " FFTW3_LDFLAGS READLINE_LIBS\n"
351 " FFTW3_LIBS SED\n"
352 " FFTW_LIBS SPECIAL_MATH_LIB\n"
353 " FLIBS XTRA_CFLAGS\n"
354 " FPICFLAG XTRA_CXXFLAGS\n"
355 "\n"
356 " --link-stand-alone Link a stand-alone executable file.\n"
357 "\n"
358 " --mex Assume we are creating a MEX file. Set the\n"
359 " default output extension to \".mex\".\n"
360 "\n"
361 " -s, --strip Strip output file.\n"
362 "\n"
363 " -n, --just-print, --dry-run\n"
364 " Print commands, but do not execute them.\n"
365 "\n"
366 " -v, --verbose Echo commands as they are executed.\n"
367 "\n"
368 " FILE Compile or link FILE. Recognized file types are:\n"
369 "\n"
370 " .c C source\n"
371 " .cc C++ source\n"
372 " .cp C++ source\n"
373 " .cpp C++ source\n"
374 " .CPP C++ source\n"
375 " .cxx C++ source\n"
376 " .c++ C++ source\n"
377 " .C C++ source\n"
378 " .f Fortran source (fixed form)\n"
379 " .F Fortran source (fixed form)\n"
380 " .f90 Fortran source (free form)\n"
381 " .F90 Fortran source (free form)\n"
382 " .o object file\n"
383 " .a library file\n"
384 #if defined (_MSC_VER)
385 " .lib library file\n"
386 #endif
387 "\n";
388 
389 static std::string
390 basename (const std::string& s, bool strip_path = false)
391 {
393 
394  size_t pos = s.rfind ('.');
395 
396  if (pos == std::string::npos)
397  retval = s;
398  else
399  retval = s.substr (0, pos);
400 
401  if (strip_path)
402  {
403  size_t p1 = retval.rfind ('/'), p2 = retval.rfind ('\\');
404 
405  pos = (p1 != std::string::npos && p2 != std::string::npos
406  ? std::max (p1, p2) : (p2 != std::string::npos ? p2 : p1));
407 
408  if (pos != std::string::npos)
409  retval = retval.substr (++pos, std::string::npos);
410  }
411 
412  return retval;
413 }
414 
415 inline bool
416 starts_with (const std::string& s, const std::string& prefix)
417 {
418  return (s.length () >= prefix.length () && s.find (prefix) == 0);
419 }
420 
421 inline bool
422 ends_with (const std::string& s, const std::string& suffix)
423 {
424  return (s.length () >= suffix.length ()
425  && s.rfind (suffix) == s.length () - suffix.length ());
426 }
427 
428 static int
429 run_command (const std::string& cmd, bool printonly = false)
430 {
431  if (printonly)
432  {
433  std::cout << cmd << std::endl;
434  return 0;
435  }
436 
437  if (debug)
438  std::cout << cmd << std::endl;
439 
440  int result = system (cmd.c_str ());
441 
444 
445  return result;
446 }
447 
448 bool
450 {
451  return (s == "yes" || s == "true");
452 }
453 
454 int
455 main (int argc, char **argv)
456 {
457  initialize ();
458 
459  if (argc == 1)
460  {
461  std::cout << usage_msg << std::endl;
462  return 1;
463  }
464 
465  if (argc == 2 && (! strcmp (argv[1], "-v")
466  || ! strcmp (argv[1], "-version")
467  || ! strcmp (argv[1], "--version")))
468  {
469  std::cout << version_msg << std::endl;
470  return 0;
471  }
472 
473  std::list<std::string> cfiles, ccfiles, f77files;
474  std::string output_ext = ".oct";
475  std::string objfiles, libfiles, octfile, outputfile;
476  std::string incflags, defs, ldflags, pass_on_options;
477  bool strip = false;
478  bool no_oct_file_strip_on_this_platform = is_true ("%NO_OCT_FILE_STRIP%");
479  bool link = true;
480  bool link_stand_alone = false;
481  bool depend = false;
482  bool printonly = false;
483 
484  for (int i = 1; i < argc; i++)
485  {
486  std::string arg = argv[i];
487 
489 
490  if (ends_with (arg, ".c"))
491  {
492  file = arg;
493  cfiles.push_back (file);
494  }
495  else if (ends_with (arg, ".cc") || ends_with (arg, ".cp")
496  || ends_with (arg, ".cpp") || ends_with (arg, ".CPP")
497  || ends_with (arg, ".cxx") || ends_with (arg, ".c++")
498  || ends_with (arg, ".C"))
499  {
500  file = arg;
501  ccfiles.push_back (file);
502  }
503  else if (ends_with (arg, ".f") || ends_with (arg, ".F")
504  || ends_with (arg, "f90") || ends_with (arg, ".F90"))
505  {
506  file = arg;
507  f77files.push_back (file);
508  }
509  else if (ends_with (arg, ".o") || ends_with (arg, ".obj"))
510  {
511  file = arg;
512  objfiles += (' ' + quote_path (arg));
513  }
514  else if (ends_with (arg, ".lib") || ends_with (arg, ".a"))
515  {
516  file = arg;
517  libfiles += (' ' + quote_path (arg));
518  }
519  else if (arg == "-d" || arg == "-debug" || arg == "--debug"
520  || arg == "-v" || arg == "-verbose" || arg == "--verbose")
521  {
522  debug = true;
523  if (vars["CC"] == "cc-msvc")
524  vars["CC"] += " -d";
525  if (vars["CXX"] == "cc-msvc")
526  vars["CXX"] += " -d";
527  if (vars["DL_LD"] == "cc-msvc")
528  vars["DL_LD"] += " -d";
529  }
530  else if (arg == "-h" || arg == "-?" || arg == "-help" || arg == "--help")
531  {
532  std::cout << usage_msg << std::endl;
533  std::cout << help_msg << std::endl;
534  return 0;
535  }
536  else if (starts_with (arg, "-I"))
537  {
538  incflags += (' ' + quote_path (arg));
539  }
540  else if (arg == "-idirafter")
541  {
542  if (i < argc-1)
543  {
544  arg = argv[++i];
545  incflags += (" -idirafter " + arg);
546  }
547  else
548  std::cerr << "mkoctfile: include directory name missing"
549  << std::endl;
550  }
551  else if (starts_with (arg, "-D"))
552  {
553  defs += (' ' + arg);
554  }
555  else if (arg == "-largeArrayDims" || arg == "-compatibleArrayDims")
556  {
557  std::cout << "warning: -largeArrayDims and -compatibleArrayDims are accepted for compatibility, but ignored" << std::endl;
558  }
559  else if (starts_with (arg, "-Wl,") || starts_with (arg, "-l")
560  || starts_with (arg, "-L") || starts_with (arg, "-R"))
561  {
562  ldflags += (' ' + arg);
563  }
564 #if ! defined (OCTAVE_USE_WINDOWS_API)
565  else if (arg == "-pthread")
566  {
567  ldflags += (' ' + arg);
568  }
569 #endif
570  else if (arg == "-M" || arg == "-depend" || arg == "--depend")
571  {
572  depend = true;
573  }
574  else if (arg == "-o" || arg == "-output" || arg == "--output")
575  {
576  if (i < argc-1)
577  {
578  arg = argv[++i];
579  outputfile = arg;
580  }
581  else
582  std::cerr << "mkoctfile: output filename missing" << std::endl;
583  }
584  else if (arg == "-n" || arg == "--dry-run" || arg == "--just-print")
585  {
586  printonly = true;
587  }
588  else if (arg == "-p" || arg == "-print" || arg == "--print")
589  {
590  if (i < argc-1)
591  {
592  arg = argv[++i];
593  std::cout << vars[arg] << std::endl;
594  return 0;
595  }
596  else
597  std::cerr << "mkoctfile: --print requires argument" << std::endl;
598  }
599  else if (arg == "-s" || arg == "-strip" || arg == "--strip")
600  {
601  if (no_oct_file_strip_on_this_platform)
602  std::cerr << "mkoctfile: stripping disabled on this platform"
603  << std::endl;
604  else
605  strip = true;
606  }
607  else if (arg == "-c" || arg == "-compile" || arg == "--compile")
608  {
609  link = false;
610  }
611  else if (arg == "-g")
612  {
613  vars["ALL_CFLAGS"] += " -g";
614  vars["ALL_CXXFLAGS"] += " -g";
615  vars["ALL_FFLAGS"] += " -g";
616  }
617  else if (arg == "-link-stand-alone" || arg == "--link-stand-alone")
618  {
619  link_stand_alone = true;
620  }
621  else if (arg == "-mex" || arg == "--mex")
622  {
623  incflags += " -I.";
624 #if defined (_MSC_VER)
625  ldflags += " -Wl,-export:mexFunction";
626 #endif
627  output_ext = ".mex";
628  }
629  else if (starts_with (arg, "-W"))
630  {
631  pass_on_options += (' ' + arg);
632  }
633  else if (starts_with (arg, "-O"))
634  {
635  pass_on_options += (' ' + arg);
636  }
637  else if (starts_with (arg, "-"))
638  {
639  // Pass through any unrecognized options.
640  pass_on_options += (' ' + arg);
641  // Check for an additional argument following the option.
642  // However, don't check the final position which is typically a file
643  if (i < argc-2)
644  {
645  arg = argv[i+1];
646  if (arg[0] != '-')
647  {
648  pass_on_options += (' ' + arg);
649  i++;
650  }
651  }
652  }
653  else
654  {
655  std::cerr << "mkoctfile: unrecognized argument " << arg << std::endl;
656  return 1;
657  }
658 
659  if (! file.empty () && octfile.empty ())
660  octfile = file;
661  }
662 
663  if (output_ext == ".mex"
664  && vars["ALL_CFLAGS"].find ("-g") != std::string::npos)
665  {
666  defs += " -DMEX_DEBUG";
667  }
668 
669  std::string output_option;
670 
671  if (link_stand_alone)
672  {
673  if (! outputfile.empty ())
674  output_option = "-o " + outputfile;
675  }
676  else
677  {
678  if (! outputfile.empty ())
679  {
680  octfile = outputfile;
681  size_t len = octfile.length ();
682  size_t len_ext = output_ext.length ();
683  if (octfile.substr (len-len_ext) != output_ext)
684  octfile += output_ext;
685  }
686  else
687  octfile = basename (octfile, true) + output_ext;
688  }
689 
690  if (depend)
691  {
692  for (const auto& f : cfiles)
693  {
694  std::string dfile = basename (f, true) + ".d", line;
695 
696  octave_unlink_wrapper (dfile.c_str ());
697 
698  std::string cmd
699  = (vars["CC"] + ' ' + vars["DEPEND_FLAGS"] + ' '
700  + vars["CPPFLAGS"] + ' ' + vars["ALL_CFLAGS"] + ' '
701  + incflags + ' ' + defs + ' ' + quote_path (f));
702 
703  FILE *fd = popen (cmd.c_str (), "r");
704  std::ofstream fo (dfile.c_str ());
705  size_t pos;
706  while (! feof (fd))
707  {
708  line = get_line (fd);
709  if ((pos = line.rfind (".o:")) != std::string::npos)
710  {
711  size_t spos = line.rfind ('/', pos);
713  (spos == std::string::npos
714  ? line.substr (0, pos+2)
715  : line.substr (spos+1, pos-spos+1));
716  fo << "pic/" << ofile << ' ' << ofile << ' '
717  << dfile << line.substr (pos) << std::endl;
718  }
719  else
720  fo << line << std::endl;
721  }
722  pclose (fd);
723  fo.close ();
724  }
725 
726  for (const auto& f : ccfiles)
727  {
728  std::string dfile = basename (f, true) + ".d", line;
729 
730  octave_unlink_wrapper (dfile.c_str ());
731 
732  std::string cmd
733  = (vars["CXX"] + ' ' + vars["DEPEND_FLAGS"] + ' '
734  + vars["CPPFLAGS"] + ' ' + vars["ALL_CXXFLAGS"] + ' '
735  + incflags + ' ' + defs + ' ' + quote_path (f));
736 
737  FILE *fd = popen (cmd.c_str (), "r");
738  std::ofstream fo (dfile.c_str ());
739  size_t pos;
740  while (! feof (fd))
741  {
742  line = get_line (fd);
743  if ((pos = line.rfind (".o:")) != std::string::npos)
744  {
745  size_t spos = line.rfind ('/', pos);
747  (spos == std::string::npos
748  ? line.substr (0, pos+2)
749  : line.substr (spos+1, pos-spos+1));
750  fo << "pic/" << ofile << ' ' << ofile << ' '
751  << dfile << line.substr (pos+2) << std::endl;
752  }
753  else
754  fo << line << std::endl;
755  }
756  pclose (fd);
757  fo.close ();
758  }
759 
760  return 0;
761  }
762 
763  for (const auto& f : f77files)
764  {
765  std::string b = basename (f, true);
766 
767  if (! vars["F77"].empty ())
768  {
769  std::string o;
770  if (! outputfile.empty ())
771  {
772  if (link)
773  o = b + ".o";
774  else
775  o = outputfile;
776  }
777  else
778  o = b + ".o";
779  objfiles += (' ' + o);
780 
781  std::string cmd
782  = (vars["F77"] + " -c " + vars["FPICFLAG"] + ' '
783  + vars["ALL_FFLAGS"] + ' ' + incflags + ' ' + defs + ' '
784  + pass_on_options + ' ' + f + " -o " + o);
785 
786  int status = run_command (cmd, printonly);
787 
788  if (status)
789  return status;
790  }
791  else
792  {
793  std::cerr << "mkoctfile: no way to compile Fortran file " << f
794  << std::endl;
795  return 1;
796  }
797  }
798 
799  for (const auto& f : cfiles)
800  {
801  if (! vars["CC"].empty ())
802  {
803  std::string b = basename (f, true), o;
804  if (! outputfile.empty ())
805  {
806  if (link)
807  o = b + ".o";
808  else
809  o = outputfile;
810  }
811  else
812  o = b + ".o";
813  objfiles += (' ' + o);
814 
815  std::string cmd
816  = (vars["CC"] + " -c " + vars["CPPFLAGS"] + ' '
817  + vars["CPICFLAG"] + ' ' + vars["ALL_CFLAGS"] + ' '
818  + pass_on_options + ' ' + incflags + ' ' + defs + ' '
819  + quote_path (f) + " -o " + quote_path (o));
820 
821  int status = run_command (cmd, printonly);
822 
823  if (status)
824  return status;
825  }
826  else
827  {
828  std::cerr << "mkoctfile: no way to compile C file " << f
829  << std::endl;
830  return 1;
831  }
832  }
833 
834  for (const auto& f : ccfiles)
835  {
836  if (! vars["CXX"].empty ())
837  {
838  std::string b = basename (f, true), o;
839  if (! outputfile.empty ())
840  {
841  if (link)
842  o = b + ".o";
843  else
844  o = outputfile;
845  }
846  else
847  o = b + ".o";
848  objfiles += (' ' + o);
849 
850  std::string cmd
851  = (vars["CXX"] + " -c " + vars["CPPFLAGS"] + ' '
852  + vars["CXXPICFLAG"] + ' ' + vars["ALL_CXXFLAGS"] + ' '
853  + pass_on_options + ' ' + incflags + ' ' + defs + ' '
854  + quote_path (f) + " -o " + quote_path (o));
855 
856  int status = run_command (cmd, printonly);
857 
858  if (status)
859  return status;
860  }
861  else
862  {
863  std::cerr << "mkoctfile: no way to compile C++ file " << f
864  << std::endl;
865  return 1;
866  }
867  }
868 
869  if (link && ! objfiles.empty ())
870  {
871  if (link_stand_alone)
872  {
873  if (! vars["LD_CXX"].empty ())
874  {
875  std::string cmd
876  = (vars["LD_CXX"] + ' ' + vars["CPPFLAGS"] + ' '
877  + vars["ALL_CXXFLAGS"] + ' ' + vars["RDYNAMIC_FLAG"] + ' '
878  + vars["ALL_LDFLAGS"] + ' ' + pass_on_options + ' '
879  + output_option + ' ' + objfiles + ' ' + libfiles + ' '
880  + ldflags + ' ' + vars["LFLAGS"] + " -loctinterp -loctave "
881  + vars["OCTAVE_LINK_OPTS"] + ' ' + vars["OCTAVE_LINK_DEPS"]);
882 
883  int status = run_command (cmd, printonly);
884 
885  if (status)
886  return status;
887  }
888  else
889  {
890  std::cerr
891  << "mkoctfile: no way to link stand-alone executable file"
892  << std::endl;
893  return 1;
894  }
895  }
896  else
897  {
898  std::string cmd
899  = (vars["DL_LD"] + ' ' + vars["ALL_CXXFLAGS"] + ' '
900  + vars["DL_LDFLAGS"] + ' ' + pass_on_options
901  + " -o " + octfile + ' ' + objfiles + ' ' + libfiles + ' '
902  + ldflags + ' ' + vars["LFLAGS"] + " -loctinterp -loctave "
903  + vars["OCT_LINK_OPTS"] + ' ' + vars["OCT_LINK_DEPS"]);
904 
905  int status = run_command (cmd, printonly);
906 
907  if (status)
908  return status;
909  }
910 
911  if (strip)
912  {
913  std::string cmd = "strip " + octfile;
914 
915  int status = run_command (cmd, printonly);
916 
917  if (status)
918  return status;
919  }
920  }
921 
922  return 0;
923 }
static void set_octave_home(void)
Definition: shared-fcns.h:102
For example cd octave end example noindent changes the current working directory to file
Definition: dirfns.cc:124
static std::string prepend_octave_exec_home(const std::string &s)
Definition: shared-fcns.h:186
static std::string Voctave_exec_home
Definition: shared-fcns.h:99
static std::string usage_msg
bool octave_wifexited_wrapper(int status)
static std::string help_msg
int unlink(const std::string &name)
Definition: file-ops.cc:618
identity matrix If supplied two scalar respectively For allows like xample val
Definition: data.cc:4986
F77_RET_T const F77_REAL const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE * f
int argc
Definition: load-save.cc:646
nd example oindent opens the file binary numeric values will be read assuming they are stored in IEEE format with the least significant bit and then converted to the native representation Opening a file that is already open simply opens it again and returns a separate file id It is not an error to open a file several though writing to the same file through several different file ids may produce unexpected results The possible values of text mode reading and writing automatically converts linefeeds to the appropriate line end character for the system(carriage-return linefeed on Windows). The default when no mode is specified is binary. Additionally
static std::map< std::string, std::string > vars
Definition: mkoctfile.in.cc:52
static int run_command(const std::string &cmd, bool printonly=false)
bool starts_with(const std::string &s, const std::string &prefix)
nd example oindent opens the file binary numeric values will be read assuming they are stored in IEEE format with the least significant bit and then converted to the native representation Opening a file that is already open simply opens it again and returns a separate file id It is not an error to open a file several though writing to the same file through several different file ids may produce unexpected results The possible values of text mode reading and writing automatically converts linefeeds to the appropriate line end character for the you may append a you must also open the file in binary mode The parameter conversions are currently only supported for and permissions will be set to and then everything is written in a single operation This is very efficient and improves performance c
Definition: file-io.cc:587
static std::string basename(const std::string &s, bool strip_path=false)
s
Definition: file-io.cc:2729
bool ends_with(const std::string &s, const std::string &suffix)
int main(int argc, char **argv)
octave_value arg
Definition: pr-output.cc:3244
string_vector argv
Definition: load-save.cc:648
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:96
static std::string version_msg
create a structure array and initialize its values The dimensions of each cell array of values must match Singleton cells and non cell values are repeated so that they fill the entire array If the cells are empty
Definition: ov-struct.cc:1736
nd deftypefn *std::string name
Definition: sysdep.cc:647
OCTAVE_EXPORT octave_value_list isdir nd deftypefn *std::string nm
Definition: utils.cc:975
int octave_unlink_wrapper(const char *nm)
bool strcmp(const T &str_a, const T &str_b)
True if strings are the same.
Definition: oct-string.cc:112
#define OCTAVE_VERSION
Definition: mkoctfile.in.cc:55
octave_value retval
Definition: data.cc:6246
static std::string Voctave_home
Definition: shared-fcns.h:98
bool is_true(const std::string &s)
int octave_wexitstatus_wrapper(int status)
With real return the complex result
Definition: data.cc:3260
static octave_idx_type find(octave_idx_type i, octave_idx_type *pp)
Definition: colamd.cc:103
charNDArray max(char d, const charNDArray &m)
Definition: chNDArray.cc:227
std::ofstream ofile(filename.c_str(), std::ios::out|std::ios::binary)
static OCTAVE_UNUSED std::string prepend_octave_home(const std::string &s)
Definition: shared-fcns.h:180
b
Definition: cellfun.cc:400
static std::string get_variable(const char *name, const std::string &defval)
for i
Definition: data.cc:5264
static std::string get_line(FILE *fp)
Definition: mkoctfile.in.cc:91
If this string is the system will ring the terminal sometimes it is useful to be able to print the original representation of the string
Definition: utils.cc:888
static std::string quote_path(const std::string &s)