28 #if defined (HAVE_CONFIG_H)
43 #if defined (OCTAVE_USE_WINDOWS_API)
61 # include <sys/types.h>
62 # include <sys/wait.h>
64 # ifndef OCTAVE_UNUSED
65 # define OCTAVE_UNUSED
78 #if ! defined (OCTAVE_VERSION)
79 # define OCTAVE_VERSION "9.1.0"
82 #if ! defined (OCTAVE_PREFIX)
83 # define OCTAVE_PREFIX "/usr/local"
86 #if ! defined (OCTAVE_EXEC_PREFIX)
87 # define OCTAVE_EXEC_PREFIX "/usr/local"
97 return mkostemps (tmpl, suffixlen, 0);
109 return WIFEXITED (status);
115 return WEXITSTATUS (status);
123 std::ostringstream buf;
127 int c = std::fgetc (fp);
129 if (c ==
'\n' || c == EOF)
132 buf << static_cast<char> (c);
139 get_variable (
const char *name,
const std::string& defval)
141 const char *val = getenv (name);
144 return std::string (val);
150 quote_path (
const std::string& s)
152 if (s.find (
' ') != std::string::npos && s[0] !=
'"')
153 return '"' + s +
'"';
159 replace_prefix (std::string s)
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 )
168 if (pos > 0 && s[pos-1] !=
'"' && s[pos-1] !=
'\'')
169 s.replace (pos, match.length (), quote_path (repl));
171 s.replace (pos, match.length (), repl);
172 pos = s.find (match);
179 static std::map<std::string, std::string>
180 make_vars_map (
bool link_stand_alone,
bool verbose,
bool debug)
184 std::map<std::string, std::string> vars;
186 vars[
"OCTAVE_HOME"] = Voctave_home;
187 vars[
"OCTAVE_EXEC_HOME"] = Voctave_exec_home;
189 vars[
"API_VERSION"] =
"api-v59";
190 vars[
"CANONICAL_HOST_TYPE"] =
"x86_64-pc-linux-gnu";
191 vars[
"DEFAULT_PAGER"] =
"less";
193 vars[
"MAN1EXT"] =
".1";
194 vars[
"OCTAVE_VERSION"] =
"9.1.0";
223 vars[
"OCTINCLUDEDIR"]
224 = get_variable (
"OCTINCLUDEDIR",
228 = get_variable (
"INCLUDEDIR",
235 = get_variable (
"OCTLIBDIR",
238 std::string DEFAULT_INCFLAGS;
240 #if defined (OCTAVE_USE_WINDOWS_API)
241 DEFAULT_INCFLAGS =
"-I" + quote_path (vars[
"OCTINCLUDEDIR"] + R
"(\..)")
242 + " -I" + quote_path (vars[
"OCTINCLUDEDIR"]);
244 DEFAULT_INCFLAGS =
"-I" + quote_path (vars[
"OCTINCLUDEDIR"] +
"/..")
245 +
" -I" + quote_path (vars[
"OCTINCLUDEDIR"]);
248 if (vars[
"INCLUDEDIR"] !=
"/usr/include")
249 DEFAULT_INCFLAGS +=
" -I" + quote_path (vars[
"INCLUDEDIR"]);
251 std::string DEFAULT_LDFLAGS;
253 #if (defined (OCTAVE_USE_WINDOWS_API) || defined (CROSS) || defined (OCTAVE_LINK_ALL_DEPS))
256 DEFAULT_LDFLAGS +=
"-L" + quote_path (vars[
"OCTLIBDIR"]);
259 if (vars[
"LIBDIR"] !=
"/usr/lib")
260 DEFAULT_LDFLAGS +=
" -L" + quote_path (vars[
"LIBDIR"]);
262 vars[
"CPPFLAGS"] = get_variable (
"CPPFLAGS",
263 replace_prefix (
" "));
265 vars[
"INCFLAGS"] = get_variable (
"INCFLAGS", DEFAULT_INCFLAGS);
267 vars[
"F77"] = get_variable (
"F77",
"gfortran");
269 vars[
"FFLAGS"] = get_variable (
"FFLAGS",
"-g -O2 -std=legacy");
271 vars[
"FPICFLAG"] = get_variable (
"FPICFLAG",
"-fPIC");
273 vars[
"CC"] = get_variable (
"CC",
"gcc");
274 if (verbose && vars[
"CC"] ==
"cc-msvc")
277 vars[
"CFLAGS"] = get_variable (
"CFLAGS",
"-g -O2");
279 vars[
"CPICFLAG"] = get_variable (
"CPICFLAG",
"-fPIC");
281 vars[
"CXX"] = get_variable (
"CXX",
"g++");
282 if (verbose && vars[
"CXX"] ==
"cc-msvc")
283 vars[
"CXX"] +=
" -d";
285 vars[
"CXXFLAGS"] = get_variable (
"CXXFLAGS",
"-g -O2");
287 vars[
"CXXLD"] = get_variable (
"CXXLD", vars[
"CXX"]);
288 if (verbose && vars[
"CXXLD"] ==
"cc-msvc")
289 vars[
"CXXLD"] +=
" -d";
291 vars[
"CXXPICFLAG"] = get_variable (
"CXXPICFLAG",
"-fPIC");
293 vars[
"XTRA_CFLAGS"] = get_variable (
"XTRA_CFLAGS",
" -pthread -fopenmp");
295 vars[
"XTRA_CXXFLAGS"] = get_variable (
"XTRA_CXXFLAGS",
296 " -pthread -fopenmp");
298 vars[
"AR"] = get_variable (
"AR",
"ar");
300 vars[
"RANLIB"] = get_variable (
"RANLIB",
"ranlib");
302 vars[
"DEPEND_FLAGS"] = get_variable (
"DEPEND_FLAGS",
305 vars[
"DEPEND_EXTRA_SED_PATTERN"]
306 = get_variable (
"DEPEND_EXTRA_SED_PATTERN",
309 vars[
"DL_LDFLAGS"] = get_variable (
"DL_LDFLAGS",
310 "-shared -Wl,-Bsymbolic");
312 if (! link_stand_alone)
313 DEFAULT_LDFLAGS +=
' ' + vars[
"DL_LDFLAGS"];
315 vars[
"RDYNAMIC_FLAG"] = get_variable (
"RDYNAMIC_FLAG",
318 vars[
"LIBOCTAVE"] =
"-loctave";
320 vars[
"LIBOCTINTERP"] =
"-loctinterp";
322 vars[
"READLINE_LIBS"] =
"-lreadline";
324 vars[
"LAPACK_LIBS"] = get_variable (
"LAPACK_LIBS",
"");
326 vars[
"BLAS_LIBS"] = get_variable (
"BLAS_LIBS",
"-lopenblas");
328 vars[
"FFTW3_LDFLAGS"]
329 = get_variable (
"FFTW3_LDFLAGS",
330 replace_prefix (
""));
332 vars[
"FFTW3_LIBS"] = get_variable (
"FFTW3_LIBS",
"-lfftw3_threads -lfftw3");
334 vars[
"FFTW3F_LDFLAGS"]
335 = get_variable (
"FFTW3F_LDFLAGS",
336 replace_prefix (
""));
338 vars[
"FFTW3F_LIBS"] = get_variable (
"FFTW3F_LIBS",
"-lfftw3f_threads -lfftw3f");
340 vars[
"LIBS"] = get_variable (
"LIBS",
"-lsundials_ida -lsundials_nvecserial -lklu -lopenblas -L/usr/lib/gcc/x86_64-linux-gnu/11 -L/usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/11/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/11/../../.. -lgfortran -lm -lquadmath -lpthread -lm ");
342 vars[
"FLIBS"] = get_variable (
"FLIBS",
343 replace_prefix (
" -L/usr/lib/gcc/x86_64-linux-gnu/11 -L/usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/11/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/11/../../.. -lgfortran -lm -lquadmath"));
345 vars[
"OCTAVE_LINK_DEPS"] = get_variable (
"OCTAVE_LINK_DEPS",
348 vars[
"OCTAVE_LINK_OPTS"] = get_variable (
"OCTAVE_LINK_OPTS",
351 vars[
"OCT_LINK_DEPS"] = get_variable (
"OCT_LINK_DEPS",
354 vars[
"OCT_LINK_OPTS"]
355 = get_variable (
"OCT_LINK_OPTS",
356 replace_prefix (
" "));
358 vars[
"LDFLAGS"] = get_variable (
"LDFLAGS", DEFAULT_LDFLAGS);
360 vars[
"LD_STATIC_FLAG"] = get_variable (
"LD_STATIC_FLAG",
363 vars[
"F77_INTEGER8_FLAG"] = get_variable (
"F77_INTEGER8_FLAG",
365 vars[
"ALL_FFLAGS"] = vars[
"FFLAGS"] +
' ' + vars[
"F77_INTEGER8_FLAG"];
367 vars[
"ALL_FFLAGS"] +=
" -g";
370 = vars[
"INCFLAGS"] +
' ' + vars[
"XTRA_CFLAGS"] +
' ' + vars[
"CFLAGS"];
372 vars[
"ALL_CFLAGS"] +=
" -g";
375 = vars[
"INCFLAGS"] +
' ' + vars[
"XTRA_CXXFLAGS"] +
' ' + vars[
"CXXFLAGS"];
377 vars[
"ALL_CXXFLAGS"] +=
" -g";
380 = vars[
"LD_STATIC_FLAG"] +
' ' + vars[
"CPICFLAG"] +
' ' + vars[
"LDFLAGS"];
383 = (vars[
"LIBOCTINTERP"] +
' ' + vars[
"LIBOCTAVE"] +
' '
384 + vars[
"SPECIAL_MATH_LIB"]);
386 vars[
"FFTW_LIBS"] = vars[
"FFTW3_LDFLAGS"] +
' ' + vars[
"FFTW3_LIBS"] +
' '
387 + vars[
"FFTW3F_LDFLAGS"] +
' ' + vars[
"FFTW3F_LIBS"];
392 static std::string usage_msg =
"usage: mkoctfile [options] file ...";
394 static std::string version_msg =
"mkoctfile, version " OCTAVE_VERSION;
396 static std::string help_msg =
400 " -h, -?, --help Print this message.\n"
402 " -IDIR Add -IDIR to compile commands.\n"
404 " -idirafter DIR Add -idirafter DIR to compile commands.\n"
406 " -DDEF Add -DDEF to compile commands.\n"
408 " -lLIB Add library LIB to link command.\n"
410 " -LDIR Add -LDIR to link command.\n"
412 " -M, --depend Generate dependency files (.d) for C and C++\n"
414 #if ! defined (OCTAVE_USE_WINDOWS_API)
416 " -pthread Add -pthread to link command.\n"
419 " -RDIR Add -RDIR to link command.\n"
421 " -Wl,... Pass flags though the linker like -Wl,-rpath=...\n"
423 " -W... Pass flags though the compiler like -Wa,OPTION.\n"
425 " -c, --compile Compile, but do not link.\n"
427 " -o FILE, --output FILE Output filename. Default extension is .oct\n"
428 " (or .mex if --mex is specified) unless linking\n"
429 " a stand-alone executable.\n"
431 " -g Enable debugging options for compilers.\n"
433 " -p VAR, --print VAR Print configuration variable VAR. There are\n"
434 " three categories of variables:\n"
436 " Octave configuration variables that users may\n"
437 " override with environment variables. These are\n"
438 " used in commands that mkoctfile executes.\n"
440 " ALL_CFLAGS INCLUDEDIR\n"
441 " ALL_CXXFLAGS LAPACK_LIBS\n"
442 " ALL_FFLAGS LDFLAGS\n"
443 " ALL_LDFLAGS LD_STATIC_FLAG\n"
444 " BLAS_LIBS LIBDIR\n"
446 " CFLAGS LIBOCTINTERP\n"
447 " CPICFLAG OCTAVE_LINK_OPTS\n"
448 " CPPFLAGS OCTINCLUDEDIR\n"
450 " CXXFLAGS OCTAVE_LINK_DEPS\n"
452 " CXXPICFLAG OCT_LINK_DEPS\n"
453 " DL_LDFLAGS OCT_LINK_OPTS\n"
454 " F77 RDYNAMIC_FLAG\n"
455 " F77_INTEGER8_FLAG SPECIAL_MATH_LIB\n"
456 " FFLAGS XTRA_CFLAGS\n"
457 " FPICFLAG XTRA_CXXFLAGS\n"
460 " Octave configuration variables as above, but\n"
461 " currently unused by mkoctfile.\n"
464 " DEPEND_EXTRA_SED_PATTERN\n"
476 " Octave configuration variables that are provided\n"
477 " for informational purposes only. Except for\n"
478 " OCTAVE_HOME and OCTAVE_EXEC_HOME, users may not\n"
479 " override these variables.\n"
481 " If OCTAVE_HOME or OCTAVE_EXEC_HOME are set in\n"
482 " the environment, then other variables are adjusted\n"
483 " accordingly with OCTAVE_HOME or OCTAVE_EXEC_HOME\n"
484 " substituted for the original value of the directory\n"
485 " specified by the --prefix or --exec-prefix options\n"
486 " that were used when Octave was configured.\n"
488 " API_VERSION LOCALFCNFILEDIR\n"
489 " ARCHLIBDIR LOCALOCTFILEDIR\n"
490 " BINDIR LOCALSTARTUPFILEDIR\n"
491 " CANONICAL_HOST_TYPE LOCALVERARCHLIBDIR\n"
492 " DATADIR LOCALVERFCNFILEDIR\n"
493 " DATAROOTDIR LOCALVEROCTFILEDIR\n"
494 " DEFAULT_PAGER MAN1DIR\n"
495 " EXEC_PREFIX MAN1EXT\n"
497 " FCNFILEDIR OCTAVE_EXEC_HOME\n"
498 " IMAGEDIR OCTAVE_HOME\n"
499 " INFODIR OCTAVE_VERSION\n"
500 " INFOFILE OCTDATADIR\n"
501 " LIBEXECDIR OCTDOCDIR\n"
502 " LOCALAPIARCHLIBDIR OCTFILEDIR\n"
503 " LOCALAPIFCNFILEDIR OCTFONTSDIR\n"
504 " LOCALAPIOCTFILEDIR STARTUPFILEDIR\n"
507 " --link-stand-alone Link a stand-alone executable file.\n"
509 " --mex Assume we are creating a MEX file. Set the\n"
510 " default output extension to \".mex\".\n"
512 " -s, --strip Strip output file.\n"
514 " -n, --just-print, --dry-run\n"
515 " Print commands, but do not execute them.\n"
517 " -v, --verbose Echo commands as they are executed.\n"
519 " --silent Ignored. Intended to suppress output from\n"
522 " FILE Compile or link FILE. Recognized file types are:\n"
532 " .f Fortran source (fixed form)\n"
533 " .F Fortran source (fixed form)\n"
534 " .f90 Fortran source (free form)\n"
535 " .F90 Fortran source (free form)\n"
538 #if defined (_MSC_VER)
539 " .lib library file\n"
544 basename (
const std::string& s,
bool strip_path =
false)
548 std::size_t pos = s.rfind (
'.');
550 if (pos == std::string::npos)
553 retval = s.substr (0, pos);
557 std::size_t p1 = retval.rfind (
'/'), p2 = retval.rfind (
'\\');
559 pos = (p1 != std::string::npos && p2 != std::string::npos
560 ?
std::max (p1, p2) : (p2 != std::string::npos ? p2 : p1));
562 if (pos != std::string::npos)
563 retval = retval.substr (++pos, std::string::npos);
572 return (s.length () >= prefix.length () && s.find (prefix) == 0);
576 ends_with (
const std::string& s,
const std::string& suffix)
578 return (s.length () >= suffix.length ()
579 && s.rfind (suffix) == s.length () - suffix.length ());
583 run_command (
const std::string& cmd,
bool verbose,
bool printonly =
false)
587 std::cout << cmd << std::endl;
592 std::cout << cmd << std::endl;
595 int result =
system (cmd.c_str ());
606 return (s ==
"yes" || s ==
"true");
610 get_temp_directory ()
614 tempd = octave_getenv (
"TMPDIR");
616 #if defined (__MINGW32__) || defined (_MSC_VER)
619 tempd = octave_getenv (
"TEMP");
622 tempd = octave_getenv (
"TMP");
624 #if defined (P_tmpdir)
631 if (tempd.empty () || tempd == R
"(\)")
632 tempd = R"(c:\temp)";
636 #if defined (P_tmpdir)
650 create_interleaved_complex_file ()
652 std::string tmpl = get_temp_directory () +
"/oct-XXXXXX.c";
654 char *ctmpl =
new char [tmpl.length () + 1];
656 ctmpl = strcpy (ctmpl, tmpl.c_str ());
664 std::string retval (ctmpl);
668 FILE *fid = fdopen (fd,
"w");
669 fputs (
"const int __mx_has_interleaved_complex__ = 1;\n", fid);
678 std::string tmpl = get_temp_directory () +
"/oct-XXXXXX.o";
680 char *ctmpl =
new char [tmpl.length () + 1];
682 ctmpl = strcpy (ctmpl, tmpl.c_str ());
689 std::string retval (ctmpl);
696 clean_up_tmp_files (
const std::list<std::string>& tmp_files)
698 for (
const auto& file : tmp_files)
702 #if defined (OCTAVE_USE_WINDOWS_API) && defined (_UNICODE)
705 wmain (
int argc,
wchar_t **sys_argv)
707 std::vector<std::string> argv;
712 std::wstring_convert<std::codecvt_utf8<wchar_t>,
wchar_t> wchar_conv;
713 for (
int i_arg = 0; i_arg < argc; i_arg++)
714 argv.push_back (wchar_conv.to_bytes (sys_argv[i_arg]));
717 main (
int argc,
char **sys_argv)
719 std::vector<std::string> argv;
722 for (
int i_arg = 0; i_arg < argc; i_arg++)
723 argv.push_back (sys_argv[i_arg]);
728 std::cout << usage_msg << std::endl;
732 if (argc == 2 && (argv[1] ==
"-v" || argv[1] ==
"-version"
733 || argv[1] ==
"--version"))
735 std::cout << version_msg << std::endl;
739 std::list<std::string> cfiles, ccfiles, f77files, tmp_objfiles;
740 std::string output_ext =
".oct";
741 std::string objfiles, libfiles, octfile, outputfile;
742 std::string incflags, defs, ldflags, pass_on_options;
743 std::string var_to_print;
745 bool verbose =
false;
747 bool no_oct_file_strip_on_this_platform =
is_true (
"false");
748 bool compile_only =
false;
749 bool link_stand_alone =
false;
751 bool printonly =
false;
752 bool output_file_option =
false;
753 bool creating_mex_file =
false;
754 bool r2017b_option =
false;
755 bool r2018a_option =
false;
757 bool mx_has_interleaved_complex =
false;
758 bool pass_on_followup =
false;
760 for (
int i = 1; i < argc; i++)
762 std::string arg = argv[i];
766 bool found_unknown_dash_arg =
false;
771 cfiles.push_back (file);
779 ccfiles.push_back (file);
785 f77files.push_back (file);
790 objfiles += (
' ' + quote_path (arg));
795 libfiles += (
' ' + quote_path (arg));
797 else if (arg ==
"-d" || arg ==
"-debug" || arg ==
"--debug"
798 || arg ==
"-v" || arg ==
"-verbose" || arg ==
"--verbose")
802 else if (arg ==
"-silent" || arg ==
"--silent")
806 else if (arg ==
"-h" || arg ==
"-?" || arg ==
"-help" || arg ==
"--help")
808 std::cout << usage_msg << std::endl;
809 std::cout << help_msg << std::endl;
814 incflags += (
' ' + quote_path (arg));
816 else if (arg ==
"-idirafter")
821 incflags += (
" -idirafter " + arg);
824 std::cerr <<
"mkoctfile: include directory name missing"
831 else if (arg ==
"-largeArrayDims" || arg ==
"-compatibleArrayDims")
833 std::cerr <<
"mkoctfile: warning: -largeArrayDims and -compatibleArrayDims are accepted for compatibility, but ignored" << std::endl;
835 else if (arg ==
"-R2017b")
839 std::cerr <<
"mkoctfile: only one of -R2017b and -R2018a may be used" << std::endl;
843 r2017b_option =
true;
845 else if (arg ==
"-R2018a")
849 std::cerr <<
"mkoctfile: only one of -R2017b and -R2018a may be used" << std::endl;
853 r2018a_option =
true;
854 mx_has_interleaved_complex =
true;
859 ldflags += (
' ' + quote_path (arg));
861 #if ! defined (OCTAVE_USE_WINDOWS_API)
862 else if (arg ==
"-pthread")
864 ldflags += (
' ' + arg);
867 else if (arg ==
"-M" || arg ==
"-depend" || arg ==
"--depend")
871 else if (arg ==
"-o" || arg ==
"-output" || arg ==
"--output")
873 output_file_option =
true;
881 std::cerr <<
"mkoctfile: output filename missing" << std::endl;
883 else if (arg ==
"-n" || arg ==
"--dry-run" || arg ==
"--just-print")
887 else if (arg ==
"-p" || arg ==
"-print" || arg ==
"--print")
893 if (! var_to_print.empty ())
894 std::cerr <<
"mkoctfile: warning: only one '" << arg
895 <<
"' option will be processed" << std::endl;
897 var_to_print = argv[i];
900 std::cerr <<
"mkoctfile: --print requires argument" << std::endl;
902 else if (arg ==
"-s" || arg ==
"-strip" || arg ==
"--strip")
904 if (no_oct_file_strip_on_this_platform)
905 std::cerr <<
"mkoctfile: stripping disabled on this platform"
910 else if (arg ==
"-c" || arg ==
"-compile" || arg ==
"--compile")
914 else if (arg ==
"-g")
918 else if (arg ==
"-link-stand-alone" || arg ==
"--link-stand-alone")
920 link_stand_alone =
true;
922 else if (arg ==
"-mex" || arg ==
"--mex")
924 creating_mex_file =
true;
927 #if defined (_MSC_VER)
928 ldflags +=
" -Wl,-export:mexFunction";
934 pass_on_options += (
' ' + arg);
938 pass_on_options += (
' ' + arg);
942 found_unknown_dash_arg =
true;
945 pass_on_options += (
' ' + arg);
951 pass_on_followup =
true;
953 else if (pass_on_followup)
956 pass_on_options += (
' ' + arg);
960 std::cerr <<
"mkoctfile: unrecognized argument " << arg << std::endl;
965 if (! found_unknown_dash_arg)
966 pass_on_followup =
false;
968 if (! file.empty () && octfile.empty ())
972 std::map<std::string, std::string> vars
973 = make_vars_map (link_stand_alone, verbose, debug);
975 if (! var_to_print.empty ())
977 if (vars.find (var_to_print) == vars.end ())
979 std::cerr <<
"mkoctfile: unknown variable '" << var_to_print <<
"'"
984 std::cout << vars[var_to_print] << std::endl;
989 if (creating_mex_file)
991 if (vars[
"ALL_CFLAGS"].find (
"-g") != std::string::npos)
992 defs +=
" -DMEX_DEBUG";
994 if (mx_has_interleaved_complex)
996 defs +=
" -DMX_HAS_INTERLEAVED_COMPLEX=1";
1005 std::string tmp_file = create_interleaved_complex_file ();
1007 cfiles.push_back (tmp_file);
1014 std::cerr <<
"mkoctfile: warning: -R2017b option ignored unless creating mex file"
1018 std::cerr <<
"mkoctfile: warning: -R2018a option ignored unless creating mex file"
1022 if (compile_only && output_file_option
1023 && (cfiles.size () + ccfiles.size () + f77files.size ()) > 1)
1025 std::cerr <<
"mkoctfile: may not use -c and -o with multiple source files"
1030 std::string output_option;
1032 if (link_stand_alone)
1034 if (! outputfile.empty ())
1035 output_option =
"-o " + outputfile;
1039 if (! outputfile.empty ())
1045 octfile = outputfile;
1046 std::size_t
len = octfile.length ();
1047 std::size_t len_ext = output_ext.length ();
1048 if (
len <= len_ext || octfile.substr (
len-len_ext) != output_ext)
1049 octfile += output_ext;
1052 octfile = basename (octfile,
true) + output_ext;
1057 #if defined (OCTAVE_USE_WINDOWS_API) && ! defined (_UNICODE)
1058 std::wstring_convert<std::codecvt_utf8<wchar_t>,
wchar_t> wchar_conv;
1061 for (
const auto&
f : cfiles)
1063 std::string dfile = basename (
f,
true) +
".d",
line;
1068 = (vars[
"CC"] +
' ' + vars[
"DEPEND_FLAGS"] +
' '
1069 + vars[
"CPPFLAGS"] +
' ' + vars[
"ALL_CFLAGS"] +
' '
1070 + incflags +
' ' + defs +
' ' + quote_path (
f));
1072 #if defined (OCTAVE_USE_WINDOWS_API)
1076 std::wstring wcmd = wchar_conv.from_bytes (cmd);
1077 fd = ::_wpopen (wcmd.c_str (), L
"r");
1079 catch (
const std::range_error& e)
1081 fd =
::popen (cmd.c_str (),
"r");
1087 std::wstring wfile = wchar_conv.from_bytes (dfile);
1088 fo.open (wfile.c_str ());
1090 catch (
const std::range_error& e)
1092 fo.open (dfile.c_str ());
1095 FILE *fd =
popen (cmd.c_str (),
"r");
1103 line = get_line (fd);
1104 if ((pos =
line.rfind (
".o:")) != std::string::npos)
1106 std::size_t spos =
line.rfind (
'/', pos);
1108 = (spos == std::string::npos
1109 ?
line.substr (0, pos+2)
1110 :
line.substr (spos+1, pos-spos+1));
1111 fo <<
"pic/" << ofile <<
' ' << ofile <<
' '
1112 << dfile <<
line.substr (pos) << std::endl;
1115 fo <<
line << std::endl;
1121 for (
const auto&
f : ccfiles)
1123 std::string dfile = basename (
f,
true) +
".d",
line;
1128 = (vars[
"CXX"] +
' ' + vars[
"DEPEND_FLAGS"] +
' '
1129 + vars[
"CPPFLAGS"] +
' ' + vars[
"ALL_CXXFLAGS"] +
' '
1130 + incflags +
' ' + defs +
' ' + quote_path (
f));
1132 #if defined (OCTAVE_USE_WINDOWS_API)
1136 std::wstring wcmd = wchar_conv.from_bytes (cmd);
1137 fd = ::_wpopen (wcmd.c_str (), L
"r");
1139 catch (
const std::range_error& e)
1141 fd =
::popen (cmd.c_str (),
"r");
1147 std::wstring wfile = wchar_conv.from_bytes (dfile);
1148 fo.open (wfile.c_str ());
1150 catch (
const std::range_error& e)
1152 fo.open (dfile.c_str ());
1155 FILE *fd =
popen (cmd.c_str (),
"r");
1163 line = get_line (fd);
1164 if ((pos =
line.rfind (
".o:")) != std::string::npos)
1166 std::size_t spos =
line.rfind (
'/', pos);
1168 = (spos == std::string::npos
1169 ?
line.substr (0, pos+2)
1170 :
line.substr (spos+1, pos-spos+1));
1171 fo <<
"pic/" << ofile <<
' ' << ofile <<
' '
1172 << dfile <<
line.substr (pos+2) << std::endl;
1175 fo <<
line << std::endl;
1184 for (
const auto&
f : f77files)
1186 if (! vars[
"F77"].empty ())
1191 if (! outputfile.empty ())
1194 o = basename (
f,
true) +
".o";
1198 o = tmp_objfile_name ();
1200 tmp_objfiles.push_back (o);
1202 objfiles += (
' ' + o);
1206 = (vars[
"F77"] +
" -c " + vars[
"FPICFLAG"] +
' '
1207 + vars[
"ALL_FFLAGS"] +
' ' + incflags +
' ' + defs +
' '
1208 + pass_on_options +
' ' + quote_path (
f)
1209 +
" -o " + quote_path (o));
1211 int status = run_command (cmd, verbose, printonly);
1218 std::cerr <<
"mkoctfile: no way to compile Fortran file " <<
f
1224 for (
const auto&
f : cfiles)
1226 if (! vars[
"CC"].empty ())
1231 if (! outputfile.empty ())
1234 o = basename (
f,
true) +
".o";
1238 o = tmp_objfile_name ();
1240 tmp_objfiles.push_back (o);
1242 objfiles += (
' ' + o);
1246 = (vars[
"CC"] +
" -c " + vars[
"CPPFLAGS"] +
' '
1247 + vars[
"CPICFLAG"] +
' ' + vars[
"ALL_CFLAGS"] +
' '
1248 + pass_on_options +
' ' + incflags +
' ' + defs +
' '
1249 + quote_path (
f) +
" -o " + quote_path (o));
1251 int status = run_command (cmd, verbose, printonly);
1258 std::cerr <<
"mkoctfile: no way to compile C file " <<
f
1264 for (
const auto&
f : ccfiles)
1266 if (! vars[
"CXX"].empty ())
1271 if (! outputfile.empty ())
1274 o = basename (
f,
true) +
".o";
1278 o = tmp_objfile_name ();
1280 tmp_objfiles.push_back (o);
1282 objfiles += (
' ' + o);
1286 = (vars[
"CXX"] +
" -c " + vars[
"CPPFLAGS"] +
' '
1287 + vars[
"CXXPICFLAG"] +
' ' + vars[
"ALL_CXXFLAGS"] +
' '
1288 + pass_on_options +
' ' + incflags +
' ' + defs +
' '
1289 + quote_path (
f) +
" -o " + quote_path (o));
1291 int status = run_command (cmd, verbose, printonly);
1298 std::cerr <<
"mkoctfile: no way to compile C++ file " <<
f
1309 if (objfiles.empty ())
1311 std::cerr <<
"mkoctfile: no objects to link" << std::endl;
1315 std::string octave_libs;
1317 if (link_stand_alone)
1319 if (! vars[
"CXXLD"].empty ())
1321 octave_libs =
"-L" + quote_path (vars[
"OCTLIBDIR"])
1322 +
' ' + vars[
"OCTAVE_LIBS"];
1325 = (vars[
"CXXLD"] +
' ' + vars[
"CPPFLAGS"] +
' '
1326 + vars[
"ALL_CXXFLAGS"] +
' ' + vars[
"RDYNAMIC_FLAG"] +
' '
1327 + pass_on_options +
' ' + output_option +
' ' + objfiles +
' '
1328 + libfiles +
' ' + ldflags +
' ' + vars[
"ALL_LDFLAGS"] +
' '
1330 + vars[
"OCTAVE_LINK_OPTS"] +
' ' + vars[
"OCTAVE_LINK_DEPS"]);
1332 int status = run_command (cmd, verbose, printonly);
1334 clean_up_tmp_files (tmp_objfiles);
1342 <<
"mkoctfile: no way to link stand-alone executable file"
1349 #if defined (OCTAVE_USE_WINDOWS_API) || defined(CROSS)
1350 octave_libs =
"-L" + quote_path (vars[
"OCTLIBDIR"])
1351 +
' ' + vars[
"OCTAVE_LIBS"];
1355 = (vars[
"CXXLD"] +
' ' + vars[
"ALL_CXXFLAGS"] +
' '
1356 + pass_on_options +
" -o " + octfile +
' ' + objfiles +
' '
1357 + libfiles +
' ' + ldflags +
' ' + vars[
"DL_LDFLAGS"] +
' '
1358 + vars[
"LDFLAGS"] +
' ' + octave_libs +
' '
1359 + vars[
"OCT_LINK_OPTS"] +
' ' + vars[
"OCT_LINK_DEPS"]);
1361 #if defined (OCTAVE_USE_WINDOWS_API) || defined(CROSS)
1362 if (! f77files.empty () && ! vars[
"FLIBS"].empty ())
1363 cmd +=
' ' + vars[
"FLIBS"];
1366 int status = run_command (cmd, verbose, printonly);
1368 clean_up_tmp_files (tmp_objfiles);
1376 std::string cmd =
"strip " + octfile;
1378 int status = run_command (cmd, verbose, printonly);
charNDArray max(char d, const charNDArray &m)
std::string prepend_octave_home(const std::string &s)
std::string prepend_octave_exec_home(const std::string &s)
F77_RET_T const F77_DBLE const F77_DBLE * f
int system(const std::string &cmd_str)
std::ofstream ofstream(const std::string &filename, const std::ios::openmode mode)
bool is_true(const std::string &s)
bool ends_with(const std::string &s, const std::string &suffix)
int main(int argc, char **sys_argv)
bool starts_with(const std::string &s, const std::string &prefix)
int octave_mkostemps_wrapper(char *tmpl, int suffixlen)
int unlink(const std::string &name)
FILE * popen(const char *command, const char *mode)
int octave_unlink_wrapper(const char *nm)
int octave_wexitstatus_wrapper(int status)
bool octave_wifexited_wrapper(int status)