24 #if defined (HAVE_CONFIG_H)
42 #include <sys/types.h>
44 #if defined HAVE_SYS_WAIT_H
49 #define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
53 #define WEXITSTATUS(stat_val) (static_cast<unsigned> (stat_val) >> 8)
56 static std::map<std::string, std::string>
vars;
58 #ifndef OCTAVE_VERSION
59 #define OCTAVE_VERSION "4.0.0"
63 #define OCTAVE_PREFIX "/usr/local"
71 static std::vector<char> buf (100);
77 c = gnulib::fgetc (fp);
78 if (c ==
'\n' || c == EOF)
80 if (buf.size () <= idx)
81 buf.resize (buf.size () + 100);
85 return std::string (
"");
87 return std::string (&buf[0], idx);
94 const char *val = getenv (name);
96 return std::string (val);
104 if (s.find (
' ') != std::string::npos && s[0] !=
'"')
105 return "\"" + s +
"\"";
118 std::string DEFAULT_OCTINCLUDEDIR =
"/usr/local/include/octave-4.0.0/octave";
119 std::string DEFAULT_INCLUDEDIR =
"/usr/local/include";
120 std::string DEFAULT_LIBDIR =
"/usr/local/lib";
121 std::string DEFAULT_OCTLIBDIR =
"/usr/local/lib/octave/4.0.0";
128 vars[
"OCTINCLUDEDIR"] =
get_variable (
"OCTINCLUDEDIR", DEFAULT_OCTINCLUDEDIR);
129 vars[
"INCLUDEDIR"] =
get_variable (
"INCLUDEDIR", DEFAULT_INCLUDEDIR);
130 vars[
"LIBDIR"] =
get_variable (
"LIBDIR", DEFAULT_LIBDIR);
131 vars[
"OCTLIBDIR"] =
get_variable (
"OCTLIBDIR", DEFAULT_OCTLIBDIR);
133 #if defined (__WIN32__) && ! defined (_POSIX_VERSION)
134 std::string DEFAULT_INCFLAGS
135 =
"-I" +
quote_path (vars[
"OCTINCLUDEDIR"] +
"\\..")
138 std::string DEFAULT_INCFLAGS
139 =
"-I" +
quote_path (vars[
"OCTINCLUDEDIR"] +
"/..")
142 if (vars[
"INCLUDEDIR"] !=
"/usr/include")
143 DEFAULT_INCFLAGS +=
" -I" +
quote_path (vars[
"INCLUDEDIR"]);
145 std::string DEFAULT_LFLAGS =
"-L" +
quote_path (vars[
"OCTLIBDIR"]);
146 if (vars[
"LIBDIR"] !=
"/usr/lib")
147 DEFAULT_LFLAGS +=
" -L" +
quote_path (vars[
"LIBDIR"]);
149 vars[
"CPPFLAGS"] =
get_variable (
"CPPFLAGS",
"-I/usr/include/hdf5/serial");
150 vars[
"INCFLAGS"] =
get_variable (
"INCFLAGS", DEFAULT_INCFLAGS);
159 vars[
"CXXPICFLAG"] =
get_variable (
"CXXPICFLAG",
"-fPIC");
160 vars[
"XTRA_CFLAGS"] =
get_variable (
"XTRA_CFLAGS",
"-pthread -fopenmp");
162 "-pthread -fopenmp");
169 vars[
"DEPEND_EXTRA_SED_PATTERN"] =
get_variable (
"DEPEND_EXTRA_SED_PATTERN",
174 "-shared -Wl,-Bsymbolic");
178 vars[
"LIBOCTAVE"] =
"-loctave";
179 vars[
"LIBOCTINTERP"] =
"-loctinterp";
180 vars[
"READLINE_LIBS"] =
"-lreadline";
182 vars[
"BLAS_LIBS"] =
get_variable (
"BLAS_LIBS",
"-lopenblas");
185 vars[
"FFTW3_LIBS"] =
get_variable (
"FFTW3_LIBS",
"-lfftw3_threads -lfftw3");
186 vars[
"FFTW3F_LDFLAGS"] =
get_variable (
"FFTW3F_LDFLAGS",
188 vars[
"FFTW3F_LIBS"] =
get_variable (
"FFTW3F_LIBS",
"-lfftw3f_threads -lfftw3f");
190 vars[
"FLIBS"] =
get_variable (
"FLIBS",
"-L/usr/lib/x86_64-linux-gnu/hdf5/serial -L/usr/lib/gcc/x86_64-linux-gnu/4.9 -L/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../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/4.9/../../.. -lgfortran -lm -lquadmath");
191 vars[
"OCTAVE_LINK_DEPS"] =
get_variable (
"OCTAVE_LINK_DEPS",
193 vars[
"OCTAVE_LINK_OPTS"] =
get_variable (
"OCTAVE_LINK_OPTS",
198 "-L/usr/lib/x86_64-linux-gnu/hdf5/serial ");
200 vars[
"LDFLAGS"] =
get_variable (
"LDFLAGS",
"-L/usr/lib/x86_64-linux-gnu/hdf5/serial");
201 vars[
"LD_STATIC_FLAG"] =
get_variable (
"LD_STATIC_FLAG",
203 vars[
"LFLAGS"] =
get_variable (
"LFLAGS", DEFAULT_LFLAGS);
204 vars[
"F77_INTEGER8_FLAG"] =
get_variable (
"F77_INTEGER8_FLAG",
207 vars[
"ALL_FFLAGS"] = vars[
"FFLAGS"] +
" " + vars[
"F77_INTEGER8_FLAG"];
209 vars[
"ALL_CFLAGS"] = vars[
"INCFLAGS"] +
" " + vars[
"XTRA_CFLAGS"] +
" "
212 vars[
"ALL_CXXFLAGS"] = vars[
"INCFLAGS"] +
" " + vars[
"XTRA_CXXFLAGS"] +
" "
215 vars[
"ALL_LDFLAGS"] = vars[
"LD_STATIC_FLAG"] +
" " + vars[
"CPICFLAG"] +
" "
218 vars[
"OCTAVE_LIBS"] = vars[
"LIBOCTINTERP"] +
" " + vars[
"LIBOCTAVE"] +
" "
219 + vars[
"SPECIAL_MATH_LIB"];
221 vars[
"FFTW_LIBS"] = vars[
"FFTW3_LDFLAGS"] +
" " + vars[
"FFTW3_LIBS"] +
" "
222 + vars[
"FFTW3F_LDFLAGS"] +
" " + vars[
"FFTW3F_LIBS"];
225 static std::string
usage_msg =
"usage: mkoctfile [options] file ...";
232 " -h, -?, --help Print this message.\n"
234 " -IDIR Add -IDIR to compile commands.\n"
236 " -idirafter DIR Add -idirafter DIR to compile commands.\n"
238 " -DDEF Add -DDEF to compile commands.\n"
240 " -lLIB Add library LIB to link command.\n"
242 " -LDIR Add -LDIR to link command.\n"
244 " -M, --depend Generate dependency files (.d) for C and C++\n"
246 #if ! defined (__WIN32__) || defined (_POSIX_VERSION)
248 " -pthread Add -pthread to link command.\n"
251 " -RDIR Add -RDIR to link command.\n"
253 " -Wl,... Pass flags though the linker like -Wl,-rpath=...\n"
255 " -W... Pass flags though the compiler like -Wa,OPTION.\n"
257 " -c, --compile Compile, but do not link.\n"
259 " -o FILE, --output FILE Output file name. Default extension is .oct\n"
260 " (or .mex if --mex is specified) unless linking\n"
261 " a stand-alone executable.\n"
263 " -g Enable debugging options for compilers.\n"
265 " -p VAR, --print VAR Print configuration variable VAR. Recognized\n"
268 " ALL_CFLAGS INCFLAGS\n"
269 " ALL_CXXFLAGS INCLUDEDIR\n"
270 " ALL_FFLAGS LAPACK_LIBS\n"
271 " ALL_LDFLAGS LD_CXX\n"
273 " BLAS_LIBS LD_STATIC_FLAG\n"
276 " CPICFLAG LIBOCTAVE\n"
277 " CPPFLAGS LIBOCTINTERP\n"
279 " CXXFLAGS OCTAVE_HOME\n"
280 " CXXPICFLAG OCTAVE_LIBS\n"
281 " DEPEND_EXTRA_SED_PATTERN OCTAVE_LINK_DEPS\n"
282 " DEPEND_FLAGS OCTAVE_LINK_OPTS\n"
283 " DL_LD OCTAVE_PREFIX\n"
284 " DL_LDFLAGS OCTINCLUDEDIR\n"
286 " F77_INTEGER8_FLAG OCT_LINK_DEPS\n"
287 " FFLAGS OCT_LINK_OPTS\n"
288 " FFTW3F_LDFLAGS RANLIB\n"
289 " FFTW3F_LIBS RDYNAMIC_FLAG\n"
290 " FFTW3_LDFLAGS READLINE_LIBS\n"
292 " FFTW_LIBS SPECIAL_MATH_LIB\n"
293 " FLIBS XTRA_CFLAGS\n"
294 " FPICFLAG XTRA_CXXFLAGS\n"
296 " --link-stand-alone Link a stand-alone executable file.\n"
298 " --mex Assume we are creating a MEX file. Set the\n"
299 " default output extension to \".mex\".\n"
301 " -s, --strip Strip output file.\n"
303 " -v, --verbose Echo commands as they are executed.\n"
305 " FILE Compile or link FILE. Recognized file types are:\n"
311 " .f Fortran source (fixed form)\n"
312 " .F Fortran source (fixed form)\n"
313 " .f90 Fortran source (free form)\n"
314 " .F90 Fortran source (free form)\n"
318 " .lib library file\n"
323 basename (
const std::string& s,
bool strip_path =
false)
326 size_t pos = s.rfind (
'.');
328 if (pos == std::string::npos)
331 retval = s.substr (0, pos);
335 size_t p1 = retval.rfind (
'/'), p2 = retval.rfind (
'\\');
336 pos = (p1 != std::string::npos && p2 != std::string::npos
337 ?
std::max (p1, p2) : (p2 != std::string::npos ? p2 : p1));
338 if (pos != std::string::npos)
339 retval = retval.substr (++pos, std::string::npos);
348 return (s.length () >= prefix.length () && s.find (prefix) == 0);
352 ends_with (
const std::string& s,
const std::string& suffix)
354 return (s.length () >= suffix.length ()
355 && s.rfind (suffix) == s.length () - suffix.length ());
362 std::cout << cmd << std::endl;
364 int result = system (cmd.c_str ());
375 return (s ==
"yes" || s ==
"true");
383 std::string file, output_option;
384 std::list<std::string> cfiles, ccfiles, f77files;
387 std::string objfiles =
"";
388 std::string libfiles =
"";
389 std::string octfile =
"";
390 std::string outputfile =
"";
391 std::string incflags =
"";
392 std::string defs =
"";
393 std::string ldflags =
"";
394 std::string pass_on_options =
"";
396 bool no_oct_file_strip_on_this_platform =
is_true (
"false");
398 bool link_stand_alone =
false;
399 std::string output_ext =
".oct";
408 if (argc == 2 && (!strcmp (argv[1],
"-v")
409 || !strcmp (argv[1],
"-version")
410 || !strcmp (argv[1],
"--version")))
416 for (
int i = 1; i < argc; i++)
418 std::string
arg = argv[i];
423 cfiles.push_back (file);
429 ccfiles.push_back (file);
435 f77files.push_back (file);
447 else if (arg ==
"-d" || arg ==
"-debug" || arg ==
"--debug"
448 || arg ==
"-v" || arg ==
"-verbose" || arg ==
"--verbose")
451 if (vars[
"CC"] ==
"cc-msvc")
453 if (vars[
"CXX"] ==
"cc-msvc")
454 vars[
"CXX"] +=
" -d";
455 if (vars[
"DL_LD"] ==
"cc-msvc")
456 vars[
"DL_LD"] +=
" -d";
458 else if (arg ==
"-h" || arg ==
"-?" || arg ==
"-help" || arg ==
"--help")
468 else if (arg ==
"-idirafter")
473 incflags += (
" -idirafter " +
arg);
476 std::cerr <<
"mkoctfile: include directory name missing"
486 ldflags += (
" " +
arg);
488 #if ! defined (__WIN32__) || defined (_POSIX_VERSION)
489 else if (arg ==
"-pthread")
491 ldflags += (
" " +
arg);
494 else if (arg ==
"-M" || arg ==
"-depend" || arg ==
"--depend")
498 else if (arg ==
"-o" || arg ==
"-output" || arg ==
"--output")
506 std::cerr <<
"mkoctfile: output file name missing" << std::endl;
508 else if (arg ==
"-p" || arg ==
"-print" || arg ==
"--print")
513 std::cout << vars[
arg] << std::endl;
517 std::cerr <<
"mkoctfile: --print requires argument" << std::endl;
519 else if (arg ==
"-s" || arg ==
"-strip" || arg ==
"--strip")
521 if (no_oct_file_strip_on_this_platform)
522 std::cerr <<
"mkoctfile: stripping disabled on this platform"
527 else if (arg ==
"-c" || arg ==
"-compile" || arg ==
"--compile")
531 else if (arg ==
"-g")
533 vars[
"ALL_CFLAGS"] +=
" -g";
534 vars[
"ALL_CXXFLAGS"] +=
" -g";
535 vars[
"ALL_FFLAGS"] +=
" -g";
537 else if (arg ==
"-link-stand-alone" || arg ==
"--link-stand-alone")
539 link_stand_alone =
true;
541 else if (arg ==
"-mex" || arg ==
"--mex")
545 ldflags +=
" -Wl,-export:mexFunction";
551 pass_on_options += (
" " +
arg);
556 pass_on_options += (
" " +
arg);
560 std::cerr <<
"mkoctfile: unrecognized argument " << arg << std::endl;
564 if (!file.empty () && octfile.empty ())
568 if (link_stand_alone)
570 if (!outputfile.empty ())
571 output_option =
"-o " + outputfile;
575 if (!outputfile.empty ())
577 octfile = outputfile;
578 size_t len = octfile.length ();
579 size_t len_ext = output_ext.length ();
580 if (octfile.substr (len-len_ext) != output_ext)
581 octfile += output_ext;
584 octfile =
basename (octfile,
true) + output_ext;
587 std::list<std::string>::const_iterator it;
591 for (it = cfiles.begin (); it != cfiles.end (); ++it)
593 std::string
f = *it, dfile =
basename (f,
true) +
".d",
line;
595 gnulib::unlink (dfile.c_str ());
596 std::string cmd = vars[
"CC"] +
" "
597 + vars[
"DEPEND_FLAGS"] +
" "
598 + vars[
"CPPFLAGS"] +
" "
599 + vars[
"ALL_CFLAGS"] +
" "
600 + incflags +
" " + defs +
" " +
quote_path (f);
602 FILE *fd = popen (cmd.c_str (),
"r");
603 std::ofstream fo (dfile.c_str ());
608 if ((pos =
line.rfind (
".o:")) != std::string::npos)
610 size_t spos =
line.rfind (
'/', pos);
612 (spos == std::string::npos
613 ?
line.substr (0, pos+2)
614 :
line.substr (spos+1, pos-spos+1));
615 fo <<
"pic/" << ofile <<
" " << ofile <<
" "
616 << dfile <<
line.substr (pos) << std::endl;
619 fo <<
line << std::endl;
625 for (it = ccfiles.begin (); it != ccfiles.end (); ++it)
627 std::string
f = *it, dfile =
basename (f,
true) +
".d",
line;
629 gnulib::unlink (dfile.c_str ());
630 std::string cmd = vars[
"CC"] +
" "
631 + vars[
"DEPEND_FLAGS"] +
" "
632 + vars[
"CPPFLAGS"] +
" "
633 + vars[
"ALL_CXXFLAGS"] +
" "
634 + incflags +
" " + defs +
" " +
quote_path (f);
636 FILE *fd = popen (cmd.c_str (),
"r");
637 std::ofstream fo (dfile.c_str ());
642 if ((pos =
line.rfind (
".o:")) != std::string::npos)
644 size_t spos =
line.rfind (
'/', pos);
646 (spos == std::string::npos
647 ?
line.substr (0, pos+2)
648 :
line.substr (spos+1, pos-spos+1));
649 fo <<
"pic/" << ofile <<
" " << ofile <<
" "
650 << dfile <<
line.substr (pos+2) << std::endl;
653 fo <<
line << std::endl;
662 for (it = f77files.begin (); it != f77files.end () && !result; ++it)
664 std::string
f = *it, b =
basename (f,
true);
665 if (!vars[
"F77"].empty ())
668 if (!outputfile.empty ())
677 objfiles += (
" " + o);
678 std::string cmd = vars[
"F77"] +
" -c "
679 + vars[
"FPICFLAG"] +
" "
680 + vars[
"ALL_FFLAGS"] +
" "
681 + incflags +
" " + defs +
" " + pass_on_options
682 +
" " + f +
" -o " + o;
687 std::cerr <<
"mkoctfile: no way to compile Fortran file " << f
693 for (it = cfiles.begin (); it != cfiles.end () && !result; ++it)
696 if (!vars[
"CC"].empty ())
698 std::string b =
basename (f,
true), o;
699 if (!outputfile.empty ())
708 objfiles += (
" " + o);
709 std::string cmd = vars[
"CC"] +
" -c "
710 + vars[
"CPPFLAGS"] +
" "
711 + vars[
"CPICFLAG"] +
" " + vars[
"ALL_CFLAGS"] +
" "
712 + pass_on_options +
" "
713 + incflags +
" " + defs +
" "
719 std::cerr <<
"mkoctfile: no way to compile C file " << f
725 for (it = ccfiles.begin (); it != ccfiles.end () && !result; ++it)
728 if (!vars[
"CXX"].empty ())
730 std::string b =
basename (f,
true), o;
731 if (!outputfile.empty ())
740 objfiles += (
" " + o);
741 std::string cmd = vars[
"CXX"] +
" -c "
742 + vars[
"CPPFLAGS"] +
" "
743 + vars[
"CXXPICFLAG"] +
" "
744 + vars[
"ALL_CXXFLAGS"] +
" "
745 + pass_on_options +
" "
746 + incflags +
" " + defs +
" "
752 std::cerr <<
"mkoctfile: no way to compile C++ file " << f
758 if (link && !objfiles.empty () && !result)
760 if (link_stand_alone)
762 if (!vars[
"LD_CXX"].empty ())
764 std::string cmd = vars[
"LD_CXX"] +
" "
765 + vars[
"CPPFLAGS"] +
" "
766 + vars[
"ALL_CXXFLAGS"] +
" "
767 + vars[
"RDYNAMIC_FLAG"] +
" "
768 + vars[
"ALL_LDFLAGS"] +
" "
769 + pass_on_options +
" " + output_option +
" "
770 + objfiles +
" " + libfiles +
" "
771 + ldflags +
" " + vars[
"LFLAGS"]
772 +
" -loctinterp -loctave "
773 +
" " + vars[
"OCTAVE_LINK_OPTS"]
774 +
" " + vars[
"OCTAVE_LINK_DEPS"];
780 <<
"mkoctfile: no way to link stand-alone executable file"
787 std::string cmd = vars[
"DL_LD"] +
" "
788 + vars[
"DL_LDFLAGS"] +
" "
790 +
" -o " + octfile +
" "
791 + objfiles +
" " + libfiles +
" "
793 + vars[
"LFLAGS"] +
" -loctinterp -loctave "
794 + vars[
"OCT_LINK_OPTS"] +
" "
795 + vars[
"OCT_LINK_DEPS"];
801 std::string cmd =
"strip " + octfile;
bool starts_with(const std::string &s, const std::string &prefix)
static std::string get_line(FILE *fp)
static std::string help_msg
static std::string get_octave_home(void)
bool is_true(const std::string &s)
static std::string subst_octave_home(const std::string &s)
static int run_command(const std::string &cmd)
int main(int argc, char **argv)
static std::map< std::string, std::string > vars
bool ends_with(const std::string &s, const std::string &suffix)
static std::string quote_path(const std::string &s)
static octave_idx_type link(octave_idx_type s, octave_idx_type t, octave_idx_type *pp)
#define WIFEXITED(stat_val)
static std::string basename(const std::string &s, bool strip_path=false)
F77_RET_T const double const double * f
static std::string get_variable(const char *name, const std::string &defval)
static std::string version_msg
charNDArray max(char d, const charNDArray &m)
static std::string usage_msg
#define WEXITSTATUS(stat_val)
static void initialize(void)