1########################################################################
2##
3## Copyright (C) 2006-2021 The Octave Project Developers
4##
5## See the file COPYRIGHT.md in the top-level directory of this
6## distribution or <https://octave.org/copyright/>.
7##
8## This file is part of Octave.
9##
10## Octave is free software: you can redistribute it and/or modify it
11## under the terms of the GNU General Public License as published by
12## the Free Software Foundation, either version 3 of the License, or
13## (at your option) any later version.
14##
15## Octave is distributed in the hope that it will be useful, but
16## WITHOUT ANY WARRANTY; without even the implied warranty of
17## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18## GNU General Public License for more details.
19##
20## You should have received a copy of the GNU General Public License
21## along with Octave; see the file COPYING.  If not, see
22## <https://www.gnu.org/licenses/>.
23##
24########################################################################
25
26## -*- texinfo -*-
27## @deftypefn  {} {} mkoctfile [-options] file @dots{}
28## @deftypefnx {} {[@var{output}, @var{status}] =} mkoctfile (@dots{})
29##
30## The @code{mkoctfile} function compiles source code written in C, C++, or
31## Fortran.  Depending on the options used with @code{mkoctfile}, the
32## compiled code can be called within Octave or can be used as a stand-alone
33## application.
34##
35## @code{mkoctfile} can be called from the shell prompt or from the Octave
36## prompt.  Calling it from the Octave prompt simply delegates the call to
37## the shell prompt.  Any output is stored in the @var{output} variable and
38## the exit status in the @var{status} variable.  If called with no outputs
39## and the compilation fails then Octave will emit an error.  If the programmer
40## requests @var{output} or @var{status}, however, Octave will merely issue
41## a warning and it is the programmer's responsibility to verify the command
42## was successful.
43##
44## @code{mkoctfile} accepts the following options, all of which are optional
45## except for the filename of the code you wish to compile:
46##
47## @table @samp
48## @item -I DIR
49## Add the include directory DIR to compile commands.
50##
51## @item -D DEF
52## Add the definition DEF to the compiler call.
53##
54## @item -l LIB
55## Add the library LIB to the link command.
56##
57## @item -L DIR
58## Add the library directory DIR to the link command.
59##
60## @item  -M
61## @itemx --depend
62## Generate dependency files (.d) for C and C++ source files.
63##
64## @item -R DIR
65## Add the run-time path to the link command.
66##
67## @item @nospell{-Wl,@dots{}}
68## Pass options to the linker like @nospell{"-Wl,-rpath=@dots{}"}.
69## The quotes are needed since commas are interpreted as command
70## separators.
71##
72## @item -W@dots{}
73## Pass options to the assembler like @nospell{"-Wa,OPTION"}.
74##
75## @item -c
76## Compile but do not link.
77##
78## @item -g
79## Enable debugging options for compilers.
80##
81## @item  -o FILE
82## @itemx --output FILE
83## Output filename.  Default extension is @file{.oct} (or @file{.mex} if
84## @samp{--mex} is specified) unless linking a stand-alone executable.
85##
86## @item  -p VAR
87## @itemx --print VAR
88## Print configuration variable VAR@.  There are three categories of
89## variables:
90##
91## Octave configuration variables that users may override with environment
92## variables.  These are used in commands that @code{mkoctfile} executes.
93##
94## @example
95##    ALL_CFLAGS                  INCLUDEDIR
96##    ALL_CXXFLAGS                LAPACK_LIBS
97##    ALL_FFLAGS                  LDFLAGS
98##    ALL_LDFLAGS                 LD_STATIC_FLAG
99##    BLAS_LIBS                   LFLAGS
100##    CC                          LIBDIR
101##    CFLAGS                      LIBOCTAVE
102##    CPICFLAG                    LIBOCTINTERP
103##    CPPFLAGS                    OCTAVE_LINK_OPTS
104##    CXX                         OCTINCLUDEDIR
105##    CXXFLAGS                    OCTAVE_LIBS
106##    CXXLD                       OCTAVE_LINK_DEPS
107##    CXXPICFLAG                  OCTLIBDIR
108##    DL_LDFLAGS                  OCT_LINK_DEPS
109##    F77                         OCT_LINK_OPTS
110##    F77_INTEGER8_FLAG           RDYNAMIC_FLAG
111##    FFLAGS                      SPECIAL_MATH_LIB
112##    FPICFLAG                    XTRA_CFLAGS
113##    INCFLAGS                    XTRA_CXXFLAGS
114## @end example
115##
116## Octave configuration variables as above, but currently unused by
117## @code{mkoctfile}.
118##
119## @example
120## @group
121##    AR
122##    DEPEND_EXTRA_SED_PATTERN
123##    DEPEND_FLAGS
124##    FFTW3F_LDFLAGS
125##    FFTW3F_LIBS
126##    FFTW3_LDFLAGS
127##    FFTW3_LIBS
128##    FFTW_LIBS
129##    FLIBS
130##    LIBS
131##    RANLIB
132##    READLINE_LIBS
133## @end group
134## @end example
135##
136## Octave configuration variables that are provided for informational
137## purposes only.  Except for @samp{OCTAVE_HOME} and @samp{OCTAVE_EXEC_HOME},
138## users may not override these variables.
139##
140## If @w{@env{OCTAVE_HOME}} or @w{@env{OCTAVE_EXEC_HOME}} are set in the
141## environment, then other variables are adjusted accordingly with
142## @w{@env{OCTAVE_HOME}} or @w{@env{OCTAVE_EXEC_HOME}} substituted for the
143## original value of the directory specified by the @option{--prefix} or
144## @option{--exec-prefix} options that were used when Octave was configured.
145##
146## @example
147## @group
148##    API_VERSION                 LOCALFCNFILEDIR
149##    ARCHLIBDIR                  LOCALOCTFILEDIR
150##    BINDIR                      LOCALSTARTUPFILEDIR
151##    CANONICAL_HOST_TYPE         LOCALVERARCHLIBDIR
152##    DATADIR                     LOCALVERFCNFILEDIR
153##    DATAROOTDIR                 LOCALVEROCTFILEDIR
154##    DEFAULT_PAGER               MAN1DIR
155##    EXEC_PREFIX                 MAN1EXT
156##    EXEEXT                      MANDIR
157##    FCNFILEDIR                  OCTAVE_EXEC_HOME
158##    IMAGEDIR                    OCTAVE_HOME
159##    INFODIR                     OCTAVE_VERSION
160##    INFOFILE                    OCTDATADIR
161##    LIBEXECDIR                  OCTDOCDIR
162##    LOCALAPIARCHLIBDIR          OCTFILEDIR
163##    LOCALAPIFCNFILEDIR          OCTFONTSDIR
164##    LOCALAPIOCTFILEDIR          STARTUPFILEDIR
165##    LOCALARCHLIBDIR
166## @end group
167## @end example
168##
169## @item --link-stand-alone
170## Link a stand-alone executable file.
171##
172## @item --mex
173## Assume creation of a MEX file.  Set the default output extension to
174## @file{.mex}.
175##
176## @item  -s
177## @itemx --strip
178## Strip the output file.
179##
180## @item  -v
181## @itemx --verbose
182## Echo commands as they are executed.
183##
184## @item file
185## The file to compile or link.  Recognized file types are:
186##
187## @example
188## @group
189##    .c    C source
190##    .cc   C++ source
191##    .cp   C++ source
192##    .cpp  C++ source
193##    .CPP  C++ source
194##    .cxx  C++ source
195##    .c++  C++ source
196##    .C    C++ source
197##    .f    Fortran source (fixed form)
198##    .F    Fortran source (fixed form)
199##    .f90  Fortran source (free form)
200##    .F90  Fortran source (free form)
201##    .o    object file
202##    .a    library file
203## @end group
204## @end example
205##
206## @end table
207## @end deftypefn
208
209function [output, status] = mkoctfile (varargin)
210
211  bindir = __octave_config_info__ ("bindir");
212  ext = __octave_config_info__ ("EXEEXT");
213
214  shell_script = fullfile (bindir,
215                           sprintf ("mkoctfile-%s%s", OCTAVE_VERSION, ext));
216
217  if (! exist (shell_script, "file"))
218    __gripe_missing_component__ ("mkoctfile", "mkoctfile");
219  endif
220
221  cmd = ['"' shell_script '"'];
222  for i = 1:nargin
223    cmd = [cmd ' "' varargin{i} '"'];
224  endfor
225
226  [sts, out] = system (cmd);
227
228  if (nargout > 0)
229    [output, status] = deal (out, sts);
230    if (sts != 0)
231      warning ("mkoctfile: building exited with failure status\n");
232    endif
233  else
234    printf ("%s", out);
235    if (sts != 0)
236      error ("mkoctfile: building exited with failure status\n");
237    endif
238  endif
239
240endfunction
241