GNU Octave 7.1.0
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//
5// Copyright (C) 2008-2022 The Octave Project Developers
6//
7// See the file COPYRIGHT.md in the top-level directory of this
8// distribution or <https://octave.org/copyright/>.
9//
10// This file is part of Octave.
11//
12// Octave is free software: you can redistribute it and/or modify it
13// under the terms of the GNU General Public License as published by
14// the Free Software Foundation, either version 3 of the License, or
15// (at your option) any later version.
16//
17// Octave is distributed in the hope that it will be useful, but
18// WITHOUT ANY WARRANTY; without even the implied warranty of
19// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20// GNU General Public License for more details.
21//
22// You should have received a copy of the GNU General Public License
23// along with Octave; see the file COPYING. If not, see
24// <https://www.gnu.org/licenses/>.
25//
26////////////////////////////////////////////////////////////////////////
27
28#if defined (HAVE_CONFIG_H)
29# include "config.h"
30#endif
31
32#include <string>
33#include <cstring>
34#include <map>
35#include <list>
36#include <algorithm>
37#include <iostream>
38#include <fstream>
39#include <sstream>
40#include <vector>
41#include <cstdlib>
42
43#if defined (OCTAVE_USE_WINDOWS_API)
44# include <locale>
45# include <codecvt>
46#endif
47
48// Programming note: The CROSS macro here refers to building a
49// cross-compiler aware version of mkoctfile that can be used to cross
50// compile .oct file for Windows builds of Octave, not that mkoctfile
51// itself is being cross compiled.
52//
53// We don't use the wrapper and gnulib functions when we are building
54// with CROSS defined. This configuration is only expected to work on
55// modern systems that should not need to have gnulib to fix POSIX
56// portability problems. So we just assume a working POSIX system when
57// CROSS is defined.
58
59#if defined (CROSS)
60# include <stdlib.h>
61# include <sys/types.h>
62# include <sys/wait.h>
63# include <unistd.h>
64# ifndef OCTAVE_UNUSED
65# define OCTAVE_UNUSED
66# endif
67#else
68// We are linking against static libs so do not decorate with dllimport.
69// FIXME: This should be done by the build system.
70# undef OCTAVE_API
71# define OCTAVE_API
72# include "mkostemps-wrapper.h"
73# include "uniconv-wrappers.h"
74# include "unistd-wrappers.h"
75# include "wait-wrappers.h"
76#endif
77
78#if ! defined (OCTAVE_VERSION)
79# define OCTAVE_VERSION %OCTAVE_CONF_VERSION%
80#endif
81
82#if ! defined (OCTAVE_PREFIX)
83# define OCTAVE_PREFIX %OCTAVE_CONF_PREFIX%
84#endif
85
86#if ! defined (OCTAVE_EXEC_PREFIX)
87# define OCTAVE_EXEC_PREFIX %OCTAVE_CONF_EXEC_PREFIX%
88#endif
89
90#include "shared-fcns.h"
91
92#if defined (CROSS)
93
94static int
95octave_mkostemps_wrapper (char *tmpl, int suffixlen)
96{
97 return mkostemps (tmpl, suffixlen, 0);
98}
99
100static int
101octave_unlink_wrapper (const char *nm)
102{
103 return unlink (nm);
104}
105
106static bool
107octave_wifexited_wrapper (int status)
108{
109 return WIFEXITED (status);
110}
111
112static int
114{
115 return WEXITSTATUS (status);
116}
117
118#endif
119
120static std::string
121get_line (FILE *fp)
122{
123 std::ostringstream buf;
124
125 while (true)
126 {
127 int c = std::fgetc (fp);
128
129 if (c == '\n' || c == EOF)
130 break;
131
132 buf << static_cast<char> (c);
133 }
134
135 return buf.str ();
136}
137
138static std::string
139get_variable (const char *name, const std::string& defval)
140{
141 const char *val = getenv (name);
142
143 if (val && *val)
144 return std::string (val);
145 else
146 return defval;
147}
148
149static std::string
150quote_path (const std::string& s)
151{
152 if (s.find (' ') != std::string::npos && s[0] != '"')
153 return '"' + s + '"';
154 else
155 return s;
156}
157
158static std::string
159replace_prefix (std::string s)
160{
161#if defined (OCTAVE_REPLACE_PREFIX)
162 const std::string match = "${prefix}";
163 const std::string repl = Voctave_exec_home;
164 std::size_t pos = s.find (match);
165 while (pos != std::string::npos )
166 {
167 s.replace (pos, match.length (), repl);
168 pos = s.find (match);
169 }
170#endif
171
172 return s;
173}
174
175static std::map<std::string, std::string>
176make_vars_map (bool link_stand_alone, bool verbose, bool debug)
177{
179
180 std::map<std::string, std::string> vars;
181
182 vars["OCTAVE_HOME"] = Voctave_home;
183 vars["OCTAVE_EXEC_HOME"] = Voctave_exec_home;
184
185 vars["API_VERSION"] = %OCTAVE_API_VERSION%;
186 vars["CANONICAL_HOST_TYPE"] = %OCTAVE_CANONICAL_HOST_TYPE%;
187 vars["DEFAULT_PAGER"] = %OCTAVE_DEFAULT_PAGER%;
188 vars["EXEEXT"] = %OCTAVE_EXEEXT%;
189 vars["MAN1EXT"] = %OCTAVE_MAN1EXT%;
190 vars["OCTAVE_VERSION"] = %OCTAVE_VERSION%;
191
194 vars["DATADIR"] = prepend_octave_home (%OCTAVE_DATADIR%);
195 vars["DATAROOTDIR"] = prepend_octave_home (%OCTAVE_DATAROOTDIR%);
196 vars["FCNFILEDIR"] = prepend_octave_home (%OCTAVE_FCNFILEDIR%);
197 vars["IMAGEDIR"] = prepend_octave_home (%OCTAVE_IMAGEDIR%);
198 vars["INFODIR"] = prepend_octave_home (%OCTAVE_INFODIR%);
199 vars["INFOFILE"] = prepend_octave_home (%OCTAVE_INFOFILE%);
200 vars["LIBEXECDIR"] = prepend_octave_exec_home (%OCTAVE_LIBEXECDIR%);
201 vars["LOCALAPIARCHLIBDIR"] = prepend_octave_exec_home (%OCTAVE_LOCALAPIARCHLIBDIR%);
202 vars["LOCALAPIFCNFILEDIR"] = prepend_octave_home (%OCTAVE_LOCALAPIFCNFILEDIR%);
203 vars["LOCALAPIOCTFILEDIR"] = prepend_octave_exec_home (%OCTAVE_LOCALAPIOCTFILEDIR%);
204 vars["LOCALARCHLIBDIR"] = prepend_octave_exec_home (%OCTAVE_LOCALARCHLIBDIR%);
205 vars["LOCALFCNFILEDIR"] = prepend_octave_home (%OCTAVE_LOCALFCNFILEDIR%);
206 vars["LOCALOCTFILEDIR"] = prepend_octave_exec_home (%OCTAVE_LOCALOCTFILEDIR%);
207 vars["LOCALSTARTUPFILEDIR"] = prepend_octave_home (%OCTAVE_LOCALSTARTUPFILEDIR%);
208 vars["LOCALVERARCHLIBDIR"] = prepend_octave_exec_home (%OCTAVE_LOCALVERARCHLIBDIR%);
209 vars["LOCALVERFCNFILEDIR"] = prepend_octave_home (%OCTAVE_LOCALVERFCNFILEDIR%);
210 vars["LOCALVEROCTFILEDIR"] = prepend_octave_exec_home (%OCTAVE_LOCALVEROCTFILEDIR%);
211 vars["MAN1DIR"] = prepend_octave_home (%OCTAVE_MAN1DIR%);
212 vars["MANDIR"] = prepend_octave_home (%OCTAVE_MANDIR%);
213 vars["OCTDATADIR"] = prepend_octave_home (%OCTAVE_OCTDATADIR%);
214 vars["OCTDOCDIR"] = prepend_octave_home (%OCTAVE_OCTDOCDIR%);
215 vars["OCTFILEDIR"] = prepend_octave_exec_home (%OCTAVE_OCTFILEDIR%);
216 vars["OCTFONTSDIR"] = prepend_octave_home (%OCTAVE_OCTFONTSDIR%);
217 vars["STARTUPFILEDIR"] = prepend_octave_home (%OCTAVE_STARTUPFILEDIR%);
218
219 vars["OCTINCLUDEDIR"]
220 = get_variable ("OCTINCLUDEDIR",
221 prepend_octave_home (%OCTAVE_CONF_OCTINCLUDEDIR%));
222
223 vars["INCLUDEDIR"]
224 = get_variable ("INCLUDEDIR",
225 prepend_octave_home (%OCTAVE_CONF_INCLUDEDIR%));
226
227 vars["LIBDIR"]
228 = get_variable ("LIBDIR", prepend_octave_exec_home (%OCTAVE_CONF_LIBDIR%));
229
230 vars["OCTLIBDIR"]
231 = get_variable ("OCTLIBDIR",
232 prepend_octave_exec_home (%OCTAVE_CONF_OCTLIBDIR%));
233
234 std::string DEFAULT_INCFLAGS;
235
236#if defined (OCTAVE_USE_WINDOWS_API)
237 DEFAULT_INCFLAGS = "-I" + quote_path (vars["OCTINCLUDEDIR"] + R"(\..)")
238 + " -I" + quote_path (vars["OCTINCLUDEDIR"]);
239#else
240 DEFAULT_INCFLAGS = "-I" + quote_path (vars["OCTINCLUDEDIR"] + "/..")
241 + " -I" + quote_path (vars["OCTINCLUDEDIR"]);
242#endif
243
244 if (vars["INCLUDEDIR"] != "/usr/include")
245 DEFAULT_INCFLAGS += " -I" + quote_path (vars["INCLUDEDIR"]);
246
247 std::string DEFAULT_LDFLAGS;
248
249#if (defined (OCTAVE_USE_WINDOWS_API) || defined (CROSS) || defined (OCTAVE_LINK_ALL_DEPS))
250 // We'll be linking the files we compile with -loctinterp and -loctave,
251 // so we need to know where to find them.
252 DEFAULT_LDFLAGS += "-L" + quote_path (vars["OCTLIBDIR"]);
253#endif
254
255 if (vars["LIBDIR"] != "/usr/lib")
256 DEFAULT_LDFLAGS += " -L" + quote_path (vars["LIBDIR"]);
257
258 vars["CPPFLAGS"] = get_variable ("CPPFLAGS",
259 replace_prefix (%OCTAVE_CONF_CPPFLAGS%));
260
261 vars["INCFLAGS"] = get_variable ("INCFLAGS", DEFAULT_INCFLAGS);
262
263 vars["F77"] = get_variable ("F77", %OCTAVE_CONF_MKOCTFILE_F77%);
264
265 vars["FFLAGS"] = get_variable ("FFLAGS", %OCTAVE_CONF_FFLAGS%);
266
267 vars["FPICFLAG"] = get_variable ("FPICFLAG", %OCTAVE_CONF_FPICFLAG%);
268
269 vars["CC"] = get_variable ("CC", %OCTAVE_CONF_MKOCTFILE_CC%);
270 if (verbose && vars["CC"] == "cc-msvc")
271 vars["CC"] += " -d";
272
273 vars["CFLAGS"] = get_variable ("CFLAGS", %OCTAVE_CONF_CFLAGS%);
274
275 vars["CPICFLAG"] = get_variable ("CPICFLAG", %OCTAVE_CONF_CPICFLAG%);
276
277 vars["CXX"] = get_variable ("CXX", %OCTAVE_CONF_MKOCTFILE_CXX%);
278 if (verbose && vars["CXX"] == "cc-msvc")
279 vars["CXX"] += " -d";
280
281 vars["CXXFLAGS"] = get_variable ("CXXFLAGS", %OCTAVE_CONF_CXXFLAGS%);
282
283 vars["CXXLD"] = get_variable ("CXXLD", vars["CXX"]);
284 if (verbose && vars["CXXLD"] == "cc-msvc")
285 vars["CXXLD"] += " -d";
286
287 vars["CXXPICFLAG"] = get_variable ("CXXPICFLAG", %OCTAVE_CONF_CXXPICFLAG%);
288
289 vars["XTRA_CFLAGS"] = get_variable ("XTRA_CFLAGS", %OCTAVE_CONF_XTRA_CFLAGS%);
290
291 vars["XTRA_CXXFLAGS"] = get_variable ("XTRA_CXXFLAGS",
292 %OCTAVE_CONF_XTRA_CXXFLAGS%);
293
294 vars["AR"] = get_variable ("AR", %OCTAVE_CONF_MKOCTFILE_AR%);
295
296 vars["RANLIB"] = get_variable ("RANLIB", %OCTAVE_CONF_MKOCTFILE_RANLIB%);
297
298 vars["DEPEND_FLAGS"] = get_variable ("DEPEND_FLAGS",
299 %OCTAVE_CONF_DEPEND_FLAGS%);
300
301 vars["DEPEND_EXTRA_SED_PATTERN"]
302 = get_variable ("DEPEND_EXTRA_SED_PATTERN",
303 %OCTAVE_CONF_DEPEND_EXTRA_SED_PATTERN%);
304
305 vars["DL_LDFLAGS"] = get_variable ("DL_LDFLAGS",
306 %OCTAVE_CONF_MKOCTFILE_DL_LDFLAGS%);
307
308 if (! link_stand_alone)
309 DEFAULT_LDFLAGS += ' ' + vars["DL_LDFLAGS"];
310
311 vars["RDYNAMIC_FLAG"] = get_variable ("RDYNAMIC_FLAG",
312 %OCTAVE_CONF_RDYNAMIC_FLAG%);
313
314 vars["LIBOCTAVE"] = "-loctave";
315
316 vars["LIBOCTINTERP"] = "-loctinterp";
317
318 vars["READLINE_LIBS"] = "-lreadline";
319
320 vars["LAPACK_LIBS"] = get_variable ("LAPACK_LIBS", %OCTAVE_CONF_LAPACK_LIBS%);
321
322 vars["BLAS_LIBS"] = get_variable ("BLAS_LIBS", %OCTAVE_CONF_BLAS_LIBS%);
323
324 vars["FFTW3_LDFLAGS"]
325 = get_variable ("FFTW3_LDFLAGS",
326 replace_prefix (%OCTAVE_CONF_FFTW3_LDFLAGS%));
327
328 vars["FFTW3_LIBS"] = get_variable ("FFTW3_LIBS", %OCTAVE_CONF_FFTW3_LIBS%);
329
330 vars["FFTW3F_LDFLAGS"]
331 = get_variable ("FFTW3F_LDFLAGS",
332 replace_prefix (%OCTAVE_CONF_FFTW3F_LDFLAGS%));
333
334 vars["FFTW3F_LIBS"] = get_variable ("FFTW3F_LIBS", %OCTAVE_CONF_FFTW3F_LIBS%);
335
336 vars["LIBS"] = get_variable ("LIBS", %OCTAVE_CONF_LIBS%);
337
338 vars["FLIBS"] = get_variable ("FLIBS",
339 replace_prefix (%OCTAVE_CONF_FLIBS%));
340
341 vars["OCTAVE_LINK_DEPS"] = get_variable ("OCTAVE_LINK_DEPS",
342 %OCTAVE_CONF_MKOCTFILE_OCTAVE_LINK_DEPS%);
343
344 vars["OCTAVE_LINK_OPTS"] = get_variable ("OCTAVE_LINK_OPTS",
345 %OCTAVE_CONF_OCTAVE_LINK_OPTS%);
346
347 vars["OCT_LINK_DEPS"] = get_variable ("OCT_LINK_DEPS",
348 %OCTAVE_CONF_MKOCTFILE_OCT_LINK_DEPS%);
349
350 vars["OCT_LINK_OPTS"]
351 = get_variable ("OCT_LINK_OPTS",
352 replace_prefix (%OCTAVE_CONF_OCT_LINK_OPTS%));
353
354 vars["LDFLAGS"] = get_variable ("LDFLAGS", DEFAULT_LDFLAGS);
355
356 vars["LD_STATIC_FLAG"] = get_variable ("LD_STATIC_FLAG",
357 %OCTAVE_CONF_LD_STATIC_FLAG%);
358
359 // FIXME: Remove LFLAGS in Octave 9
360 vars["LFLAGS"] = get_variable ("LFLAGS", DEFAULT_LDFLAGS);
361 if (vars["LFLAGS"] != DEFAULT_LDFLAGS)
362 std::cerr << "mkoctfile: warning: LFLAGS is deprecated and will be removed in a future version of Octave, use LDFLAGS instead" << std::endl;
363
364 vars["F77_INTEGER8_FLAG"] = get_variable ("F77_INTEGER8_FLAG",
365 %OCTAVE_CONF_F77_INTEGER_8_FLAG%);
366 vars["ALL_FFLAGS"] = vars["FFLAGS"] + ' ' + vars["F77_INTEGER8_FLAG"];
367 if (debug)
368 vars["ALL_FFLAGS"] += " -g";
369
370 vars["ALL_CFLAGS"]
371 = vars["INCFLAGS"] + ' ' + vars["XTRA_CFLAGS"] + ' ' + vars["CFLAGS"];
372 if (debug)
373 vars["ALL_CFLAGS"] += " -g";
374
375 vars["ALL_CXXFLAGS"]
376 = vars["INCFLAGS"] + ' ' + vars["XTRA_CXXFLAGS"] + ' ' + vars["CXXFLAGS"];
377 if (debug)
378 vars["ALL_CXXFLAGS"] += " -g";
379
380 vars["ALL_LDFLAGS"]
381 = vars["LD_STATIC_FLAG"] + ' ' + vars["CPICFLAG"] + ' ' + vars["LDFLAGS"];
382
383 vars["OCTAVE_LIBS"]
384 = (vars["LIBOCTINTERP"] + ' ' + vars["LIBOCTAVE"] + ' '
385 + vars["SPECIAL_MATH_LIB"]);
386
387 vars["FFTW_LIBS"] = vars["FFTW3_LDFLAGS"] + ' ' + vars["FFTW3_LIBS"] + ' '
388 + vars["FFTW3F_LDFLAGS"] + ' ' + vars["FFTW3F_LIBS"];
389
390 return vars;
391}
392
393static std::string usage_msg = "usage: mkoctfile [options] file ...";
394
395static std::string version_msg = "mkoctfile, version " OCTAVE_VERSION;
396
397static std::string help_msg =
398 "\n"
399 "Options:\n"
400 "\n"
401 " -h, -?, --help Print this message.\n"
402 "\n"
403 " -IDIR Add -IDIR to compile commands.\n"
404 "\n"
405 " -idirafter DIR Add -idirafter DIR to compile commands.\n"
406 "\n"
407 " -DDEF Add -DDEF to compile commands.\n"
408 "\n"
409 " -lLIB Add library LIB to link command.\n"
410 "\n"
411 " -LDIR Add -LDIR to link command.\n"
412 "\n"
413 " -M, --depend Generate dependency files (.d) for C and C++\n"
414 " source files.\n"
415#if ! defined (OCTAVE_USE_WINDOWS_API)
416 "\n"
417 " -pthread Add -pthread to link command.\n"
418#endif
419 "\n"
420 " -RDIR Add -RDIR to link command.\n"
421 "\n"
422 " -Wl,... Pass flags though the linker like -Wl,-rpath=...\n"
423 "\n"
424 " -W... Pass flags though the compiler like -Wa,OPTION.\n"
425 "\n"
426 " -c, --compile Compile, but do not link.\n"
427 "\n"
428 " -o FILE, --output FILE Output filename. Default extension is .oct\n"
429 " (or .mex if --mex is specified) unless linking\n"
430 " a stand-alone executable.\n"
431 "\n"
432 " -g Enable debugging options for compilers.\n"
433 "\n"
434 " -p VAR, --print VAR Print configuration variable VAR. There are\n"
435 " three categories of variables:\n"
436 "\n"
437 " Octave configuration variables that users may\n"
438 " override with environment variables. These are\n"
439 " used in commands that mkoctfile executes.\n"
440 "\n"
441 " ALL_CFLAGS INCLUDEDIR\n"
442 " ALL_CXXFLAGS LAPACK_LIBS\n"
443 " ALL_FFLAGS LDFLAGS\n"
444 " ALL_LDFLAGS LD_STATIC_FLAG\n"
445 " BLAS_LIBS LIBDIR\n"
446 " CC LIBOCTAVE\n"
447 " CFLAGS LIBOCTINTERP\n"
448 " CPICFLAG OCTAVE_LINK_OPTS\n"
449 " CPPFLAGS OCTINCLUDEDIR\n"
450 " CXX OCTAVE_LIBS\n"
451 " CXXFLAGS OCTAVE_LINK_DEPS\n"
452 " CXXLD OCTLIBDIR\n"
453 " CXXPICFLAG OCT_LINK_DEPS\n"
454 " DL_LDFLAGS OCT_LINK_OPTS\n"
455 " F77 RDYNAMIC_FLAG\n"
456 " F77_INTEGER8_FLAG SPECIAL_MATH_LIB\n"
457 " FFLAGS XTRA_CFLAGS\n"
458 " FPICFLAG XTRA_CXXFLAGS\n"
459 " INCFLAGS\n"
460 "\n"
461 " Octave configuration variables as above, but\n"
462 " currently unused by mkoctfile.\n"
463 "\n"
464 " AR\n"
465 " DEPEND_EXTRA_SED_PATTERN\n"
466 " DEPEND_FLAGS\n"
467 " FFTW3F_LDFLAGS\n"
468 " FFTW3F_LIBS\n"
469 " FFTW3_LDFLAGS\n"
470 " FFTW3_LIBS\n"
471 " FFTW_LIBS\n"
472 " FLIBS\n"
473 " LIBS\n"
474 " RANLIB\n"
475 " READLINE_LIBS\n"
476 "\n"
477 " Octave configuration variables that are provided\n"
478 " for informational purposes only. Except for\n"
479 " OCTAVE_HOME and OCTAVE_EXEC_HOME, users may not\n"
480 " override these variables.\n"
481 "\n"
482 " If OCTAVE_HOME or OCTAVE_EXEC_HOME are set in\n"
483 " the environment, then other variables are adjusted\n"
484 " accordingly with OCTAVE_HOME or OCTAVE_EXEC_HOME\n"
485 " substituted for the original value of the directory\n"
486 " specified by the --prefix or --exec-prefix options\n"
487 " that were used when Octave was configured.\n"
488 "\n"
489 " API_VERSION LOCALFCNFILEDIR\n"
490 " ARCHLIBDIR LOCALOCTFILEDIR\n"
491 " BINDIR LOCALSTARTUPFILEDIR\n"
492 " CANONICAL_HOST_TYPE LOCALVERARCHLIBDIR\n"
493 " DATADIR LOCALVERFCNFILEDIR\n"
494 " DATAROOTDIR LOCALVEROCTFILEDIR\n"
495 " DEFAULT_PAGER MAN1DIR\n"
496 " EXEC_PREFIX MAN1EXT\n"
497 " EXEEXT MANDIR\n"
498 " FCNFILEDIR OCTAVE_EXEC_HOME\n"
499 " IMAGEDIR OCTAVE_HOME\n"
500 " INFODIR OCTAVE_VERSION\n"
501 " INFOFILE OCTDATADIR\n"
502 " LIBEXECDIR OCTDOCDIR\n"
503 " LOCALAPIARCHLIBDIR OCTFILEDIR\n"
504 " LOCALAPIFCNFILEDIR OCTFONTSDIR\n"
505 " LOCALAPIOCTFILEDIR STARTUPFILEDIR\n"
506 " LOCALARCHLIBDIR\n"
507 "\n"
508 " --link-stand-alone Link a stand-alone executable file.\n"
509 "\n"
510 " --mex Assume we are creating a MEX file. Set the\n"
511 " default output extension to \".mex\".\n"
512 "\n"
513 " -s, --strip Strip output file.\n"
514 "\n"
515 " -n, --just-print, --dry-run\n"
516 " Print commands, but do not execute them.\n"
517 "\n"
518 " -v, --verbose Echo commands as they are executed.\n"
519 "\n"
520 " --silent Ignored. Intended to suppress output from\n"
521 " compiler steps.\n"
522 "\n"
523 " FILE Compile or link FILE. Recognized file types are:\n"
524 "\n"
525 " .c C source\n"
526 " .cc C++ source\n"
527 " .cp C++ source\n"
528 " .cpp C++ source\n"
529 " .CPP C++ source\n"
530 " .cxx C++ source\n"
531 " .c++ C++ source\n"
532 " .C C++ source\n"
533 " .f Fortran source (fixed form)\n"
534 " .F Fortran source (fixed form)\n"
535 " .f90 Fortran source (free form)\n"
536 " .F90 Fortran source (free form)\n"
537 " .o object file\n"
538 " .a library file\n"
539#if defined (_MSC_VER)
540 " .lib library file\n"
541#endif
542 "\n";
543
544static std::string
545basename (const std::string& s, bool strip_path = false)
546{
547 std::string retval;
548
549 std::size_t pos = s.rfind ('.');
550
551 if (pos == std::string::npos)
552 retval = s;
553 else
554 retval = s.substr (0, pos);
555
556 if (strip_path)
557 {
558 std::size_t p1 = retval.rfind ('/'), p2 = retval.rfind ('\\');
559
560 pos = (p1 != std::string::npos && p2 != std::string::npos
561 ? std::max (p1, p2) : (p2 != std::string::npos ? p2 : p1));
562
563 if (pos != std::string::npos)
564 retval = retval.substr (++pos, std::string::npos);
565 }
566
567 return retval;
568}
569
570inline bool
571starts_with (const std::string& s, const std::string& prefix)
572{
573 return (s.length () >= prefix.length () && s.find (prefix) == 0);
574}
575
576inline bool
577ends_with (const std::string& s, const std::string& suffix)
578{
579 return (s.length () >= suffix.length ()
580 && s.rfind (suffix) == s.length () - suffix.length ());
581}
582
583static int
584run_command (const std::string& cmd, bool verbose, bool printonly = false)
585{
586 if (printonly)
587 {
588 std::cout << cmd << std::endl;
589 return 0;
590 }
591
592 if (verbose)
593 std::cout << cmd << std::endl;
594
595 // FIXME: Call _wsystem on Windows or octave::sys::system.
596 int result = system (cmd.c_str ());
597
598 if (octave_wifexited_wrapper (result))
599 result = octave_wexitstatus_wrapper (result);
600
601 return result;
602}
603
604bool
605is_true (const std::string& s)
606{
607 return (s == "yes" || s == "true");
608}
609
610static std::string
612{
613 std::string tempd;
614
615 tempd = octave_getenv ("TMPDIR");
616
617#if defined (__MINGW32__) || defined (_MSC_VER)
618
619 if (tempd.empty ())
620 tempd = octave_getenv ("TEMP");
621
622 if (tempd.empty ())
623 tempd = octave_getenv ("TMP");
624
625#if defined (P_tmpdir)
626 if (tempd.empty ())
627 tempd = P_tmpdir;
628#endif
629
630 // Some versions of MinGW and MSVC either don't define P_tmpdir, or
631 // define it to a single backslash. In such cases just use C:\temp.
632 if (tempd.empty () || tempd == R"(\)")
633 tempd = R"(c:\temp)";
634
635#else
636
637#if defined (P_tmpdir)
638 if (tempd.empty ())
639 tempd = P_tmpdir;
640#else
641 if (tempd.empty ())
642 tempd = "/tmp";
643#endif
644
645#endif
646
647 return tempd;
648}
649
650static std::string
652{
653 std::string tmpl = get_temp_directory () + "/oct-XXXXXX.c";
654
655 char *ctmpl = new char [tmpl.length () + 1];
656
657 ctmpl = strcpy (ctmpl, tmpl.c_str ());
658
659 // mkostemps will open the file and return a file descriptor. We
660 // won't worry about closing it because we will need the file until we
661 // are done and then the file will be closed when mkoctfile exits.
662 int fd = octave_mkostemps_wrapper (ctmpl, 2);
663
664 // Make C++ string from filled-in template.
665 std::string retval (ctmpl);
666 delete [] ctmpl;
667
668 // Write symbol definition to file.
669 FILE *fid = fdopen (fd, "w");
670 fputs ("const int __mx_has_interleaved_complex__ = 1;\n", fid);
671 fclose (fid);
672
673 return retval;
674}
675
676static std::string
678{
679 std::string tmpl = get_temp_directory () + "/oct-XXXXXX.o";
680
681 char *ctmpl = new char [tmpl.length () + 1];
682
683 ctmpl = strcpy (ctmpl, tmpl.c_str ());
684
685 // mkostemps will open the file and return a file descriptor. We
686 // won't worry about closing it because we will need the file until we
687 // are done and then the file will be closed when mkoctfile exits.
688 octave_mkostemps_wrapper (ctmpl, 2);
689
690 std::string retval (ctmpl); // make C++ string from filled-in template
691 delete [] ctmpl;
692
693 return retval;
694}
695
696static void
697clean_up_tmp_files (const std::list<std::string>& tmp_files)
698{
699 for (const auto& file : tmp_files)
700 octave_unlink_wrapper (file.c_str ());
701}
702
703#if defined (OCTAVE_USE_WINDOWS_API) && defined (_UNICODE)
704extern "C"
705int
706wmain (int argc, wchar_t **sys_argv)
707{
708 std::vector<std::string> argv;
709
710 // Convert wide character strings to multibyte UTF-8 strings and save
711 // them in a vector of std::string objects for later processing.
712
713 std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> wchar_conv;
714 for (int i_arg = 0; i_arg < argc; i_arg++)
715 argv.push_back (wchar_conv.to_bytes (sys_argv[i_arg]));
716#else
717int
718main (int argc, char **sys_argv)
719{
720 std::vector<std::string> argv;
721
722 // Save args as vector of std::string objects for later processing.
723 for (int i_arg = 0; i_arg < argc; i_arg++)
724 argv.push_back (sys_argv[i_arg]);
725#endif
726
727 if (argc == 1)
728 {
729 std::cout << usage_msg << std::endl;
730 return 1;
731 }
732
733 if (argc == 2 && (argv[1] == "-v" || argv[1] == "-version"
734 || argv[1] == "--version"))
735 {
736 std::cout << version_msg << std::endl;
737 return 0;
738 }
739
740 std::list<std::string> cfiles, ccfiles, f77files, tmp_objfiles;
741 std::string output_ext = ".oct";
742 std::string objfiles, libfiles, octfile, outputfile;
743 std::string incflags, defs, ldflags, pass_on_options;
744 std::string var_to_print;
745 bool debug = false;
746 bool verbose = false;
747 bool strip = false;
748 bool no_oct_file_strip_on_this_platform = is_true ("%NO_OCT_FILE_STRIP%");
749 bool compile_only = false;
750 bool link_stand_alone = false;
751 bool depend = false;
752 bool printonly = false;
753 bool output_file_option = false;
754 bool creating_mex_file = false;
755 bool r2017b_option = false;
756 bool r2018a_option = false;
757 // The default for this may change in the future.
758 bool mx_has_interleaved_complex = false;
759
760 for (int i = 1; i < argc; i++)
761 {
762 std::string arg = argv[i];
763
764 std::string file;
765
766 if (ends_with (arg, ".c"))
767 {
768 file = arg;
769 cfiles.push_back (file);
770 }
771 else if (ends_with (arg, ".cc") || ends_with (arg, ".cp")
772 || ends_with (arg, ".cpp") || ends_with (arg, ".CPP")
773 || ends_with (arg, ".cxx") || ends_with (arg, ".c++")
774 || ends_with (arg, ".C"))
775 {
776 file = arg;
777 ccfiles.push_back (file);
778 }
779 else if (ends_with (arg, ".f") || ends_with (arg, ".F")
780 || ends_with (arg, "f90") || ends_with (arg, ".F90"))
781 {
782 file = arg;
783 f77files.push_back (file);
784 }
785 else if (ends_with (arg, ".o") || ends_with (arg, ".obj"))
786 {
787 file = arg;
788 objfiles += (' ' + quote_path (arg));
789 }
790 else if (ends_with (arg, ".lib") || ends_with (arg, ".a"))
791 {
792 file = arg;
793 libfiles += (' ' + quote_path (arg));
794 }
795 else if (arg == "-d" || arg == "-debug" || arg == "--debug"
796 || arg == "-v" || arg == "-verbose" || arg == "--verbose")
797 {
798 verbose = true;
799 }
800 else if (arg == "-silent" || arg == "--silent")
801 {
802 // Ignored for now.
803 }
804 else if (arg == "-h" || arg == "-?" || arg == "-help" || arg == "--help")
805 {
806 std::cout << usage_msg << std::endl;
807 std::cout << help_msg << std::endl;
808 return 0;
809 }
810 else if (starts_with (arg, "-I"))
811 {
812 incflags += (' ' + quote_path (arg));
813 }
814 else if (arg == "-idirafter")
815 {
816 if (i < argc-1)
817 {
818 arg = argv[++i];
819 incflags += (" -idirafter " + arg);
820 }
821 else
822 std::cerr << "mkoctfile: include directory name missing"
823 << std::endl;
824 }
825 else if (starts_with (arg, "-D"))
826 {
827 defs += (' ' + arg);
828 }
829 else if (arg == "-largeArrayDims" || arg == "-compatibleArrayDims")
830 {
831 std::cerr << "mkoctfile: warning: -largeArrayDims and -compatibleArrayDims are accepted for compatibility, but ignored" << std::endl;
832 }
833 else if (arg == "-R2017b")
834 {
835 if (r2018a_option)
836 {
837 std::cerr << "mkoctfile: only one of -R2017b and -R2018a may be used" << std::endl;
838 return 1;
839 }
840
841 r2017b_option = true;
842 }
843 else if (arg == "-R2018a")
844 {
845 if (r2017b_option)
846 {
847 std::cerr << "mkoctfile: only one of -R2017b and -R2018a may be used" << std::endl;
848 return 1;
849 }
850
851 r2018a_option = true;
852 mx_has_interleaved_complex = true;
853 }
854 else if (starts_with (arg, "-Wl,") || starts_with (arg, "-l")
855 || starts_with (arg, "-L") || starts_with (arg, "-R"))
856 {
857 ldflags += (' ' + quote_path (arg));
858 }
859#if ! defined (OCTAVE_USE_WINDOWS_API)
860 else if (arg == "-pthread")
861 {
862 ldflags += (' ' + arg);
863 }
864#endif
865 else if (arg == "-M" || arg == "-depend" || arg == "--depend")
866 {
867 depend = true;
868 }
869 else if (arg == "-o" || arg == "-output" || arg == "--output")
870 {
871 output_file_option = true;
872
873 if (i < argc-1)
874 {
875 arg = argv[++i];
876 outputfile = arg;
877 }
878 else
879 std::cerr << "mkoctfile: output filename missing" << std::endl;
880 }
881 else if (arg == "-n" || arg == "--dry-run" || arg == "--just-print")
882 {
883 printonly = true;
884 }
885 else if (arg == "-p" || arg == "-print" || arg == "--print")
886 {
887 if (i < argc-1)
888 {
889 ++i;
890
891 // FIXME: Remove LFLAGS checking in Octave 9
892 if (argv[i] == "LFLAGS")
893 std::cerr << "mkoctfile: warning: LFLAGS is deprecated and will be removed in a future version of Octave, use LDFLAGS instead" << std::endl;
894
895 if (! var_to_print.empty ())
896 std::cerr << "mkoctfile: warning: only one '" << arg
897 << "' option will be processed" << std::endl;
898 else
899 var_to_print = argv[i];
900 }
901 else
902 std::cerr << "mkoctfile: --print requires argument" << std::endl;
903 }
904 else if (arg == "-s" || arg == "-strip" || arg == "--strip")
905 {
906 if (no_oct_file_strip_on_this_platform)
907 std::cerr << "mkoctfile: stripping disabled on this platform"
908 << std::endl;
909 else
910 strip = true;
911 }
912 else if (arg == "-c" || arg == "-compile" || arg == "--compile")
913 {
914 compile_only = true;
915 }
916 else if (arg == "-g")
917 {
918 debug = true;
919 }
920 else if (arg == "-link-stand-alone" || arg == "--link-stand-alone")
921 {
922 link_stand_alone = true;
923 }
924 else if (arg == "-mex" || arg == "--mex")
925 {
926 creating_mex_file = true;
927
928 incflags += " -I.";
929#if defined (_MSC_VER)
930 ldflags += " -Wl,-export:mexFunction";
931#endif
932 output_ext = ".mex";
933 }
934 else if (starts_with (arg, "-W"))
935 {
936 pass_on_options += (' ' + arg);
937 }
938 else if (starts_with (arg, "-O"))
939 {
940 pass_on_options += (' ' + arg);
941 }
942 else if (starts_with (arg, "-"))
943 {
944 // Pass through any unrecognized options.
945 pass_on_options += (' ' + arg);
946 // Check for an additional argument following the option.
947 // However, don't check the final position which is typically a file
948 if (i < argc-2)
949 {
950 arg = argv[i+1];
951 if (arg[0] != '-')
952 {
953 pass_on_options += (' ' + arg);
954 i++;
955 }
956 }
957 }
958 else
959 {
960 std::cerr << "mkoctfile: unrecognized argument " << arg << std::endl;
961 return 1;
962 }
963
964 if (! file.empty () && octfile.empty ())
965 octfile = file;
966 }
967
968 std::map<std::string, std::string> vars
969 = make_vars_map (link_stand_alone, verbose, debug);
970
971 if (! var_to_print.empty ())
972 {
973 if (vars.find (var_to_print) == vars.end ())
974 {
975 std::cerr << "mkoctfile: unknown variable '" << var_to_print << "'"
976 << std::endl;
977 return 1;
978 }
979
980 std::cout << vars[var_to_print] << std::endl;
981
982 return 0;
983 }
984
985 if (creating_mex_file)
986 {
987 if (vars["ALL_CFLAGS"].find ("-g") != std::string::npos)
988 defs += " -DMEX_DEBUG";
989
990 if (mx_has_interleaved_complex)
991 {
992 defs += " -DMX_HAS_INTERLEAVED_COMPLEX=1";
993
994 if (! compile_only)
995 {
996 // Create tmp C source file that defines an extern symbol
997 // that can be checked when loading the mex file to
998 // determine that the file was compiled expecting
999 // interleaved complex values.
1000
1001 std::string tmp_file = create_interleaved_complex_file ();
1002
1003 cfiles.push_back (tmp_file);
1004 }
1005 }
1006 }
1007 else
1008 {
1009 if (r2017b_option)
1010 std::cerr << "mkoctfile: warning: -R2017b option ignored unless creating mex file"
1011 << std::endl;
1012
1013 if (r2018a_option)
1014 std::cerr << "mkoctfile: warning: -R2018a option ignored unless creating mex file"
1015 << std::endl;
1016 }
1017
1018 if (compile_only && output_file_option
1019 && (cfiles.size () + ccfiles.size () + f77files.size ()) > 1)
1020 {
1021 std::cerr << "mkoctfile: may not use -c and -o with multiple source files"
1022 << std::endl;
1023 return 1;
1024 }
1025
1026 std::string output_option;
1027
1028 if (link_stand_alone)
1029 {
1030 if (! outputfile.empty ())
1031 output_option = "-o " + outputfile;
1032 }
1033 else
1034 {
1035 if (! outputfile.empty ())
1036 {
1037 // FIXME: should probably do a better job of finding the
1038 // filename extension instead of just looking at the filename
1039 // length.
1040
1041 octfile = outputfile;
1042 std::size_t len = octfile.length ();
1043 std::size_t len_ext = output_ext.length ();
1044 if (len <= len_ext || octfile.substr (len-len_ext) != output_ext)
1045 octfile += output_ext;
1046 }
1047 else
1048 octfile = basename (octfile, true) + output_ext;
1049 }
1050
1051 if (depend)
1052 {
1053#if defined (OCTAVE_USE_WINDOWS_API) && ! defined (_UNICODE)
1054 std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> wchar_conv;
1055#endif
1056
1057 for (const auto& f : cfiles)
1058 {
1059 std::string dfile = basename (f, true) + ".d", line;
1060
1061 octave_unlink_wrapper (dfile.c_str ());
1062
1063 std::string cmd
1064 = (vars["CC"] + ' ' + vars["DEPEND_FLAGS"] + ' '
1065 + vars["CPPFLAGS"] + ' ' + vars["ALL_CFLAGS"] + ' '
1066 + incflags + ' ' + defs + ' ' + quote_path (f));
1067
1068#if defined (OCTAVE_USE_WINDOWS_API)
1069 FILE *fd;
1070 try
1071 {
1072 std::wstring wcmd = wchar_conv.from_bytes (cmd);
1073 fd = ::_wpopen (wcmd.c_str (), L"r");
1074 }
1075 catch (const std::range_error& e)
1076 {
1077 fd = ::popen (cmd.c_str (), "r");
1078 }
1079
1080 std::ofstream fo;
1081 try
1082 {
1083 std::wstring wfile = wchar_conv.from_bytes (dfile);
1084 fo.open (wfile.c_str ());
1085 }
1086 catch (const std::range_error& e)
1087 {
1088 fo.open (dfile.c_str ());
1089 }
1090#else
1091 FILE *fd = popen (cmd.c_str (), "r");
1092
1093 std::ofstream fo (dfile.c_str ());
1094#endif
1095
1096 std::size_t pos;
1097 while (! feof (fd))
1098 {
1099 line = get_line (fd);
1100 if ((pos = line.rfind (".o:")) != std::string::npos)
1101 {
1102 std::size_t spos = line.rfind ('/', pos);
1103 std::string ofile
1104 = (spos == std::string::npos
1105 ? line.substr (0, pos+2)
1106 : line.substr (spos+1, pos-spos+1));
1107 fo << "pic/" << ofile << ' ' << ofile << ' '
1108 << dfile << line.substr (pos) << std::endl;
1109 }
1110 else
1111 fo << line << std::endl;
1112 }
1113 pclose (fd);
1114 fo.close ();
1115 }
1116
1117 for (const auto& f : ccfiles)
1118 {
1119 std::string dfile = basename (f, true) + ".d", line;
1120
1121 octave_unlink_wrapper (dfile.c_str ());
1122
1123 std::string cmd
1124 = (vars["CXX"] + ' ' + vars["DEPEND_FLAGS"] + ' '
1125 + vars["CPPFLAGS"] + ' ' + vars["ALL_CXXFLAGS"] + ' '
1126 + incflags + ' ' + defs + ' ' + quote_path (f));
1127
1128#if defined (OCTAVE_USE_WINDOWS_API)
1129 FILE *fd;
1130 try
1131 {
1132 std::wstring wcmd = wchar_conv.from_bytes (cmd);
1133 fd = ::_wpopen (wcmd.c_str (), L"r");
1134 }
1135 catch (const std::range_error& e)
1136 {
1137 fd = ::popen (cmd.c_str (), "r");
1138 }
1139
1140 std::ofstream fo;
1141 try
1142 {
1143 std::wstring wfile = wchar_conv.from_bytes (dfile);
1144 fo.open (wfile.c_str ());
1145 }
1146 catch (const std::range_error& e)
1147 {
1148 fo.open (dfile.c_str ());
1149 }
1150#else
1151 FILE *fd = popen (cmd.c_str (), "r");
1152
1153 std::ofstream fo (dfile.c_str ());
1154#endif
1155
1156 std::size_t pos;
1157 while (! feof (fd))
1158 {
1159 line = get_line (fd);
1160 if ((pos = line.rfind (".o:")) != std::string::npos)
1161 {
1162 std::size_t spos = line.rfind ('/', pos);
1163 std::string ofile
1164 = (spos == std::string::npos
1165 ? line.substr (0, pos+2)
1166 : line.substr (spos+1, pos-spos+1));
1167 fo << "pic/" << ofile << ' ' << ofile << ' '
1168 << dfile << line.substr (pos+2) << std::endl;
1169 }
1170 else
1171 fo << line << std::endl;
1172 }
1173 pclose (fd);
1174 fo.close ();
1175 }
1176
1177 return 0;
1178 }
1179
1180 for (const auto& f : f77files)
1181 {
1182 if (! vars["F77"].empty ())
1183 {
1184 std::string o;
1185 if (compile_only)
1186 {
1187 if (! outputfile.empty ())
1188 o = outputfile;
1189 else
1190 o = basename (f, true) + ".o";
1191 }
1192 else
1193 {
1194 o = tmp_objfile_name ();
1195
1196 tmp_objfiles.push_back (o);
1197
1198 objfiles += (' ' + o);
1199 }
1200
1201 std::string cmd
1202 = (vars["F77"] + " -c " + vars["FPICFLAG"] + ' '
1203 + vars["ALL_FFLAGS"] + ' ' + incflags + ' ' + defs + ' '
1204 + pass_on_options + ' ' + quote_path (f)
1205 + " -o " + quote_path (o));
1206
1207 int status = run_command (cmd, verbose, printonly);
1208
1209 if (status)
1210 return status;
1211 }
1212 else
1213 {
1214 std::cerr << "mkoctfile: no way to compile Fortran file " << f
1215 << std::endl;
1216 return 1;
1217 }
1218 }
1219
1220 for (const auto& f : cfiles)
1221 {
1222 if (! vars["CC"].empty ())
1223 {
1224 std::string o;
1225 if (compile_only)
1226 {
1227 if (! outputfile.empty ())
1228 o = outputfile;
1229 else
1230 o = basename (f, true) + ".o";
1231 }
1232 else
1233 {
1234 o = tmp_objfile_name ();
1235
1236 tmp_objfiles.push_back (o);
1237
1238 objfiles += (' ' + o);
1239 }
1240
1241 std::string cmd
1242 = (vars["CC"] + " -c " + vars["CPPFLAGS"] + ' '
1243 + vars["CPICFLAG"] + ' ' + vars["ALL_CFLAGS"] + ' '
1244 + pass_on_options + ' ' + incflags + ' ' + defs + ' '
1245 + quote_path (f) + " -o " + quote_path (o));
1246
1247 int status = run_command (cmd, verbose, printonly);
1248
1249 if (status)
1250 return status;
1251 }
1252 else
1253 {
1254 std::cerr << "mkoctfile: no way to compile C file " << f
1255 << std::endl;
1256 return 1;
1257 }
1258 }
1259
1260 for (const auto& f : ccfiles)
1261 {
1262 if (! vars["CXX"].empty ())
1263 {
1264 std::string o;
1265 if (compile_only)
1266 {
1267 if (! outputfile.empty ())
1268 o = outputfile;
1269 else
1270 o = basename (f, true) + ".o";
1271 }
1272 else
1273 {
1274 o = tmp_objfile_name ();
1275
1276 tmp_objfiles.push_back (o);
1277
1278 objfiles += (' ' + o);
1279 }
1280
1281 std::string cmd
1282 = (vars["CXX"] + " -c " + vars["CPPFLAGS"] + ' '
1283 + vars["CXXPICFLAG"] + ' ' + vars["ALL_CXXFLAGS"] + ' '
1284 + pass_on_options + ' ' + incflags + ' ' + defs + ' '
1285 + quote_path (f) + " -o " + quote_path (o));
1286
1287 int status = run_command (cmd, verbose, printonly);
1288
1289 if (status)
1290 return status;
1291 }
1292 else
1293 {
1294 std::cerr << "mkoctfile: no way to compile C++ file " << f
1295 << std::endl;
1296 return 1;
1297 }
1298 }
1299
1300 // If we are only compiling, we are done.
1301
1302 if (compile_only)
1303 return 0;
1304
1305 if (objfiles.empty ())
1306 {
1307 std::cerr << "mkoctfile: no objects to link" << std::endl;
1308 return 1;
1309 }
1310
1311 std::string octave_libs;
1312
1313 if (link_stand_alone)
1314 {
1315 if (! vars["CXXLD"].empty ())
1316 {
1317 octave_libs = "-L" + quote_path (vars["OCTLIBDIR"])
1318 + ' ' + vars["OCTAVE_LIBS"];
1319
1320 // FIXME: Remove LFLAGS in Octave 9
1321 std::string cmd
1322 = (vars["CXXLD"] + ' ' + vars["CPPFLAGS"] + ' '
1323 + vars["ALL_CXXFLAGS"] + ' ' + vars["RDYNAMIC_FLAG"] + ' '
1324 + pass_on_options + ' ' + output_option + ' ' + objfiles + ' '
1325 + libfiles + ' ' + ldflags + ' ' + vars["ALL_LDFLAGS"] + ' '
1326 + vars["LFLAGS"] + ' ' + octave_libs + ' '
1327 + vars["OCTAVE_LINK_OPTS"] + ' ' + vars["OCTAVE_LINK_DEPS"]);
1328
1329 int status = run_command (cmd, verbose, printonly);
1330
1331 clean_up_tmp_files (tmp_objfiles);
1332
1333 if (status)
1334 return status;
1335 }
1336 else
1337 {
1338 std::cerr
1339 << "mkoctfile: no way to link stand-alone executable file"
1340 << std::endl;
1341 return 1;
1342 }
1343 }
1344 else
1345 {
1346#if defined (OCTAVE_USE_WINDOWS_API) || defined(CROSS)
1347 octave_libs = "-L" + quote_path (vars["OCTLIBDIR"])
1348 + ' ' + vars["OCTAVE_LIBS"];
1349#endif
1350
1351 // FIXME: Remove LFLAGS in Octave 9
1352 std::string cmd
1353 = (vars["CXXLD"] + ' ' + vars["ALL_CXXFLAGS"] + ' '
1354 + pass_on_options + " -o " + octfile + ' ' + objfiles + ' '
1355 + libfiles + ' ' + ldflags + ' ' + vars["DL_LDFLAGS"] + ' '
1356 + vars["LDFLAGS"] + ' ' + vars["LFLAGS"] + ' ' + octave_libs + ' '
1357 + vars["OCT_LINK_OPTS"] + ' ' + vars["OCT_LINK_DEPS"]);
1358
1359#if defined (OCTAVE_USE_WINDOWS_API) || defined(CROSS)
1360 if (! f77files.empty () && ! vars["FLIBS"].empty ())
1361 cmd += ' ' + vars["FLIBS"];
1362#endif
1363
1364 int status = run_command (cmd, verbose, printonly);
1365
1366 clean_up_tmp_files (tmp_objfiles);
1367
1368 if (status)
1369 return status;
1370 }
1371
1372 if (strip)
1373 {
1374 std::string cmd = "strip " + octfile;
1375
1376 int status = run_command (cmd, verbose, printonly);
1377
1378 if (status)
1379 return status;
1380 }
1381
1382 return 0;
1383}
charNDArray max(char d, const charNDArray &m)
Definition: chNDArray.cc:230
static octave_idx_type find(octave_idx_type i, octave_idx_type *pp)
Definition: colamd.cc:106
QString name
F77_RET_T const F77_DBLE const F77_DBLE * f
#define OCTAVE_BINDIR
Definition: main.in.cc:71
#define OCTAVE_ARCHLIBDIR
Definition: main.in.cc:67
static std::string version_msg
static std::string quote_path(const std::string &s)
static std::string tmp_objfile_name(void)
static std::string get_line(FILE *fp)
static std::string help_msg
static std::string basename(const std::string &s, bool strip_path=false)
#define OCTAVE_VERSION
Definition: mkoctfile.in.cc:79
bool is_true(const std::string &s)
bool ends_with(const std::string &s, const std::string &suffix)
static int run_command(const std::string &cmd, bool verbose, bool printonly=false)
int main(int argc, char **sys_argv)
static std::string get_temp_directory(void)
static std::string get_variable(const char *name, const std::string &defval)
static std::string replace_prefix(std::string s)
static std::string usage_msg
bool starts_with(const std::string &s, const std::string &prefix)
static std::map< std::string, std::string > make_vars_map(bool link_stand_alone, bool verbose, bool debug)
static void clean_up_tmp_files(const std::list< std::string > &tmp_files)
static std::string create_interleaved_complex_file(void)
int octave_mkostemps_wrapper(char *tmpl, int suffixlen)
std::ofstream ofstream(const std::string &filename, const std::ios::openmode mode)
Definition: lo-sysdep.cc:414
int unlink(const std::string &name)
Definition: file-ops.cc:621
int system(const std::string &cmd_str)
Definition: lo-sysdep.cc:59
static std::map< std::string, std::string > vars
static std::string Voctave_home
Definition: shared-fcns.h:107
static void set_octave_home(void)
Definition: shared-fcns.h:111
static std::string prepend_octave_exec_home(const std::string &s)
Definition: shared-fcns.h:195
static std::string Voctave_exec_home
Definition: shared-fcns.h:108
static std::string octave_getenv(const std::string &name)
Definition: shared-fcns.h:100
static OCTAVE_UNUSED std::string prepend_octave_home(const std::string &s)
Definition: shared-fcns.h:189
int pclose(FILE *f)
Definition: sysdep.cc:711
FILE * popen(const char *command, const char *mode)
Definition: sysdep.cc:695
int octave_unlink_wrapper(const char *nm)
int octave_wexitstatus_wrapper(int status)
bool octave_wifexited_wrapper(int status)
F77_RET_T len
Definition: xerbla.cc:61