28#if defined (HAVE_CONFIG_H)
44#if defined (OCTAVE_USE_WINDOWS_API)
62# include <sys/types.h>
79#if ! defined (OCTAVE_VERSION)
80# define OCTAVE_VERSION %OCTAVE_CONF_VERSION%
83#if ! defined (OCTAVE_PREFIX)
84# define OCTAVE_PREFIX %OCTAVE_CONF_PREFIX%
87#if ! defined (OCTAVE_EXEC_PREFIX)
88# define OCTAVE_EXEC_PREFIX %OCTAVE_CONF_EXEC_PREFIX%
98 return mkostemps (tmpl, suffixlen, 0);
110 return WIFEXITED (status);
116 return WEXITSTATUS (status);
124 std::ostringstream buf;
128 int c = std::fgetc (fp);
130 if (c ==
'\n' || c == EOF)
133 buf << static_cast<char> (c);
140get_variable (
const char *name,
const std::string& defval)
142 const char *val = getenv (name);
145 return std::string (val);
151quote_path (
const std::string& s)
153 if (s.find (
' ') != std::string::npos && s[0] !=
'"')
154 return '"' + s +
'"';
160replace_prefix (std::string s)
162#if defined (OCTAVE_REPLACE_PREFIX)
163 const std::string match =
"${prefix}";
164 const std::string repl = Voctave_exec_home;
165 std::size_t pos = s.find (match);
166 while (pos != std::string::npos )
169 if (pos > 0 && s[pos-1] !=
'"' && s[pos-1] !=
'\'')
170 s.replace (pos, match.length (), quote_path (repl));
172 s.replace (pos, match.length (), repl);
173 pos = s.find (match);
180static std::map<std::string, std::string>
181make_vars_map (
bool link_stand_alone,
bool verbose,
bool debug)
185 std::map<std::string, std::string> vars;
187 vars[
"OCTAVE_HOME"] = Voctave_home;
188 vars[
"OCTAVE_EXEC_HOME"] = Voctave_exec_home;
190 vars[
"API_VERSION"] = %OCTAVE_API_VERSION%;
191 vars[
"CANONICAL_HOST_TYPE"] = %OCTAVE_CANONICAL_HOST_TYPE%;
192 vars[
"DEFAULT_PAGER"] = %OCTAVE_DEFAULT_PAGER%;
193 vars[
"EXEEXT"] = %OCTAVE_EXEEXT%;
194 vars[
"MAN1EXT"] = %OCTAVE_MAN1EXT%;
225 vars[
"OCTINCLUDEDIR"]
226 = get_variable (
"OCTINCLUDEDIR",
227 prepend_octave_home (%OCTAVE_CONF_OCTINCLUDEDIR%));
230 = get_variable (
"INCLUDEDIR",
231 prepend_octave_home (%OCTAVE_CONF_INCLUDEDIR%));
234 = get_variable (
"LIBDIR", prepend_octave_exec_home (%OCTAVE_CONF_LIBDIR%));
237 = get_variable (
"OCTLIBDIR",
238 prepend_octave_exec_home (%OCTAVE_CONF_OCTLIBDIR%));
240 std::string DEFAULT_INCFLAGS;
242#if defined (OCTAVE_USE_WINDOWS_API)
243 DEFAULT_INCFLAGS =
"-I" + quote_path (vars[
"OCTINCLUDEDIR"] + R
"(\..)")
244 + " -I" + quote_path (vars[
"OCTINCLUDEDIR"]);
246 DEFAULT_INCFLAGS =
"-I" + quote_path (vars[
"OCTINCLUDEDIR"] +
"/..")
247 +
" -I" + quote_path (vars[
"OCTINCLUDEDIR"]);
250 if (vars[
"INCLUDEDIR"] !=
"/usr/include")
251 DEFAULT_INCFLAGS +=
" -I" + quote_path (vars[
"INCLUDEDIR"]);
253 std::string DEFAULT_LDFLAGS;
255 if (vars[
"LIBDIR"] !=
"/usr/lib")
256 DEFAULT_LDFLAGS +=
" -L" + quote_path (vars[
"LIBDIR"]);
258 vars[
"CPPFLAGS"] = get_variable (
"CPPFLAGS",
259 replace_prefix (%OCTAVE_CONF_CPPFLAGS%));
261 vars[
"INCFLAGS"] = get_variable (
"INCFLAGS", DEFAULT_INCFLAGS);
263 vars[
"F77"] = get_variable (
"F77", %OCTAVE_CONF_MKOCTFILE_F77%);
265 vars[
"FFLAGS"] = get_variable (
"FFLAGS", %OCTAVE_CONF_FFLAGS%);
267 vars[
"FPICFLAG"] = get_variable (
"FPICFLAG", %OCTAVE_CONF_FPICFLAG%);
269 vars[
"CC"] = get_variable (
"CC", %OCTAVE_CONF_MKOCTFILE_CC%);
270 if (verbose && vars[
"CC"] ==
"cc-msvc")
273 vars[
"CFLAGS"] = get_variable (
"CFLAGS", %OCTAVE_CONF_CFLAGS%);
275 vars[
"CPICFLAG"] = get_variable (
"CPICFLAG", %OCTAVE_CONF_CPICFLAG%);
277 vars[
"CXX"] = get_variable (
"CXX", %OCTAVE_CONF_MKOCTFILE_CXX%);
278 if (verbose && vars[
"CXX"] ==
"cc-msvc")
279 vars[
"CXX"] +=
" -d";
281 vars[
"CXXFLAGS"] = get_variable (
"CXXFLAGS", %OCTAVE_CONF_CXXFLAGS%);
283 vars[
"CXXLD"] = get_variable (
"CXXLD", vars[
"CXX"]);
284 if (verbose && vars[
"CXXLD"] ==
"cc-msvc")
285 vars[
"CXXLD"] +=
" -d";
287 vars[
"CXXPICFLAG"] = get_variable (
"CXXPICFLAG", %OCTAVE_CONF_CXXPICFLAG%);
289 vars[
"XTRA_CFLAGS"] = get_variable (
"XTRA_CFLAGS", %OCTAVE_CONF_XTRA_CFLAGS%);
291 vars[
"XTRA_CXXFLAGS"] = get_variable (
"XTRA_CXXFLAGS",
292 %OCTAVE_CONF_XTRA_CXXFLAGS%);
294 vars[
"AR"] = get_variable (
"AR", %OCTAVE_CONF_MKOCTFILE_AR%);
296 vars[
"RANLIB"] = get_variable (
"RANLIB", %OCTAVE_CONF_MKOCTFILE_RANLIB%);
298 vars[
"DEPEND_FLAGS"] = get_variable (
"DEPEND_FLAGS",
299 %OCTAVE_CONF_DEPEND_FLAGS%);
301 vars[
"DEPEND_EXTRA_SED_PATTERN"]
302 = get_variable (
"DEPEND_EXTRA_SED_PATTERN",
303 %OCTAVE_CONF_DEPEND_EXTRA_SED_PATTERN%);
305 vars[
"DL_LDFLAGS"] = get_variable (
"DL_LDFLAGS",
306 %OCTAVE_CONF_MKOCTFILE_DL_LDFLAGS%);
308 if (! link_stand_alone)
309 DEFAULT_LDFLAGS +=
' ' + vars[
"DL_LDFLAGS"];
311 vars[
"RDYNAMIC_FLAG"] = get_variable (
"RDYNAMIC_FLAG",
312 %OCTAVE_CONF_RDYNAMIC_FLAG%);
314 vars[
"LIBOCTAVE"] =
"-loctave";
316 vars[
"LIBOCTINTERP"] =
"-loctinterp";
318 vars[
"LIBOCTMEX"] =
"-loctmex";
320 vars[
"READLINE_LIBS"] = %OCTAVE_CONF_READLINE_LIBS%;
322 vars[
"LAPACK_LIBS"] = get_variable (
"LAPACK_LIBS", %OCTAVE_CONF_LAPACK_LIBS%);
324 vars[
"BLAS_LIBS"] = get_variable (
"BLAS_LIBS", %OCTAVE_CONF_BLAS_LIBS%);
326 vars[
"FFTW3_LDFLAGS"]
327 = get_variable (
"FFTW3_LDFLAGS",
328 replace_prefix (%OCTAVE_CONF_FFTW3_LDFLAGS%));
330 vars[
"FFTW3_LIBS"] = get_variable (
"FFTW3_LIBS", %OCTAVE_CONF_FFTW3_LIBS%);
332 vars[
"FFTW3F_LDFLAGS"]
333 = get_variable (
"FFTW3F_LDFLAGS",
334 replace_prefix (%OCTAVE_CONF_FFTW3F_LDFLAGS%));
336 vars[
"FFTW3F_LIBS"] = get_variable (
"FFTW3F_LIBS", %OCTAVE_CONF_FFTW3F_LIBS%);
338 vars[
"LIBS"] = get_variable (
"LIBS", %OCTAVE_CONF_LIBS%);
340 vars[
"FLIBS"] = get_variable (
"FLIBS",
341 replace_prefix (%OCTAVE_CONF_FLIBS%));
343 vars[
"OCTAVE_LINK_DEPS"] = get_variable (
"OCTAVE_LINK_DEPS",
344 replace_prefix (%OCTAVE_CONF_MKOCTFILE_OCTAVE_LINK_DEPS%));
346 vars[
"OCTAVE_LINK_OPTS"] = get_variable (
"OCTAVE_LINK_OPTS",
347 %OCTAVE_CONF_OCTAVE_LINK_OPTS%);
349 vars[
"OCT_LINK_DEPS"] = get_variable (
"OCT_LINK_DEPS",
350 replace_prefix (%OCTAVE_CONF_MKOCTFILE_OCT_LINK_DEPS%));
352 vars[
"OCT_LINK_OPTS"]
353 = get_variable (
"OCT_LINK_OPTS",
354 replace_prefix (%OCTAVE_CONF_OCT_LINK_OPTS%));
356 vars[
"LDFLAGS"] = get_variable (
"LDFLAGS", DEFAULT_LDFLAGS);
358 vars[
"LD_STATIC_FLAG"] = get_variable (
"LD_STATIC_FLAG",
359 %OCTAVE_CONF_LD_STATIC_FLAG%);
361 vars[
"F77_INTEGER8_FLAG"] = get_variable (
"F77_INTEGER8_FLAG",
362 %OCTAVE_CONF_F77_INTEGER_8_FLAG%);
363 vars[
"ALL_FFLAGS"] = vars[
"FFLAGS"] +
' ' + vars[
"F77_INTEGER8_FLAG"];
365 vars[
"ALL_FFLAGS"] +=
" -g";
368 = vars[
"INCFLAGS"] +
' ' + vars[
"XTRA_CFLAGS"] +
' ' + vars[
"CFLAGS"];
370 vars[
"ALL_CFLAGS"] +=
" -g";
373 = vars[
"INCFLAGS"] +
' ' + vars[
"XTRA_CXXFLAGS"] +
' ' + vars[
"CXXFLAGS"];
375 vars[
"ALL_CXXFLAGS"] +=
" -g";
378 = vars[
"LD_STATIC_FLAG"] +
' ' + vars[
"CPICFLAG"] +
' ' + vars[
"LDFLAGS"];
381 = (vars[
"LIBOCTINTERP"] +
' ' + vars[
"LIBOCTAVE"] +
' '
382 + vars[
"SPECIAL_MATH_LIB"]);
384 vars[
"FFTW_LIBS"] = vars[
"FFTW3_LDFLAGS"] +
' ' + vars[
"FFTW3_LIBS"] +
' '
385 + vars[
"FFTW3F_LDFLAGS"] +
' ' + vars[
"FFTW3F_LIBS"];
390static std::string usage_msg =
"usage: mkoctfile [options] file ...";
392static std::string version_msg =
"mkoctfile, version " OCTAVE_VERSION;
394static std::string help_msg =
398 " -h, -?, --help Print this message.\n"
400 " -IDIR Add -IDIR to compile commands.\n"
402 " -idirafter DIR Add -idirafter DIR to compile commands.\n"
404 " -DDEF Add -DDEF to compile commands.\n"
406 " -lLIB Add library LIB to link command.\n"
408 " -LDIR Add -LDIR to link command.\n"
410 " -M, --depend Generate dependency files (.d) for C and C++\n"
412#if ! defined (OCTAVE_USE_WINDOWS_API)
414 " -pthread Add -pthread to link command.\n"
417 " -RDIR Add -RDIR to link command.\n"
419 " -Wl,... Pass flags though the linker like -Wl,-rpath=...\n"
421 " -W... Pass flags though the compiler like -Wa,OPTION.\n"
423 " -c, --compile Compile, but do not link.\n"
425 " -o FILE, --output FILE Output filename. Default extension is .oct\n"
426 " (or .mex if --mex is specified) unless linking\n"
427 " a stand-alone executable.\n"
429 " -g Enable debugging options for compilers.\n"
431 " -p VAR, --print VAR Print configuration variable VAR. There are\n"
432 " three categories of variables:\n"
434 " Octave configuration variables that users may\n"
435 " override with environment variables. These are\n"
436 " used in commands that mkoctfile executes.\n"
438 " ALL_CFLAGS INCLUDEDIR\n"
439 " ALL_CXXFLAGS LAPACK_LIBS\n"
440 " ALL_FFLAGS LDFLAGS\n"
441 " ALL_LDFLAGS LD_STATIC_FLAG\n"
442 " BLAS_LIBS LIBDIR\n"
444 " CFLAGS LIBOCTINTERP\n"
445 " CPICFLAG LIBOCTMEX\n"
446 " CPPFLAGS OCTAVE_LINK_OPTS\n"
447 " CXX OCTINCLUDEDIR\n"
448 " CXXFLAGS OCTAVE_LIBS\n"
449 " CXXLD OCTAVE_LINK_DEPS\n"
450 " CXXPICFLAG OCTLIBDIR\n"
451 " DL_LDFLAGS OCT_LINK_DEPS\n"
452 " F77 OCT_LINK_OPTS\n"
453 " F77_INTEGER8_FLAG RDYNAMIC_FLAG\n"
454 " FFLAGS SPECIAL_MATH_LIB\n"
455 " FPICFLAG XTRA_CFLAGS\n"
456 " INCFLAGS XTRA_CXXFLAGS\n"
458 " Octave configuration variables as above, but\n"
459 " currently unused by mkoctfile.\n"
462 " DEPEND_EXTRA_SED_PATTERN\n"
474 " Octave configuration variables that are provided\n"
475 " for informational purposes only. Except for\n"
476 " OCTAVE_HOME and OCTAVE_EXEC_HOME, users may not\n"
477 " override these variables.\n"
479 " If OCTAVE_HOME or OCTAVE_EXEC_HOME are set in\n"
480 " the environment, then other variables are adjusted\n"
481 " accordingly with OCTAVE_HOME or OCTAVE_EXEC_HOME\n"
482 " substituted for the original value of the directory\n"
483 " specified by the --prefix or --exec-prefix options\n"
484 " that were used when Octave was configured.\n"
486 " API_VERSION LOCALFCNFILEDIR\n"
487 " ARCHLIBDIR LOCALOCTFILEDIR\n"
488 " BINDIR LOCALSTARTUPFILEDIR\n"
489 " CANONICAL_HOST_TYPE LOCALVERARCHLIBDIR\n"
490 " DATADIR LOCALVERFCNFILEDIR\n"
491 " DATAROOTDIR LOCALVEROCTFILEDIR\n"
492 " DEFAULT_PAGER MAN1DIR\n"
493 " EXEC_PREFIX MAN1EXT\n"
495 " FCNFILEDIR OCTAVE_EXEC_HOME\n"
496 " IMAGEDIR OCTAVE_HOME\n"
497 " INFODIR OCTAVE_VERSION\n"
498 " INFOFILE OCTDATADIR\n"
499 " LIBEXECDIR OCTDOCDIR\n"
500 " LOCALAPIARCHLIBDIR OCTFILEDIR\n"
501 " LOCALAPIFCNFILEDIR OCTFONTSDIR\n"
502 " LOCALAPIOCTFILEDIR STARTUPFILEDIR\n"
505 " --link-stand-alone Link a stand-alone executable file.\n"
507 " --mex Assume we are creating a MEX file. Set the\n"
508 " default output extension to \".mex\". Link to\n"
509 " liboctmex instead of liboctinterp and liboctave.\n"
511 " -s, --strip Strip output file.\n"
513 " -n, --just-print, --dry-run\n"
514 " Print commands, but do not execute them.\n"
516 " -v, --verbose Echo commands as they are executed.\n"
518 " --quiet Ignored. Intended to suppress output from\n"
521 " FILE Compile or link FILE. Recognized file types are:\n"
531 " .f Fortran source (fixed form)\n"
532 " .F Fortran source (fixed form)\n"
533 " .f90 Fortran source (free form)\n"
534 " .F90 Fortran source (free form)\n"
537#if defined (_MSC_VER)
538 " .lib library file\n"
543basename (
const std::string& s,
bool strip_path =
false)
547 std::size_t pos = s.rfind (
'.');
549 if (pos == std::string::npos)
552 retval = s.substr (0, pos);
556 std::size_t p1 = retval.rfind (
'/'), p2 = retval.rfind (
'\\');
558 pos = (p1 != std::string::npos && p2 != std::string::npos
559 ? std::max (p1, p2) : (p2 != std::string::npos ? p2 : p1));
561 if (pos != std::string::npos)
562 retval = retval.substr (++pos, std::string::npos);
571 return (s.length () >= prefix.length () && s.find (prefix) == 0);
575ends_with (
const std::string& s,
const std::string& suffix)
577 return (s.length () >= suffix.length ()
578 && s.rfind (suffix) == s.length () - suffix.length ());
582run_command (
const std::string& cmd,
bool verbose,
bool printonly =
false)
586 std::cout << cmd << std::endl;
591 std::cout << cmd << std::endl;
594 int result =
system (cmd.c_str ());
605 return (s ==
"yes" || s ==
"true");
613 tempd = octave_getenv (
"TMPDIR");
615#if defined (__MINGW32__) || defined (_MSC_VER)
618 tempd = octave_getenv (
"TEMP");
621 tempd = octave_getenv (
"TMP");
623#if defined (P_tmpdir)
630 if (tempd.empty () || tempd == R
"(\)")
631 tempd = R"(c:\temp)";
635#if defined (P_tmpdir)
649create_interleaved_complex_file ()
651 std::string tmpl = get_temp_directory () +
"/oct-XXXXXX.c";
653 char *ctmpl =
new char [tmpl.length () + 1];
655 ctmpl = strcpy (ctmpl, tmpl.c_str ());
663 std::string retval (ctmpl);
667 FILE *fid = fdopen (fd,
"w");
668 fputs (
"const int __mx_has_interleaved_complex__ = 1;\n", fid);
675create_mex_soversion_file ()
677 std::string tmpl = get_temp_directory () +
"/oct-XXXXXX.c";
679 char *ctmpl =
new char [tmpl.length () + 1];
681 ctmpl = strcpy (ctmpl, tmpl.c_str ());
689 std::string retval (ctmpl);
693 FILE *fid = fdopen (fd,
"w");
694 fprintf (fid,
"const int __octave_mex_soversion__ = %d;\n",
695 OCTAVE_MEX_SOVERSION);
704 std::string tmpl = get_temp_directory () +
"/oct-XXXXXX.o";
706 char *ctmpl =
new char [tmpl.length () + 1];
708 ctmpl = strcpy (ctmpl, tmpl.c_str ());
715 std::string retval (ctmpl);
722clean_up_tmp_files (
const std::list<std::string>& tmp_files)
724 for (
const auto& file : tmp_files)
728#if defined (OCTAVE_USE_WINDOWS_API) && defined (_UNICODE)
731wmain (
int argc,
wchar_t **sys_argv)
733 std::vector<std::string> argv;
738 std::wstring_convert<std::codecvt_utf8<wchar_t>,
wchar_t> wchar_conv;
739 for (
int i_arg = 0; i_arg < argc; i_arg++)
740 argv.push_back (wchar_conv.to_bytes (sys_argv[i_arg]));
743main (
int argc,
char **sys_argv)
745 std::vector<std::string> argv;
748 for (
int i_arg = 0; i_arg < argc; i_arg++)
749 argv.push_back (sys_argv[i_arg]);
754 std::cout << usage_msg << std::endl;
758 if (argc == 2 && (argv[1] ==
"-v" || argv[1] ==
"-version"
759 || argv[1] ==
"--version"))
761 std::cout << version_msg << std::endl;
765 std::list<std::string> cfiles, ccfiles, f77files, tmp_objfiles;
766 std::string output_ext =
".oct";
767 std::string objfiles, libfiles, octfile, outputfile;
768 std::string incflags, defs, ldflags, pass_on_options;
769 std::string var_to_print;
771 bool verbose =
false;
773 bool no_oct_file_strip_on_this_platform =
is_true (
"%NO_OCT_FILE_STRIP%");
774 bool compile_only =
false;
775 bool link_stand_alone =
false;
777 bool printonly =
false;
778 bool output_file_option =
false;
779 bool creating_mex_file =
false;
780 bool r2017b_option =
false;
781 bool r2018a_option =
false;
783 bool mx_has_interleaved_complex =
false;
784 bool pass_on_followup =
false;
786 for (
int i = 1; i < argc; i++)
788 std::string arg = argv[i];
792 bool found_unknown_dash_arg =
false;
797 cfiles.push_back (file);
805 ccfiles.push_back (file);
811 f77files.push_back (file);
816 objfiles += (
' ' + quote_path (arg));
821 libfiles += (
' ' + quote_path (arg));
823 else if (arg ==
"-d" || arg ==
"-debug" || arg ==
"--debug"
824 || arg ==
"-v" || arg ==
"-verbose" || arg ==
"--verbose")
828 else if (arg ==
"-silent" || arg ==
"--silent"
829 || arg ==
"-quiet" || arg ==
"--quiet")
833 else if (arg ==
"-h" || arg ==
"-?" || arg ==
"-help" || arg ==
"--help")
835 std::cout << usage_msg << std::endl;
836 std::cout << help_msg << std::endl;
841 incflags += (
' ' + quote_path (arg));
843 else if (arg ==
"-idirafter")
848 incflags += (
" -idirafter " + arg);
851 std::cerr <<
"mkoctfile: include directory name missing"
858 else if (arg ==
"-largeArrayDims" || arg ==
"-compatibleArrayDims")
860 std::cerr <<
"mkoctfile: warning: -largeArrayDims and -compatibleArrayDims are accepted for compatibility, but ignored" << std::endl;
862 else if (arg ==
"-R2017b")
866 std::cerr <<
"mkoctfile: only one of -R2017b and -R2018a may be used" << std::endl;
870 r2017b_option =
true;
872 else if (arg ==
"-R2018a")
876 std::cerr <<
"mkoctfile: only one of -R2017b and -R2018a may be used" << std::endl;
880 r2018a_option =
true;
881 mx_has_interleaved_complex =
true;
886 ldflags += (
' ' + quote_path (arg));
888#if ! defined (OCTAVE_USE_WINDOWS_API)
889 else if (arg ==
"-pthread")
891 ldflags += (
' ' + arg);
894 else if (arg ==
"-M" || arg ==
"-depend" || arg ==
"--depend")
898 else if (arg ==
"-o" || arg ==
"-output" || arg ==
"--output")
900 output_file_option =
true;
908 std::cerr <<
"mkoctfile: output filename missing" << std::endl;
910 else if (arg ==
"-n" || arg ==
"--dry-run" || arg ==
"--just-print")
914 else if (arg ==
"-p" || arg ==
"-print" || arg ==
"--print")
920 if (! var_to_print.empty ())
921 std::cerr <<
"mkoctfile: warning: only one '" << arg
922 <<
"' option will be processed" << std::endl;
924 var_to_print = argv[i];
927 std::cerr <<
"mkoctfile: --print requires argument" << std::endl;
929 else if (arg ==
"-s" || arg ==
"-strip" || arg ==
"--strip")
931 if (no_oct_file_strip_on_this_platform)
932 std::cerr <<
"mkoctfile: stripping disabled on this platform"
937 else if (arg ==
"-c" || arg ==
"-compile" || arg ==
"--compile")
941 else if (arg ==
"-g")
945 else if (arg ==
"-link-stand-alone" || arg ==
"--link-stand-alone")
947 link_stand_alone =
true;
949 else if (arg ==
"-mex" || arg ==
"--mex")
951 creating_mex_file =
true;
954#if defined (_MSC_VER)
955 ldflags +=
" -Wl,-export:mexFunction";
961 pass_on_options += (
' ' + arg);
965 pass_on_options += (
' ' + arg);
969 found_unknown_dash_arg =
true;
972 pass_on_options += (
' ' + arg);
978 pass_on_followup =
true;
980 else if (pass_on_followup)
983 pass_on_options += (
' ' + arg);
987 std::cerr <<
"mkoctfile: unrecognized argument " << arg << std::endl;
992 if (! found_unknown_dash_arg)
993 pass_on_followup =
false;
995 if (! file.empty () && octfile.empty ())
999 std::map<std::string, std::string> vars
1000 = make_vars_map (link_stand_alone, verbose, debug);
1002 if (! var_to_print.empty ())
1004 if (vars.find (var_to_print) == vars.end ())
1006 std::cerr <<
"mkoctfile: unknown variable '" << var_to_print <<
"'"
1011 std::cout << vars[var_to_print] << std::endl;
1016 if (creating_mex_file)
1018 if (vars[
"ALL_CFLAGS"].find (
"-g") != std::string::npos)
1019 defs +=
" -DMEX_DEBUG";
1025 std::string tmp_file = create_mex_soversion_file ();
1027 cfiles.push_back (tmp_file);
1029 if (mx_has_interleaved_complex)
1031 defs +=
" -DMX_HAS_INTERLEAVED_COMPLEX=1";
1040 tmp_file = create_interleaved_complex_file ();
1042 cfiles.push_back (tmp_file);
1049 std::cerr <<
"mkoctfile: warning: -R2017b option ignored unless creating mex file"
1053 std::cerr <<
"mkoctfile: warning: -R2018a option ignored unless creating mex file"
1057 if (compile_only && output_file_option
1058 && (cfiles.size () + ccfiles.size () + f77files.size ()) > 1)
1060 std::cerr <<
"mkoctfile: may not use -c and -o with multiple source files"
1065 std::string output_option;
1067 if (link_stand_alone)
1069 if (! outputfile.empty ())
1070 output_option =
"-o " + outputfile;
1074 if (! outputfile.empty ())
1080 octfile = outputfile;
1081 std::size_t
len = octfile.length ();
1082 std::size_t len_ext = output_ext.length ();
1083 if (
len <= len_ext || octfile.substr (
len-len_ext) != output_ext)
1084 octfile += output_ext;
1087 octfile = basename (octfile,
true) + output_ext;
1092#if defined (OCTAVE_USE_WINDOWS_API) && ! defined (_UNICODE)
1093 std::wstring_convert<std::codecvt_utf8<wchar_t>,
wchar_t> wchar_conv;
1096 for (
const auto&
f : cfiles)
1098 std::string dfile = basename (
f,
true) +
".d", line;
1103 = (vars[
"CC"] +
' ' + vars[
"DEPEND_FLAGS"] +
' '
1104 + vars[
"CPPFLAGS"] +
' ' + vars[
"ALL_CFLAGS"] +
' '
1105 + incflags +
' ' + defs +
' ' + quote_path (
f));
1107#if defined (OCTAVE_USE_WINDOWS_API)
1111 std::wstring wcmd = wchar_conv.from_bytes (cmd);
1112 fd = ::_wpopen (wcmd.c_str (), L
"r");
1114 catch (
const std::range_error& e)
1116 fd =
::popen (cmd.c_str (),
"r");
1122 std::wstring wfile = wchar_conv.from_bytes (dfile);
1123 fo.open (wfile.c_str ());
1125 catch (
const std::range_error& e)
1127 fo.open (dfile.c_str ());
1130 FILE *fd =
popen (cmd.c_str (),
"r");
1132 std::ofstream fo (dfile.c_str ());
1138 line = get_line (fd);
1139 if ((pos = line.rfind (
".o:")) != std::string::npos)
1141 std::size_t spos = line.rfind (
'/', pos);
1143 = (spos == std::string::npos
1144 ? line.substr (0, pos+2)
1145 : line.substr (spos+1, pos-spos+1));
1146 fo <<
"pic/" << ofile <<
' ' << ofile <<
' '
1147 << dfile << line.substr (pos) << std::endl;
1150 fo << line << std::endl;
1156 for (
const auto&
f : ccfiles)
1158 std::string dfile = basename (
f,
true) +
".d", line;
1163 = (vars[
"CXX"] +
' ' + vars[
"DEPEND_FLAGS"] +
' '
1164 + vars[
"CPPFLAGS"] +
' ' + vars[
"ALL_CXXFLAGS"] +
' '
1165 + incflags +
' ' + defs +
' ' + quote_path (
f));
1167#if defined (OCTAVE_USE_WINDOWS_API)
1171 std::wstring wcmd = wchar_conv.from_bytes (cmd);
1172 fd = ::_wpopen (wcmd.c_str (), L
"r");
1174 catch (
const std::range_error& e)
1176 fd =
::popen (cmd.c_str (),
"r");
1182 std::wstring wfile = wchar_conv.from_bytes (dfile);
1183 fo.open (wfile.c_str ());
1185 catch (
const std::range_error& e)
1187 fo.open (dfile.c_str ());
1190 FILE *fd =
popen (cmd.c_str (),
"r");
1192 std::ofstream fo (dfile.c_str ());
1198 line = get_line (fd);
1199 if ((pos = line.rfind (
".o:")) != std::string::npos)
1201 std::size_t spos = line.rfind (
'/', pos);
1203 = (spos == std::string::npos
1204 ? line.substr (0, pos+2)
1205 : line.substr (spos+1, pos-spos+1));
1206 fo <<
"pic/" << ofile <<
' ' << ofile <<
' '
1207 << dfile << line.substr (pos+2) << std::endl;
1210 fo << line << std::endl;
1219 for (
const auto&
f : f77files)
1221 if (! vars[
"F77"].empty ())
1226 if (! outputfile.empty ())
1229 o = basename (
f,
true) +
".o";
1233 o = tmp_objfile_name ();
1235 tmp_objfiles.push_back (o);
1237 objfiles += (
' ' + o);
1241 = (vars[
"F77"] +
" -c " + vars[
"FPICFLAG"] +
' '
1242 + vars[
"ALL_FFLAGS"] +
' ' + incflags +
' ' + defs +
' '
1243 + pass_on_options +
' ' + quote_path (
f)
1244 +
" -o " + quote_path (o));
1246 int status = run_command (cmd, verbose, printonly);
1253 std::cerr <<
"mkoctfile: no way to compile Fortran file " <<
f
1259 for (
const auto&
f : cfiles)
1261 if (! vars[
"CC"].empty ())
1266 if (! outputfile.empty ())
1269 o = basename (
f,
true) +
".o";
1273 o = tmp_objfile_name ();
1275 tmp_objfiles.push_back (o);
1277 objfiles += (
' ' + o);
1281 = (vars[
"CC"] +
" -c " + vars[
"CPPFLAGS"] +
' '
1282 + vars[
"CPICFLAG"] +
' ' + vars[
"ALL_CFLAGS"] +
' '
1283 + pass_on_options +
' ' + incflags +
' ' + defs +
' '
1284 + quote_path (
f) +
" -o " + quote_path (o));
1286 int status = run_command (cmd, verbose, printonly);
1293 std::cerr <<
"mkoctfile: no way to compile C file " <<
f
1299 for (
const auto&
f : ccfiles)
1301 if (! vars[
"CXX"].empty ())
1306 if (! outputfile.empty ())
1309 o = basename (
f,
true) +
".o";
1313 o = tmp_objfile_name ();
1315 tmp_objfiles.push_back (o);
1317 objfiles += (
' ' + o);
1321 = (vars[
"CXX"] +
" -c " + vars[
"CPPFLAGS"] +
' '
1322 + vars[
"CXXPICFLAG"] +
' ' + vars[
"ALL_CXXFLAGS"] +
' '
1323 + pass_on_options +
' ' + incflags +
' ' + defs +
' '
1324 + quote_path (
f) +
" -o " + quote_path (o));
1326 int status = run_command (cmd, verbose, printonly);
1333 std::cerr <<
"mkoctfile: no way to compile C++ file " <<
f
1344 if (objfiles.empty ())
1346 std::cerr <<
"mkoctfile: no objects to link" << std::endl;
1350 std::string octave_libs;
1352 if (link_stand_alone)
1354 if (! vars[
"CXXLD"].empty ())
1356 octave_libs =
"-L" + quote_path (vars[
"OCTLIBDIR"])
1357 +
' ' + vars[
"OCTAVE_LIBS"];
1360 = (vars[
"CXXLD"] +
' ' + vars[
"CPPFLAGS"] +
' '
1361 + vars[
"ALL_CXXFLAGS"] +
' ' + vars[
"RDYNAMIC_FLAG"] +
' '
1362 + pass_on_options +
' ' + output_option +
' ' + objfiles +
' '
1363 + libfiles +
' ' + ldflags +
' ' + vars[
"ALL_LDFLAGS"] +
' '
1365 + vars[
"OCTAVE_LINK_OPTS"] +
' ' + vars[
"OCTAVE_LINK_DEPS"]);
1367 int status = run_command (cmd, verbose, printonly);
1369 clean_up_tmp_files (tmp_objfiles);
1377 <<
"mkoctfile: no way to link stand-alone executable file"
1384 if (creating_mex_file)
1385 octave_libs = (
" -L" + quote_path (vars[
"OCTLIBDIR"]) +
' '
1386 + vars[
"LIBOCTMEX"]);
1389 = (vars[
"CXXLD"] +
' ' + vars[
"ALL_CXXFLAGS"] +
' '
1390 + pass_on_options +
" -o " + octfile +
' ' + objfiles +
' '
1391 + libfiles +
' ' + ldflags +
' ' + vars[
"DL_LDFLAGS"] +
' '
1392 + vars[
"LDFLAGS"] +
' ' + octave_libs +
' '
1393 + vars[
"OCT_LINK_OPTS"]);
1395 if (! creating_mex_file)
1396 cmd +=
' ' + vars[
"OCT_LINK_DEPS"];
1398#if defined (OCTAVE_USE_WINDOWS_API) || defined (CROSS) || defined (OCTAVE_LINK_ALL_DEPS)
1399 if (! f77files.empty () && ! vars[
"FLIBS"].empty ())
1400 cmd +=
' ' + vars[
"FLIBS"];
1403 int status = run_command (cmd, verbose, printonly);
1405 clean_up_tmp_files (tmp_objfiles);
1413 std::string cmd =
"strip " + octfile;
1415 int status = run_command (cmd, verbose, printonly);
std::string prepend_octave_home(const std::string &s)
std::string prepend_octave_exec_home(const std::string &s)
int unlink(const std::string &name)
F77_RET_T const F77_DBLE const F77_DBLE * f
int system(const std::string &cmd_str)
#define OCTAVE_ARCHLIBDIR
bool is_true(const std::string &s)
bool ends_with(const std::string &s, const std::string &suffix)
bool starts_with(const std::string &s, const std::string &prefix)
int octave_mkostemps_wrapper(char *tmpl, int suffixlen)
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)